[MERGE] trunk.

bzr revid: vda@tinyerp.com-20111110053010-764swpojy1kb241f
This commit is contained in:
Vaibhav (OpenERP) 2011-11-10 11:00:10 +05:30
commit 2975c1406a
44 changed files with 3068 additions and 696 deletions

View File

@ -23,6 +23,7 @@
"static/lib/jquery.ui/js/jquery-ui-timepicker-addon.js",
"static/lib/jquery.ui.notify/js/jquery.notify.js",
"static/lib/jquery.deferred-queue/jquery.deferred-queue.js",
"static/lib/jquery.scrollTo/jquery.scrollTo-min.js",
"static/lib/json/json2.js",
"static/lib/qweb/qweb2.js",
"static/lib/underscore/underscore.js",
@ -53,4 +54,7 @@
"static/src/css/data_export.css",
"static/src/css/data_import.css",
],
'qweb' : [
"static/src/xml/*.xml",
],
}

View File

@ -129,6 +129,18 @@ class XmlRPCConnector(Connector):
# TODO should try except and wrap exception into LibException
return getattr(service, method)(*args)
class XmlRPCSConnector(XmlRPCConnector):
"""
A type of connector that uses the secured XMLRPC protocol.
"""
PROTOCOL = 'xmlrpcs'
__logger = _getChildLogger(_logger, 'connector.xmlrpcs')
def __init__(self, hostname, port=8071):
super(XmlRPCSConnector, self).__init__(hostname, port)
self.url = 'https://%s:%d/xmlrpc' % (self.hostname, self.port)
class NetRPC_Exception(Exception):
"""
Exception for NetRPC errors.
@ -438,6 +450,7 @@ class Model(object):
:return: A list of dictionaries containing all the specified fields.
"""
record_ids = self.search(domain or [], offset, limit or False, order or False, context or {})
if not record_ids: return []
records = self.read(record_ids, fields or [], context or {})
return records
@ -450,15 +463,17 @@ def get_connector(hostname=None, protocol="xmlrpc", port="auto"):
:param port: The number of the port. Defaults to auto.
"""
if port == 'auto':
port = 8069 if protocol=="xmlrpc" else 8070
port = 8069 if protocol=="xmlrpc" else (8070 if protocol == "netrpc" else 8071)
if protocol == "xmlrpc":
return XmlRPCConnector(hostname, port)
elif protocol == "xmlrpcs":
return XmlRPCSConnector(hostname, port)
elif protocol == "netrpc":
return NetRPCConnector(hostname, port)
elif protocol == "local":
return LocalConnector()
else:
raise ValueError("You must choose xmlrpc or netrpc or local")
raise ValueError("You must choose xmlrpc(s), netrpc or local")
def get_connection(hostname=None, protocol="xmlrpc", port='auto', database=None,
login=None, password=None, user_id=None):

View File

@ -24,19 +24,51 @@ openerpweb = web.common.http
# OpenERP Web web Controllers
#----------------------------------------------------------
def concat_files(file_list):
""" Concatenate file content
def concat_xml(file_list):
"""Concatenate xml files
return (concat,timestamp)
concat: concatenation of file content
timestamp: max(os.path.getmtime of file_list)
"""
root = None
files_timestamp = 0
for fname in file_list:
ftime = os.path.getmtime(fname)
if ftime > files_timestamp:
files_timestamp = ftime
xml = ElementTree.parse(fname).getroot()
if root is None:
root = ElementTree.Element(xml.tag)
#elif root.tag != xml.tag:
# raise ValueError("Root tags missmatch: %r != %r" % (root.tag, xml.tag))
for child in xml.getchildren():
root.append(child)
return ElementTree.tostring(root, 'utf-8'), files_timestamp
def concat_files(file_list, reader=None):
""" Concatenate file content
return (concat,timestamp)
concat: concatenation of file content, read by `reader`
timestamp: max(os.path.getmtime of file_list)
"""
if reader is None:
def reader(f):
with open(f) as fp:
return fp.read()
files_content = []
files_timestamp = 0
for fname in file_list:
ftime = os.path.getmtime(fname)
if ftime > files_timestamp:
files_timestamp = ftime
files_content.append(open(fname).read())
files_content.append(reader(fname))
files_concat = "".join(files_content)
return files_concat,files_timestamp
@ -98,10 +130,42 @@ class WebClient(openerpweb.Controller):
def jslist(self, req, mods=None):
return self.manifest_list(req, mods, 'js')
@openerpweb.jsonrequest
def qweblist(self, req, mods=None):
return self.manifest_list(req, mods, 'qweb')
@openerpweb.httprequest
def css(self, req, mods=None):
files = [f[0] for f in self.manifest_glob(req, mods, 'css')]
content,timestamp = concat_files(files)
files = list(self.manifest_glob(req, mods, 'css'))
file_map = dict(files)
rx_import = re.compile(r"""@import\s+('|")(?!'|"|/|https?://)""", re.U)
rx_url = re.compile(r"""url\s*\(\s*('|"|)(?!'|"|/|https?://)""", re.U)
def reader(f):
"""read the a css file and absolutify all relative uris"""
with open(f) as fp:
data = fp.read()
web_path = file_map[f]
web_dir = os.path.dirname(web_path)
data = re.sub(
rx_import,
r"""@import \1%s/""" % (web_dir,),
data,
)
data = re.sub(
rx_url,
r"""url(\1%s/""" % (web_dir,),
data,
)
return data
content,timestamp = concat_files((f[0] for f in files), reader)
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'text/css')])
@ -112,6 +176,14 @@ class WebClient(openerpweb.Controller):
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'application/javascript')])
@openerpweb.httprequest
def qweb(self, req, mods=None):
files = [f[0] for f in self.manifest_glob(req, mods, 'qweb')]
content,timestamp = concat_xml(files)
# TODO use timestamp to set Last mofified date and E-tag
return req.make_response(content, [('Content-Type', 'text/xml')])
@openerpweb.httprequest
def home(self, req, s_action=None, **kw):
js = "\n ".join('<script type="text/javascript" src="%s"></script>'%i for i in self.manifest_list(req, None, 'js'))
@ -451,7 +523,7 @@ def clean_action(req, action, do_not_eval=False):
# values come from the server, we can just eval them
if isinstance(action.get('context'), basestring):
action['context'] = eval( action['context'], eval_ctx ) or {}
if isinstance(action.get('domain'), basestring):
action['domain'] = eval( action['domain'], eval_ctx ) or []
else:
@ -1121,19 +1193,26 @@ class Export(View):
@openerpweb.jsonrequest
def get_fields(self, req, model, prefix='', parent_name= '',
import_compat=True, parent_field_type=None):
import_compat=True, parent_field_type=None,
exclude=None):
if import_compat and parent_field_type == "many2one":
fields = {}
else:
fields = self.fields_get(req, model)
fields['.id'] = fields.pop('id') if 'id' in fields else {'string': 'ID'}
if import_compat:
fields.pop('id', None)
else:
fields['.id'] = fields.pop('id', {'string': 'ID'})
fields_sequence = sorted(fields.iteritems(),
key=lambda field: field[1].get('string', ''))
records = []
for field_name, field in fields_sequence:
if import_compat and (exclude and field_name in exclude):
continue
if import_compat and field.get('readonly'):
# If none of the field's states unsets readonly, skip the field
if all(dict(attrs).get('readonly', True)
@ -1145,7 +1224,8 @@ class Export(View):
record = {'id': id, 'string': name,
'value': id, 'children': False,
'field_type': field.get('type'),
'required': field.get('required')}
'required': field.get('required'),
'relation_field': field.get('relation_field')}
records.append(record)
if len(name.split('/')) < 3 and 'relation' in field:
@ -1177,7 +1257,6 @@ class Export(View):
def fields_info(self, req, model, export_fields):
info = {}
fields = self.fields_get(req, model)
fields['.id'] = fields.pop('id') if 'id' in fields else {'string': 'ID'}
# To make fields retrieval more efficient, fetch all sub-fields of a
# given field at the same time. Because the order in the export list is

699
addons/web/po/ar.po Normal file
View File

@ -0,0 +1,699 @@
# Arabic translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
"PO-Revision-Date: 2011-11-08 05:44+0000\n"
"Last-Translator: Ahmad Khayyat <Unknown>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr "تحذير، تم تحرير السجل، تعديلاتك سيتم تجاهلها"
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>    مزيداً من البحث...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   إنشاء \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   إنشاء و تحرير...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "عليك إختيار سجل واحد علي الأقل."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "تحذير"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "ترجمات"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "حفظ"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "إغلاق"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr "x"
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr "#{لقب}"
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr "#{text}"
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr "مدعوم من kifcaliph و"
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr "openerp.com"
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr "."
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "جاري التحميل..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "إنشاء"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "إزالة"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "نسخة إحتياطية"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "استرجاع"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "كلمة المرور"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "العودة للدخول"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "إنشاء قاعدة بيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "كلمة المرور الرئيسية:"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "اسم قاعدة البيانات الجديدة:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "تحميل البيانات الوهمية:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "اللغة الافتراضية:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "كلمة مرور المشرف العام:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "تأكيد كلمة المرور:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "إسقاط قاعدة البيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "قاعدة البيانات:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "كلمة المرور الرئيسية:"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "نسخ إحتياطي لقاعدة البيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "إسترجاع قاعدة بيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "ملف:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "تغيير كلمة المرور الرئيسية"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "كلمة مرور رئيسية جديدة:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "تأكيد كلمة المرور الرئيسية الجديدة:"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "مستخدم:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "كلمة المرور:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "قاعدة بيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "تسجيل الدخول"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "اسم مستخدم او كلمة مرور خاطئة"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr "نؤمن بأن نشاط العمل اليومي يمكن أن يكون بديهي، فعال، سريع و ممتع"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr "رؤي برنامج OpenERP هي:"
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr "كامل الأوصاف"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
"تتعدد تحديات المنشآت اليوم، و لذلك نوفر العديد من الوحدات البرمجية لكل "
"احتياج."
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr "مفتوح المصدر"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr "لبناء منتج قوي، نحن نعتمد علي معرفة ألاف المساهمين."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "سهل الإستخدام"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr "تتمثل الإنتاجية في حاجة الأفراد إلي إستخدام واجهة سهلة و لائقة."
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr "("
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ")"
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "تسجيل الخروج"
#: addons/web/static/src/xml/base.xml:0
msgid "&laquo;"
msgstr "&laquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr "&raquo;"
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_menu_item"
msgstr "oe_secondary_menu_item"
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_submenu_item"
msgstr "oe_secondary_submenu_item"
#: addons/web/static/src/xml/base.xml:0
msgid "Hide this tip"
msgstr "إخفاء هذه الملحوظة"
#: addons/web/static/src/xml/base.xml:0
msgid "Disable all tips"
msgstr "تعطيل جميع الإرشادات"
#: addons/web/static/src/xml/base.xml:0
msgid "View#"
msgstr "View#"
#: addons/web/static/src/xml/base.xml:0
msgid "Fields"
msgstr "حقول"
#: addons/web/static/src/xml/base.xml:0
msgid "View labels"
msgstr "عرض التسميات"
#: addons/web/static/src/xml/base.xml:0
msgid "Sidebar Relates"
msgstr "روابط الشريط الجانبي"
#: addons/web/static/src/xml/base.xml:0
msgid "Field"
msgstr "حقل"
#: addons/web/static/src/xml/base.xml:0
msgid ":"
msgstr ":"
#: addons/web/static/src/xml/base.xml:0
msgid "Translate view"
msgstr "ترجمة العرض"
#: addons/web/static/src/xml/base.xml:0
msgid "Translate sidebar"
msgstr "ترجمة الشريط الجانبي"
#: addons/web/static/src/xml/base.xml:0
msgid "Delete"
msgstr "حذف"
#: addons/web/static/src/xml/base.xml:0
msgid "First"
msgstr "الأول"
#: addons/web/static/src/xml/base.xml:0
msgid "<"
msgstr "<"
#: addons/web/static/src/xml/base.xml:0
msgid ">"
msgstr ">"
#: addons/web/static/src/xml/base.xml:0
msgid "Last"
msgstr "الأخير"
#: addons/web/static/src/xml/base.xml:0
msgid "♻"
msgstr "♻"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Edit"
msgstr "حفظ و تحرير"
#: addons/web/static/src/xml/base.xml:0
msgid "Create & Edit"
msgstr "إنشاء و تحرير"
#: addons/web/static/src/xml/base.xml:0
msgid "New"
msgstr "جديد"
#: addons/web/static/src/xml/base.xml:0
msgid "Duplicate"
msgstr "تكرار"
#: addons/web/static/src/xml/base.xml:0
msgid "Readonly/Editable"
msgstr "للقراءة فقط/قابل للتحرير"
#: addons/web/static/src/xml/base.xml:0
msgid "<<"
msgstr ">>"
#: addons/web/static/src/xml/base.xml:0
msgid "0"
msgstr "0"
#: addons/web/static/src/xml/base.xml:0
msgid "/"
msgstr "/"
#: addons/web/static/src/xml/base.xml:0
msgid ">>"
msgstr ">>"
#: addons/web/static/src/xml/base.xml:0
msgid "Add"
msgstr "اضافة"
#: addons/web/static/src/xml/base.xml:0
msgid "Unhandled widget"
msgstr "أداة غير معالجة"
#: addons/web/static/src/xml/base.xml:0
msgid "?"
msgstr "؟"
#: addons/web/static/src/xml/base.xml:0
msgid "#"
msgstr "#"
#: addons/web/static/src/xml/base.xml:0
msgid "Done"
msgstr "تم"
#: addons/web/static/src/xml/base.xml:0
msgid "Open..."
msgstr "فتح..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create..."
msgstr "إنشاء..."
#: addons/web/static/src/xml/base.xml:0
msgid "Search..."
msgstr "بحث..."
#: addons/web/static/src/xml/base.xml:0
msgid "..."
msgstr "..."
#: addons/web/static/src/xml/base.xml:0
msgid "Uploading ..."
msgstr "جاري التحميل..."
#: addons/web/static/src/xml/base.xml:0
msgid "Select"
msgstr "حدّد"
#: addons/web/static/src/xml/base.xml:0
msgid "Save As"
msgstr "حفظ كـ"
#: addons/web/static/src/xml/base.xml:0
msgid "Clear"
msgstr "إفراغ"
#: addons/web/static/src/xml/base.xml:0
msgid "Advanced Filter"
msgstr "مرشحات متقدمة"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Filters --"
msgstr "-- مرشحات --"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Actions --"
msgstr "-- إجراءات --"
#: addons/web/static/src/xml/base.xml:0
msgid "Save Filter"
msgstr "حفظ المرشح"
#: addons/web/static/src/xml/base.xml:0
msgid "Manage Filters"
msgstr "إدارة المرشحات"
#: addons/web/static/src/xml/base.xml:0
msgid "Filter Name:"
msgstr "اسم المرشح:"
#: addons/web/static/src/xml/base.xml:0
msgid "(Any existing filter with the same name will be replaced)"
msgstr "(لاحظ أن أي مرشح بنفس الاسم سيتم إستبداله)"
#: addons/web/static/src/xml/base.xml:0
msgid "Any of the following conditions must match"
msgstr "يجب تطابق أي من الشروط التالية"
#: addons/web/static/src/xml/base.xml:0
msgid "All the following conditions must match"
msgstr "يجب تطابق كل الشروط التالية"
#: addons/web/static/src/xml/base.xml:0
msgid "None of the following conditions must match"
msgstr "لا يجب تطابق أي من الشروط التالية"
#: addons/web/static/src/xml/base.xml:0
msgid "Add condition"
msgstr "إضافة شرط"
#: addons/web/static/src/xml/base.xml:0
msgid "and"
msgstr "و"
#: addons/web/static/src/xml/base.xml:0
msgid "Cancel"
msgstr "إلغاء"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & New"
msgstr "حفظ و جديد"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Close"
msgstr "حفظ و إغلاق"
#: addons/web/static/src/xml/base.xml:0
msgid "Export"
msgstr "تصدير"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"This wizard will export all data that matches the current search criteria to "
"a CSV file.\n"
" You can export all data or only the fields that can be "
"reimported after modification."
msgstr ""
"هذا المعالج سيقوم بتصدير كافة البيانات التي تطابق شروط البحث الحالية لملف "
"CSV.\n"
" يمكنك تصدير كل البيانات أو الحقول التي يمكن إستيرادها بعد "
"التعديل."
#: addons/web/static/src/xml/base.xml:0
msgid "Export Type:"
msgstr "نوع التصدير:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Compatible Export"
msgstr "إستيراد بيانات ملائمة للتصدير"
#: addons/web/static/src/xml/base.xml:0
msgid "Export all Data"
msgstr "تصدير جميع البيانات"
#: addons/web/static/src/xml/base.xml:0
msgid "Export Formats"
msgstr "تنسيقات التصدير"
#: addons/web/static/src/xml/base.xml:0
msgid "Available fields"
msgstr "الحقول المتوفرة"
#: addons/web/static/src/xml/base.xml:0
msgid "Fields to export"
msgstr "حقول للتصدير"
#: addons/web/static/src/xml/base.xml:0
msgid "Save fields list"
msgstr "حفظ قائمة الحقول"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove"
msgstr "إزالة"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove All"
msgstr "إزالة الكل"
#: addons/web/static/src/xml/base.xml:0
msgid "Name"
msgstr "اسم"
#: addons/web/static/src/xml/base.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"
#: addons/web/static/src/xml/base.xml:0
msgid "Save as:"
msgstr "حفظ باسم:"
#: addons/web/static/src/xml/base.xml:0
msgid "Ok"
msgstr "تم"
#: addons/web/static/src/xml/base.xml:0
msgid "Saved exports:"
msgstr "مُصدرة محفوظة:"
#: addons/web/static/src/xml/base.xml:0
msgid "Old Password:"
msgstr "كلمة المرور القديمة:"
#: addons/web/static/src/xml/base.xml:0
msgid "New Password:"
msgstr "كلمة المرور الجديدة:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm Password:"
msgstr "تأكيد كلمة المرور:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import"
msgstr "استيراد"
#: addons/web/static/src/xml/base.xml:0
msgid "1. Import a .CSV file"
msgstr "إستيراد ملف .CSV"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Select a .CSV file to import. If you need a sample of file to import,\n"
" you should use the export tool with the \"Import Compatible\" option."
msgstr ""
"اختر ملف .CSV للإستيراد. إذا كنت بحاجة إلى عينة ملف للاستيراد،\n"
" يجب عليك إستخدام أداة تصدير مع الخيار \" Compatible\" option."
#: addons/web/static/src/xml/base.xml:0
msgid "CSV File:"
msgstr "ملف CSV :"
#: addons/web/static/src/xml/base.xml:0
msgid "2. Check your file format"
msgstr "تأكد من إمتداد الملف"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Options"
msgstr "خيارات الاستيراد"
#: addons/web/static/src/xml/base.xml:0
msgid "Does your file have titles?"
msgstr "هل لملفك عناوين؟"
#: addons/web/static/src/xml/base.xml:0
msgid "Separator:"
msgstr "فاصل :"
#: addons/web/static/src/xml/base.xml:0
msgid "Delimiter:"
msgstr "محدد:"
#: addons/web/static/src/xml/base.xml:0
msgid "Encoding:"
msgstr "ترميز:"
#: addons/web/static/src/xml/base.xml:0
msgid "UTF-8"
msgstr "UTF-8"
#: addons/web/static/src/xml/base.xml:0
msgid "Latin 1"
msgstr "Latin 1"
#: addons/web/static/src/xml/base.xml:0
msgid "Lines to skip"
msgstr "خطوط للتجاهل"
#: addons/web/static/src/xml/base.xml:0
msgid "The import failed due to:"
msgstr "فشلت عملية الإستيراد للأسباب التالية:"
#: addons/web/static/src/xml/base.xml:0
msgid "Here is a preview of the file we could not import:"
msgstr "هذه معاينة لملف لم يتمكن من إستيراده:"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP Web"
msgstr "OpenERP عبر الإنترنت"
#: addons/web/static/src/xml/base.xml:0
msgid "Version"
msgstr "الإصدار"
#: addons/web/static/src/xml/base.xml:0
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
msgstr "جميع حقوق النشر محفوظة لـ © 2011-TODAY OpenERP SA."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP is a trademark of the"
msgstr "OpenERP هي علامة تجارية لـ"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP SA Company"
msgstr "شركة OpenERP SA"
#: addons/web/static/src/xml/base.xml:0
msgid "Licenced under the terms of"
msgstr "النظام مرخص بشروط"
#: addons/web/static/src/xml/base.xml:0
msgid "GNU Affero General Public License"
msgstr "GNU Affero General Public License"
#: addons/web/static/src/xml/base.xml:0
msgid "About OpenERP"
msgstr "عن OpenERP"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP"
msgstr "OpenERP"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"is a free enterprise-scale software system that is designed to boost\n"
" productivity and profit through data integration. It connects, "
"improves and\n"
" manages business processes in areas such as sales, finance, "
"supply chain,\n"
" project management, production, services, CRM, etc..."
msgstr ""
"هو نظام حر يناسب المؤسسات و الشركات و تم تصميمه لتعزيز\n"
" الإنتاجية و الربح من خلال تكامل البيانات. فيمكنك من ربط، و "
"تحسين، و\n"
" إدارة العمليات التجارية في إدارات مثل المبيعات، المحاسبة "
"المالية، المخازن،\n"
" إدارة المشروعات، الإنتاج و العمليات الصناعية، و القطاع الخدمي، , "
"إدارة علاقات العملاء..."
#: addons/web/static/src/xml/base.xml:0
msgid ""
"The system is platform-independent, and can be installed on Windows, Mac OS "
"X,\n"
" and various Linux and other Unix-based distributions. Its "
"architecture enables\n"
" new functionality to be rapidly created, modifications to be "
"made to a\n"
" production system and migration to a new version to be "
"straightforward."
msgstr ""
"يعمل البرنامج مع العديد من الأنظمة مثل Windows، و Mac OS X، و\n"
" معظم أنظمة لينكس بالإضافة إلي اليونكس. فلقد تم تصميمه ليتيح "
"إمكانية\n"
" إضافة وظائف أخري له بسهولة، و برمجته و تعديله بسرعه ليلائم "
"الواقع العملي\n"
" كما أنه يتيح سهولة نقل البيانات من إصدار إلي إصدار."
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Depending on your needs, OpenERP is available through a web or application "
"client."
msgstr ""
"حسب إحتياجاتك، نظام OpenERP متاح من خلال تطبيق الويب أو البرنامج المحلي."

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
"PO-Revision-Date: 2011-10-11 14:21+0000\n"
"PO-Revision-Date: 2011-11-08 21:58+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-01 05:09+0000\n"
"X-Generator: Launchpad (build 14197)\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
@ -264,7 +264,7 @@ msgstr "oe_secondary_menu_item"
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_submenu_item"
msgstr ""
msgstr "oe_secondary_submenu_item"
#: addons/web/static/src/xml/base.xml:0
msgid "Hide this tip"

687
addons/web/po/pl.po Normal file
View File

@ -0,0 +1,687 @@
# Polish translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
"PO-Revision-Date: 2011-11-04 16:44+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web/static/src/js/view_form.js:355
msgid ""
"Warning, the record has been modified, your changes will be discarded."
msgstr "Uwaga, rekord został zmodyfikowany, twoje zmiany zostaną odrzucone."
#: addons/web/static/src/js/view_form.js:1659
msgid "<em>   Search More...</em>"
msgstr "<em>   Szukaj dalej...</em>"
#: addons/web/static/src/js/view_form.js:1672
#, python-format
msgid "<em>   Create \"<strong>%s</strong>\"</em>"
msgstr "<em>   Utwórz \"<strong>%s</strong>\"</em>"
#: addons/web/static/src/js/view_form.js:1678
msgid "<em>   Create and Edit...</em>"
msgstr "<em>   Utwórz i edytuj...</em>"
#: addons/web/static/src/js/views.js:568
msgid "You must choose at least one record."
msgstr "Musisz wybrac co najmniej jeden rekord."
#: addons/web/static/src/js/views.js:569
msgid "Warning"
msgstr "Ostrzeżenie"
#: addons/web/static/src/js/views.js:609
msgid "Translations"
msgstr "Tłumaczenia"
#: addons/web/static/src/js/views.js:614 addons/web/static/src/xml/base.xml:0
msgid "Save"
msgstr "Zapisz"
#: addons/web/static/src/js/views.js:615
msgid "Close"
msgstr "Zamknij"
#: addons/web/static/src/xml/base.xml:0
msgid "x"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{title}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#{text}"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Powered by"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "openerp.com"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Loading..."
msgstr "Wczytywanie..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create"
msgstr "Utwórz"
#: addons/web/static/src/xml/base.xml:0
msgid "Drop"
msgstr "Usuń bazę danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Backup"
msgstr "Kopia zapasowa bazy danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Restore"
msgstr "Odtwórz bazę danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Password"
msgstr "Hasło"
#: addons/web/static/src/xml/base.xml:0
msgid "Back to Login"
msgstr "Wróć do logowania"
#: addons/web/static/src/xml/base.xml:0
msgid "CREATE DATABASE"
msgstr "UTWÓRZ BAZĘ DANYCH"
#: addons/web/static/src/xml/base.xml:0
msgid "Master password:"
msgstr "Hasło madrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "New database name:"
msgstr "Nazwa nowej bazy danych:"
#: addons/web/static/src/xml/base.xml:0
msgid "Load Demonstration data:"
msgstr "Wczytaj dane demonstracyjne:"
#: addons/web/static/src/xml/base.xml:0
msgid "Default language:"
msgstr "Domyślny język:"
#: addons/web/static/src/xml/base.xml:0
msgid "Admin password:"
msgstr "Hasło admina:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm password:"
msgstr "Potwierdź hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "DROP DATABASE"
msgstr "USUŃ BAZĘ DANYCH"
#: addons/web/static/src/xml/base.xml:0
msgid "Database:"
msgstr "Baza danych:"
#: addons/web/static/src/xml/base.xml:0
msgid "Master Password:"
msgstr "Hasło nadrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "BACKUP DATABASE"
msgstr "ZAPISZ BAZĘ"
#: addons/web/static/src/xml/base.xml:0
msgid "RESTORE DATABASE"
msgstr "ODTWÓRZ BAZĘ"
#: addons/web/static/src/xml/base.xml:0
msgid "File:"
msgstr "Plik:"
#: addons/web/static/src/xml/base.xml:0
msgid "CHANGE MASTER PASSWORD"
msgstr "ZMIEŃ HASŁO NADRZĘDNE"
#: addons/web/static/src/xml/base.xml:0
msgid "New master password:"
msgstr "Nowe hasło nadrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm new master password:"
msgstr "Potwierdź nowe hasło nadrzędne:"
#: addons/web/static/src/xml/base.xml:0
msgid "User:"
msgstr "Użytkownik:"
#: addons/web/static/src/xml/base.xml:0
msgid "Password:"
msgstr "Hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "Database"
msgstr "Baza danych"
#: addons/web/static/src/xml/base.xml:0
msgid "Login"
msgstr "Login"
#: addons/web/static/src/xml/base.xml:0
msgid "Bad username or password"
msgstr "Niepoprawna nazwa użytkownika lub hasło"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"We think that daily job activities can be more intuitive, efficient, "
"automated, .. and even fun."
msgstr ""
"Sądzimy, że codzienne zadania mogą być bardziej intuicyjne, efektywne, "
"zautomatyzowan, ... a nawet przyjemne."
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP's vision to be:"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Full featured"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Today's enterprise challenges are multiple. We provide one module for each "
"need."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Open Source"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"To Build a great product, we rely on the knowledge of thousands of "
"contributors."
msgstr ""
"Przy budowie wielkiego produktu polegamy na wiedzy tysięcy społeczników."
#: addons/web/static/src/xml/base.xml:0
msgid "User Friendly"
msgstr "Przyjazne dla użytkownika"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"In order to be productive, people need clean and easy to use interface."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "("
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ")"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "LOGOUT"
msgstr "WYLOGUJ"
#: addons/web/static/src/xml/base.xml:0
msgid "&laquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "&raquo;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_menu_item"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "oe_secondary_submenu_item"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Hide this tip"
msgstr "Ukryj tę wskazówkę"
#: addons/web/static/src/xml/base.xml:0
msgid "Disable all tips"
msgstr "Wyłącz wszystkie wskazówki"
#: addons/web/static/src/xml/base.xml:0
msgid "View#"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Fields"
msgstr "Pola"
#: addons/web/static/src/xml/base.xml:0
msgid "View labels"
msgstr "Pokaż etykiety"
#: addons/web/static/src/xml/base.xml:0
msgid "Sidebar Relates"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Field"
msgstr "Pole"
#: addons/web/static/src/xml/base.xml:0
msgid ":"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Translate view"
msgstr "Przetłumacz widok"
#: addons/web/static/src/xml/base.xml:0
msgid "Translate sidebar"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Delete"
msgstr "Usuń"
#: addons/web/static/src/xml/base.xml:0
msgid "First"
msgstr "Pierwsze"
#: addons/web/static/src/xml/base.xml:0
msgid "<"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ">"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Last"
msgstr "Ostatnie"
#: addons/web/static/src/xml/base.xml:0
msgid "♻"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Edit"
msgstr "Zapisz i edytuj"
#: addons/web/static/src/xml/base.xml:0
msgid "Create & Edit"
msgstr "Utwórz i edytuj"
#: addons/web/static/src/xml/base.xml:0
msgid "New"
msgstr "Nowy"
#: addons/web/static/src/xml/base.xml:0
msgid "Duplicate"
msgstr "Duplikuj"
#: addons/web/static/src/xml/base.xml:0
msgid "Readonly/Editable"
msgstr "Tylko odczyt/Edytowalne"
#: addons/web/static/src/xml/base.xml:0
msgid "<<"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "0"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "/"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ">>"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Add"
msgstr "Dodaj"
#: addons/web/static/src/xml/base.xml:0
msgid "Unhandled widget"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "?"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "#"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Done"
msgstr "Wykonano"
#: addons/web/static/src/xml/base.xml:0
msgid "Open..."
msgstr "Otwórz..."
#: addons/web/static/src/xml/base.xml:0
msgid "Create..."
msgstr "Utwórz..."
#: addons/web/static/src/xml/base.xml:0
msgid "Search..."
msgstr "Wyszukaj..."
#: addons/web/static/src/xml/base.xml:0
msgid "..."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Uploading ..."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Select"
msgstr "Wybierz"
#: addons/web/static/src/xml/base.xml:0
msgid "Save As"
msgstr "Zapisz jako"
#: addons/web/static/src/xml/base.xml:0
msgid "Clear"
msgstr "Wyczyść"
#: addons/web/static/src/xml/base.xml:0
msgid "Advanced Filter"
msgstr "Zaawansowany filtr"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Filters --"
msgstr "-- Filtry --"
#: addons/web/static/src/xml/base.xml:0
msgid "-- Actions --"
msgstr "-- Akcje --"
#: addons/web/static/src/xml/base.xml:0
msgid "Save Filter"
msgstr "Zapisz filtr"
#: addons/web/static/src/xml/base.xml:0
msgid "Manage Filters"
msgstr "Zarządzaj filtrami"
#: addons/web/static/src/xml/base.xml:0
msgid "Filter Name:"
msgstr "Nazwa filtra:"
#: addons/web/static/src/xml/base.xml:0
msgid "(Any existing filter with the same name will be replaced)"
msgstr "(Każdy filtr o tej samej nazwie zostanie zamazany)"
#: addons/web/static/src/xml/base.xml:0
msgid "Any of the following conditions must match"
msgstr "Jeden z tych warunków musi być spełniony"
#: addons/web/static/src/xml/base.xml:0
msgid "All the following conditions must match"
msgstr "Wszystkie warunki muszą być spełnione"
#: addons/web/static/src/xml/base.xml:0
msgid "None of the following conditions must match"
msgstr "Żadeń z tych warunków nie może być spełniony"
#: addons/web/static/src/xml/base.xml:0
msgid "Add condition"
msgstr "Dodaj warunek"
#: addons/web/static/src/xml/base.xml:0
msgid "and"
msgstr "i"
#: addons/web/static/src/xml/base.xml:0
msgid "Cancel"
msgstr "Anuluj"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & New"
msgstr "Zapisz i nowy"
#: addons/web/static/src/xml/base.xml:0
msgid "Save & Close"
msgstr "Zapisz i zamknij"
#: addons/web/static/src/xml/base.xml:0
msgid "Export"
msgstr "Eksportuj"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"This wizard will export all data that matches the current search criteria to "
"a CSV file.\n"
" You can export all data or only the fields that can be "
"reimported after modification."
msgstr ""
"Ten kreator wyeksportuje wszystkie dane, które spełniają bieżące kryteria "
"wyszukiwania, do pliku CSV.\n"
" Możesz eksportować wszystkie dane lub tylko pola, które mają być "
"importowane po zmianie."
#: addons/web/static/src/xml/base.xml:0
msgid "Export Type:"
msgstr "Typ eksportu:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Compatible Export"
msgstr "Eksport kompatybilny z importem"
#: addons/web/static/src/xml/base.xml:0
msgid "Export all Data"
msgstr "Eksportuj wszystkie dane"
#: addons/web/static/src/xml/base.xml:0
msgid "Export Formats"
msgstr "Format eksportu"
#: addons/web/static/src/xml/base.xml:0
msgid "Available fields"
msgstr "Dostępne pola"
#: addons/web/static/src/xml/base.xml:0
msgid "Fields to export"
msgstr "Pola do eksportu"
#: addons/web/static/src/xml/base.xml:0
msgid "Save fields list"
msgstr "Zapisz listę pól"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove"
msgstr "Usuń"
#: addons/web/static/src/xml/base.xml:0
msgid "Remove All"
msgstr "Usuń wszystko"
#: addons/web/static/src/xml/base.xml:0
msgid "Name"
msgstr "Nazwa"
#: addons/web/static/src/xml/base.xml:0
msgid "&nbsp;"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Save as:"
msgstr "Zapisz jako:"
#: addons/web/static/src/xml/base.xml:0
msgid "Ok"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Saved exports:"
msgstr "Zapisane eksporty"
#: addons/web/static/src/xml/base.xml:0
msgid "Old Password:"
msgstr "Poprzednie hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "New Password:"
msgstr "Nowe hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "Confirm Password:"
msgstr "Potwierdź hasło:"
#: addons/web/static/src/xml/base.xml:0
msgid "Import"
msgstr "Importuj"
#: addons/web/static/src/xml/base.xml:0
msgid "1. Import a .CSV file"
msgstr "1. Importuj plik .CSV"
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Select a .CSV file to import. If you need a sample of file to import,\n"
" you should use the export tool with the \"Import Compatible\" option."
msgstr ""
"Wybierz plik .CSV do importu. Jeśli chcesz zobaczyć przykład pliku do "
"importu,\n"
" powinieneś wyeksportować dane z opcją \"Kompatybilne z importem\"."
#: addons/web/static/src/xml/base.xml:0
msgid "CSV File:"
msgstr "Plik CSV:"
#: addons/web/static/src/xml/base.xml:0
msgid "2. Check your file format"
msgstr "2. Sprawdź format pliku"
#: addons/web/static/src/xml/base.xml:0
msgid "Import Options"
msgstr "Opcje importu"
#: addons/web/static/src/xml/base.xml:0
msgid "Does your file have titles?"
msgstr "Czy plik zawiera nazwy pól?"
#: addons/web/static/src/xml/base.xml:0
msgid "Separator:"
msgstr "Separator:"
#: addons/web/static/src/xml/base.xml:0
msgid "Delimiter:"
msgstr "Znak dziesiętny:"
#: addons/web/static/src/xml/base.xml:0
msgid "Encoding:"
msgstr "Kodowanie:"
#: addons/web/static/src/xml/base.xml:0
msgid "UTF-8"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Latin 1"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Lines to skip"
msgstr "Linie do pominięcia"
#: addons/web/static/src/xml/base.xml:0
msgid "The import failed due to:"
msgstr "Import się nie udał z powodu:"
#: addons/web/static/src/xml/base.xml:0
msgid "Here is a preview of the file we could not import:"
msgstr "Oto podgląd pliku, którego nie można zaimportować:"
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP Web"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Version"
msgstr "Wersja"
#: addons/web/static/src/xml/base.xml:0
msgid "Copyright © 2011-TODAY OpenERP SA. All Rights Reserved."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP is a trademark of the"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP SA Company"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "Licenced under the terms of"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "GNU Affero General Public License"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "About OpenERP"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid "OpenERP"
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"is a free enterprise-scale software system that is designed to boost\n"
" productivity and profit through data integration. It connects, "
"improves and\n"
" manages business processes in areas such as sales, finance, "
"supply chain,\n"
" project management, production, services, CRM, etc..."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"The system is platform-independent, and can be installed on Windows, Mac OS "
"X,\n"
" and various Linux and other Unix-based distributions. Its "
"architecture enables\n"
" new functionality to be rapidly created, modifications to be "
"made to a\n"
" production system and migration to a new version to be "
"straightforward."
msgstr ""
#: addons/web/static/src/xml/base.xml:0
msgid ""
"Depending on your needs, OpenERP is available through a web or application "
"client."
msgstr ""

View File

@ -0,0 +1,91 @@
1.4.2
[Feature]
- The plugin support percentages as target ('50%' or {top:'50%', left:'45%'})
- Exposed the max() calculation as $.scrollTo.max
[Enhancement]
- Renamed $.fn.scrollable to $.fn._scrollable to avoid conflicts with other plugins
[Fix]
- Fixing max calculations for regular DOM elements
1.4.1
[Feature]
- The target can be 'max' to scroll to the end while keeping it elegant.
[Enhancement]
- Default duration is 0 for jquery +1.3. Means sync animation
- The plugin works on all major browsers, on compat & quirks modes, including iframes.
- In addition to window/document, if html or body are received, the plugin will choose the right one.
[Fix]
- The plugin accepts floating numbers, Thanks Ramin
- Using jQuery.nodeName where neccessary so that this works on xml+xhtml
- The max() internal function wasn't completely accurrate, now it is 98% (except for IE on quirks mode and it's not too noticeable).
1.4
[Fix]
- Fixed the problem when scrolling the window to absolute positioned elements on Safari.
- Fixed the problem on Opera 9.5 when scrolling the window. That it always scrolls to 0.
[Feature]
- Added the settings object as 2nd argument to the onAfter callback.
- The 3rd argument of scrollTo can be just a function and it's used as the onAfter.
- Added full support for iframes (even max scroll calculation).
- Instead of $.scrollTo, $(window).scrollTo() and $(document).scrollTo() can be used.
- Added $().scrollable() that returns the real element to scroll, f.e: $(window).scrollable() == [body|html], works for iframes.
[Enhancement]
- Cleaned the code a bit, specially the comments
1.3.3
[Change]
- Changed the licensing from GPL to GPL+MIT.
1.3.2
[Enhancement]
- Small improvements to make the code shorter.
[Change]
- Removed the last argument received by onAfter as it was the same as the 'this' but jqueryfied.
1.3.1
[Feature]
- Exposed $.scrollTo.window() to get the element that needs to be animated, to scroll the window.
- Added option 'over'.
[Enhancement]
- Made the code as short as possible.
[Change]
- Changed the arguments received by onAfter
1.3
[Enhancement]
- Added semicolon to the start, for safe file concatenation
- Added a limit check, values below 0 or over the maximum are fixed.
- Now it should work faster, only one of html or body go through all the processing, instead of both for all browsers.
[Fix]
- Fixed the behavior for Opera, which seemed to react to both changes on <html> and <body>.
- The border is also reduced, when 'margin' is set to true.
[Change]
- The option speed has been renamed to duration.
[Feature]
- The duration can be specified with a number as 2nd argument, and the rest of the settings as the third ( like $().animate )
- Remade the demo
1.2.4
[Enhancement]
- The target can be in the form of { top:x, left:y } allowing different position for each axis.
[Feature]
- The option 'offset' has been added, to scroll behind or past the target. Can be a number(both axes) or { top:x, left:y }.
1.2.3
[Feature]
- Exposed the defaults.
[Enhancement]
- Made the callback functions receive more parameters.
1.2.2
[Fix]
- Fixed a bug, I didn't have to add the scrolled amount if it was body or html.
1.2
[Change]
- The option 'onafter' is now called 'onAfter'.
[Feature]
- Two axes can be scrolled together, this is set with the option 'axis'.
- In case 2 axes are chosen, the scrolling can be queued: one scrolls, and then the other.
- There's an intermediary event, 'onAfterFirst' called in case the axes are queued, after the first ends.
- If the option 'margin' is set to true, the plugin will take in account, the margin of the target(no use if target is a value).

View File

@ -0,0 +1,11 @@
/**
* jQuery.ScrollTo - Easy element scrolling using jQuery.
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
* @author Ariel Flesler
* @version 1.4.2
*
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
*/
;(function(d){var k=d.scrollTo=function(a,i,e){d(window).scrollTo(a,i,e)};k.defaults={axis:'xy',duration:parseFloat(d.fn.jquery)>=1.3?0:1};k.window=function(a){return d(window)._scrollable()};d.fn._scrollable=function(){return this.map(function(){var a=this,i=!a.nodeName||d.inArray(a.nodeName.toLowerCase(),['iframe','#document','html','body'])!=-1;if(!i)return a;var e=(a.contentWindow||a).document||a.ownerDocument||a;return d.browser.safari||e.compatMode=='BackCompat'?e.body:e.documentElement})};d.fn.scrollTo=function(n,j,b){if(typeof j=='object'){b=j;j=0}if(typeof b=='function')b={onAfter:b};if(n=='max')n=9e9;b=d.extend({},k.defaults,b);j=j||b.speed||b.duration;b.queue=b.queue&&b.axis.length>1;if(b.queue)j/=2;b.offset=p(b.offset);b.over=p(b.over);return this._scrollable().each(function(){var q=this,r=d(q),f=n,s,g={},u=r.is('html,body');switch(typeof f){case'number':case'string':if(/^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(f)){f=p(f);break}f=d(f,this);case'object':if(f.is||f.style)s=(f=d(f)).offset()}d.each(b.axis.split(''),function(a,i){var e=i=='x'?'Left':'Top',h=e.toLowerCase(),c='scroll'+e,l=q[c],m=k.max(q,i);if(s){g[c]=s[h]+(u?0:l-r.offset()[h]);if(b.margin){g[c]-=parseInt(f.css('margin'+e))||0;g[c]-=parseInt(f.css('border'+e+'Width'))||0}g[c]+=b.offset[h]||0;if(b.over[h])g[c]+=f[i=='x'?'width':'height']()*b.over[h]}else{var o=f[h];g[c]=o.slice&&o.slice(-1)=='%'?parseFloat(o)/100*m:o}if(/^\d+$/.test(g[c]))g[c]=g[c]<=0?0:Math.min(g[c],m);if(!a&&b.queue){if(l!=g[c])t(b.onAfterFirst);delete g[c]}});t(b.onAfter);function t(a){r.animate(g,j,b.easing,a&&function(){a.call(this,n,b)})}}).end()};k.max=function(a,i){var e=i=='x'?'Width':'Height',h='scroll'+e;if(!d(a).is('html,body'))return a[h]-d(a)[e.toLowerCase()]();var c='client'+e,l=a.ownerDocument.documentElement,m=a.ownerDocument.body;return Math.max(l[h],m[h])-Math.min(l[c],m[c])};function p(a){return typeof a=='object'?a:{top:a,left:a}}})(jQuery);

View File

@ -0,0 +1,215 @@
/**
* jQuery.ScrollTo
* Copyright (c) 2007-2009 Ariel Flesler - aflesler(at)gmail(dot)com | http://flesler.blogspot.com
* Dual licensed under MIT and GPL.
* Date: 5/25/2009
*
* @projectDescription Easy element scrolling using jQuery.
* http://flesler.blogspot.com/2007/10/jqueryscrollto.html
* Works with jQuery +1.2.6. Tested on FF 2/3, IE 6/7/8, Opera 9.5/6, Safari 3, Chrome 1 on WinXP.
*
* @author Ariel Flesler
* @version 1.4.2
*
* @id jQuery.scrollTo
* @id jQuery.fn.scrollTo
* @param {String, Number, DOMElement, jQuery, Object} target Where to scroll the matched elements.
* The different options for target are:
* - A number position (will be applied to all axes).
* - A string position ('44', '100px', '+=90', etc ) will be applied to all axes
* - A jQuery/DOM element ( logically, child of the element to scroll )
* - A string selector, that will be relative to the element to scroll ( 'li:eq(2)', etc )
* - A hash { top:x, left:y }, x and y can be any kind of number/string like above.
* - A percentage of the container's dimension/s, for example: 50% to go to the middle.
* - The string 'max' for go-to-end.
* @param {Number} duration The OVERALL length of the animation, this argument can be the settings object instead.
* @param {Object,Function} settings Optional set of settings or the onAfter callback.
* @option {String} axis Which axis must be scrolled, use 'x', 'y', 'xy' or 'yx'.
* @option {Number} duration The OVERALL length of the animation.
* @option {String} easing The easing method for the animation.
* @option {Boolean} margin If true, the margin of the target element will be deducted from the final position.
* @option {Object, Number} offset Add/deduct from the end position. One number for both axes or { top:x, left:y }.
* @option {Object, Number} over Add/deduct the height/width multiplied by 'over', can be { top:x, left:y } when using both axes.
* @option {Boolean} queue If true, and both axis are given, the 2nd axis will only be animated after the first one ends.
* @option {Function} onAfter Function to be called after the scrolling ends.
* @option {Function} onAfterFirst If queuing is activated, this function will be called after the first scrolling ends.
* @return {jQuery} Returns the same jQuery object, for chaining.
*
* @desc Scroll to a fixed position
* @example $('div').scrollTo( 340 );
*
* @desc Scroll relatively to the actual position
* @example $('div').scrollTo( '+=340px', { axis:'y' } );
*
* @dec Scroll using a selector (relative to the scrolled element)
* @example $('div').scrollTo( 'p.paragraph:eq(2)', 500, { easing:'swing', queue:true, axis:'xy' } );
*
* @ Scroll to a DOM element (same for jQuery object)
* @example var second_child = document.getElementById('container').firstChild.nextSibling;
* $('#container').scrollTo( second_child, { duration:500, axis:'x', onAfter:function(){
* alert('scrolled!!');
* }});
*
* @desc Scroll on both axes, to different values
* @example $('div').scrollTo( { top: 300, left:'+=200' }, { axis:'xy', offset:-20 } );
*/
;(function( $ ){
var $scrollTo = $.scrollTo = function( target, duration, settings ){
$(window).scrollTo( target, duration, settings );
};
$scrollTo.defaults = {
axis:'xy',
duration: parseFloat($.fn.jquery) >= 1.3 ? 0 : 1
};
// Returns the element that needs to be animated to scroll the window.
// Kept for backwards compatibility (specially for localScroll & serialScroll)
$scrollTo.window = function( scope ){
return $(window)._scrollable();
};
// Hack, hack, hack :)
// Returns the real elements to scroll (supports window/iframes, documents and regular nodes)
$.fn._scrollable = function(){
return this.map(function(){
var elem = this,
isWin = !elem.nodeName || $.inArray( elem.nodeName.toLowerCase(), ['iframe','#document','html','body'] ) != -1;
if( !isWin )
return elem;
var doc = (elem.contentWindow || elem).document || elem.ownerDocument || elem;
return $.browser.safari || doc.compatMode == 'BackCompat' ?
doc.body :
doc.documentElement;
});
};
$.fn.scrollTo = function( target, duration, settings ){
if( typeof duration == 'object' ){
settings = duration;
duration = 0;
}
if( typeof settings == 'function' )
settings = { onAfter:settings };
if( target == 'max' )
target = 9e9;
settings = $.extend( {}, $scrollTo.defaults, settings );
// Speed is still recognized for backwards compatibility
duration = duration || settings.speed || settings.duration;
// Make sure the settings are given right
settings.queue = settings.queue && settings.axis.length > 1;
if( settings.queue )
// Let's keep the overall duration
duration /= 2;
settings.offset = both( settings.offset );
settings.over = both( settings.over );
return this._scrollable().each(function(){
var elem = this,
$elem = $(elem),
targ = target, toff, attr = {},
win = $elem.is('html,body');
switch( typeof targ ){
// A number will pass the regex
case 'number':
case 'string':
if( /^([+-]=)?\d+(\.\d+)?(px|%)?$/.test(targ) ){
targ = both( targ );
// We are done
break;
}
// Relative selector, no break!
targ = $(targ,this);
case 'object':
// DOMElement / jQuery
if( targ.is || targ.style )
// Get the real position of the target
toff = (targ = $(targ)).offset();
}
$.each( settings.axis.split(''), function( i, axis ){
var Pos = axis == 'x' ? 'Left' : 'Top',
pos = Pos.toLowerCase(),
key = 'scroll' + Pos,
old = elem[key],
max = $scrollTo.max(elem, axis);
if( toff ){// jQuery / DOMElement
attr[key] = toff[pos] + ( win ? 0 : old - $elem.offset()[pos] );
// If it's a dom element, reduce the margin
if( settings.margin ){
attr[key] -= parseInt(targ.css('margin'+Pos)) || 0;
attr[key] -= parseInt(targ.css('border'+Pos+'Width')) || 0;
}
attr[key] += settings.offset[pos] || 0;
if( settings.over[pos] )
// Scroll to a fraction of its width/height
attr[key] += targ[axis=='x'?'width':'height']() * settings.over[pos];
}else{
var val = targ[pos];
// Handle percentage values
attr[key] = val.slice && val.slice(-1) == '%' ?
parseFloat(val) / 100 * max
: val;
}
// Number or 'number'
if( /^\d+$/.test(attr[key]) )
// Check the limits
attr[key] = attr[key] <= 0 ? 0 : Math.min( attr[key], max );
// Queueing axes
if( !i && settings.queue ){
// Don't waste time animating, if there's no need.
if( old != attr[key] )
// Intermediate animation
animate( settings.onAfterFirst );
// Don't animate this axis again in the next iteration.
delete attr[key];
}
});
animate( settings.onAfter );
function animate( callback ){
$elem.animate( attr, duration, settings.easing, callback && function(){
callback.call(this, target, settings);
});
};
}).end();
};
// Max scrolling position, works on quirks mode
// It only fails (not too badly) on IE, quirks mode.
$scrollTo.max = function( elem, axis ){
var Dim = axis == 'x' ? 'Width' : 'Height',
scroll = 'scroll'+Dim;
if( !$(elem).is('html,body') )
return elem[scroll] - $(elem)[Dim.toLowerCase()]();
var size = 'client' + Dim,
html = elem.ownerDocument.documentElement,
body = elem.ownerDocument.body;
return Math.max( html[scroll], body[scroll] )
- Math.min( html[size] , body[size] );
};
function both( val ){
return typeof val == 'object' ? val : { top:val, left:val };
};
})( jQuery );

View File

@ -654,6 +654,9 @@ label.error {
display: none;
}
.openerp .oe_search-view-buttons {
padding: 10px 0 10px 0;
}
.openerp .oe_search-view-custom-filter-btn span {
background: url(/web/static/src/img/icons/gtk-add.png) repeat-y;
padding-left: 18px;
@ -1080,20 +1083,43 @@ label.error {
}
.openerp .oe-view-manager-logs {
clear: both;
font-size: 85%;
margin: 0.25em 0;
background: #fff;
padding: 0 10px;
margin: 0.25em 0;
font-size: 85%;
color: #4C4C4C;
position: relative;
overflow: hidden;
}
.openerp .oe-view-manager-logs ul {
margin: 0;
padding: 0 10px;
list-style: none;
}
.openerp .oe-view-manager-logs li:before {
content: '→ ';
content: '\2192 ';
}
.openerp .oe-view-manager-logs a {
text-decoration: none;
color: inherit;
}
/* only display first three log items of a folded logs list */
.openerp .oe-view-manager-logs.oe-folded li:nth-child(n+4) {
display: none;
}
/* display link to more logs if there are more logs to view and the logview is
currently folded */
.openerp .oe-view-manager-logs a.oe-more-logs {
display: none;
}
.openerp .oe-view-manager-logs.oe-folded.oe-has-more a.oe-more-logs {
display: block;
}
.openerp .oe-view-manager-logs a.oe-remove-everything {
position: absolute;
top: 0;
right: 0;
cursor: pointer;
}
.openerp .view-manager-main-sidebar {
width: 180px;
@ -1448,3 +1474,4 @@ ul.oe-arrow-list li.oe-arrow-list-selected .oe-arrow-list-after {
.openerp .oe_view_editor_tree_grid a {
display: block;
}

View File

@ -65,6 +65,11 @@ openerp.web = function(instance) {
openerp.web[files[i]](instance);
}
}
instance.log = function() {
if (instance.connection.debug && window.console) {
console.log.apply(console, arguments);
}
}
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

View File

@ -109,7 +109,7 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
}
},
start: function () {
this.$dialog = $('<div id="' + this.element_id + '"></div>').dialog(this.dialog_options);
this.$dialog = $(this.$element).dialog(this.dialog_options);
this._super();
return this;
},
@ -136,10 +136,10 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog#
}
});
openerp.web.CrashManager = openerp.web.SessionAware.extend({
init: function(parent) {
this._super((parent || {}).session);
this.session.on_rpc_error.add(this.on_rpc_error);
openerp.web.CrashManager = openerp.web.CallbackEnabled.extend({
init: function() {
this._super();
openerp.connection.on_rpc_error.add(this.on_rpc_error);
},
on_rpc_error: function(error) {
this.error = error;
@ -959,17 +959,15 @@ openerp.web.WebClient = openerp.web.Widget.extend(/** @lends openerp.web.WebClie
this._super(null, element_id);
openerp.webclient = this;
QWeb.add_template("/web/static/src/xml/base.xml");
var params = {};
if(jQuery.param != undefined && jQuery.deparam(jQuery.param.querystring()).kitten != undefined) {
this.$element.addClass("kitten-mode-activated");
}
this.$element.html(QWeb.render("Interface", params));
this.notification = new openerp.web.Notification();
this.session = new openerp.web.Session();
this.notification = new openerp.web.Notification(this);
this.loading = new openerp.web.Loading(this,"oe_loading");
this.crashmanager = new openerp.web.CrashManager(this);
this.crashmanager = new openerp.web.CrashManager();
this.header = new openerp.web.Header(this);
this.login = new openerp.web.Login(this);

View File

@ -237,8 +237,8 @@ openerp.web.Registry = openerp.web.Class.extend( /** @lends openerp.web.Registry
* registry was created.
*
* An object path is simply a dotted name from the openerp root to the
* object pointed to (e.g. ``"openerp.web.Session"`` for an OpenERP
* session object).
* object pointed to (e.g. ``"openerp.web.Connection"`` for an OpenERP
* connection object).
*
* @constructs openerp.web.Registry
* @param {Object} mapping a mapping of keys to object-paths
@ -338,9 +338,9 @@ openerp.web.CallbackEnabled = openerp.web.Class.extend(/** @lends openerp.web.Ca
}
});
openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Session# */{
openerp.web.Connection = openerp.web.CallbackEnabled.extend( /** @lends openerp.web.Connection# */{
/**
* @constructs openerp.web.Session
* @constructs openerp.web.Connection
* @extends openerp.web.CallbackEnabled
*
* @param {String} [server] JSON-RPC endpoint hostname
@ -364,7 +364,9 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
// TODO: session should have an optional name indicating that they'll
// be saved to (and revived from) cookies
this.name = 'session';
this.do_load_qweb(['/web/webclient/qweb']);
},
start: function() {
this.session_restore();
},
@ -487,9 +489,11 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
self.user_context = result.context;
self.db = result.db;
self.session_save();
self.on_session_valid();
return true;
}).then(success_callback);
},
login: function() { this.session_login.apply(this, arguments); },
/**
* Reloads uid and session_id from local storage, if they exist
*/
@ -577,6 +581,7 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
self.rpc('/web/webclient/jslist', {"mods": modules}, function(files) {
self.do_load_js(file_list.concat(files));
});
self.rpc('/web/webclient/qweblist', {"mods": modules}, self.do_load_qweb);
openerp._modules_loaded = true;
});
});
@ -610,6 +615,12 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
this.on_modules_loaded();
}
},
do_load_qweb: function(files) {
var self = this;
_.each(files, function(file) {
openerp.web.qweb.add_template(file);
});
},
on_modules_loaded: function() {
for(var j=0; j<this.module_list.length; j++) {
var mod = this.module_list[j];
@ -716,36 +727,6 @@ openerp.web.Session = openerp.web.CallbackEnabled.extend( /** @lends openerp.web
}
});
openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.SessionAware# */{
/**
* Utility class that any class is allowed to extend to easy common manipulations.
*
* It provides rpc calls, callback on all methods preceded by "on_" or "do_" and a
* logging facility.
*
* @constructs openerp.web.SessionAware
* @extends openerp.web.CallbackEnabled
*
* @param {openerp.web.Session} session
*/
init: function(session) {
this._super();
this.session = session;
},
/**
* Performs a JSON-RPC call
*
* @param {String} url endpoint url
* @param {Object} data RPC parameters
* @param {Function} success RPC call success callback
* @param {Function} error RPC call error callback
* @returns {jQuery.Deferred} deferred object for the RPC call
*/
rpc: function(url, data, success, error) {
return this.session.rpc(url, data, success, error);
}
});
/**
* Base class for all visual components. Provides a lot of functionalities helpful
* for the management of a part of the DOM.
@ -756,8 +737,6 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp
* destroyed too).
* - Insertion in DOM.
*
* Widget also extends SessionAware for ease of use.
*
* Guide to create implementations of the Widget class:
* ==============================================
*
@ -798,7 +777,7 @@ openerp.web.SessionAware = openerp.web.CallbackEnabled.extend(/** @lends openerp
*
* That will kill the widget in a clean way and erase its content from the dom.
*/
openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widget# */{
openerp.web.Widget = openerp.web.CallbackEnabled.extend(/** @lends openerp.web.Widget# */{
/**
* The name of the QWeb template that will be used for rendering. Must be
* redefined in subclasses or the default render() method can not be used.
@ -813,11 +792,16 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* @type string
*/
identifier_prefix: 'generic-identifier-',
/**
* Tag name when creating a default $element.
* @type string
*/
tag_name: 'div',
/**
* Construct the widget and set its parent if a parent is given.
*
* @constructs openerp.web.Widget
* @extends openerp.web.SessionAware
* @extends openerp.web.CallbackEnabled
*
* @param {openerp.web.Widget} parent Binds the current instance to the given Widget instance.
* When that widget is destroyed by calling stop(), the current instance will be
@ -828,13 +812,14 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* for new components this argument should not be provided any more.
*/
init: function(parent, /** @deprecated */ element_id) {
this._super((parent || {}).session);
this._super();
this.session = openerp.connection;
// if given an element_id, try to get the associated DOM element and save
// a reference in this.$element. Else just generate a unique identifier.
this.element_id = element_id;
this.element_id = this.element_id || _.uniqueId(this.identifier_prefix);
var tmp = document.getElementById(this.element_id);
this.$element = tmp ? $(tmp) : undefined;
this.$element = tmp ? $(tmp) : $(document.createElement(this.tag_name));
this.widget_parent = parent;
this.widget_children = [];
@ -889,8 +874,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
}, target);
},
_render_and_insert: function(insertion, target) {
var rendered = this.render();
this.$element = $(rendered);
this.render_element();
if (target instanceof openerp.web.Widget)
target = target.$element;
insertion(target);
@ -898,6 +882,15 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
return this.start();
},
on_inserted: function(element, widget) {},
/**
* Renders the element and insert the result of the render() method in this.$element.
*/
render_element: function() {
var rendered = this.render();
if (rendered || rendered === "")
this.$element = $(rendered);
return this;
},
/**
* Renders the widget using QWeb, `this.template` must be defined.
* The context given to QWeb contains the "widget" key that references `this`.
@ -905,7 +898,9 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
* @param {Object} additional Additional context arguments to pass to the template.
*/
render: function (additional) {
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
if (this.template)
return openerp.web.qweb.render(this.template, _.extend({widget: this}, additional || {}));
return false;
},
/**
* Method called after rendering. Mostly used to bind actions, perform asynchronous
@ -967,7 +962,7 @@ openerp.web.Widget = openerp.web.SessionAware.extend(/** @lends openerp.web.Widg
rpc: function(url, data, success, error) {
var def = $.Deferred().then(success, error);
var self = this;
this._super(url, data). then(function() {
openerp.connection.rpc(url, data). then(function() {
if (!self.widget_is_stopped)
def.resolve.apply(def, arguments);
}, function() {
@ -1047,6 +1042,8 @@ if ($.blockUI) {
$.blockUI.defaults.baseZ = 1100;
$.blockUI.defaults.message = '<img src="/web/static/src/img/throbber2.gif">';
}
/** Configure default qweb */
openerp.web._t = new openerp.web.TranslationDataBase().build_translation_function();
openerp.web.qweb = new QWeb2.Engine();
openerp.web.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
@ -1067,6 +1064,9 @@ openerp.web.qweb.format_text_node = function(s) {
return tr === ts ? s : tr;
}
/** Setup default connection */
openerp.connection = new openerp.web.Connection();
};
// vim:et fdc=0 fdl=0 foldnestmax=3 fdm=syntax:

View File

@ -32,7 +32,7 @@ openerp.web.DataGroup = openerp.web.Widget.extend( /** @lends openerp.web.DataG
* @constructs openerp.web.DataGroup
* @extends openerp.web.Widget
*
* @param {openerp.web.Session} session Current OpenERP session
* @param {openerp.web.Widget} parent widget
* @param {String} model name of the model managed by this DataGroup
* @param {Array} domain search domain for this DataGroup
* @param {Object} context context of the DataGroup's searches
@ -785,11 +785,15 @@ openerp.web.ProxyDataSet = openerp.web.DataSetSearch.extend({
on_unlink: function(ids) {}
});
openerp.web.Model = openerp.web.SessionAware.extend({
init: function(session, model_name) {
this._super(session);
openerp.web.Model = openerp.web.CallbackEnabled.extend({
init: function(_, model_name) {
this._super();
this.model_name = model_name;
},
rpc: function() {
var c = openerp.connection;
return c.rpc.apply(c, arguments);
},
get_func: function(method_name) {
var self = this;
return function() {

View File

@ -165,7 +165,11 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
}
var model = record['params']['model'],
prefix = record['params']['prefix'],
name = record['params']['name'];
name = record['params']['name'],
exclude_fields = [];
if (record['relation_field']) {
exclude_fields.push(record['relation_field']);
}
if (!record.loaded) {
var import_comp = self.$element.find("#import_compat").val();
@ -174,7 +178,8 @@ openerp.web.DataExport = openerp.web.Dialog.extend({
prefix: prefix,
parent_name: name,
import_compat: Boolean(import_comp),
parent_field_type : record['field_type']
parent_field_type : record['field_type'],
exclude: exclude_fields
}, function(results) {
record.loaded = true;
self.on_show_data(results, record.id);

View File

@ -433,6 +433,7 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
* @param view the ancestor view of this widget
*/
init: function (view) {
this._super(view);
this.view = view;
},
/**
@ -473,10 +474,8 @@ openerp.web.search.Widget = openerp.web.Widget.extend( /** @lends openerp.web.se
this._super();
},
render: function (defaults) {
return QWeb.render(
this.template, _.extend(this, {
defaults: defaults
}));
// FIXME
return this._super(_.extend(this, {defaults: defaults}));
}
});
openerp.web.search.add_expand_listener = function($root) {

View File

@ -10,6 +10,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
* view should be displayed (if there is one active).
*/
searchable: false,
readonly : false,
form_template: "FormView",
identifier_prefix: 'formview-',
/**
@ -37,7 +38,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.dirty_for_user = false;
this.default_focus_field = null;
this.default_focus_button = null;
this.registry = openerp.web.form.widgets;
this.registry = this.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
this.has_been_loaded = $.Deferred();
this.$form_header = null;
this.translatable_fields = [];
@ -101,10 +102,10 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.on_pager_action(action);
});
this.$form_header.find('button.oe_form_button_save').click(this.do_save);
this.$form_header.find('button.oe_form_button_cancel').click(this.do_cancel);
this.$form_header.find('button.oe_form_button_save').click(this.on_button_save);
this.$form_header.find('button.oe_form_button_new').click(this.on_button_new);
this.$form_header.find('button.oe_form_button_duplicate').click(this.on_button_duplicate);
this.$form_header.find('button.oe_form_button_delete').click(this.on_button_delete);
this.$form_header.find('button.oe_form_button_toggle').click(this.on_toggle_readonly);
if (this.options.sidebar && this.options.sidebar_id) {
@ -123,11 +124,16 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.widgets = {};
self.fields = {};
self.$form_header.find('button').unbind('click');
self.registry = self.registry === openerp.web.form.widgets
? openerp.web.form.readonly
: openerp.web.form.widgets;
self.readonly = !self.readonly;
self.registry = self.readonly ? openerp.web.form.readonly : openerp.web.form.widgets;
self.on_loaded(self.fields_view);
self.reload();
return self.reload();
},
do_set_readonly: function() {
return this.readonly ? $.Deferred().resolve() : this.on_toggle_readonly();
},
do_set_editable: function() {
return !this.readonly ? $.Deferred().resolve() : this.on_toggle_readonly();
},
do_show: function () {
var promise;
@ -164,6 +170,8 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.$form_header.find('.oe_form_on_update').show();
this.$form_header.find('button.oe_form_button_new').show();
}
this.$form_header.find('.oe_form_on_readonly').toggle(this.readonly);
this.$form_header.find('.oe_form_on_editable').toggle(!this.readonly);
this.dirty_for_user = false;
this.datarecord = record;
for (var f in this.fields) {
@ -189,7 +197,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.do_update_pager(record.id == null);
if (this.sidebar) {
this.sidebar.attachments.do_update();
this.sidebar.$element.find('.oe_sidebar_translate').toggleClass('oe_hide', !record.id);
}
if (this.default_focus_field && !this.embedded_view) {
this.default_focus_field.focus();
@ -287,7 +294,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return self.on_processed_onchange(response, processed);
});
} else {
console.log("Wrong on_change format", on_change);
console.warn("Wrong on_change format", on_change);
}
}
} catch(e) {
@ -338,20 +345,25 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
return $.Deferred().reject();
}
},
on_button_save: function() {
return this.do_save().then(this.do_set_readonly);
},
on_button_new: function() {
var self = this;
var def = $.Deferred();
$.when(this.has_been_loaded).then(function() {
if (self.can_be_discarded()) {
var keys = _.keys(self.fields_view.fields);
if (keys.length) {
self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
$.when(self.do_set_editable()).then(function() {
if (keys.length) {
self.dataset.default_get(keys).then(self.on_record_loaded).then(function() {
def.resolve();
});
} else {
self.on_record_loaded({});
def.resolve();
});
} else {
self.on_record_loaded({});
def.resolve();
}
}
});
}
});
return def.promise();
@ -363,7 +375,20 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (self.can_be_discarded()) {
self.dataset.call('copy', [self.datarecord.id, {}, self.dataset.context]).then(function(new_id) {
return self.on_created({ result : new_id });
}).then(function() {
}).then(self.do_set_editable).then(function() {
def.resolve();
});
}
});
return def.promise();
},
on_button_delete: function() {
var self = this;
var def = $.Deferred();
$.when(this.has_been_loaded).then(function() {
if (self.can_be_discarded() && self.datarecord.id) {
self.dataset.unlink([self.datarecord.id]).then(function() {
self.on_pager_action('next');
def.resolve();
});
}
@ -409,12 +434,18 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
self.on_invalid();
return $.Deferred().reject();
} else {
console.log("About to save", values);
if (!self.datarecord.id) {
openerp.log("FormView(", self, ") : About to create", values);
return self.dataset.create(values).pipe(function(r) {
return self.on_created(r, undefined, prepend_on_create);
}).then(success);
} else if (_.isEmpty(values)) {
openerp.log("FormView(", self, ") : Nothing to save");
if (success) {
success();
}
} else {
openerp.log("FormView(", self, ") : About to save", values);
return self.dataset.write(self.datarecord.id, values, {}).pipe(function(r) {
return self.on_saved(r);
}).then(success);
@ -428,10 +459,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
this.mutating_lock = this.mutating_lock.pipe(action, action);
return this.mutating_lock;
},
switch_readonly: function() {
},
switch_editable: function() {
},
on_invalid: function() {
var msg = "<ul>";
_.each(this.fields, function(f) {
@ -481,7 +508,7 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
if (this.sidebar) {
this.sidebar.attachments.do_update();
}
console.debug("The record has been created with id #" + this.datarecord.id);
openerp.log("The record has been created with id #" + this.datarecord.id);
this.reload();
return $.when(_.extend(r, {created: true})).then(success);
}
@ -489,9 +516,6 @@ openerp.web.FormView = openerp.web.View.extend( /** @lends openerp.web.FormView#
on_action: function (action) {
console.debug('Executing action', action);
},
do_cancel: function () {
console.debug("Cancelling form");
},
reload: function() {
var self = this;
var act = function() {
@ -678,7 +702,7 @@ openerp.web.form.compute_domain = function(expr, fields) {
stack.push(!_(val).contains(field_value));
break;
default:
console.log("Unsupported operator in modifiers :", op);
console.warn("Unsupported operator in modifiers :", op);
}
}
return _.all(stack, _.identity);
@ -1078,7 +1102,7 @@ openerp.web.form.WidgetLabel = openerp.web.form.Widget.extend({
var self = this;
this.$element.find("label").dblclick(function() {
var widget = self['for'] || self;
console.log(widget.element_class , widget);
openerp.log(widget.element_class , widget);
window.w = widget;
});
}

View File

@ -441,6 +441,16 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
}
}
var $res_logs = this.$element.find('.oe-view-manager-logs:first');
$res_logs.delegate('a.oe-more-logs', 'click', function () {
$res_logs.removeClass('oe-folded');
return false;
}).delegate('a.oe-remove-everything', 'click', function () {
$res_logs.removeClass('oe-has-more')
.find('ul').empty();
return false;
});
return manager_ready;
},
on_mode_switch: function (view_type) {
@ -518,10 +528,14 @@ session.web.ViewManagerAction = session.web.ViewManager.extend(/** @lends oepner
*/
do_display_log: function (log_records) {
var self = this,
$logs = this.$element.find('ul.oe-view-manager-logs:first').empty();
_(log_records).each(function (record) {
cutoff = 3,
$logs = this.$element.find('.oe-view-manager-logs:first')
.addClass('oe-folded'),
$logs_list = $logs.find('ul').empty();
$logs.toggleClass('oe-has-more', log_records.length > cutoff);
_(log_records.reverse()).each(function (record) {
$(_.sprintf('<li><a href="#">%s</a></li>', record.name))
.appendTo($logs)
.appendTo($logs_list)
.delegate('a', 'click', function (e) {
self.do_action({
type: 'ir.actions.act_window',
@ -564,36 +578,38 @@ session.web.Sidebar = session.web.Widget.extend({
},
add_default_sections: function() {
this.add_section(_t('Customize'), 'customize');
this.add_items('customize', [
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
classname: 'oe_hide oe_sidebar_edit_workflow'
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}
]);
if (this.session.uid === 1) {
this.add_section(_t('Customize'), 'customize');
this.add_items('customize', [
{
label: _t("Manage Views"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}, {
label: _t("Edit Workflow"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object"),
classname: 'oe_hide oe_sidebar_edit_workflow'
}, {
label: _t("Customize Object"),
callback: this.call_default_on_sidebar,
title: _t("Manage views of the current object")
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
title: _t("Technical translation")
}
]);
}
this.add_section(_t('Other Options'), 'other');
this.add_items('other', [
this.add_items('other', [
{
label: _t("Import"),
callback: this.call_default_on_sidebar
}, {
label: _t("Export"),
callback: this.call_default_on_sidebar
}, {
label: _t("Translate"),
callback: this.call_default_on_sidebar,
classname: 'oe_sidebar_translate oe_hide'
}, {
label: _t("View Log"),
callback: this.call_default_on_sidebar,
@ -619,14 +635,14 @@ session.web.Sidebar = session.web.Widget.extend({
}
});
},
add_section: function(name, code) {
if(!code) code = _.underscored(name);
var $section = this.sections[code];
if(!$section) {
section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
var $section = $(session.web.qweb.render("Sidebar.section", {
var section_id = _.uniqueId(this.element_id + '_section_' + code + '_');
$section = $(session.web.qweb.render("Sidebar.section", {
section_id: section_id,
name: name,
classname: 'oe_sidebar_' + code
@ -740,11 +756,6 @@ session.web.TranslateDialog = session.web.Dialog.extend({
this._super();
$.when(this.languages_loaded).then(function() {
self.$element.html(session.web.qweb.render('TranslateDialog', { widget: self }));
self.$element.tabs();
if (!(self.view.translatable_fields && self.view.translatable_fields.length)) {
self.hide_tabs('fields');
self.select_tab('view');
}
self.$fields_form = self.$element.find('.oe_translation_form');
self.$fields_form.find('.oe_trad_field').change(function() {
$(this).toggleClass('touched', ($(this).val() != $(this).attr('data-value')));
@ -787,21 +798,6 @@ session.web.TranslateDialog = session.web.Dialog.extend({
});
$.when.apply(null, deffered).then(callback);
},
show_tabs: function() {
for (var i = 0; i < arguments.length; i++) {
this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().show();
}
},
hide_tabs: function() {
for (var i = 0; i < arguments.length; i++) {
this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().hide();
}
},
select_tab: function(name) {
this.show_tabs(name);
var index = this.$element.find('ul.oe_translate_tabs li a[href$="' + arguments[i] + '"]').parent().index() - 1;
this.$element.tabs('select', index);
},
open: function(field) {
var self = this,
sup = this._super;
@ -810,7 +806,9 @@ session.web.TranslateDialog = session.web.Dialog.extend({
self.do_load_fields_values(function() {
sup.call(self);
if (field) {
// TODO: focus and scroll to field
var $field_input = self.$element.find('tr[data-field="' + field.name + '"] td:nth-child(2) *:first-child');
self.$element.scrollTo($field_input);
$field_input.focus();
}
});
} else {
@ -963,7 +961,15 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
export_view.start();
},
on_sidebar_translate: function() {
this.open_translate_dialog();
return this.do_action({
res_model : 'ir.translation',
domain : [['type', '!=', 'object'], '|', ['name', '=', this.dataset.model], ['name', 'ilike', this.dataset.model + ',']],
views: [[false, 'list'], [false, 'form']],
type : 'ir.actions.act_window',
auto_search : true,
view_type : "list",
view_mode : "list"
});
},
on_sidebar_view_log: function() {
}

View File

@ -457,7 +457,11 @@
</button>
</t>
<t t-jquery=".oe-view-manager-header" t-operation="after">
<ul class="oe-view-manager-logs"></ul>
<div class="oe-view-manager-logs oe-folded">
<ul></ul>
<a class="oe-more-logs" href="#">More…</a>
<a class="oe-remove-everything ui-icon ui-icon-closethick"/>
</div>
</t>
</t>
@ -473,8 +477,6 @@
<h2><t t-esc="name"/></h2>
</div>
</t>
<t t-name="Sidebar.section.items">
<li t-foreach="items" t-as="item" t-att-class="item.classname">
<a class="oe_sidebar_action_a" t-att-id="item.element_id" t-att-title="item.title" href="#">
@ -484,38 +486,25 @@
</t>
<t t-name="TranslateDialog">
<ul class="oe_translate_tabs">
<li><a t-attf-href="##{widget.element_id}_fields">Fields</a></li>
<li><a t-attf-href="##{widget.element_id}_view">View labels</a></li>
<li><a t-attf-href="##{widget.element_id}_sidebar">Sidebar Relates</a></li>
</ul>
<div t-attf-id="#{widget.element_id}_fields">
<table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="oe_form_separator" width="1%" nowrap="nowrap">
<div class="separator horizontal">Field</div>
</td>
<th t-foreach="widget.languages" align="left">
<div class="separator horizontal"><t t-esc="name"/></div>
</th>
</tr>
<tr t-foreach="widget.view.translatable_fields" t-as="field">
<td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
<label class="oe_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
<input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
</div>
<div t-attf-id="#{widget.element_id}_view">
Translate view
</div>
<div t-attf-id="#{widget.element_id}_sidebar">
Translate sidebar
</div>
<table t-if="widget.view.translatable_fields" class="oe_frame oe_forms oe_translation_form" border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td class="oe_form_separator" width="1%" nowrap="nowrap">
<div class="separator horizontal">Field</div>
</td>
<th t-foreach="widget.languages" align="left">
<div class="separator horizontal"><t t-esc="name"/></div>
</th>
</tr>
<tr t-foreach="widget.view.translatable_fields" t-as="field" t-att-data-field="field.name">
<td class="oe_form_frame_cell" width="1%" nowrap="nowrap">
<label class="oe_label"><t t-esc="field.string"/>:</label>
</td>
<td t-foreach="widget.languages" t-as="lg" class="oe_form_frame_cell">
<input t-if="field.type == 'char'" type="text" t-attf-name="#{lg.code}-#{field.name}" value="" data-value="" class="oe_trad_field" style="width: 100%"/>
<textarea t-if="field.type == 'text'" t-attf-name="#{lg.code}-#{field.name}" data-value="" class="oe_trad_field" style="width: 100%"></textarea>
</td>
</tr>
</table>
</t>
<t t-name="TreeView">
<select t-if="toolbar" style="width: 30%">
@ -551,6 +540,7 @@
</span>
</td>
</tr>
<table t-name="ListView" class="oe-listview-content">
<t t-set="columns_count" t-value="visible_columns.length + (options.selectable ? 1 : 0) + (options.deletable ? 1 : 0)"/>
<thead class="ui-widget-header">
@ -660,16 +650,18 @@
<t t-name="ListView.row.form">
<t t-raw="frame.render()"/>
</t>
<t t-name="FormView">
<div class="oe_form_header">
<div class="oe_form_buttons" t-if="widget.options.action_buttons !== false">
<button type="button" class="oe_form_button_save">
<span class="oe_form_on_update">Save</span>
<span class="oe_form_on_create">Create</span>
<button type="button" class="oe_form_button_save oe_form_on_editable">Save</button>
<button type="button" class="oe_form_button_toggle">
<span class="oe_form_on_editable">Cancel</span>
<span class="oe_form_on_readonly">Edit</span>
</button>
<button type="button" class="oe_form_button_new">New</button>
<button type="button" class="oe_form_button_duplicate oe_form_on_update">Duplicate</button>
<button type="button" class="oe_form_button_toggle">Readonly/Editable</button>
<button type="button" class="oe_form_button_new oe_form_on_readonly">Create</button>
<button type="button" class="oe_form_button_duplicate oe_form_on_readonly">Duplicate</button>
<button type="button" class="oe_form_button_delete oe_form_on_readonly">Delete</button>
</div>
<div class="oe_form_pager" t-if="widget.options.pager !== false">
<button type="button" data-pager-action="first">First</button>
@ -1010,10 +1002,11 @@
<span t-if="widget.string"><t t-esc="widget.string"/></span>
</button>
</t>
<t t-name="SearchView">
<form class="oe_forms">
<t t-call="SearchView.render_lines"/>
<div class="oe_search-view-buttons" style="text-align: right;">
<div class="oe_search-view-buttons">
<input type="submit" value="Search"/>
<input type="reset" value="Clear"/>
<button class="oe_search-view-custom-filter-btn"><span>Advanced Filter</span></button>

View File

@ -11,5 +11,8 @@
"css": ['static/lib/dhtmlxScheduler/codebase/dhtmlxscheduler.css',
'static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_ext.css'
],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True
}

View File

@ -0,0 +1,22 @@
# Arabic translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:38+0200\n"
"PO-Revision-Date: 2011-11-03 15:02+0000\n"
"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_calendar/static/src/xml/web_calendar.xml:0
msgid "&nbsp;"
msgstr "&nbsp;"

View File

@ -5,7 +5,6 @@
openerp.web_calendar = function(openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_calendar/static/src/xml/web_calendar.xml');
openerp.web.views.add('calendar', 'openerp.web_calendar.CalendarView');
openerp.web_calendar.CalendarView = openerp.web.View.extend({
// Dhtmlx scheduler ?

View File

@ -7,5 +7,8 @@
'static/src/js/dashboard.js'
],
"css": ['static/src/css/dashboard.css'],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True
}

View File

@ -0,0 +1,46 @@
# Arabic translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-03 15:09+0000\n"
"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "إستعادة"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "تراجع"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "أضف أداة"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "تغيير المخطط"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "اختر مخطط للعرض"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "التقدم:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr "%"

View File

@ -0,0 +1,46 @@
# Polish translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-04 16:28+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Reset"
msgstr "Przywróć"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Undo"
msgstr "Cofnij"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Add Widget"
msgstr "Dodaj kontrolkę"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Change layout"
msgstr "Zmień układ"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "Choose dashboard layout"
msgstr "Wybierz układ konsoli"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "progress:"
msgstr "postęp:"
#: addons/web_dashboard/static/src/xml/web_dashboard.xml:0
msgid "%"
msgstr ""

View File

@ -1,6 +1,5 @@
openerp.web_dashboard = function(openerp) {
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_dashboard/static/src/xml/web_dashboard.xml');
if (!openerp.web_dashboard) {
/** @namespace */

View File

@ -30,7 +30,7 @@
</t>
<t t-name="DashBoard.action">
<div t-att-data-id="action.attrs.name" class="oe-dashboard-action">
<h2 t-attf-class="oe-dashboard-action-header oe_view_title #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
<h2 t-attf-class="oe-dashboard-action-header #{action.attrs.string ? '' : 'oe-dashboard-action-header-empty'}">
<input class="oe-dashboard-action-input" type="text" name="title" value="" style="display: none"/>
<t t-esc="action.attrs.string"/>
<t t-if="!action.attrs.string">&amp;nbsp;</t>

View File

@ -0,0 +1,38 @@
# Arabic translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-08 05:50+0000\n"
"Last-Translator: Ahmad Khayyat <Unknown>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
msgstr "أهلاً و مرحباً بك في OpenERP"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Remember to bookmark this page."
msgstr "لا تنس إدراج هذه الصفحة ضمن المفضلات"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Remember your login:"
msgstr "تذكر كلمة المرور"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Choose the first OpenERP Application you want to install.."
msgstr "اختر أول تطبيق OpenERP تود تثبيته"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Install"
msgstr "تثبيت"

View File

@ -0,0 +1,38 @@
# Polish translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-04 16:30+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Welcome to your new OpenERP instance."
msgstr "Witamy w twojej nowej instancji OpenERP."
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Remember to bookmark this page."
msgstr "Pamiętaj o dodaniu tej strony do zakładek."
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Remember your login:"
msgstr "Zapamiętaj twój login:"
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Choose the first OpenERP Application you want to install.."
msgstr "Wybierz pierwszą aplikację OpenERP do instalacji."
#: addons/web_default_home/static/src/xml/web_default_home.xml:0
msgid "Install"
msgstr "Instaluj"

View File

@ -13,5 +13,8 @@
'css' : [
"static/src/css/base_diagram.css",
],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True,
}

View File

@ -0,0 +1,54 @@
# Arabic translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-03 15:11+0000\n"
"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "طرف جديد"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr "حافة جديدة"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr "عرض الشبكة"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "الأول"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr "0"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr "/"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ">>"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "الأخير"

View File

@ -8,14 +8,14 @@ msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-10-11 14:05+0000\n"
"PO-Revision-Date: 2011-11-08 21:59+0000\n"
"Last-Translator: Jonas Mortensen <Unknown>\n"
"Language-Team: Danish <da@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-01 05:10+0000\n"
"X-Generator: Launchpad (build 14197)\n"
"X-Launchpad-Export-Date: 2011-11-09 05:09+0000\n"
"X-Generator: Launchpad (build 14263)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
@ -23,7 +23,7 @@ msgstr "Ny tilstand"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr ""
msgstr "Ny kant"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"

View File

@ -0,0 +1,54 @@
# Polish translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-04 16:24+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Node"
msgstr "Nowy węzeł"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "New Edge"
msgstr "Nowa linia"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Show Grid:"
msgstr "Pokaż siatkę"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "First"
msgstr "Pierwsze"
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "<<"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "0"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "/"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid ">>"
msgstr ""
#: addons/web_diagram/static/src/xml/base_diagram.xml:0
msgid "Last"
msgstr "Ostatnie"

View File

@ -4,7 +4,6 @@
openerp.web_diagram = function (openerp) {
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_diagram/static/src/xml/base_diagram.xml');
openerp.web.views.add('diagram', 'openerp.web.DiagramView');
openerp.web.DiagramView = openerp.web.View.extend({
searchable: false,

View File

@ -9,5 +9,8 @@
'static/src/js/gantt.js'
],
"css": ['static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css'],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True
}

View File

@ -4,8 +4,6 @@
openerp.web_gantt = function (openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_gantt/static/src/xml/web_gantt.xml');
openerp.web.views.add('gantt', 'openerp.web_gantt.GanttView');
openerp.web_gantt.GanttView = openerp.web.View.extend({

View File

@ -7,5 +7,8 @@
"static/lib/dhtmlxGraph/codebase/dhtmlxchart_debug.js",
"static/src/js/graph.js"],
"css": ["static/lib/dhtmlxGraph/codebase/dhtmlxchart.css"],
'qweb' : [
"static/src/xml/*.xml",
],
"active": True
}

View File

@ -13,7 +13,6 @@ var COLOR_PALETTE = [
'#cc0000', '#d400a8'];
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_graph/static/src/xml/web_graph.xml');
openerp.web.views.add('graph', 'openerp.web_graph.GraphView');
openerp.web_graph.GraphView = openerp.web.View.extend({

View File

@ -9,5 +9,8 @@
"css": [
"static/src/css/kanban.css"
],
'qweb' : [
"static/src/xml/*.xml",
],
'active': True
}

View File

@ -1,37 +1,71 @@
.openerp .oe_kanban_view .oe_column {
width: 100%;
}
.openerp .oe_vertical_text {
writing-mode:tb-rl;
-webkit-transform:rotate(90deg);
-moz-transform:rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
display:block;
width:30px;
height:20px;
align:center;
font-size:24px;
white-space: nowrap;
}
.openerp .oe_kanban_view .ui-sortable-placeholder {
border: 1px dotted black;
visibility: visible !important;
height: 60px !important;
}
.openerp .oe_kanban_group_header {
position: relative;
}
.openerp .oe_kanban_group_folded {
padding: 0 5px 0 5px;
}
.openerp .oe_kanban_group_folded .oe_kanban_group_title,
.openerp .oe_kanban_group_folded .oe_kanban_aggregates {
display: none;
}
.openerp .oe_kanban_group_folded .oe_kanban_group_title_vertical {
display: block;
}
.openerp .oe_kanban_view .oe_column_heading {
.openerp .oe_kanban_group_title {
color: #000000;
font-size: 130%;
font-weight: bold;
}
.openerp .oe_kanban_view .fold-columns-icon {
.openerp .oe_kanban_group_title_undefined {
color: #666666;
}
.openerp .oe_kanban_group_title_vertical {
writing-mode: tb-rl;
-webkit-transform: rotate(90deg);
-moz-transform: rotate(90deg);
-o-transform: rotate(90deg);
-ms-transform: rotate(90deg);
transform: rotate(90deg);
width: 30px;
height: 20px;
align: center;
font-size: 24px;
white-space: nowrap;
display: none;
position: absolute;
top: 10px;
}
.openerp .oe_kanban_fold_icon {
cursor: pointer;
float: left;
padding: 2px 2px 0 0;
width: 16px;
height: 16px;
background: url(/web_kanban/static/src/img/minus-icon.png) no-repeat;
}
.openerp .oe_kanban_group_folded .oe_kanban_fold_icon {
background: url(/web_kanban/static/src/img/plus-icon.png) no-repeat;
}
.openerp ul.oe_kanban_aggregates {
padding: 0;
margin: 0 0 0 22px;
}
.openerp ul.oe_kanban_aggregates li {
list-style: circle;
font-style: italic;
}
.openerp ul.oe_kanban_aggregates span {
text-decoration: underline;
}
.openerp .oe_kanban_action_button {
height: 22px;
margin: 0;
@ -244,7 +278,18 @@
border-color: #D979C1;
}
/* Alert color */
.openerp .oe_kanban_color_alert .oe_kanban_color_border {
/* Red border */
.openerp .oe_kanban_color_alert .oe_kanban_color_border,
.openerp .oe_kanban_color_red .oe_kanban_color_border {
border-color: #c00 !important;
}
/* Green border */
.openerp .oe_kanban_color_green .oe_kanban_color_border {
border-color: #0c0 !important;
}
/* Blue border */
.openerp .oe_kanban_color_blue .oe_kanban_color_border {
border-color: #00c !important;
}

View File

@ -1,48 +1,59 @@
openerp.web_kanban = function (openerp) {
var _t = openerp.web._t;
var QWeb = openerp.web.qweb;
QWeb.add_template('/web_kanban/static/src/xml/web_kanban.xml');
openerp.web.views.add('kanban', 'openerp.web_kanban.KanbanView');
openerp.web_kanban.KanbanView = openerp.web.View.extend({
template: "KanbanView",
default_nr_columns: 3,
init: function (parent, dataset, view_id, options) {
this._super(parent);
this.set_default_options(options);
this.dataset = dataset;
this.model = dataset.model;
this.view_id = view_id;
this.fields_view = {};
this.group_by = [];
this.source_index = {};
this.all_display_data = false;
this.fields_keys = [];
this.group_by = null;
this.state = {
groups : {},
records : {}
};
this.groups = [];
this.qweb = new QWeb2.Engine();
this.qweb.debug = (window.location.search.indexOf('?debug') !== -1);
this.aggregates = {};
this.NO_OF_COLUMNS = 3;
this.form_dialog = new openerp.web.FormDialog(this, {}, this.options.action_views_ids.form, dataset).start();
this.form_dialog.on_form_dialog_saved.add_last(this.on_record_saved);
this.form_dialog.on_form_dialog_saved.add_last(this.do_reload);
this.aggregates = {};
this.qweb = new QWeb2.Engine();
this.qweb.debug = openerp.connection.debug;
this.qweb.default_dict = {
'_' : _,
'_t' : _t
}
this.has_been_loaded = $.Deferred();
this.search_domain = this.search_context = this.search_group_by = null;
this.currently_dragging = {};
},
start: function() {
this._super();
return this.rpc("/web/view/load", {"model": this.model, "view_id": this.view_id, "view_type": "kanban"}, this.on_loaded);
this.$element.find('button.oe_kanban_button_new').click(this.do_add_record);
this.$groups = this.$element.find('.oe_kanban_groups tr');
var context = new openerp.web.CompoundContext(this.dataset.get_context());
return this.rpc('/web/view/load', {
'model': this.dataset.model,
'view_id': this.view_id,
'view_type': 'kanban',
context: context
}, this.on_loaded);
},
on_loaded: function(data) {
var self = this;
this.fields_view = data;
this.fields_keys = _.keys(this.fields_view.fields);
this.add_qweb_template();
this.has_been_loaded.resolve();
},
add_qweb_template: function() {
var group_operator = ["avg", "max", "min", "sum", "count"]
for (var i=0, ii=this.fields_view.arch.children.length; i < ii; i++) {
var child = this.fields_view.arch.children[i];
if (child.tag === "field") {
for(j=0, jj=group_operator.length; j < jj; j++) {
if (child.attrs[group_operator[j]]) {
this.aggregates[child.attrs.name] = child.attrs[group_operator[j]];
break;
}
}
}
if (child.tag === "templates") {
this.transform_qweb_template(child);
this.qweb.add_template(openerp.web.json_node_to_xml(child));
@ -50,15 +61,421 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
}
}
},
get_qweb_context: function(record) {
return {
record: this.do_transform_record(record),
kanban_color: _.bind(this.kanban_color, this),
kanban_gravatar: _.bind(this.kanban_gravatar, this),
kanban_image: _.bind(this.kanban_image, this),
kanban_text_ellipsis: _.bind(this.kanban_text_ellipsis, this),
'_' : _
transform_qweb_template: function(node) {
var qweb_prefix = QWeb.prefix,
group_operator = ['avg', 'max', 'min', 'sum', 'count'];
switch (node.tag) {
case 'field':
node.tag = qweb_prefix;
node.attrs[qweb_prefix + '-esc'] = 'record.' + node.attrs['name'] + '.value';
for (var j = 0, jj = group_operator.length; j < jj; j++) {
if (node.attrs[group_operator[j]]) {
this.aggregates[node.attrs.name] = node.attrs[group_operator[j]];
break;
}
}
break
case 'button':
case 'a':
var type = node.attrs.type || '';
if (_.indexOf('action,object,edit,delete,color'.split(','), type) !== -1) {
_.each(node.attrs, function(v, k) {
if (_.indexOf('icon,type,name,string,context,states,kanban_states'.split(','), k) != -1) {
node.attrs['data-' + k] = v;
delete(node.attrs[k]);
}
});
if (node.attrs['data-states']) {
var states = _.map(node.attrs['data-states'].split(','), function(state) {
return "record.state.raw_value == '" + _.trim(state) + "'";
});
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
}
if (node.attrs['data-kanban_states']) {
var states = _.map(node.attrs['data-kanban_states'].split(','), function(state) {
return "record.kanban_state.raw_value == '" + _.trim(state) + "'";
});
node.attrs[qweb_prefix + '-if'] = states.join(' or ');
}
if (node.attrs['data-string']) {
node.attrs.title = node.attrs['data-string'];
}
if (node.attrs['data-icon']) {
node.children = [{
tag: 'img',
attrs: {
src: '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png',
width: '16',
height: '16'
}
}];
}
if (node.tag == 'a') {
node.attrs.href = '#';
} else {
node.attrs.type = 'button';
}
node.attrs['class'] = (node.attrs['class'] || '') + ' oe_kanban_action oe_kanban_action_' + node.tag;
}
break;
}
if (node.children) {
for (var i = 0, ii = node.children.length; i < ii; i++) {
this.transform_qweb_template(node.children[i]);
}
}
},
do_add_record: function() {
this.dataset.index = null;
this.do_switch_view('form');
},
do_search: function(domain, context, group_by) {
var self = this;
this.search_domain = domain;
this.search_context = context;
this.search_group_by = group_by;
$.when(this.has_been_loaded).then(function() {
self.group_by = group_by.length ? group_by[0] : self.fields_view.arch.attrs.default_group_by;
self.datagroup = new openerp.web.DataGroup(self, self.dataset.model, domain, context, self.group_by ? [self.group_by] : []);
self.datagroup.list(self.fields_keys, self.do_process_groups, self.do_process_dataset);
});
},
do_process_groups: function(groups) {
this.do_clear_groups();
this.dataset.ids = [];
var self = this,
remaining = groups.length - 1,
groups_array = [];
_.each(groups, function (group, index) {
var group_name = group.value,
group_value = group.value,
group_aggregates = {};
if (group.value instanceof Array) {
group_name = group.value[1];
group_value = group.value[0];
}
_.each(self.aggregates, function(value, key) {
group_aggregates[value] = group.aggregates[key];
});
var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
dataset.read_slice(self.fields_keys, {'domain': group.domain, 'context': group.context}, function(records) {
self.dataset.ids.push.apply(self.dataset.ids, dataset.ids);
groups_array[index] = new openerp.web_kanban.KanbanGroup(self, records, group_value, group_name, group_aggregates);
if (!remaining--) {
self.dataset.index = self.dataset.ids.length ? 0 : null;
self.do_add_groups(groups_array);
}
});
});
},
do_process_dataset: function(dataset) {
var self = this;
this.do_clear_groups();
this.dataset.read_slice(this.fields_keys, {}, function(records) {
var groups = [];
while (records.length) {
for (var i = 0; i < self.default_nr_columns; i++) {
if (!groups[i]) {
groups[i] = [];
}
groups[i].push(records.shift());
}
}
for (var i = 0; i < groups.length; i++) {
groups[i] = new openerp.web_kanban.KanbanGroup(self, _.compact(groups[i]));
}
self.do_add_groups(groups);
});
},
do_reload: function() {
this.do_search(this.search_domain, this.search_context, this.search_group_by);
},
do_clear_groups: function() {
_.each(this.groups, function(group) {
group.stop();
});
this.groups = [];
this.$element.find('.oe_kanban_groups_headers, .oe_kanban_groups_records').empty();
},
do_add_groups: function(groups) {
var self = this;
_.each(groups, function(group) {
self.groups[group.undefined_title ? 'unshift' : 'push'](group);
});
_.each(this.groups, function(group) {
group.appendTo(self.$element.find('.oe_kanban_groups_headers'));
});
this.on_groups_started();
},
on_groups_started: function() {
var self = this;
this.compute_groups_width();
if (this.group_by) {
this.$element.find('.oe_kanban_column').sortable({
connectWith: '.oe_kanban_column',
handle : '.oe_kanban_draghandle',
start: function(event, ui) {
self.currently_dragging.index = ui.item.index();
self.currently_dragging.group = ui.item.parents('.oe_kanban_column:first').data('widget');
},
stop: function(event, ui) {
var record = ui.item.data('widget'),
old_index = self.currently_dragging.index,
new_index = ui.item.index(),
old_group = self.currently_dragging.group,
new_group = ui.item.parents('.oe_kanban_column:first').data('widget');
if (!(old_group.title === new_group.title && old_group.value === new_group.value && old_index == new_index)) {
self.on_record_moved(record, old_group, old_index, new_group, new_index);
}
},
scroll: false
});
} else {
this.$element.find('.oe_kanban_draghandle').removeClass('oe_kanban_draghandle');
}
},
on_record_moved : function(record, old_group, old_index, new_group, new_index) {
if (old_group === new_group) {
new_group.records.splice(old_index, 1);
new_group.records.splice(new_index, 0, record);
new_group.do_save_sequences();
} else {
old_group.records.splice(old_index, 1);
new_group.records.splice(new_index, 0, record);
record.group = new_group;
var data = {};
data[this.group_by] = new_group.value;
this.dataset.write(record.id, data, {}, function() {
record.do_reload();
new_group.do_save_sequences();
});
}
},
do_show: function () {
this.$element.show();
},
do_hide: function () {
this.$element.hide();
},
compute_groups_width: function() {
var unfolded = 0;
_.each(this.groups, function(group) {
unfolded += group.state.folded ? 0 : 1;
group.$element.css('width', '');
});
_.each(this.groups, function(group) {
if (!group.state.folded) {
group.$element.css('width', Math.round(100/unfolded) + '%');
}
});
}
});
openerp.web_kanban.KanbanGroup = openerp.web.Widget.extend({
template: 'KanbanView.group_header',
init: function (parent, records, value, title, aggregates) {
var self = this;
this._super(parent);
this.view = parent;
this.value = value;
this.title = title;
if (title === false) {
this.title = _t('Undefined');
this.undefined_title = true;
}
this.aggregates = aggregates || {};
var key = this.view.group_by + '-' + value;
if (!this.view.state.groups[key]) {
this.view.state.groups[key] = {
folded: false
}
}
this.state = this.view.state.groups[key];
this.$records = null;
this.records = _.map(records, function(record) {
return new openerp.web_kanban.KanbanRecord(self, record);
});
},
start: function() {
var self = this,
def = this._super();
this.$records = $(QWeb.render('KanbanView.group_records_container', { widget : this}));
this.$records.appendTo(this.view.$element.find('.oe_kanban_groups_records'));
_.each(this.records, function(record) {
record.appendTo(self.$records);
});
this.$element.find(".oe_kanban_fold_icon").click(function() {
self.do_toggle_fold();
self.view.compute_groups_width();
return false;
});
if (this.state.folded) {
this.do_toggle_fold();
}
this.$element.data('widget', this);
this.$records.data('widget', this);
return def;
},
stop: function() {
this._super();
if (this.$records) {
this.$records.remove();
}
},
remove_record: function(id, remove_from_dataset) {
for (var i = 0, ii = this.records.length; i < ii; i++) {
if (this.records[i]['id'] === id) {
this.records.splice(i, 1);
}
}
},
do_toggle_fold: function(compute_width) {
this.$element.toggleClass('oe_kanban_group_folded');
this.$records.find('.oe_kanban_record').toggle();
this.state.folded = this.$element.is('.oe_kanban_group_folded');
},
do_save_sequences: function() {
var self = this;
if (_.indexOf(this.view.fields_keys, 'sequence') > -1) {
_.each(this.records, function(record, index) {
self.view.dataset.write(record.id, { sequence : index });
});
}
}
});
openerp.web_kanban.KanbanRecord = openerp.web.Widget.extend({
template: 'KanbanView.record',
init: function (parent, record) {
this._super(parent);
this.group = parent;
this.view = parent.view;
this.id = null;
this.set_record(record);
if (!this.view.state.records[this.id]) {
this.view.state.records[this.id] = {
folded: false
};
}
this.state = this.view.state.records[this.id];
},
set_record: function(record) {
this.id = record.id;
this.record = this.transform_record(record);
},
start: function() {
this._super();
this.$element.data('widget', this);
this.bind_events();
},
transform_record: function(record) {
var self = this,
new_record = {};
_.each(record, function(value, name) {
var r = _.clone(self.view.fields_view.fields[name]);
r.raw_value = value;
r.value = openerp.web.format_value(value, r);
new_record[name] = r;
});
return new_record;
},
render: function() {
var ctx = {
record: this.record,
widget: this
}
for (var p in this) {
if (_.startsWith(p, 'kanban_')) {
ctx[p] = _.bind(this[p], this);
}
}
return this._super({
'content': this.view.qweb.render('kanban-box', ctx)
});
},
bind_events: function() {
var self = this,
$show_on_click = self.$element.find('.oe_kanban_box_show_onclick');
$show_on_click.toggle(this.state.folded);
this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() {
$show_on_click.toggle();
self.state.folded = !self.state.folded;
});
this.$element.find('.oe_kanban_action').click(function() {
var $action = $(this),
type = $action.data('type') || 'button',
method = 'do_action_' + type;
if (typeof self[method] === 'function') {
self[method]($action);
} else {
self.do_warn("Kanban: no action for type : " + type);
}
return false;
});
},
do_action_delete: function($action) {
var self = this;
if (confirm(_t("Are you sure you want to delete this record ?"))) {
return $.when(this.view.dataset.unlink([this.id])).then(function() {
self.group.remove_record(self.id)
self.stop();
});
}
},
do_action_edit: function($action) {
var self = this;
if ($action.attr('target') === 'dialog') {
this.view.form_dialog.select_id(this.id).then(function() {
self.view.form_dialog.open();
});
} else {
if (self.view.dataset.select_id(this.id)) {
this.view.do_switch_view('form');
} else {
this.do_warn("Kanban: could not find id#" + id);
}
}
},
do_action_color: function($action) {
var self = this,
colors = '#FFFFFF,#CCCCCC,#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','),
$cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 }));
$action.after($cpicker);
$cpicker.mouseenter(function() {
clearTimeout($cpicker.data('timeoutId'));
}).mouseleave(function(evt) {
var timeoutId = setTimeout(function() { $cpicker.remove() }, 500);
$cpicker.data('timeoutId', timeoutId);
});
$cpicker.find('a').click(function() {
var data = {};
data[$action.data('name')] = $(this).data('color');
self.view.dataset.write(self.id, data, {}, function() {
self.record[$action.data('name')] = $(this).data('color');
self.do_reload();
});
$cpicker.remove();
return false;
});
},
do_action_object: function ($action) {
var button_attrs = $action.data();
this.view.do_execute_action(button_attrs, this.view.dataset, this.id, this.do_reload);
},
do_reload: function() {
var self = this;
this.view.dataset.read_ids([this.id], this.view.fields_keys, function(records) {
if (records.length) {
self.set_record(records[0]);
self.do_render();
} else {
self.stop();
}
});
},
do_render: function() {
this.$element.html(this.render());
this.bind_events();
},
kanban_color: function(variable) {
var number_of_color_schemes = 10,
@ -93,410 +510,6 @@ openerp.web_kanban.KanbanView = openerp.web.View.extend({
return '';
}
return s.substr(0, size) + '...';
},
transform_qweb_template: function(node) {
var qweb_prefix = QWeb.prefix;
switch (node.tag) {
case 'field':
node.tag = 't';
node.attrs['t-esc'] = 'record.' + node.attrs['name'] + '.value';
break
case 'button':
case 'a':
var type = node.attrs.type || '';
if (_.indexOf('action,object,edit,delete,color'.split(','), type) !== -1) {
_.each(node.attrs, function(v, k) {
if (_.indexOf('icon,type,name,string,context,states'.split(','), k) != -1) {
node.attrs['data-' + k] = v;
delete(node.attrs[k]);
}
});
if (node.attrs['data-states']) {
var states = _.map(node.attrs['data-states'].split(','), function(state) {
return "record.state.raw_value == '" + _.trim(state) + "'";
});
node.attrs['t-if'] = states.join(' or ');
}
if (node.attrs['data-string']) {
node.attrs.title = node.attrs['data-string'];
}
if (node.attrs['data-icon']) {
node.children = [{
tag: 'img',
attrs: {
src: '/web/static/src/img/icons/' + node.attrs['data-icon'] + '.png',
width: '16',
height: '16'
}
}];
}
if (node.tag == 'a') {
node.attrs.href = '#';
} else {
node.attrs.type = 'button';
}
node.attrs['class'] = (node.attrs['class'] || '') + ' oe_kanban_action oe_kanban_action_' + node.tag;
}
break;
}
if (node.children) {
for (var i = 0, ii = node.children.length; i < ii; i++) {
this.transform_qweb_template(node.children[i]);
}
}
},
on_show_data: function() {
var self = this;
if (!this.group_by.length) {
this.do_record_group();
}
this.$element.html(QWeb.render("KanbanView", {"data": self.all_display_data}));
this.on_reload_kanban();
this.$element.find(".oe_vertical_text").hide();
var drag_handel = false;
if (this.$element.find(".oe_kanban_draghandle").length > 0) {
drag_handel = ".oe_kanban_draghandle";
}
if (!this.group_by.length) {
drag_handel = true;
}
this.$element.find(".oe_column").sortable({
connectWith: ".oe_column",
handle : drag_handel,
start: function(event, ui) {
self.source_index['index'] = ui.item.index();
self.source_index['column'] = ui.item.parent().attr('id');
},
stop: self.on_receive_record,
scroll: false
});
this.$element.find('button.oe_kanban_button_new').click(this.do_add_record);
this.$element.find(".fold-columns-icon").click(function(event) {
self.do_fold_unfold_columns(event, this.id);
});
},
do_fold_unfold_columns: function(event, element_id) {
var column_id = "column_" + element_id;
var column_element = this.$element.find("#" + column_id + " .oe_fold_column");
if (column_element.is(":hidden")) {
this.$element.find("#" + column_id).find("img.fold-columns-icon").attr('src', '/web_kanban/static/src/img/minus-icon.png');
column_element.show();
this.$element.find("#" + column_id + ".oe_table_column").css("width",Math.round(99 / this.all_display_data.length) + "%");
this.$element.find("#" + column_id + ".oe_vertical_text").hide();
}
else{
this.$element.find("#" + column_id).find("img.fold-columns-icon").attr('src', '/web_kanban/static/src/img/plus-icon.png');
column_element.hide();
this.$element.find("#" + column_id + ".oe_table_column").css("width","0.5%");
this.$element.find("#" + column_id + ".oe_vertical_text").show();
}
},
do_record_group: function() {
if (this.NO_OF_COLUMNS && this.all_display_data.length > 0) {
var records = this.all_display_data[0].records;
var record_per_group = Math.round((records).length / this.NO_OF_COLUMNS);
this.all_display_data = [];
for (var i=0, ii=this.NO_OF_COLUMNS; i < ii; i++) {
this.all_display_data.push({'records': records.slice(0,record_per_group), 'value':i, 'header' : false, 'ids':[]});
records.splice(0,record_per_group);
}
}
},
on_button_click: function (button_attrs, record_id) {
this.on_execute_button_click(this.dataset, button_attrs, record_id);
},
do_add_record: function() {
this.dataset.index = null;
this.do_switch_view('form');
},
do_edit_record: function(record_id) {
var self = this;
this.form_dialog.select_id(record_id).then(function() {
self.form_dialog.open();
});
},
on_record_saved: function(r) {
var id = this.form_dialog.form.datarecord.id;
this.on_reload_record(id);
},
do_change_color: function(record_id, $e) {
var self = this,
id = record_id,
colors = '#FFFFFF,#CCCCCC,#FFC7C7,#FFF1C7,#E3FFC7,#C7FFD5,#C7FFFF,#C7D5FF,#E3C7FF,#FFC7F1'.split(','),
$cpicker = $(QWeb.render('KanbanColorPicker', { colors : colors, columns: 2 }));
$e.after($cpicker);
$cpicker.mouseenter(function() {
clearTimeout($cpicker.data('timeoutId'));
}).mouseleave(function(evt) {
var timeoutId = setTimeout(function() { $cpicker.remove() }, 500);
$cpicker.data('timeoutId', timeoutId);
});
$cpicker.find('a').click(function(evt) {
var data = {};
data[$e.data('name')] = $(this).data('color');
self.dataset.write(id, data, {}, function() {
self.on_reload_record(id);
});
$cpicker.remove();
return false;
});
},
/**
Reload one record in view.
record_id : reload record id.
*/
on_reload_record: function (record_id){
var self = this;
this.dataset.read_ids([record_id], _.keys(self.fields_view.fields), function (records) {
if (records.length > 0) {
for (var i=0, ii=self.all_display_data.length; i < ii; i++) {
for(j=0, jj=self.all_display_data[i].records.length; j < jj; j++) {
if (self.all_display_data[i].records[j].id == record_id) {
_.extend(self.all_display_data[i].records[j], records[0]);
self.$element.find("#main_" + record_id).children().remove();
self.$element.find("#main_" + record_id).append(
self.qweb.render('kanban-box', self.get_qweb_context(self.all_display_data[i].records[j]))
);
break;
}
}
}
self.$element.find("#main_" + record_id + " .oe_kanban_action").click(self.on_action_clicked);
self.$element.find("#main_" + record_id + " .oe_kanban_box_show_onclick_trigger").click(function() {
$(this).parent("#main_" + record_id + " .oe_kanban_box").find(".oe_kanban_box_show_onclick").toggle();
});
}
});
},
do_delete: function (id) {
var self = this;
return $.when(this.dataset.unlink([id])).then(function () {
self.drop_records(id);
});
},
drop_records: function (id) {
var self = this;
_.each(self.all_display_data, function(data, index) {
_.each(data.records, function(record, index_row) {
if (parseInt(record.id) == id) {
self.all_display_data[index]['records'].splice(index_row, 1);
self.all_display_data[index]['ids'].splice(index_row, 1);
return false;
}
});
});
self.$element.find("#main_" + id).remove();
},
on_execute_button_click: function (dataset, button_attrs, record_id) {
var self = this;
this.do_execute_action(
button_attrs, dataset,
record_id, function () {
self.on_reload_record(record_id);
}
);
},
on_receive_record: function (event, ui) {
var self = this;
var from = ui.item.index();
var search_action = false;
var to = ui.item.prev().index() || 0;
if (!ui.item.attr("id")) {
return false;
}
if (self.fields_view.fields.sequence != undefined && ((self.source_index.index >= 0 && self.source_index.index != from) ||
(self.source_index.column && self.source_index.column != ui.item.parent().attr('id')))) {
var child_record = ui.item.parent().children();
var data, sequence = 1, index = to;
child_record.splice(0, to);
var flag = false;
if (to >= 0 && child_record) {
var record_id = parseInt($(child_record).attr("id").split("_")[1]);
if (record_id) {
_.each(self.all_display_data, function(data, index) {
_.each(data.records, function(record, index_row) {
if(record_id == record.id && record.sequence) {
sequence = record.sequence;
flag = true;
return false;
}
});
if(flag) {return false;}
});
}
}
_.each(child_record, function (child) {
var child_id = parseInt($(child).attr("id").split("_")[1]);
if (child_id) {
flag = false;
_.each(self.all_display_data, function(data, index) {
_.each(data.records, function(record, index_row) {
if(parseInt(record.id) == child_id) {
self.all_display_data[index]['records'][index_row]['sequence'] = sequence;
flag = true;
return false;
}
});
if (flag) {return false;}
});
self.dataset.write(child_id, {sequence: sequence});
sequence++;
search_action = true;
}
});
}
if (self.group_by.length > 0 && self.source_index.column && self.source_index.column != ui.item.parent().attr('id')) {
var value = ui.item.closest("td").attr("id");
if (value) {
var data_val = {};
var wirte_id = parseInt(ui.item.attr("id").split("_")[1]);
value = value.split("_")[1];
if (value == 'false') {
value = false;
}
var update_record = false;
_.each(self.all_display_data, function(data, index) {
_.each(data.records, function(record, index_row) {
if(parseInt(record.id) == wirte_id) {
self.all_display_data[index]['records'][index_row][self.group_by[0]] = value;
update_record = self.all_display_data[index]['records'].splice(index_row,1)
return false;
}
});
if (update_record) {return false;}
});
_.each(self.all_display_data, function(data, index) {
if (data.value == value || (data.value == 'false' && value == false)) {
self.all_display_data[index]['records'].push(update_record[0]);
}
});
data_val[self.group_by[0]] = value;
self.dataset.write(wirte_id, data_val);
search_action = true;
}
}
if (search_action) {
self.on_reload_kanban();
}
this.source_index = {};
},
on_reload_kanban: function() {
var self = this;
_.each(self.all_display_data, function(data, index) {
if (data.records.length > 0){
_.each(data.records, function(record) {
self.$element.find("#main_" + record.id).children().remove();
self.$element.find("#main_" + record.id).append(
self.qweb.render('kanban-box', self.get_qweb_context(record))
);
});
}
});
this.$element.find('.oe_kanban_action').click(this.on_action_clicked);
this.$element.find('.oe_kanban_box_show_onclick_trigger').click(function() {
$(this).parent('.oe_kanban_box').find('.oe_kanban_box_show_onclick').toggle();
});
},
on_action_clicked: function(evt) {
evt.preventDefault();
var $action = $(evt.currentTarget),
record_id = parseInt($action.closest(".oe_kanban_record").attr("id").split('_')[1]),
type = $action.data('type');
if (type == 'delete') {
this.do_delete(record_id);
} else if (type == 'edit') {
this.do_edit_record(record_id);
} else if (type == 'color') {
this.do_change_color(record_id, $action);
} else {
var button_attrs = $action.data();
this.on_button_click(button_attrs, record_id);
}
},
do_transform_record: function(record) {
var self = this,
new_record = {};
_.each(record, function(value, name) {
var r = _.clone(self.fields_view.fields[name]);
r.raw_value = value;
r.value = openerp.web.format_value(value, r);
new_record[name] = r;
});
return new_record;
},
do_search: function (domain, context, group_by) {
var self = this;
self.group_by = group_by;
var self = this,
group_by = self.group_by;
if (!group_by.length && this.fields_view.arch.attrs.default_group_by) {
group_by = [this.fields_view.arch.attrs.default_group_by];
self.group_by = group_by;
}
self.datagroup = new openerp.web.DataGroup(self, self.model, domain, context, group_by);
self.datagroup.list(
_.keys(self.fields_view.fields),
function (groups) {
self.dataset.ids = [];
self.groups = groups;
if (groups.length) {
self.do_render_group(groups);
} else {
self.all_display_data = [];
self.on_show_data();
}
},
function (dataset) {
self.groups = [];
self.dataset.read_slice(_.keys(self.fields_view.fields), {}, function(records) {
if (records.length) {
self.all_display_data = [{'records': records, 'value':false, 'header' : false, 'ids': self.dataset.ids}];
} else {
self.all_display_data = [];
}
self.$element.find(".oe_kanban_view").remove();
self.on_show_data();
});
}
);
},
do_render_group : function (datagroups) {
this.all_display_data = [];
var self = this,
remaining = datagroups.length - 1;
_.each(datagroups, function (group, index) {
var group_name = group.value;
var group_value = group.value;
if (!group.value) {
group_name = "Undefined";
group_value = 'false';
} else if (group.value instanceof Array) {
group_name = group.value[1];
group_value = group.value[0];
}
var group_aggregates = {};
_.each(self.aggregates, function(value, key) {
group_aggregates[value] = group.aggregates[key];
});
var dataset = new openerp.web.DataSetSearch(self, self.dataset.model, group.context, group.domain);
self.$element.find(".oe_kanban_view").remove();
dataset.read_slice(_.keys(self.fields_view.fields), {'domain': group.domain, 'context': group.context}, function(records) {
self.dataset.ids.push.apply(self.dataset.ids, dataset.ids);
self.all_display_data[index] = {"value" : group_value, "records" : records, 'header' : group_name, 'ids' : dataset.ids, 'aggregates' : group_aggregates};
if (!remaining--) {
self.dataset.index = self.dataset.ids.length ? 0 : null;
self.on_show_data();
}
});
});
},
do_show: function () {
this.$element.show();
},
do_hide: function () {
this.$element.hide();
}
});
};

View File

@ -1,33 +1,43 @@
<template>
<t t-name="KanbanView">
<table style="width:100%;" class="oe_kanban_view">
<tr>
<td>
<div class="oe_form_header">
<button type="button" class="oe_kanban_button_new">New</button>
</div>
</td>
</tr>
<tr>
<td t-foreach="data" t-as="columns" class="oe_table_column" t-att-id="'column_' + columns.value">
<img t-att-id="columns.value" class="fold-columns-icon" src="/web_kanban/static/src/img/minus-icon.png"/>
<div class="oe_fold_column" t-att-id="'column_' + columns.value">
<div class="oe_column_heading" t-if="columns.value and columns.header">
<t t-esc="columns.header"/>
</div>
<div t-foreach="columns.aggregates or {}" t-as="aggregate">
<i><u><t t-esc="aggregate"/>:</u> <t t-esc="aggregate_value"/></i>
<div class="oe_kanban_header">
<button type="button" class="oe_kanban_button_new">New</button>
</div>
<div class="oe_kanban_view">
<table style="width:100%;" class="oe_kanban_groups">
<tr class="oe_kanban_groups_headers">
</tr>
<tr class="oe_kanban_groups_records">
</tr>
</table>
</div>
</t>
<t t-name="KanbanView.group_header">
<td class="oe_kanban_group_header">
<t t-if="widget.view.group_by">
<div class="oe_kanban_fold_icon"></div>
<div class="oe_fold_column">
<div t-attf-class="oe_kanban_group_title #{widget.undefined_title ? 'oe_kanban_group_title_undefined' : ''}">
<t t-esc="widget.title"/>
</div>
<ul class="oe_kanban_aggregates">
<li t-foreach="widget.aggregates" t-as="aggregate">
<span><t t-esc="aggregate"/>:</span> <t t-esc="aggregate_value"/>
</li>
</ul>
</div>
</td>
</tr>
<tr>
<td t-foreach="data" t-as="columns" class="oe_column oe_table_column" t-att-id="'column_' + columns.value" t-attf-style="width: #{Math.round(99 / data.length)}%">
<p t-if="columns.header" class="oe_vertical_text" t-att-id="'column_' + columns.value"><t t-esc="columns.header"/></p>
<div t-foreach="columns.records" t-as="record" class="oe_fold_column oe_kanban_record" t-att-id="'main_' + record.id"/>
</td>
</tr>
</table>
<p t-if="widget.title" class="oe_kanban_group_title_vertical"><t t-esc="widget.title"/></p>
</t>
</td>
</t>
<t t-name="KanbanView.group_records_container">
<td class="oe_kanban_column">
</td>
</t>
<t t-name="KanbanView.record">
<div class="oe_fold_column oe_kanban_record">
<t t-raw="content"/>
</div>
</t>
<t t-name="KanbanColorPicker">
<table cellspacing="0" cellpadding="0" border="0" class="oe_kanban_color_picker">

View File

@ -0,0 +1,66 @@
# Arabic translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-03 15:13+0000\n"
"Last-Translator: kifcaliph <kifcaliph@hotmail.com>\n"
"Language-Team: Arabic <ar@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-04 05:32+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
msgstr "OpenERP"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Database:"
msgstr "قاعدة البيانات:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login:"
msgstr "الدخول:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Password:"
msgstr "كلمة المرور:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login"
msgstr "تسجيل الدخول"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Bad username or password"
msgstr "اسم مستخدم او كلمة مرور خاطئة"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Favourite"
msgstr "مفضّلة"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Preference"
msgstr "التفضيلات"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Applications"
msgstr "تطبيقات"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Options"
msgstr "خيارات"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Logout"
msgstr "تسجيل الخروج"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid ":"
msgstr ":"

View File

@ -0,0 +1,66 @@
# Polish translation for openerp-web
# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011
# This file is distributed under the same license as the openerp-web package.
# FIRST AUTHOR <EMAIL@ADDRESS>, 2011.
#
msgid ""
msgstr ""
"Project-Id-Version: openerp-web\n"
"Report-Msgid-Bugs-To: FULL NAME <EMAIL@ADDRESS>\n"
"POT-Creation-Date: 2011-10-07 10:39+0200\n"
"PO-Revision-Date: 2011-11-04 16:26+0000\n"
"Last-Translator: Grzegorz Grzelak (OpenGLOBE.pl) <grzegorz@openglobe.pl>\n"
"Language-Team: Polish <pl@li.org>\n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
"X-Launchpad-Export-Date: 2011-11-05 06:04+0000\n"
"X-Generator: Launchpad (build 14231)\n"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "OpenERP"
msgstr ""
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Database:"
msgstr "Baza danych:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login:"
msgstr "Login:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Password:"
msgstr "Hasło:"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Login"
msgstr "Login"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Bad username or password"
msgstr "Niepoprawna nazwa użytkownika lub hasło"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Favourite"
msgstr "Ulubione"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Preference"
msgstr "Preferencje"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Applications"
msgstr "Aplikacje"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Options"
msgstr "Opcje"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid "Logout"
msgstr "Wyloguj"
#: addons/web_mobile/static/src/xml/web_mobile.xml:0
msgid ":"
msgstr ""