diff --git a/addons/web/__openerp__.py b/addons/web/__openerp__.py index adf61f5facc..6921b36f91d 100644 --- a/addons/web/__openerp__.py +++ b/addons/web/__openerp__.py @@ -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", + ], } diff --git a/addons/web/common/openerplib/main.py b/addons/web/common/openerplib/main.py index 5cae9ce4636..773ea020d52 100644 --- a/addons/web/common/openerplib/main.py +++ b/addons/web/common/openerplib/main.py @@ -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): diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py index 6cc46b476a9..6f72d836ea4 100644 --- a/addons/web/controllers/main.py +++ b/addons/web/controllers/main.py @@ -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(''%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 diff --git a/addons/web/po/ar.po b/addons/web/po/ar.po new file mode 100644 index 00000000000..4a6ebecff9f --- /dev/null +++ b/addons/web/po/ar.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \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 \n" +"Language-Team: Arabic \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 "   Search More..." +msgstr "    مزيداً من البحث..." + +#: addons/web/static/src/js/view_form.js:1672 +#, python-format +msgid "   Create \"%s\"" +msgstr "   إنشاء \"%s\"" + +#: addons/web/static/src/js/view_form.js:1678 +msgid "   Create and Edit..." +msgstr "   إنشاء و تحرير..." + +#: 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 "«" +msgstr "«" + +#: addons/web/static/src/xml/base.xml:0 +msgid "»" +msgstr "»" + +#: 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 " " +msgstr " " + +#: 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 متاح من خلال تطبيق الويب أو البرنامج المحلي." diff --git a/addons/web/po/da.po b/addons/web/po/da.po index c0931065d1e..db03cc5e19b 100644 --- a/addons/web/po/da.po +++ b/addons/web/po/da.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openerp-web\n" "Report-Msgid-Bugs-To: FULL NAME \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 \n" "Language-Team: Danish \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" diff --git a/addons/web/po/pl.po b/addons/web/po/pl.po new file mode 100644 index 00000000000..fde2196a73e --- /dev/null +++ b/addons/web/po/pl.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \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) \n" +"Language-Team: Polish \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 "   Search More..." +msgstr "   Szukaj dalej..." + +#: addons/web/static/src/js/view_form.js:1672 +#, python-format +msgid "   Create \"%s\"" +msgstr "   Utwórz \"%s\"" + +#: addons/web/static/src/js/view_form.js:1678 +msgid "   Create and Edit..." +msgstr "   Utwórz i edytuj..." + +#: 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 "«" +msgstr "" + +#: addons/web/static/src/xml/base.xml:0 +msgid "»" +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 " " +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 "" diff --git a/addons/web/static/lib/jquery.scrollTo/changes.txt b/addons/web/static/lib/jquery.scrollTo/changes.txt new file mode 100644 index 00000000000..4b2933f6667 --- /dev/null +++ b/addons/web/static/lib/jquery.scrollTo/changes.txt @@ -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 and . +- 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). \ No newline at end of file diff --git a/addons/web/static/lib/jquery.scrollTo/jquery.scrollTo-min.js b/addons/web/static/lib/jquery.scrollTo/jquery.scrollTo-min.js new file mode 100644 index 00000000000..73a334184e4 --- /dev/null +++ b/addons/web/static/lib/jquery.scrollTo/jquery.scrollTo-min.js @@ -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); \ No newline at end of file diff --git a/addons/web/static/lib/jquery.scrollTo/jquery.scrollTo.js b/addons/web/static/lib/jquery.scrollTo/jquery.scrollTo.js new file mode 100644 index 00000000000..eec31e191cb --- /dev/null +++ b/addons/web/static/lib/jquery.scrollTo/jquery.scrollTo.js @@ -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 ); \ No newline at end of file diff --git a/addons/web/static/src/css/base.css b/addons/web/static/src/css/base.css index 3430dfe196a..01f4b11f4d3 100644 --- a/addons/web/static/src/css/base.css +++ b/addons/web/static/src/css/base.css @@ -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; } + diff --git a/addons/web/static/src/js/boot.js b/addons/web/static/src/js/boot.js index 5fba5f4d8d4..58dcd922ea9 100644 --- a/addons/web/static/src/js/boot.js +++ b/addons/web/static/src/js/boot.js @@ -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: diff --git a/addons/web/static/src/js/chrome.js b/addons/web/static/src/js/chrome.js index 22c2b0ba2ea..25b73ee59d5 100644 --- a/addons/web/static/src/js/chrome.js +++ b/addons/web/static/src/js/chrome.js @@ -109,7 +109,7 @@ openerp.web.Dialog = openerp.web.OldWidget.extend(/** @lends openerp.web.Dialog# } }, start: function () { - this.$dialog = $('
').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); diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js index 9563abea49a..1929c573e42 100644 --- a/addons/web/static/src/js/core.js +++ b/addons/web/static/src/js/core.js @@ -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 cutoff); + _(log_records.reverse()).each(function (record) { $(_.sprintf('
  • %s
  • ', 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() { } diff --git a/addons/web/static/src/xml/base.xml b/addons/web/static/src/xml/base.xml index 0d86a840718..9783f4ae959 100644 --- a/addons/web/static/src/xml/base.xml +++ b/addons/web/static/src/xml/base.xml @@ -457,7 +457,11 @@ -
      +
      +
        + More… + +
        @@ -473,8 +477,6 @@

        - -
      • @@ -484,38 +486,25 @@ - -
        - - - - - - - - - -
        -
        Field
        -
        -
        -
        - - - - -
        -
        -
        - Translate view -
        -
        - Translate sidebar -
        + + + + + + + + + +
        +
        Field
        +
        +
        +
        + + + + +
        diff --git a/addons/web_calendar/__openerp__.py b/addons/web_calendar/__openerp__.py index 1eba26065f5..5b09e70cba8 100644 --- a/addons/web_calendar/__openerp__.py +++ b/addons/web_calendar/__openerp__.py @@ -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 } diff --git a/addons/web_calendar/po/ar.po b/addons/web_calendar/po/ar.po new file mode 100644 index 00000000000..33e04220c2c --- /dev/null +++ b/addons/web_calendar/po/ar.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-10-07 10:38+0200\n" +"PO-Revision-Date: 2011-11-03 15:02+0000\n" +"Last-Translator: kifcaliph \n" +"Language-Team: Arabic \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 " " +msgstr " " diff --git a/addons/web_calendar/static/src/js/calendar.js b/addons/web_calendar/static/src/js/calendar.js index a5fd8bcac9c..982fc60e1c4 100644 --- a/addons/web_calendar/static/src/js/calendar.js +++ b/addons/web_calendar/static/src/js/calendar.js @@ -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 ? diff --git a/addons/web_dashboard/__openerp__.py b/addons/web_dashboard/__openerp__.py index 7a527511b03..68c73731c71 100644 --- a/addons/web_dashboard/__openerp__.py +++ b/addons/web_dashboard/__openerp__.py @@ -7,5 +7,8 @@ 'static/src/js/dashboard.js' ], "css": ['static/src/css/dashboard.css'], + 'qweb' : [ + "static/src/xml/*.xml", + ], 'active': True } diff --git a/addons/web_dashboard/po/ar.po b/addons/web_dashboard/po/ar.po new file mode 100644 index 00000000000..0e2cf4dfcf2 --- /dev/null +++ b/addons/web_dashboard/po/ar.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-10-07 10:39+0200\n" +"PO-Revision-Date: 2011-11-03 15:09+0000\n" +"Last-Translator: kifcaliph \n" +"Language-Team: Arabic \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 "%" diff --git a/addons/web_dashboard/po/pl.po b/addons/web_dashboard/po/pl.po new file mode 100644 index 00000000000..256945c9030 --- /dev/null +++ b/addons/web_dashboard/po/pl.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \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) \n" +"Language-Team: Polish \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 "" diff --git a/addons/web_dashboard/static/src/js/dashboard.js b/addons/web_dashboard/static/src/js/dashboard.js index b5f3b606d71..e629a4a6ef5 100644 --- a/addons/web_dashboard/static/src/js/dashboard.js +++ b/addons/web_dashboard/static/src/js/dashboard.js @@ -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 */ diff --git a/addons/web_dashboard/static/src/xml/web_dashboard.xml b/addons/web_dashboard/static/src/xml/web_dashboard.xml index 87222baa5fd..77eab4b7e28 100644 --- a/addons/web_dashboard/static/src/xml/web_dashboard.xml +++ b/addons/web_dashboard/static/src/xml/web_dashboard.xml @@ -30,7 +30,7 @@
        -

        +

        &nbsp; diff --git a/addons/web_default_home/po/ar.po b/addons/web_default_home/po/ar.po new file mode 100644 index 00000000000..16c56db9120 --- /dev/null +++ b/addons/web_default_home/po/ar.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \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 \n" +"Language-Team: Arabic \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 "تثبيت" diff --git a/addons/web_default_home/po/pl.po b/addons/web_default_home/po/pl.po new file mode 100644 index 00000000000..3eec2b0ab49 --- /dev/null +++ b/addons/web_default_home/po/pl.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \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) \n" +"Language-Team: Polish \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" diff --git a/addons/web_diagram/__openerp__.py b/addons/web_diagram/__openerp__.py index 584c0a16e66..cd9eb719934 100644 --- a/addons/web_diagram/__openerp__.py +++ b/addons/web_diagram/__openerp__.py @@ -13,5 +13,8 @@ 'css' : [ "static/src/css/base_diagram.css", ], + 'qweb' : [ + "static/src/xml/*.xml", + ], 'active': True, } diff --git a/addons/web_diagram/po/ar.po b/addons/web_diagram/po/ar.po new file mode 100644 index 00000000000..af8c6ab7213 --- /dev/null +++ b/addons/web_diagram/po/ar.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-10-07 10:39+0200\n" +"PO-Revision-Date: 2011-11-03 15:11+0000\n" +"Last-Translator: kifcaliph \n" +"Language-Team: Arabic \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 "الأخير" diff --git a/addons/web_diagram/po/da.po b/addons/web_diagram/po/da.po index b0a68cf641c..76d870fbc78 100644 --- a/addons/web_diagram/po/da.po +++ b/addons/web_diagram/po/da.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openerp-web\n" "Report-Msgid-Bugs-To: FULL NAME \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 \n" "Language-Team: Danish \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:" diff --git a/addons/web_diagram/po/pl.po b/addons/web_diagram/po/pl.po new file mode 100644 index 00000000000..f36f3853850 --- /dev/null +++ b/addons/web_diagram/po/pl.po @@ -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 , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openerp-web\n" +"Report-Msgid-Bugs-To: FULL NAME \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) \n" +"Language-Team: Polish \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" diff --git a/addons/web_diagram/static/src/js/diagram.js b/addons/web_diagram/static/src/js/diagram.js index ffa27734769..e4fb3ef5b75 100644 --- a/addons/web_diagram/static/src/js/diagram.js +++ b/addons/web_diagram/static/src/js/diagram.js @@ -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, diff --git a/addons/web_gantt/__openerp__.py b/addons/web_gantt/__openerp__.py index d2b24f96d08..cd24a8f7314 100644 --- a/addons/web_gantt/__openerp__.py +++ b/addons/web_gantt/__openerp__.py @@ -9,5 +9,8 @@ 'static/src/js/gantt.js' ], "css": ['static/lib/dhtmlxGantt/codebase/dhtmlxgantt.css'], + 'qweb' : [ + "static/src/xml/*.xml", + ], 'active': True } diff --git a/addons/web_gantt/static/src/js/gantt.js b/addons/web_gantt/static/src/js/gantt.js index bb19ecbbae6..2165bd7ce88 100644 --- a/addons/web_gantt/static/src/js/gantt.js +++ b/addons/web_gantt/static/src/js/gantt.js @@ -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({ diff --git a/addons/web_graph/__openerp__.py b/addons/web_graph/__openerp__.py index 68775b7c0e3..d7c37acb180 100644 --- a/addons/web_graph/__openerp__.py +++ b/addons/web_graph/__openerp__.py @@ -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 } diff --git a/addons/web_graph/static/src/js/graph.js b/addons/web_graph/static/src/js/graph.js index 33321da970a..04e9d77f5d0 100644 --- a/addons/web_graph/static/src/js/graph.js +++ b/addons/web_graph/static/src/js/graph.js @@ -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({ diff --git a/addons/web_kanban/__openerp__.py b/addons/web_kanban/__openerp__.py index f39cd64999b..92d60b0f4ed 100644 --- a/addons/web_kanban/__openerp__.py +++ b/addons/web_kanban/__openerp__.py @@ -9,5 +9,8 @@ "css": [ "static/src/css/kanban.css" ], + 'qweb' : [ + "static/src/xml/*.xml", + ], 'active': True } diff --git a/addons/web_kanban/static/src/css/kanban.css b/addons/web_kanban/static/src/css/kanban.css index d7c27510f4d..86818f6541c 100644 --- a/addons/web_kanban/static/src/css/kanban.css +++ b/addons/web_kanban/static/src/css/kanban.css @@ -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; +} diff --git a/addons/web_kanban/static/src/js/kanban.js b/addons/web_kanban/static/src/js/kanban.js index 13d3c9203fc..b2d5dcadc25 100644 --- a/addons/web_kanban/static/src/js/kanban.js +++ b/addons/web_kanban/static/src/js/kanban.js @@ -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(); } }); }; diff --git a/addons/web_kanban/static/src/xml/web_kanban.xml b/addons/web_kanban/static/src/xml/web_kanban.xml index 8281352cc15..c1346a0b90d 100644 --- a/addons/web_kanban/static/src/xml/web_kanban.xml +++ b/addons/web_kanban/static/src/xml/web_kanban.xml @@ -1,33 +1,43 @@