From 753cb318040fc29995f5397b63ad9cc42a03cd90 Mon Sep 17 00:00:00 2001
From: Antony Lesuisse
Date: Mon, 2 Dec 2013 15:22:40 +0100
Subject: [PATCH 1/6] [IMP] upgrade backbone to 1.1.0
bzr revid: al@openerp.com-20131202142240-ifh2rua2oiennfao
---
addons/web/static/lib/backbone/backbone.js | 1826 +++++++++++---------
addons/web/static/src/js/core.js | 2 +-
2 files changed, 989 insertions(+), 839 deletions(-)
diff --git a/addons/web/static/lib/backbone/backbone.js b/addons/web/static/lib/backbone/backbone.js
index 3373c952bfa..f7783c2c199 100644
--- a/addons/web/static/lib/backbone/backbone.js
+++ b/addons/web/static/lib/backbone/backbone.js
@@ -1,6 +1,7 @@
-// Backbone.js 0.9.2
+// Backbone.js 1.1.0
-// (c) 2010-2012 Jeremy Ashkenas, DocumentCloud Inc.
+// (c) 2010-2011 Jeremy Ashkenas, DocumentCloud Inc.
+// (c) 2011-2013 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors
// Backbone may be freely distributed under the MIT license.
// For all details and documentation:
// http://backbonejs.org
@@ -10,7 +11,7 @@
// Initial Setup
// -------------
- // Save a reference to the global object (`window` in the browser, `global`
+ // Save a reference to the global object (`window` in the browser, `exports`
// on the server).
var root = this;
@@ -18,12 +19,14 @@
// restored later on, if `noConflict` is used.
var previousBackbone = root.Backbone;
- // Create a local reference to slice/splice.
- var slice = Array.prototype.slice;
- var splice = Array.prototype.splice;
+ // Create local references to array methods we'll want to use later.
+ var array = [];
+ var push = array.push;
+ var slice = array.slice;
+ var splice = array.splice;
// The top-level namespace. All public Backbone classes and modules will
- // be attached to this. Exported for both CommonJS and the browser.
+ // be attached to this. Exported for both the browser and the server.
var Backbone;
if (typeof exports !== 'undefined') {
Backbone = exports;
@@ -32,23 +35,15 @@
}
// Current version of the library. Keep in sync with `package.json`.
- Backbone.VERSION = '0.9.2';
+ Backbone.VERSION = '1.1.0';
// Require Underscore, if we're on the server, and it's not already present.
var _ = root._;
if (!_ && (typeof require !== 'undefined')) _ = require('underscore');
- // For Backbone's purposes, jQuery, Zepto, or Ender owns the `$` variable.
- var $ = root.jQuery || root.Zepto || root.ender;
-
- // Set the JavaScript library that will be used for DOM manipulation and
- // Ajax calls (a.k.a. the `$` variable). By default Backbone will use: jQuery,
- // Zepto, or Ender; but the `setDomLibrary()` method lets you inject an
- // alternate JavaScript library (or a mock library for testing your views
- // outside of a browser).
- Backbone.setDomLibrary = function(lib) {
- $ = lib;
- };
+ // For Backbone's purposes, jQuery, Zepto, Ender, or My Library (kidding) owns
+ // the `$` variable.
+ Backbone.$ = root.jQuery || root.Zepto || root.ender || root.$;
// Runs Backbone.js in *noConflict* mode, returning the `Backbone` variable
// to its previous owner. Returns a reference to this Backbone object.
@@ -58,7 +53,7 @@
};
// Turn on `emulateHTTP` to support legacy HTTP servers. Setting this option
- // will fake `"PUT"` and `"DELETE"` requests via the `_method` parameter and
+ // will fake `"PATCH"`, `"PUT"` and `"DELETE"` requests via the `_method` parameter and
// set a `X-Http-Method-Override` header.
Backbone.emulateHTTP = false;
@@ -69,14 +64,12 @@
Backbone.emulateJSON = false;
// Backbone.Events
- // -----------------
-
- // Regular expression used to split event strings
- var eventSplitter = /\s+/;
+ // ---------------
// A module that can be mixed in to *any object* in order to provide it with
- // custom events. You may bind with `on` or remove with `off` callback functions
- // to an event; trigger`-ing an event fires all callbacks in succession.
+ // custom events. You may bind with `on` or remove with `off` callback
+ // functions to an event; `trigger`-ing an event fires all callbacks in
+ // succession.
//
// var object = {};
// _.extend(object, Backbone.Events);
@@ -85,58 +78,55 @@
//
var Events = Backbone.Events = {
- // Bind one or more space separated events, `events`, to a `callback`
- // function. Passing `"all"` will bind the callback to all events fired.
- on: function(events, callback, context) {
-
- var calls, event, node, tail, list;
- if (!callback) return this;
- events = events.split(eventSplitter);
- calls = this._callbacks || (this._callbacks = {});
-
- // Create an immutable callback list, allowing traversal during
- // modification. The tail is an empty object that will always be used
- // as the next node.
- while (event = events.shift()) {
- list = calls[event];
- node = list ? list.tail : {};
- node.next = tail = {};
- node.context = context;
- node.callback = callback;
- calls[event] = {tail: tail, next: list ? list.next : node};
- }
-
+ // Bind an event to a `callback` function. Passing `"all"` will bind
+ // the callback to all events fired.
+ on: function(name, callback, context) {
+ if (!eventsApi(this, 'on', name, [callback, context]) || !callback) return this;
+ this._events || (this._events = {});
+ var events = this._events[name] || (this._events[name] = []);
+ events.push({callback: callback, context: context, ctx: context || this});
return this;
},
- // Remove one or many callbacks. If `context` is null, removes all callbacks
- // with that function. If `callback` is null, removes all callbacks for the
- // event. If `events` is null, removes all bound callbacks for all events.
- off: function(events, callback, context) {
- var event, calls, node, tail, cb, ctx;
+ // Bind an event to only be triggered a single time. After the first time
+ // the callback is invoked, it will be removed.
+ once: function(name, callback, context) {
+ if (!eventsApi(this, 'once', name, [callback, context]) || !callback) return this;
+ var self = this;
+ var once = _.once(function() {
+ self.off(name, once);
+ callback.apply(this, arguments);
+ });
+ once._callback = callback;
+ return this.on(name, once, context);
+ },
- // No events, or removing *all* events.
- if (!(calls = this._callbacks)) return;
- if (!(events || callback || context)) {
- delete this._callbacks;
+ // Remove one or many callbacks. If `context` is null, removes all
+ // callbacks with that function. If `callback` is null, removes all
+ // callbacks for the event. If `name` is null, removes all bound
+ // callbacks for all events.
+ off: function(name, callback, context) {
+ var retain, ev, events, names, i, l, j, k;
+ if (!this._events || !eventsApi(this, 'off', name, [callback, context])) return this;
+ if (!name && !callback && !context) {
+ this._events = {};
return this;
}
-
- // Loop through the listed events and contexts, splicing them out of the
- // linked list of callbacks if appropriate.
- events = events ? events.split(eventSplitter) : _.keys(calls);
- while (event = events.shift()) {
- node = calls[event];
- delete calls[event];
- if (!node || !(callback || context)) continue;
- // Create a new list, omitting the indicated callbacks.
- tail = node.tail;
- while ((node = node.next) !== tail) {
- cb = node.callback;
- ctx = node.context;
- if ((callback && cb !== callback) || (context && ctx !== context)) {
- this.on(event, cb, ctx);
+ names = name ? [name] : _.keys(this._events);
+ for (i = 0, l = names.length; i < l; i++) {
+ name = names[i];
+ if (events = this._events[name]) {
+ this._events[name] = retain = [];
+ if (callback || context) {
+ for (j = 0, k = events.length; j < k; j++) {
+ ev = events[j];
+ if ((callback && callback !== ev.callback && callback !== ev.callback._callback) ||
+ (context && context !== ev.context)) {
+ retain.push(ev);
+ }
+ }
}
+ if (!retain.length) delete this._events[name];
}
}
@@ -147,65 +137,122 @@
// passed the same arguments as `trigger` is, apart from the event name
// (unless you're listening on `"all"`, which will cause your callback to
// receive the true name of the event as the first argument).
- trigger: function(events) {
- var event, node, calls, tail, args, all, rest;
- if (!(calls = this._callbacks)) return this;
- all = calls.all;
- events = events.split(eventSplitter);
- rest = slice.call(arguments, 1);
+ trigger: function(name) {
+ if (!this._events) return this;
+ var args = slice.call(arguments, 1);
+ if (!eventsApi(this, 'trigger', name, args)) return this;
+ var events = this._events[name];
+ var allEvents = this._events.all;
+ if (events) triggerEvents(events, args);
+ if (allEvents) triggerEvents(allEvents, arguments);
+ return this;
+ },
- // For each event, walk through the linked list of callbacks twice,
- // first to trigger the event, then to trigger any `"all"` callbacks.
- while (event = events.shift()) {
- if (node = calls[event]) {
- tail = node.tail;
- while ((node = node.next) !== tail) {
- node.callback.apply(node.context || this, rest);
- }
- }
- if (node = all) {
- tail = node.tail;
- args = [event].concat(rest);
- while ((node = node.next) !== tail) {
- node.callback.apply(node.context || this, args);
- }
- }
+ // Tell this object to stop listening to either specific events ... or
+ // to every object it's currently listening to.
+ stopListening: function(obj, name, callback) {
+ var listeningTo = this._listeningTo;
+ if (!listeningTo) return this;
+ var remove = !name && !callback;
+ if (!callback && typeof name === 'object') callback = this;
+ if (obj) (listeningTo = {})[obj._listenId] = obj;
+ for (var id in listeningTo) {
+ obj = listeningTo[id];
+ obj.off(name, callback, this);
+ if (remove || _.isEmpty(obj._events)) delete this._listeningTo[id];
}
-
return this;
}
};
+ // Regular expression used to split event strings.
+ var eventSplitter = /\s+/;
+
+ // Implement fancy features of the Events API such as multiple event
+ // names `"change blur"` and jQuery-style event maps `{change: action}`
+ // in terms of the existing API.
+ var eventsApi = function(obj, action, name, rest) {
+ if (!name) return true;
+
+ // Handle event maps.
+ if (typeof name === 'object') {
+ for (var key in name) {
+ obj[action].apply(obj, [key, name[key]].concat(rest));
+ }
+ return false;
+ }
+
+ // Handle space separated event names.
+ if (eventSplitter.test(name)) {
+ var names = name.split(eventSplitter);
+ for (var i = 0, l = names.length; i < l; i++) {
+ obj[action].apply(obj, [names[i]].concat(rest));
+ }
+ return false;
+ }
+
+ return true;
+ };
+
+ // A difficult-to-believe, but optimized internal dispatch function for
+ // triggering events. Tries to keep the usual cases speedy (most internal
+ // Backbone events have 3 arguments).
+ var triggerEvents = function(events, args) {
+ var ev, i = -1, l = events.length, a1 = args[0], a2 = args[1], a3 = args[2];
+ switch (args.length) {
+ case 0: while (++i < l) (ev = events[i]).callback.call(ev.ctx); return;
+ case 1: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1); return;
+ case 2: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2); return;
+ case 3: while (++i < l) (ev = events[i]).callback.call(ev.ctx, a1, a2, a3); return;
+ default: while (++i < l) (ev = events[i]).callback.apply(ev.ctx, args);
+ }
+ };
+
+ var listenMethods = {listenTo: 'on', listenToOnce: 'once'};
+
+ // Inversion-of-control versions of `on` and `once`. Tell *this* object to
+ // listen to an event in another object ... keeping track of what it's
+ // listening to.
+ _.each(listenMethods, function(implementation, method) {
+ Events[method] = function(obj, name, callback) {
+ var listeningTo = this._listeningTo || (this._listeningTo = {});
+ var id = obj._listenId || (obj._listenId = _.uniqueId('l'));
+ listeningTo[id] = obj;
+ if (!callback && typeof name === 'object') callback = this;
+ obj[implementation](name, callback, this);
+ return this;
+ };
+ });
+
// Aliases for backwards compatibility.
Events.bind = Events.on;
Events.unbind = Events.off;
+ // Allow the `Backbone` object to serve as a global event bus, for folks who
+ // want global "pubsub" in a convenient place.
+ _.extend(Backbone, Events);
+
// Backbone.Model
// --------------
- // Create a new model, with defined attributes. A client id (`cid`)
+ // Backbone **Models** are the basic data object in the framework --
+ // frequently representing a row in a table in a database on your server.
+ // A discrete chunk of data and a bunch of useful, related methods for
+ // performing computations and transformations on that data.
+
+ // Create a new model with the specified attributes. A client id (`cid`)
// is automatically generated and assigned for you.
var Model = Backbone.Model = function(attributes, options) {
- var defaults;
- attributes || (attributes = {});
- if (options && options.parse) attributes = this.parse(attributes);
- if (defaults = getValue(this, 'defaults')) {
- attributes = _.extend({}, defaults, attributes);
- }
- if (options && options.collection) this.collection = options.collection;
- this.attributes = {};
- this._escapedAttributes = {};
+ var attrs = attributes || {};
+ options || (options = {});
this.cid = _.uniqueId('c');
+ this.attributes = {};
+ if (options.collection) this.collection = options.collection;
+ if (options.parse) attrs = this.parse(attrs, options) || {};
+ attrs = _.defaults({}, attrs, _.result(this, 'defaults'));
+ this.set(attrs, options);
this.changed = {};
- this._silent = {};
- this._pending = {};
- this.set(attributes, {silent: true});
- // Reset change tracking.
- this.changed = {};
- this._silent = {};
- this._pending = {};
- this._previousAttributes = _.clone(this.attributes);
this.initialize.apply(this, arguments);
};
@@ -215,13 +262,8 @@
// A hash of attributes whose current and previous value differ.
changed: null,
- // A hash of attributes that have silently changed since the last time
- // `change` was called. Will become pending attributes on the next call.
- _silent: null,
-
- // A hash of attributes that have changed since the last `'change'` event
- // began.
- _pending: null,
+ // The value returned during the last failed validation.
+ validationError: null,
// The default name for the JSON `id` attribute is `"id"`. MongoDB and
// CouchDB users may want to set this to `"_id"`.
@@ -236,6 +278,12 @@
return _.clone(this.attributes);
},
+ // Proxy `Backbone.sync` by default -- but override this if you need
+ // custom syncing semantics for *this* particular model.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
+ },
+
// Get the value of an attribute.
get: function(attr) {
return this.attributes[attr];
@@ -243,10 +291,7 @@
// Get the HTML-escaped value of an attribute.
escape: function(attr) {
- var html;
- if (html = this._escapedAttributes[attr]) return html;
- var val = this.get(attr);
- return this._escapedAttributes[attr] = _.escape(val == null ? '' : '' + val);
+ return _.escape(this.get(attr));
},
// Returns `true` if the attribute contains a value that is not null
@@ -255,146 +300,198 @@
return this.get(attr) != null;
},
- // Set a hash of model attributes on the object, firing `"change"` unless
- // you choose to silence it.
- set: function(key, value, options) {
- var attrs, attr, val;
+ // Set a hash of model attributes on the object, firing `"change"`. This is
+ // the core primitive operation of a model, updating the data and notifying
+ // anyone who needs to know about the change in state. The heart of the beast.
+ set: function(key, val, options) {
+ var attr, attrs, unset, changes, silent, changing, prev, current;
+ if (key == null) return this;
// Handle both `"key", value` and `{key: value}` -style arguments.
- if (_.isObject(key) || key == null) {
+ if (typeof key === 'object') {
attrs = key;
- options = value;
+ options = val;
} else {
- attrs = {};
- attrs[key] = value;
+ (attrs = {})[key] = val;
}
- // Extract attributes and options.
options || (options = {});
- if (!attrs) return this;
- if (attrs instanceof Model) attrs = attrs.attributes;
- if (options.unset) for (attr in attrs) attrs[attr] = void 0;
// Run validation.
if (!this._validate(attrs, options)) return false;
+ // Extract attributes and options.
+ unset = options.unset;
+ silent = options.silent;
+ changes = [];
+ changing = this._changing;
+ this._changing = true;
+
+ if (!changing) {
+ this._previousAttributes = _.clone(this.attributes);
+ this.changed = {};
+ }
+ current = this.attributes, prev = this._previousAttributes;
+
// Check for changes of `id`.
if (this.idAttribute in attrs) this.id = attrs[this.idAttribute];
- var changes = options.changes = {};
- var now = this.attributes;
- var escaped = this._escapedAttributes;
- var prev = this._previousAttributes || {};
-
- // For each `set` attribute...
+ // For each `set` attribute, update or delete the current value.
for (attr in attrs) {
val = attrs[attr];
-
- // If the new and current value differ, record the change.
- if (!_.isEqual(now[attr], val) || (options.unset && _.has(now, attr))) {
- delete escaped[attr];
- (options.silent ? this._silent : changes)[attr] = true;
- }
-
- // Update or delete the current value.
- options.unset ? delete now[attr] : now[attr] = val;
-
- // If the new and previous value differ, record the change. If not,
- // then remove changes for this attribute.
- if (!_.isEqual(prev[attr], val) || (_.has(now, attr) != _.has(prev, attr))) {
+ if (!_.isEqual(current[attr], val)) changes.push(attr);
+ if (!_.isEqual(prev[attr], val)) {
this.changed[attr] = val;
- if (!options.silent) this._pending[attr] = true;
} else {
delete this.changed[attr];
- delete this._pending[attr];
+ }
+ unset ? delete current[attr] : current[attr] = val;
+ }
+
+ // Trigger all relevant attribute changes.
+ if (!silent) {
+ if (changes.length) this._pending = true;
+ for (var i = 0, l = changes.length; i < l; i++) {
+ this.trigger('change:' + changes[i], this, current[changes[i]], options);
}
}
- // Fire the `"change"` events.
- if (!options.silent) this.change(options);
+ // You might be wondering why there's a `while` loop here. Changes can
+ // be recursively nested within `"change"` events.
+ if (changing) return this;
+ if (!silent) {
+ while (this._pending) {
+ this._pending = false;
+ this.trigger('change', this, options);
+ }
+ }
+ this._pending = false;
+ this._changing = false;
return this;
},
- // Remove an attribute from the model, firing `"change"` unless you choose
- // to silence it. `unset` is a noop if the attribute doesn't exist.
+ // Remove an attribute from the model, firing `"change"`. `unset` is a noop
+ // if the attribute doesn't exist.
unset: function(attr, options) {
- (options || (options = {})).unset = true;
- return this.set(attr, null, options);
+ return this.set(attr, void 0, _.extend({}, options, {unset: true}));
},
- // Clear all attributes on the model, firing `"change"` unless you choose
- // to silence it.
+ // Clear all attributes on the model, firing `"change"`.
clear: function(options) {
- (options || (options = {})).unset = true;
- return this.set(_.clone(this.attributes), options);
+ var attrs = {};
+ for (var key in this.attributes) attrs[key] = void 0;
+ return this.set(attrs, _.extend({}, options, {unset: true}));
+ },
+
+ // Determine if the model has changed since the last `"change"` event.
+ // If you specify an attribute name, determine if that attribute has changed.
+ hasChanged: function(attr) {
+ if (attr == null) return !_.isEmpty(this.changed);
+ return _.has(this.changed, attr);
+ },
+
+ // Return an object containing all the attributes that have changed, or
+ // false if there are no changed attributes. Useful for determining what
+ // parts of a view need to be updated and/or what attributes need to be
+ // persisted to the server. Unset attributes will be set to undefined.
+ // You can also pass an attributes object to diff against the model,
+ // determining if there *would be* a change.
+ changedAttributes: function(diff) {
+ if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
+ var val, changed = false;
+ var old = this._changing ? this._previousAttributes : this.attributes;
+ for (var attr in diff) {
+ if (_.isEqual(old[attr], (val = diff[attr]))) continue;
+ (changed || (changed = {}))[attr] = val;
+ }
+ return changed;
+ },
+
+ // Get the previous value of an attribute, recorded at the time the last
+ // `"change"` event was fired.
+ previous: function(attr) {
+ if (attr == null || !this._previousAttributes) return null;
+ return this._previousAttributes[attr];
+ },
+
+ // Get all of the attributes of the model at the time of the previous
+ // `"change"` event.
+ previousAttributes: function() {
+ return _.clone(this._previousAttributes);
},
// Fetch the model from the server. If the server's representation of the
- // model differs from its current attributes, they will be overriden,
+ // model differs from its current attributes, they will be overridden,
// triggering a `"change"` event.
fetch: function(options) {
options = options ? _.clone(options) : {};
+ if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
- options.success = function(resp, status, xhr) {
- if (!model.set(model.parse(resp, xhr), options)) return false;
- if (success) success(model, resp);
+ options.success = function(resp) {
+ if (!model.set(model.parse(resp, options), options)) return false;
+ if (success) success(model, resp, options);
+ model.trigger('sync', model, resp, options);
};
- options.error = Backbone.wrapError(options.error, model, options);
- return (this.sync || Backbone.sync).call(this, 'read', this, options);
+ wrapError(this, options);
+ return this.sync('read', this, options);
},
// Set a hash of model attributes, and sync the model to the server.
// If the server returns an attributes hash that differs, the model's
// state will be `set` again.
- save: function(key, value, options) {
- var attrs, current;
+ save: function(key, val, options) {
+ var attrs, method, xhr, attributes = this.attributes;
- // Handle both `("key", value)` and `({key: value})` -style calls.
- if (_.isObject(key) || key == null) {
+ // Handle both `"key", value` and `{key: value}` -style arguments.
+ if (key == null || typeof key === 'object') {
attrs = key;
- options = value;
+ options = val;
} else {
- attrs = {};
- attrs[key] = value;
+ (attrs = {})[key] = val;
}
- options = options ? _.clone(options) : {};
- // If we're "wait"-ing to set changed attributes, validate early.
- if (options.wait) {
+ options = _.extend({validate: true}, options);
+
+ // If we're not waiting and attributes exist, save acts as
+ // `set(attr).save(null, opts)` with validation. Otherwise, check if
+ // the model will be valid when the attributes, if any, are set.
+ if (attrs && !options.wait) {
+ if (!this.set(attrs, options)) return false;
+ } else {
if (!this._validate(attrs, options)) return false;
- current = _.clone(this.attributes);
}
- // Regular saves `set` attributes before persisting to the server.
- var silentOptions = _.extend({}, options, {silent: true});
- if (attrs && !this.set(attrs, options.wait ? silentOptions : options)) {
- return false;
+ // Set temporary attributes if `{wait: true}`.
+ if (attrs && options.wait) {
+ this.attributes = _.extend({}, attributes, attrs);
}
// After a successful server-side save, the client is (optionally)
// updated with the server-side state.
+ if (options.parse === void 0) options.parse = true;
var model = this;
var success = options.success;
- options.success = function(resp, status, xhr) {
- var serverAttrs = model.parse(resp, xhr);
- if (options.wait) {
- delete options.wait;
- serverAttrs = _.extend(attrs || {}, serverAttrs);
- }
- if (!model.set(serverAttrs, options)) return false;
- if (success) {
- success(model, resp);
- } else {
- model.trigger('sync', model, resp, options);
+ options.success = function(resp) {
+ // Ensure attributes are restored during synchronous saves.
+ model.attributes = attributes;
+ var serverAttrs = model.parse(resp, options);
+ if (options.wait) serverAttrs = _.extend(attrs || {}, serverAttrs);
+ if (_.isObject(serverAttrs) && !model.set(serverAttrs, options)) {
+ return false;
}
+ if (success) success(model, resp, options);
+ model.trigger('sync', model, resp, options);
};
+ wrapError(this, options);
+
+ method = this.isNew() ? 'create' : (options.patch ? 'patch' : 'update');
+ if (method === 'patch') options.attrs = attrs;
+ xhr = this.sync(method, this, options);
+
+ // Restore attributes.
+ if (attrs && options.wait) this.attributes = attributes;
- // Finish configuring and sending the Ajax request.
- options.error = Backbone.wrapError(options.error, model, options);
- var method = this.isNew() ? 'create' : 'update';
- var xhr = (this.sync || Backbone.sync).call(this, method, this, options);
- if (options.wait) this.set(current, silentOptions);
return xhr;
},
@@ -406,27 +503,24 @@
var model = this;
var success = options.success;
- var triggerDestroy = function() {
+ var destroy = function() {
model.trigger('destroy', model, model.collection, options);
};
- if (this.isNew()) {
- triggerDestroy();
- return false;
- }
-
options.success = function(resp) {
- if (options.wait) triggerDestroy();
- if (success) {
- success(model, resp);
- } else {
- model.trigger('sync', model, resp, options);
- }
+ if (options.wait || model.isNew()) destroy();
+ if (success) success(model, resp, options);
+ if (!model.isNew()) model.trigger('sync', model, resp, options);
};
- options.error = Backbone.wrapError(options.error, model, options);
- var xhr = (this.sync || Backbone.sync).call(this, 'delete', this, options);
- if (!options.wait) triggerDestroy();
+ if (this.isNew()) {
+ options.success();
+ return false;
+ }
+ wrapError(this, options);
+
+ var xhr = this.sync('delete', this, options);
+ if (!options.wait) destroy();
return xhr;
},
@@ -434,14 +528,14 @@
// using Backbone's restful methods, override this to change the endpoint
// that will be called.
url: function() {
- var base = getValue(this, 'urlRoot') || getValue(this.collection, 'url') || urlError();
+ var base = _.result(this, 'urlRoot') || _.result(this.collection, 'url') || urlError();
if (this.isNew()) return base;
- return base + (base.charAt(base.length - 1) == '/' ? '' : '/') + encodeURIComponent(this.id);
+ return base + (base.charAt(base.length - 1) === '/' ? '' : '/') + encodeURIComponent(this.id);
},
// **parse** converts a response into the hash of attributes to be `set` on
// the model. The default implementation is just to pass the response along.
- parse: function(resp, xhr) {
+ parse: function(resp, options) {
return resp;
},
@@ -455,116 +549,62 @@
return this.id == null;
},
- // Call this method to manually fire a `"change"` event for this model and
- // a `"change:attribute"` event for each changed attribute.
- // Calling this will cause all objects observing the model to update.
- change: function(options) {
- options || (options = {});
- var changing = this._changing;
- this._changing = true;
-
- // Silent changes become pending changes.
- for (var attr in this._silent) this._pending[attr] = true;
-
- // Silent changes are triggered.
- var changes = _.extend({}, options.changes, this._silent);
- this._silent = {};
- for (var attr in changes) {
- this.trigger('change:' + attr, this, this.get(attr), options);
- }
- if (changing) return this;
-
- // Continue firing `"change"` events while there are pending changes.
- while (!_.isEmpty(this._pending)) {
- this._pending = {};
- this.trigger('change', this, options);
- // Pending and silent changes still remain.
- for (var attr in this.changed) {
- if (this._pending[attr] || this._silent[attr]) continue;
- delete this.changed[attr];
- }
- this._previousAttributes = _.clone(this.attributes);
- }
-
- this._changing = false;
- return this;
- },
-
- // Determine if the model has changed since the last `"change"` event.
- // If you specify an attribute name, determine if that attribute has changed.
- hasChanged: function(attr) {
- if (!arguments.length) return !_.isEmpty(this.changed);
- return _.has(this.changed, attr);
- },
-
- // Return an object containing all the attributes that have changed, or
- // false if there are no changed attributes. Useful for determining what
- // parts of a view need to be updated and/or what attributes need to be
- // persisted to the server. Unset attributes will be set to undefined.
- // You can also pass an attributes object to diff against the model,
- // determining if there *would be* a change.
- changedAttributes: function(diff) {
- if (!diff) return this.hasChanged() ? _.clone(this.changed) : false;
- var val, changed = false, old = this._previousAttributes;
- for (var attr in diff) {
- if (_.isEqual(old[attr], (val = diff[attr]))) continue;
- (changed || (changed = {}))[attr] = val;
- }
- return changed;
- },
-
- // Get the previous value of an attribute, recorded at the time the last
- // `"change"` event was fired.
- previous: function(attr) {
- if (!arguments.length || !this._previousAttributes) return null;
- return this._previousAttributes[attr];
- },
-
- // Get all of the attributes of the model at the time of the previous
- // `"change"` event.
- previousAttributes: function() {
- return _.clone(this._previousAttributes);
- },
-
- // Check if the model is currently in a valid state. It's only possible to
- // get into an *invalid* state if you're using silent changes.
- isValid: function() {
- return !this.validate(this.attributes);
+ // Check if the model is currently in a valid state.
+ isValid: function(options) {
+ return this._validate({}, _.extend(options || {}, { validate: true }));
},
// Run validation against the next complete set of model attributes,
- // returning `true` if all is well. If a specific `error` callback has
- // been passed, call that instead of firing the general `"error"` event.
+ // returning `true` if all is well. Otherwise, fire an `"invalid"` event.
_validate: function(attrs, options) {
- if (options.silent || !this.validate) return true;
+ if (!options.validate || !this.validate) return true;
attrs = _.extend({}, this.attributes, attrs);
- var error = this.validate(attrs, options);
+ var error = this.validationError = this.validate(attrs, options) || null;
if (!error) return true;
- if (options && options.error) {
- options.error(this, error, options);
- } else {
- this.trigger('error', this, error, options);
- }
+ this.trigger('invalid', this, error, _.extend(options, {validationError: error}));
return false;
}
});
+ // Underscore methods that we want to implement on the Model.
+ var modelMethods = ['keys', 'values', 'pairs', 'invert', 'pick', 'omit'];
+
+ // Mix in each Underscore method as a proxy to `Model#attributes`.
+ _.each(modelMethods, function(method) {
+ Model.prototype[method] = function() {
+ var args = slice.call(arguments);
+ args.unshift(this.attributes);
+ return _[method].apply(_, args);
+ };
+ });
+
// Backbone.Collection
// -------------------
- // Provides a standard collection class for our sets of models, ordered
- // or unordered. If a `comparator` is specified, the Collection will maintain
+ // If models tend to represent a single row of data, a Backbone Collection is
+ // more analagous to a table full of data ... or a small slice or page of that
+ // table, or a collection of rows that belong together for a particular reason
+ // -- all of the messages in this particular folder, all of the documents
+ // belonging to this particular author, and so on. Collections maintain
+ // indexes of their models, both in order, and for lookup by `id`.
+
+ // Create a new **Collection**, perhaps to contain a specific type of `model`.
+ // If a `comparator` is specified, the Collection will maintain
// its models in sort order, as they're added and removed.
var Collection = Backbone.Collection = function(models, options) {
options || (options = {});
if (options.model) this.model = options.model;
- if (options.comparator) this.comparator = options.comparator;
+ if (options.comparator !== void 0) this.comparator = options.comparator;
this._reset();
this.initialize.apply(this, arguments);
- if (models) this.reset(models, {silent: true, parse: options.parse});
+ if (models) this.reset(models, _.extend({silent: true}, options));
};
+ // Default options for `Collection#set`.
+ var setOptions = {add: true, remove: true, merge: true};
+ var addOptions = {add: true, remove: false};
+
// Define the Collection's inheritable methods.
_.extend(Collection.prototype, Events, {
@@ -582,68 +622,27 @@
return this.map(function(model){ return model.toJSON(options); });
},
- // Add a model, or list of models to the set. Pass **silent** to avoid
- // firing the `add` event for every new model.
- add: function(models, options) {
- var i, index, length, model, cid, id, cids = {}, ids = {}, dups = [];
- options || (options = {});
- models = _.isArray(models) ? models.slice() : [models];
-
- // Begin by turning bare objects into model references, and preventing
- // invalid models or duplicate models from being added.
- for (i = 0, length = models.length; i < length; i++) {
- if (!(model = models[i] = this._prepareModel(models[i], options))) {
- throw new Error("Can't add an invalid model to a collection");
- }
- cid = model.cid;
- id = model.id;
- if (cids[cid] || this._byCid[cid] || ((id != null) && (ids[id] || this._byId[id]))) {
- dups.push(i);
- continue;
- }
- cids[cid] = ids[id] = model;
- }
-
- // Remove duplicates.
- i = dups.length;
- while (i--) {
- models.splice(dups[i], 1);
- }
-
- // Listen to added models' events, and index models for lookup by
- // `id` and by `cid`.
- for (i = 0, length = models.length; i < length; i++) {
- (model = models[i]).on('all', this._onModelEvent, this);
- this._byCid[model.cid] = model;
- if (model.id != null) this._byId[model.id] = model;
- }
-
- // Insert models into the collection, re-sorting if needed, and triggering
- // `add` events unless silenced.
- this.length += length;
- index = options.at != null ? options.at : this.models.length;
- splice.apply(this.models, [index, 0].concat(models));
- if (this.comparator) this.sort({silent: true});
- if (options.silent) return this;
- for (i = 0, length = this.models.length; i < length; i++) {
- if (!cids[(model = this.models[i]).cid]) continue;
- options.index = i;
- model.trigger('add', model, this, options);
- }
- return this;
+ // Proxy `Backbone.sync` by default.
+ sync: function() {
+ return Backbone.sync.apply(this, arguments);
},
- // Remove a model, or a list of models from the set. Pass silent to avoid
- // firing the `remove` event for every model removed.
+ // Add a model, or list of models to the set.
+ add: function(models, options) {
+ return this.set(models, _.extend({merge: false}, options, addOptions));
+ },
+
+ // Remove a model, or a list of models from the set.
remove: function(models, options) {
- var i, l, index, model;
+ var singular = !_.isArray(models);
+ models = singular ? [models] : _.clone(models);
options || (options = {});
- models = _.isArray(models) ? models.slice() : [models];
+ var i, l, index, model;
for (i = 0, l = models.length; i < l; i++) {
- model = this.getByCid(models[i]) || this.get(models[i]);
+ model = models[i] = this.get(models[i]);
if (!model) continue;
delete this._byId[model.id];
- delete this._byCid[model.cid];
+ delete this._byId[model.cid];
index = this.indexOf(model);
this.models.splice(index, 1);
this.length--;
@@ -653,14 +652,123 @@
}
this._removeReference(model);
}
- return this;
+ return singular ? models[0] : models;
+ },
+
+ // Update a collection by `set`-ing a new list of models, adding new ones,
+ // removing models that are no longer present, and merging models that
+ // already exist in the collection, as necessary. Similar to **Model#set**,
+ // the core operation for updating the data contained by the collection.
+ set: function(models, options) {
+ options = _.defaults({}, options, setOptions);
+ if (options.parse) models = this.parse(models, options);
+ var singular = !_.isArray(models);
+ models = singular ? (models ? [models] : []) : _.clone(models);
+ var i, l, id, model, attrs, existing, sort;
+ var at = options.at;
+ var targetModel = this.model;
+ var sortable = this.comparator && (at == null) && options.sort !== false;
+ var sortAttr = _.isString(this.comparator) ? this.comparator : null;
+ var toAdd = [], toRemove = [], modelMap = {};
+ var add = options.add, merge = options.merge, remove = options.remove;
+ var order = !sortable && add && remove ? [] : false;
+
+ // Turn bare objects into model references, and prevent invalid models
+ // from being added.
+ for (i = 0, l = models.length; i < l; i++) {
+ attrs = models[i];
+ if (attrs instanceof Model) {
+ id = model = attrs;
+ } else {
+ id = attrs[targetModel.prototype.idAttribute];
+ }
+
+ // If a duplicate is found, prevent it from being added and
+ // optionally merge it into the existing model.
+ if (existing = this.get(id)) {
+ if (remove) modelMap[existing.cid] = true;
+ if (merge) {
+ attrs = attrs === model ? model.attributes : attrs;
+ if (options.parse) attrs = existing.parse(attrs, options);
+ existing.set(attrs, options);
+ if (sortable && !sort && existing.hasChanged(sortAttr)) sort = true;
+ }
+ models[i] = existing;
+
+ // If this is a new, valid model, push it to the `toAdd` list.
+ } else if (add) {
+ model = models[i] = this._prepareModel(attrs, options);
+ if (!model) continue;
+ toAdd.push(model);
+
+ // Listen to added models' events, and index models for lookup by
+ // `id` and by `cid`.
+ model.on('all', this._onModelEvent, this);
+ this._byId[model.cid] = model;
+ if (model.id != null) this._byId[model.id] = model;
+ }
+ if (order) order.push(existing || model);
+ }
+
+ // Remove nonexistent models if appropriate.
+ if (remove) {
+ for (i = 0, l = this.length; i < l; ++i) {
+ if (!modelMap[(model = this.models[i]).cid]) toRemove.push(model);
+ }
+ if (toRemove.length) this.remove(toRemove, options);
+ }
+
+ // See if sorting is needed, update `length` and splice in new models.
+ if (toAdd.length || (order && order.length)) {
+ if (sortable) sort = true;
+ this.length += toAdd.length;
+ if (at != null) {
+ for (i = 0, l = toAdd.length; i < l; i++) {
+ this.models.splice(at + i, 0, toAdd[i]);
+ }
+ } else {
+ if (order) this.models.length = 0;
+ var orderedModels = order || toAdd;
+ for (i = 0, l = orderedModels.length; i < l; i++) {
+ this.models.push(orderedModels[i]);
+ }
+ }
+ }
+
+ // Silently sort the collection if appropriate.
+ if (sort) this.sort({silent: true});
+
+ // Unless silenced, it's time to fire all appropriate add/sort events.
+ if (!options.silent) {
+ for (i = 0, l = toAdd.length; i < l; i++) {
+ (model = toAdd[i]).trigger('add', model, this, options);
+ }
+ if (sort || (order && order.length)) this.trigger('sort', this, options);
+ }
+
+ // Return the added (or merged) model (or models).
+ return singular ? models[0] : models;
+ },
+
+ // When you have more items than you want to add or remove individually,
+ // you can reset the entire set with a new list of models, without firing
+ // any granular `add` or `remove` events. Fires `reset` when finished.
+ // Useful for bulk operations and optimizations.
+ reset: function(models, options) {
+ options || (options = {});
+ for (var i = 0, l = this.models.length; i < l; i++) {
+ this._removeReference(this.models[i]);
+ }
+ options.previousModels = this.models;
+ this._reset();
+ models = this.add(models, _.extend({silent: true}, options));
+ if (!options.silent) this.trigger('reset', this, options);
+ return models;
},
// Add a model to the end of the collection.
push: function(model, options) {
- model = this._prepareModel(model, options);
- this.add(model, options);
- return model;
+ return this.add(model, _.extend({at: this.length}, options));
},
// Remove a model from the end of the collection.
@@ -672,9 +780,7 @@
// Add a model to the beginning of the collection.
unshift: function(model, options) {
- model = this._prepareModel(model, options);
- this.add(model, _.extend({at: 0}, options));
- return model;
+ return this.add(model, _.extend({at: 0}, options));
},
// Remove a model from the beginning of the collection.
@@ -684,15 +790,15 @@
return model;
},
- // Get a model from the set by id.
- get: function(id) {
- if (id == null) return void 0;
- return this._byId[id.id != null ? id.id : id];
+ // Slice out a sub-array of models from the collection.
+ slice: function() {
+ return slice.apply(this.models, arguments);
},
- // Get a model from the set by client id.
- getByCid: function(cid) {
- return cid && this._byCid[cid.cid || cid];
+ // Get a model from the set by id.
+ get: function(obj) {
+ if (obj == null) return void 0;
+ return this._byId[obj.id] || this._byId[obj.cid] || this._byId[obj];
},
// Get the model at the given index.
@@ -700,10 +806,11 @@
return this.models[index];
},
- // Return models with matching attributes. Useful for simple cases of `filter`.
- where: function(attrs) {
- if (_.isEmpty(attrs)) return [];
- return this.filter(function(model) {
+ // Return models with matching attributes. Useful for simple cases of
+ // `filter`.
+ where: function(attrs, first) {
+ if (_.isEmpty(attrs)) return first ? void 0 : [];
+ return this[first ? 'find' : 'filter'](function(model) {
for (var key in attrs) {
if (attrs[key] !== model.get(key)) return false;
}
@@ -711,75 +818,65 @@
});
},
+ // Return the first model with matching attributes. Useful for simple cases
+ // of `find`.
+ findWhere: function(attrs) {
+ return this.where(attrs, true);
+ },
+
// Force the collection to re-sort itself. You don't need to call this under
// normal circumstances, as the set will maintain sort order as each item
// is added.
sort: function(options) {
- options || (options = {});
if (!this.comparator) throw new Error('Cannot sort a set without a comparator');
- var boundComparator = _.bind(this.comparator, this);
- if (this.comparator.length == 1) {
- this.models = this.sortBy(boundComparator);
+ options || (options = {});
+
+ // Run sort based on type of `comparator`.
+ if (_.isString(this.comparator) || this.comparator.length === 1) {
+ this.models = this.sortBy(this.comparator, this);
} else {
- this.models.sort(boundComparator);
+ this.models.sort(_.bind(this.comparator, this));
}
- if (!options.silent) this.trigger('reset', this, options);
+
+ if (!options.silent) this.trigger('sort', this, options);
return this;
},
// Pluck an attribute from each model in the collection.
pluck: function(attr) {
- return _.map(this.models, function(model){ return model.get(attr); });
- },
-
- // When you have more items than you want to add or remove individually,
- // you can reset the entire set with a new list of models, without firing
- // any `add` or `remove` events. Fires `reset` when finished.
- reset: function(models, options) {
- models || (models = []);
- options || (options = {});
- for (var i = 0, l = this.models.length; i < l; i++) {
- this._removeReference(this.models[i]);
- }
- this._reset();
- this.add(models, _.extend({silent: true}, options));
- if (!options.silent) this.trigger('reset', this, options);
- return this;
+ return _.invoke(this.models, 'get', attr);
},
// Fetch the default set of models for this collection, resetting the
- // collection when they arrive. If `add: true` is passed, appends the
- // models to the collection instead of resetting.
+ // collection when they arrive. If `reset: true` is passed, the response
+ // data will be passed through the `reset` method instead of `set`.
fetch: function(options) {
options = options ? _.clone(options) : {};
- if (options.parse === undefined) options.parse = true;
- var collection = this;
+ if (options.parse === void 0) options.parse = true;
var success = options.success;
- options.success = function(resp, status, xhr) {
- collection[options.add ? 'add' : 'reset'](collection.parse(resp, xhr), options);
- if (success) success(collection, resp);
+ var collection = this;
+ options.success = function(resp) {
+ var method = options.reset ? 'reset' : 'set';
+ collection[method](resp, options);
+ if (success) success(collection, resp, options);
+ collection.trigger('sync', collection, resp, options);
};
- options.error = Backbone.wrapError(options.error, collection, options);
- return (this.sync || Backbone.sync).call(this, 'read', this, options);
+ wrapError(this, options);
+ return this.sync('read', this, options);
},
// Create a new instance of a model in this collection. Add the model to the
// collection immediately, unless `wait: true` is passed, in which case we
// wait for the server to agree.
create: function(model, options) {
- var coll = this;
options = options ? _.clone(options) : {};
- model = this._prepareModel(model, options);
- if (!model) return false;
- if (!options.wait) coll.add(model, options);
+ if (!(model = this._prepareModel(model, options))) return false;
+ if (!options.wait) this.add(model, options);
+ var collection = this;
var success = options.success;
- options.success = function(nextModel, resp, xhr) {
- if (options.wait) coll.add(nextModel, options);
- if (success) {
- success(nextModel, resp);
- } else {
- nextModel.trigger('sync', model, resp, options);
- }
+ options.success = function(model, resp, options) {
+ if (options.wait) collection.add(model, options);
+ if (success) success(model, resp, options);
};
model.save(null, options);
return model;
@@ -787,44 +884,41 @@
// **parse** converts a response into a list of models to be added to the
// collection. The default implementation is just to pass it through.
- parse: function(resp, xhr) {
+ parse: function(resp, options) {
return resp;
},
- // Proxy to _'s chain. Can't be proxied the same way the rest of the
- // underscore methods are proxied because it relies on the underscore
- // constructor.
- chain: function () {
- return _(this.models).chain();
+ // Create a new collection with an identical list of models as this one.
+ clone: function() {
+ return new this.constructor(this.models);
},
- // Reset all internal state. Called when the collection is reset.
- _reset: function(options) {
+ // Private method to reset all internal state. Called when the collection
+ // is first initialized or reset.
+ _reset: function() {
this.length = 0;
this.models = [];
this._byId = {};
- this._byCid = {};
},
- // Prepare a model or hash of attributes to be added to this collection.
- _prepareModel: function(model, options) {
- options || (options = {});
- if (!(model instanceof Model)) {
- var attrs = model;
- options.collection = this;
- model = new this.model(attrs, options);
- if (!model._validate(model.attributes, options)) model = false;
- } else if (!model.collection) {
- model.collection = this;
+ // Prepare a hash of attributes (or other model) to be added to this
+ // collection.
+ _prepareModel: function(attrs, options) {
+ if (attrs instanceof Model) {
+ if (!attrs.collection) attrs.collection = this;
+ return attrs;
}
- return model;
+ options = options ? _.clone(options) : {};
+ options.collection = this;
+ var model = new this.model(attrs, options);
+ if (!model.validationError) return model;
+ this.trigger('invalid', this, model.validationError, options);
+ return false;
},
- // Internal method to remove a model's ties to a collection.
+ // Internal method to sever a model's ties to a collection.
_removeReference: function(model) {
- if (this == model.collection) {
- delete model.collection;
- }
+ if (this === model.collection) delete model.collection;
model.off('all', this._onModelEvent, this);
},
@@ -833,13 +927,11 @@
// events simply proxy through. "add" and "remove" events that originate
// in other collections are ignored.
_onModelEvent: function(event, model, collection, options) {
- if ((event == 'add' || event == 'remove') && collection != this) return;
- if (event == 'destroy') {
- this.remove(model, options);
- }
+ if ((event === 'add' || event === 'remove') && collection !== this) return;
+ if (event === 'destroy') this.remove(model, options);
if (model && event === 'change:' + model.idAttribute) {
delete this._byId[model.previous(model.idAttribute)];
- this._byId[model.id] = model;
+ if (model.id != null) this._byId[model.id] = model;
}
this.trigger.apply(this, arguments);
}
@@ -847,302 +939,54 @@
});
// Underscore methods that we want to implement on the Collection.
- var methods = ['forEach', 'each', 'map', 'reduce', 'reduceRight', 'find',
- 'detect', 'filter', 'select', 'reject', 'every', 'all', 'some', 'any',
- 'include', 'contains', 'invoke', 'max', 'min', 'sortBy', 'sortedIndex',
- 'toArray', 'size', 'first', 'initial', 'rest', 'last', 'without', 'indexOf',
- 'shuffle', 'lastIndexOf', 'isEmpty', 'groupBy'];
+ // 90% of the core usefulness of Backbone Collections is actually implemented
+ // right here:
+ var methods = ['forEach', 'each', 'map', 'collect', 'reduce', 'foldl',
+ 'inject', 'reduceRight', 'foldr', 'find', 'detect', 'filter', 'select',
+ 'reject', 'every', 'all', 'some', 'any', 'include', 'contains', 'invoke',
+ 'max', 'min', 'toArray', 'size', 'first', 'head', 'take', 'initial', 'rest',
+ 'tail', 'drop', 'last', 'without', 'difference', 'indexOf', 'shuffle',
+ 'lastIndexOf', 'isEmpty', 'chain'];
// Mix in each Underscore method as a proxy to `Collection#models`.
_.each(methods, function(method) {
Collection.prototype[method] = function() {
- return _[method].apply(_, [this.models].concat(_.toArray(arguments)));
+ var args = slice.call(arguments);
+ args.unshift(this.models);
+ return _[method].apply(_, args);
};
});
- // Backbone.Router
- // -------------------
+ // Underscore methods that take a property name as an argument.
+ var attributeMethods = ['groupBy', 'countBy', 'sortBy'];
- // Routers map faux-URLs to actions, and fire events when routes are
- // matched. Creating a new one sets its `routes` hash, if not set statically.
- var Router = Backbone.Router = function(options) {
- options || (options = {});
- if (options.routes) this.routes = options.routes;
- this._bindRoutes();
- this.initialize.apply(this, arguments);
- };
-
- // Cached regular expressions for matching named param parts and splatted
- // parts of route strings.
- var namedParam = /:\w+/g;
- var splatParam = /\*\w+/g;
- var escapeRegExp = /[-[\]{}()+?.,\\^$|#\s]/g;
-
- // Set up all inheritable **Backbone.Router** properties and methods.
- _.extend(Router.prototype, Events, {
-
- // Initialize is an empty function by default. Override it with your own
- // initialization logic.
- initialize: function(){},
-
- // Manually bind a single named route to a callback. For example:
- //
- // this.route('search/:query/p:num', 'search', function(query, num) {
- // ...
- // });
- //
- route: function(route, name, callback) {
- Backbone.history || (Backbone.history = new History);
- if (!_.isRegExp(route)) route = this._routeToRegExp(route);
- if (!callback) callback = this[name];
- Backbone.history.route(route, _.bind(function(fragment) {
- var args = this._extractParameters(route, fragment);
- callback && callback.apply(this, args);
- this.trigger.apply(this, ['route:' + name].concat(args));
- Backbone.history.trigger('route', this, name, args);
- }, this));
- return this;
- },
-
- // Simple proxy to `Backbone.history` to save a fragment into the history.
- navigate: function(fragment, options) {
- Backbone.history.navigate(fragment, options);
- },
-
- // Bind all defined routes to `Backbone.history`. We have to reverse the
- // order of the routes here to support behavior where the most general
- // routes can be defined at the bottom of the route map.
- _bindRoutes: function() {
- if (!this.routes) return;
- var routes = [];
- for (var route in this.routes) {
- routes.unshift([route, this.routes[route]]);
- }
- for (var i = 0, l = routes.length; i < l; i++) {
- this.route(routes[i][0], routes[i][1], this[routes[i][1]]);
- }
- },
-
- // Convert a route string into a regular expression, suitable for matching
- // against the current location hash.
- _routeToRegExp: function(route) {
- route = route.replace(escapeRegExp, '\\$&')
- .replace(namedParam, '([^\/]+)')
- .replace(splatParam, '(.*?)');
- return new RegExp('^' + route + '$');
- },
-
- // Given a route, and a URL fragment that it matches, return the array of
- // extracted parameters.
- _extractParameters: function(route, fragment) {
- return route.exec(fragment).slice(1);
- }
-
- });
-
- // Backbone.History
- // ----------------
-
- // Handles cross-browser history management, based on URL fragments. If the
- // browser does not support `onhashchange`, falls back to polling.
- var History = Backbone.History = function() {
- this.handlers = [];
- _.bindAll(this, 'checkUrl');
- };
-
- // Cached regex for cleaning leading hashes and slashes .
- var routeStripper = /^[#\/]/;
-
- // Cached regex for detecting MSIE.
- var isExplorer = /msie [\w.]+/;
-
- // Has the history handling already been started?
- History.started = false;
-
- // Set up all inheritable **Backbone.History** properties and methods.
- _.extend(History.prototype, Events, {
-
- // The default interval to poll for hash changes, if necessary, is
- // twenty times a second.
- interval: 50,
-
- // Gets the true hash value. Cannot use location.hash directly due to bug
- // in Firefox where location.hash will always be decoded.
- getHash: function(windowOverride) {
- var loc = windowOverride ? windowOverride.location : window.location;
- var match = loc.href.match(/#(.*)$/);
- return match ? match[1] : '';
- },
-
- // Get the cross-browser normalized URL fragment, either from the URL,
- // the hash, or the override.
- getFragment: function(fragment, forcePushState) {
- if (fragment == null) {
- if (this._hasPushState || forcePushState) {
- fragment = window.location.pathname;
- var search = window.location.search;
- if (search) fragment += search;
- } else {
- fragment = this.getHash();
- }
- }
- if (!fragment.indexOf(this.options.root)) fragment = fragment.substr(this.options.root.length);
- return fragment.replace(routeStripper, '');
- },
-
- // Start the hash change handling, returning `true` if the current URL matches
- // an existing route, and `false` otherwise.
- start: function(options) {
- if (History.started) throw new Error("Backbone.history has already been started");
- History.started = true;
-
- // Figure out the initial configuration. Do we need an iframe?
- // Is pushState desired ... is it available?
- this.options = _.extend({}, {root: '/'}, this.options, options);
- this._wantsHashChange = this.options.hashChange !== false;
- this._wantsPushState = !!this.options.pushState;
- this._hasPushState = !!(this.options.pushState && window.history && window.history.pushState);
- var fragment = this.getFragment();
- var docMode = document.documentMode;
- var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
-
- if (oldIE) {
- this.iframe = $('').hide().appendTo('body')[0].contentWindow;
- this.navigate(fragment);
- }
-
- // Depending on whether we're using pushState or hashes, and whether
- // 'onhashchange' is supported, determine how we check the URL state.
- if (this._hasPushState) {
- $(window).bind('popstate', this.checkUrl);
- } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
- $(window).bind('hashchange', this.checkUrl);
- } else if (this._wantsHashChange) {
- this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
- }
-
- // Determine if we need to change the base url, for a pushState link
- // opened by a non-pushState browser.
- this.fragment = fragment;
- var loc = window.location;
- var atRoot = loc.pathname == this.options.root;
-
- // If we've started off with a route from a `pushState`-enabled browser,
- // but we're currently in a browser that doesn't support it...
- if (this._wantsHashChange && this._wantsPushState && !this._hasPushState && !atRoot) {
- this.fragment = this.getFragment(null, true);
- window.location.replace(this.options.root + '#' + this.fragment);
- // Return immediately as browser will do redirect to new url
- return true;
-
- // Or if we've started out with a hash-based route, but we're currently
- // in a browser where it could be `pushState`-based instead...
- } else if (this._wantsPushState && this._hasPushState && atRoot && loc.hash) {
- this.fragment = this.getHash().replace(routeStripper, '');
- window.history.replaceState({}, document.title, loc.protocol + '//' + loc.host + this.options.root + this.fragment);
- }
-
- if (!this.options.silent) {
- return this.loadUrl();
- }
- },
-
- // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
- // but possibly useful for unit testing Routers.
- stop: function() {
- $(window).unbind('popstate', this.checkUrl).unbind('hashchange', this.checkUrl);
- clearInterval(this._checkUrlInterval);
- History.started = false;
- },
-
- // Add a route to be tested when the fragment changes. Routes added later
- // may override previous routes.
- route: function(route, callback) {
- this.handlers.unshift({route: route, callback: callback});
- },
-
- // Checks the current URL to see if it has changed, and if it has,
- // calls `loadUrl`, normalizing across the hidden iframe.
- checkUrl: function(e) {
- var current = this.getFragment();
- if (current == this.fragment && this.iframe) current = this.getFragment(this.getHash(this.iframe));
- if (current == this.fragment) return false;
- if (this.iframe) this.navigate(current);
- this.loadUrl() || this.loadUrl(this.getHash());
- },
-
- // Attempt to load the current URL fragment. If a route succeeds with a
- // match, returns `true`. If no defined routes matches the fragment,
- // returns `false`.
- loadUrl: function(fragmentOverride) {
- var fragment = this.fragment = this.getFragment(fragmentOverride);
- var matched = _.any(this.handlers, function(handler) {
- if (handler.route.test(fragment)) {
- handler.callback(fragment);
- return true;
- }
- });
- return matched;
- },
-
- // Save a fragment into the hash history, or replace the URL state if the
- // 'replace' option is passed. You are responsible for properly URL-encoding
- // the fragment in advance.
- //
- // The options object can contain `trigger: true` if you wish to have the
- // route callback be fired (not usually desirable), or `replace: true`, if
- // you wish to modify the current URL without adding an entry to the history.
- navigate: function(fragment, options) {
- if (!History.started) return false;
- if (!options || options === true) options = {trigger: options};
- var frag = (fragment || '').replace(routeStripper, '');
- if (this.fragment == frag) return;
-
- // If pushState is available, we use it to set the fragment as a real URL.
- if (this._hasPushState) {
- if (frag.indexOf(this.options.root) != 0) frag = this.options.root + frag;
- this.fragment = frag;
- window.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, frag);
-
- // If hash changes haven't been explicitly disabled, update the hash
- // fragment to store history.
- } else if (this._wantsHashChange) {
- this.fragment = frag;
- this._updateHash(window.location, frag, options.replace);
- if (this.iframe && (frag != this.getFragment(this.getHash(this.iframe)))) {
- // Opening and closing the iframe tricks IE7 and earlier to push a history entry on hash-tag change.
- // When replace is true, we don't want this.
- if(!options.replace) this.iframe.document.open().close();
- this._updateHash(this.iframe.location, frag, options.replace);
- }
-
- // If you've told us that you explicitly don't want fallback hashchange-
- // based history, then `navigate` becomes a page refresh.
- } else {
- window.location.assign(this.options.root + fragment);
- }
- if (options.trigger) this.loadUrl(fragment);
- },
-
- // Update the hash location, either replacing the current entry, or adding
- // a new one to the browser history.
- _updateHash: function(location, fragment, replace) {
- if (replace) {
- location.replace(location.toString().replace(/(javascript:|#).*$/, '') + '#' + fragment);
- } else {
- location.hash = fragment;
- }
- }
+ // Use attributes instead of properties.
+ _.each(attributeMethods, function(method) {
+ Collection.prototype[method] = function(value, context) {
+ var iterator = _.isFunction(value) ? value : function(model) {
+ return model.get(value);
+ };
+ return _[method](this.models, iterator, context);
+ };
});
// Backbone.View
// -------------
+ // Backbone Views are almost more convention than they are actual code. A View
+ // is simply a JavaScript object that represents a logical chunk of UI in the
+ // DOM. This might be a single item, an entire list, a sidebar or panel, or
+ // even the surrounding frame which wraps your whole app. Defining a chunk of
+ // UI as a **View** allows you to define your DOM events declaratively, without
+ // having to worry about render order ... and makes it easy for the view to
+ // react to specific changes in the state of your models.
+
// Creating a Backbone.View creates its initial element outside of the DOM,
// if an existing element is not provided...
var View = Backbone.View = function(options) {
this.cid = _.uniqueId('view');
- this._configure(options || {});
+ options || (options = {});
+ _.extend(this, _.pick(options, viewOptions));
this._ensureElement();
this.initialize.apply(this, arguments);
this.delegateEvents();
@@ -1152,7 +996,7 @@
var delegateEventSplitter = /^(\S+)\s*(.*)$/;
// List of view options to be merged as properties.
- var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName'];
+ var viewOptions = ['model', 'collection', 'el', 'id', 'attributes', 'className', 'tagName', 'events'];
// Set up all inheritable **Backbone.View** properties and methods.
_.extend(View.prototype, Events, {
@@ -1161,7 +1005,7 @@
tagName: 'div',
// jQuery delegate for element lookup, scoped to DOM elements within the
- // current view. This should be prefered to global lookups where possible.
+ // current view. This should be preferred to global lookups where possible.
$: function(selector) {
return this.$el.find(selector);
},
@@ -1177,30 +1021,19 @@
return this;
},
- // Remove this view from the DOM. Note that the view isn't present in the
- // DOM by default, so calling this method may be a no-op.
+ // Remove this view by taking the element out of the DOM, and removing any
+ // applicable Backbone.Events listeners.
remove: function() {
this.$el.remove();
+ this.stopListening();
return this;
},
- // For small amounts of DOM Elements, where a full-blown template isn't
- // needed, use **make** to manufacture elements, one at a time.
- //
- // var el = this.make('li', {'class': 'row'}, this.model.escape('title'));
- //
- make: function(tagName, attributes, content) {
- var el = document.createElement(tagName);
- if (attributes) $(el).attr(attributes);
- if (content) $(el).html(content);
- return el;
- },
-
// Change the view's element (`this.el` property), including event
// re-delegation.
setElement: function(element, delegate) {
if (this.$el) this.undelegateEvents();
- this.$el = (element instanceof $) ? element : $(element);
+ this.$el = element instanceof Backbone.$ ? element : Backbone.$(element);
this.el = this.$el[0];
if (delegate !== false) this.delegateEvents();
return this;
@@ -1212,7 +1045,7 @@
//
// {
// 'mousedown .title': 'edit',
- // 'click .button': 'save'
+ // 'click .button': 'save',
// 'click .open': function(e) { ... }
// }
//
@@ -1222,41 +1055,32 @@
// This only works for delegate-able events: not `focus`, `blur`, and
// not `change`, `submit`, and `reset` in Internet Explorer.
delegateEvents: function(events) {
- if (!(events || (events = getValue(this, 'events')))) return;
+ if (!(events || (events = _.result(this, 'events')))) return this;
this.undelegateEvents();
for (var key in events) {
var method = events[key];
if (!_.isFunction(method)) method = this[events[key]];
- if (!method) throw new Error('Method "' + events[key] + '" does not exist');
+ if (!method) continue;
+
var match = key.match(delegateEventSplitter);
var eventName = match[1], selector = match[2];
method = _.bind(method, this);
eventName += '.delegateEvents' + this.cid;
if (selector === '') {
- this.$el.bind(eventName, method);
+ this.$el.on(eventName, method);
} else {
- this.$el.delegate(selector, eventName, method);
+ this.$el.on(eventName, selector, method);
}
}
+ return this;
},
// Clears all callbacks previously bound to the view with `delegateEvents`.
// You usually don't need to use this, but may wish to if you have multiple
// Backbone views attached to the same DOM element.
undelegateEvents: function() {
- this.$el.unbind('.delegateEvents' + this.cid);
- },
-
- // Performs the initial configuration of a View with a set of options.
- // Keys with special meaning *(model, collection, id, className)*, are
- // attached directly to the view.
- _configure: function(options) {
- if (this.options) options = _.extend({}, this.options, options);
- for (var i = 0, l = viewOptions.length; i < l; i++) {
- var attr = viewOptions[i];
- if (options[attr]) this[attr] = options[attr];
- }
- this.options = options;
+ this.$el.off('.delegateEvents' + this.cid);
+ return this;
},
// Ensure that the View has a DOM element to render into.
@@ -1265,38 +1089,21 @@
// an element from the `id`, `className` and `tagName` properties.
_ensureElement: function() {
if (!this.el) {
- var attrs = getValue(this, 'attributes') || {};
- if (this.id) attrs.id = this.id;
- if (this.className) attrs['class'] = this.className;
- this.setElement(this.make(this.tagName, attrs), false);
+ var attrs = _.extend({}, _.result(this, 'attributes'));
+ if (this.id) attrs.id = _.result(this, 'id');
+ if (this.className) attrs['class'] = _.result(this, 'className');
+ var $el = Backbone.$('<' + _.result(this, 'tagName') + '>').attr(attrs);
+ this.setElement($el, false);
} else {
- this.setElement(this.el, false);
+ this.setElement(_.result(this, 'el'), false);
}
}
});
- // The self-propagating extend function that Backbone classes use.
- var extend = function (protoProps, classProps) {
- var child = inherits(this, protoProps, classProps);
- child.extend = this.extend;
- return child;
- };
-
- // Set up inheritance for the model, collection, and view.
- Model.extend = Collection.extend = Router.extend = View.extend = extend;
-
// Backbone.sync
// -------------
- // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
- var methodMap = {
- 'create': 'POST',
- 'update': 'PUT',
- 'delete': 'DELETE',
- 'read': 'GET'
- };
-
// Override this function to change the manner in which Backbone persists
// models to the server. You will be passed the type of request, and the
// model in question. By default, makes a RESTful Ajax request
@@ -1316,116 +1123,459 @@
var type = methodMap[method];
// Default options, unless specified.
- options || (options = {});
+ _.defaults(options || (options = {}), {
+ emulateHTTP: Backbone.emulateHTTP,
+ emulateJSON: Backbone.emulateJSON
+ });
// Default JSON-request options.
var params = {type: type, dataType: 'json'};
// Ensure that we have a URL.
if (!options.url) {
- params.url = getValue(model, 'url') || urlError();
+ params.url = _.result(model, 'url') || urlError();
}
// Ensure that we have the appropriate request data.
- if (!options.data && model && (method == 'create' || method == 'update')) {
+ if (options.data == null && model && (method === 'create' || method === 'update' || method === 'patch')) {
params.contentType = 'application/json';
- params.data = JSON.stringify(model.toJSON());
+ params.data = JSON.stringify(options.attrs || model.toJSON(options));
}
// For older servers, emulate JSON by encoding the request into an HTML-form.
- if (Backbone.emulateJSON) {
+ if (options.emulateJSON) {
params.contentType = 'application/x-www-form-urlencoded';
params.data = params.data ? {model: params.data} : {};
}
// For older servers, emulate HTTP by mimicking the HTTP method with `_method`
// And an `X-HTTP-Method-Override` header.
- if (Backbone.emulateHTTP) {
- if (type === 'PUT' || type === 'DELETE') {
- if (Backbone.emulateJSON) params.data._method = type;
- params.type = 'POST';
- params.beforeSend = function(xhr) {
- xhr.setRequestHeader('X-HTTP-Method-Override', type);
- };
- }
+ if (options.emulateHTTP && (type === 'PUT' || type === 'DELETE' || type === 'PATCH')) {
+ params.type = 'POST';
+ if (options.emulateJSON) params.data._method = type;
+ var beforeSend = options.beforeSend;
+ options.beforeSend = function(xhr) {
+ xhr.setRequestHeader('X-HTTP-Method-Override', type);
+ if (beforeSend) return beforeSend.apply(this, arguments);
+ };
}
// Don't process data on a non-GET request.
- if (params.type !== 'GET' && !Backbone.emulateJSON) {
+ if (params.type !== 'GET' && !options.emulateJSON) {
params.processData = false;
}
+ // If we're sending a `PATCH` request, and we're in an old Internet Explorer
+ // that still has ActiveX enabled by default, override jQuery to use that
+ // for XHR instead. Remove this line when jQuery supports `PATCH` on IE8.
+ if (params.type === 'PATCH' && noXhrPatch) {
+ params.xhr = function() {
+ return new ActiveXObject("Microsoft.XMLHTTP");
+ };
+ }
+
// Make the request, allowing the user to override any Ajax options.
- return $.ajax(_.extend(params, options));
+ var xhr = options.xhr = Backbone.ajax(_.extend(params, options));
+ model.trigger('request', model, xhr, options);
+ return xhr;
};
- // Wrap an optional error callback with a fallback error event.
- Backbone.wrapError = function(onError, originalModel, options) {
- return function(model, resp) {
- resp = model === originalModel ? resp : model;
- if (onError) {
- onError(originalModel, resp, options);
- } else {
- originalModel.trigger('error', originalModel, resp, options);
- }
- };
+ var noXhrPatch = typeof window !== 'undefined' && !!window.ActiveXObject && !(window.XMLHttpRequest && (new XMLHttpRequest).dispatchEvent);
+
+ // Map from CRUD to HTTP for our default `Backbone.sync` implementation.
+ var methodMap = {
+ 'create': 'POST',
+ 'update': 'PUT',
+ 'patch': 'PATCH',
+ 'delete': 'DELETE',
+ 'read': 'GET'
};
+ // Set the default implementation of `Backbone.ajax` to proxy through to `$`.
+ // Override this if you'd like to use a different library.
+ Backbone.ajax = function() {
+ return Backbone.$.ajax.apply(Backbone.$, arguments);
+ };
+
+ // Backbone.Router
+ // ---------------
+
+ // Routers map faux-URLs to actions, and fire events when routes are
+ // matched. Creating a new one sets its `routes` hash, if not set statically.
+ var Router = Backbone.Router = function(options) {
+ options || (options = {});
+ if (options.routes) this.routes = options.routes;
+ this._bindRoutes();
+ this.initialize.apply(this, arguments);
+ };
+
+ // Cached regular expressions for matching named param parts and splatted
+ // parts of route strings.
+ var optionalParam = /\((.*?)\)/g;
+ var namedParam = /(\(\?)?:\w+/g;
+ var splatParam = /\*\w+/g;
+ var escapeRegExp = /[\-{}\[\]+?.,\\\^$|#\s]/g;
+
+ // Set up all inheritable **Backbone.Router** properties and methods.
+ _.extend(Router.prototype, Events, {
+
+ // Initialize is an empty function by default. Override it with your own
+ // initialization logic.
+ initialize: function(){},
+
+ // Manually bind a single named route to a callback. For example:
+ //
+ // this.route('search/:query/p:num', 'search', function(query, num) {
+ // ...
+ // });
+ //
+ route: function(route, name, callback) {
+ if (!_.isRegExp(route)) route = this._routeToRegExp(route);
+ if (_.isFunction(name)) {
+ callback = name;
+ name = '';
+ }
+ if (!callback) callback = this[name];
+ var router = this;
+ Backbone.history.route(route, function(fragment) {
+ var args = router._extractParameters(route, fragment);
+ callback && callback.apply(router, args);
+ router.trigger.apply(router, ['route:' + name].concat(args));
+ router.trigger('route', name, args);
+ Backbone.history.trigger('route', router, name, args);
+ });
+ return this;
+ },
+
+ // Simple proxy to `Backbone.history` to save a fragment into the history.
+ navigate: function(fragment, options) {
+ Backbone.history.navigate(fragment, options);
+ return this;
+ },
+
+ // Bind all defined routes to `Backbone.history`. We have to reverse the
+ // order of the routes here to support behavior where the most general
+ // routes can be defined at the bottom of the route map.
+ _bindRoutes: function() {
+ if (!this.routes) return;
+ this.routes = _.result(this, 'routes');
+ var route, routes = _.keys(this.routes);
+ while ((route = routes.pop()) != null) {
+ this.route(route, this.routes[route]);
+ }
+ },
+
+ // Convert a route string into a regular expression, suitable for matching
+ // against the current location hash.
+ _routeToRegExp: function(route) {
+ route = route.replace(escapeRegExp, '\\$&')
+ .replace(optionalParam, '(?:$1)?')
+ .replace(namedParam, function(match, optional) {
+ return optional ? match : '([^\/]+)';
+ })
+ .replace(splatParam, '(.*?)');
+ return new RegExp('^' + route + '$');
+ },
+
+ // Given a route, and a URL fragment that it matches, return the array of
+ // extracted decoded parameters. Empty or unmatched parameters will be
+ // treated as `null` to normalize cross-browser behavior.
+ _extractParameters: function(route, fragment) {
+ var params = route.exec(fragment).slice(1);
+ return _.map(params, function(param) {
+ return param ? decodeURIComponent(param) : null;
+ });
+ }
+
+ });
+
+ // Backbone.History
+ // ----------------
+
+ // Handles cross-browser history management, based on either
+ // [pushState](http://diveintohtml5.info/history.html) and real URLs, or
+ // [onhashchange](https://developer.mozilla.org/en-US/docs/DOM/window.onhashchange)
+ // and URL fragments. If the browser supports neither (old IE, natch),
+ // falls back to polling.
+ var History = Backbone.History = function() {
+ this.handlers = [];
+ _.bindAll(this, 'checkUrl');
+
+ // Ensure that `History` can be used outside of the browser.
+ if (typeof window !== 'undefined') {
+ this.location = window.location;
+ this.history = window.history;
+ }
+ };
+
+ // Cached regex for stripping a leading hash/slash and trailing space.
+ var routeStripper = /^[#\/]|\s+$/g;
+
+ // Cached regex for stripping leading and trailing slashes.
+ var rootStripper = /^\/+|\/+$/g;
+
+ // Cached regex for detecting MSIE.
+ var isExplorer = /msie [\w.]+/;
+
+ // Cached regex for removing a trailing slash.
+ var trailingSlash = /\/$/;
+
+ // Cached regex for stripping urls of hash and query.
+ var pathStripper = /[?#].*$/;
+
+ // Has the history handling already been started?
+ History.started = false;
+
+ // Set up all inheritable **Backbone.History** properties and methods.
+ _.extend(History.prototype, Events, {
+
+ // The default interval to poll for hash changes, if necessary, is
+ // twenty times a second.
+ interval: 50,
+
+ // Gets the true hash value. Cannot use location.hash directly due to bug
+ // in Firefox where location.hash will always be decoded.
+ getHash: function(window) {
+ var match = (window || this).location.href.match(/#(.*)$/);
+ return match ? match[1] : '';
+ },
+
+ // Get the cross-browser normalized URL fragment, either from the URL,
+ // the hash, or the override.
+ getFragment: function(fragment, forcePushState) {
+ if (fragment == null) {
+ if (this._hasPushState || !this._wantsHashChange || forcePushState) {
+ fragment = this.location.pathname;
+ var root = this.root.replace(trailingSlash, '');
+ if (!fragment.indexOf(root)) fragment = fragment.slice(root.length);
+ } else {
+ fragment = this.getHash();
+ }
+ }
+ return fragment.replace(routeStripper, '');
+ },
+
+ // Start the hash change handling, returning `true` if the current URL matches
+ // an existing route, and `false` otherwise.
+ start: function(options) {
+ if (History.started) throw new Error("Backbone.history has already been started");
+ History.started = true;
+
+ // Figure out the initial configuration. Do we need an iframe?
+ // Is pushState desired ... is it available?
+ this.options = _.extend({root: '/'}, this.options, options);
+ this.root = this.options.root;
+ this._wantsHashChange = this.options.hashChange !== false;
+ this._wantsPushState = !!this.options.pushState;
+ this._hasPushState = !!(this.options.pushState && this.history && this.history.pushState);
+ var fragment = this.getFragment();
+ var docMode = document.documentMode;
+ var oldIE = (isExplorer.exec(navigator.userAgent.toLowerCase()) && (!docMode || docMode <= 7));
+
+ // Normalize root to always include a leading and trailing slash.
+ this.root = ('/' + this.root + '/').replace(rootStripper, '/');
+
+ if (oldIE && this._wantsHashChange) {
+ this.iframe = Backbone.$('').hide().appendTo('body')[0].contentWindow;
+ this.navigate(fragment);
+ }
+
+ // Depending on whether we're using pushState or hashes, and whether
+ // 'onhashchange' is supported, determine how we check the URL state.
+ if (this._hasPushState) {
+ Backbone.$(window).on('popstate', this.checkUrl);
+ } else if (this._wantsHashChange && ('onhashchange' in window) && !oldIE) {
+ Backbone.$(window).on('hashchange', this.checkUrl);
+ } else if (this._wantsHashChange) {
+ this._checkUrlInterval = setInterval(this.checkUrl, this.interval);
+ }
+
+ // Determine if we need to change the base url, for a pushState link
+ // opened by a non-pushState browser.
+ this.fragment = fragment;
+ var loc = this.location;
+ var atRoot = loc.pathname.replace(/[^\/]$/, '$&/') === this.root;
+
+ // Transition from hashChange to pushState or vice versa if both are
+ // requested.
+ if (this._wantsHashChange && this._wantsPushState) {
+
+ // If we've started off with a route from a `pushState`-enabled
+ // browser, but we're currently in a browser that doesn't support it...
+ if (!this._hasPushState && !atRoot) {
+ this.fragment = this.getFragment(null, true);
+ this.location.replace(this.root + this.location.search + '#' + this.fragment);
+ // Return immediately as browser will do redirect to new url
+ return true;
+
+ // Or if we've started out with a hash-based route, but we're currently
+ // in a browser where it could be `pushState`-based instead...
+ } else if (this._hasPushState && atRoot && loc.hash) {
+ this.fragment = this.getHash().replace(routeStripper, '');
+ this.history.replaceState({}, document.title, this.root + this.fragment + loc.search);
+ }
+
+ }
+
+ if (!this.options.silent) return this.loadUrl();
+ },
+
+ // Disable Backbone.history, perhaps temporarily. Not useful in a real app,
+ // but possibly useful for unit testing Routers.
+ stop: function() {
+ Backbone.$(window).off('popstate', this.checkUrl).off('hashchange', this.checkUrl);
+ clearInterval(this._checkUrlInterval);
+ History.started = false;
+ },
+
+ // Add a route to be tested when the fragment changes. Routes added later
+ // may override previous routes.
+ route: function(route, callback) {
+ this.handlers.unshift({route: route, callback: callback});
+ },
+
+ // Checks the current URL to see if it has changed, and if it has,
+ // calls `loadUrl`, normalizing across the hidden iframe.
+ checkUrl: function(e) {
+ var current = this.getFragment();
+ if (current === this.fragment && this.iframe) {
+ current = this.getFragment(this.getHash(this.iframe));
+ }
+ if (current === this.fragment) return false;
+ if (this.iframe) this.navigate(current);
+ this.loadUrl();
+ },
+
+ // Attempt to load the current URL fragment. If a route succeeds with a
+ // match, returns `true`. If no defined routes matches the fragment,
+ // returns `false`.
+ loadUrl: function(fragment) {
+ fragment = this.fragment = this.getFragment(fragment);
+ return _.any(this.handlers, function(handler) {
+ if (handler.route.test(fragment)) {
+ handler.callback(fragment);
+ return true;
+ }
+ });
+ },
+
+ // Save a fragment into the hash history, or replace the URL state if the
+ // 'replace' option is passed. You are responsible for properly URL-encoding
+ // the fragment in advance.
+ //
+ // The options object can contain `trigger: true` if you wish to have the
+ // route callback be fired (not usually desirable), or `replace: true`, if
+ // you wish to modify the current URL without adding an entry to the history.
+ navigate: function(fragment, options) {
+ if (!History.started) return false;
+ if (!options || options === true) options = {trigger: !!options};
+
+ var url = this.root + (fragment = this.getFragment(fragment || ''));
+
+ // Strip the fragment of the query and hash for matching.
+ fragment = fragment.replace(pathStripper, '');
+
+ if (this.fragment === fragment) return;
+ this.fragment = fragment;
+
+ // Don't include a trailing slash on the root.
+ if (fragment === '' && url !== '/') url = url.slice(0, -1);
+
+ // If pushState is available, we use it to set the fragment as a real URL.
+ if (this._hasPushState) {
+ this.history[options.replace ? 'replaceState' : 'pushState']({}, document.title, url);
+
+ // If hash changes haven't been explicitly disabled, update the hash
+ // fragment to store history.
+ } else if (this._wantsHashChange) {
+ this._updateHash(this.location, fragment, options.replace);
+ if (this.iframe && (fragment !== this.getFragment(this.getHash(this.iframe)))) {
+ // Opening and closing the iframe tricks IE7 and earlier to push a
+ // history entry on hash-tag change. When replace is true, we don't
+ // want this.
+ if(!options.replace) this.iframe.document.open().close();
+ this._updateHash(this.iframe.location, fragment, options.replace);
+ }
+
+ // If you've told us that you explicitly don't want fallback hashchange-
+ // based history, then `navigate` becomes a page refresh.
+ } else {
+ return this.location.assign(url);
+ }
+ if (options.trigger) return this.loadUrl(fragment);
+ },
+
+ // Update the hash location, either replacing the current entry, or adding
+ // a new one to the browser history.
+ _updateHash: function(location, fragment, replace) {
+ if (replace) {
+ var href = location.href.replace(/(javascript:|#).*$/, '');
+ location.replace(href + '#' + fragment);
+ } else {
+ // Some browsers require that `hash` contains a leading #.
+ location.hash = '#' + fragment;
+ }
+ }
+
+ });
+
+ // Create the default Backbone.history.
+ Backbone.history = new History;
+
// Helpers
// -------
- // Shared empty constructor function to aid in prototype-chain creation.
- var ctor = function(){};
-
// Helper function to correctly set up the prototype chain, for subclasses.
// Similar to `goog.inherits`, but uses a hash of prototype properties and
// class properties to be extended.
- var inherits = function(parent, protoProps, staticProps) {
+ var extend = function(protoProps, staticProps) {
+ var parent = this;
var child;
// The constructor function for the new subclass is either defined by you
// (the "constructor" property in your `extend` definition), or defaulted
// by us to simply call the parent's constructor.
- if (protoProps && protoProps.hasOwnProperty('constructor')) {
+ if (protoProps && _.has(protoProps, 'constructor')) {
child = protoProps.constructor;
} else {
- child = function(){ parent.apply(this, arguments); };
+ child = function(){ return parent.apply(this, arguments); };
}
- // Inherit class (static) properties from parent.
- _.extend(child, parent);
+ // Add static properties to the constructor function, if supplied.
+ _.extend(child, parent, staticProps);
// Set the prototype chain to inherit from `parent`, without calling
// `parent`'s constructor function.
- ctor.prototype = parent.prototype;
- child.prototype = new ctor();
+ var Surrogate = function(){ this.constructor = child; };
+ Surrogate.prototype = parent.prototype;
+ child.prototype = new Surrogate;
// Add prototype properties (instance properties) to the subclass,
// if supplied.
if (protoProps) _.extend(child.prototype, protoProps);
- // Add static properties to the constructor function, if supplied.
- if (staticProps) _.extend(child, staticProps);
-
- // Correctly set child's `prototype.constructor`.
- child.prototype.constructor = child;
-
- // Set a convenience property in case the parent's prototype is needed later.
+ // Set a convenience property in case the parent's prototype is needed
+ // later.
child.__super__ = parent.prototype;
return child;
};
- // Helper function to get a value from a Backbone object as a property
- // or as a function.
- var getValue = function(object, prop) {
- if (!(object && object[prop])) return null;
- return _.isFunction(object[prop]) ? object[prop]() : object[prop];
- };
+ // Set up inheritance for the model, collection, router, view and history.
+ Model.extend = Collection.extend = Router.extend = View.extend = History.extend = extend;
// Throw an error when a URL is needed, and none is supplied.
var urlError = function() {
throw new Error('A "url" property or function must be specified');
};
+ // Wrap an optional error callback with a fallback error event.
+ var wrapError = function(model, options) {
+ var error = options.error;
+ options.error = function(resp) {
+ if (error) error(model, resp, options);
+ model.trigger('error', model, resp, options);
+ };
+ };
+
}).call(this);
diff --git a/addons/web/static/src/js/core.js b/addons/web/static/src/js/core.js
index d62c04b0ecb..81e029f5f87 100644
--- a/addons/web/static/src/js/core.js
+++ b/addons/web/static/src/js/core.js
@@ -561,8 +561,8 @@ instance.web.TranslationDataBase.include({
});
/** Custom jQuery plugins */
+$.browser = $.browser || {};
if(navigator.appVersion.indexOf("MSIE") !== -1) {
- $.browser = $.browser || {};
$.browser.msie = 1;
}
$.fn.getAttributes = function() {
From 0dff8277ccb20c6673b2a3013d2cb3d6e330e56c Mon Sep 17 00:00:00 2001
From: Xavier Morel
Date: Mon, 2 Dec 2013 16:10:37 +0100
Subject: [PATCH 2/6] [FIX] breakage due to backbone change: in 1.0+,
this.reset() will call this.add()
in 0.9, this.add would only be called if items were provided to
reset(), changed in commit cf6e862.
bzr revid: xmo@openerp.com-20131202151037-xxmvu5790p2jsxz6
---
addons/web/static/src/js/search.js | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index fcfcfb08f8e..83eaecd845a 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -71,7 +71,10 @@ my.SearchQuery = B.Collection.extend({
},
add: function (values, options) {
options = options || {};
- if (!(values instanceof Array)) {
+
+ if (!values) {
+ values = [];
+ } else if (!(values instanceof Array)) {
values = [values];
}
From ef08d834f639e4d8b9d1053df833067322d5ce14 Mon Sep 17 00:00:00 2001
From: Xavier Morel
Date: Mon, 2 Dec 2013 16:18:38 +0100
Subject: [PATCH 3/6] [IMP] add warning re. changed behavior of backbone which
may be changed in the client
bzr revid: xmo@openerp.com-20131202151838-z26qnz0xpt3tigrd
---
addons/web/static/src/js/search.js | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/addons/web/static/src/js/search.js b/addons/web/static/src/js/search.js
index 83eaecd845a..c3ef682bfcc 100644
--- a/addons/web/static/src/js/search.js
+++ b/addons/web/static/src/js/search.js
@@ -90,6 +90,10 @@ my.SearchQuery = B.Collection.extend({
}
B.Collection.prototype.add.call(this, model, options);
}, this);
+ // warning: in backbone 1.0+ add is supposed to return the added models,
+ // but here toggle may delegate to add and return its value directly.
+ // return value of neither seems actually used but should be tested
+ // before change, probably
return this;
},
toggle: function (value, options) {
From 3e94f7ab1b53d88d1369ea7a331d697c050edb88 Mon Sep 17 00:00:00 2001
From: Launchpad Translations on behalf of openerp <>
Date: Tue, 3 Dec 2013 05:41:24 +0000
Subject: [PATCH 4/6] Launchpad automatic translations update.
bzr revid: launchpad_translations_on_behalf_of_openerp-20131203054049-9sioco00f1s4dxvt
bzr revid: launchpad_translations_on_behalf_of_openerp-20131203054124-0db72b59pfm46z0f
---
addons/account/i18n/hu.po | 83 +++++++++++++++-----
addons/mail/i18n/hu.po | 8 +-
openerp/addons/base/i18n/ab.po | 4 +-
openerp/addons/base/i18n/af.po | 4 +-
openerp/addons/base/i18n/am.po | 4 +-
openerp/addons/base/i18n/ar.po | 4 +-
openerp/addons/base/i18n/bg.po | 4 +-
openerp/addons/base/i18n/bs.po | 4 +-
openerp/addons/base/i18n/ca.po | 4 +-
openerp/addons/base/i18n/cs.po | 4 +-
openerp/addons/base/i18n/da.po | 4 +-
openerp/addons/base/i18n/de.po | 4 +-
openerp/addons/base/i18n/el.po | 4 +-
openerp/addons/base/i18n/en_GB.po | 4 +-
openerp/addons/base/i18n/es.po | 4 +-
openerp/addons/base/i18n/es_AR.po | 4 +-
openerp/addons/base/i18n/es_BO.po | 4 +-
openerp/addons/base/i18n/es_CL.po | 4 +-
openerp/addons/base/i18n/es_CR.po | 4 +-
openerp/addons/base/i18n/es_DO.po | 4 +-
openerp/addons/base/i18n/es_EC.po | 4 +-
openerp/addons/base/i18n/es_MX.po | 4 +-
openerp/addons/base/i18n/es_VE.po | 4 +-
openerp/addons/base/i18n/et.po | 4 +-
openerp/addons/base/i18n/eu.po | 4 +-
openerp/addons/base/i18n/fa.po | 4 +-
openerp/addons/base/i18n/fa_AF.po | 4 +-
openerp/addons/base/i18n/fi.po | 84 ++++++++++----------
openerp/addons/base/i18n/fr.po | 4 +-
openerp/addons/base/i18n/fr_CA.po | 4 +-
openerp/addons/base/i18n/gl.po | 4 +-
openerp/addons/base/i18n/gu.po | 4 +-
openerp/addons/base/i18n/he.po | 4 +-
openerp/addons/base/i18n/hi.po | 4 +-
openerp/addons/base/i18n/hr.po | 4 +-
openerp/addons/base/i18n/hu.po | 4 +-
openerp/addons/base/i18n/hy.po | 4 +-
openerp/addons/base/i18n/id.po | 4 +-
openerp/addons/base/i18n/is.po | 4 +-
openerp/addons/base/i18n/it.po | 4 +-
openerp/addons/base/i18n/ja.po | 16 ++--
openerp/addons/base/i18n/ka.po | 4 +-
openerp/addons/base/i18n/kk.po | 4 +-
openerp/addons/base/i18n/ko.po | 4 +-
openerp/addons/base/i18n/lt.po | 4 +-
openerp/addons/base/i18n/lv.po | 20 +++--
openerp/addons/base/i18n/mk.po | 4 +-
openerp/addons/base/i18n/mn.po | 4 +-
openerp/addons/base/i18n/nb.po | 4 +-
openerp/addons/base/i18n/nl.po | 4 +-
openerp/addons/base/i18n/nl_BE.po | 4 +-
openerp/addons/base/i18n/pl.po | 4 +-
openerp/addons/base/i18n/pt.po | 4 +-
openerp/addons/base/i18n/pt_BR.po | 6 +-
openerp/addons/base/i18n/ro.po | 110 +++++++++++++--------------
openerp/addons/base/i18n/ru.po | 4 +-
openerp/addons/base/i18n/sk.po | 4 +-
openerp/addons/base/i18n/sl.po | 4 +-
openerp/addons/base/i18n/sq.po | 4 +-
openerp/addons/base/i18n/sr.po | 4 +-
openerp/addons/base/i18n/sr@latin.po | 4 +-
openerp/addons/base/i18n/sv.po | 4 +-
openerp/addons/base/i18n/th.po | 4 +-
openerp/addons/base/i18n/tlh.po | 4 +-
openerp/addons/base/i18n/tr.po | 4 +-
openerp/addons/base/i18n/uk.po | 4 +-
openerp/addons/base/i18n/ur.po | 4 +-
openerp/addons/base/i18n/vi.po | 4 +-
openerp/addons/base/i18n/zh_CN.po | 6 +-
openerp/addons/base/i18n/zh_HK.po | 4 +-
openerp/addons/base/i18n/zh_TW.po | 61 +++++++++------
71 files changed, 352 insertions(+), 290 deletions(-)
diff --git a/addons/account/i18n/hu.po b/addons/account/i18n/hu.po
index 0e17cb39113..f8b9fd115b4 100644
--- a/addons/account/i18n/hu.po
+++ b/addons/account/i18n/hu.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2012-12-27 22:48+0000\n"
-"Last-Translator: Balint (eSolve) \n"
+"PO-Revision-Date: 2013-12-02 19:56+0000\n"
+"Last-Translator: krnkris \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-09-12 05:27+0000\n"
-"X-Generator: Launchpad (build 16761)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:41+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: account
#: model:process.transition,name:account.process_transition_supplierreconcilepaid0
@@ -26,6 +26,8 @@ msgstr "Kifizetési rendszer"
msgid ""
"An account fiscal position could be defined only once time on same accounts."
msgstr ""
+"Egy könyvelés költségvetési évfordulóját csak egyszer lehet megadni az arra "
+"hivatkozó számlákra vonatkozólag."
#. module: account
#: help:account.tax.code,sequence:0
@@ -60,7 +62,7 @@ msgstr "Rendezetlen összeg"
#: code:addons/account/account_bank_statement.py:369
#, python-format
msgid "Journal item \"%s\" is not valid."
-msgstr ""
+msgstr "A \"%s\" könyvelési napló tétel nem érvényes."
#. module: account
#: model:ir.model,name:account.model_report_aged_receivable
@@ -78,7 +80,7 @@ msgstr "Importálás számlából vagy pénzügyi rendezésből"
#: code:addons/account/account_move_line.py:1210
#, python-format
msgid "Bad Account!"
-msgstr ""
+msgstr "Eltévesztett könyvelési számla!"
#. module: account
#: view:account.move:0
@@ -92,6 +94,8 @@ msgid ""
"Error!\n"
"You cannot create recursive account templates."
msgstr ""
+"Hiba!\n"
+"Nem hozhat létre visszatérő számla sablonokat."
#. module: account
#. openerp-web
@@ -102,7 +106,7 @@ msgstr ""
#: code:addons/account/static/src/xml/account_move_reconciliation.xml:30
#, python-format
msgid "Reconcile"
-msgstr "Párosítás"
+msgstr "Egyeztetés"
#. module: account
#: field:account.bank.statement,name:0
@@ -114,7 +118,7 @@ msgstr "Párosítás"
#: xsl:account.transfer:0
#: field:cash.box.in,ref:0
msgid "Reference"
-msgstr "Hivatkozás"
+msgstr "Információforrás"
#. module: account
#: help:account.payment.term,active:0
@@ -122,7 +126,8 @@ msgid ""
"If the active field is set to False, it will allow you to hide the payment "
"term without removing it."
msgstr ""
-"Ha az aktív mező nincs bejelölve, nem használható a fizetési feltétel."
+"Ha az aktív mező hamisra van állatva, akkor a fizetési feltételt "
+"eltüntetheti anélkül, hogy törölné azt."
#. module: account
#: code:addons/account/account.py:641
@@ -151,7 +156,7 @@ msgstr "Figyelem!"
#: code:addons/account/account.py:3197
#, python-format
msgid "Miscellaneous Journal"
-msgstr "Vegyes napló"
+msgstr "Vegyes könyvelési napló"
#. module: account
#: code:addons/account/wizard/account_open_closed_fiscalyear.py:39
@@ -161,6 +166,8 @@ msgid ""
"which is set after generating opening entries from 'Generate Opening "
"Entries'."
msgstr ""
+"Be kell állítania az 'Év végi belépő könyvelési naplót' ehhez a 'Nyitási "
+"tétel létrehozása' menüvel létrehozott üzlez év tételeihez."
#. module: account
#: field:account.fiscal.position.account,account_src_id:0
@@ -879,7 +886,7 @@ msgstr "Párosítás visszavonása"
#. module: account
#: model:ir.model,name:account.model_account_analytic_journal_report
msgid "Account Analytic Journal"
-msgstr "Gyűjtőnapló"
+msgstr "Gyűjtőnapló számla"
#. module: account
#: view:account.invoice:0
@@ -1475,7 +1482,7 @@ msgstr "Listázási beállítások"
#. module: account
#: field:account.fiscalyear.close.state,fy_id:0
msgid "Fiscal Year to Close"
-msgstr ""
+msgstr "Bezárni kívánt üzleti év"
#. module: account
#: field:account.config.settings,sale_sequence_prefix:0
@@ -1553,7 +1560,7 @@ msgstr "Adók keresése"
#. module: account
#: model:ir.model,name:account.model_account_analytic_cost_ledger
msgid "Account Analytic Cost Ledger"
-msgstr "Gyűjtőkód karton"
+msgstr "Főkönyvi költség gyűjtőkód karton számla"
#. module: account
#: view:account.model:0
@@ -1624,6 +1631,8 @@ msgid ""
"By unchecking the active field, you may hide a fiscal position without "
"deleting it."
msgstr ""
+"Az aktív mező üresen hagyásával, eltüntetheti az ÁFA helyét, annak törlése "
+"nélkül."
#. module: account
#: model:ir.model,name:account.model_temp_range
@@ -2194,7 +2203,7 @@ msgstr "Korosított folyószámla kivonat"
#. module: account
#: view:account.fiscalyear.close.state:0
msgid "Close Fiscal Year"
-msgstr ""
+msgstr "Üzleti év lezárása"
#. module: account
#. openerp-web
@@ -2207,6 +2216,7 @@ msgstr ""
#: sql_constraint:account.fiscal.position.tax:0
msgid "A tax fiscal position could be defined only once time on same taxes."
msgstr ""
+"Az adó adóügyi pozíciója csak egyszer határozható meg ugyanarra az adóra."
#. module: account
#: view:account.tax:0
@@ -2320,7 +2330,7 @@ msgstr "Részleges tételsorok"
#: view:account.fiscalyear:0
#: field:account.treasury.report,fiscalyear_id:0
msgid "Fiscalyear"
-msgstr "Üzleti év"
+msgstr "Üzletiév"
#. module: account
#: code:addons/account/wizard/account_move_bank_reconcile.py:53
@@ -2963,6 +2973,22 @@ msgid ""
"
\n"
" "
msgstr ""
+"\n"
+" Kattintson új adóügyi év létrehozásához.\n"
+"
\n"
+" Határozza meg a vállalkozása üzleti évét a kívánságainak "
+"megfelelően.\n"
+" Egy üzleti év egy idő periódus, aminek a végén a vállalkozás "
+"könyvelése\n"
+" elszámolásra kerül (általában 12 hónap). Az üzleti év arra a "
+"dátumra\n"
+" hivatkozik általában ahol az véget ér. Például,\n"
+" ha a vállalkozás pénzügyi üzleti éve 2011 november 30-ára "
+"esik, akkor\n"
+" minden ami 2010 december 1 és 2011 november 30 közé esik\n"
+" azt hívjuk 2011 évi üzleti/pénzügyi/adóügyi évnek.\n"
+"
\n"
+" "
#. module: account
#: view:account.common.report:0
@@ -3912,6 +3938,8 @@ msgid ""
"There is no fiscal year defined for this date.\n"
"Please create one from the configuration of the accounting menu."
msgstr ""
+"Erre a dátumra nem lett üzleti adóügyi év meghatározva.\n"
+"Kérem hozzon létre egyet a könyvelési menü beállítása menüpont alatt."
#. module: account
#: view:account.addtmpl.wizard:0
@@ -4282,6 +4310,8 @@ msgid ""
"The fiscalyear, periods or chart of account chosen have to belong to the "
"same company."
msgstr ""
+"Az üzelti adóügyi év, periódus vagy számlatükör kiválasztása ugyanarra a "
+"vállalkozásra kell, hogy vonatkozzon."
#. module: account
#: help:account.tax.code.template,notprintable:0
@@ -7344,6 +7374,8 @@ msgid ""
"Error!\n"
"The start date of a fiscal year must precede its end date."
msgstr ""
+"Hiba!\n"
+"Az üzleti adóügyi év elejének előbb kell lennie mint a végének."
#. module: account
#: view:account.tax.template:0
@@ -8276,7 +8308,8 @@ msgstr ""
msgid ""
"Select Fiscal Year which you want to remove entries for its End of year "
"entries journal"
-msgstr "Válassza ki az üzleti évet, amelynek a nyitó tételeit törölni akarja"
+msgstr ""
+"Válassza ki az üzleti évet, amelynek a záró tételei közül törölni szeretne"
#. module: account
#: field:account.tax.template,type_tax_use:0
@@ -8397,7 +8430,7 @@ msgstr "Gyűjtőkód karton"
#. module: account
#: view:account.config.settings:0
msgid "No Fiscal Year Defined for This Company"
-msgstr ""
+msgstr "Ehhez a vállalkozáshoz nem lett üzleti adóügyi év meghatározva"
#. module: account
#: view:account.invoice:0
@@ -8548,6 +8581,9 @@ msgid ""
"This wizard will remove the end of year journal entries of selected fiscal "
"year. Note that you can run this wizard many times for the same fiscal year."
msgstr ""
+"Ez a varázsló a kiválasztott üzleti adóügyi évet lezáró könyvelési napló "
+"tételeit fogja eltávolítani. Megjegyezzük, hogy ezt a varázslót többször is "
+"elindíthatja ugyanarra az üzleti évre."
#. module: account
#: report:account.invoice:0
@@ -8732,7 +8768,7 @@ msgstr ""
#. module: account
#: model:ir.model,name:account.model_account_fiscalyear_close_state
msgid "Fiscalyear Close state"
-msgstr "Üzleti év zárása"
+msgstr "Üzleti év zárt állapotban"
#. module: account
#: field:account.invoice.refund,journal_id:0
@@ -9161,7 +9197,7 @@ msgstr ""
#. module: account
#: field:account.config.settings,has_fiscal_year:0
msgid "Company has a fiscal year"
-msgstr ""
+msgstr "Vállalkozásnak van üzleti, adóügyi éve"
#. module: account
#: help:account.tax,child_depend:0
@@ -9599,6 +9635,9 @@ msgid ""
"The period is invalid. Either some periods are overlapping or the period's "
"dates are not matching the scope of the fiscal year."
msgstr ""
+"Hiba!\n"
+"Az időszak nem érvényes. Vagy az egyes időszakok átfedik egymást vagy az "
+"időszakok nem egyeznek az üzleti év határidőivel."
#. module: account
#: report:account.overdue:0
@@ -9897,7 +9936,7 @@ msgstr "Gyűjtőkódokból"
#. module: account
#: view:account.installer:0
msgid "Configure your Fiscal Year"
-msgstr ""
+msgstr "Állítsa be az üzleti, adóügyi évét"
#. module: account
#: field:account.period,name:0
@@ -10834,6 +10873,8 @@ msgstr "Könyvelési tételsorok jóváhagyása"
msgid ""
"The fiscal position will determine taxes and accounts used for the partner."
msgstr ""
+"Az ÁFA pozíció meghatározza a partnerre vonatkozó adókat és főkönyvi "
+"számlákat."
#. module: account
#: model:process.node,note:account.process_node_supplierpaidinvoice0
@@ -10906,7 +10947,7 @@ msgstr ""
#: view:ir.sequence:0
#: model:ir.ui.menu,name:account.menu_action_account_fiscalyear
msgid "Fiscal Years"
-msgstr "Üzleti év"
+msgstr "Üzleti évek"
#. module: account
#: help:account.analytic.journal,active:0
diff --git a/addons/mail/i18n/hu.po b/addons/mail/i18n/hu.po
index b03ef6d9b0d..9b376093a29 100644
--- a/addons/mail/i18n/hu.po
+++ b/addons/mail/i18n/hu.po
@@ -7,14 +7,14 @@ msgstr ""
"Project-Id-Version: OpenERP Server 6.0dev\n"
"Report-Msgid-Bugs-To: support@openerp.com\n"
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
-"PO-Revision-Date: 2013-02-14 16:43+0000\n"
+"PO-Revision-Date: 2013-12-02 18:38+0000\n"
"Last-Translator: krnkris \n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=utf-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-09-12 06:29+0000\n"
-"X-Generator: Launchpad (build 16761)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:41+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: mail
#: view:mail.followers:0
@@ -1791,7 +1791,7 @@ msgstr "Altípusok"
#. module: mail
#: model:ir.model,name:mail.model_mail_alias
msgid "Email Aliases"
-msgstr "e-amil álnevek"
+msgstr "Email álnevek"
#. module: mail
#: field:mail.group,image_small:0
diff --git a/openerp/addons/base/i18n/ab.po b/openerp/addons/base/i18n/ab.po
index 5b890fb0d73..4a5c7cffe51 100644
--- a/openerp/addons/base/i18n/ab.po
+++ b/openerp/addons/base/i18n/ab.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:48+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:29+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/af.po b/openerp/addons/base/i18n/af.po
index 6277f666a76..aa30caf0889 100644
--- a/openerp/addons/base/i18n/af.po
+++ b/openerp/addons/base/i18n/af.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:48+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:29+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/am.po b/openerp/addons/base/i18n/am.po
index a2aee8915f3..c48b8720533 100644
--- a/openerp/addons/base/i18n/am.po
+++ b/openerp/addons/base/i18n/am.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:49+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:29+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/ar.po b/openerp/addons/base/i18n/ar.po
index 67018e499ef..2cc0271838a 100644
--- a/openerp/addons/base/i18n/ar.po
+++ b/openerp/addons/base/i18n/ar.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:49+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:29+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/bg.po b/openerp/addons/base/i18n/bg.po
index 2600d4b65f5..b4c3fb66957 100644
--- a/openerp/addons/base/i18n/bg.po
+++ b/openerp/addons/base/i18n/bg.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:50+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:30+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/bs.po b/openerp/addons/base/i18n/bs.po
index 8e2be9d681c..c9ff72f2df3 100644
--- a/openerp/addons/base/i18n/bs.po
+++ b/openerp/addons/base/i18n/bs.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:50+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:30+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/ca.po b/openerp/addons/base/i18n/ca.po
index 7bb11a4d5a3..7ae72c759e9 100644
--- a/openerp/addons/base/i18n/ca.po
+++ b/openerp/addons/base/i18n/ca.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:50+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:30+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/cs.po b/openerp/addons/base/i18n/cs.po
index 5e4bf740dfe..01ef16527a2 100644
--- a/openerp/addons/base/i18n/cs.po
+++ b/openerp/addons/base/i18n/cs.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:50+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:30+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
"X-Poedit-Language: Czech\n"
#. module: base
diff --git a/openerp/addons/base/i18n/da.po b/openerp/addons/base/i18n/da.po
index 9ff86170376..4a906e2ecaa 100644
--- a/openerp/addons/base/i18n/da.po
+++ b/openerp/addons/base/i18n/da.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:50+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:31+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/de.po b/openerp/addons/base/i18n/de.po
index a7d53b7452b..6e1569d4199 100644
--- a/openerp/addons/base/i18n/de.po
+++ b/openerp/addons/base/i18n/de.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:52+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:32+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/el.po b/openerp/addons/base/i18n/el.po
index 7fb38358130..850f3851788 100644
--- a/openerp/addons/base/i18n/el.po
+++ b/openerp/addons/base/i18n/el.po
@@ -12,8 +12,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:52+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:32+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
"X-Poedit-Country: GREECE\n"
"X-Poedit-Language: Greek\n"
"X-Poedit-SourceCharset: utf-8\n"
diff --git a/openerp/addons/base/i18n/en_GB.po b/openerp/addons/base/i18n/en_GB.po
index b9b7343fdb1..80f270dd346 100644
--- a/openerp/addons/base/i18n/en_GB.po
+++ b/openerp/addons/base/i18n/en_GB.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:38+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es.po b/openerp/addons/base/i18n/es.po
index af136ea8eb9..5be6de287a8 100644
--- a/openerp/addons/base/i18n/es.po
+++ b/openerp/addons/base/i18n/es.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:57+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:36+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_AR.po b/openerp/addons/base/i18n/es_AR.po
index 9801919b7f2..62b8bdf2c09 100644
--- a/openerp/addons/base/i18n/es_AR.po
+++ b/openerp/addons/base/i18n/es_AR.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:38+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_BO.po b/openerp/addons/base/i18n/es_BO.po
index 3478e7cbfe6..4b553837293 100644
--- a/openerp/addons/base/i18n/es_BO.po
+++ b/openerp/addons/base/i18n/es_BO.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:39+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_CL.po b/openerp/addons/base/i18n/es_CL.po
index 94d69de44c9..95da6400d36 100644
--- a/openerp/addons/base/i18n/es_CL.po
+++ b/openerp/addons/base/i18n/es_CL.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:39+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_CR.po b/openerp/addons/base/i18n/es_CR.po
index 4bd57d1985f..03e0f4e3894 100644
--- a/openerp/addons/base/i18n/es_CR.po
+++ b/openerp/addons/base/i18n/es_CR.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:00+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:40+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
"Language: \n"
#. module: base
diff --git a/openerp/addons/base/i18n/es_DO.po b/openerp/addons/base/i18n/es_DO.po
index 5c94c53d8c7..392515887c0 100644
--- a/openerp/addons/base/i18n/es_DO.po
+++ b/openerp/addons/base/i18n/es_DO.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:39+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_EC.po b/openerp/addons/base/i18n/es_EC.po
index c423bc0cbfe..da7a06982c5 100644
--- a/openerp/addons/base/i18n/es_EC.po
+++ b/openerp/addons/base/i18n/es_EC.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:00+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:40+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_MX.po b/openerp/addons/base/i18n/es_MX.po
index 2e6dbbe3515..98cd32c214c 100644
--- a/openerp/addons/base/i18n/es_MX.po
+++ b/openerp/addons/base/i18n/es_MX.po
@@ -15,8 +15,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:00+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:40+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/es_VE.po b/openerp/addons/base/i18n/es_VE.po
index a964c388e41..4dc59a2343a 100644
--- a/openerp/addons/base/i18n/es_VE.po
+++ b/openerp/addons/base/i18n/es_VE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:58+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:38+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/et.po b/openerp/addons/base/i18n/et.po
index 57f18f68e25..746f0f76f99 100644
--- a/openerp/addons/base/i18n/et.po
+++ b/openerp/addons/base/i18n/et.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:51+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:31+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/eu.po b/openerp/addons/base/i18n/eu.po
index 71878d844c3..10519023b75 100644
--- a/openerp/addons/base/i18n/eu.po
+++ b/openerp/addons/base/i18n/eu.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:49+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:30+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/fa.po b/openerp/addons/base/i18n/fa.po
index 624146edcd8..891043414b5 100644
--- a/openerp/addons/base/i18n/fa.po
+++ b/openerp/addons/base/i18n/fa.po
@@ -9,8 +9,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:55+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:35+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
"X-Poedit-Country: IRAN, ISLAMIC REPUBLIC OF\n"
"X-Poedit-Language: Persian\n"
diff --git a/openerp/addons/base/i18n/fa_AF.po b/openerp/addons/base/i18n/fa_AF.po
index 78da335f6aa..99407d21416 100644
--- a/openerp/addons/base/i18n/fa_AF.po
+++ b/openerp/addons/base/i18n/fa_AF.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:01+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:40+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/fi.po b/openerp/addons/base/i18n/fi.po
index 18cd0d553c4..48468e6bc5d 100644
--- a/openerp/addons/base/i18n/fi.po
+++ b/openerp/addons/base/i18n/fi.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:51+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:31+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@@ -51,7 +51,7 @@ msgid ""
"The second argument of the many2many field %s must be a SQL table !You used "
"%s, which is not a valid SQL table name."
msgstr ""
-"Jälkimmäisen argumentin many2many -kentässä %s pitää olla SQL-taulu! "
+"Jälkimmäisen argumentin moni-moneen -kentässä %s pitää olla SQL-taulu! "
"Antamasi nimi %s ei ole hyväksytty SQL-taulun nimi."
#. module: base
@@ -192,7 +192,7 @@ msgstr "Pääraporttitiedoston polku"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_analytic_plans
msgid "Sales Analytic Distribution"
-msgstr "Kustannusten kohdistaminen myynnille"
+msgstr "Myynnin analyyttinen jakaantuminen"
#. module: base
#: model:ir.module.module,description:base.module_hr_timesheet_invoice
@@ -324,7 +324,7 @@ msgstr ""
#. module: base
#: view:res.partner:0
msgid "Search Partner"
-msgstr "Etsi kumppaneista"
+msgstr "Hae kumppani"
#. module: base
#: field:ir.module.category,module_nr:0
@@ -457,7 +457,7 @@ msgstr "Lähdeobjekti"
#. module: base
#: model:res.partner.bank.type,format_layout:base.bank_normal
msgid "%(bank_name)s: %(acc_number)s"
-msgstr ""
+msgstr "%(bank_name)s: %(acc_number)s"
#. module: base
#: view:ir.actions.todo:0
@@ -2234,7 +2234,7 @@ msgstr "Luku / Kirjoitus / Kopiointi"
#. module: base
#: view:ir.sequence:0
msgid "Second: %(sec)s"
-msgstr "Sekuntti: %(sec)s"
+msgstr "Sekunti: %(sec)s"
#. module: base
#: field:ir.actions.act_window,view_mode:0
@@ -2273,7 +2273,7 @@ msgstr "Logo"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_cr
msgid "Costa Rica - Accounting"
-msgstr ""
+msgstr "Costa Rica - Kirjanpito"
#. module: base
#: selection:ir.actions.act_url,target:0
@@ -2912,7 +2912,7 @@ msgstr ""
#: model:res.groups,name:base.group_sale_manager
#: model:res.groups,name:base.group_tool_manager
msgid "Manager"
-msgstr "Ylläpitäjä"
+msgstr "Päällikkö"
#. module: base
#: code:addons/base/ir/ir_model.py:726
@@ -3296,7 +3296,7 @@ msgstr "Armenia"
#. module: base
#: model:ir.module.module,summary:base.module_hr_evaluation
msgid "Periodical Evaluations, Appraisals, Surveys"
-msgstr "Säännöllinen arviointi, kehityskeskustelut, tutkimukset"
+msgstr "Säännöllinen arviointi, kehityskeskustelut, kyselyt"
#. module: base
#: model:ir.actions.act_window,name:base.ir_property_form
@@ -3754,7 +3754,7 @@ msgstr "Kotitoiminto"
#. module: base
#: field:res.lang,grouping:0
msgid "Separator Format"
-msgstr "Erottimen muotoilu"
+msgstr "Tuhansien muotoilu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_report_webkit
@@ -5190,7 +5190,7 @@ msgstr "ir.actions.actions"
#. module: base
#: selection:ir.model.fields,select_level:0
msgid "Not Searchable"
-msgstr "Ei haettava"
+msgstr "Ei haettavissa"
#. module: base
#: view:ir.config_parameter:0
@@ -5369,7 +5369,7 @@ msgstr "Jokaisen mallin pitää olla uniikki"
#: model:ir.module.category,name:base.module_category_localization
#: model:ir.ui.menu,name:base.menu_localisation
msgid "Localization"
-msgstr "Lokalisointi"
+msgstr "Kotoistus"
#. module: base
#: model:ir.module.module,description:base.module_web_api
@@ -5484,7 +5484,7 @@ msgstr "Liitetty kohteeseen"
#. module: base
#: field:res.lang,decimal_point:0
msgid "Decimal Separator"
-msgstr "Desimaalin erotin"
+msgstr "Desimaalierotin"
#. module: base
#: code:addons/orm.py:5319
@@ -5590,7 +5590,7 @@ msgstr "Kenttä"
#. module: base
#: model:ir.module.module,shortdesc:base.module_project_long_term
msgid "Long Term Projects"
-msgstr "Pitkän aikavälin projektit"
+msgstr "Pitkäkestoiset projektit"
#. module: base
#: model:res.country,name:base.ve
@@ -5779,7 +5779,7 @@ msgstr "ir.actions.act_url"
#. module: base
#: model:ir.ui.menu,name:base.menu_translation_app
msgid "Application Terms"
-msgstr "Sovelluksen käyttöehdot"
+msgstr "Sovelluksen termit"
#. module: base
#: model:ir.actions.act_window,help:base.open_module_tree
@@ -6831,7 +6831,7 @@ msgstr "Konfiguraatiota ei voi monistaa!"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_syscohada
msgid "OHADA - Accounting"
-msgstr ""
+msgstr "OHADA - Kirjanpito"
#. module: base
#: help:res.bank,bic:0
@@ -6866,7 +6866,7 @@ msgstr "Määritellyt raportit"
#. module: base
#: model:ir.module.module,shortdesc:base.module_project_gtd
msgid "Todo Lists"
-msgstr "Tehtävälistat"
+msgstr "Tehtäväluettelot"
#. module: base
#: view:ir.actions.report.xml:0
@@ -6953,7 +6953,7 @@ msgstr "Iso-Britannia"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_pa
msgid "Panama Localization Chart Account"
-msgstr ""
+msgstr "Panama kotoistettu tilikartta"
#. module: base
#: help:res.partner.category,active:0
@@ -7372,7 +7372,7 @@ msgstr ""
#. module: base
#: model:ir.ui.menu,name:base.menu_project_long_term
msgid "Long Term Planning"
-msgstr "Pitkän aikavälin suunnittelu"
+msgstr "Pitkän tähtäimen suunnittelu (PTS)"
#. module: base
#: field:ir.actions.server,message:0
@@ -7776,7 +7776,7 @@ msgstr "Reklmaatioporttaali"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_pe
msgid "Peru Localization Chart Account"
-msgstr "Perun (maa) lokalisoitu tilikartta"
+msgstr "Peru (maa) kotoistettu tilikartta"
#. module: base
#: model:ir.module.module,description:base.module_auth_oauth
@@ -7824,7 +7824,7 @@ msgstr "RML sisäinen ylätunniste"
#. module: base
#: field:ir.actions.act_window,search_view_id:0
msgid "Search View Ref."
-msgstr "Hakunäkymän referenssi"
+msgstr "Hae näytettävä viite"
#. module: base
#: help:res.users,partner_id:0
@@ -8006,7 +8006,7 @@ msgstr "Burkina Faso"
#. module: base
#: selection:ir.model.fields,state:0
msgid "Custom Field"
-msgstr "Kustomoitu kenttä"
+msgstr "Mukautettu kenttä"
#. module: base
#: model:ir.module.module,summary:base.module_account_accountant
@@ -8395,7 +8395,7 @@ msgstr "Viestintä"
#. module: base
#: model:ir.module.module,shortdesc:base.module_analytic
msgid "Analytic Accounting"
-msgstr "Analyyttinen tilikirjanpito"
+msgstr "Analyyttinen kirjanpito"
#. module: base
#: model:ir.model,name:base.model_ir_model_constraint
@@ -8429,7 +8429,7 @@ msgstr "ir.server.object.lines"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_be
msgid "Belgium - Accounting"
-msgstr ""
+msgstr "Belgia - Kirjanpito"
#. module: base
#: view:ir.model.access:0
@@ -8707,7 +8707,7 @@ msgstr "Dokumentin sivu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_ar
msgid "Argentina Localization Chart Account"
-msgstr "Argentiinan lokalisoitu tilikartta"
+msgstr "Argentiina kotoistettu tilikartta"
#. module: base
#: field:ir.module.module,description_html:0
@@ -9546,7 +9546,7 @@ msgstr "Omat pikalinkit"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_si
msgid "Slovenian - Accounting"
-msgstr ""
+msgstr "Slovenia - Kirjanpito"
#. module: base
#: model:ir.module.module,description:base.module_account_cancel
@@ -10279,7 +10279,7 @@ msgstr "Tätä menetelmää ei ole enää olemassa"
#: model:ir.actions.act_window,name:base.action_wizard_update_translations
#: model:ir.ui.menu,name:base.menu_wizard_update_translations
msgid "Synchronize Terms"
-msgstr "Synkronoi termi"
+msgstr "Synkronoi termit"
#. module: base
#: field:res.lang,thousands_sep:0
@@ -11558,7 +11558,7 @@ msgstr "RML-sisältö"
#. module: base
#: view:res.lang:0
msgid "Update Terms"
-msgstr "Päivitä ehdot"
+msgstr "Päivitä termit"
#. module: base
#: field:res.request,act_to:0
@@ -11856,7 +11856,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_bo
msgid "Bolivia Localization Chart Account"
-msgstr ""
+msgstr "Bolivia kotoistettu tilikartta"
#. module: base
#: model:ir.module.module,description:base.module_plugin_thunderbird
@@ -12175,7 +12175,7 @@ msgstr "Raportin tyyppi"
#: view:res.partner.bank:0
#: view:res.users:0
msgid "State"
-msgstr "Tila"
+msgstr "Valtio"
#. module: base
#: selection:base.language.install,lang:0
@@ -12195,7 +12195,7 @@ msgstr "4. %b, %B = joulu, joulukuu"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_cl
msgid "Chile Localization Chart Account"
-msgstr ""
+msgstr "Chile Kotoitettu tilikartta"
#. module: base
#: selection:base.language.install,lang:0
@@ -12797,7 +12797,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_gr
msgid "Greece - Accounting"
-msgstr ""
+msgstr "Kreikka - Kirjanpito"
#. module: base
#: sql_constraint:res.country:0
@@ -13005,7 +13005,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_th
msgid "Thailand - Accounting"
-msgstr ""
+msgstr "Thaimaa - Kirjanpito"
#. module: base
#: view:res.lang:0
@@ -13397,7 +13397,7 @@ msgstr "ir.sequence.type"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_be_hr_payroll_account
msgid "Belgium - Payroll with Accounting"
-msgstr ""
+msgstr "Belgia - Kirjanpito ja palkkahallinto"
#. module: base
#: selection:base.language.export,format:0
@@ -13904,7 +13904,7 @@ msgstr "Tanska / Dansk"
#. module: base
#: selection:ir.model.fields,select_level:0
msgid "Advanced Search (deprecated)"
-msgstr "Kehittynyt haku (vähehksytty)"
+msgstr "Kehittynyt haku vanhentunut - hae uudelleen"
#. module: base
#: model:res.country,name:base.cx
@@ -15190,10 +15190,14 @@ msgid ""
"1,06,500;[1,2,-1] will represent it to be 106,50,0;[3] will represent it as "
"106,500. Provided ',' as the thousand separator in each case."
msgstr ""
-"Erottimen formaatin tulisi olla muotoa [,n] jossa n > 0 ja -1 lopettaa "
-"erottelun. Esimerkiksi luku 106500 (tuhaterottimena on käytetty "
-"pilkkua):[3,2,-1] esittää sen muodossa 1,06,500;[1,2,-1] esittää sen "
-"muodossa 106,50,0;[3] esittää sen muodossa 106,500."
+"Tuhansien muotoilun tulisi olla muotoa [3, 0] eli jokaisen kolmen numeron "
+"välein on tuhaterotin.\r\n"
+"Tuhatmuotoilu annetaan muodossa [,n], jossa n > 0 ja erikoistapauksena n = -"
+"1 lopettaa tuhaterottelun. \r\n"
+"Esimerkiksi luku 106500 (tuhaterottimena on käytetty pilkkua):\r\n"
+"[ 3,2,-1] esittää sen muodossa 1,06,500;\r\n"
+"[1,2,-1] esittää sen muodossa 106,50,0;\r\n"
+"[3] esittää sen muodossa 106,500."
#. module: base
#: field:ir.module.module,auto_install:0
diff --git a/openerp/addons/base/i18n/fr.po b/openerp/addons/base/i18n/fr.po
index b92eeb89264..fc4eaa61d59 100644
--- a/openerp/addons/base/i18n/fr.po
+++ b/openerp/addons/base/i18n/fr.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:51+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:31+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/fr_CA.po b/openerp/addons/base/i18n/fr_CA.po
index ae702a01efa..6295a6845df 100644
--- a/openerp/addons/base/i18n/fr_CA.po
+++ b/openerp/addons/base/i18n/fr_CA.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:39+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/gl.po b/openerp/addons/base/i18n/gl.po
index 66b0f363ca3..0c7714c15e2 100644
--- a/openerp/addons/base/i18n/gl.po
+++ b/openerp/addons/base/i18n/gl.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:52+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:32+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/gu.po b/openerp/addons/base/i18n/gu.po
index 257ffeaa485..87529ba8926 100644
--- a/openerp/addons/base/i18n/gu.po
+++ b/openerp/addons/base/i18n/gu.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:52+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:32+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/he.po b/openerp/addons/base/i18n/he.po
index 3b24304d5d3..7f0429847ab 100644
--- a/openerp/addons/base/i18n/he.po
+++ b/openerp/addons/base/i18n/he.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:52+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:32+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/hi.po b/openerp/addons/base/i18n/hi.po
index fa45cea55d3..0620b3fd8da 100644
--- a/openerp/addons/base/i18n/hi.po
+++ b/openerp/addons/base/i18n/hi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:53+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:33+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/hr.po b/openerp/addons/base/i18n/hr.po
index 223e6137906..f66b99bd54e 100644
--- a/openerp/addons/base/i18n/hr.po
+++ b/openerp/addons/base/i18n/hr.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:56+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:36+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
"Language: hr\n"
#. module: base
diff --git a/openerp/addons/base/i18n/hu.po b/openerp/addons/base/i18n/hu.po
index 6af3a2fe2b9..9755f7cbe31 100644
--- a/openerp/addons/base/i18n/hu.po
+++ b/openerp/addons/base/i18n/hu.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-25 05:32+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:33+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/hy.po b/openerp/addons/base/i18n/hy.po
index 6de8f713003..ca7b1162e70 100644
--- a/openerp/addons/base/i18n/hy.po
+++ b/openerp/addons/base/i18n/hy.po
@@ -9,8 +9,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:49+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:29+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/id.po b/openerp/addons/base/i18n/id.po
index f3852514db3..8178f6f4a11 100644
--- a/openerp/addons/base/i18n/id.po
+++ b/openerp/addons/base/i18n/id.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:53+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:33+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/is.po b/openerp/addons/base/i18n/is.po
index f5d2f47aa7d..6747ee44667 100644
--- a/openerp/addons/base/i18n/is.po
+++ b/openerp/addons/base/i18n/is.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:53+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:33+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/it.po b/openerp/addons/base/i18n/it.po
index 3f6fbe41366..25bda01f2da 100644
--- a/openerp/addons/base/i18n/it.po
+++ b/openerp/addons/base/i18n/it.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:53+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:33+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/ja.po b/openerp/addons/base/i18n/ja.po
index df9d3c00098..aabf4300913 100644
--- a/openerp/addons/base/i18n/ja.po
+++ b/openerp/addons/base/i18n/ja.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:54+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:33+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@@ -9356,7 +9356,7 @@ msgstr "マリ共和国"
#. module: base
#: model:ir.ui.menu,name:base.menu_project_config_project
msgid "Stages"
-msgstr ""
+msgstr "ステージ"
#. module: base
#: selection:base.language.install,lang:0
@@ -9623,7 +9623,7 @@ msgstr "アメリカ合衆国 - 勘定科目表"
#: view:res.users:0
#: view:wizard.ir.model.menu.create:0
msgid "Cancel"
-msgstr "キャンセル"
+msgstr "取消"
#. module: base
#: code:addons/orm.py:1507
@@ -9953,7 +9953,7 @@ msgstr "グループ化…"
#. module: base
#: view:base.module.update:0
msgid "Module Update Result"
-msgstr ""
+msgstr "モジュール更新結果"
#. module: base
#: model:ir.module.module,description:base.module_analytic_contract_hr_expense
@@ -11331,7 +11331,7 @@ msgstr "町名番地2"
#. module: base
#: model:ir.actions.act_window,name:base.action_view_base_module_update
msgid "Module Update"
-msgstr "モジュールの更新"
+msgstr "モジュール更新"
#. module: base
#: code:addons/base/module/wizard/base_module_upgrade.py:85
@@ -12752,7 +12752,7 @@ msgstr ""
#. module: base
#: model:ir.model,name:base.model_base_module_update
msgid "Update Module"
-msgstr "モジュールの更新"
+msgstr "モジュール更新"
#. module: base
#: view:ir.model.fields:0
@@ -13220,7 +13220,7 @@ msgstr "アドミニストレーション"
#. module: base
#: view:base.module.update:0
msgid "Click on Update below to start the process..."
-msgstr "プロセスを開始するために以下にある更新をクリックして下さい。"
+msgstr "下の「更新」をクリックして処理を開始してください。"
#. module: base
#: model:res.country,name:base.ir
diff --git a/openerp/addons/base/i18n/ka.po b/openerp/addons/base/i18n/ka.po
index ea6f84fb25d..f2b25b56518 100644
--- a/openerp/addons/base/i18n/ka.po
+++ b/openerp/addons/base/i18n/ka.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:51+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:32+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/kk.po b/openerp/addons/base/i18n/kk.po
index 088e68c8ecf..6e4ba5af6a2 100644
--- a/openerp/addons/base/i18n/kk.po
+++ b/openerp/addons/base/i18n/kk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:54+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:34+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/ko.po b/openerp/addons/base/i18n/ko.po
index 7fcfaea8090..15517e3b7d8 100644
--- a/openerp/addons/base/i18n/ko.po
+++ b/openerp/addons/base/i18n/ko.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:54+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:34+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/lt.po b/openerp/addons/base/i18n/lt.po
index a5444cb20a9..13f78cccfab 100644
--- a/openerp/addons/base/i18n/lt.po
+++ b/openerp/addons/base/i18n/lt.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:54+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:34+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/lv.po b/openerp/addons/base/i18n/lv.po
index 9bdabdd7375..2821b0c5cc6 100644
--- a/openerp/addons/base/i18n/lv.po
+++ b/openerp/addons/base/i18n/lv.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:54+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:34+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@@ -811,7 +811,7 @@ msgstr "Automatizētas darbības"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_ro
msgid "Romania - Accounting"
-msgstr ""
+msgstr "Rumānija - Grāmatvedība"
#. module: base
#: model:ir.model,name:base.model_res_config_settings
@@ -937,12 +937,12 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_document_webdav
msgid "Shared Repositories (WebDAV)"
-msgstr ""
+msgstr "Koplietošanas Krātuves (WebDAV)"
#. module: base
#: view:res.users:0
msgid "Email Preferences"
-msgstr ""
+msgstr "E-pasta Uzstādījumi"
#. module: base
#: code:addons/base/ir/ir_fields.py:195
@@ -1005,7 +1005,7 @@ msgstr "Omāna"
#. module: base
#: model:ir.module.module,shortdesc:base.module_mrp
msgid "MRP"
-msgstr ""
+msgstr "Ražošana"
#. module: base
#: model:ir.module.module,description:base.module_hr_attendance
@@ -2491,7 +2491,7 @@ msgstr "Grupas (ja nav = globāla)"
#. module: base
#: view:ir.module.module:0
msgid "Extra"
-msgstr ""
+msgstr "Papildus"
#. module: base
#: model:res.country,name:base.st
@@ -16443,3 +16443,9 @@ msgstr ""
#~ msgid "Administration Dashboard"
#~ msgstr "Administrēšanas instrumentu panelis"
+
+#~ msgid "Process"
+#~ msgstr "Apstrādāt"
+
+#~ msgid "Website of Partner."
+#~ msgstr "Partnera Vietne"
diff --git a/openerp/addons/base/i18n/mk.po b/openerp/addons/base/i18n/mk.po
index 50a0c798e04..5a00f189c50 100644
--- a/openerp/addons/base/i18n/mk.po
+++ b/openerp/addons/base/i18n/mk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:54+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:34+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/mn.po b/openerp/addons/base/i18n/mn.po
index 34ebb4dbd9c..e5881f12e7d 100644
--- a/openerp/addons/base/i18n/mn.po
+++ b/openerp/addons/base/i18n/mn.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:55+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:34+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/nb.po b/openerp/addons/base/i18n/nb.po
index f2f99275430..6d6634f2816 100644
--- a/openerp/addons/base/i18n/nb.po
+++ b/openerp/addons/base/i18n/nb.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:55+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:35+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/nl.po b/openerp/addons/base/i18n/nl.po
index 058b613bbc5..f8c9847ff7c 100644
--- a/openerp/addons/base/i18n/nl.po
+++ b/openerp/addons/base/i18n/nl.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:51+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:31+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/nl_BE.po b/openerp/addons/base/i18n/nl_BE.po
index 606bf883037..3b569c62d90 100644
--- a/openerp/addons/base/i18n/nl_BE.po
+++ b/openerp/addons/base/i18n/nl_BE.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:59+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:39+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/pl.po b/openerp/addons/base/i18n/pl.po
index 57b43e7c23c..1f92bb9c7ad 100644
--- a/openerp/addons/base/i18n/pl.po
+++ b/openerp/addons/base/i18n/pl.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:55+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:35+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/pt.po b/openerp/addons/base/i18n/pt.po
index f7cb3a108c2..798ac68932b 100644
--- a/openerp/addons/base/i18n/pt.po
+++ b/openerp/addons/base/i18n/pt.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:55+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:35+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/pt_BR.po b/openerp/addons/base/i18n/pt_BR.po
index 60584967b72..b38b1150afe 100644
--- a/openerp/addons/base/i18n/pt_BR.po
+++ b/openerp/addons/base/i18n/pt_BR.po
@@ -9,13 +9,13 @@ msgstr ""
"POT-Creation-Date: 2012-12-21 17:04+0000\n"
"PO-Revision-Date: 2012-12-16 22:18+0000\n"
"Last-Translator: Fábio Martinelli - http://zupy.com.br "
-"\n"
+"\n"
"Language-Team: \n"
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:58+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:38+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/ro.po b/openerp/addons/base/i18n/ro.po
index c695f8af8cc..ddf6c83cb06 100644
--- a/openerp/addons/base/i18n/ro.po
+++ b/openerp/addons/base/i18n/ro.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:56+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:35+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@@ -211,14 +211,14 @@ msgid ""
"reports."
msgstr ""
"\n"
-"Genereaza Facturi din Cheltuieli, Inregistrari ale Fiselor de Pontaj.\n"
+"Generează Facturi din Cheltuieli, Înregistrări ale Fișelor de Pontaj.\n"
"========================================================\n"
"\n"
"Modul pentru generarea facturilor pe baza costurilor (resurse umane, "
"cheltuieli, ...).\n"
"\n"
-"Puteti defini liste de preturi in contul analitic, puteti face unele raporte "
-"teoretice\n"
+"Puteți defini liste de preturi în contul analitic, puteți face unele "
+"rapoarte teoretice\n"
"ale veniturilor."
#. module: base
@@ -236,8 +236,8 @@ msgid ""
"Properties of base fields cannot be altered in this manner! Please modify "
"them through Python code, preferably through a custom addon!"
msgstr ""
-"Proprietatile campurilor principale nu pot fi modificate in acest mod! Va "
-"rugam sa le modificati prin codul Python, preferabil printr-un addon "
+"Proprietățile câmpurilor principale nu pot fi modificate în acest mod! Vă "
+"rugăm sa le modificați prin codul Python, preferabil printr-un addon "
"personalizat!"
#. module: base
@@ -333,12 +333,12 @@ msgstr ""
#. module: base
#: view:res.partner:0
msgid "Search Partner"
-msgstr "Cauta Partener"
+msgstr "Caută Partener"
#. module: base
#: field:ir.module.category,module_nr:0
msgid "Number of Modules"
-msgstr "Numar de Module"
+msgstr "Număr de module"
#. module: base
#: help:multi_company.default,company_dest_id:0
@@ -348,7 +348,7 @@ msgstr "Compania unde se pastreaza înregistrarea actuală"
#. module: base
#: field:res.partner.bank.type.field,size:0
msgid "Max. Size"
-msgstr "Dimensiunea maxima"
+msgstr "Dimensiunea maximă"
#. module: base
#: help:ir.actions.act_window,res_id:0
@@ -451,7 +451,7 @@ msgstr ""
#: code:addons/orm.py:2649
#, python-format
msgid "Invalid group_by"
-msgstr "Grup invalid_dupa"
+msgstr "Grupare_După invalidă"
#. module: base
#: field:ir.module.category,child_ids:0
@@ -499,7 +499,7 @@ msgstr "Configurare pași asistent"
#. module: base
#: model:ir.model,name:base.model_ir_ui_view_sc
msgid "ir.ui.view_sc"
-msgstr "ir.ui.vizualizare_sc"
+msgstr "ir.ui.view_sc"
#. module: base
#: view:ir.model.access:0
@@ -1289,7 +1289,7 @@ msgstr "Principatul Andorra"
#. module: base
#: field:ir.rule,perm_read:0
msgid "Apply for Read"
-msgstr "Se aplică pentru Citit"
+msgstr "Se aplică pentru citire"
#. module: base
#: model:res.country,name:base.mn
@@ -2204,7 +2204,7 @@ msgstr "Timorul de Est"
#: view:ir.module.module:0
#, python-format
msgid "Install"
-msgstr "Instalează"
+msgstr "Instalați"
#. module: base
#: field:res.currency,accuracy:0
@@ -2704,7 +2704,7 @@ msgstr "Bahamas"
#. module: base
#: field:ir.rule,perm_create:0
msgid "Apply for Create"
-msgstr "Aplică pentru Creare"
+msgstr "Aplică pentru creare"
#. module: base
#: model:ir.module.category,name:base.module_category_tools
@@ -3310,7 +3310,7 @@ msgstr "Raport RML"
#. module: base
#: model:ir.ui.menu,name:base.menu_translation_export
msgid "Import / Export"
-msgstr "Import / Export"
+msgstr "Importați / Exportați"
#. module: base
#: model:ir.module.module,description:base.module_sale
@@ -3479,7 +3479,7 @@ msgstr "Letonia"
#. module: base
#: view:ir.actions.server:0
msgid "Field Mappings"
-msgstr "Aplicatii Camp"
+msgstr "Corespondențe câmp"
#. module: base
#: view:base.language.export:0
@@ -4557,7 +4557,7 @@ msgstr "Persoane"
#. module: base
#: view:base.language.import:0
msgid "_Import"
-msgstr "_Importă"
+msgstr "_Importați"
#. module: base
#: field:res.users,action_id:0
@@ -6122,7 +6122,7 @@ msgstr "Asistenta IT"
#. module: base
#: model:ir.module.category,name:base.module_category_specific_industry_applications
msgid "Specific Industry Applications"
-msgstr "Aplicatii Specifice Industriei"
+msgstr "Aplicații Specifice Industriei"
#. module: base
#: model:ir.module.module,shortdesc:base.module_google_docs
@@ -6340,7 +6340,7 @@ msgstr "Nu poate fi cautat"
#: view:ir.config_parameter:0
#: field:ir.config_parameter,key:0
msgid "Key"
-msgstr "Tastă"
+msgstr "Cheie"
#. module: base
#: field:res.company,rml_header:0
@@ -7050,7 +7050,7 @@ msgstr "ir.actions.act_url"
#. module: base
#: model:ir.ui.menu,name:base.menu_translation_app
msgid "Application Terms"
-msgstr "Termeni aplicație"
+msgstr "Termenii aplicației"
#. module: base
#: model:ir.actions.act_window,help:base.open_module_tree
@@ -9347,7 +9347,7 @@ msgstr "Burundi"
#: view:base.module.configuration:0
#: view:base.module.update:0
msgid "Close"
-msgstr "Inchide"
+msgstr "Închideți"
#. module: base
#: selection:base.language.install,lang:0
@@ -9570,7 +9570,7 @@ msgstr "Chineza (CN) / 简体中文"
#. module: base
#: field:ir.model.fields,selection:0
msgid "Selection Options"
-msgstr "Optiuni de selectie"
+msgstr "Opțiuni de selecție"
#. module: base
#: field:res.bank,street:0
@@ -9847,13 +9847,13 @@ msgid ""
" \n"
" "
msgstr ""
-"\n"
-" Faceti click pentru a adauga un contact in agenda "
-"dumneavoastra.\n"
+"
\n"
+" Faceți clic pentru a adaugă un contact în agenda "
+"dumneavoastră.\n"
"
\n"
-" OpenERP va ajuta sa tineti evidenta cu usurinta a tuturor "
-"activitatilor legate de\n"
-" un client: discutii, istoricul oportunitatilor de afaceri,\n"
+" OpenERP vă ajută să țineți evidența cu ușurință a tuturor "
+"activităților legate de\n"
+" un client: discuții, istoricul oportunităților de afaceri,\n"
" documente, etc.\n"
"
\n"
" "
@@ -10656,8 +10656,8 @@ msgid ""
"If the selected language is loaded in the system, all documents related to "
"this contact will be printed in this language. If not, it will be English."
msgstr ""
-"Daca limba selectata este incarcata in sistem, toate documentele asociate "
-"acestui contact vor fi tiparite in aceasta limba. Daca nu, limba va fi "
+"Dacă limba selectata este încărcata în sistem, toate documentele asociate "
+"acestui contact vor fi tipărite în aceasta limba. Dacă nu, limba va fi "
"engleza."
#. module: base
@@ -10828,7 +10828,7 @@ msgstr ""
#. module: base
#: field:ir.actions.report.xml,attachment_use:0
msgid "Reload from Attachment"
-msgstr "Reincarcati din Atasament"
+msgstr "Reîncarcați din Atașament"
#. module: base
#: model:res.country,name:base.mx
@@ -10982,7 +10982,7 @@ msgstr "ID-ul vizualizarii definita in fisierul xml"
#. module: base
#: model:ir.model,name:base.model_base_module_import
msgid "Import Module"
-msgstr "Importati Modulul"
+msgstr "Importați Modulul"
#. module: base
#: model:res.country,name:base.as
@@ -11632,7 +11632,7 @@ msgstr "efectuat"
#. module: base
#: view:ir.actions.act_window:0
msgid "General Settings"
-msgstr "Configurari generale"
+msgstr "Configurări generale"
#. module: base
#: model:ir.module.module,description:base.module_l10n_in
@@ -13074,7 +13074,7 @@ msgstr ""
#: model:ir.actions.act_window,name:base.action_view_base_module_upgrade
#, python-format
msgid "Apply Schedule Upgrade"
-msgstr "Aplica Programeaza Actualizarea"
+msgstr "Aplică actualizările planificate"
#. module: base
#: view:workflow.activity:0
@@ -13444,7 +13444,7 @@ msgstr ""
#. module: base
#: view:base.module.import:0
msgid "Import module"
-msgstr "Importati modulul"
+msgstr "Importați modulul"
#. module: base
#: field:ir.actions.server,loop_action:0
@@ -13745,10 +13745,10 @@ msgid ""
"not connect to the system. You can assign them groups in order to give them "
"specific access to the applications they need to use in the system."
msgstr ""
-"Creati si gestionati utilizatori care se vor conecta la sistem. Utilizatorii "
-"pot fi dezactivati in caz ca exista o perioada de timp in care ei nu se "
-"conecteaza la sistem. Le puteti atribui grupuri pentru a le da acces "
-"specific la aplicatiile de care ei au nevoie in sistem."
+"Creați și gestionați utilizatori care se vor conecta la sistem. Utilizatorii "
+"pot fi dezactivați în caz că există o perioada de timp în care ei nu se "
+"conectează la sistem. Le puteți atribui grupuri pentru a le da acces "
+"specific la aplicațiile de care ei au nevoie în sistem."
#. module: base
#: selection:res.request,priority:0
@@ -13856,7 +13856,7 @@ msgstr "Declansati Configurarea"
#. module: base
#: view:base.language.install:0
msgid "Load"
-msgstr "Incarca"
+msgstr "Încărcați"
#. module: base
#: model:ir.module.module,description:base.module_warning
@@ -14298,7 +14298,7 @@ msgstr "Contactul nu a putut fi creat fara adresa de email !"
#: model:ir.ui.menu,name:base.menu_mrp_config
#: model:ir.ui.menu,name:base.menu_mrp_root
msgid "Manufacturing"
-msgstr "Fabricatie"
+msgstr "Fabricație"
#. module: base
#: model:res.country,name:base.km
@@ -14931,7 +14931,7 @@ msgstr ""
#: model:ir.actions.act_window,name:base.action_view_base_import_language
#: model:ir.ui.menu,name:base.menu_view_base_import_language
msgid "Import Translation"
-msgstr "Importati Traducerea"
+msgstr "Importați Traducerea"
#. module: base
#: view:ir.module.module:0
@@ -15470,7 +15470,7 @@ msgstr "Grecia"
#. module: base
#: view:res.config:0
msgid "Apply"
-msgstr "Aplicati"
+msgstr "Aplicați"
#. module: base
#: field:res.request,trigger_date:0
@@ -17452,7 +17452,7 @@ msgstr "Helpdesk (Serviciu de asistenta tehnica)"
#. module: base
#: field:ir.rule,perm_write:0
msgid "Apply for Write"
-msgstr "Aplica pentru Scriere"
+msgstr "Aplicați pentru scriere"
#. module: base
#: field:ir.ui.menu,parent_left:0
@@ -17558,7 +17558,7 @@ msgstr "Vizualizare :"
#. module: base
#: field:ir.model.fields,view_load:0
msgid "View Auto-Load"
-msgstr "Vizualizare Incarcare Automata"
+msgstr "Vizualizare încarcare automată"
#. module: base
#: model:ir.module.module,description:base.module_l10n_et
@@ -17607,7 +17607,7 @@ msgstr "Fisier Pictograma Web"
#. module: base
#: model:ir.ui.menu,name:base.menu_view_base_module_upgrade
msgid "Apply Scheduled Upgrades"
-msgstr "Aplica Actualizarile Planificate"
+msgstr "Aplică actualizările planificate"
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale_journal
@@ -18572,7 +18572,7 @@ msgstr "Conditie"
#: model:ir.actions.client,name:base.modules_updates_act_cl
#: model:ir.ui.menu,name:base.menu_module_updates
msgid "Updates"
-msgstr "Actualizari"
+msgstr "Actualizări"
#. module: base
#: help:res.currency,rate:0
@@ -18875,7 +18875,7 @@ msgid ""
"Helps you manage your manufacturing processes and generate reports on those "
"processes."
msgstr ""
-"Va ajuta sa va administrati procesele de fabricatie si sa generati rapoarte "
+"Vă ajută să vă administrați procesele de fabricație și să generați rapoarte "
"pentru aceste procese."
#. module: base
@@ -19030,13 +19030,13 @@ msgid ""
" \n"
" "
msgstr ""
-"\n"
-" Faceti click pentru a adauga un contact in agenda "
-"dumneavoastra.\n"
+"\n"
+" Faceți clic pentru a adaugă un contact în agenda "
+"dumneavoastră.\n"
"
\n"
-" OpenERP va ajuta sa tineti evidenta cu usurinta a tuturor "
-"activitatilor asociate unui\n"
-" client; discutii, istoricul oportunitatilor de afaceri,\n"
+" OpenERP vă ajută să țineți evidența cu ușurință a tuturor "
+"activităților legate de\n"
+" un client: discuții, istoricul oportunităților de afaceri,\n"
" documente, etc.\n"
"
\n"
" "
diff --git a/openerp/addons/base/i18n/ru.po b/openerp/addons/base/i18n/ru.po
index 747c668f58e..b648054f2ff 100644
--- a/openerp/addons/base/i18n/ru.po
+++ b/openerp/addons/base/i18n/ru.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:56+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:35+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/sk.po b/openerp/addons/base/i18n/sk.po
index e2a3d3d2c70..a49a57f40b7 100644
--- a/openerp/addons/base/i18n/sk.po
+++ b/openerp/addons/base/i18n/sk.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:56+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:36+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/sl.po b/openerp/addons/base/i18n/sl.po
index 30c74d45a3b..07f1ef6cc72 100644
--- a/openerp/addons/base/i18n/sl.po
+++ b/openerp/addons/base/i18n/sl.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:57+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:36+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/sq.po b/openerp/addons/base/i18n/sq.po
index b65571634e8..6e9dcf6c81e 100644
--- a/openerp/addons/base/i18n/sq.po
+++ b/openerp/addons/base/i18n/sq.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:49+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:29+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/sr.po b/openerp/addons/base/i18n/sr.po
index 401b8eeeefe..3639a2e1a0a 100644
--- a/openerp/addons/base/i18n/sr.po
+++ b/openerp/addons/base/i18n/sr.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:56+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:36+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/sr@latin.po b/openerp/addons/base/i18n/sr@latin.po
index 487c476d291..3231571faaf 100644
--- a/openerp/addons/base/i18n/sr@latin.po
+++ b/openerp/addons/base/i18n/sr@latin.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:01+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:40+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/sv.po b/openerp/addons/base/i18n/sv.po
index 308a8414d14..fce7d3c433e 100644
--- a/openerp/addons/base/i18n/sv.po
+++ b/openerp/addons/base/i18n/sv.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:57+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:37+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/th.po b/openerp/addons/base/i18n/th.po
index b2db6d0218f..67dd4a1d937 100644
--- a/openerp/addons/base/i18n/th.po
+++ b/openerp/addons/base/i18n/th.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:57+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:37+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/tlh.po b/openerp/addons/base/i18n/tlh.po
index fc5523973d0..8f697a3cc0a 100644
--- a/openerp/addons/base/i18n/tlh.po
+++ b/openerp/addons/base/i18n/tlh.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:57+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:37+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/tr.po b/openerp/addons/base/i18n/tr.po
index ee2d812abc9..9b9459b6824 100644
--- a/openerp/addons/base/i18n/tr.po
+++ b/openerp/addons/base/i18n/tr.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:57+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:37+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/uk.po b/openerp/addons/base/i18n/uk.po
index 09ce58ae0e6..8b04e292c43 100644
--- a/openerp/addons/base/i18n/uk.po
+++ b/openerp/addons/base/i18n/uk.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:58+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:37+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/ur.po b/openerp/addons/base/i18n/ur.po
index 02d7b94a7b5..d60600ea028 100644
--- a/openerp/addons/base/i18n/ur.po
+++ b/openerp/addons/base/i18n/ur.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:58+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:37+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/vi.po b/openerp/addons/base/i18n/vi.po
index 35590f72e7c..1baf54016ca 100644
--- a/openerp/addons/base/i18n/vi.po
+++ b/openerp/addons/base/i18n/vi.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:58+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:38+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/zh_CN.po b/openerp/addons/base/i18n/zh_CN.po
index b7f757443f6..11d6e3cd8ec 100644
--- a/openerp/addons/base/i18n/zh_CN.po
+++ b/openerp/addons/base/i18n/zh_CN.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:00+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:40+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@@ -11642,7 +11642,7 @@ msgid ""
msgstr ""
"\n"
"模块提供事件变更警告。\n"
-" ==============================================\n"
+"==============================================\n"
"\n"
"Warning messages can be displayed for objects like sale order, purchase "
"order,\n"
diff --git a/openerp/addons/base/i18n/zh_HK.po b/openerp/addons/base/i18n/zh_HK.po
index e0aa71c1260..2144e7f4a58 100644
--- a/openerp/addons/base/i18n/zh_HK.po
+++ b/openerp/addons/base/i18n/zh_HK.po
@@ -14,8 +14,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 05:58+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:38+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
diff --git a/openerp/addons/base/i18n/zh_TW.po b/openerp/addons/base/i18n/zh_TW.po
index c5b91007ef1..a65c4e31d40 100644
--- a/openerp/addons/base/i18n/zh_TW.po
+++ b/openerp/addons/base/i18n/zh_TW.po
@@ -13,8 +13,8 @@ msgstr ""
"MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n"
-"X-Launchpad-Export-Date: 2013-11-23 06:00+0000\n"
-"X-Generator: Launchpad (build 16831)\n"
+"X-Launchpad-Export-Date: 2013-12-03 05:39+0000\n"
+"X-Generator: Launchpad (build 16856)\n"
#. module: base
#: model:ir.module.module,description:base.module_account_check_writing
@@ -50,7 +50,7 @@ msgstr "日期時間"
msgid ""
"The second argument of the many2many field %s must be a SQL table !You used "
"%s, which is not a valid SQL table name."
-msgstr "「多對多(many2many)」欄位 %s 之第二個引數須為 SQL 表格!您用了並非有效 SQL 表格名稱之 %s。"
+msgstr "「多對多(many2many)」欄位 %s 之第二個引數須為 SQL 表格!您輸入的 %s 並非有效 SQL 表格名稱。"
#. module: base
#: field:ir.ui.view,arch:0
@@ -61,7 +61,7 @@ msgstr "檢視架構"
#. module: base
#: model:ir.module.module,summary:base.module_sale_stock
msgid "Quotation, Sale Orders, Delivery & Invoicing Control"
-msgstr "報價, 銷售訂單, 交貨及發票管理"
+msgstr "報價單, 銷貨單, 發貨及發票管理"
#. module: base
#: selection:ir.sequence,implementation:0
@@ -88,7 +88,7 @@ msgstr "幫助你管理專案,追蹤任務,生成計劃"
#. module: base
#: model:ir.module.module,summary:base.module_point_of_sale
msgid "Touchscreen Interface for Shops"
-msgstr "商店觸控螢幕界面"
+msgstr "店面用觸控螢幕界面"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_in_hr_payroll
@@ -122,15 +122,15 @@ msgid ""
" "
msgstr ""
"\n"
-"在產品表格中加入製造商及屬性之模組\n"
+"此模組在產品表單中加入製造商及屬性\n"
"====================================================================\n"
"\n"
-"您可以對一件產品做以下定義:\n"
+"您可以對產品定義以下內容:\n"
"-----------------------------------------------\n"
" * 製造商\n"
" * 製造商的產品名稱\n"
" * 製造商的產品代碼\n"
-" * 產品性質\n"
+" * 產品屬性\n"
" "
#. module: base
@@ -145,11 +145,14 @@ msgid ""
"The module adds google user in res user.\n"
"========================================\n"
msgstr ""
+"\n"
+"此模組將 Google 使用者加到 res user 中。\n"
+"========================================\n"
#. module: base
#: help:res.partner,employee:0
msgid "Check this box if this contact is an Employee."
-msgstr "如果聯絡人是員工則請勾選"
+msgstr "如果聯絡人是員工則請勾選此項"
#. module: base
#: help:ir.model.fields,domain:0
@@ -232,7 +235,7 @@ msgstr "ir.ui.view.custom"
#: code:addons/base/ir/ir_model.py:374
#, python-format
msgid "Renaming sparse field \"%s\" is not allowed"
-msgstr ""
+msgstr "不允許重新命名稀疏欄位「%s」"
#. module: base
#: model:res.country,name:base.sz
@@ -286,6 +289,12 @@ msgid ""
"\n"
" "
msgstr ""
+"\n"
+"智利會計科目及稅務在地化。\n"
+"==============================================\n"
+"Plan contable chileno e impuestos de acuerdo a disposiciones vigentes\n"
+"\n"
+" "
#. module: base
#: model:ir.module.module,shortdesc:base.module_sale
@@ -324,7 +333,7 @@ msgstr "最大尺寸"
msgid ""
"Database ID of record to open in form view, when ``view_mode`` is set to "
"'form' only"
-msgstr ""
+msgstr "當「檢視模式」僅設為「表單」時,將開啟的紀錄的資料庫 ID"
#. module: base
#: help:ir.values,key2:0
@@ -389,7 +398,7 @@ msgstr ""
msgid ""
"There is already a shared filter set as default for %(model)s, delete or "
"change it before setting a new default"
-msgstr ""
+msgstr "已有一共享的過濾器被設為 %(model)s 的預設過濾器。要設定新的預設過濾器前,請先修改或刪除原有預設過濾器。"
#. module: base
#: code:addons/orm.py:2649
@@ -465,7 +474,7 @@ msgstr "所指定為無效的日期/時間格式指示。請參照當您編寫
msgid ""
"One of the records you are trying to modify has already been deleted "
"(Document type: %s)."
-msgstr ""
+msgstr "您要修改的紀錄已被刪除(文件類型: %s)。"
#. module: base
#: help:ir.actions.act_window,views:0
@@ -691,7 +700,7 @@ msgstr "自訂欄位名稱開頭必須是 'x_' !"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_mx
msgid "Mexico - Accounting"
-msgstr ""
+msgstr "墨西哥 - 會計"
#. module: base
#: help:ir.actions.server,action_id:0
@@ -847,7 +856,7 @@ msgstr "自動化動作"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_ro
msgid "Romania - Accounting"
-msgstr ""
+msgstr "羅馬尼亞 - 會計"
#. module: base
#: model:ir.model,name:base.model_res_config_settings
@@ -970,7 +979,7 @@ msgstr "報表類型,如 pdf, html, raw, sxw, odt, html2html, mako2html, ..."
#. module: base
#: model:ir.module.module,shortdesc:base.module_document_webdav
msgid "Shared Repositories (WebDAV)"
-msgstr ""
+msgstr "共享的儲存庫(WebDAV)"
#. module: base
#: view:res.users:0
@@ -997,7 +1006,7 @@ msgstr "辛巴威"
#: help:ir.model.constraint,type:0
msgid ""
"Type of the constraint: `f` for a foreign key, `u` for other constraints."
-msgstr ""
+msgstr "限制條件類型:「f」為 foreign key ,「u」代表其他限制條件。"
#. module: base
#: view:ir.actions.report.xml:0
@@ -1092,7 +1101,7 @@ msgstr "請求參考類型"
#. module: base
#: model:ir.module.module,shortdesc:base.module_google_base_account
msgid "Google Users"
-msgstr ""
+msgstr "Google 使用者"
#. module: base
#: model:ir.module.module,shortdesc:base.module_fleet
@@ -1260,6 +1269,8 @@ msgid ""
"Language with code \"%s\" is not defined in your system !\n"
"Define it through the Administration menu."
msgstr ""
+"您的系統中尚未定義語言代碼為「 %s 」的語言! \n"
+"請於管理者介面中定義。"
#. module: base
#: model:res.country,name:base.gu
@@ -1269,7 +1280,7 @@ msgstr "關島(美屬)"
#. module: base
#: sql_constraint:res.country:0
msgid "The name of the country must be unique !"
-msgstr ""
+msgstr "國家名稱必須為獨一無二的!"
#. module: base
#: field:ir.module.module,installed_version:0
@@ -1406,7 +1417,7 @@ msgid ""
"suitable\n"
" for uploading to OpenERP's translation "
"platform,"
-msgstr ""
+msgstr "TGZ 格式:這是含有 PO 格式檔案的壓縮檔,適用於直接上傳至 OpenERP 的翻譯平台。"
#. module: base
#: view:res.lang:0
@@ -1430,7 +1441,7 @@ msgstr "測試"
#. module: base
#: field:ir.actions.report.xml,attachment:0
msgid "Save as Attachment Prefix"
-msgstr ""
+msgstr "另存附件檔案的前綴字元"
#. module: base
#: field:ir.ui.view_sc,res_id:0
@@ -1467,7 +1478,7 @@ msgstr "海地"
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_fr_hr_payroll
msgid "French Payroll"
-msgstr ""
+msgstr "法國薪資"
#. module: base
#: view:ir.ui.view:0
@@ -1506,12 +1517,12 @@ msgstr "操作取消"
#. module: base
#: model:ir.module.module,shortdesc:base.module_document
msgid "Document Management System"
-msgstr ""
+msgstr "文件管理系統"
#. module: base
#: model:ir.module.module,shortdesc:base.module_crm_claim
msgid "Claims Management"
-msgstr ""
+msgstr "申訴管理"
#. module: base
#: model:ir.module.module,description:base.module_document_webdav
@@ -13105,7 +13116,7 @@ msgstr ""
#. module: base
#: model:ir.module.module,shortdesc:base.module_l10n_be_hr_payroll_account
msgid "Belgium - Payroll with Accounting"
-msgstr ""
+msgstr "比利時 - 薪資(含會計)"
#. module: base
#: selection:base.language.export,format:0
From 43979cfd8f4a9145504522c333a5ca09b2dde5f3 Mon Sep 17 00:00:00 2001
From: Antony Lesuisse
Date: Tue, 3 Dec 2013 20:06:39 +0100
Subject: [PATCH 5/6] [IMP] http improvement - context manager request object
(removes some ugly hacks) - improve http error handling - add lazyresponses
bzr revid: al@openerp.com-20131203190639-e8r1qm9wc82t8g4k
---
openerp/addons/base/ir/ir_http.py | 60 ++++++++++----
openerp/http.py | 130 +++++++++++++++---------------
2 files changed, 108 insertions(+), 82 deletions(-)
diff --git a/openerp/addons/base/ir/ir_http.py b/openerp/addons/base/ir/ir_http.py
index ff8a2a8ebd8..02d3fee61b7 100644
--- a/openerp/addons/base/ir/ir_http.py
+++ b/openerp/addons/base/ir/ir_http.py
@@ -3,6 +3,7 @@
#----------------------------------------------------------
import logging
import re
+import sys
import werkzeug.exceptions
import werkzeug.routing
@@ -74,26 +75,29 @@ class ir_http(osv.AbstractModel):
request.disable_db = True
request.uid = None
- def _authenticate(self, func, arguments):
- auth_method = getattr(func, "auth", "user")
+ def _authenticate(self, auth_method='user'):
if request.session.uid:
try:
request.session.check_security()
# what if error in security.check()
# -> res_users.check()
# -> res_users.check_credentials()
- except Exception:
+ except http.SessionExpiredException:
request.session.logout()
+ raise http.SessionExpiredException("Session expired for request %s" % request.httprequest)
getattr(self, "_auth_method_%s" % auth_method)()
return auth_method
- def _handle_404(self, exception):
- raise exception
+ def _handle_exception(self, exception):
+ if isinstance(exception, openerp.exceptions.AccessError):
+ code = 403
+ else:
+ code = getattr(exception, 'code', 500)
- def _handle_403(self, exception):
- raise exception
+ fn = getattr(self, '_handle_%d' % code, self._handle_unknown_exception)
+ return fn(exception)
- def _handle_500(self, exception):
+ def _handle_unknown_exception(self, exception):
raise exception
def _dispatch(self):
@@ -101,13 +105,16 @@ class ir_http(osv.AbstractModel):
try:
func, arguments = self._find_handler()
except werkzeug.exceptions.NotFound, e:
- return self._handle_404(e)
+ return self._handle_exception(e)
# check authentication level
try:
- auth_method = self._authenticate(func, arguments)
- except werkzeug.exceptions.NotFound, e:
- return self._handle_403(e)
+ auth_method = self._authenticate(getattr(func, "auth", None))
+ except Exception:
+ # force a Forbidden exception with the original traceback
+ return self._handle_exception(
+ convert_exception_to(
+ werkzeug.exceptions.Forbidden))
# post process arg to set uid on browse records
for arg in arguments.itervalues():
@@ -121,9 +128,7 @@ class ir_http(osv.AbstractModel):
if isinstance(result, Exception):
raise result
except Exception, e:
- fn = getattr(self, '_handle_%s' % getattr(e, 'code', 500),
- self._handle_500)
- return fn(e)
+ return self._handle_exception(e)
return result
@@ -139,4 +144,29 @@ class ir_http(osv.AbstractModel):
return self._routing_map
+def convert_exception_to(to_type, with_message=False):
+ """ Should only be called from an exception handler. Fetches the current
+ exception data from sys.exc_info() and creates a new exception of type
+ ``to_type`` with the original traceback.
+
+ If ``with_message`` is ``True``, sets the new exception's message to be
+ the stringification of the original exception. If ``False``, does not
+ set the new exception's message. Otherwise, uses ``with_message`` as the
+ new exception's message.
+
+ :type with_message: str|bool
+ """
+ etype, original, tb = sys.exc_info()
+ try:
+ if with_message is False:
+ message = None
+ elif with_message is True:
+ message = str(original)
+ else:
+ message = str(with_message)
+
+ raise to_type, message, tb
+ except to_type, e:
+ return e
+
# vim:et:
diff --git a/openerp/http.py b/openerp/http.py
index 993af6d2752..6e819ba45f1 100644
--- a/openerp/http.py
+++ b/openerp/http.py
@@ -3,7 +3,6 @@
# OpenERP HTTP layer
#----------------------------------------------------------
import ast
-import cgi
import collections
import contextlib
import errno
@@ -36,13 +35,20 @@ import werkzeug.wsgi
import openerp
from openerp.service import security, model as service_model
-from openerp.tools import config
_logger = logging.getLogger(__name__)
#----------------------------------------------------------
# RequestHandler
#----------------------------------------------------------
+# Thread local global request object
+_request_stack = werkzeug.local.LocalStack()
+
+request = _request_stack()
+"""
+ A global proxy that always redirect to the current request object.
+"""
+
class WebRequest(object):
""" Parent class for all OpenERP Web request types, mostly deals with
initialization and setup of the request object (the dispatching itself has
@@ -138,11 +144,24 @@ class WebRequest(object):
trying to access this property will raise an exception.
"""
# some magic to lazy create the cr
- if not self._cr_cm:
- self._cr_cm = self.registry.cursor()
- self._cr = self._cr_cm.__enter__()
+ if not self._cr:
+ self._cr = self.registry.db.cursor()
return self._cr
+ def __enter__(self):
+ _request_stack.push(self)
+ return self
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ _request_stack.pop()
+ if self._cr:
+ if exc_type is None:
+ self._cr.commit()
+ self._cr.close()
+ # just to be sure no one tries to re-use the request
+ self.disable_db = True
+ self.uid = None
+
def set_handler(self, func, arguments, auth):
# is this needed ?
arguments = dict((k, v) for k, v in arguments.iteritems()
@@ -154,39 +173,23 @@ class WebRequest(object):
self.auth_method = auth
def _call_function(self, *args, **kwargs):
- try:
- # ugly syntax only to get the __exit__ arguments to pass to self._cr
- request = self
- class with_obj(object):
- def __enter__(self):
- pass
- def __exit__(self, *args):
- if request._cr_cm:
- request._cr_cm.__exit__(*args)
- request._cr_cm = None
- request._cr = None
+ request = self
+ if self.func_request_type != self._request_type:
+ raise Exception("%s, %s: Function declared as capable of handling request of type '%s' but called with a request of type '%s'" \
+ % (self.func, self.httprequest.path, self.func_request_type, self._request_type))
- with with_obj():
- if self.func_request_type != self._request_type:
- raise Exception("%s, %s: Function declared as capable of handling request of type '%s' but called with a request of type '%s'" \
- % (self.func, self.httprequest.path, self.func_request_type, self._request_type))
+ kwargs.update(self.func_arguments)
- kwargs.update(self.func_arguments)
-
- # Backward for 7.0
- if getattr(self.func, '_first_arg_is_req', False):
- args = (request,) + args
- # Correct exception handling and concurency retry
- @service_model.check
- def checked_call(dbname, *a, **kw):
- return self.func(*a, **kw)
- if self.db:
- return checked_call(self.db, *args, **kwargs)
- return self.func(*args, **kwargs)
- finally:
- # just to be sure no one tries to re-use the request
- self.disable_db = True
- self.uid = None
+ # Backward for 7.0
+ if getattr(self.func, '_first_arg_is_req', False):
+ args = (request,) + args
+ # Correct exception handling and concurency retry
+ @service_model.check
+ def checked_call(dbname, *a, **kw):
+ return self.func(*a, **kw)
+ if self.db:
+ return checked_call(self.db, *args, **kwargs)
+ return self.func(*args, **kwargs)
@property
def debug(self):
@@ -197,7 +200,7 @@ class WebRequest(object):
warnings.warn('please use request.registry and request.cr directly', DeprecationWarning)
yield (self.registry, self.cr)
-def route(route, type="http", auth="user"):
+def route(route, type="http", auth="user", methods=None):
"""
Decorator marking the decorated method as being a handler for requests. The method must be part of a subclass
of ``Controller``.
@@ -214,6 +217,7 @@ def route(route, type="http", auth="user"):
* ``none``: The method is always active, even if there is no database. Mainly used by the framework and
authentication modules. There request code will not have any facilities to access the database nor have any
configuration indicating the current database nor the current user.
+ :param methods: A sequence of http methods this route applies to. If not specified, all methods are allowed.
"""
assert type in ["http", "json"]
def decorator(f):
@@ -221,6 +225,7 @@ def route(route, type="http", auth="user"):
f.routes = route
else:
f.routes = [route]
+ f.methods = methods
f.exposed = type
if getattr(f, "auth", None) is None:
f.auth = auth
@@ -398,17 +403,8 @@ class HttpRequest(WebRequest):
def dispatch(self):
try:
r = self._call_function(**self.params)
- except werkzeug.exceptions.HTTPException, e:
+ except (werkzeug.exceptions.HTTPException), e:
r = e
- except Exception, e:
- _logger.exception("An exception occured during an http request")
- se = serialize_exception(e)
- error = {
- 'code': 200,
- 'message': "OpenERP Server Error",
- 'data': se
- }
- r = werkzeug.exceptions.InternalServerError(cgi.escape(simplejson.dumps(error)))
else:
if not r:
r = werkzeug.wrappers.Response(status=204) # no content
@@ -451,24 +447,6 @@ def httprequest(f):
base = ""
return route([base, base + "/"], type="http", auth="user")(f)
-#----------------------------------------------------------
-# Thread local global request object
-#----------------------------------------------------------
-_request_stack = werkzeug.local.LocalStack()
-
-request = _request_stack()
-"""
- A global proxy that always redirect to the current request object.
-"""
-
-@contextlib.contextmanager
-def set_request(req):
- _request_stack.push(req)
- try:
- yield
- finally:
- _request_stack.pop()
-
#----------------------------------------------------------
# Controller and route registration
#----------------------------------------------------------
@@ -526,7 +504,7 @@ def routing_map(modules, nodb_only, converters=None):
url = o._cp_path.rstrip('/') + '/' + url.lstrip('/')
if url.endswith("/") and len(url) > 1:
url = url[: -1]
- routing_map.add(werkzeug.routing.Rule(url, endpoint=mv))
+ routing_map.add(werkzeug.routing.Rule(url, endpoint=mv, methods=mv.methods))
return routing_map
#----------------------------------------------------------
@@ -816,6 +794,18 @@ mimetypes.add_type('application/font-woff', '.woff')
mimetypes.add_type('application/vnd.ms-fontobject', '.eot')
mimetypes.add_type('application/x-font-ttf', '.ttf')
+class LazyResponse(werkzeug.wrappers.Response):
+ """ Lazy werkzeug response.
+ API not yet frozen"""
+
+ def __init__(self, callback, **kwargs):
+ super(LazyResponse, self).__init__(mimetype='text/html')
+ self.callback = callback
+ self.params = kwargs
+ def process(self):
+ response = self.callback(**self.params)
+ self.response.append(response)
+
class DisableCacheMiddleware(object):
def __init__(self, app):
self.app = app
@@ -941,6 +931,12 @@ class Root(object):
return HttpRequest(httprequest)
def get_response(self, httprequest, result, explicit_session):
+ if isinstance(result, LazyResponse):
+ try:
+ result.process()
+ except(Exception), e:
+ result = request.registry['ir.http']._handle_exception(e)
+
if isinstance(result, basestring):
response = werkzeug.wrappers.Response(result, mimetype='text/html')
else:
@@ -980,7 +976,7 @@ class Root(object):
result = request.dispatch()
return result
- with set_request(request):
+ with request:
db = request.session.db
if db:
openerp.modules.registry.RegistryManager.check_registry_signaling(db)
From 4c45774b6d87eafa7b5c1b006894b5f3339d64b2 Mon Sep 17 00:00:00 2001
From: Antony Lesuisse
Date: Tue, 3 Dec 2013 20:16:21 +0100
Subject: [PATCH 6/6] [IMP] manual exception handling for non-json controllers
bzr revid: al@openerp.com-20131203191621-xu2350cw0u3izn3s
---
addons/web/controllers/main.py | 32 +++++++++++++++++++++++++++++---
1 file changed, 29 insertions(+), 3 deletions(-)
diff --git a/addons/web/controllers/main.py b/addons/web/controllers/main.py
index 41bb6ccfca7..8f7c5d4f70d 100644
--- a/addons/web/controllers/main.py
+++ b/addons/web/controllers/main.py
@@ -3,6 +3,7 @@
import ast
import base64
import csv
+import functools
import glob
import itertools
import logging
@@ -35,7 +36,9 @@ from openerp.tools.translate import _
from openerp.tools import config
from openerp import http
-from openerp.http import request
+from openerp.http import request, serialize_exception as _serialize_exception
+
+_logger = logging.getLogger(__name__)
#----------------------------------------------------------
# OpenERP Web helpers
@@ -89,6 +92,22 @@ db_list = http.db_list
db_monodb = http.db_monodb
+def serialize_exception(f):
+ @functools.wraps(f)
+ def wrap(*args, **kwargs):
+ try:
+ return f(*args, **kwargs)
+ except Exception, e:
+ _logger.exception("An exception occured during an http request")
+ se = _serialize_exception(e)
+ error = {
+ 'code': 200,
+ 'message': "OpenERP Server Error",
+ 'data': se
+ }
+ return werkzeug.exceptions.InternalServerError(simplejson.dumps(error))
+ return wrap
+
def redirect_with_hash(url, code=303):
if request.httprequest.user_agent.browser in ('msie', 'safari'):
# Most IE and Safari versions decided not to preserve location.hash upon
@@ -542,14 +561,14 @@ class Home(http.Controller):
def redirect(db):
query = dict(urlparse.parse_qsl(request.httprequest.query_string, keep_blank_values=True))
- query.update({'db': db})
+ query['db'] = db
redirect = request.httprequest.path + '?' + urllib.urlencode(query)
return redirect_with_hash(redirect)
if db is None and guessed_db is not None:
return redirect(guessed_db)
- if db is not None and db != guessed_db:
+ if db is not None and db != request.session.db:
request.session.logout()
request.session.db = db
guessed_db = db
@@ -1220,6 +1239,7 @@ class Binary(http.Controller):
return open(os.path.join(addons_path, 'web', 'static', 'src', 'img', image), 'rb').read()
@http.route('/web/binary/saveas', type='http', auth="user")
+ @serialize_exception
def saveas(self, model, field, id=None, filename_field=None, **kw):
""" Download link for files stored as binary fields.
@@ -1253,6 +1273,7 @@ class Binary(http.Controller):
('Content-Disposition', content_disposition(filename))])
@http.route('/web/binary/saveas_ajax', type='http', auth="user")
+ @serialize_exception
def saveas_ajax(self, data, token):
jdata = simplejson.loads(data)
model = jdata['model']
@@ -1286,6 +1307,7 @@ class Binary(http.Controller):
cookies={'fileToken': token})
@http.route('/web/binary/upload', type='http', auth="user")
+ @serialize_exception
def upload(self, callback, ufile):
# TODO: might be useful to have a configuration flag for max-length file uploads
out = """