From 8cca1716611bb420f48bfd82a449aa7cf4cab05f Mon Sep 17 00:00:00 2001 From: "vda (OpenERP)" Date: Tue, 31 May 2011 16:55:45 +0530 Subject: [PATCH 001/230] [FIX] Calendar. bzr revid: vda@tinyerp.com-20110531112545-laa8rp2xxx9ympgk --- addons/base_calendar/controllers/main.py | 350 +---------------- .../base_calendar/static/src/js/calendar.js | 370 +++++++++++------- .../static/src/xml/base_calendar.xml | 10 +- 3 files changed, 233 insertions(+), 497 deletions(-) diff --git a/addons/base_calendar/controllers/main.py b/addons/base_calendar/controllers/main.py index a54d75c5b9b..41ede2bb7ab 100644 --- a/addons/base_calendar/controllers/main.py +++ b/addons/base_calendar/controllers/main.py @@ -1,356 +1,10 @@ from base.controllers.main import View -import openerpweb, time, math, re, datetime as DT, pytz - -COLOR_PALETTE = ['#f57900', '#cc0000', '#d400a8', '#75507b', '#3465a4', '#73d216', '#c17d11', '#edd400', - '#fcaf3e', '#ef2929', '#ff00c9', '#ad7fa8', '#729fcf', '#8ae234', '#e9b96e', '#fce94f', - '#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00', - '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900', ] - -_colorline = ['#%02x%02x%02x' % (25 + ((r + 10) % 11) * 23, 5 + ((g + 1) % 11) * 20, 25 + ((b + 4) % 11) * 23) for r in range(11) for g in range(11) for b in range(11) ] - -DT_SERVER_FORMATS = { - 'datetime' : '%Y-%m-%d %H:%M:%S', - 'date' : '%Y-%m-%d', - 'time' : '%H:%M:%S' -} - -DT_FORMAT_INFO = {'datetime' : ('%Y-%m-%d %H:%M:%S', DT.datetime, 0, 6), - 'date': ('%Y-%m-%d', DT.date, 0, 3), - 'time': ('%H:%M:%S', DT.time, 3, 6)} - -def choice_colors(n): - if n > len(COLOR_PALETTE): - return _colorline[0:-1:len(_colorline) / (n + 1)] - elif n: - return COLOR_PALETTE[:n] - return [] +import openerpweb class CalendarView(View): _cp_path = "/base_calendar/calendarview" - mode = 'month' - date_start = None - date_delay = None - date_stop = None - color_field = None - day_length = 8 - use_search = False - selected_day = None - date_format = '%Y-%m-%d' - info_fields = [] - fields = {} - events = [] - - colors = {} - color_values = [] - - remote_timezone = 'utc' - client_timezone = False - - calendar_fields = {} - concurrency_info = None - - ids = [] - model = '' - domain = [] - context = {} - @openerpweb.jsonrequest def load(self, req, model, view_id): fields_view = self.fields_view_get(req, model, view_id, 'calendar') - return {'fields_view':fields_view} - - def convert(self, event): - fields = [self.date_start] - if self.date_stop: - fields.append(self.date_stop) - - for fld in fields: - fld_type = self.fields[fld]['type'] - fmt = DT_SERVER_FORMATS[fld_type] - if event[fld] and fmt: - event[fld] = time.strptime(event[fld], fmt) - - # default start/stop time is 9:00 AM / 5:00 PM - if fld_type == 'date' and event[fld]: - ds = list(event[fld]) - if fld == self.date_start: - ds[3] = 9 - elif fld == self.date_stop: - ds[3] = 17 - event[fld] = tuple(ds) - - - @openerpweb.jsonrequest - def schedule_events(self, req, **kw): - self.model = kw['model'] - self.mode = kw.get('mode') or self.mode or 'month' - self.fields = kw['fields'] - self.color_field = kw.get('color_field') or self.color_field or None - self.colors = kw.get('colors') or {} - self.calendar_fields = kw['calendar_fields'] - self.info_fields = kw['info_fields'] - self.date_start = self.calendar_fields['date_start']['name'] - self.domain = kw.get('domain') or [] - - self.remote_timezone = req.session.remote_timezone - self.client_timezone = req.session.client_timezone - - if self.calendar_fields.get('date_stop'): - self.date_stop = self.calendar_fields['date_stop']['name'] - - if self.calendar_fields.get('date_delay'): - self.date_delay = self.calendar_fields['date_delay']['name'] - - model = req.session.model(self.model) - event_ids = model.search(self.domain) - - self.events = model.read(event_ids, self.fields.keys()) - result = [] - self.date_format = req.session._lang and req.session._lang['date_format'] - - if self.color_field: - for evt in self.events: - key = evt[self.color_field] - name = key - value = key - if isinstance(key, list): # M2O, XMLRPC returns List instead of Tuple - name = key[0] - value = key[-1] - evt[self.color_field] = key = key[-1] - if isinstance(key, tuple): # M2O - value, name = key - self.colors[key] = (name, value, None) - - colors = choice_colors(len(self.colors)) - for i, (key, value) in enumerate(self.colors.items()): - self.colors[key] = [value[0], value[1], colors[i]] - - for evt in self.events: - self.convert(evt) - a = self.get_event_widget(evt) - result.append(a) - - return {'result':result,'sidebar':self.colors} - - def parsedatetime(self, string): - - kind = 'datetime' - - if '-' in string and ':' in string: - kind = 'datetime' - elif '-' in string: - kind = 'date' - elif ':' in string: - kind = 'time' - - fmt, obj, i, j = DT_FORMAT_INFO[kind] - return obj(*time.strptime(string, fmt)[i:j]) - - def parse_datetime(self, value, kind="datetime", as_timetuple=False): - server_format = DT_SERVER_FORMATS[kind] - local_format = self.date_format - if not value: - return False - - if isinstance(value, (time.struct_time, tuple)): - value = time.strftime(local_format, value) - - try: - value = time.strptime(value, local_format) - except ValueError: - try: - # might be in server format already (e.g. filter domain) - value = time.strptime(value, server_format) - except ValueError: - try: - dt = list(time.localtime()) - dt[2] = int(value) - value = tuple(dt) - except: - return False - - if kind == "datetime": - try: - value = self.tz_convert(value, 'parse') - except Exception,e: - print "*******************Error in timezone parsing *********",e - - if as_timetuple: - return value - - return time.strftime(server_format, value) - - - @openerpweb.jsonrequest - def edit_events(self, req,**kw): - data = {} - ds = self.parsedatetime(kw['start_date']) - de = self.parsedatetime(kw['end_date']) - data[kw['calendar_fields']['date_start']['name']] = self.parse_datetime(ds.timetuple()) - - if 'date_stop' in kw['calendar_fields']: - data[kw['calendar_fields']['date_stop']['name']] = self.parse_datetime(de.timetuple()) - elif 'date_delay' in kw['calendar_fields']: - day_length = kw['calendar_fields']['day_length'] - - tds = time.mktime(ds.timetuple()) - tde = time.mktime(de.timetuple()) - - n = (tde - tds) / (60 * 60) - - if n > day_length: - d = math.floor(n / 24) - h = n % 24 - - n = d * day_length + h - - data[kw['calendar_fields']['date_delay']['name']] = n - error = None - try: - req.session.model(kw['model']).write([int(kw['id'])], data) - except Exception, e: - error = e - return error - - def tz_convert(self, struct_time, action): - # if no client timezone is configured, consider the client is in the same - # timezone as the server - lzone = pytz.timezone(self.client_timezone or self.remote_timezone) - szone = pytz.timezone(self.remote_timezone) - dt = DT.datetime.fromtimestamp(time.mktime(struct_time)) - - if action == 'parse': - fromzone = lzone - tozone = szone - elif action == 'format': - fromzone = szone - tozone = lzone - else: - raise Exception("_tz_convert action should be 'parse' or 'format'. Not '%s'" % (action, )) - - localized_original_datetime = fromzone.localize(dt, is_dst=True) - destination_datetime = localized_original_datetime.astimezone(tozone) - return destination_datetime.timetuple() - - def format_datetime(self, value, kind="datetime", as_timetuple=False): - """Convert date value to the local datetime considering timezone info. - - @param value: the date value - @param kind: type of the date value (date, time or datetime) - @param as_timetuple: return timetuple - - @type value: basestring or time.time_tuple) - - @return: string or timetuple - """ - - server_format = DT_SERVER_FORMATS[kind] - local_format = self.date_format - - if not value: - return '' - - if isinstance(value, (time.struct_time, tuple)): - value = time.strftime(server_format, value) - - if isinstance(value, DT.datetime): - value = value - try: - value = DT.datetime.strptime(value[:10], server_format) - return value.strftime(local_format) - except: - return '' - - value = value.strip() - - # remove trailing miliseconds - value = re.sub("(.*?)(\s+\d{2}:\d{2}:\d{2})(\.\d+)?$", "\g<1>\g<2>", value) - - # add time part in value if missing - if kind == 'datetime' and not re.search('\s+\d{2}:\d{2}:\d{2}?$', value): - value += ' 00:00:00' - - # remove time part from value - elif kind == 'date': - value = re.sub('\s+\d{2}:\d{2}:\d{2}(\.\d+)?$', '', value) - - value = time.strptime(value, server_format) - - if kind == "datetime": - try: - value = self.tz_convert(value, 'format') - except Exception, e: - print "\n\n\n************ Error in timezone formatting", e - - if as_timetuple: - return value - - return time.strftime(local_format, value) - - def get_event_widget(self, event): - title = '' # the title - description = [] # the description - - if self.info_fields: - - f = self.info_fields[0] - s = event[f] - - if isinstance(s, (tuple, list)): s = s[-1] - - title = s - for f in self.info_fields[1:]: - s = event[f] - if isinstance(s, (tuple, list)): - s = s[-1] - if s: - description.append(str(s)) - - starts = event.get(self.date_start) - ends = event.get(self.date_delay) or 1.0 - span = 0 - - if starts and ends: - - n = 0 - h = ends - - if ends == self.day_length: - span = 1 - - elif ends > self.day_length: - n = ends / self.day_length - h = ends % self.day_length - - n = int(math.floor(n)) - - if h > 0: - span = n + 1 - else: - span = n - ends = time.localtime(time.mktime(starts) + (h * 60 * 60) + (n * 24 * 60 * 60)) - - if starts and self.date_stop: - - ends = event.get(self.date_stop) - if not ends: - ends = time.localtime(time.mktime(starts) + 60 * 60) - - tds = time.mktime(starts) - tde = time.mktime(ends) - - if tds >= tde: - tde = tds + 60 * 60 - ends = time.localtime(tde) - - n = (tde - tds) / (60 * 60) - - if n >= self.day_length: - span = math.ceil(n / 24) - - starts = self.format_datetime(starts, "datetime", True) - ends = self.format_datetime(ends, "datetime", True) - title = title.strip() - description = ', '.join(description).strip() - return {'id': event['id'], 'start_date': str(DT.datetime(*starts[:6])), 'end_date': str(DT.datetime(*ends[:6])), 'text': title, 'title': description, 'color': self.colors[event[self.color_field]][-1]} + return {'fields_view': fields_view} diff --git a/addons/base_calendar/static/src/js/calendar.js b/addons/base_calendar/static/src/js/calendar.js index 96a7fad8178..5e6d52fc93a 100644 --- a/addons/base_calendar/static/src/js/calendar.js +++ b/addons/base_calendar/static/src/js/calendar.js @@ -11,14 +11,13 @@ openerp.base_calendar.CalendarView = openerp.base.Controller.extend({ this._super(session, element_id); this.view_manager = view_manager; this.dataset = dataset; - this.dataset_index = 0; this.model = dataset.model; this.view_id = view_id; this.fields_view = {}; this.widgets = {}; this.widgets_counter = 0; this.fields = this.dataset.fields ? this.dataset.fields: {}; - this.datarecord = {}; + this.ids = this.dataset.ids; this.name = ""; this.date_start = ""; this.date_delay = ""; @@ -35,23 +34,22 @@ openerp.base_calendar.CalendarView = openerp.base.Controller.extend({ start: function() { this.rpc("/base_calendar/calendarview/load", {"model": this.model, "view_id": this.view_id}, this.on_loaded); }, - on_loaded: function(result) { - var self = this; - var params = {}; - this.fields_view = result.fields_view; - this.name = this.fields_view.name || this.fields_view.arch.attrs.string; + on_loaded: function(data) { + + this.fields_view = data.fields_view; + this.name = this.fields_view.name || this.fields_view.arch.attrs.string; this.view_id = this.fields_view.view_id; - - this.date_start = this.fields_view.arch.attrs.date_start; + + this.date_start = this.fields_view.arch.attrs.date_start; this.date_delay = this.fields_view.arch.attrs.date_delay; this.date_stop = this.fields_view.arch.attrs.date_stop; - - this.colors = this.fields_view.arch.attrs.colors; + + this.colors = this.fields_view.arch.attrs.colors; this.day_length = this.fields_view.arch.attrs.day_length || 8; this.color_field = this.fields_view.arch.attrs.color; this.fields = this.fields_view.fields; - - //* Calendar Fields * + + //* Calendar Fields * this.calendar_fields['date_start'] = {'name': this.date_start, 'kind': this.fields[this.date_start]['type']}; if(this.date_delay) @@ -59,121 +57,181 @@ openerp.base_calendar.CalendarView = openerp.base.Controller.extend({ if(this.date_stop) this.calendar_fields['date_stop'] = {'name': this.date_stop, 'kind': this.fields[this.date_stop]['type']}; - - this.calendar_fields['day_length'] = this.day_length; - //* ------- * - for(var fld=0;fld',{'width':'100%','cellspacing': 0, 'cellpadding': 0, 'id':'cal-sidebar-option'}) - ) - for(s in sidebar) { - jQuery('#cal-sidebar-option').append( - jQuery('').append( - jQuery('').append( - jQuery('
') - .append( - jQuery('', - { - 'type': 'checkbox', - 'id':sidebar[s][0], - 'value':sidebar[s][0] - }).bind('click',function(){ - self.reload_scheduler() - }), - sidebar[s][1] - ) - .css('background-color',sidebar[s][sidebar[s].length-1]) - ) - ) - ) - } - }, - - convert_date_format: function(start_date, end_date) { - var params = {}; - params['start_date'] = start_date.getFullYear() +'-' + start_date.getMonth()+'-' + start_date.getDate()+' '+start_date.getHours()+':'+start_date.getMinutes()+':'+start_date.getSeconds(); - if(end_date) { - params['end_date'] = end_date.getFullYear() +'-' + end_date.getMonth()+'-' + end_date.getDate()+' '+end_date.getHours()+':'+end_date.getMinutes()+':'+end_date.getSeconds(); - } - return params; - }, - - edit_event: function(evt_id, evt_object) { - var dates = this.convert_date_format(evt_object.start_date, evt_object.end_date); - this.rpc( - '/base_calendar/calendarview/edit_events', - { - 'start_date': dates.start_date, - 'end_date': dates.end_date, - 'id': evt_id, - 'model': this.model, - 'info_fields': this.info_fields, - 'fields': this.fields, - 'calendar_fields': this.calendar_fields - } - ); - }, - - mini_calendar: function() { + + //To parse Events we have to convert date Format + var res_events = []; + for(var e=0;e this.day_length) { + n = end / this.day_length; + h = end % this.day_length; + n = parseInt(Math.floor(n)); + + if(h > 0) + span = n + 1 + else + span = n + } + var end_date = openerp.base.parse_datetime(start); + end = end_date.add({hours: h, minutes: n}) + } + if(start && this.date_stop) { + var tds = start = openerp.base.parse_datetime(start); + var tde = ends = openerp.base.parse_datetime(event[this.date_stop]); + if(event[this.date_stop] == undefined) { + if(tds) { + end = (tds.getOrdinalNumber() + 60 * 60) + } + } + + if(tds && tde) { + //time.mktime equivalent + tds = (tds.getOrdinalNumber() / 1e3 >> 0) - (tds.getOrdinalNumber() < 0); + tde = (tde.getOrdinalNumber() / 1e3 >> 0) - (tde.getOrdinalNumber() < 0); + + } + if(tds >= tde) { + tde = tds + 60 * 60; + } + + n = (tde - tds) / (60 * 60); + if (n >= this.day_length) { + span = Math.ceil(n / 24); + } + } + + return { + 'start_date': start.toString('yyyy-MM-dd HH:mm:ss'), + 'end_date': end.toString('yyyy-MM-dd HH:mm:ss'), + 'text': res_text, + 'id': event['id'], + 'title': res_description.join() + } + }, + + mini_calendar: function() { if(scheduler.isCalendarVisible()) { scheduler.destroyCalendar(); @@ -189,11 +247,22 @@ openerp.base_calendar.CalendarView = openerp.base.Controller.extend({ }); } }, - - reload_scheduler: function() { -// self.color_field - console.log('Reload Scheduler>>>') - }, + + do_search: function(domains, contexts, groupbys) { + var self = this; + this.rpc('/base/session/eval_domain_and_context', { + domains: domains, + contexts: contexts, + group_by_seq: groupbys + }, function (results) { + // TODO: handle non-empty results.group_by with read_group + self.dataset.context = self.context = results.context; + self.dataset.domain = self.domain = results.domain; + self.dataset.read_slice(self.fields, 0, self.limit,function(events){ + self.schedule_events(events) + }); + }); + }, do_show: function () { this.$element.show(); @@ -201,23 +270,42 @@ openerp.base_calendar.CalendarView = openerp.base.Controller.extend({ do_hide: function () { this.$element.hide(); + }, + + popup_event: function(event_id) { + var action_manager = this.view_manager.session.action_manager; + + var action = { + "res_model": this.dataset.model, + "res_id": event_id, + "views":[[false,"form"]], + "type":"ir.actions.act_window", + "view_type":"form", + "view_mode":"form" + } + + action.flags = { + search_view: false, + sidebar : false, + views_switcher : false, + action_buttons : false, + pager: false + } + var element_id = _.uniqueId("act_window_dialog"); + var dialog = jQuery('
', { + 'id': element_id + }).dialog({ + modal: true, + width: 'auto', + height: 'auto' + }); + + var action_manager = new openerp.base.ActionManager(this.session, element_id); + action_manager.start(); + action_manager.do_action(action); } }); -//openerp.base.Action = openerp.base.Action.extend({ -// do_action_window: function(action) { -// this._super.apply(this,arguments); -// for(var i = 0; i < action.views.length; i++) { -// if(action.views[i][1] == "calendar") { -// this.calendar_id = action.views[i][0]; -// break; -// } -// } -// // IF there is a view calender -// // if(this.calendar_id -// }, -//}); - }; // DEBUG_RPC:rpc.request:('execute', 'addons-dsh-l10n_us', 1, '*', ('ir.filters', 'get_filters', u'res.partner')) diff --git a/addons/base_calendar/static/src/xml/base_calendar.xml b/addons/base_calendar/static/src/xml/base_calendar.xml index 02d67be05bb..59f77cbb0bc 100644 --- a/addons/base_calendar/static/src/xml/base_calendar.xml +++ b/addons/base_calendar/static/src/xml/base_calendar.xml @@ -1,15 +1,9 @@ From 41f1ac6d77f9fe618f1824268ae123306dc124c6 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 1 Jul 2011 14:19:03 +0200 Subject: [PATCH 028/230] [ADD] handling of clicking on a not-done config item in order to execute it Also, refresh the widget after the config popup has closed bzr revid: xmo@openerp.com-20110701121903-bzrxzc6eynh7txe9 --- .../base_dashboard/static/src/js/dashboard.js | 29 +++++++++++++++---- .../static/src/xml/base_dashboard.xml | 3 +- 2 files changed, 26 insertions(+), 6 deletions(-) diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index 926a0173178..eadea5d2319 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -280,14 +280,19 @@ openerp.base.client_actions.add( if (!openerp.base_dashboard) { openerp.base_dashboard = {}; } -openerp.base_dashboard.ConfigOverview = openerp.base.Controller.extend({ +openerp.base_dashboard.ConfigOverview = openerp.base.View.extend({ + init: function (parent_or_session, element_id) { + this._super(parent_or_session, element_id); + this.dataset = new openerp.base.DataSetSearch( + this.session, 'ir.actions.todo'); + }, start: function () { - new openerp.base.DataSetSearch(this.session, 'ir.actions.todo') - .read_slice(['state', 'action_id'], undefined, undefined, + this.dataset.read_slice(['state', 'action_id'], undefined, undefined, this.on_records_loaded); }, on_records_loaded: function (records) { - var done_records = _(records).filter(function (record) { + var self = this, + done_records = _(records).filter(function (record) { return record.state === 'done';}), done_ratio = done_records.length / records.length; this.$element.html(QWeb.render('ConfigOverview', { @@ -299,12 +304,26 @@ openerp.base_dashboard.ConfigOverview = openerp.base.Controller.extend({ state: record.state, done: record.state === 'done', skipped: record.state === 'skip', - to_do: record.state !== 'done' && record.state !== 'skip' + to_do: (record.state !== 'done' && record.state !== 'skip') } }) })); var $progress = this.$element.find('div.oe-config-progress'); $progress.progressbar({value: $progress.data('completion')}); + + // allow for executing to-do and skipped action + this.$element.find('div.oe-dashboard-config-overview ul') + .delegate('li.ui-state-error', 'click', function () { + self.execute_action({ + type: 'action', + name: $(this).data('action') + }, self.dataset, + new openerp.base.ActionManager(self.session, self.element_id), + null, null, function () { + // after action popup closed, refresh configuration thingie + self.start(); + }); + }); } }) }; diff --git a/addons/base_dashboard/static/src/xml/base_dashboard.xml b/addons/base_dashboard/static/src/xml/base_dashboard.xml index a6b9d9f7002..0149dfa8d01 100644 --- a/addons/base_dashboard/static/src/xml/base_dashboard.xml +++ b/addons/base_dashboard/static/src/xml/base_dashboard.xml @@ -69,7 +69,8 @@
  • + t-att-class="!todo.done ? 'ui-state-error ' + (todo.skipped ? 'ui-priority-secondary' : 'ui-priority-primary') : ''" + t-att-data-action="todo.action"> From dc2cdac7e03db3c8732e17f16053eeafeb800523 Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Fri, 1 Jul 2011 17:52:22 +0530 Subject: [PATCH 029/230] [IMP] Implemented Drop DB feature. bzr revid: noz@tinyerp.com-20110701122222-kph026dlps1tkgzq --- addons/base/controllers/main.py | 14 +++++++++++++- addons/base/static/src/css/base.css | 2 +- addons/base/static/src/js/chrome.js | 14 ++++++++++++++ addons/base/static/src/xml/base.xml | 18 +++++++++--------- 4 files changed, 37 insertions(+), 11 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 5f923e7a35a..8d3069cc190 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -119,7 +119,19 @@ class Session(openerpweb.Controller): except Exception, e: pass return {"lang_list": lang_list} - + + @openerpweb.jsonrequest + def drop_db(self, req, **kw): + + db = kw.get('db') + password = kw.get('password') + try: + res = req.session.proxy("db").drop(password, db) + if res: + return res + except TypeError: + return {'error': e} + @openerpweb.jsonrequest def modules(self, req): return {"modules": [name diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index e6d475b4bc2..cf54e816288 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -189,7 +189,7 @@ ul.db_options li { -moz-border-radius: 10px; } -.db_option_table input[type="text"], input[type="password"], select, textarea { +.db_option_table input[type="text"], input[type="password"], select { width: 300px; } diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 19104f67e77..a2a243790df 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -938,6 +938,20 @@ openerp.base.Database = openerp.base.Controller.extend({ self.$element.find('#db-drop').click(function() { self.db_string = "DROP DATABASE"; self.$option_id.html(QWeb.render("DropDB", self)); + + self.$option_id.find('#drop_db_btn').click(function() { + var db = self.$option_id.find("select[name=drop_db]").val(); + var password = self.$option_id.find("input[name=drop_password]").val(); + + if (confirm("Do you really want to delete the database: " + db + " ?")) { + self.rpc("/base/session/drop_db", {'db': db, 'password': password}, + function(result) { + self.$option_id.find("select[name=drop_db] :selected").remove(); + self.notification.notify("Dropping database", "The database '" + db + "' has been dropped"); + }); + } + }); + }); self.$element.find('#db-backup').click(function() { self.db_string = "BACKUP DATABASE"; diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index ffe40947ca3..8bb13f10963 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -113,7 +113,7 @@ - + @@ -127,9 +127,9 @@ - + - @@ -137,11 +137,11 @@ - - + + - +
    @@ -171,7 +171,7 @@ - + @@ -197,7 +197,7 @@ - + @@ -223,7 +223,7 @@ - + From 38340f448d069bf44ce685b99594491abed2ed17 Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Fri, 1 Jul 2011 17:54:30 +0530 Subject: [PATCH 030/230] [FIX] Created common method for all Database operations. bzr revid: noz@tinyerp.com-20110701122430-lhomemgtfay5jeev --- addons/base/controllers/main.py | 19 ++++++++++--------- addons/base/static/src/js/chrome.js | 2 +- 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 8d3069cc190..56328489a5b 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -121,16 +121,17 @@ class Session(openerpweb.Controller): return {"lang_list": lang_list} @openerpweb.jsonrequest - def drop_db(self, req, **kw): + def db_operation(self, req, flag, **kw): - db = kw.get('db') - password = kw.get('password') - try: - res = req.session.proxy("db").drop(password, db) - if res: - return res - except TypeError: - return {'error': e} + if flag == 'drop': + db = kw.get('db') + password = kw.get('password') + try: + res = req.session.proxy("db").drop(password, db) + if res: + return res + except TypeError: + return {'error': e} @openerpweb.jsonrequest def modules(self, req): diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index a2a243790df..7e19d138ff0 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -944,7 +944,7 @@ openerp.base.Database = openerp.base.Controller.extend({ var password = self.$option_id.find("input[name=drop_password]").val(); if (confirm("Do you really want to delete the database: " + db + " ?")) { - self.rpc("/base/session/drop_db", {'db': db, 'password': password}, + self.rpc("/base/session/db_operation", {'flag': 'drop', 'db': db, 'password': password}, function(result) { self.$option_id.find("select[name=drop_db] :selected").remove(); self.notification.notify("Dropping database", "The database '" + db + "' has been dropped"); From b027703a918fee2fa262fe35380fc3a8bd48d526 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 1 Jul 2011 14:59:19 +0200 Subject: [PATCH 031/230] [FIX] stray comma in dashboard code bzr revid: xmo@openerp.com-20110701125919-fqo4ipj5pjo0d6pc --- addons/base_dashboard/static/src/js/dashboard.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index eadea5d2319..476dbd499f3 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -147,7 +147,7 @@ openerp.base.form.DashBoard = openerp.base.form.Widget.extend({ modal: true, title: 'Edit Layout', width: 'auto', - height: 'auto', + height: 'auto' }).html(QWeb.render('DashBoard.layouts', qdict)); $dialog.find('li').click(function() { var layout = $(this).attr('data-layout'); From 93eccd6b5439e6328634371d13841f55aa89032c Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 1 Jul 2011 15:03:13 +0200 Subject: [PATCH 032/230] [IMP] don't filter dashboard action picker on act_window, server & url &etc... are kind-of valid although the dashboard will probably need to have its own ActionManager and override the behavior of default for some actions e.g. act_url bzr revid: xmo@openerp.com-20110701130313-g5755hicgkle9k2q --- addons/base_dashboard/static/src/js/dashboard.js | 1 - 1 file changed, 1 deletion(-) diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index 476dbd499f3..df2ae08e5de 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -61,7 +61,6 @@ openerp.base.form.DashBoard = openerp.base.form.Widget.extend({ type : 'ir.actions.act_window', limit : 80, auto_search : true, - domain : [['type', '=', 'ir.actions.act_window']], flags : { sidebar : false, views_switcher : false, From cbbae67165670e574cf737648652ca4b6dc2b6e2 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 1 Jul 2011 15:05:17 +0200 Subject: [PATCH 033/230] [ADD] possibility to use a client action in a menu bzr revid: xmo@openerp.com-20110701130517-p8dz909jho2658vk --- openerp/addons/base/ir/ir_ui_menu.py | 1 + 1 file changed, 1 insertion(+) diff --git a/openerp/addons/base/ir/ir_ui_menu.py b/openerp/addons/base/ir/ir_ui_menu.py index d67f0c247d1..9ed4d7806bc 100644 --- a/openerp/addons/base/ir/ir_ui_menu.py +++ b/openerp/addons/base/ir/ir_ui_menu.py @@ -273,6 +273,7 @@ class ir_ui_menu(osv.osv): ('ir.actions.wizard', 'ir.actions.wizard'), ('ir.actions.url', 'ir.actions.url'), ('ir.actions.server', 'ir.actions.server'), + ('ir.actions.client', 'ir.actions.client'), ]), } From 37dfdc617650868df584fbf17b9f3c320db32080 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Fri, 1 Jul 2011 15:35:34 +0200 Subject: [PATCH 034/230] [ADD] config overview client action to the administration dashboard bzr revid: xmo@openerp.com-20110701133534-6rl45ygunb5oqcti --- addons/board/board_administration_view.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/addons/board/board_administration_view.xml b/addons/board/board_administration_view.xml index 337ca63dab8..e997059c51c 100644 --- a/addons/board/board_administration_view.xml +++ b/addons/board/board_administration_view.xml @@ -87,6 +87,11 @@ + + Configuration Overview + board.config.overview + + board.res.log.report.graph @@ -143,6 +148,7 @@ + From ba2221125bab804dbc3a69c9c08d36f04707aa31 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 4 Jul 2011 15:04:24 +0200 Subject: [PATCH 035/230] [IMP] hide secondary menu by default, only show when a menu is activated bzr revid: xmo@openerp.com-20110704130424-o7pi6fi48kcmwx1e --- addons/base/static/src/css/base.css | 1 + addons/base/static/src/js/chrome.js | 6 +++--- addons/base/static/src/xml/base.xml | 2 +- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index 32a335d7eb8..1d5dd7b6314 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -430,6 +430,7 @@ background: linear-gradient(top, #ffffff 0%,#d8d8d8 11%,#afafaf 86%,#333333 91%, } /* Main Application */ +.openerp .oe-main-content, .openerp .oe-application { padding: 0; height: 100%; diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 6064e0f4c46..1faf0eb2878 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -271,7 +271,7 @@ openerp.base.BasicController = Class.extend( /** @lends openerp.base.BasicContro * that does nothing and always return undefined). * * @param {Class} claz - * @param {dict} add Additional functions to override. + * @param {Object} add Additional functions to override. * @return {Class} */ openerp.base.generate_null_object_class = function(claz, add) { @@ -1012,7 +1012,7 @@ openerp.base.Menu = openerp.base.Controller.extend({ init: function(session, element_id, secondary_menu_id) { this._super(session, element_id); this.secondary_menu_id = secondary_menu_id; - this.$secondary_menu = $("#" + secondary_menu_id); + this.$secondary_menu = $("#" + secondary_menu_id).hide(); this.menu = false; }, start: function() { @@ -1071,7 +1071,7 @@ openerp.base.Menu = openerp.base.Controller.extend({ this.on_menu_action_loaded); } - $('.active', this.$element.add(this.$secondary_menu)).removeClass('active'); + $('.active', this.$element.add(this.$secondary_menu.show())).removeClass('active'); $parent.addClass('active'); $menu.addClass('active'); $menu.parent('h4').addClass('active'); diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 9bef00147d3..96c05f2595e 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -27,7 +27,7 @@ - +
    &nbsp;
    From 9d77bed1cab4965ddbabe19fbc97b4b582e42621 Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Mon, 4 Jul 2011 18:48:38 +0530 Subject: [PATCH 036/230] [FIX] Handled exception when dropping a database. bzr revid: noz@tinyerp.com-20110704131838-lf4x944os5ynuy0u --- addons/base/controllers/main.py | 8 ++------ addons/base/static/src/js/chrome.js | 10 ++++++---- openerpweb/openerpweb.py | 29 ++++++++++++++++++++--------- 3 files changed, 28 insertions(+), 19 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 56328489a5b..cfc463e031c 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -12,6 +12,7 @@ import openerpweb.ast import openerpweb.nonliterals import cherrypy +import xmlrpclib # Should move to openerpweb.Xml2Json class Xml2Json: @@ -126,12 +127,7 @@ class Session(openerpweb.Controller): if flag == 'drop': db = kw.get('db') password = kw.get('password') - try: - res = req.session.proxy("db").drop(password, db) - if res: - return res - except TypeError: - return {'error': e} + return req.session.proxy("db").drop(password, db) @openerpweb.jsonrequest def modules(self, req): diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 7e19d138ff0..62d9b9c92c1 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -880,8 +880,8 @@ openerp.base.CrashManager = openerp.base.Dialog.extend({ this.dialog_title = "OpenERP Error"; this.template = 'DialogTraceback'; this.open({ - width: '80%', - height: '80%' + width: 'auto', + height: 'auto' }); } } @@ -946,8 +946,10 @@ openerp.base.Database = openerp.base.Controller.extend({ if (confirm("Do you really want to delete the database: " + db + " ?")) { self.rpc("/base/session/db_operation", {'flag': 'drop', 'db': db, 'password': password}, function(result) { - self.$option_id.find("select[name=drop_db] :selected").remove(); - self.notification.notify("Dropping database", "The database '" + db + "' has been dropped"); + if (!result.error) { + self.$option_id.find("select[name=drop_db] :selected").remove(); + self.notification.notify("Dropping database", "The database '" + db + "' has been dropped"); + } }); } }); diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py index 33c5c14edb3..8a759bd9b82 100644 --- a/openerpweb/openerpweb.py +++ b/openerpweb/openerpweb.py @@ -317,16 +317,27 @@ class JsonRequest(object): } } except xmlrpclib.Fault, e: - error = { - 'code': 200, - 'message': "OpenERP Server Error", - 'data': { - 'type': 'server_exception', - 'fault_code': e.faultCode, - 'debug': "Client %s\nServer %s" % ( - "".join(traceback.format_exception("", None, sys.exc_traceback)), e.faultString) + if e.faultCode and e.faultCode.split(':')[0] == 'AccessDenied': + message, string = e.faultCode.split(':') + error = { + 'code': 200, + 'message': message, + 'data': { + 'type': 'server_exception', + 'debug': string + } + } + else: + error = { + 'code': 200, + 'message': "OpenERP Server Error", + 'data': { + 'type': 'server_exception', + 'fault_code': e.faultCode, + 'debug': "Client %s\nServer %s" % ( + "".join(traceback.format_exception("", None, sys.exc_traceback)), e.faultString) + } } - } except Exception: cherrypy.log("An error occured while handling a json request", severity=logging.ERROR, traceback=True) From 6c971a0fda8e8e51c148aae574dc685898ee373b Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Mon, 4 Jul 2011 19:18:23 +0530 Subject: [PATCH 037/230] [IMP] Improved methods for backup, restore, change password. bzr revid: noz@tinyerp.com-20110704134823-bhn2qg4nwgx819ii --- addons/base/controllers/main.py | 24 +++++++++++++++ addons/base/static/src/js/chrome.js | 46 +++++++++++++++++++++++++++-- addons/base/static/src/xml/base.xml | 28 +++++++++--------- 3 files changed, 82 insertions(+), 16 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index cfc463e031c..ca4b044e74e 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -127,7 +127,31 @@ class Session(openerpweb.Controller): if flag == 'drop': db = kw.get('db') password = kw.get('password') + return req.session.proxy("db").drop(password, db) + + elif flag == 'backup': + db = kw.get('db') + password = kw.get('password') + # todo: content type + res = rpc.session.proxy("db").dump(password, db) + if res: + return base64.decodestring(res) + + elif flag == 'restore': + filename = kw.get('filename') + db = kw.get('db') + password = kw.get('password') + + data = base64.encodestring(filename.file.read()) + return rpc.session.proxy("db").restore(password, db, data) + + elif flag == 'change_password': + old_password = kw.get('old_password') + new_password = kw.get('new_password') + confirm_password = kw.get('confirm_password') + + return rpc.session.proxy("db").change_admin_password(old_password, new_password) @openerpweb.jsonrequest def modules(self, req): diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 62d9b9c92c1..72bbac257f8 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -935,13 +935,14 @@ openerp.base.Database = openerp.base.Controller.extend({ self.db_string = "CREATE DATABASE"; self.$option_id.html(QWeb.render("CreateDB", self)); }); + self.$element.find('#db-drop').click(function() { self.db_string = "DROP DATABASE"; self.$option_id.html(QWeb.render("DropDB", self)); self.$option_id.find('#drop_db_btn').click(function() { var db = self.$option_id.find("select[name=drop_db]").val(); - var password = self.$option_id.find("input[name=drop_password]").val(); + var password = self.$option_id.find("input[name=drop_pwd]").val(); if (confirm("Do you really want to delete the database: " + db + " ?")) { self.rpc("/base/session/db_operation", {'flag': 'drop', 'db': db, 'password': password}, @@ -953,20 +954,61 @@ openerp.base.Database = openerp.base.Controller.extend({ }); } }); - }); + self.$element.find('#db-backup').click(function() { self.db_string = "BACKUP DATABASE"; self.$option_id.html(QWeb.render("BackupDB", self)); + + self.$option_id.find('#backup_db_btn').click(function() { + var db = self.$option_id.find("select[name=backup_db]").val(); + var password = self.$option_id.find("input[name=backup_pwd]").val(); + + self.rpc("/base/session/db_operation", {'flag': 'backup', 'db': db, 'password': password}, + function(result) { + if (!result.error) { + self.notification.notify("Backup has been created for the database: '" + db + "'"); + } + }); + }); }); + self.$element.find('#db-restore').click(function() { self.db_string = "RESTORE DATABASE"; self.$option_id.html(QWeb.render("RestoreDB", self)); + + self.$option_id.find('#restore_db_btn').click(function() { + var db = self.$option_id.find("input[name=restore_db]").val(); + var password = self.$option_id.find("input[name=restore_pwd]").val(); + var new_db = self.$option_id.find("input[name=new_db]").val(); + + self.rpc("/base/session/db_operation", {'flag': 'restore', 'db': db, 'password': password, 'new_db': new_db}, + function(result) { + if (!result.error) { + self.notification.notify("You restored your database as: '" + new_db + "'"); + } + }); + }); }); + self.$element.find('#db-change-password').click(function() { self.db_string = "CHANGE DATABASE PASSWORD"; self.$option_id.html(QWeb.render("Change_DB_Pwd", self)); + + self.$option_id.find('#change_pwd_btn').click(function() { + var old_pwd = self.$option_id.find("input[name=old_db]").val(); + var new_pwd = self.$option_id.find("input[name=new_pwd]").val(); + var confirm_pwd = self.$option_id.find("input[name=confirm_pwd]").val(); + + self.rpc("/base/session/db_operation", {'flag': 'change_password', 'old_password': old_pwd, 'new_password': new_pwd, 'confirm_password': confirm_pwd}, + function(result) { + if (!result.error) { + self.notification.notify("Password has been changed successfully"); + } + }); + }); }); + self.$element.find('#back-to-login').click(function() { self.header = new openerp.base.Header(self.session, "oe_header"); self.header.on_logout(); diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 8bb13f10963..4edfd27068f 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -113,7 +113,7 @@ - + @@ -137,8 +137,8 @@ - - + + @@ -155,10 +155,10 @@ - + - - + + - +
    - @@ -167,11 +167,11 @@
    @@ -185,19 +185,19 @@ - - + + - - + + - +
    @@ -223,7 +223,7 @@ - + From 213b47685c0aec579492d81bd0dfc6a703883364 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 4 Jul 2011 16:18:07 +0200 Subject: [PATCH 038/230] [ADD] home action loading and execution bzr revid: xmo@openerp.com-20110704141807-147dsoqrx6v53jl4 --- addons/base/controllers/main.py | 5 ++++ addons/base/static/src/js/chrome.js | 42 +++++++++++++++++++++++++---- openerpweb/openerpweb.py | 11 +++++--- 3 files changed, 50 insertions(+), 8 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 850069bb141..30794733f44 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -231,6 +231,11 @@ class Session(openerpweb.Controller): if not saved_actions: return None return saved_actions["actions"].get(key) + + @openerpweb.jsonrequest + def check(self, req): + req.session.assert_valid() + return None def eval_context_and_domain(session, context, domain=None): e_context = session.eval_context(context) diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 1faf0eb2878..b96783d4247 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -337,7 +337,12 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b this.context = {}; }, start: function() { - this.session_restore(); + var self = this; + return this.session_restore().then(function () { + self.on_session_valid(); + }, function () { + self.on_session_invalid(); + }); }, /** * Executes an RPC call, registering the provided callbacks. @@ -472,7 +477,7 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b this.session_id = this.get_cookie('session_id'); // we should do an rpc to confirm that this session_id is valid and if it is retrieve the information about db and login // then call on_session_valid - this.on_session_valid(); + return this.rpc('/base/session/check', {}, function () {}, function () {}); }, /** * Saves the session id and uid locally @@ -531,7 +536,6 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b var modules = self.module_list.join(','); self.rpc('/base/session/csslist', {mods: modules}, self.do_load_css); self.rpc('/base/session/jslist', {"mods": modules}, self.debug ? self.do_load_modules_debug : self.do_load_modules_prod); - openerp._modules_loaded = true; }); }, do_load_css: function (result) { @@ -566,6 +570,7 @@ openerp.base.Session = openerp.base.BasicController.extend( /** @lends openerp.b this.module_loaded[mod] = true; } } + openerp._modules_loaded = true; } }); @@ -1100,8 +1105,8 @@ openerp.base.ImportExport = openerp.base.Controller.extend({ openerp.base.WebClient = openerp.base.Controller.extend({ init: function(element_id) { - var self = this; this._super(null, element_id); + this.view_manager = {}; QWeb.add_template("xml/base.xml"); var params = {}; @@ -1143,14 +1148,41 @@ openerp.base.WebClient = openerp.base.Controller.extend({ // if using saved actions, load the action and give it to action manager var parameters = jQuery.deparam(jQuery.param.querystring()); - if(parameters["s_action"] != undefined) { + if (parameters["s_action"] != undefined) { var key = parseInt(parameters["s_action"]); var self = this; this.rpc("/base/session/get_session_action", {key:key}, function(action) { self.action_manager.do_action(action); }); + } else if (openerp._modules_loaded) { // TODO: find better option than this + this.load_url_state() + } else { + this.session.on_modules_loaded.add({ + callback: $.proxy(this, 'load_url_state'), + unique: true, + position: 'last' + }) } }, + /** + * Loads state from URL if any, or checks if there is a home action and + * loads that, assuming we're at the index + */ + load_url_state: function () { + var self = this; + // TODO: add actual loading if there is url state to unpack, test on window.location.hash + var ds = new openerp.base.DataSetSearch(this.session, 'res.users'); + ds.read_ids([parseInt(this.session.uid, 10)], ['action_id'], function (actions) { + var home_action = actions[0].action_id; + if (!home_action) { return; } + // oh dear + openerp.base.View.prototype.execute_action.call( + self, { + 'name': home_action[0], + 'type': 'action' + }, ds, self.action_manager); + }) + }, on_menu_action: function(action) { this.action_manager.do_action(action); }, diff --git a/openerpweb/openerpweb.py b/openerpweb/openerpweb.py index 33c5c14edb3..f1dc97038f4 100644 --- a/openerpweb/openerpweb.py +++ b/openerpweb/openerpweb.py @@ -108,15 +108,20 @@ class OpenERPSession(object): if uid: self.get_context() return uid - def execute(self, model, func, *l, **d): + def assert_valid(self): + """ + Ensures this session is valid (logged into the openerp server) + """ if not (self._db and self._uid and self._password): raise OpenERPUnboundException() + + def execute(self, model, func, *l, **d): + self.assert_valid() r = self.proxy('object').execute(self._db, self._uid, self._password, model, func, *l, **d) return r def exec_workflow(self, model, id, signal): - if not (self._db and self._uid and self._password): - raise OpenERPUnboundException() + self.assert_valid() r = self.proxy('object').exec_workflow(self._db, self._uid, self._password, model, signal, id) return r From f36d077063a6593d9ffa9b915b49a1f70e89368e Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Mon, 4 Jul 2011 16:34:02 +0200 Subject: [PATCH 039/230] [FIX] always provide a radix to parseint bzr revid: xmo@openerp.com-20110704143402-e47xmd53obcou6b8 --- addons/base/static/src/js/chrome.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index b96783d4247..12ea496a3e6 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -1149,7 +1149,7 @@ openerp.base.WebClient = openerp.base.Controller.extend({ // if using saved actions, load the action and give it to action manager var parameters = jQuery.deparam(jQuery.param.querystring()); if (parameters["s_action"] != undefined) { - var key = parseInt(parameters["s_action"]); + var key = parseInt(parameters["s_action"], 10); var self = this; this.rpc("/base/session/get_session_action", {key:key}, function(action) { self.action_manager.do_action(action); From f94300bdf49e5ee5675828fd116cbb8b1ec4cd50 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 5 Jul 2011 12:43:54 +0200 Subject: [PATCH 040/230] [ADD] non-breaking space to dashboard action titles, just in case there is no specified title or the actual action was not found bzr revid: xmo@openerp.com-20110705104354-1nu5crjd3r4mfi3s --- addons/base_dashboard/static/src/xml/base_dashboard.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base_dashboard/static/src/xml/base_dashboard.xml b/addons/base_dashboard/static/src/xml/base_dashboard.xml index 0149dfa8d01..43572a5bda4 100644 --- a/addons/base_dashboard/static/src/xml/base_dashboard.xml +++ b/addons/base_dashboard/static/src/xml/base_dashboard.xml @@ -32,7 +32,7 @@
    - +   From 433f2fb5fce473550d35871f12b0e60460d6486c Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 5 Jul 2011 13:42:58 +0200 Subject: [PATCH 041/230] [ADD] homescreen application tiles bzr revid: xmo@openerp.com-20110705114258-upkmqyzzqhebs34l --- .../static/src/css/dashboard.css | 45 +++++++++++++++++++ .../base_dashboard/static/src/js/dashboard.js | 31 +++++++++++++ .../static/src/xml/base_dashboard.xml | 18 ++++++++ 3 files changed, 94 insertions(+) diff --git a/addons/base_dashboard/static/src/css/dashboard.css b/addons/base_dashboard/static/src/css/dashboard.css index 2c9cc513ef0..f513995b549 100644 --- a/addons/base_dashboard/static/src/css/dashboard.css +++ b/addons/base_dashboard/static/src/css/dashboard.css @@ -148,3 +148,48 @@ display: inline-block; vertical-align: bottom; } + +.openerp .oe-dashboard-home-tile { + text-align: center; + margin: 10px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + -webkit-box-shadow: 3px 3px 5px 3px #DADDDD; + -moz-box-shadow: 3px 3px 5px 3px #DADDDD; + box-shadow: 3px 3px 5px 3px #DADDDD; +} +.openerp .oe-dashboard-home-tile span { + display: block; + padding: 0 0 15px; + font-weight: bold; + text-transform: uppercase; + color: #555; + white-space: nowrap; +} +.openerp .oe-dashboard-home-tile-icon { + height: 100px; +} +.openerp .oe-dashboard-home-tile-icon img { + display: block; + margin: 0 auto; +} +.openerp .oe-dashboard-home-tile-icon img.hover { + display: none; +} +.openerp .oe-dashboard-home-tile:hover { + background-color: #fafafa; + -webkit-box-shadow: 3px 3px 5px 3px #979797; + -moz-box-shadow: 3px 3px 5px 3px #979797; + box-shadow: 3px 3px 5px 3px #979797; +} +.openerp .oe-dashboard-home-tile:hover img { + display: none; +} +.openerp .oe-dashboard-home-tile:hover img.hover { + display: block; +} +.openerp .oe-dashboard-home-tile:hover span { + color: black; +} + diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index df2ae08e5de..b1e925c7b0a 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -324,5 +324,36 @@ openerp.base_dashboard.ConfigOverview = openerp.base.View.extend({ }); }); } +}); + +openerp.base.client_actions.add( + 'board.home.applications', 'openerp.base_dashboard.ApplicationTiles'); +openerp.base_dashboard.ApplicationTiles = openerp.base.View.extend({ + init: function (parent_or_session, element_id) { + this._super(parent_or_session, element_id); + this.dataset = new openerp.base.DataSetSearch( + this.session, 'ir.ui.menu', null, [['parent_id', '=', false]]); + }, + start: function () { + var self = this; + this.dataset.read_slice( + ['name', 'web_icon_data', 'web_icon_hover_data'], + null, null, function (applications) { + // Create a matrix of 3*x applications + var rows = []; + while (applications.length) { + rows.push(applications.splice(0, 3)); + } + self.$element + .append(QWeb.render( + 'ApplicationTiles', {rows: rows})) + .find('.oe-dashboard-home-tile') + .click(function () { + var $this = $(this); + $this.closest('.openerp') + .find('.menu a[data-menu=' + $this.data('menuid') + ']') + .click();}); + }); + } }) }; diff --git a/addons/base_dashboard/static/src/xml/base_dashboard.xml b/addons/base_dashboard/static/src/xml/base_dashboard.xml index 43572a5bda4..91fa13d763a 100644 --- a/addons/base_dashboard/static/src/xml/base_dashboard.xml +++ b/addons/base_dashboard/static/src/xml/base_dashboard.xml @@ -80,4 +80,22 @@
+
+ + + + +
+
+
+ +
+ +
+
+
From 15ef484d7d1423b91865461496d9a9189372653f Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Tue, 5 Jul 2011 18:40:53 +0530 Subject: [PATCH 042/230] [IMP] Implemented validation for Change password. bzr revid: noz@tinyerp.com-20110705131053-ccjarqd328y5hsk8 --- addons/base/controllers/main.py | 7 +- .../lib/jquery.validate/jquery.validate.js | 1166 +++++++++++++++++ addons/base/static/src/base.html | 1 + addons/base/static/src/css/base.css | 8 + addons/base/static/src/js/chrome.js | 40 +- addons/base/static/src/xml/base.xml | 52 +- 6 files changed, 1241 insertions(+), 33 deletions(-) create mode 100644 addons/base/static/lib/jquery.validate/jquery.validate.js diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index ca4b044e74e..b085b5baab8 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -134,7 +134,7 @@ class Session(openerpweb.Controller): db = kw.get('db') password = kw.get('password') # todo: content type - res = rpc.session.proxy("db").dump(password, db) + res = req.session.proxy("db").dump(password, db) if res: return base64.decodestring(res) @@ -144,14 +144,15 @@ class Session(openerpweb.Controller): password = kw.get('password') data = base64.encodestring(filename.file.read()) - return rpc.session.proxy("db").restore(password, db, data) + return req.session.proxy("db").restore(password, db, data) elif flag == 'change_password': old_password = kw.get('old_password') new_password = kw.get('new_password') confirm_password = kw.get('confirm_password') - return rpc.session.proxy("db").change_admin_password(old_password, new_password) + if old_password and new_password and confirm_password: + return req.session.proxy("db").change_admin_password(old_password, new_password) @openerpweb.jsonrequest def modules(self, req): diff --git a/addons/base/static/lib/jquery.validate/jquery.validate.js b/addons/base/static/lib/jquery.validate/jquery.validate.js new file mode 100644 index 00000000000..72296a61f20 --- /dev/null +++ b/addons/base/static/lib/jquery.validate/jquery.validate.js @@ -0,0 +1,1166 @@ +/** + * jQuery Validation Plugin 1.8.1 + * + * http://bassistance.de/jquery-plugins/jquery-plugin-validation/ + * http://docs.jquery.com/Plugins/Validation + * + * Copyright (c) 2006 - 2011 Jörn Zaefferer + * + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ + +(function($) { + +$.extend($.fn, { + // http://docs.jquery.com/Plugins/Validation/validate + validate: function( options ) { + + // if nothing is selected, return nothing; can't chain anyway + if (!this.length) { + options && options.debug && window.console && console.warn( "nothing selected, can't validate, returning nothing" ); + return; + } + + // check if a validator for this form was already created + var validator = $.data(this[0], 'validator'); + if ( validator ) { + return validator; + } + + validator = new $.validator( options, this[0] ); + $.data(this[0], 'validator', validator); + + if ( validator.settings.onsubmit ) { + + // allow suppresing validation by adding a cancel class to the submit button + this.find("input, button").filter(".cancel").click(function() { + validator.cancelSubmit = true; + }); + + // when a submitHandler is used, capture the submitting button + if (validator.settings.submitHandler) { + this.find("input, button").filter(":submit").click(function() { + validator.submitButton = this; + }); + } + + // validate the form on submit + this.submit( function( event ) { + if ( validator.settings.debug ) + // prevent form submit to be able to see console output + event.preventDefault(); + + function handle() { + if ( validator.settings.submitHandler ) { + if (validator.submitButton) { + // insert a hidden input as a replacement for the missing submit button + var hidden = $("").attr("name", validator.submitButton.name).val(validator.submitButton.value).appendTo(validator.currentForm); + } + validator.settings.submitHandler.call( validator, validator.currentForm ); + if (validator.submitButton) { + // and clean up afterwards; thanks to no-block-scope, hidden can be referenced + hidden.remove(); + } + return false; + } + return true; + } + + // prevent submit for invalid forms or custom submit handlers + if ( validator.cancelSubmit ) { + validator.cancelSubmit = false; + return handle(); + } + if ( validator.form() ) { + if ( validator.pendingRequest ) { + validator.formSubmitted = true; + return false; + } + return handle(); + } else { + validator.focusInvalid(); + return false; + } + }); + } + + return validator; + }, + // http://docs.jquery.com/Plugins/Validation/valid + valid: function() { + if ( $(this[0]).is('form')) { + return this.validate().form(); + } else { + var valid = true; + var validator = $(this[0].form).validate(); + this.each(function() { + valid &= validator.element(this); + }); + return valid; + } + }, + // attributes: space seperated list of attributes to retrieve and remove + removeAttrs: function(attributes) { + var result = {}, + $element = this; + $.each(attributes.split(/\s/), function(index, value) { + result[value] = $element.attr(value); + $element.removeAttr(value); + }); + return result; + }, + // http://docs.jquery.com/Plugins/Validation/rules + rules: function(command, argument) { + var element = this[0]; + + if (command) { + var settings = $.data(element.form, 'validator').settings; + var staticRules = settings.rules; + var existingRules = $.validator.staticRules(element); + switch(command) { + case "add": + $.extend(existingRules, $.validator.normalizeRule(argument)); + staticRules[element.name] = existingRules; + if (argument.messages) + settings.messages[element.name] = $.extend( settings.messages[element.name], argument.messages ); + break; + case "remove": + if (!argument) { + delete staticRules[element.name]; + return existingRules; + } + var filtered = {}; + $.each(argument.split(/\s/), function(index, method) { + filtered[method] = existingRules[method]; + delete existingRules[method]; + }); + return filtered; + } + } + + var data = $.validator.normalizeRules( + $.extend( + {}, + $.validator.metadataRules(element), + $.validator.classRules(element), + $.validator.attributeRules(element), + $.validator.staticRules(element) + ), element); + + // make sure required is at front + if (data.required) { + var param = data.required; + delete data.required; + data = $.extend({required: param}, data); + } + + return data; + } +}); + +// Custom selectors +$.extend($.expr[":"], { + // http://docs.jquery.com/Plugins/Validation/blank + blank: function(a) {return !$.trim("" + a.value);}, + // http://docs.jquery.com/Plugins/Validation/filled + filled: function(a) {return !!$.trim("" + a.value);}, + // http://docs.jquery.com/Plugins/Validation/unchecked + unchecked: function(a) {return !a.checked;} +}); + +// constructor for validator +$.validator = function( options, form ) { + this.settings = $.extend( true, {}, $.validator.defaults, options ); + this.currentForm = form; + this.init(); +}; + +$.validator.format = function(source, params) { + if ( arguments.length == 1 ) + return function() { + var args = $.makeArray(arguments); + args.unshift(source); + return $.validator.format.apply( this, args ); + }; + if ( arguments.length > 2 && params.constructor != Array ) { + params = $.makeArray(arguments).slice(1); + } + if ( params.constructor != Array ) { + params = [ params ]; + } + $.each(params, function(i, n) { + source = source.replace(new RegExp("\\{" + i + "\\}", "g"), n); + }); + return source; +}; + +$.extend($.validator, { + + defaults: { + messages: {}, + groups: {}, + rules: {}, + errorClass: "error", + validClass: "valid", + errorElement: "label", + focusInvalid: true, + errorContainer: $( [] ), + errorLabelContainer: $( [] ), + onsubmit: true, + ignore: [], + ignoreTitle: false, + onfocusin: function(element) { + this.lastActive = element; + + // hide error label and remove error class on focus if enabled + if ( this.settings.focusCleanup && !this.blockFocusCleanup ) { + this.settings.unhighlight && this.settings.unhighlight.call( this, element, this.settings.errorClass, this.settings.validClass ); + this.addWrapper(this.errorsFor(element)).hide(); + } + }, + onfocusout: function(element) { + if ( !this.checkable(element) && (element.name in this.submitted || !this.optional(element)) ) { + this.element(element); + } + }, + onkeyup: function(element) { + if ( element.name in this.submitted || element == this.lastElement ) { + this.element(element); + } + }, + onclick: function(element) { + // click on selects, radiobuttons and checkboxes + if ( element.name in this.submitted ) + this.element(element); + // or option elements, check parent select in that case + else if (element.parentNode.name in this.submitted) + this.element(element.parentNode); + }, + highlight: function(element, errorClass, validClass) { + if (element.type === 'radio') { + this.findByName(element.name).addClass(errorClass).removeClass(validClass); + } else { + $(element).addClass(errorClass).removeClass(validClass); + } + }, + unhighlight: function(element, errorClass, validClass) { + if (element.type === 'radio') { + this.findByName(element.name).removeClass(errorClass).addClass(validClass); + } else { + $(element).removeClass(errorClass).addClass(validClass); + } + } + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/setDefaults + setDefaults: function(settings) { + $.extend( $.validator.defaults, settings ); + }, + + messages: { + required: "This field is required.", + remote: "Please fix this field.", + email: "Please enter a valid email address.", + url: "Please enter a valid URL.", + date: "Please enter a valid date.", + dateISO: "Please enter a valid date (ISO).", + number: "Please enter a valid number.", + digits: "Please enter only digits.", + creditcard: "Please enter a valid credit card number.", + equalTo: "Please enter the same value again.", + accept: "Please enter a value with a valid extension.", + maxlength: $.validator.format("Please enter no more than {0} characters."), + minlength: $.validator.format("Please enter at least {0} characters."), + rangelength: $.validator.format("Please enter a value between {0} and {1} characters long."), + range: $.validator.format("Please enter a value between {0} and {1}."), + max: $.validator.format("Please enter a value less than or equal to {0}."), + min: $.validator.format("Please enter a value greater than or equal to {0}.") + }, + + autoCreateRanges: false, + + prototype: { + + init: function() { + this.labelContainer = $(this.settings.errorLabelContainer); + this.errorContext = this.labelContainer.length && this.labelContainer || $(this.currentForm); + this.containers = $(this.settings.errorContainer).add( this.settings.errorLabelContainer ); + this.submitted = {}; + this.valueCache = {}; + this.pendingRequest = 0; + this.pending = {}; + this.invalid = {}; + this.reset(); + + var groups = (this.groups = {}); + $.each(this.settings.groups, function(key, value) { + $.each(value.split(/\s/), function(index, name) { + groups[name] = key; + }); + }); + var rules = this.settings.rules; + $.each(rules, function(key, value) { + rules[key] = $.validator.normalizeRule(value); + }); + + function delegate(event) { + var validator = $.data(this[0].form, "validator"), + eventType = "on" + event.type.replace(/^validate/, ""); + validator.settings[eventType] && validator.settings[eventType].call(validator, this[0] ); + } + $(this.currentForm) + .validateDelegate(":text, :password, :file, select, textarea", "focusin focusout keyup", delegate) + .validateDelegate(":radio, :checkbox, select, option", "click", delegate); + + if (this.settings.invalidHandler) + $(this.currentForm).bind("invalid-form.validate", this.settings.invalidHandler); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/form + form: function() { + this.checkForm(); + $.extend(this.submitted, this.errorMap); + this.invalid = $.extend({}, this.errorMap); + if (!this.valid()) + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.showErrors(); + return this.valid(); + }, + + checkForm: function() { + this.prepareForm(); + for ( var i = 0, elements = (this.currentElements = this.elements()); elements[i]; i++ ) { + this.check( elements[i] ); + } + return this.valid(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/element + element: function( element ) { + element = this.clean( element ); + this.lastElement = element; + this.prepareElement( element ); + this.currentElements = $(element); + var result = this.check( element ); + if ( result ) { + delete this.invalid[element.name]; + } else { + this.invalid[element.name] = true; + } + if ( !this.numberOfInvalids() ) { + // Hide error containers on last error + this.toHide = this.toHide.add( this.containers ); + } + this.showErrors(); + return result; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/showErrors + showErrors: function(errors) { + if(errors) { + // add items to error list and map + $.extend( this.errorMap, errors ); + this.errorList = []; + for ( var name in errors ) { + this.errorList.push({ + message: errors[name], + element: this.findByName(name)[0] + }); + } + // remove items from success list + this.successList = $.grep( this.successList, function(element) { + return !(element.name in errors); + }); + } + this.settings.showErrors + ? this.settings.showErrors.call( this, this.errorMap, this.errorList ) + : this.defaultShowErrors(); + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/resetForm + resetForm: function() { + if ( $.fn.resetForm ) + $( this.currentForm ).resetForm(); + this.submitted = {}; + this.prepareForm(); + this.hideErrors(); + this.elements().removeClass( this.settings.errorClass ); + }, + + numberOfInvalids: function() { + return this.objectLength(this.invalid); + }, + + objectLength: function( obj ) { + var count = 0; + for ( var i in obj ) + count++; + return count; + }, + + hideErrors: function() { + this.addWrapper( this.toHide ).hide(); + }, + + valid: function() { + return this.size() == 0; + }, + + size: function() { + return this.errorList.length; + }, + + focusInvalid: function() { + if( this.settings.focusInvalid ) { + try { + $(this.findLastActive() || this.errorList.length && this.errorList[0].element || []) + .filter(":visible") + .focus() + // manually trigger focusin event; without it, focusin handler isn't called, findLastActive won't have anything to find + .trigger("focusin"); + } catch(e) { + // ignore IE throwing errors when focusing hidden elements + } + } + }, + + findLastActive: function() { + var lastActive = this.lastActive; + return lastActive && $.grep(this.errorList, function(n) { + return n.element.name == lastActive.name; + }).length == 1 && lastActive; + }, + + elements: function() { + var validator = this, + rulesCache = {}; + + // select all valid inputs inside the form (no submit or reset buttons) + return $(this.currentForm) + .find("input, select, textarea") + .not(":submit, :reset, :image, [disabled]") + .not( this.settings.ignore ) + .filter(function() { + !this.name && validator.settings.debug && window.console && console.error( "%o has no name assigned", this); + + // select only the first element for each name, and only those with rules specified + if ( this.name in rulesCache || !validator.objectLength($(this).rules()) ) + return false; + + rulesCache[this.name] = true; + return true; + }); + }, + + clean: function( selector ) { + return $( selector )[0]; + }, + + errors: function() { + return $( this.settings.errorElement + "." + this.settings.errorClass, this.errorContext ); + }, + + reset: function() { + this.successList = []; + this.errorList = []; + this.errorMap = {}; + this.toShow = $([]); + this.toHide = $([]); + this.currentElements = $([]); + }, + + prepareForm: function() { + this.reset(); + this.toHide = this.errors().add( this.containers ); + }, + + prepareElement: function( element ) { + this.reset(); + this.toHide = this.errorsFor(element); + }, + + check: function( element ) { + element = this.clean( element ); + + // if radio/checkbox, validate first element in group instead + if (this.checkable(element)) { + element = this.findByName( element.name ).not(this.settings.ignore)[0]; + } + + var rules = $(element).rules(); + var dependencyMismatch = false; + for (var method in rules ) { + var rule = { method: method, parameters: rules[method] }; + try { + var result = $.validator.methods[method].call( this, element.value.replace(/\r/g, ""), element, rule.parameters ); + + // if a method indicates that the field is optional and therefore valid, + // don't mark it as valid when there are no other rules + if ( result == "dependency-mismatch" ) { + dependencyMismatch = true; + continue; + } + dependencyMismatch = false; + + if ( result == "pending" ) { + this.toHide = this.toHide.not( this.errorsFor(element) ); + return; + } + + if( !result ) { + this.formatAndAdd( element, rule ); + return false; + } + } catch(e) { + this.settings.debug && window.console && console.log("exception occured when checking element " + element.id + + ", check the '" + rule.method + "' method", e); + throw e; + } + } + if (dependencyMismatch) + return; + if ( this.objectLength(rules) ) + this.successList.push(element); + return true; + }, + + // return the custom message for the given element and validation method + // specified in the element's "messages" metadata + customMetaMessage: function(element, method) { + if (!$.metadata) + return; + + var meta = this.settings.meta + ? $(element).metadata()[this.settings.meta] + : $(element).metadata(); + + return meta && meta.messages && meta.messages[method]; + }, + + // return the custom message for the given element name and validation method + customMessage: function( name, method ) { + var m = this.settings.messages[name]; + return m && (m.constructor == String + ? m + : m[method]); + }, + + // return the first defined argument, allowing empty strings + findDefined: function() { + for(var i = 0; i < arguments.length; i++) { + if (arguments[i] !== undefined) + return arguments[i]; + } + return undefined; + }, + + defaultMessage: function( element, method) { + return this.findDefined( + this.customMessage( element.name, method ), + this.customMetaMessage( element, method ), + // title is never undefined, so handle empty string as undefined + !this.settings.ignoreTitle && element.title || undefined, + $.validator.messages[method], + "Warning: No message defined for " + element.name + "" + ); + }, + + formatAndAdd: function( element, rule ) { + var message = this.defaultMessage( element, rule.method ), + theregex = /\$?\{(\d+)\}/g; + if ( typeof message == "function" ) { + message = message.call(this, rule.parameters, element); + } else if (theregex.test(message)) { + message = jQuery.format(message.replace(theregex, '{$1}'), rule.parameters); + } + this.errorList.push({ + message: message, + element: element + }); + + this.errorMap[element.name] = message; + this.submitted[element.name] = message; + }, + + addWrapper: function(toToggle) { + if ( this.settings.wrapper ) + toToggle = toToggle.add( toToggle.parent( this.settings.wrapper ) ); + return toToggle; + }, + + defaultShowErrors: function() { + for ( var i = 0; this.errorList[i]; i++ ) { + var error = this.errorList[i]; + this.settings.highlight && this.settings.highlight.call( this, error.element, this.settings.errorClass, this.settings.validClass ); + this.showLabel( error.element, error.message ); + } + if( this.errorList.length ) { + this.toShow = this.toShow.add( this.containers ); + } + if (this.settings.success) { + for ( var i = 0; this.successList[i]; i++ ) { + this.showLabel( this.successList[i] ); + } + } + if (this.settings.unhighlight) { + for ( var i = 0, elements = this.validElements(); elements[i]; i++ ) { + this.settings.unhighlight.call( this, elements[i], this.settings.errorClass, this.settings.validClass ); + } + } + this.toHide = this.toHide.not( this.toShow ); + this.hideErrors(); + this.addWrapper( this.toShow ).show(); + }, + + validElements: function() { + return this.currentElements.not(this.invalidElements()); + }, + + invalidElements: function() { + return $(this.errorList).map(function() { + return this.element; + }); + }, + + showLabel: function(element, message) { + var label = this.errorsFor( element ); + if ( label.length ) { + // refresh error/success class + label.removeClass().addClass( this.settings.errorClass ); + + // check if we have a generated label, replace the message then + label.attr("generated") && label.html(message); + } else { + // create label + label = $("<" + this.settings.errorElement + "/>") + .attr({"for": this.idOrName(element), generated: true}) + .addClass(this.settings.errorClass) + .html(message || ""); + if ( this.settings.wrapper ) { + // make sure the element is visible, even in IE + // actually showing the wrapped element is handled elsewhere + label = label.hide().show().wrap("<" + this.settings.wrapper + "/>").parent(); + } + if ( !this.labelContainer.append(label).length ) + this.settings.errorPlacement + ? this.settings.errorPlacement(label, $(element) ) + : label.insertAfter(element); + } + if ( !message && this.settings.success ) { + label.text(""); + typeof this.settings.success == "string" + ? label.addClass( this.settings.success ) + : this.settings.success( label ); + } + this.toShow = this.toShow.add(label); + }, + + errorsFor: function(element) { + var name = this.idOrName(element); + return this.errors().filter(function() { + return $(this).attr('for') == name; + }); + }, + + idOrName: function(element) { + return this.groups[element.name] || (this.checkable(element) ? element.name : element.id || element.name); + }, + + checkable: function( element ) { + return /radio|checkbox/i.test(element.type); + }, + + findByName: function( name ) { + // select by name and filter by form for performance over form.find("[name=...]") + var form = this.currentForm; + return $(document.getElementsByName(name)).map(function(index, element) { + return element.form == form && element.name == name && element || null; + }); + }, + + getLength: function(value, element) { + switch( element.nodeName.toLowerCase() ) { + case 'select': + return $("option:selected", element).length; + case 'input': + if( this.checkable( element) ) + return this.findByName(element.name).filter(':checked').length; + } + return value.length; + }, + + depend: function(param, element) { + return this.dependTypes[typeof param] + ? this.dependTypes[typeof param](param, element) + : true; + }, + + dependTypes: { + "boolean": function(param, element) { + return param; + }, + "string": function(param, element) { + return !!$(param, element.form).length; + }, + "function": function(param, element) { + return param(element); + } + }, + + optional: function(element) { + return !$.validator.methods.required.call(this, $.trim(element.value), element) && "dependency-mismatch"; + }, + + startRequest: function(element) { + if (!this.pending[element.name]) { + this.pendingRequest++; + this.pending[element.name] = true; + } + }, + + stopRequest: function(element, valid) { + this.pendingRequest--; + // sometimes synchronization fails, make sure pendingRequest is never < 0 + if (this.pendingRequest < 0) + this.pendingRequest = 0; + delete this.pending[element.name]; + if ( valid && this.pendingRequest == 0 && this.formSubmitted && this.form() ) { + $(this.currentForm).submit(); + this.formSubmitted = false; + } else if (!valid && this.pendingRequest == 0 && this.formSubmitted) { + $(this.currentForm).triggerHandler("invalid-form", [this]); + this.formSubmitted = false; + } + }, + + previousValue: function(element) { + return $.data(element, "previousValue") || $.data(element, "previousValue", { + old: null, + valid: true, + message: this.defaultMessage( element, "remote" ) + }); + } + + }, + + classRuleSettings: { + required: {required: true}, + email: {email: true}, + url: {url: true}, + date: {date: true}, + dateISO: {dateISO: true}, + dateDE: {dateDE: true}, + number: {number: true}, + numberDE: {numberDE: true}, + digits: {digits: true}, + creditcard: {creditcard: true} + }, + + addClassRules: function(className, rules) { + className.constructor == String ? + this.classRuleSettings[className] = rules : + $.extend(this.classRuleSettings, className); + }, + + classRules: function(element) { + var rules = {}; + var classes = $(element).attr('class'); + classes && $.each(classes.split(' '), function() { + if (this in $.validator.classRuleSettings) { + $.extend(rules, $.validator.classRuleSettings[this]); + } + }); + return rules; + }, + + attributeRules: function(element) { + var rules = {}; + var $element = $(element); + + for (var method in $.validator.methods) { + var value = $element.attr(method); + if (value) { + rules[method] = value; + } + } + + // maxlength may be returned as -1, 2147483647 (IE) and 524288 (safari) for text inputs + if (rules.maxlength && /-1|2147483647|524288/.test(rules.maxlength)) { + delete rules.maxlength; + } + + return rules; + }, + + metadataRules: function(element) { + if (!$.metadata) return {}; + + var meta = $.data(element.form, 'validator').settings.meta; + return meta ? + $(element).metadata()[meta] : + $(element).metadata(); + }, + + staticRules: function(element) { + var rules = {}; + var validator = $.data(element.form, 'validator'); + if (validator.settings.rules) { + rules = $.validator.normalizeRule(validator.settings.rules[element.name]) || {}; + } + return rules; + }, + + normalizeRules: function(rules, element) { + // handle dependency check + $.each(rules, function(prop, val) { + // ignore rule when param is explicitly false, eg. required:false + if (val === false) { + delete rules[prop]; + return; + } + if (val.param || val.depends) { + var keepRule = true; + switch (typeof val.depends) { + case "string": + keepRule = !!$(val.depends, element.form).length; + break; + case "function": + keepRule = val.depends.call(element, element); + break; + } + if (keepRule) { + rules[prop] = val.param !== undefined ? val.param : true; + } else { + delete rules[prop]; + } + } + }); + + // evaluate parameters + $.each(rules, function(rule, parameter) { + rules[rule] = $.isFunction(parameter) ? parameter(element) : parameter; + }); + + // clean number parameters + $.each(['minlength', 'maxlength', 'min', 'max'], function() { + if (rules[this]) { + rules[this] = Number(rules[this]); + } + }); + $.each(['rangelength', 'range'], function() { + if (rules[this]) { + rules[this] = [Number(rules[this][0]), Number(rules[this][1])]; + } + }); + + if ($.validator.autoCreateRanges) { + // auto-create ranges + if (rules.min && rules.max) { + rules.range = [rules.min, rules.max]; + delete rules.min; + delete rules.max; + } + if (rules.minlength && rules.maxlength) { + rules.rangelength = [rules.minlength, rules.maxlength]; + delete rules.minlength; + delete rules.maxlength; + } + } + + // To support custom messages in metadata ignore rule methods titled "messages" + if (rules.messages) { + delete rules.messages; + } + + return rules; + }, + + // Converts a simple string to a {string: true} rule, e.g., "required" to {required:true} + normalizeRule: function(data) { + if( typeof data == "string" ) { + var transformed = {}; + $.each(data.split(/\s/), function() { + transformed[this] = true; + }); + data = transformed; + } + return data; + }, + + // http://docs.jquery.com/Plugins/Validation/Validator/addMethod + addMethod: function(name, method, message) { + $.validator.methods[name] = method; + $.validator.messages[name] = message != undefined ? message : $.validator.messages[name]; + if (method.length < 3) { + $.validator.addClassRules(name, $.validator.normalizeRule(name)); + } + }, + + methods: { + + // http://docs.jquery.com/Plugins/Validation/Methods/required + required: function(value, element, param) { + // check if dependency is met + if ( !this.depend(param, element) ) + return "dependency-mismatch"; + switch( element.nodeName.toLowerCase() ) { + case 'select': + // could be an array for select-multiple or a string, both are fine this way + var val = $(element).val(); + return val && val.length > 0; + case 'input': + if ( this.checkable(element) ) + return this.getLength(value, element) > 0; + default: + return $.trim(value).length > 0; + } + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/remote + remote: function(value, element, param) { + if ( this.optional(element) ) + return "dependency-mismatch"; + + var previous = this.previousValue(element); + if (!this.settings.messages[element.name] ) + this.settings.messages[element.name] = {}; + previous.originalMessage = this.settings.messages[element.name].remote; + this.settings.messages[element.name].remote = previous.message; + + param = typeof param == "string" && {url:param} || param; + + if ( this.pending[element.name] ) { + return "pending"; + } + if ( previous.old === value ) { + return previous.valid; + } + + previous.old = value; + var validator = this; + this.startRequest(element); + var data = {}; + data[element.name] = value; + $.ajax($.extend(true, { + url: param, + mode: "abort", + port: "validate" + element.name, + dataType: "json", + data: data, + success: function(response) { + validator.settings.messages[element.name].remote = previous.originalMessage; + var valid = response === true; + if ( valid ) { + var submitted = validator.formSubmitted; + validator.prepareElement(element); + validator.formSubmitted = submitted; + validator.successList.push(element); + validator.showErrors(); + } else { + var errors = {}; + var message = response || validator.defaultMessage( element, "remote" ); + errors[element.name] = previous.message = $.isFunction(message) ? message(value) : message; + validator.showErrors(errors); + } + previous.valid = valid; + validator.stopRequest(element, valid); + } + }, param)); + return "pending"; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/minlength + minlength: function(value, element, param) { + return this.optional(element) || this.getLength($.trim(value), element) >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/maxlength + maxlength: function(value, element, param) { + return this.optional(element) || this.getLength($.trim(value), element) <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/rangelength + rangelength: function(value, element, param) { + var length = this.getLength($.trim(value), element); + return this.optional(element) || ( length >= param[0] && length <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/min + min: function( value, element, param ) { + return this.optional(element) || value >= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/max + max: function( value, element, param ) { + return this.optional(element) || value <= param; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/range + range: function( value, element, param ) { + return this.optional(element) || ( value >= param[0] && value <= param[1] ); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/email + email: function(value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/email_address_validation/ + return this.optional(element) || /^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/url + url: function(value, element) { + // contributed by Scott Gonzalez: http://projects.scottsplayground.com/iri/ + return this.optional(element) || /^(https?|ftp):\/\/(((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:)*@)?(((\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5])\.(\d|[1-9]\d|1\d\d|2[0-4]\d|25[0-5]))|((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?)(:\d*)?)(\/((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)+(\/(([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)*)*)?)?(\?((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|[\uE000-\uF8FF]|\/|\?)*)?(\#((([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(%[\da-f]{2})|[!\$&'\(\)\*\+,;=]|:|@)|\/|\?)*)?$/i.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/date + date: function(value, element) { + return this.optional(element) || !/Invalid|NaN/.test(new Date(value)); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/dateISO + dateISO: function(value, element) { + return this.optional(element) || /^\d{4}[\/-]\d{1,2}[\/-]\d{1,2}$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/number + number: function(value, element) { + return this.optional(element) || /^-?(?:\d+|\d{1,3}(?:,\d{3})+)(?:\.\d+)?$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/digits + digits: function(value, element) { + return this.optional(element) || /^\d+$/.test(value); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/creditcard + // based on http://en.wikipedia.org/wiki/Luhn + creditcard: function(value, element) { + if ( this.optional(element) ) + return "dependency-mismatch"; + // accept only digits and dashes + if (/[^0-9-]+/.test(value)) + return false; + var nCheck = 0, + nDigit = 0, + bEven = false; + + value = value.replace(/\D/g, ""); + + for (var n = value.length - 1; n >= 0; n--) { + var cDigit = value.charAt(n); + var nDigit = parseInt(cDigit, 10); + if (bEven) { + if ((nDigit *= 2) > 9) + nDigit -= 9; + } + nCheck += nDigit; + bEven = !bEven; + } + + return (nCheck % 10) == 0; + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/accept + accept: function(value, element, param) { + param = typeof param == "string" ? param.replace(/,/g, '|') : "png|jpe?g|gif"; + return this.optional(element) || value.match(new RegExp(".(" + param + ")$", "i")); + }, + + // http://docs.jquery.com/Plugins/Validation/Methods/equalTo + equalTo: function(value, element, param) { + // bind to the blur event of the target in order to revalidate whenever the target field is updated + // TODO find a way to bind the event just once, avoiding the unbind-rebind overhead + var target = $(param).unbind(".validate-equalTo").bind("blur.validate-equalTo", function() { + $(element).valid(); + }); + return value == target.val(); + } + + } + +}); + +// deprecated, use $.validator.format instead +$.format = $.validator.format; + +})(jQuery); + +// ajax mode: abort +// usage: $.ajax({ mode: "abort"[, port: "uniqueport"]}); +// if mode:"abort" is used, the previous request on that port (port can be undefined) is aborted via XMLHttpRequest.abort() +;(function($) { + var pendingRequests = {}; + // Use a prefilter if available (1.5+) + if ( $.ajaxPrefilter ) { + $.ajaxPrefilter(function(settings, _, xhr) { + var port = settings.port; + if (settings.mode == "abort") { + if ( pendingRequests[port] ) { + pendingRequests[port].abort(); + } + pendingRequests[port] = xhr; + } + }); + } else { + // Proxy ajax + var ajax = $.ajax; + $.ajax = function(settings) { + var mode = ( "mode" in settings ? settings : $.ajaxSettings ).mode, + port = ( "port" in settings ? settings : $.ajaxSettings ).port; + if (mode == "abort") { + if ( pendingRequests[port] ) { + pendingRequests[port].abort(); + } + return (pendingRequests[port] = ajax.apply(this, arguments)); + } + return ajax.apply(this, arguments); + }; + } +})(jQuery); + +// provides cross-browser focusin and focusout events +// IE has native support, in other browsers, use event caputuring (neither bubbles) + +// provides delegate(type: String, delegate: Selector, handler: Callback) plugin for easier event delegation +// handler is only called when $(event.target).is(delegate), in the scope of the jquery-object for event.target +;(function($) { + // only implement if not provided by jQuery core (since 1.4) + // TODO verify if jQuery 1.4's implementation is compatible with older jQuery special-event APIs + if (!jQuery.event.special.focusin && !jQuery.event.special.focusout && document.addEventListener) { + $.each({ + focus: 'focusin', + blur: 'focusout' + }, function( original, fix ){ + $.event.special[fix] = { + setup:function() { + this.addEventListener( original, handler, true ); + }, + teardown:function() { + this.removeEventListener( original, handler, true ); + }, + handler: function(e) { + arguments[0] = $.event.fix(e); + arguments[0].type = fix; + return $.event.handle.apply(this, arguments); + } + }; + function handler(e) { + e = $.event.fix(e); + e.type = fix; + return $.event.handle.call(this, e); + } + }); + }; + $.extend($.fn, { + validateDelegate: function(delegate, type, handler) { + return this.bind(type, function(event) { + var target = $(event.target); + if (target.is(delegate)) { + return handler.apply(target, arguments); + } + }); + } + }); +})(jQuery); diff --git a/addons/base/static/src/base.html b/addons/base/static/src/base.html index 2761638c6d0..bc469d8ba90 100644 --- a/addons/base/static/src/base.html +++ b/addons/base/static/src/base.html @@ -13,6 +13,7 @@ --> + diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index 1bdcb295461..bf0d29de965 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -141,6 +141,7 @@ body.openerp { display: none; } +/* Database */ .openerp.database_block .db_options_row { height: 100%; display: table-row; @@ -202,6 +203,13 @@ ul.db_options li { font-size: large; } +label.error { + float: none; + color: red; + padding-left: .5em; + vertical-align: top; +} + /* Main*/ .openerp .main_table { width: 100%; diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 3db3aa4f70a..cd68396ef47 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -994,18 +994,46 @@ openerp.base.Database = openerp.base.Controller.extend({ self.db_string = "CHANGE DATABASE PASSWORD"; self.$option_id.html(QWeb.render("Change_DB_Pwd", self)); - self.$option_id.find('#change_pwd_btn').click(function() { - var old_pwd = self.$option_id.find("input[name=old_db]").val(); + $("form[name=change_db_pwd]").validate(); + + $("input[name=old_pwd]").rules("add", { + required: true, + minlength: 1, + messages: { + required: "Please enter password !" + } + }); + $("input[name=new_pwd]").rules("add", { + required: true, + minlength: 1, + messages: { + required: "Please enter password !" + } + }); + $("input[name=confirm_pwd]").rules("add", { + required: true, + equalTo: 'input[name=new_pwd]', + messages: { + required: "Password did not match !" + } + }); + + $("input[name=old_pwd]").focus(); + + self.$option_id.find('form[name=change_db_pwd]').submit(function(ev) { + ev.preventDefault(); + + var old_pwd = self.$option_id.find("input[name=old_pwd]").val(); var new_pwd = self.$option_id.find("input[name=new_pwd]").val(); var confirm_pwd = self.$option_id.find("input[name=confirm_pwd]").val(); - + self.rpc("/base/session/db_operation", {'flag': 'change_password', 'old_password': old_pwd, 'new_password': new_pwd, 'confirm_password': confirm_pwd}, function(result) { - if (!result.error) { + if (result && !result.error) { self.notification.notify("Password has been changed successfully"); } }); - }); + }); }); self.$element.find('#back-to-login').click(function() { @@ -1051,7 +1079,7 @@ openerp.base.Login = openerp.base.Controller.extend({ self.database.start(); }); - this.$element.find("form").submit(this.on_submit); + this.$element.find("form").submit(this.on_submit); }, on_login_invalid: function() { this.$element.closest(".openerp").addClass("login-mode"); diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 8c6a0b29f83..89074b14ced 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -199,30 +199,34 @@ - - - - -
- -
- - - - - - - - - - - - - - - - -
+
+ + + + +
+ +
+ + + + + + + + + + + + + + + + +
+ +
+
From b8df60828a880a22bf9912e8cd0cd070b03b639f Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Tue, 5 Jul 2011 18:54:23 +0530 Subject: [PATCH 043/230] [FIX] Added validation for rest of the forms (create, drop, backup...) bzr revid: noz@tinyerp.com-20110705132423-ue5agedqk92fbr2h --- addons/base/static/src/js/chrome.js | 12 +- addons/base/static/src/xml/base.xml | 250 ++++++++++++++-------------- 2 files changed, 138 insertions(+), 124 deletions(-) diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index cd68396ef47..4316d6f6fa6 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -933,12 +933,16 @@ openerp.base.Database = openerp.base.Controller.extend({ this.$element.find('#db-create').click(function() { self.db_string = "CREATE DATABASE"; self.$option_id.html(QWeb.render("CreateDB", self)); + + $("form[name=create_db_form]").validate(); }); self.$element.find('#db-drop').click(function() { self.db_string = "DROP DATABASE"; self.$option_id.html(QWeb.render("DropDB", self)); + $("form[name=drop_db_form]").validate(); + self.$option_id.find('#drop_db_btn').click(function() { var db = self.$option_id.find("select[name=drop_db]").val(); var password = self.$option_id.find("input[name=drop_pwd]").val(); @@ -959,6 +963,8 @@ openerp.base.Database = openerp.base.Controller.extend({ self.db_string = "BACKUP DATABASE"; self.$option_id.html(QWeb.render("BackupDB", self)); + $("form[name=backup_db_form]").validate(); + self.$option_id.find('#backup_db_btn').click(function() { var db = self.$option_id.find("select[name=backup_db]").val(); var password = self.$option_id.find("input[name=backup_pwd]").val(); @@ -976,6 +982,8 @@ openerp.base.Database = openerp.base.Controller.extend({ self.db_string = "RESTORE DATABASE"; self.$option_id.html(QWeb.render("RestoreDB", self)); + $("form[name=restore_db_form]").validate(); + self.$option_id.find('#restore_db_btn').click(function() { var db = self.$option_id.find("input[name=restore_db]").val(); var password = self.$option_id.find("input[name=restore_pwd]").val(); @@ -994,7 +1002,7 @@ openerp.base.Database = openerp.base.Controller.extend({ self.db_string = "CHANGE DATABASE PASSWORD"; self.$option_id.html(QWeb.render("Change_DB_Pwd", self)); - $("form[name=change_db_pwd]").validate(); + $("form[name=change_pwd_form]").validate(); $("input[name=old_pwd]").rules("add", { required: true, @@ -1020,7 +1028,7 @@ openerp.base.Database = openerp.base.Controller.extend({ $("input[name=old_pwd]").focus(); - self.$option_id.find('form[name=change_db_pwd]').submit(function(ev) { + self.$option_id.find('form[name=change_pwd_form]').submit(function(ev) { ev.preventDefault(); var old_pwd = self.$option_id.find("input[name=old_pwd]").val(); diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index 89074b14ced..add5f8a14b9 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -69,137 +69,145 @@ - - - - -
- -
- - - - - - - - - - - - - - - - - - - - - - - - - - - - -
- - - -
+ + + + + +
+ +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+ + + +
+
- - - - -
- -
- - - - - - - - - - - - - - -
-
- - - - - -
- -
- - - - + + + + + + + +
+
+ + + + +
+ +
+ + + - - - - - - - - - - -
+
+ +
+ +
+ + + + +
+ +
+ + + + + + + + + + + + +
+ + + +
+
- - - - -
- -
- - - - - - - - - - - - - - - - -
+
+ + + + +
+ +
+ + + + + + + + + + + + + + + + +
+
-
+ - +
@@ -221,9 +229,7 @@
- -
From 5ffdaf4ec14aee10feede010c4eb20ad8fe6e0c3 Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Tue, 5 Jul 2011 19:12:13 +0530 Subject: [PATCH 044/230] [FIX] Fixed methods for submit. bzr revid: noz@tinyerp.com-20110705134213-c83d7bxpxd676uu4 --- addons/base/controllers/main.py | 4 +++- addons/base/static/src/js/chrome.js | 20 +++++++++++++------- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index b085b5baab8..1a15d4ea933 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -133,9 +133,11 @@ class Session(openerpweb.Controller): elif flag == 'backup': db = kw.get('db') password = kw.get('password') - # todo: content type + res = req.session.proxy("db").dump(password, db) if res: + cherrypy.response.headers['Content-Type'] = "application/data" + cherrypy.response.headers['Content-Disposition'] = 'filename="' + db + '.dump"' return base64.decodestring(res) elif flag == 'restore': diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index 4316d6f6fa6..fb7b7ace862 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -943,14 +943,16 @@ openerp.base.Database = openerp.base.Controller.extend({ $("form[name=drop_db_form]").validate(); - self.$option_id.find('#drop_db_btn').click(function() { + self.$option_id.find('form[name=drop_db_form]').submit(function(ev) { + ev.preventDefault(); + var db = self.$option_id.find("select[name=drop_db]").val(); var password = self.$option_id.find("input[name=drop_pwd]").val(); if (confirm("Do you really want to delete the database: " + db + " ?")) { self.rpc("/base/session/db_operation", {'flag': 'drop', 'db': db, 'password': password}, function(result) { - if (!result.error) { + if (result && !result.error) { self.$option_id.find("select[name=drop_db] :selected").remove(); self.notification.notify("Dropping database", "The database '" + db + "' has been dropped"); } @@ -965,13 +967,15 @@ openerp.base.Database = openerp.base.Controller.extend({ $("form[name=backup_db_form]").validate(); - self.$option_id.find('#backup_db_btn').click(function() { + self.$option_id.find('form[name=backup_db_form]').submit(function(ev) { + ev.preventDefault(); + var db = self.$option_id.find("select[name=backup_db]").val(); var password = self.$option_id.find("input[name=backup_pwd]").val(); - + self.rpc("/base/session/db_operation", {'flag': 'backup', 'db': db, 'password': password}, function(result) { - if (!result.error) { + if (result && !result.error) { self.notification.notify("Backup has been created for the database: '" + db + "'"); } }); @@ -984,14 +988,16 @@ openerp.base.Database = openerp.base.Controller.extend({ $("form[name=restore_db_form]").validate(); - self.$option_id.find('#restore_db_btn').click(function() { + self.$option_id.find('form[name=restore_db_form]').submit(function(ev) { + ev.preventDefault(); + var db = self.$option_id.find("input[name=restore_db]").val(); var password = self.$option_id.find("input[name=restore_pwd]").val(); var new_db = self.$option_id.find("input[name=new_db]").val(); self.rpc("/base/session/db_operation", {'flag': 'restore', 'db': db, 'password': password, 'new_db': new_db}, function(result) { - if (!result.error) { + if (result && !result.error) { self.notification.notify("You restored your database as: '" + new_db + "'"); } }); From 0f88193e8f9c2e0ae5e70230066844321c35bd40 Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Wed, 6 Jul 2011 12:45:46 +0530 Subject: [PATCH 045/230] [FIX] Some improvement in exception handling. bzr revid: noz@tinyerp.com-20110706071546-w9fcjdsbxg473a90 --- addons/base/controllers/main.py | 22 ++++++++++++++-------- addons/base/static/src/js/chrome.js | 10 +++++++--- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 1a15d4ea933..f153c3da747 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -133,20 +133,26 @@ class Session(openerpweb.Controller): elif flag == 'backup': db = kw.get('db') password = kw.get('password') - - res = req.session.proxy("db").dump(password, db) - if res: - cherrypy.response.headers['Content-Type'] = "application/data" - cherrypy.response.headers['Content-Disposition'] = 'filename="' + db + '.dump"' - return base64.decodestring(res) + try: + res = req.session.proxy("db").dump(password, db) + if res: + cherrypy.response.headers['Content-Type'] = "application/data" + cherrypy.response.headers['Content-Disposition'] = 'filename="' + db + '.dump"' + return base64.decodestring(res) + except Exception: + return {'error': 'Could not create backup !'} elif flag == 'restore': filename = kw.get('filename') db = kw.get('db') password = kw.get('password') - data = base64.encodestring(filename.file.read()) - return req.session.proxy("db").restore(password, db, data) + try: + if filename: + data = base64.encodestring(filename.file.read()) + return req.session.proxy("db").restore(password, db, data) + except Exception: + return {'error': 'Could not restore database !'} elif flag == 'change_password': old_password = kw.get('old_password') diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index fb7b7ace862..ef86595245d 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -976,7 +976,9 @@ openerp.base.Database = openerp.base.Controller.extend({ self.rpc("/base/session/db_operation", {'flag': 'backup', 'db': db, 'password': password}, function(result) { if (result && !result.error) { - self.notification.notify("Backup has been created for the database: '" + db + "'"); + self.notification.notify("Backup Database", "Backup has been created for the database: '" + db + "'"); + } else if (result.error) { + self.notification.notify("Backup Database", result.error); } }); }); @@ -998,7 +1000,9 @@ openerp.base.Database = openerp.base.Controller.extend({ self.rpc("/base/session/db_operation", {'flag': 'restore', 'db': db, 'password': password, 'new_db': new_db}, function(result) { if (result && !result.error) { - self.notification.notify("You restored your database as: '" + new_db + "'"); + self.notification.notify("Restore Database", "You restored your database as: '" + new_db + "'"); + } else if (result.error) { + self.notification.notify("Restore Database", result.error); } }); }); @@ -1044,7 +1048,7 @@ openerp.base.Database = openerp.base.Controller.extend({ self.rpc("/base/session/db_operation", {'flag': 'change_password', 'old_password': old_pwd, 'new_password': new_pwd, 'confirm_password': confirm_pwd}, function(result) { if (result && !result.error) { - self.notification.notify("Password has been changed successfully"); + self.notification.notify("Changed Password", "Password has been changed successfully"); } }); }); From 0d3aa4cada845fc25f0bd69cb0e3dd5379e7a4e5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 6 Jul 2011 16:26:37 +0200 Subject: [PATCH 046/230] [IMP] switch to jquery 1.6, has more go fast bzr revid: xmo@openerp.com-20110706142637-bdmgmv29sgl15iyb --- .../{jquery-1.5.2.js => jquery-1.6.2.js} | 2685 ++++++++++------- addons/base/static/src/base.html | 2 +- 2 files changed, 1647 insertions(+), 1040 deletions(-) rename addons/base/static/lib/jquery/{jquery-1.5.2.js => jquery-1.6.2.js} (77%) diff --git a/addons/base/static/lib/jquery/jquery-1.5.2.js b/addons/base/static/lib/jquery/jquery-1.6.2.js similarity index 77% rename from addons/base/static/lib/jquery/jquery-1.5.2.js rename to addons/base/static/lib/jquery/jquery-1.6.2.js index ae0234d2bb4..f3201aacb6f 100644 --- a/addons/base/static/lib/jquery/jquery-1.5.2.js +++ b/addons/base/static/lib/jquery/jquery-1.6.2.js @@ -1,5 +1,5 @@ /*! - * jQuery JavaScript Library v1.5.2 + * jQuery JavaScript Library v1.6.2 * http://jquery.com/ * * Copyright 2011, John Resig @@ -11,12 +11,14 @@ * Copyright 2011, The Dojo Foundation * Released under the MIT, BSD, and GPL Licenses. * - * Date: Thu Mar 31 15:28:23 2011 -0400 + * Date: Thu Jun 30 14:16:56 2011 -0400 */ (function( window, undefined ) { // Use the correct document accordingly with window argument (sandbox) -var document = window.document; +var document = window.document, + navigator = window.navigator, + location = window.location; var jQuery = (function() { // Define a local copy of jQuery @@ -36,7 +38,7 @@ var jQuery = function( selector, context ) { // A simple way to check for HTML strings or ID strings // (both of which we optimize for) - quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]+)$)/, + quickExpr = /^(?:[^<]*(<[\w\W]+>)[^>]*$|#([\w\-]*)$)/, // Check if a string has a non-whitespace character in it rnotwhite = /\S/, @@ -63,6 +65,14 @@ var jQuery = function( selector, context ) { rmsie = /(msie) ([\w.]+)/, rmozilla = /(mozilla)(?:.*? rv:([\w.]+))?/, + // Matches dashed string for camelizing + rdashAlpha = /-([a-z])/ig, + + // Used by jQuery.camelCase as callback to replace() + fcamelCase = function( all, letter ) { + return letter.toUpperCase(); + }, + // Keep a UserAgent string for use with jQuery.browser userAgent = navigator.userAgent, @@ -107,7 +117,7 @@ jQuery.fn = jQuery.prototype = { if ( selector === "body" && !context && document.body ) { this.context = document; this[0] = document.body; - this.selector = "body"; + this.selector = selector; this.length = 1; return this; } @@ -115,7 +125,13 @@ jQuery.fn = jQuery.prototype = { // Handle HTML strings if ( typeof selector === "string" ) { // Are we dealing with HTML string or an ID? - match = quickExpr.exec( selector ); + if ( selector.charAt(0) === "<" && selector.charAt( selector.length - 1 ) === ">" && selector.length >= 3 ) { + // Assume that strings that start and end with <> are HTML and skip the regex check + match = [ null, selector, null ]; + + } else { + match = quickExpr.exec( selector ); + } // Verify a match, and that no context was specified for #id if ( match && (match[1] || !context) ) { @@ -196,7 +212,7 @@ jQuery.fn = jQuery.prototype = { selector: "", // The current version of jQuery being used - jquery: "1.5.2", + jquery: "1.6.2", // The default length of a jQuery object is 0 length: 0, @@ -372,9 +388,11 @@ jQuery.extend = jQuery.fn.extend = function() { jQuery.extend({ noConflict: function( deep ) { - window.$ = _$; + if ( window.$ === jQuery ) { + window.$ = _$; + } - if ( deep ) { + if ( deep && window.jQuery === jQuery ) { window.jQuery = _jQuery; } @@ -388,15 +406,19 @@ jQuery.extend({ // the ready event fires. See #6781 readyWait: 1, + // Hold (or release) the ready event + holdReady: function( hold ) { + if ( hold ) { + jQuery.readyWait++; + } else { + jQuery.ready( true ); + } + }, + // Handle when the DOM is ready ready: function( wait ) { - // A third-party is pushing the ready event forwards - if ( wait === true ) { - jQuery.readyWait--; - } - - // Make sure that the DOM is not already loaded - if ( !jQuery.readyWait || (wait !== true && !jQuery.isReady) ) { + // Either a released hold or an DOMready/load event and not yet ready + if ( (wait === true && !--jQuery.readyWait) || (wait !== true && !jQuery.isReady) ) { // Make sure body exists, at least, in case IE gets a little overzealous (ticket #5443). if ( !document.body ) { return setTimeout( jQuery.ready, 1 ); @@ -446,7 +468,7 @@ jQuery.extend({ } else if ( document.attachEvent ) { // ensure firing before onload, // maybe late but safe also for iframes - document.attachEvent("onreadystatechange", DOMContentLoaded); + document.attachEvent( "onreadystatechange", DOMContentLoaded ); // A fallback to window.onload, that will always work window.attachEvent( "onload", jQuery.ready ); @@ -534,20 +556,21 @@ jQuery.extend({ // Make sure leading/trailing whitespace is removed (IE can't handle it) data = jQuery.trim( data ); + // Attempt to parse using the native JSON parser first + if ( window.JSON && window.JSON.parse ) { + return window.JSON.parse( data ); + } + // Make sure the incoming data is actual JSON // Logic borrowed from http://json.org/json2.js - if ( rvalidchars.test(data.replace(rvalidescape, "@") - .replace(rvalidtokens, "]") - .replace(rvalidbraces, "")) ) { + if ( rvalidchars.test( data.replace( rvalidescape, "@" ) + .replace( rvalidtokens, "]" ) + .replace( rvalidbraces, "")) ) { - // Try to use the native JSON parser first - return window.JSON && window.JSON.parse ? - window.JSON.parse( data ) : - (new Function("return " + data))(); + return (new Function( "return " + data ))(); - } else { - jQuery.error( "Invalid JSON: " + data ); } + jQuery.error( "Invalid JSON: " + data ); }, // Cross-browser xml parsing @@ -574,27 +597,26 @@ jQuery.extend({ noop: function() {}, - // Evalulates a script in a global context + // Evaluates a script in a global context + // Workarounds based on findings by Jim Driscoll + // http://weblogs.java.net/blog/driscoll/archive/2009/09/08/eval-javascript-global-context globalEval: function( data ) { - if ( data && rnotwhite.test(data) ) { - // Inspired by code by Andrea Giammarchi - // http://webreflection.blogspot.com/2007/08/global-scope-evaluation-and-dom.html - var head = document.head || document.getElementsByTagName( "head" )[0] || document.documentElement, - script = document.createElement( "script" ); - - if ( jQuery.support.scriptEval() ) { - script.appendChild( document.createTextNode( data ) ); - } else { - script.text = data; - } - - // Use insertBefore instead of appendChild to circumvent an IE6 bug. - // This arises when a base node is used (#2709). - head.insertBefore( script, head.firstChild ); - head.removeChild( script ); + if ( data && rnotwhite.test( data ) ) { + // We use execScript on Internet Explorer + // We use an anonymous function so that context is window + // rather than jQuery in Firefox + ( window.execScript || function( data ) { + window[ "eval" ].call( window, data ); + } )( data ); } }, + // Converts a dashed string to camelCased string; + // Used by both the css and data modules + camelCase: function( string ) { + return string.replace( rdashAlpha, fcamelCase ); + }, + nodeName: function( elem, name ) { return elem.nodeName && elem.nodeName.toUpperCase() === name.toUpperCase(); }, @@ -603,7 +625,7 @@ jQuery.extend({ each: function( object, callback, args ) { var name, i = 0, length = object.length, - isObj = length === undefined || jQuery.isFunction(object); + isObj = length === undefined || jQuery.isFunction( object ); if ( args ) { if ( isObj ) { @@ -629,8 +651,11 @@ jQuery.extend({ } } } else { - for ( var value = object[0]; - i < length && callback.call( value, i, value ) !== false; value = object[++i] ) {} + for ( ; i < length; ) { + if ( callback.call( object[ i ], i, object[ i++ ] ) === false ) { + break; + } + } } } @@ -661,7 +686,7 @@ jQuery.extend({ // The extra typeof function check is to prevent crashes // in Safari 2 (See: #3039) // Tweaked logic slightly to handle Blackberry 4.7 RegExp issues #6930 - var type = jQuery.type(array); + var type = jQuery.type( array ); if ( array.length == null || type === "string" || type === "function" || type === "regexp" || jQuery.isWindow( array ) ) { push.call( ret, array ); @@ -674,8 +699,9 @@ jQuery.extend({ }, inArray: function( elem, array ) { - if ( array.indexOf ) { - return array.indexOf( elem ); + + if ( indexOf ) { + return indexOf.call( array, elem ); } for ( var i = 0, length = array.length; i < length; i++ ) { @@ -725,15 +751,30 @@ jQuery.extend({ // arg is for internal usage only map: function( elems, callback, arg ) { - var ret = [], value; + var value, key, ret = [], + i = 0, + length = elems.length, + // jquery objects are treated as arrays + isArray = elems instanceof jQuery || length !== undefined && typeof length === "number" && ( ( length > 0 && elems[ 0 ] && elems[ length -1 ] ) || length === 0 || jQuery.isArray( elems ) ) ; // Go through the array, translating each of the items to their - // new value (or values). - for ( var i = 0, length = elems.length; i < length; i++ ) { - value = callback( elems[ i ], i, arg ); + if ( isArray ) { + for ( ; i < length; i++ ) { + value = callback( elems[ i ], i, arg ); - if ( value != null ) { - ret[ ret.length ] = value; + if ( value != null ) { + ret[ ret.length ] = value; + } + } + + // Go through every key on the object, + } else { + for ( key in elems ) { + value = callback( elems[ key ], key, arg ); + + if ( value != null ) { + ret[ ret.length ] = value; + } } } @@ -744,36 +785,35 @@ jQuery.extend({ // A global GUID counter for objects guid: 1, - proxy: function( fn, proxy, thisObject ) { - if ( arguments.length === 2 ) { - if ( typeof proxy === "string" ) { - thisObject = fn; - fn = thisObject[ proxy ]; - proxy = undefined; - - } else if ( proxy && !jQuery.isFunction( proxy ) ) { - thisObject = proxy; - proxy = undefined; - } + // Bind a function to a context, optionally partially applying any + // arguments. + proxy: function( fn, context ) { + if ( typeof context === "string" ) { + var tmp = fn[ context ]; + context = fn; + fn = tmp; } - if ( !proxy && fn ) { + // Quick check to determine if target is callable, in the spec + // this throws a TypeError, but we will just return undefined. + if ( !jQuery.isFunction( fn ) ) { + return undefined; + } + + // Simulated bind + var args = slice.call( arguments, 2 ), proxy = function() { - return fn.apply( thisObject || this, arguments ); + return fn.apply( context, args.concat( slice.call( arguments ) ) ); }; - } // Set the guid of unique handler to the same of original handler, so it can be removed - if ( fn ) { - proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - } + proxy.guid = fn.guid = fn.guid || proxy.guid || jQuery.guid++; - // So proxy can be declared as an argument return proxy; }, // Mutifunctional method to get and set values to a collection - // The value/s can be optionally by executed if its a function + // The value/s can optionally be executed if it's a function access: function( elems, key, value, exec, fn, pass ) { var length = elems.length; @@ -820,24 +860,24 @@ jQuery.extend({ }, sub: function() { - function jQuerySubclass( selector, context ) { - return new jQuerySubclass.fn.init( selector, context ); + function jQuerySub( selector, context ) { + return new jQuerySub.fn.init( selector, context ); } - jQuery.extend( true, jQuerySubclass, this ); - jQuerySubclass.superclass = this; - jQuerySubclass.fn = jQuerySubclass.prototype = this(); - jQuerySubclass.fn.constructor = jQuerySubclass; - jQuerySubclass.subclass = this.subclass; - jQuerySubclass.fn.init = function init( selector, context ) { - if ( context && context instanceof jQuery && !(context instanceof jQuerySubclass) ) { - context = jQuerySubclass(context); + jQuery.extend( true, jQuerySub, this ); + jQuerySub.superclass = this; + jQuerySub.fn = jQuerySub.prototype = this(); + jQuerySub.fn.constructor = jQuerySub; + jQuerySub.sub = this.sub; + jQuerySub.fn.init = function init( selector, context ) { + if ( context && context instanceof jQuery && !(context instanceof jQuerySub) ) { + context = jQuerySub( context ); } - return jQuery.fn.init.call( this, selector, context, rootjQuerySubclass ); + return jQuery.fn.init.call( this, selector, context, rootjQuerySub ); }; - jQuerySubclass.fn.init.prototype = jQuerySubclass.fn; - var rootjQuerySubclass = jQuerySubclass(document); - return jQuerySubclass; + jQuerySub.fn.init.prototype = jQuerySub.fn; + var rootjQuerySub = jQuerySub(document); + return jQuerySub; }, browser: {} @@ -859,12 +899,6 @@ if ( jQuery.browser.webkit ) { jQuery.browser.safari = true; } -if ( indexOf ) { - jQuery.inArray = function( elem, array ) { - return indexOf.call( array, elem ); - }; -} - // IE doesn't match non-breaking spaces with \s if ( rnotwhite.test( "\xA0" ) ) { trimLeft = /^[\s\xA0]+/; @@ -910,14 +944,13 @@ function doScrollCheck() { jQuery.ready(); } -// Expose jQuery to the global object return jQuery; })(); var // Promise methods - promiseMethods = "then done fail isResolved isRejected promise".split( " " ), + promiseMethods = "done fail isResolved isRejected promise then always pipe".split( " " ), // Static reference to slice sliceDeferred = [].slice; @@ -1016,10 +1049,37 @@ jQuery.extend({ deferred.done( doneCallbacks ).fail( failCallbacks ); return this; }, + always: function() { + return deferred.done.apply( deferred, arguments ).fail.apply( this, arguments ); + }, fail: failDeferred.done, rejectWith: failDeferred.resolveWith, reject: failDeferred.resolve, isRejected: failDeferred.isResolved, + pipe: function( fnDone, fnFail ) { + return jQuery.Deferred(function( newDefer ) { + jQuery.each( { + done: [ fnDone, "resolve" ], + fail: [ fnFail, "reject" ] + }, function( handler, data ) { + var fn = data[ 0 ], + action = data[ 1 ], + returned; + if ( jQuery.isFunction( fn ) ) { + deferred[ handler ](function() { + returned = fn.apply( this, arguments ); + if ( returned && jQuery.isFunction( returned.promise ) ) { + returned.promise().then( newDefer.resolve, newDefer.reject ); + } else { + newDefer[ action ]( returned ); + } + }); + } else { + deferred[ handler ]( newDefer[ action ] ); + } + }); + }).promise(); + }, // Get a promise for this deferred // If obj is provided, the promise aspect is added to the object promise: function( obj ) { @@ -1035,7 +1095,7 @@ jQuery.extend({ } return obj; } - } ); + }); // Make sure only one callback list will be used deferred.done( failDeferred.cancel ).fail( deferred.cancel ); // Unexpose cancel @@ -1087,46 +1147,64 @@ jQuery.extend({ +jQuery.support = (function() { -(function() { + var div = document.createElement( "div" ), + documentElement = document.documentElement, + all, + a, + select, + opt, + input, + marginDiv, + support, + fragment, + body, + testElementParent, + testElement, + testElementStyle, + tds, + events, + eventName, + i, + isSupported; - jQuery.support = {}; + // Preliminary tests + div.setAttribute("className", "t"); + div.innerHTML = "
a"; - var div = document.createElement("div"); - - div.style.display = "none"; - div.innerHTML = "
a"; - - var all = div.getElementsByTagName("*"), - a = div.getElementsByTagName("a")[0], - select = document.createElement("select"), - opt = select.appendChild( document.createElement("option") ), - input = div.getElementsByTagName("input")[0]; + all = div.getElementsByTagName( "*" ); + a = div.getElementsByTagName( "a" )[ 0 ]; // Can't get basic test support if ( !all || !all.length || !a ) { - return; + return {}; } - jQuery.support = { + // First batch of supports tests + select = document.createElement( "select" ); + opt = select.appendChild( document.createElement("option") ); + input = div.getElementsByTagName( "input" )[ 0 ]; + + support = { // IE strips leading whitespace when .innerHTML is used - leadingWhitespace: div.firstChild.nodeType === 3, + leadingWhitespace: ( div.firstChild.nodeType === 3 ), // Make sure that tbody elements aren't automatically inserted // IE will insert them into empty tables - tbody: !div.getElementsByTagName("tbody").length, + tbody: !div.getElementsByTagName( "tbody" ).length, // Make sure that link elements get serialized correctly by innerHTML // This requires a wrapper element in IE - htmlSerialize: !!div.getElementsByTagName("link").length, + htmlSerialize: !!div.getElementsByTagName( "link" ).length, // Get the style information from getAttribute - // (IE uses .cssText insted) - style: /red/.test( a.getAttribute("style") ), + // (IE uses .cssText instead) + style: /top/.test( a.getAttribute("style") ), // Make sure that URLs aren't manipulated // (IE normalizes it by default) - hrefNormalized: a.getAttribute("href") === "/a", + hrefNormalized: ( a.getAttribute( "href" ) === "/a" ), // Make sure that element opacity exists // (IE uses filter instead) @@ -1140,188 +1218,193 @@ jQuery.extend({ // Make sure that if no value is specified for a checkbox // that it defaults to "on". // (WebKit defaults to "" instead) - checkOn: input.value === "on", + checkOn: ( input.value === "on" ), // Make sure that a selected-by-default option has a working selected property. // (WebKit defaults to false instead of true, IE too, if it's in an optgroup) optSelected: opt.selected, + // Test setAttribute on camelCase class. If it works, we need attrFixes when doing get/setAttribute (ie6/7) + getSetAttribute: div.className !== "t", + // Will be defined later + submitBubbles: true, + changeBubbles: true, + focusinBubbles: false, deleteExpando: true, - optDisabled: false, - checkClone: false, noCloneEvent: true, - noCloneChecked: true, - boxModel: null, inlineBlockNeedsLayout: false, shrinkWrapBlocks: false, - reliableHiddenOffsets: true, reliableMarginRight: true }; + // Make sure checked status is properly cloned input.checked = true; - jQuery.support.noCloneChecked = input.cloneNode( true ).checked; + support.noCloneChecked = input.cloneNode( true ).checked; // Make sure that the options inside disabled selects aren't marked as disabled - // (WebKit marks them as diabled) + // (WebKit marks them as disabled) select.disabled = true; - jQuery.support.optDisabled = !opt.disabled; - - var _scriptEval = null; - jQuery.support.scriptEval = function() { - if ( _scriptEval === null ) { - var root = document.documentElement, - script = document.createElement("script"), - id = "script" + jQuery.now(); - - // Make sure that the execution of code works by injecting a script - // tag with appendChild/createTextNode - // (IE doesn't support this, fails, and uses .text instead) - try { - script.appendChild( document.createTextNode( "window." + id + "=1;" ) ); - } catch(e) {} - - root.insertBefore( script, root.firstChild ); - - if ( window[ id ] ) { - _scriptEval = true; - delete window[ id ]; - } else { - _scriptEval = false; - } - - root.removeChild( script ); - } - - return _scriptEval; - }; + support.optDisabled = !opt.disabled; // Test to see if it's possible to delete an expando from an element // Fails in Internet Explorer try { delete div.test; - - } catch(e) { - jQuery.support.deleteExpando = false; + } catch( e ) { + support.deleteExpando = false; } if ( !div.addEventListener && div.attachEvent && div.fireEvent ) { - div.attachEvent("onclick", function click() { + div.attachEvent( "onclick", function() { // Cloning a node shouldn't copy over any // bound event handlers (IE does this) - jQuery.support.noCloneEvent = false; - div.detachEvent("onclick", click); + support.noCloneEvent = false; }); - div.cloneNode(true).fireEvent("onclick"); + div.cloneNode( true ).fireEvent( "onclick" ); } - div = document.createElement("div"); - div.innerHTML = ""; + // Check if a radio maintains it's value + // after being appended to the DOM + input = document.createElement("input"); + input.value = "t"; + input.setAttribute("type", "radio"); + support.radioValue = input.value === "t"; - var fragment = document.createDocumentFragment(); + input.setAttribute("checked", "checked"); + div.appendChild( input ); + fragment = document.createDocumentFragment(); fragment.appendChild( div.firstChild ); // WebKit doesn't clone checked state correctly in fragments - jQuery.support.checkClone = fragment.cloneNode(true).cloneNode(true).lastChild.checked; + support.checkClone = fragment.cloneNode( true ).cloneNode( true ).lastChild.checked; + + div.innerHTML = ""; // Figure out if the W3C box model works as expected - // document.body must exist before we can do this - jQuery(function() { - var div = document.createElement("div"), - body = document.getElementsByTagName("body")[0]; + div.style.width = div.style.paddingLeft = "1px"; - // Frameset documents with no body should not run this code - if ( !body ) { - return; - } + body = document.getElementsByTagName( "body" )[ 0 ]; + // We use our own, invisible, body unless the body is already present + // in which case we use a div (#9239) + testElement = document.createElement( body ? "div" : "body" ); + testElementStyle = { + visibility: "hidden", + width: 0, + height: 0, + border: 0, + margin: 0 + }; + if ( body ) { + jQuery.extend( testElementStyle, { + position: "absolute", + left: -1000, + top: -1000 + }); + } + for ( i in testElementStyle ) { + testElement.style[ i ] = testElementStyle[ i ]; + } + testElement.appendChild( div ); + testElementParent = body || documentElement; + testElementParent.insertBefore( testElement, testElementParent.firstChild ); - div.style.width = div.style.paddingLeft = "1px"; - body.appendChild( div ); - jQuery.boxModel = jQuery.support.boxModel = div.offsetWidth === 2; + // Check if a disconnected checkbox will retain its checked + // value of true after appended to the DOM (IE6/7) + support.appendChecked = input.checked; - if ( "zoom" in div.style ) { - // Check if natively block-level elements act like inline-block - // elements when setting their display to 'inline' and giving - // them layout - // (IE < 8 does this) - div.style.display = "inline"; - div.style.zoom = 1; - jQuery.support.inlineBlockNeedsLayout = div.offsetWidth === 2; + support.boxModel = div.offsetWidth === 2; - // Check if elements with layout shrink-wrap their children - // (IE 6 does this) - div.style.display = ""; - div.innerHTML = "
"; - jQuery.support.shrinkWrapBlocks = div.offsetWidth !== 2; - } + if ( "zoom" in div.style ) { + // Check if natively block-level elements act like inline-block + // elements when setting their display to 'inline' and giving + // them layout + // (IE < 8 does this) + div.style.display = "inline"; + div.style.zoom = 1; + support.inlineBlockNeedsLayout = ( div.offsetWidth === 2 ); - div.innerHTML = "
t
"; - var tds = div.getElementsByTagName("td"); + // Check if elements with layout shrink-wrap their children + // (IE 6 does this) + div.style.display = ""; + div.innerHTML = "
"; + support.shrinkWrapBlocks = ( div.offsetWidth !== 2 ); + } - // Check if table cells still have offsetWidth/Height when they are set - // to display:none and there are still other visible table cells in a - // table row; if so, offsetWidth/Height are not reliable for use when - // determining if an element has been hidden directly using - // display:none (it is still safe to use offsets if a parent element is - // hidden; don safety goggles and see bug #4512 for more information). - // (only IE 8 fails this test) - jQuery.support.reliableHiddenOffsets = tds[0].offsetHeight === 0; + div.innerHTML = "
t
"; + tds = div.getElementsByTagName( "td" ); - tds[0].style.display = ""; - tds[1].style.display = "none"; + // Check if table cells still have offsetWidth/Height when they are set + // to display:none and there are still other visible table cells in a + // table row; if so, offsetWidth/Height are not reliable for use when + // determining if an element has been hidden directly using + // display:none (it is still safe to use offsets if a parent element is + // hidden; don safety goggles and see bug #4512 for more information). + // (only IE 8 fails this test) + isSupported = ( tds[ 0 ].offsetHeight === 0 ); - // Check if empty table cells still have offsetWidth/Height - // (IE < 8 fail this test) - jQuery.support.reliableHiddenOffsets = jQuery.support.reliableHiddenOffsets && tds[0].offsetHeight === 0; - div.innerHTML = ""; + tds[ 0 ].style.display = ""; + tds[ 1 ].style.display = "none"; - // Check if div with explicit width and no margin-right incorrectly - // gets computed margin-right based on width of container. For more - // info see bug #3333 - // Fails in WebKit before Feb 2011 nightlies - // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right - if ( document.defaultView && document.defaultView.getComputedStyle ) { - div.style.width = "1px"; - div.style.marginRight = "0"; - jQuery.support.reliableMarginRight = ( parseInt(document.defaultView.getComputedStyle(div, null).marginRight, 10) || 0 ) === 0; - } + // Check if empty table cells still have offsetWidth/Height + // (IE < 8 fail this test) + support.reliableHiddenOffsets = isSupported && ( tds[ 0 ].offsetHeight === 0 ); + div.innerHTML = ""; - body.removeChild( div ).style.display = "none"; - div = tds = null; - }); + // Check if div with explicit width and no margin-right incorrectly + // gets computed margin-right based on width of container. For more + // info see bug #3333 + // Fails in WebKit before Feb 2011 nightlies + // WebKit Bug 13343 - getComputedStyle returns wrong value for margin-right + if ( document.defaultView && document.defaultView.getComputedStyle ) { + marginDiv = document.createElement( "div" ); + marginDiv.style.width = "0"; + marginDiv.style.marginRight = "0"; + div.appendChild( marginDiv ); + support.reliableMarginRight = + ( parseInt( ( document.defaultView.getComputedStyle( marginDiv, null ) || { marginRight: 0 } ).marginRight, 10 ) || 0 ) === 0; + } + + // Remove the body element we added + testElement.innerHTML = ""; + testElementParent.removeChild( testElement ); // Technique from Juriy Zaytsev // http://thinkweb2.com/projects/prototype/detecting-event-support-without-browser-sniffing/ - var eventSupported = function( eventName ) { - var el = document.createElement("div"); - eventName = "on" + eventName; - - // We only care about the case where non-standard event systems - // are used, namely in IE. Short-circuiting here helps us to - // avoid an eval call (in setAttribute) which can cause CSP - // to go haywire. See: https://developer.mozilla.org/en/Security/CSP - if ( !el.attachEvent ) { - return true; + // We only care about the case where non-standard event systems + // are used, namely in IE. Short-circuiting here helps us to + // avoid an eval call (in setAttribute) which can cause CSP + // to go haywire. See: https://developer.mozilla.org/en/Security/CSP + if ( div.attachEvent ) { + for( i in { + submit: 1, + change: 1, + focusin: 1 + } ) { + eventName = "on" + i; + isSupported = ( eventName in div ); + if ( !isSupported ) { + div.setAttribute( eventName, "return;" ); + isSupported = ( typeof div[ eventName ] === "function" ); + } + support[ i + "Bubbles" ] = isSupported; } + } - var isSupported = (eventName in el); - if ( !isSupported ) { - el.setAttribute(eventName, "return;"); - isSupported = typeof el[eventName] === "function"; - } - return isSupported; - }; + // Null connected elements to avoid leaks in IE + testElement = fragment = select = opt = body = marginDiv = div = input = null; - jQuery.support.submitBubbles = eventSupported("submit"); - jQuery.support.changeBubbles = eventSupported("change"); - - // release memory in IE - div = all = a = null; + return support; })(); +// Keep track of boxModel +jQuery.boxModel = jQuery.support.boxModel; -var rbrace = /^(?:\{.*\}|\[.*\])$/; + + +var rbrace = /^(?:\{.*\}|\[.*\])$/, + rmultiDash = /([a-z])([A-Z])/g; jQuery.extend({ cache: {}, @@ -1418,7 +1501,7 @@ jQuery.extend({ } if ( data !== undefined ) { - thisCache[ name ] = data; + thisCache[ jQuery.camelCase( name ) ] = data; } // TODO: This is a hack for 1.5 ONLY. It will be removed in 1.6. Users should @@ -1428,7 +1511,10 @@ jQuery.extend({ return thisCache[ internalKey ] && thisCache[ internalKey ].events; } - return getByName ? thisCache[ name ] : thisCache; + return getByName ? + // Check for both converted-to-camel and non-converted data property names + thisCache[ jQuery.camelCase( name ) ] || thisCache[ name ] : + thisCache; }, removeData: function( elem, name, pvt /* Internal Use Only */ ) { @@ -1544,12 +1630,13 @@ jQuery.fn.extend({ data = jQuery.data( this[0] ); if ( this[0].nodeType === 1 ) { - var attr = this[0].attributes, name; + var attr = this[0].attributes, name; for ( var i = 0, l = attr.length; i < l; i++ ) { name = attr[i].name; if ( name.indexOf( "data-" ) === 0 ) { - name = name.substr( 5 ); + name = jQuery.camelCase( name.substring(5) ); + dataAttr( this[0], name, data[ name ] ); } } @@ -1603,7 +1690,9 @@ function dataAttr( elem, key, data ) { // If nothing was found internally, try to fetch any // data from the HTML5 data-* attribute if ( data === undefined && elem.nodeType === 1 ) { - data = elem.getAttribute( "data-" + key ); + var name = "data-" + key.replace( rmultiDash, "$1-$2" ).toLowerCase(); + + data = elem.getAttribute( name ); if ( typeof data === "string" ) { try { @@ -1642,35 +1731,76 @@ function isEmptyDataObject( obj ) { +function handleQueueMarkDefer( elem, type, src ) { + var deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + defer = jQuery.data( elem, deferDataKey, undefined, true ); + if ( defer && + ( src === "queue" || !jQuery.data( elem, queueDataKey, undefined, true ) ) && + ( src === "mark" || !jQuery.data( elem, markDataKey, undefined, true ) ) ) { + // Give room for hard-coded callbacks to fire first + // and eventually mark/queue something else on the element + setTimeout( function() { + if ( !jQuery.data( elem, queueDataKey, undefined, true ) && + !jQuery.data( elem, markDataKey, undefined, true ) ) { + jQuery.removeData( elem, deferDataKey, true ); + defer.resolve(); + } + }, 0 ); + } +} + jQuery.extend({ - queue: function( elem, type, data ) { - if ( !elem ) { - return; + + _mark: function( elem, type ) { + if ( elem ) { + type = (type || "fx") + "mark"; + jQuery.data( elem, type, (jQuery.data(elem,type,undefined,true) || 0) + 1, true ); } + }, - type = (type || "fx") + "queue"; - var q = jQuery._data( elem, type ); + _unmark: function( force, elem, type ) { + if ( force !== true ) { + type = elem; + elem = force; + force = false; + } + if ( elem ) { + type = type || "fx"; + var key = type + "mark", + count = force ? 0 : ( (jQuery.data( elem, key, undefined, true) || 1 ) - 1 ); + if ( count ) { + jQuery.data( elem, key, count, true ); + } else { + jQuery.removeData( elem, key, true ); + handleQueueMarkDefer( elem, type, "mark" ); + } + } + }, - // Speed up dequeue by getting out quickly if this is just a lookup - if ( !data ) { + queue: function( elem, type, data ) { + if ( elem ) { + type = (type || "fx") + "queue"; + var q = jQuery.data( elem, type, undefined, true ); + // Speed up dequeue by getting out quickly if this is just a lookup + if ( data ) { + if ( !q || jQuery.isArray(data) ) { + q = jQuery.data( elem, type, jQuery.makeArray(data), true ); + } else { + q.push( data ); + } + } return q || []; } - - if ( !q || jQuery.isArray(data) ) { - q = jQuery._data( elem, type, jQuery.makeArray(data) ); - - } else { - q.push( data ); - } - - return q; }, dequeue: function( elem, type ) { type = type || "fx"; var queue = jQuery.queue( elem, type ), - fn = queue.shift(); + fn = queue.shift(), + defer; // If the fx queue is dequeued, always remove the progress sentinel if ( fn === "inprogress" ) { @@ -1691,6 +1821,7 @@ jQuery.extend({ if ( !queue.length ) { jQuery.removeData( elem, type + "queue", true ); + handleQueueMarkDefer( elem, type, "queue" ); } } }); @@ -1705,7 +1836,7 @@ jQuery.fn.extend({ if ( data === undefined ) { return jQuery.queue( this[0], type ); } - return this.each(function( i ) { + return this.each(function() { var queue = jQuery.queue( this, type, data ); if ( type === "fx" && queue[0] !== "inprogress" ) { @@ -1718,7 +1849,6 @@ jQuery.fn.extend({ jQuery.dequeue( this, type ); }); }, - // Based off of the plugin by Clint Helfers, with permission. // http://blindsignals.com/index.php/2009/07/jquery-delay/ delay: function( time, type ) { @@ -1732,9 +1862,41 @@ jQuery.fn.extend({ }, time ); }); }, - clearQueue: function( type ) { return this.queue( type || "fx", [] ); + }, + // Get a promise resolved when queues of a certain type + // are emptied (fx is the type by default) + promise: function( type, object ) { + if ( typeof type !== "string" ) { + object = type; + type = undefined; + } + type = type || "fx"; + var defer = jQuery.Deferred(), + elements = this, + i = elements.length, + count = 1, + deferDataKey = type + "defer", + queueDataKey = type + "queue", + markDataKey = type + "mark", + tmp; + function resolve() { + if ( !( --count ) ) { + defer.resolveWith( elements, [ elements ] ); + } + } + while( i-- ) { + if (( tmp = jQuery.data( elements[ i ], deferDataKey, undefined, true ) || + ( jQuery.data( elements[ i ], queueDataKey, undefined, true ) || + jQuery.data( elements[ i ], markDataKey, undefined, true ) ) && + jQuery.data( elements[ i ], deferDataKey, jQuery._Deferred(), true ) )) { + count++; + tmp.done( resolve ); + } + } + resolve(); + return defer.promise(); } }); @@ -1742,66 +1904,67 @@ jQuery.fn.extend({ var rclass = /[\n\t\r]/g, - rspaces = /\s+/, + rspace = /\s+/, rreturn = /\r/g, - rspecialurl = /^(?:href|src|style)$/, rtype = /^(?:button|input)$/i, rfocusable = /^(?:button|input|object|select|textarea)$/i, rclickable = /^a(?:rea)?$/i, - rradiocheck = /^(?:radio|checkbox)$/i; - -jQuery.props = { - "for": "htmlFor", - "class": "className", - readonly: "readOnly", - maxlength: "maxLength", - cellspacing: "cellSpacing", - rowspan: "rowSpan", - colspan: "colSpan", - tabindex: "tabIndex", - usemap: "useMap", - frameborder: "frameBorder" -}; + rboolean = /^(?:autofocus|autoplay|async|checked|controls|defer|disabled|hidden|loop|multiple|open|readonly|required|scoped|selected)$/i, + rinvalidChar = /\:|^on/, + formHook, boolHook; jQuery.fn.extend({ attr: function( name, value ) { return jQuery.access( this, name, value, true, jQuery.attr ); }, - removeAttr: function( name, fn ) { - return this.each(function(){ - jQuery.attr( this, name, "" ); - if ( this.nodeType === 1 ) { - this.removeAttribute( name ); - } + removeAttr: function( name ) { + return this.each(function() { + jQuery.removeAttr( this, name ); + }); + }, + + prop: function( name, value ) { + return jQuery.access( this, name, value, true, jQuery.prop ); + }, + + removeProp: function( name ) { + name = jQuery.propFix[ name ] || name; + return this.each(function() { + // try/catch handles cases where IE balks (such as removing a property on window) + try { + this[ name ] = undefined; + delete this[ name ]; + } catch( e ) {} }); }, addClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.addClass( value.call(this, i, self.attr("class")) ); + var classNames, i, l, elem, + setClass, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).addClass( value.call(this, j, this.className) ); }); } if ( value && typeof value === "string" ) { - var classNames = (value || "").split( rspaces ); + classNames = value.split( rspace ); - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; if ( elem.nodeType === 1 ) { - if ( !elem.className ) { + if ( !elem.className && classNames.length === 1 ) { elem.className = value; } else { - var className = " " + elem.className + " ", - setClass = elem.className; + setClass = " " + elem.className + " "; - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - if ( className.indexOf( " " + classNames[c] + " " ) < 0 ) { - setClass += " " + classNames[c]; + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + if ( !~setClass.indexOf( " " + classNames[ c ] + " " ) ) { + setClass += classNames[ c ] + " "; } } elem.className = jQuery.trim( setClass ); @@ -1814,24 +1977,25 @@ jQuery.fn.extend({ }, removeClass: function( value ) { - if ( jQuery.isFunction(value) ) { - return this.each(function(i) { - var self = jQuery(this); - self.removeClass( value.call(this, i, self.attr("class")) ); + var classNames, i, l, elem, className, c, cl; + + if ( jQuery.isFunction( value ) ) { + return this.each(function( j ) { + jQuery( this ).removeClass( value.call(this, j, this.className) ); }); } if ( (value && typeof value === "string") || value === undefined ) { - var classNames = (value || "").split( rspaces ); + classNames = (value || "").split( rspace ); - for ( var i = 0, l = this.length; i < l; i++ ) { - var elem = this[i]; + for ( i = 0, l = this.length; i < l; i++ ) { + elem = this[ i ]; if ( elem.nodeType === 1 && elem.className ) { if ( value ) { - var className = (" " + elem.className + " ").replace(rclass, " "); - for ( var c = 0, cl = classNames.length; c < cl; c++ ) { - className = className.replace(" " + classNames[c] + " ", " "); + className = (" " + elem.className + " ").replace( rclass, " " ); + for ( c = 0, cl = classNames.length; c < cl; c++ ) { + className = className.replace(" " + classNames[ c ] + " ", " "); } elem.className = jQuery.trim( className ); @@ -1850,9 +2014,8 @@ jQuery.fn.extend({ isBool = typeof stateVal === "boolean"; if ( jQuery.isFunction( value ) ) { - return this.each(function(i) { - var self = jQuery(this); - self.toggleClass( value.call(this, i, self.attr("class"), stateVal), stateVal ); + return this.each(function( i ) { + jQuery( this ).toggleClass( value.call(this, i, this.className, stateVal), stateVal ); }); } @@ -1863,7 +2026,7 @@ jQuery.fn.extend({ i = 0, self = jQuery( this ), state = stateVal, - classNames = value.split( rspaces ); + classNames = value.split( rspace ); while ( (className = classNames[ i++ ]) ) { // check each className given, space seperated list @@ -1895,82 +2058,42 @@ jQuery.fn.extend({ }, val: function( value ) { + var hooks, ret, + elem = this[0]; + if ( !arguments.length ) { - var elem = this[0]; - if ( elem ) { - if ( jQuery.nodeName( elem, "option" ) ) { - // attributes.value is undefined in Blackberry 4.7 but - // uses .value. See #6932 - var val = elem.attributes.value; - return !val || val.specified ? elem.value : elem.text; + hooks = jQuery.valHooks[ elem.nodeName.toLowerCase() ] || jQuery.valHooks[ elem.type ]; + + if ( hooks && "get" in hooks && (ret = hooks.get( elem, "value" )) !== undefined ) { + return ret; } - // We need to handle select boxes special - if ( jQuery.nodeName( elem, "select" ) ) { - var index = elem.selectedIndex, - values = [], - options = elem.options, - one = elem.type === "select-one"; - - // Nothing was selected - if ( index < 0 ) { - return null; - } - - // Loop through all the selected options - for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { - var option = options[ i ]; - - // Don't return options that are disabled or in a disabled optgroup - if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && - (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { - - // Get the specific value for the option - value = jQuery(option).val(); - - // We don't need an array for one selects - if ( one ) { - return value; - } - - // Multi-Selects return an array - values.push( value ); - } - } - - // Fixes Bug #2551 -- select.val() broken in IE after form.reset() - if ( one && !values.length && options.length ) { - return jQuery( options[ index ] ).val(); - } - - return values; - } - - // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified - if ( rradiocheck.test( elem.type ) && !jQuery.support.checkOn ) { - return elem.getAttribute("value") === null ? "on" : elem.value; - } - - // Everything else, we just grab the value - return (elem.value || "").replace(rreturn, ""); + ret = elem.value; + return typeof ret === "string" ? + // handle most common string cases + ret.replace(rreturn, "") : + // handle cases where value is null/undef or number + ret == null ? "" : ret; } return undefined; } - var isFunction = jQuery.isFunction(value); + var isFunction = jQuery.isFunction( value ); - return this.each(function(i) { - var self = jQuery(this), val = value; + return this.each(function( i ) { + var self = jQuery(this), val; if ( this.nodeType !== 1 ) { return; } if ( isFunction ) { - val = value.call(this, i, self.val()); + val = value.call( this, i, self.val() ); + } else { + val = value; } // Treat null/undefined as ""; convert numbers to string @@ -1978,27 +2101,16 @@ jQuery.fn.extend({ val = ""; } else if ( typeof val === "number" ) { val += ""; - } else if ( jQuery.isArray(val) ) { - val = jQuery.map(val, function (value) { + } else if ( jQuery.isArray( val ) ) { + val = jQuery.map(val, function ( value ) { return value == null ? "" : value + ""; }); } - if ( jQuery.isArray(val) && rradiocheck.test( this.type ) ) { - this.checked = jQuery.inArray( self.val(), val ) >= 0; + hooks = jQuery.valHooks[ this.nodeName.toLowerCase() ] || jQuery.valHooks[ this.type ]; - } else if ( jQuery.nodeName( this, "select" ) ) { - var values = jQuery.makeArray(val); - - jQuery( "option", this ).each(function() { - this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; - }); - - if ( !values.length ) { - this.selectedIndex = -1; - } - - } else { + // If set returns undefined, fall back to normal setting + if ( !hooks || !("set" in hooks) || hooks.set( this, val, "value" ) === undefined ) { this.value = val; } }); @@ -2006,6 +2118,72 @@ jQuery.fn.extend({ }); jQuery.extend({ + valHooks: { + option: { + get: function( elem ) { + // attributes.value is undefined in Blackberry 4.7 but + // uses .value. See #6932 + var val = elem.attributes.value; + return !val || val.specified ? elem.value : elem.text; + } + }, + select: { + get: function( elem ) { + var value, + index = elem.selectedIndex, + values = [], + options = elem.options, + one = elem.type === "select-one"; + + // Nothing was selected + if ( index < 0 ) { + return null; + } + + // Loop through all the selected options + for ( var i = one ? index : 0, max = one ? index + 1 : options.length; i < max; i++ ) { + var option = options[ i ]; + + // Don't return options that are disabled or in a disabled optgroup + if ( option.selected && (jQuery.support.optDisabled ? !option.disabled : option.getAttribute("disabled") === null) && + (!option.parentNode.disabled || !jQuery.nodeName( option.parentNode, "optgroup" )) ) { + + // Get the specific value for the option + value = jQuery( option ).val(); + + // We don't need an array for one selects + if ( one ) { + return value; + } + + // Multi-Selects return an array + values.push( value ); + } + } + + // Fixes Bug #2551 -- select.val() broken in IE after form.reset() + if ( one && !values.length && options.length ) { + return jQuery( options[ index ] ).val(); + } + + return values; + }, + + set: function( elem, value ) { + var values = jQuery.makeArray( value ); + + jQuery(elem).find("option").each(function() { + this.selected = jQuery.inArray( jQuery(this).val(), values ) >= 0; + }); + + if ( !values.length ) { + elem.selectedIndex = -1; + } + return values; + } + } + }, + attrFn: { val: true, css: true, @@ -2016,115 +2194,340 @@ jQuery.extend({ height: true, offset: true }, - + + attrFix: { + // Always normalize to ensure hook usage + tabindex: "tabIndex" + }, + attr: function( elem, name, value, pass ) { + var nType = elem.nodeType; + // don't get/set attributes on text, comment and attribute nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 || elem.nodeType === 2 ) { + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { return undefined; } if ( pass && name in jQuery.attrFn ) { - return jQuery(elem)[name](value); + return jQuery( elem )[ name ]( value ); } - var notxml = elem.nodeType !== 1 || !jQuery.isXMLDoc( elem ), - // Whether we are setting (or getting) - set = value !== undefined; + // Fallback to prop when attributes are not supported + if ( !("getAttribute" in elem) ) { + return jQuery.prop( elem, name, value ); + } - // Try to normalize/fix the name - name = notxml && jQuery.props[ name ] || name; + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); - // Only do all the following if this is a node (faster for style) - if ( elem.nodeType === 1 ) { - // These attributes require special treatment - var special = rspecialurl.test( name ); + // Normalize the name if needed + if ( notxml ) { + name = jQuery.attrFix[ name ] || name; - // Safari mis-reports the default selected property of an option - // Accessing the parent's selectedIndex property fixes it - if ( name === "selected" && !jQuery.support.optSelected ) { - var parent = elem.parentNode; - if ( parent ) { - parent.selectedIndex; + hooks = jQuery.attrHooks[ name ]; - // Make sure that it also works with optgroups, see #5701 - if ( parent.parentNode ) { - parent.parentNode.selectedIndex; - } + if ( !hooks ) { + // Use boolHook for boolean attributes + if ( rboolean.test( name ) ) { + + hooks = boolHook; + + // Use formHook for forms and if the name contains certain characters + } else if ( formHook && name !== "className" && + (jQuery.nodeName( elem, "form" ) || rinvalidChar.test( name )) ) { + + hooks = formHook; } } + } - // If applicable, access the attribute via the DOM 0 way - // 'in' checks fail in Blackberry 4.7 #6931 - if ( (name in elem || elem[ name ] !== undefined) && notxml && !special ) { - if ( set ) { - // We can't allow the type property to be changed (since it causes problems in IE) - if ( name === "type" && rtype.test( elem.nodeName ) && elem.parentNode ) { - jQuery.error( "type property can't be changed" ); - } + if ( value !== undefined ) { - if ( value === null ) { - if ( elem.nodeType === 1 ) { - elem.removeAttribute( name ); - } - - } else { - elem[ name ] = value; - } - } - - // browsers index elements by id/name on forms, give priority to attributes. - if ( jQuery.nodeName( elem, "form" ) && elem.getAttributeNode(name) ) { - return elem.getAttributeNode( name ).nodeValue; - } - - // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set - // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ - if ( name === "tabIndex" ) { - var attributeNode = elem.getAttributeNode( "tabIndex" ); - - return attributeNode && attributeNode.specified ? - attributeNode.value : - rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? - 0 : - undefined; - } - - return elem[ name ]; - } - - if ( !jQuery.support.style && notxml && name === "style" ) { - if ( set ) { - elem.style.cssText = "" + value; - } - - return elem.style.cssText; - } - - if ( set ) { - // convert the value to a string (all browsers do this but IE) see #1070 - elem.setAttribute( name, "" + value ); - } - - // Ensure that missing attributes return undefined - // Blackberry 4.7 returns "" from getAttribute #6938 - if ( !elem.attributes[ name ] && (elem.hasAttribute && !elem.hasAttribute( name )) ) { + if ( value === null ) { + jQuery.removeAttr( elem, name ); return undefined; + + } else if ( hooks && "set" in hooks && notxml && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + elem.setAttribute( name, "" + value ); + return value; } - var attr = !jQuery.support.hrefNormalized && notxml && special ? - // Some attributes require a special call on IE - elem.getAttribute( name, 2 ) : - elem.getAttribute( name ); + } else if ( hooks && "get" in hooks && notxml && (ret = hooks.get( elem, name )) !== null ) { + return ret; + + } else { + + ret = elem.getAttribute( name ); // Non-existent attributes return null, we normalize to undefined - return attr === null ? undefined : attr; + return ret === null ? + undefined : + ret; } - // Handle everything which isn't a DOM element node - if ( set ) { - elem[ name ] = value; + }, + + removeAttr: function( elem, name ) { + var propName; + if ( elem.nodeType === 1 ) { + name = jQuery.attrFix[ name ] || name; + + if ( jQuery.support.getSetAttribute ) { + // Use removeAttribute in browsers that support it + elem.removeAttribute( name ); + } else { + jQuery.attr( elem, name, "" ); + elem.removeAttributeNode( elem.getAttributeNode( name ) ); + } + + // Set corresponding property to false for boolean attributes + if ( rboolean.test( name ) && (propName = jQuery.propFix[ name ] || name) in elem ) { + elem[ propName ] = false; + } } - return elem[ name ]; + }, + + attrHooks: { + type: { + set: function( elem, value ) { + // We can't allow the type property to be changed (since it causes problems in IE) + if ( rtype.test( elem.nodeName ) && elem.parentNode ) { + jQuery.error( "type property can't be changed" ); + } else if ( !jQuery.support.radioValue && value === "radio" && jQuery.nodeName(elem, "input") ) { + // Setting the type on a radio button after the value resets the value in IE6-9 + // Reset value to it's default in case type is set after value + // This is for element creation + var val = elem.value; + elem.setAttribute( "type", value ); + if ( val ) { + elem.value = val; + } + return value; + } + } + }, + tabIndex: { + get: function( elem ) { + // elem.tabIndex doesn't always return the correct value when it hasn't been explicitly set + // http://fluidproject.org/blog/2008/01/09/getting-setting-and-removing-tabindex-values-with-javascript/ + var attributeNode = elem.getAttributeNode("tabIndex"); + + return attributeNode && attributeNode.specified ? + parseInt( attributeNode.value, 10 ) : + rfocusable.test( elem.nodeName ) || rclickable.test( elem.nodeName ) && elem.href ? + 0 : + undefined; + } + }, + // Use the value property for back compat + // Use the formHook for button elements in IE6/7 (#1954) + value: { + get: function( elem, name ) { + if ( formHook && jQuery.nodeName( elem, "button" ) ) { + return formHook.get( elem, name ); + } + return name in elem ? + elem.value : + null; + }, + set: function( elem, value, name ) { + if ( formHook && jQuery.nodeName( elem, "button" ) ) { + return formHook.set( elem, value, name ); + } + // Does not return so that setAttribute is also used + elem.value = value; + } + } + }, + + propFix: { + tabindex: "tabIndex", + readonly: "readOnly", + "for": "htmlFor", + "class": "className", + maxlength: "maxLength", + cellspacing: "cellSpacing", + cellpadding: "cellPadding", + rowspan: "rowSpan", + colspan: "colSpan", + usemap: "useMap", + frameborder: "frameBorder", + contenteditable: "contentEditable" + }, + + prop: function( elem, name, value ) { + var nType = elem.nodeType; + + // don't get/set properties on text, comment and attribute nodes + if ( !elem || nType === 3 || nType === 8 || nType === 2 ) { + return undefined; + } + + var ret, hooks, + notxml = nType !== 1 || !jQuery.isXMLDoc( elem ); + + if ( notxml ) { + // Fix name and attach hooks + name = jQuery.propFix[ name ] || name; + hooks = jQuery.propHooks[ name ]; + } + + if ( value !== undefined ) { + if ( hooks && "set" in hooks && (ret = hooks.set( elem, value, name )) !== undefined ) { + return ret; + + } else { + return (elem[ name ] = value); + } + + } else { + if ( hooks && "get" in hooks && (ret = hooks.get( elem, name )) !== undefined ) { + return ret; + + } else { + return elem[ name ]; + } + } + }, + + propHooks: {} +}); + +// Hook for boolean attributes +boolHook = { + get: function( elem, name ) { + // Align boolean attributes with corresponding properties + return jQuery.prop( elem, name ) ? + name.toLowerCase() : + undefined; + }, + set: function( elem, value, name ) { + var propName; + if ( value === false ) { + // Remove boolean attributes when set to false + jQuery.removeAttr( elem, name ); + } else { + // value is true since we know at this point it's type boolean and not false + // Set boolean attributes to the same name and set the DOM property + propName = jQuery.propFix[ name ] || name; + if ( propName in elem ) { + // Only set the IDL specifically if it already exists on the element + elem[ propName ] = true; + } + + elem.setAttribute( name, name.toLowerCase() ); + } + return name; } +}; + +// IE6/7 do not support getting/setting some attributes with get/setAttribute +if ( !jQuery.support.getSetAttribute ) { + + // propFix is more comprehensive and contains all fixes + jQuery.attrFix = jQuery.propFix; + + // Use this for any attribute on a form in IE6/7 + formHook = jQuery.attrHooks.name = jQuery.attrHooks.title = jQuery.valHooks.button = { + get: function( elem, name ) { + var ret; + ret = elem.getAttributeNode( name ); + // Return undefined if nodeValue is empty string + return ret && ret.nodeValue !== "" ? + ret.nodeValue : + undefined; + }, + set: function( elem, value, name ) { + // Check form objects in IE (multiple bugs related) + // Only use nodeValue if the attribute node exists on the form + var ret = elem.getAttributeNode( name ); + if ( ret ) { + ret.nodeValue = value; + return value; + } + } + }; + + // Set width and height to auto instead of 0 on empty string( Bug #8150 ) + // This is for removals + jQuery.each([ "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + set: function( elem, value ) { + if ( value === "" ) { + elem.setAttribute( name, "auto" ); + return value; + } + } + }); + }); +} + + +// Some attributes require a special call on IE +if ( !jQuery.support.hrefNormalized ) { + jQuery.each([ "href", "src", "width", "height" ], function( i, name ) { + jQuery.attrHooks[ name ] = jQuery.extend( jQuery.attrHooks[ name ], { + get: function( elem ) { + var ret = elem.getAttribute( name, 2 ); + return ret === null ? undefined : ret; + } + }); + }); +} + +if ( !jQuery.support.style ) { + jQuery.attrHooks.style = { + get: function( elem ) { + // Return undefined in the case of empty string + // Normalize to lowercase since IE uppercases css property names + return elem.style.cssText.toLowerCase() || undefined; + }, + set: function( elem, value ) { + return (elem.style.cssText = "" + value); + } + }; +} + +// Safari mis-reports the default selected property of an option +// Accessing the parent's selectedIndex property fixes it +if ( !jQuery.support.optSelected ) { + jQuery.propHooks.selected = jQuery.extend( jQuery.propHooks.selected, { + get: function( elem ) { + var parent = elem.parentNode; + + if ( parent ) { + parent.selectedIndex; + + // Make sure that it also works with optgroups, see #5701 + if ( parent.parentNode ) { + parent.parentNode.selectedIndex; + } + } + } + }); +} + +// Radios and checkboxes getter/setter +if ( !jQuery.support.checkOn ) { + jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = { + get: function( elem ) { + // Handle the case where in Webkit "" is returned instead of "on" if a value isn't specified + return elem.getAttribute("value") === null ? "on" : elem.value; + } + }; + }); +} +jQuery.each([ "radio", "checkbox" ], function() { + jQuery.valHooks[ this ] = jQuery.extend( jQuery.valHooks[ this ], { + set: function( elem, value ) { + if ( jQuery.isArray( value ) ) { + return (elem.checked = jQuery.inArray( jQuery(elem).val(), value ) >= 0); + } + } + }); }); @@ -2133,7 +2536,7 @@ jQuery.extend({ var rnamespaces = /\.(.*)$/, rformElems = /^(?:textarea|input|select)$/i, rperiod = /\./g, - rspace = / /g, + rspaces = / /g, rescape = /[^\w\s.|`]/g, fcleanup = function( nm ) { return nm.replace(rescape, "\\$&"); @@ -2153,17 +2556,6 @@ jQuery.event = { return; } - // TODO :: Use a try/catch until it's safe to pull this out (likely 1.6) - // Minor release fix for bug #8018 - try { - // For whatever reason, IE has trouble passing the window object - // around, causing it to be cloned in the process - if ( jQuery.isWindow( elem ) && ( elem !== window && !elem.frameElement ) ) { - elem = window; - } - } - catch ( e ) {} - if ( handler === false ) { handler = returnFalse; } else if ( !handler ) { @@ -2201,9 +2593,9 @@ jQuery.event = { if ( !eventHandle ) { elemData.handle = eventHandle = function( e ) { - // Handle the second event of a trigger and when - // an event is called after a page has unloaded - return typeof jQuery !== "undefined" && jQuery.event.triggered !== e.type ? + // Discard the second event of a jQuery.event.trigger() and + // when an event is called after a page has unloaded + return typeof jQuery !== "undefined" && (!e || jQuery.event.triggered !== e.type) ? jQuery.event.handle.apply( eventHandle.elem, arguments ) : undefined; }; @@ -2273,7 +2665,7 @@ jQuery.event = { // Add the function to the element's handler list handlers.push( handleObj ); - // Keep track of which events have been used, for global triggering + // Keep track of which events have been used, for event optimization jQuery.event.global[ type ] = true; } @@ -2406,182 +2798,185 @@ jQuery.event = { } } }, + + // Events that are safe to short-circuit if no handlers are attached. + // Native DOM events should not be added, they may have inline handlers. + customEvent: { + "getData": true, + "setData": true, + "changeData": true + }, - // bubbling is internal - trigger: function( event, data, elem /*, bubbling */ ) { + trigger: function( event, data, elem, onlyHandlers ) { // Event object or event type var type = event.type || event, - bubbling = arguments[3]; + namespaces = [], + exclusive; - if ( !bubbling ) { - event = typeof event === "object" ? - // jQuery.Event object - event[ jQuery.expando ] ? event : - // Object literal - jQuery.extend( jQuery.Event(type), event ) : - // Just the event type (string) - jQuery.Event(type); - - if ( type.indexOf("!") >= 0 ) { - event.type = type = type.slice(0, -1); - event.exclusive = true; - } - - // Handle a global trigger - if ( !elem ) { - // Don't bubble custom events when global (to avoid too much overhead) - event.stopPropagation(); - - // Only trigger if we've ever bound an event for it - if ( jQuery.event.global[ type ] ) { - // XXX This code smells terrible. event.js should not be directly - // inspecting the data cache - jQuery.each( jQuery.cache, function() { - // internalKey variable is just used to make it easier to find - // and potentially change this stuff later; currently it just - // points to jQuery.expando - var internalKey = jQuery.expando, - internalCache = this[ internalKey ]; - if ( internalCache && internalCache.events && internalCache.events[ type ] ) { - jQuery.event.trigger( event, data, internalCache.handle.elem ); - } - }); - } - } - - // Handle triggering a single element - - // don't do events on text and comment nodes - if ( !elem || elem.nodeType === 3 || elem.nodeType === 8 ) { - return undefined; - } - - // Clean up in case it is reused - event.result = undefined; - event.target = elem; - - // Clone the incoming data, if any - data = jQuery.makeArray( data ); - data.unshift( event ); + if ( type.indexOf("!") >= 0 ) { + // Exclusive events trigger only for the exact event (no namespaces) + type = type.slice(0, -1); + exclusive = true; } - event.currentTarget = elem; - - // Trigger the event, it is assumed that "handle" is a function - var handle = jQuery._data( elem, "handle" ); - - if ( handle ) { - handle.apply( elem, data ); + if ( type.indexOf(".") >= 0 ) { + // Namespaced trigger; create a regexp to match event type in handle() + namespaces = type.split("."); + type = namespaces.shift(); + namespaces.sort(); } - var parent = elem.parentNode || elem.ownerDocument; + if ( (!elem || jQuery.event.customEvent[ type ]) && !jQuery.event.global[ type ] ) { + // No jQuery handlers for this event type, and it can't have inline handlers + return; + } - // Trigger an inline bound script - try { - if ( !(elem && elem.nodeName && jQuery.noData[elem.nodeName.toLowerCase()]) ) { - if ( elem[ "on" + type ] && elem[ "on" + type ].apply( elem, data ) === false ) { - event.result = false; - event.preventDefault(); + // Caller can pass in an Event, Object, or just an event type string + event = typeof event === "object" ? + // jQuery.Event object + event[ jQuery.expando ] ? event : + // Object literal + new jQuery.Event( type, event ) : + // Just the event type (string) + new jQuery.Event( type ); + + event.type = type; + event.exclusive = exclusive; + event.namespace = namespaces.join("."); + event.namespace_re = new RegExp("(^|\\.)" + namespaces.join("\\.(?:.*\\.)?") + "(\\.|$)"); + + // triggerHandler() and global events don't bubble or run the default action + if ( onlyHandlers || !elem ) { + event.preventDefault(); + event.stopPropagation(); + } + + // Handle a global trigger + if ( !elem ) { + // TODO: Stop taunting the data cache; remove global events and always attach to document + jQuery.each( jQuery.cache, function() { + // internalKey variable is just used to make it easier to find + // and potentially change this stuff later; currently it just + // points to jQuery.expando + var internalKey = jQuery.expando, + internalCache = this[ internalKey ]; + if ( internalCache && internalCache.events && internalCache.events[ type ] ) { + jQuery.event.trigger( event, data, internalCache.handle.elem ); } + }); + return; + } + + // Don't do events on text and comment nodes + if ( elem.nodeType === 3 || elem.nodeType === 8 ) { + return; + } + + // Clean up the event in case it is being reused + event.result = undefined; + event.target = elem; + + // Clone any incoming data and prepend the event, creating the handler arg list + data = data != null ? jQuery.makeArray( data ) : []; + data.unshift( event ); + + var cur = elem, + // IE doesn't like method names with a colon (#3533, #8272) + ontype = type.indexOf(":") < 0 ? "on" + type : ""; + + // Fire event on the current element, then bubble up the DOM tree + do { + var handle = jQuery._data( cur, "handle" ); + + event.currentTarget = cur; + if ( handle ) { + handle.apply( cur, data ); } - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (inlineError) {} + // Trigger an inline bound script + if ( ontype && jQuery.acceptData( cur ) && cur[ ontype ] && cur[ ontype ].apply( cur, data ) === false ) { + event.result = false; + event.preventDefault(); + } - if ( !event.isPropagationStopped() && parent ) { - jQuery.event.trigger( event, data, parent, true ); + // Bubble up to document, then to window + cur = cur.parentNode || cur.ownerDocument || cur === event.target.ownerDocument && window; + } while ( cur && !event.isPropagationStopped() ); - } else if ( !event.isDefaultPrevented() ) { + // If nobody prevented the default action, do it now + if ( !event.isDefaultPrevented() ) { var old, - target = event.target, - targetType = type.replace( rnamespaces, "" ), - isClick = jQuery.nodeName( target, "a" ) && targetType === "click", - special = jQuery.event.special[ targetType ] || {}; + special = jQuery.event.special[ type ] || {}; - if ( (!special._default || special._default.call( elem, event ) === false) && - !isClick && !(target && target.nodeName && jQuery.noData[target.nodeName.toLowerCase()]) ) { + if ( (!special._default || special._default.call( elem.ownerDocument, event ) === false) && + !(type === "click" && jQuery.nodeName( elem, "a" )) && jQuery.acceptData( elem ) ) { + // Call a native DOM method on the target with the same name name as the event. + // Can't use an .isFunction)() check here because IE6/7 fails that test. + // IE<9 dies on focus to hidden element (#1486), may want to revisit a try/catch. try { - if ( target[ targetType ] ) { - // Make sure that we don't accidentally re-trigger the onFOO events - old = target[ "on" + targetType ]; + if ( ontype && elem[ type ] ) { + // Don't re-trigger an onFOO event when we call its FOO() method + old = elem[ ontype ]; if ( old ) { - target[ "on" + targetType ] = null; + elem[ ontype ] = null; } - jQuery.event.triggered = event.type; - target[ targetType ](); + jQuery.event.triggered = type; + elem[ type ](); } - - // prevent IE from throwing an error for some elements with some event types, see #3533 - } catch (triggerError) {} + } catch ( ieError ) {} if ( old ) { - target[ "on" + targetType ] = old; + elem[ ontype ] = old; } jQuery.event.triggered = undefined; } } + + return event.result; }, handle: function( event ) { - var all, handlers, namespaces, namespace_re, events, - namespace_sort = [], - args = jQuery.makeArray( arguments ); + event = jQuery.event.fix( event || window.event ); + // Snapshot the handlers list since a called handler may add/remove events. + var handlers = ((jQuery._data( this, "events" ) || {})[ event.type ] || []).slice(0), + run_all = !event.exclusive && !event.namespace, + args = Array.prototype.slice.call( arguments, 0 ); - event = args[0] = jQuery.event.fix( event || window.event ); + // Use the fix-ed Event rather than the (read-only) native event + args[0] = event; event.currentTarget = this; - // Namespaced event handlers - all = event.type.indexOf(".") < 0 && !event.exclusive; + for ( var j = 0, l = handlers.length; j < l; j++ ) { + var handleObj = handlers[ j ]; - if ( !all ) { - namespaces = event.type.split("."); - event.type = namespaces.shift(); - namespace_sort = namespaces.slice(0).sort(); - namespace_re = new RegExp("(^|\\.)" + namespace_sort.join("\\.(?:.*\\.)?") + "(\\.|$)"); - } + // Triggered event must 1) be non-exclusive and have no namespace, or + // 2) have namespace(s) a subset or equal to those in the bound event. + if ( run_all || event.namespace_re.test( handleObj.namespace ) ) { + // Pass in a reference to the handler function itself + // So that we can later remove it + event.handler = handleObj.handler; + event.data = handleObj.data; + event.handleObj = handleObj; - event.namespace = event.namespace || namespace_sort.join("."); + var ret = handleObj.handler.apply( this, args ); - events = jQuery._data(this, "events"); - - handlers = (events || {})[ event.type ]; - - if ( events && handlers ) { - // Clone the handlers to prevent manipulation - handlers = handlers.slice(0); - - for ( var j = 0, l = handlers.length; j < l; j++ ) { - var handleObj = handlers[ j ]; - - // Filter the functions by class - if ( all || namespace_re.test( handleObj.namespace ) ) { - // Pass in a reference to the handler function itself - // So that we can later remove it - event.handler = handleObj.handler; - event.data = handleObj.data; - event.handleObj = handleObj; - - var ret = handleObj.handler.apply( this, args ); - - if ( ret !== undefined ) { - event.result = ret; - if ( ret === false ) { - event.preventDefault(); - event.stopPropagation(); - } + if ( ret !== undefined ) { + event.result = ret; + if ( ret === false ) { + event.preventDefault(); + event.stopPropagation(); } + } - if ( event.isImmediatePropagationStopped() ) { - break; - } + if ( event.isImmediatePropagationStopped() ) { + break; } } } - return event.result; }, @@ -2620,8 +3015,9 @@ jQuery.event = { // Calculate pageX/Y if missing and clientX/Y available if ( event.pageX == null && event.clientX != null ) { - var doc = document.documentElement, - body = document.body; + var eventDocument = event.target.ownerDocument || document, + doc = eventDocument.documentElement, + body = eventDocument.body; event.pageX = event.clientX + (doc && doc.scrollLeft || body && body.scrollLeft || 0) - (doc && doc.clientLeft || body && body.clientLeft || 0); event.pageY = event.clientY + (doc && doc.scrollTop || body && body.scrollTop || 0) - (doc && doc.clientTop || body && body.clientTop || 0); @@ -2700,10 +3096,10 @@ jQuery.removeEvent = document.removeEventListener ? } }; -jQuery.Event = function( src ) { +jQuery.Event = function( src, props ) { // Allow instantiation without the 'new' keyword if ( !this.preventDefault ) { - return new jQuery.Event( src ); + return new jQuery.Event( src, props ); } // Event object @@ -2721,6 +3117,11 @@ jQuery.Event = function( src ) { this.type = src; } + // Put explicitly provided properties onto the event object + if ( props ) { + jQuery.extend( this, props ); + } + // timeStamp is buggy for some events on Firefox(#3843) // So we won't rely on the native value this.timeStamp = jQuery.now(); @@ -2782,33 +3183,27 @@ jQuery.Event.prototype = { // Checks if an event happened on an element within another element // Used in jQuery.event.special.mouseenter and mouseleave handlers var withinElement = function( event ) { + // Check if mouse(over|out) are still within the same parent element - var parent = event.relatedTarget; + var related = event.relatedTarget, + inside = false, + eventType = event.type; - // Firefox sometimes assigns relatedTarget a XUL element - // which we cannot access the parentNode property of - try { + event.type = event.data; - // Chrome does something similar, the parentNode property - // can be accessed but is null. - if ( parent && parent !== document && !parent.parentNode ) { - return; - } - // Traverse up the tree - while ( parent && parent !== this ) { - parent = parent.parentNode; + if ( related !== this ) { + + if ( related ) { + inside = jQuery.contains( this, related ); } - if ( parent !== this ) { - // set the correct event type - event.type = event.data; + if ( !inside ) { - // handle event if we actually just moused on to a non sub-element jQuery.event.handle.apply( this, arguments ); - } - // assuming we've left the element since we most likely mousedover a xul element - } catch(e) { } + event.type = eventType; + } + } }, // In case of event delegation, we only need to rename the event.type, @@ -2838,7 +3233,7 @@ if ( !jQuery.support.submitBubbles ) { jQuery.event.special.submit = { setup: function( data, namespaces ) { - if ( this.nodeName && this.nodeName.toLowerCase() !== "form" ) { + if ( !jQuery.nodeName( this, "form" ) ) { jQuery.event.add(this, "click.specialSubmit", function( e ) { var elem = e.target, type = elem.type; @@ -2887,7 +3282,7 @@ if ( !jQuery.support.changeBubbles ) { }).join("-") : ""; - } else if ( elem.nodeName.toLowerCase() === "select" ) { + } else if ( jQuery.nodeName( elem, "select" ) ) { val = elem.selectedIndex; } @@ -2927,9 +3322,9 @@ if ( !jQuery.support.changeBubbles ) { beforedeactivate: testChange, click: function( e ) { - var elem = e.target, type = elem.type; + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; - if ( type === "radio" || type === "checkbox" || elem.nodeName.toLowerCase() === "select" ) { + if ( type === "radio" || type === "checkbox" || jQuery.nodeName( elem, "select" ) ) { testChange.call( this, e ); } }, @@ -2937,9 +3332,9 @@ if ( !jQuery.support.changeBubbles ) { // Change has to be called before submit // Keydown will be called before keypress, which is used in submit-event delegation keydown: function( e ) { - var elem = e.target, type = elem.type; + var elem = e.target, type = jQuery.nodeName( elem, "input" ) ? elem.type : ""; - if ( (e.keyCode === 13 && elem.nodeName.toLowerCase() !== "textarea") || + if ( (e.keyCode === 13 && !jQuery.nodeName( elem, "textarea" ) ) || (e.keyCode === 32 && (type === "checkbox" || type === "radio")) || type === "select-multiple" ) { testChange.call( this, e ); @@ -2996,12 +3391,12 @@ function trigger( type, elem, args ) { } // Create "bubbling" focus and blur events -if ( document.addEventListener ) { +if ( !jQuery.support.focusinBubbles ) { jQuery.each({ focus: "focusin", blur: "focusout" }, function( orig, fix ) { - + // Attach a single capturing handler while someone wants focusin/focusout var attaches = 0; - + jQuery.event.special[ fix ] = { setup: function() { if ( attaches++ === 0 ) { @@ -3031,6 +3426,8 @@ if ( document.addEventListener ) { jQuery.each(["bind", "one"], function( i, name ) { jQuery.fn[ name ] = function( type, data, fn ) { + var handler; + // Handle object literals if ( typeof type === "object" ) { for ( var key in type ) { @@ -3039,15 +3436,20 @@ jQuery.each(["bind", "one"], function( i, name ) { return this; } - if ( jQuery.isFunction( data ) || data === false ) { + if ( arguments.length === 2 || data === false ) { fn = data; data = undefined; } - var handler = name === "one" ? jQuery.proxy( fn, function( event ) { - jQuery( this ).unbind( event, handler ); - return fn.apply( this, arguments ); - }) : fn; + if ( name === "one" ) { + handler = function( event ) { + jQuery( this ).unbind( event, handler ); + return fn.apply( this, arguments ); + }; + handler.guid = fn.guid || jQuery.guid++; + } else { + handler = fn; + } if ( type === "unload" && name !== "one" ) { this.one( type, data, fn ); @@ -3085,7 +3487,7 @@ jQuery.fn.extend({ undelegate: function( selector, types, fn ) { if ( arguments.length === 0 ) { - return this.unbind( "live" ); + return this.unbind( "live" ); } else { return this.die( types, null, fn, selector ); @@ -3100,35 +3502,34 @@ jQuery.fn.extend({ triggerHandler: function( type, data ) { if ( this[0] ) { - var event = jQuery.Event( type ); - event.preventDefault(); - event.stopPropagation(); - jQuery.event.trigger( event, data, this[0] ); - return event.result; + return jQuery.event.trigger( type, data, this[0], true ); } }, toggle: function( fn ) { // Save reference to arguments for access in closure var args = arguments, - i = 1; + guid = fn.guid || jQuery.guid++, + i = 0, + toggler = function( event ) { + // Figure out which function to execute + var lastToggle = ( jQuery.data( this, "lastToggle" + fn.guid ) || 0 ) % i; + jQuery.data( this, "lastToggle" + fn.guid, lastToggle + 1 ); + + // Make sure that clicks stop + event.preventDefault(); + + // and execute the function + return args[ lastToggle ].apply( this, arguments ) || false; + }; // link all the functions, so any of them can unbind this click handler + toggler.guid = guid; while ( i < args.length ) { - jQuery.proxy( fn, args[ i++ ] ); + args[ i++ ].guid = guid; } - return this.click( jQuery.proxy( fn, function( event ) { - // Figure out which function to execute - var lastToggle = ( jQuery._data( this, "lastToggle" + fn.guid ) || 0 ) % i; - jQuery._data( this, "lastToggle" + fn.guid, lastToggle + 1 ); - - // Make sure that clicks stop - event.preventDefault(); - - // and execute the function - return args[ lastToggle ].apply( this, arguments ) || false; - })); + return this.click( toggler ); }, hover: function( fnOver, fnOut ) { @@ -3157,8 +3558,16 @@ jQuery.each(["live", "die"], function( i, name ) { return this; } - if ( jQuery.isFunction( data ) ) { - fn = data; + if ( name === "die" && !types && + origSelector && origSelector.charAt(0) === "." ) { + + context.unbind( origSelector ); + + return this; + } + + if ( data === false || jQuery.isFunction( data ) ) { + fn = data || returnFalse; data = undefined; } @@ -3180,7 +3589,7 @@ jQuery.each(["live", "die"], function( i, name ) { preType = type; - if ( type === "focus" || type === "blur" ) { + if ( liveMap[ type ] ) { types.push( liveMap[ type ] + namespaces ); type = type + namespaces; @@ -3251,6 +3660,11 @@ function liveHandler( event ) { if ( handleObj.preType === "mouseenter" || handleObj.preType === "mouseleave" ) { event.type = handleObj.preType; related = jQuery( event.relatedTarget ).closest( handleObj.selector )[0]; + + // Make sure not to accidentally match a child element with the same selector + if ( related && jQuery.contains( elem, related ) ) { + related = elem; + } } if ( !related || related !== elem ) { @@ -3289,7 +3703,7 @@ function liveHandler( event ) { } function liveConvert( type, selector ) { - return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspace, "&"); + return (type && type !== "*" ? type + "." : "") + selector.replace(rperiod, "`").replace(rspaces, "&"); } jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblclick " + @@ -3314,6 +3728,7 @@ jQuery.each( ("blur focus focusin focusout load resize scroll unload click dblcl }); + /*! * Sizzle CSS Selector Engine * Copyright 2011, The Dojo Foundation @@ -3941,42 +4356,50 @@ var Expr = Sizzle.selectors = { var attr = elem.getAttribute( "type" ), type = elem.type; // IE6 and 7 will map elem.type to 'text' for new HTML5 types (search, etc) // use getAttribute instead to test this case - return "text" === type && ( attr === type || attr === null ); + return elem.nodeName.toLowerCase() === "input" && "text" === type && ( attr === type || attr === null ); }, radio: function( elem ) { - return "radio" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "radio" === elem.type; }, checkbox: function( elem ) { - return "checkbox" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "checkbox" === elem.type; }, file: function( elem ) { - return "file" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "file" === elem.type; }, + password: function( elem ) { - return "password" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "password" === elem.type; }, submit: function( elem ) { - return "submit" === elem.type; + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "submit" === elem.type; }, image: function( elem ) { - return "image" === elem.type; + return elem.nodeName.toLowerCase() === "input" && "image" === elem.type; }, reset: function( elem ) { - return "reset" === elem.type; + var name = elem.nodeName.toLowerCase(); + return (name === "input" || name === "button") && "reset" === elem.type; }, button: function( elem ) { - return "button" === elem.type || elem.nodeName.toLowerCase() === "button"; + var name = elem.nodeName.toLowerCase(); + return name === "input" && "button" === elem.type || name === "button"; }, input: function( elem ) { return (/input|select|textarea|button/i).test( elem.nodeName ); + }, + + focus: function( elem ) { + return elem === elem.ownerDocument.activeElement; } }, setFilters: { @@ -4229,6 +4652,16 @@ if ( document.documentElement.compareDocumentPosition ) { } else { sortOrder = function( a, b ) { + // The nodes are identical, we can exit early + if ( a === b ) { + hasDuplicate = true; + return 0; + + // Fallback to using sourceIndex (in IE) if it's available on both nodes + } else if ( a.sourceIndex && b.sourceIndex ) { + return a.sourceIndex - b.sourceIndex; + } + var al, bl, ap = [], bp = [], @@ -4236,13 +4669,8 @@ if ( document.documentElement.compareDocumentPosition ) { bup = b.parentNode, cur = aup; - // The nodes are identical, we can exit early - if ( a === b ) { - hasDuplicate = true; - return 0; - // If the nodes are siblings (or identical) we can do a quick check - } else if ( aup === bup ) { + if ( aup === bup ) { return siblingCheck( a, b ); // If no parents were found then the nodes are disconnected @@ -4739,17 +5167,30 @@ var runtil = /Until$/, jQuery.fn.extend({ find: function( selector ) { - var ret = this.pushStack( "", "find", selector ), - length = 0; + var self = this, + i, l; - for ( var i = 0, l = this.length; i < l; i++ ) { + if ( typeof selector !== "string" ) { + return jQuery( selector ).filter(function() { + for ( i = 0, l = self.length; i < l; i++ ) { + if ( jQuery.contains( self[ i ], this ) ) { + return true; + } + } + }); + } + + var ret = this.pushStack( "", "find", selector ), + length, n, r; + + for ( i = 0, l = this.length; i < l; i++ ) { length = ret.length; jQuery.find( selector, this[i], ret ); if ( i > 0 ) { // Make sure that the results are unique - for ( var n = length; n < ret.length; n++ ) { - for ( var r = 0; r < length; r++ ) { + for ( n = length; n < ret.length; n++ ) { + for ( r = 0; r < length; r++ ) { if ( ret[r] === ret[n] ) { ret.splice(n--, 1); break; @@ -4782,12 +5223,15 @@ jQuery.fn.extend({ }, is: function( selector ) { - return !!selector && jQuery.filter( selector, this ).length > 0; + return !!selector && ( typeof selector === "string" ? + jQuery.filter( selector, this ).length > 0 : + this.filter( selector ).length > 0 ); }, closest: function( selectors, context ) { var ret = [], i, l, cur = this[0]; - + + // Array if ( jQuery.isArray( selectors ) ) { var match, selector, matches = {}, @@ -4797,8 +5241,8 @@ jQuery.fn.extend({ for ( i = 0, l = selectors.length; i < l; i++ ) { selector = selectors[i]; - if ( !matches[selector] ) { - matches[selector] = jQuery.expr.match.POS.test( selector ) ? + if ( !matches[ selector ] ) { + matches[ selector ] = POS.test( selector ) ? jQuery( selector, context || this.context ) : selector; } @@ -4806,9 +5250,9 @@ jQuery.fn.extend({ while ( cur && cur.ownerDocument && cur !== context ) { for ( selector in matches ) { - match = matches[selector]; + match = matches[ selector ]; - if ( match.jquery ? match.index(cur) > -1 : jQuery(cur).is(match) ) { + if ( match.jquery ? match.index( cur ) > -1 : jQuery( cur ).is( match ) ) { ret.push({ selector: selector, elem: cur, level: level }); } } @@ -4821,8 +5265,10 @@ jQuery.fn.extend({ return ret; } - var pos = POS.test( selectors ) ? - jQuery( selectors, context || this.context ) : null; + // String + var pos = POS.test( selectors ) || typeof selectors !== "string" ? + jQuery( selectors, context || this.context ) : + 0; for ( i = 0, l = this.length; i < l; i++ ) { cur = this[i]; @@ -4834,14 +5280,14 @@ jQuery.fn.extend({ } else { cur = cur.parentNode; - if ( !cur || !cur.ownerDocument || cur === context ) { + if ( !cur || !cur.ownerDocument || cur === context || cur.nodeType === 11 ) { break; } } } } - ret = ret.length > 1 ? jQuery.unique(ret) : ret; + ret = ret.length > 1 ? jQuery.unique( ret ) : ret; return this.pushStack( ret, "closest", selectors ); }, @@ -4864,7 +5310,7 @@ jQuery.fn.extend({ add: function( selector, context ) { var set = typeof selector === "string" ? jQuery( selector, context ) : - jQuery.makeArray( selector ), + jQuery.makeArray( selector && selector.nodeType ? [ selector ] : selector ), all = jQuery.merge( this.get(), set ); return this.pushStack( isDisconnected( set[0] ) || isDisconnected( all[0] ) ? @@ -5002,6 +5448,11 @@ jQuery.extend({ // Implement the identical functionality for filter and not function winnow( elements, qualifier, keep ) { + + // Can't pass null or undefined to indexOf in Firefox 4 + // Set to 0 to skip string check + qualifier = qualifier || 0; + if ( jQuery.isFunction( qualifier ) ) { return jQuery.grep(elements, function( elem, i ) { var retVal = !!qualifier.call( elem, i, elem ); @@ -5042,6 +5493,8 @@ var rinlinejQuery = / jQuery\d+="(?:\d+|null)"/g, rnocache = /<(?:script|object|embed|option|style)/i, // checked="checked" or checked rchecked = /checked\s*(?:[^=]|=\s*.checked.)/i, + rscriptType = /\/(java|ecma)script/i, + rcleanScript = /^\s*", "" ], legend: [ 1, "
", "
" ], @@ -5102,7 +5555,7 @@ jQuery.fn.extend({ } return elem; - }).append(this); + }).append( this ); } return this; @@ -5410,21 +5863,27 @@ function cloneCopyEvent( src, dest ) { } } -function cloneFixAttributes(src, dest) { +function cloneFixAttributes( src, dest ) { + var nodeName; + // We do not need to do anything for non-Elements if ( dest.nodeType !== 1 ) { return; } - var nodeName = dest.nodeName.toLowerCase(); - // clearAttributes removes the attributes, which we don't want, // but also removes the attachEvent events, which we *do* want - dest.clearAttributes(); + if ( dest.clearAttributes ) { + dest.clearAttributes(); + } // mergeAttributes, in contrast, only merges back on the // original attributes, not the events - dest.mergeAttributes(src); + if ( dest.mergeAttributes ) { + dest.mergeAttributes( src ); + } + + nodeName = dest.nodeName.toLowerCase(); // IE6-8 fail to clone children inside object elements that use // the proprietary classid attribute value (rather than the type @@ -5463,8 +5922,21 @@ function cloneFixAttributes(src, dest) { } jQuery.buildFragment = function( args, nodes, scripts ) { - var fragment, cacheable, cacheresults, - doc = (nodes && nodes[0] ? nodes[0].ownerDocument || nodes[0] : document); + var fragment, cacheable, cacheresults, doc; + + // nodes may contain either an explicit document object, + // a jQuery collection or context object. + // If nodes[0] contains a valid object to assign to doc + if ( nodes && nodes[0] ) { + doc = nodes[0].ownerDocument || nodes[0]; + } + + // Ensure that an attr object doesn't incorrectly stand in as a document object + // Chrome and Firefox seem to allow this to occur and will throw exception + // Fixes #8950 + if ( !doc.createDocumentFragment ) { + doc = document; + } // Only cache "small" (1/2 KB) HTML strings that are associated with the main document // Cloning options loses the selected state, so don't cache them @@ -5474,11 +5946,10 @@ jQuery.buildFragment = function( args, nodes, scripts ) { args[0].charAt(0) === "<" && !rnocache.test( args[0] ) && (jQuery.support.checkClone || !rchecked.test( args[0] )) ) { cacheable = true; + cacheresults = jQuery.fragments[ args[0] ]; - if ( cacheresults ) { - if ( cacheresults !== 1 ) { - fragment = cacheresults; - } + if ( cacheresults && cacheresults !== 1 ) { + fragment = cacheresults; } } @@ -5527,7 +5998,7 @@ jQuery.each({ function getAll( elem ) { if ( "getElementsByTagName" in elem ) { return elem.getElementsByTagName( "*" ); - + } else if ( "querySelectorAll" in elem ) { return elem.querySelectorAll( "*" ); @@ -5536,6 +6007,21 @@ function getAll( elem ) { } } +// Used in clean, fixes the defaultChecked property +function fixDefaultChecked( elem ) { + if ( elem.type === "checkbox" || elem.type === "radio" ) { + elem.defaultChecked = elem.checked; + } +} +// Finds all inputs and passes them to fixDefaultChecked +function findInputs( elem ) { + if ( jQuery.nodeName( elem, "input" ) ) { + fixDefaultChecked( elem ); + } else if ( "getElementsByTagName" in elem ) { + jQuery.grep( elem.getElementsByTagName("input"), fixDefaultChecked ); + } +} + jQuery.extend({ clone: function( elem, dataAndEvents, deepDataAndEvents ) { var clone = elem.cloneNode(true), @@ -5580,10 +6066,15 @@ jQuery.extend({ } } + srcElements = destElements = null; + // Return the cloned set return clone; -}, + }, + clean: function( elems, context, fragment, scripts ) { + var checkScriptType; + context = context || document; // !context.createElement fails in IE with an error but returns typeof 'object' @@ -5591,7 +6082,7 @@ jQuery.extend({ context = context.ownerDocument || context[0] && context[0].ownerDocument || document; } - var ret = []; + var ret = [], j; for ( var i = 0, elem; (elem = elems[i]) != null; i++ ) { if ( typeof elem === "number" ) { @@ -5603,54 +6094,67 @@ jQuery.extend({ } // Convert html string into DOM nodes - if ( typeof elem === "string" && !rhtml.test( elem ) ) { - elem = context.createTextNode( elem ); + if ( typeof elem === "string" ) { + if ( !rhtml.test( elem ) ) { + elem = context.createTextNode( elem ); + } else { + // Fix "XHTML"-style tags in all browsers + elem = elem.replace(rxhtmlTag, "<$1>"); - } else if ( typeof elem === "string" ) { - // Fix "XHTML"-style tags in all browsers - elem = elem.replace(rxhtmlTag, "<$1>"); + // Trim whitespace, otherwise indexOf won't work as expected + var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), + wrap = wrapMap[ tag ] || wrapMap._default, + depth = wrap[0], + div = context.createElement("div"); - // Trim whitespace, otherwise indexOf won't work as expected - var tag = (rtagName.exec( elem ) || ["", ""])[1].toLowerCase(), - wrap = wrapMap[ tag ] || wrapMap._default, - depth = wrap[0], - div = context.createElement("div"); + // Go to html and back, then peel off extra wrappers + div.innerHTML = wrap[1] + elem + wrap[2]; - // Go to html and back, then peel off extra wrappers - div.innerHTML = wrap[1] + elem + wrap[2]; + // Move to the right depth + while ( depth-- ) { + div = div.lastChild; + } - // Move to the right depth - while ( depth-- ) { - div = div.lastChild; - } + // Remove IE's autoinserted from table fragments + if ( !jQuery.support.tbody ) { - // Remove IE's autoinserted from table fragments - if ( !jQuery.support.tbody ) { + // String was a , *may* have spurious + var hasBody = rtbody.test(elem), + tbody = tag === "table" && !hasBody ? + div.firstChild && div.firstChild.childNodes : - // String was a
, *may* have spurious - var hasBody = rtbody.test(elem), - tbody = tag === "table" && !hasBody ? - div.firstChild && div.firstChild.childNodes : + // String was a bare or + wrap[1] === "
" && !hasBody ? + div.childNodes : + []; - // String was a bare or - wrap[1] === "
" && !hasBody ? - div.childNodes : - []; - - for ( var j = tbody.length - 1; j >= 0 ; --j ) { - if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { - tbody[ j ].parentNode.removeChild( tbody[ j ] ); + for ( j = tbody.length - 1; j >= 0 ; --j ) { + if ( jQuery.nodeName( tbody[ j ], "tbody" ) && !tbody[ j ].childNodes.length ) { + tbody[ j ].parentNode.removeChild( tbody[ j ] ); + } } } - } + // IE completely kills leading whitespace when innerHTML is used + if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { + div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + } - // IE completely kills leading whitespace when innerHTML is used - if ( !jQuery.support.leadingWhitespace && rleadingWhitespace.test( elem ) ) { - div.insertBefore( context.createTextNode( rleadingWhitespace.exec(elem)[0] ), div.firstChild ); + elem = div.childNodes; } + } - elem = div.childNodes; + // Resets defaultChecked for any radios and checkboxes + // about to be appended to the DOM in IE 6/7 (#8060) + var len; + if ( !jQuery.support.appendChecked ) { + if ( elem[0] && typeof (len = elem.length) === "number" ) { + for ( j = 0; j < len; j++ ) { + findInputs( elem[j] ); + } + } else { + findInputs( elem ); + } } if ( elem.nodeType ) { @@ -5661,13 +6165,18 @@ jQuery.extend({ } if ( fragment ) { + checkScriptType = function( elem ) { + return !elem.type || rscriptType.test( elem.type ); + }; for ( i = 0; ret[i]; i++ ) { if ( scripts && jQuery.nodeName( ret[i], "script" ) && (!ret[i].type || ret[i].type.toLowerCase() === "text/javascript") ) { scripts.push( ret[i].parentNode ? ret[i].parentNode.removeChild( ret[i] ) : ret[i] ); } else { if ( ret[i].nodeType === 1 ) { - ret.splice.apply( ret, [i + 1, 0].concat(jQuery.makeArray(ret[i].getElementsByTagName("script"))) ); + var jsTags = jQuery.grep( ret[i].getElementsByTagName( "script" ), checkScriptType ); + + ret.splice.apply( ret, [i + 1, 0].concat( jsTags ) ); } fragment.appendChild( ret[i] ); } @@ -5729,7 +6238,7 @@ function evalScript( i, elem ) { dataType: "script" }); } else { - jQuery.globalEval( elem.text || elem.textContent || elem.innerHTML || "" ); + jQuery.globalEval( ( elem.text || elem.textContent || elem.innerHTML || "" ).replace( rcleanScript, "/*$0*/" ) ); } if ( elem.parentNode ) { @@ -5739,14 +6248,14 @@ function evalScript( i, elem ) { - var ralpha = /alpha\([^)]*\)/i, ropacity = /opacity=([^)]*)/, - rdashAlpha = /-([a-z])/ig, // fixed for IE9, see #8346 rupper = /([A-Z]|^ms)/g, rnumpx = /^-?\d+(?:px)?$/i, rnum = /^-?\d/, + rrelNum = /^[+\-]=/, + rrelNumFilter = /[^+\-\.\de]+/g, cssShow = { position: "absolute", visibility: "hidden", display: "block" }, cssWidth = [ "Left", "Right" ], @@ -5754,11 +6263,7 @@ var ralpha = /alpha\([^)]*\)/i, curCSS, getComputedStyle, - currentStyle, - - fcamelCase = function( all, letter ) { - return letter.toUpperCase(); - }; + currentStyle; jQuery.fn.css = function( name, value ) { // Setting 'undefined' is a no-op @@ -5793,11 +6298,14 @@ jQuery.extend({ // Exclude the following css properties to add px cssNumber: { - "zIndex": true, + "fillOpacity": true, "fontWeight": true, + "lineHeight": true, "opacity": true, - "zoom": true, - "lineHeight": true + "orphans": true, + "widows": true, + "zIndex": true, + "zoom": true }, // Add in properties whose names you wish to fix before @@ -5815,20 +6323,29 @@ jQuery.extend({ } // Make sure that we're working with the right name - var ret, origName = jQuery.camelCase( name ), + var ret, type, origName = jQuery.camelCase( name ), style = elem.style, hooks = jQuery.cssHooks[ origName ]; name = jQuery.cssProps[ origName ] || origName; // Check if we're setting a value if ( value !== undefined ) { + type = typeof value; + // Make sure that NaN and null values aren't set. See: #7116 - if ( typeof value === "number" && isNaN( value ) || value == null ) { + if ( type === "number" && isNaN( value ) || value == null ) { return; } + // convert relative number strings (+= or -=) to relative numbers. #7345 + if ( type === "string" && rrelNum.test( value ) ) { + value = +value.replace( rrelNumFilter, "" ) + parseFloat( jQuery.css( elem, name ) ); + // Fixes bug #9237 + type = "number"; + } + // If a number was passed in, add 'px' to the (except for certain CSS properties) - if ( typeof value === "number" && !jQuery.cssNumber[ origName ] ) { + if ( type === "number" && !jQuery.cssNumber[ origName ] ) { value += "px"; } @@ -5853,11 +6370,17 @@ jQuery.extend({ }, css: function( elem, name, extra ) { - // Make sure that we're working with the right name - var ret, origName = jQuery.camelCase( name ), - hooks = jQuery.cssHooks[ origName ]; + var ret, hooks; - name = jQuery.cssProps[ origName ] || origName; + // Make sure that we're working with the right name + name = jQuery.camelCase( name ); + hooks = jQuery.cssHooks[ name ]; + name = jQuery.cssProps[ name ] || name; + + // cssFloat needs a special treatment + if ( name === "cssFloat" ) { + name = "float"; + } // If a hook was provided get the computed value from there if ( hooks && "get" in hooks && (ret = hooks.get( elem, true, extra )) !== undefined ) { @@ -5865,7 +6388,7 @@ jQuery.extend({ // Otherwise, if a way to get the computed value exists, use that } else if ( curCSS ) { - return curCSS( elem, name, origName ); + return curCSS( elem, name ); } }, @@ -5885,10 +6408,6 @@ jQuery.extend({ for ( name in options ) { elem.style[ name ] = old[ name ]; } - }, - - camelCase: function( string ) { - return string.replace( rdashAlpha, fcamelCase ); } }); @@ -5902,44 +6421,21 @@ jQuery.each(["height", "width"], function( i, name ) { if ( computed ) { if ( elem.offsetWidth !== 0 ) { - val = getWH( elem, name, extra ); - + return getWH( elem, name, extra ); } else { jQuery.swap( elem, cssShow, function() { val = getWH( elem, name, extra ); }); } - if ( val <= 0 ) { - val = curCSS( elem, name, name ); - - if ( val === "0px" && currentStyle ) { - val = currentStyle( elem, name, name ); - } - - if ( val != null ) { - // Should return "auto" instead of 0, use 0 for - // temporary backwards-compat - return val === "" || val === "auto" ? "0px" : val; - } - } - - if ( val < 0 || val == null ) { - val = elem.style[ name ]; - - // Should return "auto" instead of 0, use 0 for - // temporary backwards-compat - return val === "" || val === "auto" ? "0px" : val; - } - - return typeof val === "string" ? val : val + "px"; + return val; } }, set: function( elem, value ) { if ( rnumpx.test( value ) ) { // ignore negative width and height values #1599 - value = parseFloat(value); + value = parseFloat( value ); if ( value >= 0 ) { return value + "px"; @@ -5956,27 +6452,28 @@ if ( !jQuery.support.opacity ) { jQuery.cssHooks.opacity = { get: function( elem, computed ) { // IE uses filters for opacity - return ropacity.test((computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "") ? - (parseFloat(RegExp.$1) / 100) + "" : + return ropacity.test( (computed && elem.currentStyle ? elem.currentStyle.filter : elem.style.filter) || "" ) ? + ( parseFloat( RegExp.$1 ) / 100 ) + "" : computed ? "1" : ""; }, set: function( elem, value ) { - var style = elem.style; + var style = elem.style, + currentStyle = elem.currentStyle; // IE has trouble with opacity if it does not have layout // Force it by setting the zoom level style.zoom = 1; // Set the alpha filter to set the opacity - var opacity = jQuery.isNaN(value) ? + var opacity = jQuery.isNaN( value ) ? "" : "alpha(opacity=" + value * 100 + ")", - filter = style.filter || ""; + filter = currentStyle && currentStyle.filter || style.filter || ""; - style.filter = ralpha.test(filter) ? - filter.replace(ralpha, opacity) : - style.filter + ' ' + opacity; + style.filter = ralpha.test( filter ) ? + filter.replace( ralpha, opacity ) : + filter + " " + opacity; } }; } @@ -6004,7 +6501,7 @@ jQuery(function() { }); if ( document.defaultView && document.defaultView.getComputedStyle ) { - getComputedStyle = function( elem, newName, name ) { + getComputedStyle = function( elem, name ) { var ret, defaultView, computedStyle; name = name.replace( rupper, "-$1" ).toLowerCase(); @@ -6061,27 +6558,50 @@ if ( document.documentElement.currentStyle ) { curCSS = getComputedStyle || currentStyle; function getWH( elem, name, extra ) { - var which = name === "width" ? cssWidth : cssHeight, - val = name === "width" ? elem.offsetWidth : elem.offsetHeight; - if ( extra === "border" ) { - return val; + // Start with offset property + var val = name === "width" ? elem.offsetWidth : elem.offsetHeight, + which = name === "width" ? cssWidth : cssHeight; + + if ( val > 0 ) { + if ( extra !== "border" ) { + jQuery.each( which, function() { + if ( !extra ) { + val -= parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } else { + val -= parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + }); + } + + return val + "px"; } - jQuery.each( which, function() { - if ( !extra ) { - val -= parseFloat(jQuery.css( elem, "padding" + this )) || 0; - } + // Fall back to computed then uncomputed css if necessary + val = curCSS( elem, name, name ); + if ( val < 0 || val == null ) { + val = elem.style[ name ] || 0; + } + // Normalize "", auto, and prepare for extra + val = parseFloat( val ) || 0; - if ( extra === "margin" ) { - val += parseFloat(jQuery.css( elem, "margin" + this )) || 0; + // Add padding, border, margin + if ( extra ) { + jQuery.each( which, function() { + val += parseFloat( jQuery.css( elem, "padding" + this ) ) || 0; + if ( extra !== "padding" ) { + val += parseFloat( jQuery.css( elem, "border" + this + "Width" ) ) || 0; + } + if ( extra === "margin" ) { + val += parseFloat( jQuery.css( elem, extra + this ) ) || 0; + } + }); + } - } else { - val -= parseFloat(jQuery.css( elem, "border" + this + "Width" )) || 0; - } - }); - - return val; + return val + "px"; } if ( jQuery.expr && jQuery.expr.filters ) { @@ -6115,10 +6635,6 @@ var r20 = /%20/g, rselectTextarea = /^(?:select|textarea)/i, rspacesAjax = /\s+/, rts = /([?&])_=[^&]*/, - rucHeaders = /(^|\-)([a-z])/g, - rucHeadersFunc = function( _, $1, $2 ) { - return $1 + $2.toUpperCase(); - }, rurl = /^([\w\+\.\-]+:)(?:\/\/([^\/?#:]*)(?::(\d+))?)?/, // Keep a copy of the old load method @@ -6149,9 +6665,9 @@ var r20 = /%20/g, ajaxLocParts; // #8138, IE may throw an exception when accessing -// a field from document.location if document.domain has been set +// a field from window.location if document.domain has been set try { - ajaxLocation = document.location.href; + ajaxLocation = location.href; } catch( e ) { // Use the href attribute of an A element // since IE will modify it given document.location @@ -6199,7 +6715,7 @@ function addToPrefiltersOrTransports( structure ) { }; } -//Base inspection function for prefilters and transports +// Base inspection function for prefilters and transports function inspectPrefiltersOrTransports( structure, options, originalOptions, jqXHR, dataType /* internal */, inspected /* internal */ ) { @@ -6348,7 +6864,7 @@ jQuery.each( "ajaxStart ajaxStop ajaxComplete ajaxError ajaxSuccess ajaxSend".sp jQuery.fn[ o ] = function( f ){ return this.bind( o, f ); }; -} ); +}); jQuery.each( [ "get", "post" ], function( i, method ) { jQuery[ method ] = function( url, data, callback, type ) { @@ -6367,7 +6883,7 @@ jQuery.each( [ "get", "post" ], function( i, method ) { dataType: type }); }; -} ); +}); jQuery.extend({ @@ -6493,6 +7009,7 @@ jQuery.extend({ ifModifiedKey, // Headers (they are sent all at once) requestHeaders = {}, + requestHeadersNames = {}, // Response headers responseHeadersString, responseHeaders, @@ -6516,7 +7033,9 @@ jQuery.extend({ // Caches the header setRequestHeader: function( name, value ) { if ( !state ) { - requestHeaders[ name.toLowerCase().replace( rucHeaders, rucHeadersFunc ) ] = value; + var lname = name.toLowerCase(); + name = requestHeadersNames[ lname ] = requestHeadersNames[ lname ] || name; + requestHeaders[ name ] = value; } return this; }, @@ -6764,24 +7283,27 @@ jQuery.extend({ // Set the correct header, if data is being sent if ( s.data && s.hasContent && s.contentType !== false || options.contentType ) { - requestHeaders[ "Content-Type" ] = s.contentType; + jqXHR.setRequestHeader( "Content-Type", s.contentType ); } // Set the If-Modified-Since and/or If-None-Match header, if in ifModified mode. if ( s.ifModified ) { ifModifiedKey = ifModifiedKey || s.url; if ( jQuery.lastModified[ ifModifiedKey ] ) { - requestHeaders[ "If-Modified-Since" ] = jQuery.lastModified[ ifModifiedKey ]; + jqXHR.setRequestHeader( "If-Modified-Since", jQuery.lastModified[ ifModifiedKey ] ); } if ( jQuery.etag[ ifModifiedKey ] ) { - requestHeaders[ "If-None-Match" ] = jQuery.etag[ ifModifiedKey ]; + jqXHR.setRequestHeader( "If-None-Match", jQuery.etag[ ifModifiedKey ] ); } } // Set the Accepts header for the server, depending on the dataType - requestHeaders.Accept = s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? - s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : - s.accepts[ "*" ]; + jqXHR.setRequestHeader( + "Accept", + s.dataTypes[ 0 ] && s.accepts[ s.dataTypes[0] ] ? + s.accepts[ s.dataTypes[0] ] + ( s.dataTypes[ 0 ] !== "*" ? ", */*; q=0.01" : "" ) : + s.accepts[ "*" ] + ); // Check for headers option for ( i in s.headers ) { @@ -6857,7 +7379,7 @@ jQuery.extend({ // Serialize the form elements jQuery.each( a, function() { add( this.name, this.value ); - } ); + }); } else { // If traditional, encode the "old" way (the way 1.3.2 or older @@ -6873,7 +7395,7 @@ jQuery.extend({ }); function buildParams( prefix, obj, traditional, add ) { - if ( jQuery.isArray( obj ) && obj.length ) { + if ( jQuery.isArray( obj ) ) { // Serialize array item. jQuery.each( obj, function( i, v ) { if ( traditional || rbracket.test( prefix ) ) { @@ -6893,16 +7415,9 @@ function buildParams( prefix, obj, traditional, add ) { }); } else if ( !traditional && obj != null && typeof obj === "object" ) { - // If we see an array here, it is empty and should be treated as an empty - // object - if ( jQuery.isArray( obj ) || jQuery.isEmptyObject( obj ) ) { - add( prefix, "" ); - // Serialize object item. - } else { - for ( var name in obj ) { - buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); - } + for ( var name in obj ) { + buildParams( prefix + "[" + name + "]", obj[ name ], traditional, add ); } } else { @@ -7095,13 +7610,12 @@ jQuery.ajaxSetup({ // Detect, normalize options and install callbacks for jsonp requests jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { - var dataIsString = ( typeof s.data === "string" ); + var inspectData = s.contentType === "application/x-www-form-urlencoded" && + ( typeof s.data === "string" ); if ( s.dataTypes[ 0 ] === "jsonp" || - originalSettings.jsonpCallback || - originalSettings.jsonp != null || s.jsonp !== false && ( jsre.test( s.url ) || - dataIsString && jsre.test( s.data ) ) ) { + inspectData && jsre.test( s.data ) ) ) { var responseContainer, jsonpCallback = s.jsonpCallback = @@ -7109,20 +7623,12 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { previous = window[ jsonpCallback ], url = s.url, data = s.data, - replace = "$1" + jsonpCallback + "$2", - cleanUp = function() { - // Set callback back to previous value - window[ jsonpCallback ] = previous; - // Call if it was a function and we have a response - if ( responseContainer && jQuery.isFunction( previous ) ) { - window[ jsonpCallback ]( responseContainer[ 0 ] ); - } - }; + replace = "$1" + jsonpCallback + "$2"; if ( s.jsonp !== false ) { url = url.replace( jsre, replace ); if ( s.url === url ) { - if ( dataIsString ) { + if ( inspectData ) { data = data.replace( jsre, replace ); } if ( s.data === data ) { @@ -7140,8 +7646,15 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { responseContainer = [ response ]; }; - // Install cleanUp function - jqXHR.then( cleanUp, cleanUp ); + // Clean-up function + jqXHR.always(function() { + // Set callback back to previous value + window[ jsonpCallback ] = previous; + // Call if it was a function and we have a response + if ( responseContainer && jQuery.isFunction( previous ) ) { + window[ jsonpCallback ]( responseContainer[ 0 ] ); + } + }); // Use data converter to retrieve json after script execution s.converters["script json"] = function() { @@ -7157,7 +7670,7 @@ jQuery.ajaxPrefilter( "json jsonp", function( s, originalSettings, jqXHR ) { // Delegate to script return "script"; } -} ); +}); @@ -7187,7 +7700,7 @@ jQuery.ajaxPrefilter( "script", function( s ) { s.type = "GET"; s.global = false; } -} ); +}); // Bind script tag hack transport jQuery.ajaxTransport( "script", function(s) { @@ -7215,7 +7728,7 @@ jQuery.ajaxTransport( "script", function(s) { // Attach handlers for all browsers script.onload = script.onreadystatechange = function( _, isAbort ) { - if ( !script.readyState || /loaded|complete/.test( script.readyState ) ) { + if ( isAbort || !script.readyState || /loaded|complete/.test( script.readyState ) ) { // Handle memory leak in IE script.onload = script.onreadystatechange = null; @@ -7246,27 +7759,20 @@ jQuery.ajaxTransport( "script", function(s) { } }; } -} ); +}); -var // #5280: next active xhr id and list of active xhrs' callbacks - xhrId = jQuery.now(), - xhrCallbacks, - - // XHR used to determine supports properties - testXHR; - -// #5280: Internet Explorer will keep connections alive if we don't abort on unload -function xhrOnUnloadAbort() { - jQuery( window ).unload(function() { +var // #5280: Internet Explorer will keep connections alive if we don't abort on unload + xhrOnUnloadAbort = window.ActiveXObject ? function() { // Abort all pending requests for ( var key in xhrCallbacks ) { xhrCallbacks[ key ]( 0, 1 ); } - }); -} + } : false, + xhrId = 0, + xhrCallbacks; // Functions to create xhrs function createStandardXHR() { @@ -7296,15 +7802,13 @@ jQuery.ajaxSettings.xhr = window.ActiveXObject ? // For all other browsers, use the standard XMLHttpRequest object createStandardXHR; -// Test if we can create an xhr object -testXHR = jQuery.ajaxSettings.xhr(); -jQuery.support.ajax = !!testXHR; - -// Does this browser support crossDomain XHR requests -jQuery.support.cors = testXHR && ( "withCredentials" in testXHR ); - -// No need for the temporary xhr anymore -testXHR = undefined; +// Determine support properties +(function( xhr ) { + jQuery.extend( jQuery.support, { + ajax: !!xhr, + cors: !!xhr && ( "withCredentials" in xhr ) + }); +})( jQuery.ajaxSettings.xhr() ); // Create transport if the browser can provide an xhr if ( jQuery.support.ajax ) { @@ -7387,7 +7891,9 @@ if ( jQuery.support.ajax ) { // Do not keep as active anymore if ( handle ) { xhr.onreadystatechange = jQuery.noop; - delete xhrCallbacks[ handle ]; + if ( xhrOnUnloadAbort ) { + delete xhrCallbacks[ handle ]; + } } // If it's an abort @@ -7448,15 +7954,18 @@ if ( jQuery.support.ajax ) { if ( !s.async || xhr.readyState === 4 ) { callback(); } else { - // Create the active xhrs callbacks list if needed - // and attach the unload handler - if ( !xhrCallbacks ) { - xhrCallbacks = {}; - xhrOnUnloadAbort(); + handle = ++xhrId; + if ( xhrOnUnloadAbort ) { + // Create the active xhrs callbacks list if needed + // and attach the unload handler + if ( !xhrCallbacks ) { + xhrCallbacks = {}; + jQuery( window ).unload( xhrOnUnloadAbort ); + } + // Add to list of active xhrs callbacks + xhrCallbacks[ handle ] = callback; } - // Add to list of active xhrs callbacks - handle = xhrId++; - xhr.onreadystatechange = xhrCallbacks[ handle ] = callback; + xhr.onreadystatechange = callback; } }, @@ -7474,6 +7983,7 @@ if ( jQuery.support.ajax ) { var elemdisplay = {}, + iframe, iframeDoc, rfxtypes = /^(?:toggle|show|hide)$/, rfxnum = /^([+\-]=)?([\d+.\-]+)([a-z%]*)$/i, timerId, @@ -7484,7 +7994,11 @@ var elemdisplay = {}, [ "width", "marginLeft", "marginRight", "paddingLeft", "paddingRight" ], // opacity animations [ "opacity" ] - ]; + ], + fxNow, + requestAnimationFrame = window.webkitRequestAnimationFrame || + window.mozRequestAnimationFrame || + window.oRequestAnimationFrame; jQuery.fn.extend({ show: function( speed, easing, callback ) { @@ -7496,19 +8010,22 @@ jQuery.fn.extend({ } else { for ( var i = 0, j = this.length; i < j; i++ ) { elem = this[i]; - display = elem.style.display; - // Reset the inline display of this element to learn if it is - // being hidden by cascaded rules or not - if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { - display = elem.style.display = ""; - } + if ( elem.style ) { + display = elem.style.display; - // Set elements which have been overridden with display: none - // in a stylesheet to whatever the default browser style is - // for such an element - if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { - jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); + // Reset the inline display of this element to learn if it is + // being hidden by cascaded rules or not + if ( !jQuery._data(elem, "olddisplay") && display === "none" ) { + display = elem.style.display = ""; + } + + // Set elements which have been overridden with display: none + // in a stylesheet to whatever the default browser style is + // for such an element + if ( display === "" && jQuery.css( elem, "display" ) === "none" ) { + jQuery._data(elem, "olddisplay", defaultDisplay(elem.nodeName)); + } } } @@ -7516,10 +8033,13 @@ jQuery.fn.extend({ // to avoid the constant reflow for ( i = 0; i < j; i++ ) { elem = this[i]; - display = elem.style.display; - if ( display === "" || display === "none" ) { - elem.style.display = jQuery._data(elem, "olddisplay") || ""; + if ( elem.style ) { + display = elem.style.display; + + if ( display === "" || display === "none" ) { + elem.style.display = jQuery._data(elem, "olddisplay") || ""; + } } } @@ -7533,17 +8053,21 @@ jQuery.fn.extend({ } else { for ( var i = 0, j = this.length; i < j; i++ ) { - var display = jQuery.css( this[i], "display" ); + if ( this[i].style ) { + var display = jQuery.css( this[i], "display" ); - if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { - jQuery._data( this[i], "olddisplay", display ); + if ( display !== "none" && !jQuery._data( this[i], "olddisplay" ) ) { + jQuery._data( this[i], "olddisplay", display ); + } } } // Set the display of the elements in a second loop // to avoid the constant reflow for ( i = 0; i < j; i++ ) { - this[i].style.display = "none"; + if ( this[i].style ) { + this[i].style.display = "none"; + } } return this; @@ -7581,32 +8105,54 @@ jQuery.fn.extend({ var optall = jQuery.speed(speed, easing, callback); if ( jQuery.isEmptyObject( prop ) ) { - return this.each( optall.complete ); + return this.each( optall.complete, [ false ] ); } + // Do not change referenced properties as per-property easing will be lost + prop = jQuery.extend( {}, prop ); + return this[ optall.queue === false ? "each" : "queue" ](function() { // XXX 'this' does not always have a nodeName when running the // test suite - var opt = jQuery.extend({}, optall), p, + if ( optall.queue === false ) { + jQuery._mark( this ); + } + + var opt = jQuery.extend( {}, optall ), isElement = this.nodeType === 1, hidden = isElement && jQuery(this).is(":hidden"), - self = this; + name, val, p, + display, e, + parts, start, end, unit; + + // will store per property easing and be used to determine when an animation is complete + opt.animatedProperties = {}; for ( p in prop ) { - var name = jQuery.camelCase( p ); + // property name normalization + name = jQuery.camelCase( p ); if ( p !== name ) { prop[ name ] = prop[ p ]; delete prop[ p ]; - p = name; } - if ( prop[p] === "hide" && hidden || prop[p] === "show" && !hidden ) { - return opt.complete.call(this); + val = prop[ name ]; + + // easing resolution: per property > opt.specialEasing > opt.easing > 'swing' (default) + if ( jQuery.isArray( val ) ) { + opt.animatedProperties[ name ] = val[ 1 ]; + val = prop[ name ] = val[ 0 ]; + } else { + opt.animatedProperties[ name ] = opt.specialEasing && opt.specialEasing[ name ] || opt.easing || 'swing'; } - if ( isElement && ( p === "height" || p === "width" ) ) { + if ( val === "hide" && hidden || val === "show" && !hidden ) { + return opt.complete.call( this ); + } + + if ( isElement && ( name === "height" || name === "width" ) ) { // Make sure that nothing sneaks out // Record all 3 overflow attributes because IE does not // change the overflow attribute when overflowX and @@ -7622,7 +8168,7 @@ jQuery.fn.extend({ this.style.display = "inline-block"; } else { - var display = defaultDisplay(this.nodeName); + display = defaultDisplay( this.nodeName ); // inline-level elements accept inline-block; // block-level elements need to be inline with layout @@ -7636,44 +8182,37 @@ jQuery.fn.extend({ } } } - - if ( jQuery.isArray( prop[p] ) ) { - // Create (if needed) and add to specialEasing - (opt.specialEasing = opt.specialEasing || {})[p] = prop[p][1]; - prop[p] = prop[p][0]; - } } if ( opt.overflow != null ) { this.style.overflow = "hidden"; } - opt.curAnim = jQuery.extend({}, prop); - - jQuery.each( prop, function( name, val ) { - var e = new jQuery.fx( self, opt, name ); + for ( p in prop ) { + e = new jQuery.fx( this, opt, p ); + val = prop[ p ]; if ( rfxtypes.test(val) ) { - e[ val === "toggle" ? hidden ? "show" : "hide" : val ]( prop ); + e[ val === "toggle" ? hidden ? "show" : "hide" : val ](); } else { - var parts = rfxnum.exec(val), - start = e.cur(); + parts = rfxnum.exec( val ); + start = e.cur(); if ( parts ) { - var end = parseFloat( parts[2] ), - unit = parts[3] || ( jQuery.cssNumber[ name ] ? "" : "px" ); + end = parseFloat( parts[2] ); + unit = parts[3] || ( jQuery.cssNumber[ p ] ? "" : "px" ); // We need to compute starting value if ( unit !== "px" ) { - jQuery.style( self, name, (end || 1) + unit); + jQuery.style( this, p, (end || 1) + unit); start = ((end || 1) / e.cur()) * start; - jQuery.style( self, name, start + unit); + jQuery.style( this, p, start + unit); } // If a +=/-= token was provided, we're doing a relative animation if ( parts[1] ) { - end = ((parts[1] === "-=" ? -1 : 1) * end) + start; + end = ( (parts[ 1 ] === "-=" ? -1 : 1) * end ) + start; } e.custom( start, end, unit ); @@ -7682,7 +8221,7 @@ jQuery.fn.extend({ e.custom( start, val, "" ); } } - }); + } // For JS strict compliance return true; @@ -7690,15 +8229,18 @@ jQuery.fn.extend({ }, stop: function( clearQueue, gotoEnd ) { - var timers = jQuery.timers; - if ( clearQueue ) { this.queue([]); } this.each(function() { - // go in reverse order so anything added to the queue during the loop is ignored - for ( var i = timers.length - 1; i >= 0; i-- ) { + var timers = jQuery.timers, + i = timers.length; + // clear marker counters if we know they won't be + if ( !gotoEnd ) { + jQuery._unmark( true, this ); + } + while ( i-- ) { if ( timers[i].elem === this ) { if (gotoEnd) { // force the next step to be the last @@ -7720,6 +8262,17 @@ jQuery.fn.extend({ }); +// Animations created synchronously will run synchronously +function createFxNow() { + setTimeout( clearFxNow, 0 ); + return ( fxNow = jQuery.now() ); +} + +function clearFxNow() { + fxNow = undefined; +} + +// Generate parameters to create a standard animation function genFx( type, num ) { var obj = {}; @@ -7758,13 +8311,16 @@ jQuery.extend({ // Queueing opt.old = opt.complete; - opt.complete = function() { - if ( opt.queue !== false ) { - jQuery(this).dequeue(); - } + opt.complete = function( noUnmark ) { if ( jQuery.isFunction( opt.old ) ) { opt.old.call( this ); } + + if ( opt.queue !== false ) { + jQuery.dequeue( this ); + } else if ( noUnmark !== false ) { + jQuery._unmark( this ); + } }; return opt; @@ -7786,9 +8342,7 @@ jQuery.extend({ this.elem = elem; this.prop = prop; - if ( !options.orig ) { - options.orig = {}; - } + options.orig = options.orig || {}; } }); @@ -7820,9 +8374,10 @@ jQuery.fx.prototype = { // Start an animation from one number to another custom: function( from, to, unit ) { var self = this, - fx = jQuery.fx; + fx = jQuery.fx, + raf; - this.startTime = jQuery.now(); + this.startTime = fxNow || createFxNow(); this.start = from; this.end = to; this.unit = unit || this.unit || ( jQuery.cssNumber[ this.prop ] ? "" : "px" ); @@ -7836,7 +8391,20 @@ jQuery.fx.prototype = { t.elem = this.elem; if ( t() && jQuery.timers.push(t) && !timerId ) { - timerId = setInterval(fx.tick, fx.interval); + // Use requestAnimationFrame instead of setInterval if available + if ( requestAnimationFrame ) { + timerId = true; + raf = function() { + // When timerId gets set to null at any point, this stops + if ( timerId ) { + requestAnimationFrame( raf ); + fx.tick(); + } + }; + requestAnimationFrame( raf ); + } else { + timerId = setInterval( fx.tick, fx.interval ); + } } }, @@ -7867,60 +8435,64 @@ jQuery.fx.prototype = { // Each step of an animation step: function( gotoEnd ) { - var t = jQuery.now(), done = true; + var t = fxNow || createFxNow(), + done = true, + elem = this.elem, + options = this.options, + i, n; - if ( gotoEnd || t >= this.options.duration + this.startTime ) { + if ( gotoEnd || t >= options.duration + this.startTime ) { this.now = this.end; this.pos = this.state = 1; this.update(); - this.options.curAnim[ this.prop ] = true; + options.animatedProperties[ this.prop ] = true; - for ( var i in this.options.curAnim ) { - if ( this.options.curAnim[i] !== true ) { + for ( i in options.animatedProperties ) { + if ( options.animatedProperties[i] !== true ) { done = false; } } if ( done ) { // Reset the overflow - if ( this.options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { - var elem = this.elem, - options = this.options; + if ( options.overflow != null && !jQuery.support.shrinkWrapBlocks ) { jQuery.each( [ "", "X", "Y" ], function (index, value) { elem.style[ "overflow" + value ] = options.overflow[index]; - } ); + }); } // Hide the element if the "hide" operation was done - if ( this.options.hide ) { - jQuery(this.elem).hide(); + if ( options.hide ) { + jQuery(elem).hide(); } // Reset the properties, if the item has been hidden or shown - if ( this.options.hide || this.options.show ) { - for ( var p in this.options.curAnim ) { - jQuery.style( this.elem, p, this.options.orig[p] ); + if ( options.hide || options.show ) { + for ( var p in options.animatedProperties ) { + jQuery.style( elem, p, options.orig[p] ); } } // Execute the complete function - this.options.complete.call( this.elem ); + options.complete.call( elem ); } return false; } else { - var n = t - this.startTime; - this.state = n / this.options.duration; - - // Perform the easing function, defaults to swing - var specialEasing = this.options.specialEasing && this.options.specialEasing[this.prop]; - var defaultEasing = this.options.easing || (jQuery.easing.swing ? "swing" : "linear"); - this.pos = jQuery.easing[specialEasing || defaultEasing](this.state, n, 0, 1, this.options.duration); - this.now = this.start + ((this.end - this.start) * this.pos); + // classical easing cannot be used with an Infinity duration + if ( options.duration == Infinity ) { + this.now = t; + } else { + n = t - this.startTime; + this.state = n / options.duration; + // Perform the easing function, defaults to swing + this.pos = jQuery.easing[ options.animatedProperties[ this.prop ] ]( this.state, n, 0, 1, options.duration ); + this.now = this.start + ((this.end - this.start) * this.pos); + } // Perform the next step of the animation this.update(); } @@ -7931,9 +8503,7 @@ jQuery.fx.prototype = { jQuery.extend( jQuery.fx, { tick: function() { - var timers = jQuery.timers; - - for ( var i = 0; i < timers.length; i++ ) { + for ( var timers = jQuery.timers, i = 0 ; i < timers.length ; ++i ) { if ( !timers[i]() ) { timers.splice(i--, 1); } @@ -7981,17 +8551,47 @@ if ( jQuery.expr && jQuery.expr.filters ) { }; } +// Try to restore the default display value of an element function defaultDisplay( nodeName ) { + if ( !elemdisplay[ nodeName ] ) { - var elem = jQuery("<" + nodeName + ">").appendTo("body"), - display = elem.css("display"); + + var body = document.body, + elem = jQuery( "<" + nodeName + ">" ).appendTo( body ), + display = elem.css( "display" ); elem.remove(); + // If the simple way fails, + // get element's real default display by attaching it to a temp iframe if ( display === "none" || display === "" ) { - display = "block"; + // No iframe to use yet, so create it + if ( !iframe ) { + iframe = document.createElement( "iframe" ); + iframe.frameBorder = iframe.width = iframe.height = 0; + } + + body.appendChild( iframe ); + + // Create a cacheable copy of the iframe document on first call. + // IE and Opera will allow us to reuse the iframeDoc without re-writing the fake HTML + // document to it; WebKit & Firefox won't allow reusing the iframe document. + if ( !iframeDoc || !iframe.createElement ) { + iframeDoc = ( iframe.contentWindow || iframe.contentDocument ).document; + iframeDoc.write( ( document.compatMode === "CSS1Compat" ? "" : "" ) + "" ); + iframeDoc.close(); + } + + elem = iframeDoc.createElement( nodeName ); + + iframeDoc.body.appendChild( elem ); + + display = jQuery.css( elem, "display" ); + + body.removeChild( iframe ); } + // Store the correct default display elemdisplay[ nodeName ] = display; } @@ -8181,17 +8781,19 @@ jQuery.offset = { curOffset = curElem.offset(), curCSSTop = jQuery.css( elem, "top" ), curCSSLeft = jQuery.css( elem, "left" ), - calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray('auto', [curCSSTop, curCSSLeft]) > -1, + calculatePosition = (position === "absolute" || position === "fixed") && jQuery.inArray("auto", [curCSSTop, curCSSLeft]) > -1, props = {}, curPosition = {}, curTop, curLeft; // need to be able to calculate position if either top or left is auto and position is either absolute or fixed if ( calculatePosition ) { curPosition = curElem.position(); + curTop = curPosition.top; + curLeft = curPosition.left; + } else { + curTop = parseFloat( curCSSTop ) || 0; + curLeft = parseFloat( curCSSLeft ) || 0; } - curTop = calculatePosition ? curPosition.top : parseInt( curCSSTop, 10 ) || 0; - curLeft = calculatePosition ? curPosition.left : parseInt( curCSSLeft, 10 ) || 0; - if ( jQuery.isFunction( options ) ) { options = options.call( elem, i, curOffset ); } @@ -8260,29 +8862,16 @@ jQuery.fn.extend({ jQuery.each( ["Left", "Top"], function( i, name ) { var method = "scroll" + name; - jQuery.fn[ method ] = function(val) { - var elem = this[0], win; + jQuery.fn[ method ] = function( val ) { + var elem, win; - if ( !elem ) { - return null; - } + if ( val === undefined ) { + elem = this[ 0 ]; - if ( val !== undefined ) { - // Set the scroll offset - return this.each(function() { - win = getWindow( this ); + if ( !elem ) { + return null; + } - if ( win ) { - win.scrollTo( - !i ? val : jQuery(win).scrollLeft(), - i ? val : jQuery(win).scrollTop() - ); - - } else { - this[ method ] = val; - } - }); - } else { win = getWindow( elem ); // Return the scroll offset @@ -8291,6 +8880,21 @@ jQuery.each( ["Left", "Top"], function( i, name ) { win.document.body[ method ] : elem[ method ]; } + + // Set the scroll offset + return this.each(function() { + win = getWindow( this ); + + if ( win ) { + win.scrollTo( + !i ? val : jQuery( win ).scrollLeft(), + i ? val : jQuery( win ).scrollTop() + ); + + } else { + this[ method ] = val; + } + }); }; }); @@ -8305,22 +8909,24 @@ function getWindow( elem ) { -// Create innerHeight, innerWidth, outerHeight and outerWidth methods +// Create width, height, innerHeight, innerWidth, outerHeight and outerWidth methods jQuery.each([ "Height", "Width" ], function( i, name ) { var type = name.toLowerCase(); // innerHeight and innerWidth - jQuery.fn["inner" + name] = function() { - return this[0] ? - parseFloat( jQuery.css( this[0], type, "padding" ) ) : + jQuery.fn[ "inner" + name ] = function() { + var elem = this[0]; + return elem && elem.style ? + parseFloat( jQuery.css( elem, type, "padding" ) ) : null; }; // outerHeight and outerWidth - jQuery.fn["outer" + name] = function( margin ) { - return this[0] ? - parseFloat( jQuery.css( this[0], type, margin ? "margin" : "border" ) ) : + jQuery.fn[ "outer" + name ] = function( margin ) { + var elem = this[0]; + return elem && elem.style ? + parseFloat( jQuery.css( elem, type, margin ? "margin" : "border" ) ) : null; }; @@ -8370,5 +8976,6 @@ jQuery.each([ "Height", "Width" ], function( i, name ) { }); +// Expose jQuery to the global object window.jQuery = window.$ = jQuery; })(window); diff --git a/addons/base/static/src/base.html b/addons/base/static/src/base.html index 2761638c6d0..4bc6d07cc15 100644 --- a/addons/base/static/src/base.html +++ b/addons/base/static/src/base.html @@ -12,7 +12,7 @@ - + From fd6563b818e1127344178fac58a9720d17d41cca Mon Sep 17 00:00:00 2001 From: "noz (OpenERP)" Date: Thu, 7 Jul 2011 14:34:44 +0530 Subject: [PATCH 047/230] [FIX] Improved required validation. bzr revid: noz@tinyerp.com-20110707090444-iaf58v4umq53lb88 --- addons/base/controllers/main.py | 5 +++- addons/base/static/src/css/base.css | 4 +++ addons/base/static/src/js/chrome.js | 46 +++++++++++++++++++++++++++-- addons/base/static/src/xml/base.xml | 20 ++++++------- 4 files changed, 61 insertions(+), 14 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index f153c3da747..609466a19df 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -124,7 +124,10 @@ class Session(openerpweb.Controller): @openerpweb.jsonrequest def db_operation(self, req, flag, **kw): - if flag == 'drop': + if flag == 'create': + pass + + elif flag == 'drop': db = kw.get('db') password = kw.get('password') diff --git a/addons/base/static/src/css/base.css b/addons/base/static/src/css/base.css index bf0d29de965..16c56ffd369 100644 --- a/addons/base/static/src/css/base.css +++ b/addons/base/static/src/css/base.css @@ -190,6 +190,10 @@ ul.db_options li { -moz-border-radius: 10px; } +table.db_option_table input.required { + background-color: #D2D2FF; +} + .db_option_table input[type="text"], input[type="password"], select { width: 300px; } diff --git a/addons/base/static/src/js/chrome.js b/addons/base/static/src/js/chrome.js index ef86595245d..3de046be84c 100644 --- a/addons/base/static/src/js/chrome.js +++ b/addons/base/static/src/js/chrome.js @@ -935,6 +935,49 @@ openerp.base.Database = openerp.base.Controller.extend({ self.$option_id.html(QWeb.render("CreateDB", self)); $("form[name=create_db_form]").validate(); + + $("input[name=create_confirm_pwd]").rules("add", { + equalTo: 'input[name=create_admin_pwd]', + messages: { + required: "Password did not match !" + } + }); + + $("input[name=super_admin_pwd]").focus(); + + self.$option_id.find('form[name=create_db_form]').submit(function(ev) { + ev.preventDefault(); + + var super_admin_pwd = self.$option_id.find("input[name=super_admin_pwd]").val(); + var db = self.$option_id.find("input[name=db_name]").val(); + var demo_data = self.$option_id.find("input[name=demo_data]:checked"); + var db_lang = self.$option_id.find("select[name=db_lang]").val(); + var admin_pwd = self.$option_id.find("input[name=create_admin_pwd]").val(); + var confirm_pwd = self.$option_id.find("input[name=create_confirm_pwd]").val(); + + if (demo_data.length) + demo_data = 'True'; + else + demo_data = 'False'; + + self.rpc("/base/session/db_operation", { + 'flag': 'create', + 'super_admin_pwd': super_admin_pwd, + 'db': db, + 'demo_data': demo_data, + 'db_lang': db_lang, + 'admin_pwd': admin_pwd, + 'confirm_pwd': confirm_pwd + }, + function(result) { + if (result && !result.error) { + + } + }); + + }); + + }); self.$element.find('#db-drop').click(function() { @@ -1015,21 +1058,18 @@ openerp.base.Database = openerp.base.Controller.extend({ $("form[name=change_pwd_form]").validate(); $("input[name=old_pwd]").rules("add", { - required: true, minlength: 1, messages: { required: "Please enter password !" } }); $("input[name=new_pwd]").rules("add", { - required: true, minlength: 1, messages: { required: "Please enter password !" } }); $("input[name=confirm_pwd]").rules("add", { - required: true, equalTo: 'input[name=new_pwd]', messages: { required: "Password did not match !" diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index add5f8a14b9..459c5d5b591 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -80,15 +80,15 @@
- + - + - + @@ -103,12 +103,12 @@ - - + + - - + + @@ -218,15 +218,15 @@
- + - + - + From 5985688d81c11d14d2c469cf47e3958d991851cb Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 7 Jul 2011 11:44:38 +0200 Subject: [PATCH 048/230] [ADD] dashboard for home page & home page actions bzr revid: xmo@openerp.com-20110707094438-07ca7kqw3vzrg5j4 --- addons/board/board_view.xml | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/addons/board/board_view.xml b/addons/board/board_view.xml index d48ddd6a025..2c5cd432539 100644 --- a/addons/board/board_view.xml +++ b/addons/board/board_view.xml @@ -1,6 +1,38 @@ + + + Applications Tiles + board.home.applications + + + Homepage Widgets + board.home.widgets + + + board.homepage + board.board + form + +
+ + + + + + + + + +
+
+ + Home Page + board.board + form + + board.note.search From 521e2891f5d536e52193e0b007b70fce0247b332 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Thu, 7 Jul 2011 15:31:04 +0530 Subject: [PATCH 049/230] [ADD] add base_export module. bzr revid: ysa@tinyerp.com-20110707100104-3trko5x1njl1huhp --- addons/base/static/src/img/collapse.gif | Bin 0 -> 80 bytes addons/base/static/src/img/expand.gif | Bin 0 -> 81 bytes addons/base/static/src/js/views.js | 14 ++- addons/base_export/__init__.py | 2 + addons/base_export/__openerp__.py | 10 ++ addons/base_export/controllers/__init__.py | 1 + addons/base_export/controllers/main.py | 59 ++++++++++ .../static/src/css/base_export.css | 65 +++++++++++ .../base_export/static/src/js/base_export.js | 32 +++++ .../static/src/xml/base_export.xml | 109 ++++++++++++++++++ 10 files changed, 290 insertions(+), 2 deletions(-) create mode 100755 addons/base/static/src/img/collapse.gif create mode 100755 addons/base/static/src/img/expand.gif create mode 100644 addons/base_export/__init__.py create mode 100644 addons/base_export/__openerp__.py create mode 100644 addons/base_export/controllers/__init__.py create mode 100644 addons/base_export/controllers/main.py create mode 100644 addons/base_export/static/src/css/base_export.css create mode 100644 addons/base_export/static/src/js/base_export.js create mode 100644 addons/base_export/static/src/xml/base_export.xml diff --git a/addons/base/static/src/img/collapse.gif b/addons/base/static/src/img/collapse.gif new file mode 100755 index 0000000000000000000000000000000000000000..759e72ebcfe18bc1bc714b6451c301b12a1f27d5 GIT binary patch literal 80 zcmZ?wbhEHb6krfwSjfZx1Zin$|G_}', {id: element_id}).dialog({ + title: "Export Data", + modal: true, + width: '50%', + height: 'auto' + }).html(QWeb.render('ExportTreeView', {'fields': result})) + + jQuery(_export).find('[id^=parentimg_]').click(function(){ + console.log('this>>>id', this.id); + }); + }, +}); + +}; diff --git a/addons/base_export/static/src/xml/base_export.xml b/addons/base_export/static/src/xml/base_export.xml new file mode 100644 index 00000000000..4fd9c7d872e --- /dev/null +++ b/addons/base_export/static/src/xml/base_export.xml @@ -0,0 +1,109 @@ + \ No newline at end of file From 02b5d5b5bce2450be14f2d5ca3efe62b284c0407 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 7 Jul 2011 12:53:23 +0200 Subject: [PATCH 050/230] [ADD] get a bunch of widgets to display (though not quite correctly... todo: fix that) bzr revid: xmo@openerp.com-20110707105323-ztjvlccxfpmgdxoj --- .../base_dashboard/static/src/js/dashboard.js | 67 ++++++++++++++++++- .../static/src/xml/base_dashboard.xml | 9 +++ 2 files changed, 75 insertions(+), 1 deletion(-) diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index b1e925c7b0a..3cdcbb3b218 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -355,5 +355,70 @@ openerp.base_dashboard.ApplicationTiles = openerp.base.View.extend({ .click();}); }); } -}) +}); +openerp.base.client_actions.add( + 'board.home.widgets', 'openerp.base_dashboard.Widgets'); +openerp.base_dashboard.Widgets = openerp.base.View.extend({ + init: function (parent_or_session, element_id) { + this._super(parent_or_session, element_id); + this.user_widgets = new openerp.base.DataSetSearch( + this.session, 'res.widget.user', null, + ['|', ['user_id', '=', false], + ['user_id', '=', this.session.uid]]); + this.widgets = new openerp.base.DataSetSearch(this.session, 'res.widget'); + }, + start: function () { + this.user_widgets.read_slice(['widget_id', 'user_id'], null, null, + this.on_widgets_list_loaded); + }, + on_widgets_list_loaded: function (user_widgets) { + var self = this; + var widget_user = {}; + _(user_widgets).each(function (widget) { + widget['widget_id'] = widget['widget_id'][0]; + widget_user[widget['widget_id']] = { + removable: widget['user_id'] !== false, + user_widget_id: widget['id'] + }; + }); + this.widgets.read_ids(_(user_widgets).pluck('widget_id'), [], function (widgets) { + _(widgets).each(function (widget) { + _.extend(widget, widget_user[widget['id']]); + }); + var root = self.$element[0]; + root.innerHTML = QWeb.render('HomeWidgets', { + widgets: widgets + }); + + self.process_widgets_scripts(0, root.getElementsByTagName('script')); + }) + }, + process_widgets_scripts: function (index, nodes) { + if (nodes.length <= index) { + return; + } + var old_write = window.document.write, + self = this, + script = nodes[index], + deferred = $.Deferred().then(function () { + window.document.write = old_write; }), + continuation = function () { + $.when(self.process_widgets_scripts(index+1, nodes)).then( + deferred.resolve()); + }; + window.document.write = function (s) { + $(script).closest('.oe-dashboard-home-widgets-widget') + .children('div') + .append(s); + }; + + if (!script.src) { + new Function(script.firstChild.nodeValue)(); + setTimeout(continuation); + } else { + $LAB.script(script.src).wait(continuation); + } + return deferred; + } +}); }; diff --git a/addons/base_dashboard/static/src/xml/base_dashboard.xml b/addons/base_dashboard/static/src/xml/base_dashboard.xml index 91fa13d763a..bb81aea45bd 100644 --- a/addons/base_dashboard/static/src/xml/base_dashboard.xml +++ b/addons/base_dashboard/static/src/xml/base_dashboard.xml @@ -98,4 +98,13 @@
+
+
+

+
+
+ +
+
From 2432079b1319190a636c0b1fdfc3cb3203f38832 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Mon, 11 Jul 2011 10:33:35 +0530 Subject: [PATCH 051/230] [IMP] improve export data. bzr revid: ysa@tinyerp.com-20110711050335-fauz9cddnwj8urnv --- addons/base_export/controllers/main.py | 11 ++--- .../base_export/static/src/js/base_export.js | 41 ++++++++++++++--- .../static/src/xml/base_export.xml | 45 ++++++++++++------- 3 files changed, 72 insertions(+), 25 deletions(-) diff --git a/addons/base_export/controllers/main.py b/addons/base_export/controllers/main.py index 6ce716fea6c..5e0d5155a1e 100644 --- a/addons/base_export/controllers/main.py +++ b/addons/base_export/controllers/main.py @@ -10,7 +10,7 @@ class Export(View): return fields @openerpweb.jsonrequest - def get_fields(self, req, model): + def get_fields(self, req, model, prefix='', field_parent=None, name= ''): fields = self.fields_get(req, model) fields.update({'id': {'string': 'ID'}, '.id': {'string': 'Database ID'}}) @@ -19,11 +19,12 @@ class Export(View): for key, value in fields.items(): record = {} - id = key - nm = value['string'] - + id = prefix + (prefix and '/' or '') + key + nm = name + (name and '/' or '') + value['string'] + levels = nm.split('/') + levels > 1 and levels.remove(levels[0]) or [] record.update(id=id, string= nm, action='javascript: void(0)', - target=None, icon=None, children=[]) + target=None, icon=None, children=[], level = levels) records.append(record) if value.get('relation', False): diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index d21dba51f0b..8b91529f85e 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -4,27 +4,58 @@ openerp.base.views.add('export', 'openerp.base_export.Export'); openerp.base_export.Export = openerp.base.Controller.extend({ init: function(session, dataset, views){ + this._super(session); this.dataset = dataset this.views = views - this.session = session - this._super(); }, start: function() { this.rpc("/base_export/export/get_fields", {"model": this.dataset.model}, this.on_loaded); }, on_loaded: function(result) { - var element_id = _.uniqueId("act_window_dialog"); var self = this; + var element_id = _.uniqueId("act_window_dialog"); var _export = $('
', {id: element_id}).dialog({ title: "Export Data", modal: true, width: '50%', height: 'auto' }).html(QWeb.render('ExportTreeView', {'fields': result})) + jQuery(_export).find('[id^=parentimg]').click(function(){ + self.on_click(this.id, result); + }); + }, + + on_click: function(id, result) { + var self = this + this.field_id = id.split("@"); + this.field_id = self.field_id[1]; + var model = '' + var prefix = '' + var name = '' + for (var record in result){ + if(result[record]['id'] == this.field_id){ + model = result[record]['params']['model'] + prefix = result[record]['params']['prefix'] + name = result[record]['params']['name'] + } + } + if (model){ + self.get_data(model, prefix, name) + } + }, + + get_data: function(model, prefix, name) { + this.rpc("/base_export/export/get_fields", {"model": model, "prefix": prefix, "field_parent" : this.field_id, "name": name}, this.on_show_data, {}); + }, + + on_show_data: function(result) { + var self = this; + $('tr #treerow_' + self.field_id).after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); + jQuery($.find('img[id ^= parentimg]')).click(function(){ + self.field_id = this.id + self.on_click(this.id, result); - jQuery(_export).find('[id^=parentimg_]').click(function(){ - console.log('this>>>id', this.id); }); }, }); diff --git a/addons/base_export/static/src/xml/base_export.xml b/addons/base_export/static/src/xml/base_export.xml index 4fd9c7d872e..a104bc853a5 100644 --- a/addons/base_export/static/src/xml/base_export.xml +++ b/addons/base_export/static/src/xml/base_export.xml @@ -43,21 +43,8 @@ Name - - - - - - - +
- - - - - - - -
+
@@ -106,4 +93,32 @@ + + + + + + + + + + + + + + + +
&nbsp; + + + + + + + +
+ + +
+
\ No newline at end of file From 4aa02596ff7d80fa144328491535aab1cb4d4311 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Mon, 11 Jul 2011 11:07:32 +0530 Subject: [PATCH 052/230] [IMP]account,account_sequence,base_contact,document,document_ics,l10n_br,l10n_cr,l10n_fr,l10n_ma,l10n_uk:Improvement is Done bzr revid: mma@tinyerp.com-20110711053732-83swt3grb29ayqez --- addons/account/account_installer.xml | 3 ++- addons/account/configurable_account_chart.xml | 3 ++- addons/account_sequence/account_sequence_installer_view.xml | 4 ++-- addons/base_contact/base_contact_installer_view.xml | 2 +- .../base_report_designer/base_report_designer_installer.xml | 3 ++- addons/document/wizard/document_configuration_view.xml | 2 +- addons/document_ics/document_ics_config_wizard.xml | 2 +- addons/l10n_br/data/l10n_br_account_chart_template.xml | 4 ++-- addons/l10n_cr/l10n_wizard.xml | 3 ++- addons/l10n_fr/l10n_fr_wizard.xml | 3 ++- addons/l10n_ma/l10n_ma_wizard.xml | 3 ++- addons/l10n_uk/l10n_uk_wizard.xml | 4 ++-- 12 files changed, 21 insertions(+), 15 deletions(-) diff --git a/addons/account/account_installer.xml b/addons/account/account_installer.xml index dd106e75afb..71633cc91f3 100644 --- a/addons/account/account_installer.xml +++ b/addons/account/account_installer.xml @@ -81,7 +81,8 @@ 3 - special + normal + open diff --git a/addons/account/configurable_account_chart.xml b/addons/account/configurable_account_chart.xml index fbae77349af..72386c839c1 100644 --- a/addons/account/configurable_account_chart.xml +++ b/addons/account/configurable_account_chart.xml @@ -617,7 +617,8 @@ Generate Chart of Accounts from a Chart Template - special + normal + open diff --git a/addons/account_sequence/account_sequence_installer_view.xml b/addons/account_sequence/account_sequence_installer_view.xml index b39521d3c01..2af22bb01ae 100644 --- a/addons/account_sequence/account_sequence_installer_view.xml +++ b/addons/account_sequence/account_sequence_installer_view.xml @@ -51,8 +51,8 @@ 3 - special - skip + normal + open diff --git a/addons/base_contact/base_contact_installer_view.xml b/addons/base_contact/base_contact_installer_view.xml index 981af67c60d..03216d49e94 100644 --- a/addons/base_contact/base_contact_installer_view.xml +++ b/addons/base_contact/base_contact_installer_view.xml @@ -54,7 +54,7 @@ 3 skip - special + normal diff --git a/addons/base_report_designer/base_report_designer_installer.xml b/addons/base_report_designer/base_report_designer_installer.xml index 0afee6233ef..6ef1ea11326 100644 --- a/addons/base_report_designer/base_report_designer_installer.xml +++ b/addons/base_report_designer/base_report_designer_installer.xml @@ -58,7 +58,8 @@ 3 - special + normal + open diff --git a/addons/document/wizard/document_configuration_view.xml b/addons/document/wizard/document_configuration_view.xml index c2bf3245afb..1fd15d1b381 100644 --- a/addons/document/wizard/document_configuration_view.xml +++ b/addons/document/wizard/document_configuration_view.xml @@ -51,7 +51,7 @@ - special + normal skip diff --git a/addons/document_ics/document_ics_config_wizard.xml b/addons/document_ics/document_ics_config_wizard.xml index efa232a0a0d..6cd9199bfc3 100644 --- a/addons/document_ics/document_ics_config_wizard.xml +++ b/addons/document_ics/document_ics_config_wizard.xml @@ -56,7 +56,7 @@ - special + normal skip diff --git a/addons/l10n_br/data/l10n_br_account_chart_template.xml b/addons/l10n_br/data/l10n_br_account_chart_template.xml index 819c4a8456a..548f7ff1341 100644 --- a/addons/l10n_br/data/l10n_br_account_chart_template.xml +++ b/addons/l10n_br/data/l10n_br_account_chart_template.xml @@ -18,8 +18,8 @@ Generate Chart of Accounts from a Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated. This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template. - open - special + skip + normal diff --git a/addons/l10n_cr/l10n_wizard.xml b/addons/l10n_cr/l10n_wizard.xml index 26a82eb22ce..ceffba6a9d8 100644 --- a/addons/l10n_cr/l10n_wizard.xml +++ b/addons/l10n_cr/l10n_wizard.xml @@ -4,7 +4,8 @@ - special + normal + skip diff --git a/addons/l10n_fr/l10n_fr_wizard.xml b/addons/l10n_fr/l10n_fr_wizard.xml index 0e97d868a52..97a12a661cf 100644 --- a/addons/l10n_fr/l10n_fr_wizard.xml +++ b/addons/l10n_fr/l10n_fr_wizard.xml @@ -4,7 +4,8 @@ - special + normal + skip diff --git a/addons/l10n_ma/l10n_ma_wizard.xml b/addons/l10n_ma/l10n_ma_wizard.xml index a59a2e9ca83..2daebf030f4 100644 --- a/addons/l10n_ma/l10n_ma_wizard.xml +++ b/addons/l10n_ma/l10n_ma_wizard.xml @@ -4,7 +4,8 @@ - special + normal + skip diff --git a/addons/l10n_uk/l10n_uk_wizard.xml b/addons/l10n_uk/l10n_uk_wizard.xml index e00fbd67add..66591f9d8b7 100644 --- a/addons/l10n_uk/l10n_uk_wizard.xml +++ b/addons/l10n_uk/l10n_uk_wizard.xml @@ -7,8 +7,8 @@ Generate Chart of Accounts from a Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated. This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template. - open - special + skip + normal From 9d4dcb1f77a397bfd970626425b86d63b3d2fb8a Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Mon, 11 Jul 2011 12:40:16 +0530 Subject: [PATCH 053/230] [IMP] improve code. bzr revid: ysa@tinyerp.com-20110711071016-w743le30aujzc80g --- addons/base_export/controllers/main.py | 6 +-- .../base_export/static/src/js/base_export.js | 4 +- .../static/src/xml/base_export.xml | 41 +++++++++---------- 3 files changed, 23 insertions(+), 28 deletions(-) diff --git a/addons/base_export/controllers/main.py b/addons/base_export/controllers/main.py index 5e0d5155a1e..6a261c826bf 100644 --- a/addons/base_export/controllers/main.py +++ b/addons/base_export/controllers/main.py @@ -19,7 +19,7 @@ class Export(View): for key, value in fields.items(): record = {} - id = prefix + (prefix and '/' or '') + key + id = prefix + (prefix and '_'or '') + key nm = name + (name and '/' or '') + value['string'] levels = nm.split('/') levels > 1 and levels.remove(levels[0]) or [] @@ -39,7 +39,7 @@ class Export(View): cfields_order.sort(lambda x,y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): - cid = id + '/' + fld + cid = id + '_' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or [] @@ -50,7 +50,7 @@ class Export(View): cfields_order.sort(lambda x,y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): - cid = id + '/' + fld + cid = id + '_' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or [] diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index 8b91529f85e..b1dcd42d2d3 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -28,8 +28,7 @@ openerp.base_export.Export = openerp.base.Controller.extend({ on_click: function(id, result) { var self = this - this.field_id = id.split("@"); - this.field_id = self.field_id[1]; + this.field_id = id.split("@")[1]; var model = '' var prefix = '' var name = '' @@ -53,7 +52,6 @@ openerp.base_export.Export = openerp.base.Controller.extend({ var self = this; $('tr #treerow_' + self.field_id).after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); jQuery($.find('img[id ^= parentimg]')).click(function(){ - self.field_id = this.id self.on_click(this.id, result); }); diff --git a/addons/base_export/static/src/xml/base_export.xml b/addons/base_export/static/src/xml/base_export.xml index a104bc853a5..d094eb1a3aa 100644 --- a/addons/base_export/static/src/xml/base_export.xml +++ b/addons/base_export/static/src/xml/base_export.xml @@ -94,31 +94,28 @@ - - - - - - - - - - - -
&nbsp; - - - - - - - -
+ + + + + + + + +
&nbsp; + + + + + + + +
- -
+ +
\ No newline at end of file From af3773c0f5590ae02e2a0d28cf76294bf9be33e8 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Mon, 11 Jul 2011 12:47:53 +0530 Subject: [PATCH 054/230] [IMP]l10n_be,l10n_es,l10n_lu : Improvement is Done bzr revid: mma@tinyerp.com-20110711071753-jmd5f3sg21y5vqah --- addons/l10n_be/l10n_be_wizard.xml | 2 +- addons/l10n_es/l10n_es_wizard.xml | 2 +- addons/l10n_lu/l10n_lu_wizard.xml | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/addons/l10n_be/l10n_be_wizard.xml b/addons/l10n_be/l10n_be_wizard.xml index 5473499d971..f97cba250f4 100644 --- a/addons/l10n_be/l10n_be_wizard.xml +++ b/addons/l10n_be/l10n_be_wizard.xml @@ -5,7 +5,7 @@ - special + normal diff --git a/addons/l10n_es/l10n_es_wizard.xml b/addons/l10n_es/l10n_es_wizard.xml index d0f89dfc87a..116ef691f45 100644 --- a/addons/l10n_es/l10n_es_wizard.xml +++ b/addons/l10n_es/l10n_es_wizard.xml @@ -4,7 +4,7 @@ - special + normal diff --git a/addons/l10n_lu/l10n_lu_wizard.xml b/addons/l10n_lu/l10n_lu_wizard.xml index bbe7949af49..e647a180279 100644 --- a/addons/l10n_lu/l10n_lu_wizard.xml +++ b/addons/l10n_lu/l10n_lu_wizard.xml @@ -4,7 +4,7 @@ - special + normal From adbeaf08d63dd3b0bfc8074d5e30db4c7dfb9311 Mon Sep 17 00:00:00 2001 From: "Mayur Maheshwari (OpenERP)" Date: Mon, 11 Jul 2011 14:42:29 +0530 Subject: [PATCH 055/230] [IMP]base_contact,l10n_be,l10n_br,l10n_cr,l10n_fr,l10n_ma,l10n_uk,l10n_es,l10n_lu : Improvement is Done as per suggestion bzr revid: mma@tinyerp.com-20110711091229-5neacsh6i7sapgb4 --- addons/base_contact/base_contact_installer_view.xml | 2 +- addons/l10n_be/l10n_be_wizard.xml | 1 + addons/l10n_br/data/l10n_br_account_chart_template.xml | 2 +- addons/l10n_cr/l10n_wizard.xml | 2 +- addons/l10n_es/l10n_es_wizard.xml | 1 + addons/l10n_fr/l10n_fr_wizard.xml | 2 +- addons/l10n_lu/l10n_lu_wizard.xml | 1 + addons/l10n_ma/l10n_ma_wizard.xml | 2 +- addons/l10n_uk/l10n_uk_wizard.xml | 2 +- 9 files changed, 9 insertions(+), 6 deletions(-) diff --git a/addons/base_contact/base_contact_installer_view.xml b/addons/base_contact/base_contact_installer_view.xml index 03216d49e94..66c486a0514 100644 --- a/addons/base_contact/base_contact_installer_view.xml +++ b/addons/base_contact/base_contact_installer_view.xml @@ -53,7 +53,7 @@ 3 - skip + open normal diff --git a/addons/l10n_be/l10n_be_wizard.xml b/addons/l10n_be/l10n_be_wizard.xml index f97cba250f4..57f1ca0588f 100644 --- a/addons/l10n_be/l10n_be_wizard.xml +++ b/addons/l10n_be/l10n_be_wizard.xml @@ -6,6 +6,7 @@ normal + open diff --git a/addons/l10n_br/data/l10n_br_account_chart_template.xml b/addons/l10n_br/data/l10n_br_account_chart_template.xml index 548f7ff1341..54f61af52de 100644 --- a/addons/l10n_br/data/l10n_br_account_chart_template.xml +++ b/addons/l10n_br/data/l10n_br_account_chart_template.xml @@ -18,7 +18,7 @@ Generate Chart of Accounts from a Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated. This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template. - skip + open normal diff --git a/addons/l10n_cr/l10n_wizard.xml b/addons/l10n_cr/l10n_wizard.xml index ceffba6a9d8..d413dbe829b 100644 --- a/addons/l10n_cr/l10n_wizard.xml +++ b/addons/l10n_cr/l10n_wizard.xml @@ -5,7 +5,7 @@ normal - skip + open diff --git a/addons/l10n_es/l10n_es_wizard.xml b/addons/l10n_es/l10n_es_wizard.xml index 116ef691f45..5586198d844 100644 --- a/addons/l10n_es/l10n_es_wizard.xml +++ b/addons/l10n_es/l10n_es_wizard.xml @@ -5,6 +5,7 @@ normal + open diff --git a/addons/l10n_fr/l10n_fr_wizard.xml b/addons/l10n_fr/l10n_fr_wizard.xml index 97a12a661cf..712bd36f103 100644 --- a/addons/l10n_fr/l10n_fr_wizard.xml +++ b/addons/l10n_fr/l10n_fr_wizard.xml @@ -5,7 +5,7 @@ normal - skip + open diff --git a/addons/l10n_lu/l10n_lu_wizard.xml b/addons/l10n_lu/l10n_lu_wizard.xml index e647a180279..abf74d7b0a8 100644 --- a/addons/l10n_lu/l10n_lu_wizard.xml +++ b/addons/l10n_lu/l10n_lu_wizard.xml @@ -5,6 +5,7 @@ normal + open diff --git a/addons/l10n_ma/l10n_ma_wizard.xml b/addons/l10n_ma/l10n_ma_wizard.xml index 2daebf030f4..c47092321b1 100644 --- a/addons/l10n_ma/l10n_ma_wizard.xml +++ b/addons/l10n_ma/l10n_ma_wizard.xml @@ -5,7 +5,7 @@ normal - skip + open diff --git a/addons/l10n_uk/l10n_uk_wizard.xml b/addons/l10n_uk/l10n_uk_wizard.xml index 66591f9d8b7..8706db11ecf 100644 --- a/addons/l10n_uk/l10n_uk_wizard.xml +++ b/addons/l10n_uk/l10n_uk_wizard.xml @@ -7,7 +7,7 @@ Generate Chart of Accounts from a Chart Template. You will be asked to pass the name of the company, the chart template to follow, the no. of digits to generate the code for your accounts and Bank account, currency to create Journals. Thus,the pure copy of chart Template is generated. This is the same wizard that runs from Financial Management/Configuration/Financial Accounting/Financial Accounts/Generate Chart of Accounts from a Chart Template. - skip + open normal From a692a00f097390f1977fdeb8d68bdc647abaf022 Mon Sep 17 00:00:00 2001 From: "Kunal Chavda (OpenERP)" Date: Mon, 11 Jul 2011 17:10:03 +0530 Subject: [PATCH 056/230] [FIX]jquery id selector problem when id has slash. bzr revid: kch@tinyerp.com-20110711114003-ava3hz0n2syvr3o8 --- addons/base_export/controllers/main.py | 6 +++--- addons/base_export/static/src/js/base_export.js | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/addons/base_export/controllers/main.py b/addons/base_export/controllers/main.py index 6a261c826bf..eb475e59a21 100644 --- a/addons/base_export/controllers/main.py +++ b/addons/base_export/controllers/main.py @@ -19,7 +19,7 @@ class Export(View): for key, value in fields.items(): record = {} - id = prefix + (prefix and '_'or '') + key + id = prefix + (prefix and '/'or '') + key nm = name + (name and '/' or '') + value['string'] levels = nm.split('/') levels > 1 and levels.remove(levels[0]) or [] @@ -39,7 +39,7 @@ class Export(View): cfields_order.sort(lambda x,y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): - cid = id + '_' + fld + cid = id + '/' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or [] @@ -50,7 +50,7 @@ class Export(View): cfields_order.sort(lambda x,y: -cmp(cfields[x].get('string', ''), cfields[y].get('string', ''))) children = [] for j, fld in enumerate(cfields_order): - cid = id + '_' + fld + cid = id + '/' + fld cid = cid.replace(' ', '_') children.append(cid) record['children'] = children or [] diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index b1dcd42d2d3..9b240421bda 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -50,7 +50,7 @@ openerp.base_export.Export = openerp.base.Controller.extend({ on_show_data: function(result) { var self = this; - $('tr #treerow_' + self.field_id).after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); + $("tr[id='treerow_" + self.field_id + "']").after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); jQuery($.find('img[id ^= parentimg]')).click(function(){ self.on_click(this.id, result); From a5fb5a10c17ddc06fe889fe793ef0a195a51c921 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Mon, 11 Jul 2011 17:15:37 +0530 Subject: [PATCH 057/230] [IMP] add add_field method and bind double click method of field. bzr revid: ysa@tinyerp.com-20110711114537-843beu7m00s225m7 --- .../static/src/css/base_export.css | 2 +- .../base_export/static/src/js/base_export.js | 28 +++++++++++++++++-- .../static/src/xml/base_export.xml | 21 +++----------- 3 files changed, 30 insertions(+), 21 deletions(-) diff --git a/addons/base_export/static/src/css/base_export.css b/addons/base_export/static/src/css/base_export.css index 4421c0e4fa5..61ddb47451b 100644 --- a/addons/base_export/static/src/css/base_export.css +++ b/addons/base_export/static/src/css/base_export.css @@ -4,7 +4,7 @@ .row:hover { background-color: #F3F3F3; - color: #0000FF; + color : #4F4F4F; } .row.selected{ diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index 9b240421bda..0dd98efc952 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -19,8 +19,20 @@ openerp.base_export.Export = openerp.base.Controller.extend({ title: "Export Data", modal: true, width: '50%', - height: 'auto' + height: 'auto', + buttons : { + "Close" : function() { + _export.dialog('destroy'); + }, + "Export To File" : function() { + _export.dialog('destroy'); + } + } }).html(QWeb.render('ExportTreeView', {'fields': result})) + + jQuery(_export).find('[id^=export]').dblclick(function(){ + self.add_field(this.id, this.text) + }); jQuery(_export).find('[id^=parentimg]').click(function(){ self.on_click(this.id, result); }); @@ -28,7 +40,7 @@ openerp.base_export.Export = openerp.base.Controller.extend({ on_click: function(id, result) { var self = this - this.field_id = id.split("@")[1]; + this.field_id = id.split("-")[1]; var model = '' var prefix = '' var name = '' @@ -53,8 +65,18 @@ openerp.base_export.Export = openerp.base.Controller.extend({ $("tr[id='treerow_" + self.field_id + "']").after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); jQuery($.find('img[id ^= parentimg]')).click(function(){ self.on_click(this.id, result); - }); + jQuery($.find('[id^=export]')).dblclick(function(){ + self.add_field(this.id, this.text) + }); + }, + + add_field: function(id, string) { + var field_list = $('#fields_list') + field_id = id.split("-")[1]; + if ( !$("#fields_list option[value='" + field_id + "']").length){ + field_list.append( new Option(string, field_id)); + } }, }); diff --git a/addons/base_export/static/src/xml/base_export.xml b/addons/base_export/static/src/xml/base_export.xml index d094eb1a3aa..c0bcd72508e 100644 --- a/addons/base_export/static/src/xml/base_export.xml +++ b/addons/base_export/static/src/xml/base_export.xml @@ -55,7 +55,7 @@ @@ -71,25 +71,12 @@
- +
- + - - - - - - - -
- - -
- - @@ -104,11 +91,11 @@ - + - + From 28a4cff1a1e41264bce79803c457add9962c3a61 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Tue, 12 Jul 2011 10:35:39 +0530 Subject: [PATCH 058/230] Improve code. bzr revid: ysa@tinyerp.com-20110712050539-17fsv9d6angr7f97 --- .../base_export/static/src/js/base_export.js | 30 ++++++++----------- .../static/src/xml/base_export.xml | 2 +- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index 0dd98efc952..944dbdb4fb9 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -15,27 +15,21 @@ openerp.base_export.Export = openerp.base.Controller.extend({ on_loaded: function(result) { var self = this; var element_id = _.uniqueId("act_window_dialog"); - var _export = $('
', {id: element_id}).dialog({ + this._export = $('
', {id: element_id}).dialog({ title: "Export Data", modal: true, width: '50%', height: 'auto', buttons : { "Close" : function() { - _export.dialog('destroy'); + this._export.dialog('destroy'); }, "Export To File" : function() { - _export.dialog('destroy'); + this._export.dialog('destroy'); } } - }).html(QWeb.render('ExportTreeView', {'fields': result})) - - jQuery(_export).find('[id^=export]').dblclick(function(){ - self.add_field(this.id, this.text) - }); - jQuery(_export).find('[id^=parentimg]').click(function(){ - self.on_click(this.id, result); - }); + }).html(QWeb.render('ExportTreeView')) + self.on_show_data(result) }, on_click: function(id, result) { @@ -52,17 +46,19 @@ openerp.base_export.Export = openerp.base.Controller.extend({ } } if (model){ - self.get_data(model, prefix, name) + this.rpc("/base_export/export/get_fields", {"model": model, "prefix": prefix, "field_parent" : this.field_id, "name": name}, this.on_show_data, {}); } }, - get_data: function(model, prefix, name) { - this.rpc("/base_export/export/get_fields", {"model": model, "prefix": prefix, "field_parent" : this.field_id, "name": name}, this.on_show_data, {}); - }, - on_show_data: function(result) { var self = this; - $("tr[id='treerow_" + self.field_id + "']").after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); + var current_tr = $("tr[id='treerow_" + self.field_id + "']"); + if (current_tr.length >= 1){ + current_tr.after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); + } + else{ + jQuery(self._export).find('#left_field_panel').append(QWeb.render('ExportTreeView-Secondary', {'fields': result})); + } jQuery($.find('img[id ^= parentimg]')).click(function(){ self.on_click(this.id, result); }); diff --git a/addons/base_export/static/src/xml/base_export.xml b/addons/base_export/static/src/xml/base_export.xml index c0bcd72508e..5f2ab00012d 100644 --- a/addons/base_export/static/src/xml/base_export.xml +++ b/addons/base_export/static/src/xml/base_export.xml @@ -44,7 +44,7 @@ - +
From d4575451a439f27a84cceeb3fe14035749d8c57c Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Tue, 12 Jul 2011 12:44:22 +0530 Subject: [PATCH 059/230] [IMP] improve tree structure in export. bzr revid: ysa@tinyerp.com-20110712071422-wq5bal1pbepyrrdq --- .../base_export/static/src/js/base_export.js | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index 944dbdb4fb9..df5b3680f0d 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -38,22 +38,45 @@ openerp.base_export.Export = openerp.base.Controller.extend({ var model = '' var prefix = '' var name = '' + var is_loaded = 0; for (var record in result){ if(result[record]['id'] == this.field_id){ model = result[record]['params']['model'] prefix = result[record]['params']['prefix'] name = result[record]['params']['name'] + if ( (result[record]['children']).length >= 1){ + $(result[record]['children']).each (function(e, childid) { + if ($("tr[id='treerow_" + childid +"']").length > 0) { + if ($("tr[id='treerow_" + childid +"']").is(':hidden')) { + is_loaded = -1; + } else { + is_loaded++; + } + } + }); + if (is_loaded == 0) { + if ($("tr[id='treerow_" + this.field_id +"']").find('img').attr('src') == '/base/static/src/img/expand.gif') { + if (model){ + this.rpc("/base_export/export/get_fields", {"model": model, "prefix": prefix, "field_parent" : this.field_id, "name": name}, function (result) { + self.on_show_data(result, true); + }); + } + } + } else if (is_loaded > 0) { + self.showcontent(this.field_id, true); + } else { + self.showcontent(this.field_id, false); + } + } } } - if (model){ - this.rpc("/base_export/export/get_fields", {"model": model, "prefix": prefix, "field_parent" : this.field_id, "name": name}, this.on_show_data, {}); - } }, - on_show_data: function(result) { + on_show_data: function(result, flag) { var self = this; var current_tr = $("tr[id='treerow_" + self.field_id + "']"); if (current_tr.length >= 1){ + current_tr.find('img').attr('src','/base/static/src/img/collapse.gif'); current_tr.after(QWeb.render('ExportTreeView-Secondary', {'fields': result})); } else{ @@ -67,6 +90,27 @@ openerp.base_export.Export = openerp.base.Controller.extend({ }); }, + + // show & hide the contents + showcontent: function (id, flag) { + var first_child = $("tr[id='treerow_" + id + "']").find('img') + if (flag) { + first_child.attr('src', '/base/static/src/img/expand.gif'); + } + else { + first_child.attr('src', '/base/static/src/img/collapse.gif'); + } + var child_field = $("tr[id^='treerow_" + id +"/']") + for (var i = 0; i < child_field.length; i++) { + if (flag) { + $(child_field[i]).hide(); + } + else { + $(child_field[i]).show(); + } + } + }, + add_field: function(id, string) { var field_list = $('#fields_list') field_id = id.split("-")[1]; From 5ad4baccf6f78aea0eac29b9d85af3f869107397 Mon Sep 17 00:00:00 2001 From: "Yogesh (OpenERP)" Date: Tue, 12 Jul 2011 15:51:18 +0530 Subject: [PATCH 060/230] [IMP] bind click event of add button and define add_field method.. bzr revid: ysa@tinyerp.com-20110712102118-zj85dz9nved836iv --- .../base_export/static/src/js/base_export.js | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/addons/base_export/static/src/js/base_export.js b/addons/base_export/static/src/js/base_export.js index df5b3680f0d..342fffa711a 100644 --- a/addons/base_export/static/src/js/base_export.js +++ b/addons/base_export/static/src/js/base_export.js @@ -7,11 +7,15 @@ openerp.base_export.Export = openerp.base.Controller.extend({ this._super(session); this.dataset = dataset this.views = views + this.selected_field_id = ''; + this.selected_field_str = ''; }, + start: function() { this.rpc("/base_export/export/get_fields", {"model": this.dataset.model}, this.on_loaded); }, + on_loaded: function(result) { var self = this; var element_id = _.uniqueId("act_window_dialog"); @@ -22,14 +26,19 @@ openerp.base_export.Export = openerp.base.Controller.extend({ height: 'auto', buttons : { "Close" : function() { - this._export.dialog('destroy'); + self._export.dialog('destroy'); }, "Export To File" : function() { - this._export.dialog('destroy'); + self.get_fields(); } } }).html(QWeb.render('ExportTreeView')) self.on_show_data(result) + jQuery(this._export).find('#add_field').click(function(){ + if (self.selected_field_id && self.selected_field_str){ + self.add_field(self.selected_field_id, self.selected_field_str); + } + }); }, on_click: function(id, result) { @@ -85,12 +94,15 @@ openerp.base_export.Export = openerp.base.Controller.extend({ jQuery($.find('img[id ^= parentimg]')).click(function(){ self.on_click(this.id, result); }); - jQuery($.find('[id^=export]')).dblclick(function(){ + jQuery($.find('[id^=export-]')).dblclick(function(){ self.add_field(this.id, this.text) }); + jQuery($.find('[id^=export-]')).click(function(){ + self.selected_field_id = this.id; + self.selected_field_str = this.text; + }); }, - // show & hide the contents showcontent: function (id, flag) { var first_child = $("tr[id='treerow_" + id + "']").find('img') @@ -114,10 +126,23 @@ openerp.base_export.Export = openerp.base.Controller.extend({ add_field: function(id, string) { var field_list = $('#fields_list') field_id = id.split("-")[1]; - if ( !$("#fields_list option[value='" + field_id + "']").length){ + if ( $("#fields_list option[value='" + field_id + "']") && !$("#fields_list option[value='" + field_id + "']").length){ field_list.append( new Option(string, field_id)); } }, + + get_fields: function (){ + var export_field = []; + jQuery("#fields_list option").each(function(){ + export_field.push(jQuery(this).val()); + }); + if (! export_field.length){ + alert('Please select fields to export...'); + } + else { + this._export.dialog('destroy'); + } + }, }); }; From f2f83401d71705c3128d05210073c84b2d7c517a Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Tue, 12 Jul 2011 13:39:21 +0200 Subject: [PATCH 061/230] [FIX] display of old res.widget instances in home sidebar bzr revid: xmo@openerp.com-20110712113921-fwxu1p1fd5kx31l6 --- addons/base_dashboard/__init__.py | 1 + addons/base_dashboard/controllers.py | 11 +++++ .../base_dashboard/static/src/js/dashboard.js | 42 ++++--------------- .../static/src/xml/base_dashboard.xml | 4 +- openerpweb/openerpweb.py | 2 +- 5 files changed, 22 insertions(+), 38 deletions(-) create mode 100644 addons/base_dashboard/controllers.py diff --git a/addons/base_dashboard/__init__.py b/addons/base_dashboard/__init__.py index 4265cc3e6c1..80b891a3d7a 100644 --- a/addons/base_dashboard/__init__.py +++ b/addons/base_dashboard/__init__.py @@ -1 +1,2 @@ #!/usr/bin/env python +import controllers diff --git a/addons/base_dashboard/controllers.py b/addons/base_dashboard/controllers.py new file mode 100644 index 00000000000..d24649a21cc --- /dev/null +++ b/addons/base_dashboard/controllers.py @@ -0,0 +1,11 @@ +# -*- coding: utf-8 -*- +import openerpweb + +class Widgets(openerpweb.openerpweb.Controller): + _cp_path = '/base_dashboard/widgets' + + @openerpweb.httprequest + def content(self, request, widget_id): + return request.session.model('res.widget').read( + [widget_id], ['content'], request.session.eval_context(request.context) + )[0]['content'] diff --git a/addons/base_dashboard/static/src/js/dashboard.js b/addons/base_dashboard/static/src/js/dashboard.js index 3cdcbb3b218..a4c4ae86ec0 100644 --- a/addons/base_dashboard/static/src/js/dashboard.js +++ b/addons/base_dashboard/static/src/js/dashboard.js @@ -381,44 +381,18 @@ openerp.base_dashboard.Widgets = openerp.base.View.extend({ user_widget_id: widget['id'] }; }); - this.widgets.read_ids(_(user_widgets).pluck('widget_id'), [], function (widgets) { + this.widgets.read_ids(_(user_widgets).pluck('widget_id'), ['title'], function (widgets) { _(widgets).each(function (widget) { _.extend(widget, widget_user[widget['id']]); }); - var root = self.$element[0]; - root.innerHTML = QWeb.render('HomeWidgets', { - widgets: widgets - }); - - self.process_widgets_scripts(0, root.getElementsByTagName('script')); + var url = _.sprintf( + '/base_dashboard/widgets/content?session_id=%s&widget_id=', + self.session.session_id); + self.$element.html(QWeb.render('HomeWidgets', { + widgets: widgets, + url: url + })); }) - }, - process_widgets_scripts: function (index, nodes) { - if (nodes.length <= index) { - return; - } - var old_write = window.document.write, - self = this, - script = nodes[index], - deferred = $.Deferred().then(function () { - window.document.write = old_write; }), - continuation = function () { - $.when(self.process_widgets_scripts(index+1, nodes)).then( - deferred.resolve()); - }; - window.document.write = function (s) { - $(script).closest('.oe-dashboard-home-widgets-widget') - .children('div') - .append(s); - }; - - if (!script.src) { - new Function(script.firstChild.nodeValue)(); - setTimeout(continuation); - } else { - $LAB.script(script.src).wait(continuation); - } - return deferred; } }); }; diff --git a/addons/base_dashboard/static/src/xml/base_dashboard.xml b/addons/base_dashboard/static/src/xml/base_dashboard.xml index bb81aea45bd..bca78998532 100644 --- a/addons/base_dashboard/static/src/xml/base_dashboard.xml +++ b/addons/base_dashboard/static/src/xml/base_dashboard.xml @@ -102,9 +102,7 @@

-
-
- + ') + : $(''); + + var lyr2 = opts.theme + ? $('') + : $(''); + + var lyr3, s; + if (opts.theme && full) { + s = ''; + } + else if (opts.theme) { + s = ''; + } + else if (full) { + s = ''; + } + else { + s = ''; + } + lyr3 = $(s); + + // if we have a message, style it + if (msg) { + if (opts.theme) { + lyr3.css(themedCSS); + lyr3.addClass('ui-widget-content'); + } + else + lyr3.css(css); + } + + // style the overlay + if (!opts.theme && (!opts.applyPlatformOpacityRules || !($.browser.mozilla && /Linux/.test(navigator.platform)))) + lyr2.css(opts.overlayCSS); + lyr2.css('position', full ? 'fixed' : 'absolute'); + + // make iframe layer transparent in IE + if ($.browser.msie || opts.forceIframe) + lyr1.css('opacity',0.0); + + //$([lyr1[0],lyr2[0],lyr3[0]]).appendTo(full ? 'body' : el); + var layers = [lyr1,lyr2,lyr3], $par = full ? $('body') : $(el); + $.each(layers, function() { + this.appendTo($par); + }); + + if (opts.theme && opts.draggable && $.fn.draggable) { + lyr3.draggable({ + handle: '.ui-dialog-titlebar', + cancel: 'li' + }); + } + + // ie7 must use absolute positioning in quirks mode and to account for activex issues (when scrolling) + var expr = setExpr && (!$.boxModel || $('object,embed', full ? null : el).length > 0); + if (ie6 || expr) { + // give body 100% height + if (full && opts.allowBodyStretch && $.boxModel) + $('html,body').css('height','100%'); + + // fix ie6 issue when blocked element has a border width + if ((ie6 || !$.boxModel) && !full) { + var t = sz(el,'borderTopWidth'), l = sz(el,'borderLeftWidth'); + var fixT = t ? '(0 - '+t+')' : 0; + var fixL = l ? '(0 - '+l+')' : 0; + } + + // simulate fixed position + $.each([lyr1,lyr2,lyr3], function(i,o) { + var s = o[0].style; + s.position = 'absolute'; + if (i < 2) { + full ? s.setExpression('height','Math.max(document.body.scrollHeight, document.body.offsetHeight) - (jQuery.boxModel?0:'+opts.quirksmodeOffsetHack+') + "px"') + : s.setExpression('height','this.parentNode.offsetHeight + "px"'); + full ? s.setExpression('width','jQuery.boxModel && document.documentElement.clientWidth || document.body.clientWidth + "px"') + : s.setExpression('width','this.parentNode.offsetWidth + "px"'); + if (fixL) s.setExpression('left', fixL); + if (fixT) s.setExpression('top', fixT); + } + else if (opts.centerY) { + if (full) s.setExpression('top','(document.documentElement.clientHeight || document.body.clientHeight) / 2 - (this.offsetHeight / 2) + (blah = document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + "px"'); + s.marginTop = 0; + } + else if (!opts.centerY && full) { + var top = (opts.css && opts.css.top) ? parseInt(opts.css.top) : 0; + var expression = '((document.documentElement.scrollTop ? document.documentElement.scrollTop : document.body.scrollTop) + '+top+') + "px"'; + s.setExpression('top',expression); + } + }); + } + + // show the message + if (msg) { + if (opts.theme) + lyr3.find('.ui-widget-content').append(msg); + else + lyr3.append(msg); + if (msg.jquery || msg.nodeType) + $(msg).show(); + } + + if (($.browser.msie || opts.forceIframe) && opts.showOverlay) + lyr1.show(); // opacity is zero + if (opts.fadeIn) { + var cb = opts.onBlock ? opts.onBlock : noOp; + var cb1 = (opts.showOverlay && !msg) ? cb : noOp; + var cb2 = msg ? cb : noOp; + if (opts.showOverlay) + lyr2._fadeIn(opts.fadeIn, cb1); + if (msg) + lyr3._fadeIn(opts.fadeIn, cb2); + } + else { + if (opts.showOverlay) + lyr2.show(); + if (msg) + lyr3.show(); + if (opts.onBlock) + opts.onBlock(); + } + + // bind key and mouse events + bind(1, el, opts); + + if (full) { + pageBlock = lyr3[0]; + pageBlockEls = $(':input:enabled:visible',pageBlock); + if (opts.focusInput) + setTimeout(focus, 20); + } + else + center(lyr3[0], opts.centerX, opts.centerY); + + if (opts.timeout) { + // auto-unblock + var to = setTimeout(function() { + full ? $.unblockUI(opts) : $(el).unblock(opts); + }, opts.timeout); + $(el).data('blockUI.timeout', to); + } +}; + +// remove the block +function remove(el, opts) { + var full = (el == window); + var $el = $(el); + var data = $el.data('blockUI.history'); + var to = $el.data('blockUI.timeout'); + if (to) { + clearTimeout(to); + $el.removeData('blockUI.timeout'); + } + opts = $.extend({}, $.blockUI.defaults, opts || {}); + bind(0, el, opts); // unbind events + + if (opts.onUnblock === null) { + opts.onUnblock = $el.data('blockUI.onUnblock'); + $el.removeData('blockUI.onUnblock'); + } + + var els; + if (full) // crazy selector to handle odd field errors in ie6/7 + els = $('body').children().filter('.blockUI').add('body > .blockUI'); + else + els = $('.blockUI', el); + + if (full) + pageBlock = pageBlockEls = null; + + if (opts.fadeOut) { + els.fadeOut(opts.fadeOut); + setTimeout(function() { reset(els,data,opts,el); }, opts.fadeOut); + } + else + reset(els, data, opts, el); +}; + +// move blocking element back into the DOM where it started +function reset(els,data,opts,el) { + els.each(function(i,o) { + // remove via DOM calls so we don't lose event handlers + if (this.parentNode) + this.parentNode.removeChild(this); + }); + + if (data && data.el) { + data.el.style.display = data.display; + data.el.style.position = data.position; + if (data.parent) + data.parent.appendChild(data.el); + $(el).removeData('blockUI.history'); + } + + if (typeof opts.onUnblock == 'function') + opts.onUnblock(el,opts); +}; + +// bind/unbind the handler +function bind(b, el, opts) { + var full = el == window, $el = $(el); + + // don't bother unbinding if there is nothing to unbind + if (!b && (full && !pageBlock || !full && !$el.data('blockUI.isBlocked'))) + return; + if (!full) + $el.data('blockUI.isBlocked', b); + + // don't bind events when overlay is not in use or if bindEvents is false + if (!opts.bindEvents || (b && !opts.showOverlay)) + return; + + // bind anchors and inputs for mouse and key events + var events = 'mousedown mouseup keydown keypress'; + b ? $(document).bind(events, opts, handler) : $(document).unbind(events, handler); + +// former impl... +// var $e = $('a,:input'); +// b ? $e.bind(events, opts, handler) : $e.unbind(events, handler); +}; + +// event handler to suppress keyboard/mouse events when blocking +function handler(e) { + // allow tab navigation (conditionally) + if (e.keyCode && e.keyCode == 9) { + if (pageBlock && e.data.constrainTabKey) { + var els = pageBlockEls; + var fwd = !e.shiftKey && e.target === els[els.length-1]; + var back = e.shiftKey && e.target === els[0]; + if (fwd || back) { + setTimeout(function(){focus(back)},10); + return false; + } + } + } + var opts = e.data; + // allow events within the message content + if ($(e.target).parents('div.' + opts.blockMsgClass).length > 0) + return true; + + // allow events for content that is not being blocked + return $(e.target).parents().children().filter('div.blockUI').length == 0; +}; + +function focus(back) { + if (!pageBlockEls) + return; + var e = pageBlockEls[back===true ? pageBlockEls.length-1 : 0]; + if (e) + e.focus(); +}; + +function center(el, x, y) { + var p = el.parentNode, s = el.style; + var l = ((p.offsetWidth - el.offsetWidth)/2) - sz(p,'borderLeftWidth'); + var t = ((p.offsetHeight - el.offsetHeight)/2) - sz(p,'borderTopWidth'); + if (x) s.left = l > 0 ? (l+'px') : '0'; + if (y) s.top = t > 0 ? (t+'px') : '0'; +}; + +function sz(el, p) { + return parseInt($.css(el,p))||0; +}; + +})(jQuery); diff --git a/addons/base/static/lib/jquery.form/jquery.form.js b/addons/base/static/lib/jquery.form/jquery.form.js new file mode 100644 index 00000000000..66ac5142238 --- /dev/null +++ b/addons/base/static/lib/jquery.form/jquery.form.js @@ -0,0 +1,911 @@ +/*! + * jQuery Form Plugin + * version: 2.83 (11-JUL-2011) + * @requires jQuery v1.3.2 or later + * + * Examples and documentation at: http://malsup.com/jquery/form/ + * Dual licensed under the MIT and GPL licenses: + * http://www.opensource.org/licenses/mit-license.php + * http://www.gnu.org/licenses/gpl.html + */ +;(function($) { + +/* + Usage Note: + ----------- + Do not use both ajaxSubmit and ajaxForm on the same form. These + functions are intended to be exclusive. Use ajaxSubmit if you want + to bind your own submit handler to the form. For example, + + $(document).ready(function() { + $('#myForm').bind('submit', function(e) { + e.preventDefault(); // <-- important + $(this).ajaxSubmit({ + target: '#output' + }); + }); + }); + + Use ajaxForm when you want the plugin to manage all the event binding + for you. For example, + + $(document).ready(function() { + $('#myForm').ajaxForm({ + target: '#output' + }); + }); + + When using ajaxForm, the ajaxSubmit function will be invoked for you + at the appropriate time. +*/ + +/** + * ajaxSubmit() provides a mechanism for immediately submitting + * an HTML form using AJAX. + */ +$.fn.ajaxSubmit = function(options) { + // fast fail if nothing selected (http://dev.jquery.com/ticket/2752) + if (!this.length) { + log('ajaxSubmit: skipping submit process - no element selected'); + return this; + } + + var method, action, url, $form = this; + + if (typeof options == 'function') { + options = { success: options }; + } + + method = this.attr('method'); + action = this.attr('action'); + url = (typeof action === 'string') ? $.trim(action) : ''; + url = url || window.location.href || ''; + if (url) { + // clean url (don't include hash vaue) + url = (url.match(/^([^#]+)/)||[])[1]; + } + + options = $.extend(true, { + url: url, + success: $.ajaxSettings.success, + type: method || 'GET', + iframeSrc: /^https/i.test(window.location.href || '') ? 'javascript:false' : 'about:blank' + }, options); + + // hook for manipulating the form data before it is extracted; + // convenient for use with rich editors like tinyMCE or FCKEditor + var veto = {}; + this.trigger('form-pre-serialize', [this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-pre-serialize trigger'); + return this; + } + + // provide opportunity to alter form data before it is serialized + if (options.beforeSerialize && options.beforeSerialize(this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSerialize callback'); + return this; + } + + var n,v,a = this.formToArray(options.semantic); + if (options.data) { + options.extraData = options.data; + for (n in options.data) { + if(options.data[n] instanceof Array) { + for (var k in options.data[n]) { + a.push( { name: n, value: options.data[n][k] } ); + } + } + else { + v = options.data[n]; + v = $.isFunction(v) ? v() : v; // if value is fn, invoke it + a.push( { name: n, value: v } ); + } + } + } + + // give pre-submit callback an opportunity to abort the submit + if (options.beforeSubmit && options.beforeSubmit(a, this, options) === false) { + log('ajaxSubmit: submit aborted via beforeSubmit callback'); + return this; + } + + // fire vetoable 'validate' event + this.trigger('form-submit-validate', [a, this, options, veto]); + if (veto.veto) { + log('ajaxSubmit: submit vetoed via form-submit-validate trigger'); + return this; + } + + var q = $.param(a); + + if (options.type.toUpperCase() == 'GET') { + options.url += (options.url.indexOf('?') >= 0 ? '&' : '?') + q; + options.data = null; // data is null for 'get' + } + else { + options.data = q; // data is the query string for 'post' + } + + var callbacks = []; + if (options.resetForm) { + callbacks.push(function() { $form.resetForm(); }); + } + if (options.clearForm) { + callbacks.push(function() { $form.clearForm(); }); + } + + // perform a load on the target only if dataType is not provided + if (!options.dataType && options.target) { + var oldSuccess = options.success || function(){}; + callbacks.push(function(data) { + var fn = options.replaceTarget ? 'replaceWith' : 'html'; + $(options.target)[fn](data).each(oldSuccess, arguments); + }); + } + else if (options.success) { + callbacks.push(options.success); + } + + options.success = function(data, status, xhr) { // jQuery 1.4+ passes xhr as 3rd arg + var context = options.context || options; // jQuery 1.4+ supports scope context + for (var i=0, max=callbacks.length; i < max; i++) { + callbacks[i].apply(context, [data, status, xhr || $form, $form]); + } + }; + + // are there files to upload? + var fileInputs = $('input:file', this).length > 0; + var mp = 'multipart/form-data'; + var multipart = ($form.attr('enctype') == mp || $form.attr('encoding') == mp); + + // options.iframe allows user to force iframe mode + // 06-NOV-09: now defaulting to iframe mode if file input is detected + if (options.iframe !== false && (fileInputs || options.iframe || multipart)) { + // hack to fix Safari hang (thanks to Tim Molendijk for this) + // see: http://groups.google.com/group/jquery-dev/browse_thread/thread/36395b7ab510dd5d + if (options.closeKeepAlive) { + $.get(options.closeKeepAlive, function() { fileUpload(a); }); + } + else { + fileUpload(a); + } + } + else { + // IE7 massage (see issue 57) + if ($.browser.msie && method == 'get') { + var ieMeth = $form[0].getAttribute('method'); + if (typeof ieMeth === 'string') + options.type = ieMeth; + } + $.ajax(options); + } + + // fire 'notify' event + this.trigger('form-submit-notify', [this, options]); + return this; + + + // private function for handling file uploads (hat tip to YAHOO!) + function fileUpload(a) { + var form = $form[0], el, i, s, g, id, $io, io, xhr, sub, n, timedOut, timeoutHandle; + var useProp = !!$.fn.prop; + + if (a) { + // ensure that every serialized input is still enabled + for (i=0; i < a.length; i++) { + el = $(form[a[i].name]); + el[ useProp ? 'prop' : 'attr' ]('disabled', false); + } + } + + if ($(':input[name=submit],:input[id=submit]', form).length) { + // if there is an input with a name or id of 'submit' then we won't be + // able to invoke the submit fn on the form (at least not x-browser) + alert('Error: Form elements must not have name or id of "submit".'); + return; + } + + s = $.extend(true, {}, $.ajaxSettings, options); + s.context = s.context || s; + id = 'jqFormIO' + (new Date().getTime()); + if (s.iframeTarget) { + $io = $(s.iframeTarget); + n = $io.attr('name'); + if (n == null) + $io.attr('name', id); + else + id = n; + } + else { + $io = $('"},load:function(a){this.src_setter(a)},src_setter:function(a){this.g.childNodes[0].src=a;this.callEvent("onXLS",[]);dhx.delay(this.Je,this);return a},Je:function(){try{dhx.event(this.getWindow(),"load",dhx.bind(function(){this.callEvent("onXLS",[])},this))}catch(a){this.callEvent("onXLE",[])}},getWindow:function(){return this.g.childNodes[0].contentWindow}, +waitMessage_setter:function(a){dhx.extend(this,dhx.ui.overlay);return a}},dhx.ui.view,dhx.EventSystem); +dhx.ui.overlay={$init:function(){if(dhx.isNotDefined(this.ba)&&this.attachEvent)this.attachEvent("onXLS",this.showOverlay),this.attachEvent("onXLE",this.hideOverlay),this.ba=null},showOverlay:function(){if(!this.ba)this.ba=dhx.html.create("DIV",{"class":"dhx_loading_overlay"},""),dhx.html.insertBefore(this.ba,this.b.firstChild,this.b)},hideOverlay:function(){if(this.ba)dhx.html.remove(this.ba),this.ba=null}}; +dhx.protoUI({name:"scrollview",defaults:{scroll:"x",scrollSpeed:"0ms"},$init:function(){this.b.className+=" dhx_scrollview"},content_setter:function(a){this.ha=dhx.ui.Oa(a);this.ha.D=this;this.d.appendChild(this.ha.b)},body_setter:function(a){return this.content_setter(a)},$getSize:function(){this.ga=this.ha.$getSize();if(this.a.scroll=="x"&&this.ga[3]>0)this.a.height=this.ga[3];else if(this.a.scroll=="y"&&this.ga[1]>0)this.a.width=this.ga[1];return dhx.ui.view.prototype.$getSize.call(this)},$setSize:function(a, +b){if(dhx.ui.view.prototype.$setSize.call(this,a,b))this.ha.$setSize(Math.max(this.ga[1],this.j),Math.max(this.ga[3],this.m)),this.d.style.width=this.ha.j+"px",this.d.style.height=this.ha.m+"px"}},dhx.Scrollable,dhx.ui.view);dhx.CanvasMgr=function(a){var b=dhx.CanvasMgr.prototype.qc;!b[a]&&document.getCSSCanvasContext&&(b[a]=!0,dhx.CanvasMgr.prototype[a](b))}; +dhx.CanvasMgr.prototype={buttonGrd:["#fefefe","#e0e0e0","#e5e5e5","#e0e0e0",32],qc:[],Pa:function(a,b,c,d,e){var f=document.getCSSCanvasContext("2d",d,18,c),g=f.createLinearGradient(0,0,0,c);g.addColorStop(0,a);g.addColorStop(1,b);f.fillStyle=g;f.strokeStyle="#93B0BA";f.lineWidth=2;e?(f.moveTo(0,0.5),f.lineTo(17.5,c/2+0.5),f.lineTo(0,c-0.5),f.lineTo(0,0.5)):(f.moveTo(18,0.5),f.lineTo(0.5,c/2+0.5),f.lineTo(18,c-0.5),f.lineTo(18,0.5));f.stroke();f.fill()},dhxArrowLeftT:function(){this.Pa(this.buttonGrd[2], +this.buttonGrd[3],this.buttonGrd[4],"dhxArrowLeftT")},dhxArrowRightT:function(){this.Pa(this.buttonGrd[2],this.buttonGrd[3],this.buttonGrd[4],"dhxArrowRightT",!0)},dhxArrowLeft:function(){this.Pa(this.buttonGrd[0],this.buttonGrd[1],this.buttonGrd[4],"dhxArrowLeft");dhx.CanvasMgr("dhxArrowLeftT")},dhxArrowRight:function(){this.Pa(this.buttonGrd[0],this.buttonGrd[1],this.buttonGrd[4],"dhxArrowRight",!0);dhx.CanvasMgr("dhxArrowRightT")}}; +dhx.attachEvent("onClick",function(a){var b=dhx.ui.get(a);if(b&&b.touchable){b.getNode(a);var c=a.target||a.srcElement,d="",e=null,f=!1;if(!(c.className&&c.className.indexOf("dhx_view")===0)){for(;c&&c.parentNode;){if(c.getAttribute){if(c.getAttribute("view_id"))break;if(d=c.className)if(d=d.split(" "),d=d[0]||d[1],b.on_click[d]){var g=b.on_click[d].call(b,a,b.a.id,c);if(g===!1)return}}c=c.parentNode}if(b.a.click){var h=dhx.toFunctor(b.a.click);h&&h.call&&h.call(b,b.a.id,a)}if(b.a.multiview){var i= +dhx.ui.get(b.a.multiview);i&&i.show&&i.show()}if(b.a.popup){var j=dhx.ui.get(b.a.popup);j.a.master=b.a.id;j.show(b.getInput()||b.getNode(),j.h.a.align||"bottom",!0)}b.callEvent("onItemClick",[b.a.id,a])}}}); +dhx.protoUI({name:"button",touchable:!0,defaults:{template:"
",height:42,label:"label",s:10},$init:function(a){this.data=this.a;this.d=this.b;dhx.sa&&(dhx.sa.elements[a.name||a.id]=this,this.mapEvent({onbeforetabclick:dhx.sa,onaftertabclick:dhx.sa,onitemclick:dhx.sa}));a.type=="prev"&&dhx.CanvasMgr("dhxArrowLeft");a.type=="next"&&dhx.CanvasMgr("dhxArrowRight")},type_setter:function(a){this.a.template=dhx.Template(this.pd[a][0]); +var b=this.pd[a][1];if(b)this.a.s=b},pd:{round:["
"],"default":["
"],form:[function(a){return"
"}],prev:["
",28],next:["
",28],big:["
",28],biground:["
", +28]},$setSize:function(a,b){dhx.ui.view.prototype.$setSize.call(this,a,b)&&this.render()},K:function(a){this.a.label=a;this.getInput().value=a},getValue:function(){return this.d.childNodes.length>0?this.ab():this.a.value},setValue:function(a){var b=this.a.value;this.a.value=a;if(this.d.childNodes.length>0)this.Md=a,this.K(a),this.callEvent("onChange",[a,b])},focus:function(){this.getInput().focus()},ab:function(){return this.a.label||""},getInput:function(){return this.d.getElementsByTagName("input")[0]}, +J:function(){return this.getInput()},Z:function(){this.a.inputWidth?this.J().style.width=this.a.inputWidth-this.a.s+"px":this.J().style.width=this.j-this.a.s+"px"},render:function(){if(dhx.AtomRender.render.call(this)){this.Z();if(this.a.align)switch(this.a.align){case "right":this.d.firstChild.style.cssFloat=this.d.firstChild.style.styleFloat="right";break;case "center":this.d.firstChild.style.display="inline-block";this.d.firstChild.parentNode.style.textAlign="center";break;case "middle":this.d.firstChild.style.marginTop= +Math.round((this.m-40)/2)+"px";break;case "bottom":this.d.firstChild.style.marginTop=this.m-40+"px";break;case "left":this.d.firstChild.parentNode.style.textAlign="left"}this.Aa&&this.Aa(this.data);this.Md!=this.a.value&&this.setValue(this.a.value)}},refresh:function(){this.render()},on_click:{Ib:function(a,b){var c=dhx.html.locate(a,"button_id");if(c&&this.callEvent("onBeforeTabClick",[b,c])){this.a.selected=c;this.refresh();if(this.a.multiview){var d=dhx.ui.get(c);d&&d.show&&d.show()}this.callEvent("onAfterTabClick", +[b,c])}},dhx_el_segmented:function(a,b){this.on_click.Ib.call(this,a,b)},dhx_el_tabbar:function(a,b){this.on_click.Ib.call(this,a,b)},dhx_inp_counter_next:function(){this.next(this.a.step,this.a.min,this.a.max)},dhx_inp_counter_prev:function(){this.prev(this.a.step,this.a.min,this.a.max)},dhx_inp_toggle_left_off:function(){var a=this.a.options;this.setValue(a[0].value)},dhx_inp_toggle_right_off:function(){var a=this.a.options;this.setValue(a[1].value)},dhx_inp_combo:function(a,b,c){c.focus()},dhx_inp_checkbox_border:function(){this.toggle()}, +dhx_inp_checkbox_label:function(){this.toggle()},dhx_inp_radio_border:function(a){var b=dhx.html.locate(a,"radio_id");this.setValue(b)},dhx_inp_radio_label:function(a,b,c){c=c.parentNode.getElementsByTagName("input")[0];return this.on_click.dhx_inp_radio_border.call(this,c,b,c)}},Ba:function(a){for(var b=0;b #label#
",label:""},Z:function(){}},dhx.ui.button);dhx.protoUI({name:"label",defaults:{template:"
#label#
"},focus:function(){return!1},J:function(){return this.d.firstChild},K:function(a){this.a.label=a;this.d.firstChild.innerHTML=a}},dhx.ui.button); +dhx.protoUI({name:"icon",defaults:{template:"
",width:42},Z:function(){}},dhx.ui.button); +dhx.protoUI({name:"segmented",defaults:{template:function(a,b){var c=a.options,d="",e;b.Ba(c);if(!a.selected)a.selected=c[0].value;for(var f=0;f"+c[f].label+"
";return"
"+d+"
"},s:28,nb:0},K:function(a){if(this.d&& +this.d.firstChild)for(var b=this.d.firstChild.childNodes,c=0;c";d+=h?""+c[f].label+"":"
"+ +c[f].label+"";d+="
"}return"
"+d+"
"},s:4}},dhx.ui.segmented); +dhx.protoUI({name:"text",wd:!0,$b:function(a,b,c){c.labelPosition=="left"?a+=b:a=b+a;return"
"+a+"
"},pb:function(a,b,c,d){var e=a.inputAlign||"left",f=a.labelAlign||"left",g=dhx.uid(),h="
";h+="
";var i=this.a.inputWidth-this.a.labelWidth-18;i<0&&(i= +0);h+=d?"
"+(a.text||a.value||"")+"
":"";h+="
";return"
"+h+"
"},qb:function(a, +b){if(!a.label)return"";var c=a.labelAlign||"left";return"
"+a.label+"
"},defaults:{template:function(a,b){return b.pb(a,"text")},labelWidth:80,s:28,nb:0},type_setter:function(a){return a},Z:function(){this.a.inputWidth?this.J().style.width=this.a.inputWidth-this.a.labelWidth-this.a.s+"px":this.J().style.width=this.j-this.a.labelWidth-this.a.s-this.a.nb+"px"},focus:function(){var a=this.d.getElementsByTagName("input")[0]; +a&&a.focus()},K:function(a){this.getInput().value=a},ab:function(){return this.getInput().value}},dhx.ui.button); +dhx.protoUI({name:"toggle",defaults:{template:function(a,b){var c=a.options;b.Ba(c);var d=b.a.inputWidth/2||"auto",e=[c[0].width||d,c[1].width||d],f=b.qb(a,"toggle"),g="";g+="";return b.$b(f,g,a)},label:"",labelWidth:0,s:20},Z:function(){},Aa:function(a){this.setValue(a.value)},$a:function(){return this.d.getElementsByTagName("input")}, +K:function(a){var b=this.$a(),c=this.a.options;a==c[1].value?(b[0].className="dhx_inp_toggle_left_off",b[1].className="dhx_inp_toggle_right_on"):(b[0].className="dhx_inp_toggle_left_on",b[1].className="dhx_inp_toggle_right_off")},ab:function(){var a=this.$a(),b=this.a.options;return a[0].className=="dhx_inp_toggle_left_on"?b[0].value:b[1].value}},dhx.ui.text); +dhx.protoUI({name:"input",defaults:{attributes:["maxlength","disabled","placeholder"],template:function(a,b){for(var c=""+c+"
"},s:28,labelWidth:0}},dhx.ui.text); +dhx.protoUI({name:"select",defaults:{template:function(a,b){var c=a.options;b.Ba(c);var d=""+c[e].label+"";d+="";return"
"+d+"
"},labelWidth:0,nb:0,s:10},getInput:function(){return this.d.firstChild.firstChild}},dhx.ui.text); +dhx.protoUI({name:"textarea",defaults:{template:function(a){return"
"},cssContant:28},Z:function(){this.a.inputWidth?this.J().style.width=this.a.inputWidth-this.a.cssContant+"px":this.J().style.width=this.j-this.a.nb-this.a.cssContant+"px";this.a.inputHeight?this.J().style.height=this.a.inputHeight+"px":this.J().style.height=this.m-9+"px"},getInput:function(){return this.d.firstChild.firstChild}, +K:function(a){this.getInput().value=a},ab:function(){return this.getInput().value}},dhx.ui.text); +dhx.protoUI({name:"counter",defaults:{template:function(a,b){var c=a.value||0,d=b.qb(a,"counter"),e="";e+="
"+c+"
";e+="";return b.$b(d,e,a)},min:1,step:1,labelWidth:0,label:"",s:145},J:function(){return this.getInput().parentNode},getLabel:function(){return this.getInput().previousSibling||this.getInput().parentNode.lastChild},Z:function(){if(this.a.label&& +!this.a.labelWidth){var a=this.getLabel();if(a)a.style.width=(this.a.inputWidth||this.j)-this.a.s+"px"}},K:function(a){this.getInput().nextSibling.innerHTML=a},getValue:function(){return(this.a.value||0)*1},next:function(a,b,c){a=a||1;this.kd(a,b,c)},prev:function(a,b,c){a=-1*(a||1);this.kd(a,b,c)},kd:function(a,b,c){var b=typeof b=="undefined"?-Infinity:b,c=typeof c=="undefined"?Infinity:c,d=this.getValue()+a;d>=b&&d<=c&&this.setValue(d)}},dhx.ui.text); +dhx.protoUI({name:"checkbox",defaults:{template:function(a,b){var c=a.value?"dhx_inp_checkbox_on":"dhx_inp_checkbox_on hidden",d="
",e=b.qb(a,"checkbox");return b.$b(e,d,a)}},K:function(a){var b=this.getInput();b.className=a?"dhx_inp_checkbox_on":"dhx_inp_checkbox_on hidden"},toggle:function(){this.setValue(!this.getValue())},getLabel:function(){var a=this.getInput().parentNode;return a.nextSibling||a.previousSibling}, +getValue:function(){return this.a.value?1:0},J:function(){return this.getInput().parentNode.parentNode}},dhx.ui.counter); +dhx.protoUI({name:"radio",defaults:{template:function(a,b){b.Ba(a.options);for(var c=[],d=0;d");var e="
";a.label=a.options[d].label;var f=b.qb(a,"radio");a.labelPosition=="left"?c.push(f+e):c.push(e+f)}return"
"+ +c.join("
")+"
"}},$getSize:function(){var a=dhx.ui.button.prototype.$getSize.call(this);if(this.a.options){for(var b=1,c=0;c]*>/g,""):this.getInput().innerHTML=c},getValue:function(){return this.a.value}},dhx.ui.text); +dhx.protoUI({name:"combo",defaults:{template:function(a,b){return b.pb(a,"combo")},filter:function(a,b){return a.value.toString().toLowerCase().indexOf(b.toLowerCase())===0?!0:!1}},Y:function(a){a.popup||this.Cb("list",a);this.dc();dhx.event(this.d,"keydown",function(b){var b=b||event,c=b.target||b.srcElement,d=dhx.ui.get(a.popup);window.clearTimeout(d.key_timer);var e=this;d.key_timer=window.setTimeout(function(){d.h.filter(function(a){return e.a.filter.apply(e,[a,c.value])});var a=dhx.ui.get(d.a.master); +a.a.value=d.h.dataCount()==1&&d.h.type.template(d.h.item(d.h.first()))==c.value?d.h.first():""},200);d.show(c,d.h.a.align||"bottom",!0)},this);this.Y=function(){}},Aa:function(a){this.Y(a);dhx.isNotDefined(a.value)||this.setValue(a.value)}},dhx.ui.richselect); +dhx.protoUI({name:"datepicker",defaults:{template:function(a,b){return b.pb(a,"list",!0,!0)}},Y:function(a){a.popup||this.Cb("calendar",a);var b=dhx.ui.get(a.popup);b.h.attachEvent("onDateSelect",function(a){var b=dhx.ui.get(this.getParent().a.master);this.getParent().hide();b.setValue(a)});this.Y=function(){}},Aa:function(a){this.Y(a);dhx.isNotDefined(a.value)||this.setValue(a.value)},K:function(a){var b=dhx.ui.get(this.a.popup.toString()),c=b.h;typeof a=="string"&&a&&(a=(this.a.dateFormat||dhx.i18n.dateFormatDate)(a)); +c.selectDate(a,!0);this.a.value=a?c.config.date:"";this.getInput().innerHTML=a?(this.a.dateFormatStr||dhx.i18n.dateFormatStr)(this.a.value):""},dateFormat_setter:function(a){this.a.dateFormatStr=dhx.Date.dateToStr(a);return dhx.Date.strToDate(a)},getValue:function(){return this.a.value||null}},dhx.ui.richselect); +dhx.ValidateData={validate:function(a){var b=!0,c=this.a.rules;if(c){var d=c.$obj;!a&&this.getValues&&(a=this.getValues());if(d&&!d.call(this,a))return!1;var e=c.$all,f;for(f in c)f.indexOf("$")!==0&&(c[f].call(this,a[f],a,f)&&(!e||e.call(this,a[f],a,f))?this.callEvent("onValidationSuccess",[f,a])&&this.tc&&this.tc(f,a):(b=!1,this.callEvent("onValidationError",[f,a])&&this.Lc&&this.Lc(f,a)))}return b}}; +dhx.rules={isNumber:function(a){return parseFloat(a)==a},isNotEmpty:function(a){return a=="0"||a}}; +dhx.RenderStack={$init:function(){this.F=document.createElement("DIV");this.data.attachEvent("onIdChange",dhx.bind(this.Zb,this));this.attachEvent("onItemClick",this.Dd);if(!this.types)this.types={"default":this.type},this.type.name="default";this.type=dhx.copy(this.types[this.type.name])},customize:function(a){dhx.Type(this,a)},type_setter:function(a){this.types[a]?(this.type=dhx.copy(this.types[a]),this.type.css&&(this.g.className+=" "+this.type.css)):this.customize(a);return a},template_setter:function(a){this.type.template= +dhx.Template(a)},xa:function(a){this.callEvent("onItemRender",[a]);return this.type.templateStart(a,this.type)+(a.$template?this.type["template"+a.$template]:this.type.template)(a,this.type)+this.type.templateEnd(a,this.type)},ld:function(a){this.F.innerHTML=this.xa(a);return this.F.firstChild},Zb:function(a,b){var c=this.pa(a);c&&(c.setAttribute(this.ma,b),this.B[b]=this.B[a],delete this.B[a])},Dd:function(){if(this.a.click){var a=dhx.toFunctor(this.a.click);a&&a.call&&a.apply(this,arguments)}}, +pa:function(a){if(this.B)return this.B[a];this.B={};for(var b=this.d.childNodes,c=0;c0&&(!this.r||!this.a.scroll))this.a.height=a[3];if(a[1]>0&&(this.r||!this.a.scroll))this.a.width=a[1];a=dhx.ui.view.prototype.$getSize.call(this);if(a[3]<=0&&this.Db> +0)a[3]=this.Db,a[2]=0;return a},$setSize:function(a,b){dhx.ui.view.prototype.$setSize.apply(this,arguments);dhx.ui.baselayout.prototype.$setSize.call(this,this.j,this.m)},render:function(){if(this.isVisible(this.a.id)&&this.fc)this.setValues(this.fc),this.fc=null},refresh:function(){this.render()},type_setter:function(a){this.g.className+=" dhx_"+a.toLowerCase()}},dhx.Scrollable,dhx.AtomDataLoader,dhx.Values,dhx.ui.baselayout,dhx.EventSystem,dhx.ValidateData); +dhx.protoUI({name:"form",defaults:{scroll:!0},Db:-1,Vc:function(a){this.g.className+=" dhx_form";if(a.elements)this.Q=a.elements,this.r=!0;delete a.elements;dhx.sa=this},type_setter:function(){}},dhx.ui.toolbar); +dhx.MouseEvents={$init:function(){this.on_click&&dhx.event(this.g,"click",this.me,this);this.on_context&&dhx.event(this.g,"contextmenu",this.ne,this);this.on_dblclick&&dhx.event(this.g,"dblclick",this.oe,this);this.on_mouse_move&&(dhx.event(this.g,"mousemove",this.Rc,this),dhx.event(this.g,dhx.env.isIE?"mouseleave":"mouseout",this.Rc,this))},me:function(a){return this.Ja(a,this.on_click,"ItemClick")},oe:function(a){return this.Ja(a,this.on_dblclick,"ItemDblClick")},ne:function(a){if(this.Ja(a,this.on_context, +"BeforeContextMenu"))return this.Ja(a,{},"AfterContextMenu"),dhx.html.preventEvent(a)},Rc:function(a){dhx.env.isIE&&(a=document.createEventObject(event));this.Nc&&window.clearTimeout(this.Nc);this.callEvent("onMouseMoving",[a]);this.Nc=window.setTimeout(dhx.bind(function(){a.type=="mousemove"?this.pe(a):this.qe(a)},this),500)},pe:function(a){this.Ja(a,this.on_mouse_move,"MouseMove")||this.callEvent("onMouseOut",[a||event])},qe:function(a){this.callEvent("onMouseOut",[a||event])},Ja:function(a,b,c){for(var a= +a||event,d=a.target||a.srcElement,e="",f=null,g=!1;d&&d.parentNode;){if(!g&&d.getAttribute&&(f=d.getAttribute(this.ma))){d.getAttribute("userdata")&&this.callEvent("onLocateData",[f,d]);if(!this.callEvent("on"+c,[f,a,d]))return;g=!0}if(e=d.className)if(e=e.split(" "),e=e[0]||e[1],b[e]){var h=b[e].call(this,a,f||dhx.html.locate(a,this.ma),d);if(typeof h!="undefined"&&h!==!0)return}d=d.parentNode}return g}}; +dhx.SelectionModel={$init:function(){this.i=dhx.toArray();this.data.attachEvent("onStoreUpdated",dhx.bind(this.Pd,this));this.data.attachEvent("onStoreLoad",dhx.bind(this.Od,this));this.data.attachEvent("onAfterFilter",dhx.bind(this.Nd,this));this.data.attachEvent("onChangeId",dhx.bind(this.Zd,this))},Zd:function(a,b){for(var c=this.i.length-1;c>=0;c--)this.i[c]==a&&(this.i[c]=b)},Nd:function(){for(var a=this.i.length-1;a>=0;a--){if(this.data.indexById(this.i[a])<0)var b=this.i[a];var c=this.item(b); +c&&delete c.$selected;this.i.splice(a,1);this.callEvent("onSelectChange",[b])}},Pd:function(a,b,c){if(c=="delete")this.i.remove(a);else if(!this.data.dataCount()&&!this.data.p)this.i=dhx.toArray()},Od:function(){this.a.select&&this.data.each(function(a){a.$selected&&this.select(a.id)},this)},ub:function(a,b,c){if(!c&&!this.callEvent("onBeforeSelect",[a,b]))return!1;this.data.item(a).$selected=b;c?c.push(a):(b?this.i.push(a):this.i.remove(a),this.Vb(a));return!0},select:function(a,b,c){if(!a)return this.selectAll(); +if(dhx.isArray(a))for(var d=0;d100||a.length>this.data.dataCount/ +2},Vb:function(a){typeof a!="object"&&(a=[a]);if(a.length){if(this.ee(a))this.data.refresh();else for(var b=0;b=0?b[c]:null},nextSibling:function(a){var b=this.branch[this.item(a).$parent],c=dhx.PowerArray.find.call(b,a)+1;return c0&&this.groupBy(g,f[l],!0,l,e+1)}else{var n= +arguments,g=[];this.branch={0:[]};for(l=n.length-1;l>=0;l--)g.push(n[l]);this.groupBy(g,this.pull,!0,"0",0);this.refresh()}}};dhx.animate=function(a,b){if(dhx.isArray(a))for(var c=0;c1){for(var d=0;d=0;b--)dhx.html.remove(a[b])}}; +dhx.protoUI({name:"list",$init:function(){this.data.provideApi(this,!0)},defaults:{select:!1,scroll:!0},ma:"dhx_l_id",on_click:{dhx_list_item:function(a,b){if(this.a.select)this.ra=!0,this.a.select=="multiselect"?this.select(b,a.ctrlKey,a.shiftKey):this.select(b),this.ra=!1}},$getSize:function(){if(this.type.width!="auto")this.a.width=this.type.width+(this.type.padding+this.type.margin)*2;if(this.a.yCount)this.a.height=(this.type.height+(this.type.padding+this.type.margin)*2+1)*(this.a.yCount=="auto"? +this.dataCount():this.a.yCount);return dhx.ui.view.prototype.$getSize.call(this)},$setSize:function(){dhx.ui.view.prototype.$setSize.apply(this,arguments)},type:{css:"",widthSize:function(a,b){return b.width+(b.width>-1?"px":"")},heightSize:function(a,b){return b.height+(b.height>-1?"px":"")},template:dhx.Template("#value#"),width:"auto",height:22,margin:0,padding:10,border:1,templateStart:dhx.Template("
"), +templateEnd:dhx.Template("
")}},dhx.MouseEvents,dhx.SelectionModel,dhx.Scrollable,dhx.ui.proto); +dhx.protoUI({name:"grouplist",defaults:{animate:{}},$init:function(){dhx.extend(this.data,dhx.TreeStore,!0);this.data.provideApi(this,!0);this.data.attachEvent("onClearAll",dhx.bind(this.Qc,this));this.b.className+=" dhx_grouplist";this.Qc()},Qc:function(){this.aa=[];this.z=[]},on_click:{dhx_list_item:function(a,b){if(this.oa)return!1;for(var c=0;c"), +templateBack:dhx.Template("< #value#"),templateItem:dhx.Template("#value#"),templateGroup:dhx.Template("#value#"),templateEnd:function(a){var b="";a.$count&&(b+="
");b+="";return b}},showItem:function(a){var b,c;if(a&&(b=this.item(a),c=b.$parent,b.$count))c=b.id;this.aa=this.data.branch[c||0];for(this.z=[];c;)this.item(c).$template="Back",this.z.unshift(c),c=this.item(c).$parent;this.ra=!0;this.render();this.ra=!1;dhx.RenderStack.showItem.call(this,a)}},dhx.ui.list); +dhx.Type(dhx.ui.grouplist,{}); +dhx.protoUI({name:"pagelist",defaults:{scroll:"x",panel:!1,scrollOffset:0},Yd:!0,$init:function(a){this.b.className+=" dhx_pagelist";a.scroll=a.scroll=="y"?"y":"x";this.type.layout=a.scroll;this.attachEvent("onAfterRender",this.Ie);this.$ready.push(this.zb);this.l=0},zb:function(){if(this.a.scroll=="x")this.d.style.height="100%";this.type.layout=this.a.scroll;this.attachEvent("onAfterScroll",this.Ld)},Ie:function(){if(this.a.scroll=="x")this.d.style.width=(this.type.width+(this.type.padding+this.type.margin)* +2+this.type.border)*this.dataCount()+"px";this.a.panel&&this.Wb()},panel_setter:function(a){a&&(this.b.className+=" hidden_scroll",a===!0&&(a={}),this.Ia(a,{size:16,itemSize:16,align:"bottom"}));return a},bd:function(a){var b=this.indexById(a);if(typeof b!="undefined"&&this.a.panel)this.l=b,this.Xb()},getActive:function(){return this.l?this.data.order[this.l]:this.first()},Ld:function(a){var b=(this.a.scroll=="y"?this.type.height:this.type.width)+(this.type.padding+this.type.margin)*2+this.type.border, +c=this.a.scroll=="y"?this.d.scrollHeight-this.m:this.d.scrollWidth-this.j,d;this.a.scroll=="y"?(d=Math.round(a.f/b),a.f=d*b,a.f=this.uc(a.f,c)):(d=Math.round(a.e/b),a.e=d*b,a.e=this.uc(a.e,c));this.l=-d;this.a.panel&&this.Xb();return!0},uc:function(a,b){var c=this.a.scrollOffset;if(c&&Math.abs(a)>c){var d=dhx.Touch.A[dhx.Touch.H]>dhx.Touch.w[dhx.Touch.H];a+=d?c:1-c}Math.abs(a)>b&&(a=-b);return a},$getSize:function(){if(this.a.scroll=="y"){if(this.type.width!="auto")this.a.width=this.type.width+(this.type.padding+ +this.type.margin)*2+this.type.border;if(this.a.yCount)this.a.height=(this.type.height+(this.type.padding+this.type.margin)*2+this.type.border)*(this.a.yCount=="auto"?this.dataCount():this.a.yCount)}else if(this.type.height!="auto")this.a.height=this.type.height+(this.type.padding+this.type.margin)*2+this.type.border;return dhx.ui.view.prototype.$getSize.call(this)},$setSize:function(a,b){if(dhx.ui.view.prototype.$setSize.apply(this,arguments)){if(this.type.fullScreen)this.type.width=this.j,this.type.height= +this.m,this.type.padding=0,this.render();this.a.panel&&this.Wb()}},type:{templateStart:function(a,b){var c="dhx_list_item dhx_list_"+b.css+"_item"+(a.$selected?"_selected":""),d="width:"+b.width+"px; height:"+b.height+"px; padding:"+b.padding+"px; margin:"+b.margin+"px; overflow:hidden;"+(b.layout&&b.layout=="x"?"float:left;":"");return"
"}}},dhx.ui.list,dhx.CarouselPanel); +dhx.protoUI({name:"multiview",defaults:{animate:{}},$init:function(){this.l=0;this.r=1;this.b.style.position="relative";this.b.className+=" dhx_multiview";this.M=[]},xd:function(a,b){var c=dhx.ui.get(a);if(!c.La)c.rb=[],c.La={};c.La[b]||(c.La[b]=!0,c.rb.push(b))},Yb:function(a){var b=dhx.ui.get(a);this.M[this.M.length-2]!=a?(this.M.length==10&&this.M.splice(0,1),this.M.push(a)):this.M.splice(this.M.length-1,1);if(b.La){for(var c=0;c-1)a[3]=this.a.height,a[2]= +0;if(this.a.width>-1)a[1]=this.a.width,a[0]=0;a[0]&&(a[1]=0);a[2]&&(a[3]=0);return a},$setSize:function(a,b){dhx.ui.baseview.prototype.$setSize.call(this,a,b);this.c[this.l].$setSize(a,b)},isVisible:function(a,b){return b&&b!=this.getActive()?(a&&this.xd(b,a),!1):dhx.ui.view.prototype.isVisible.call(this,a,this.a.id)},getActive:function(){return this.c.length?this.c[this.l].a.id:null},back:function(a){a=a||1;if(this.callEvent("onBeforeBack",[this.getActive(),a])&&this.M.length>a){var b=this.M[this.M.length- +a-1];dhx.ui.get(b).show();return b}return null}},dhx.ui.baselayout,dhx.EventSystem);dhx.html.addMeta=function(a,b){document.getElementsByTagName("head").item(0).appendChild(dhx.html.create("meta",{name:a,content:b}))}; +(function(){var a=function(){var a=!!(window.orientation%180);if(dhx.ui.orientation!==a)dhx.ui.orientation=a,dhx.callEvent("onRotate",[a])};dhx.ui.orientation=!!((dhx.isNotDefined(window.orientation)?90:window.orientation)%180);dhx.event(window,"onorientationchange"in window?"orientationchange":"resize",a);dhx.ui.fullScreen=function(){dhx.html.addMeta("apple-mobile-web-app-capable","yes");dhx.html.addMeta("viewport","initial-scale = 1.0, maximum-scale = 1.0, user-scalable = no");if(dhx.env.touch){var b= +document.body.offsetHeight,c=navigator.userAgent.indexOf("iPhone")!=-1,d=c&&(b==356||b==208||b==306||b==158),e=function(){if(c)dhx.ui.orientation?(b=480,e=d?268:300):(b=320,e=d?416:460);else{document.body.style.width=document.body.style.height="1px";document.body.style.overflow="hidden";var a=window.outerWidth/window.innerWidth,b=window.outerWidth/a,e=window.outerHeight/a}document.body.style.height=e+"px";document.body.style.width=b+"px";dhx.ui.yc=!1;dhx.ui.resize();dhx.delay(function(){window.scrollTo(0, +1)})},f=function(){dhx.ui.yc=!0;dhx.env.isSafari?e():dhx.delay(e,null,[],500)};dhx.attachEvent("onClick",function(a){a.target.tagName=="INPUT"||a.target.tagName=="TEXTAREA"||a.target.tagName=="SELECT"||(d&&window.innerHeight<416||!d&&window.innerHeight0;)c=this.Ve[a%16]+c,a=Math.floor(a/16);for(;c.length0?c[0].substr(f,e):c[0].substr(0,e+f),d=g+(d?b.groupDelimiter+d:"")}while(f>0);return d+b.decimalDelimeter+c[1]},numToStr:function(a){return function(b){return dhx.Number.format(b,a)}}}; +dhx.Date={Locale:{month_full:"January,February,March,April,May,June,July,August,September,October,November,December".split(","),month_short:"Jan,Feb,Mar,Apr,May,Jun,Jul,Aug,Sep,Oct,Nov,Dec".split(","),day_full:"Sunday,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday".split(","),day_short:"Sun,Mon,Tue,Wed,Thu,Fri,Sat".split(",")},weekStart:function(a){var b=a.getDay();this.config.start_on_monday&&(b===0?b=6:b--);return this.date_part(this.add(a,-1*b,"day"))},monthStart:function(a){a.setDate(1);return this.date_part(a)}, +yearStart:function(a){a.setMonth(0);return this.month_start(a)},dayStart:function(a){return this.date_part(a)},dateToStr:function(a,b){a=a.replace(/%[a-zA-Z]/g,function(a){switch(a){case "%d":return'"+dhx.math.toFixed(date.getDate())+"';case "%m":return'"+dhx.math.toFixed((date.getMonth()+1))+"';case "%j":return'"+date.getDate()+"';case "%n":return'"+(date.getMonth()+1)+"';case "%y":return'"+dhx.math.toFixed(date.getFullYear()%100)+"';case "%Y":return'"+date.getFullYear()+"';case "%D":return'"+dhx.Date.Locale.day_short[date.getDay()]+"'; +case "%l":return'"+dhx.Date.Locale.day_full[date.getDay()]+"';case "%M":return'"+dhx.Date.Locale.month_short[date.getMonth()]+"';case "%F":return'"+dhx.Date.Locale.month_full[date.getMonth()]+"';case "%h":return'"+dhx.math.toFixed((date.getHours()+11)%12+1)+"';case "%g":return'"+((date.getHours()+11)%12+1)+"';case "%G":return'"+date.getHours()+"';case "%H":return'"+dhx.math.toFixed(date.getHours())+"';case "%i":return'"+dhx.math.toFixed(date.getMinutes())+"';case "%a":return'"+(date.getHours()>11?"pm":"am")+"'; +case "%A":return'"+(date.getHours()>11?"PM":"AM")+"';case "%s":return'"+dhx.math.toFixed(date.getSeconds())+"';case "%W":return'"+dhx.math.toFixed(dhx.Date.getISOWeek(date))+"';default:return a}});b===!0&&(a=a.replace(/date\.get/g,"date.getUTC"));return new Function("date",'return "'+a+'";')},strToDate:function(a,b){for(var c="var temp=date.split(/[^0-9a-zA-Z]+/g);",d=a.match(/%[a-zA-Z]/g),e=0;e50?1900:2000);";break;case "%g":case "%G":case "%h":case "%H":c+="set[3]=temp["+e+"]||0;";break;case "%i":c+="set[4]=temp["+e+"]||0;";break;case "%Y":c+="set[0]=temp["+e+"]||0;";break;case "%a":case "%A":c+="set[3]=set[3]%12+((temp["+e+"]||'').toLowerCase()=='am'?0:12);";break;case "%s":c+="set[5]=temp["+e+"]||0;"}var f="set[0],set[1],set[2],set[3],set[4],set[5]";b&&(f=" Date.UTC("+f+")");return new Function("date", +"var set=[0,0,1,0,0,0]; "+c+" return new Date("+f+");")},getISOWeek:function(a){if(!a)return!1;var b=a.getDay();b===0&&(b=7);var c=new Date(a.valueOf());c.setDate(a.getDate()+(4-b));var d=c.getFullYear(),e=Math.floor((c.getTime()-(new Date(d,0,1)).getTime())/864E5),f=1+Math.floor(e/7);return f},getUTCISOWeek:function(a){return this.getISOWeek(a)},add:function(a,b,c){var d=new Date(a.valueOf());switch(c){case "day":d.setDate(d.getDate()+b);break;case "week":d.setDate(d.getDate()+7*b);break;case "month":d.setMonth(d.getMonth()+ +b);break;case "year":d.setYear(d.getFullYear()+b);break;case "hour":d.setHours(d.getHours()+b);break;case "minute":d.setMinutes(d.getMinutes()+b)}return d},datePart:function(a){var b=this.copy(a);b.setHours(0);b.setMinutes(0);b.setSeconds(0);b.setMilliseconds(0);return b},timePart:function(a){var b=this.copy(a);return(b.valueOf()/1E3-b.getTimezoneOffset()*60)%86400},copy:function(a){return new Date(a.valueOf())}};dhx.i18n.setLocale("en");dhx.format=function(a){a=a||{};this.$init(a)}; +dhx.format.prototype={$init:function(a){this.a={};this.a.groupDelimiter=a.groupDelimiter||" ";this.a.groupNumber=a.groupNumber||3;this.a.decimalPoint=a.decimalPoint||",";this.a.fractNumber=a.fractNumber||5;this.a.dateFormat=a.dateFormat||"%Y/%m/%d";this.a.stringTemplate=a.stringTemplate||"{value}";this.ff=dhx.Date.str_to_date(this.a.dateFormat);this.Qd=dhx.Date.date_to_str(this.a.dateFormat)},define:function(a,b){this.a[a]=b},format:function(a,b){b=b||this.formatAutoDefine(a);return this["format__"+ +b]?this["format__"+b](a):a},formatAutoDefine:function(a){return typeof a=="number"||a instanceof Number?"number":a instanceof Date?"date":typeof a=="string"||a instanceof String?isNaN(parseFloat(a))?"string":"number":!1},format__number:function(a){var b="";typeof a=="number"||a instanceof Number||(a=parseFloat(a));var c=a.toFixed(this.a.fractNumber).toString(),c=c.split("."),d=this.add_delimiter_to_int(c[0]),e=this.str_reverse(this.add_delimiter_to_int(this.str_reverse(c[1])));return b=d+this.a.decimalPoint+ +e},add_delimiter_to_int:function(a){for(var b=0,c="",d=a.length-1;d>=0;d--)c=a[d]+c,b++,b==this.a.groupNumber&&(c=this.a.groupDelimiter+c,b=0);return c},str_reverse:function(a){for(var b="",c=a.length-1;c>=0;c--)b+=a[c];return b},format__date:function(a){var b=this.Qd(a);return b},attachFormat:function(a,b){this["format__"+a]=b},format__string:function(a){var b=this.a.stringTemplate.replace("{value}",a);return b},format__bold:function(a){return typeof a=="string"||a instanceof String?a.bold():a}}; +dhx.i18n.setLocale(); +dhx.protoUI({name:"calendar",defaults:{date:null,startOnMonday:!0,navigation:!0,weekHeader:!1,weekNumber:!1,timeSelect:!1,skipEmptyWeeks:!0,cellHeight:36,minuteStep:15,hourStart:6,hourEnd:24,hourFormat:"%H",calendarHeader:"%F %Y",calendarDay:"%d",calendarWeekHeader:"W#",calendarWeek:"%W",width:300,height:300,selectedCss:"dhx_cal_selected_day"},skin:{monthHeaderHeight:40,weekHeaderHeight:20,timeSelectHeight:32},hourFormat_setter:dhx.Date.dateToStr,calendarHeader_setter:dhx.Date.dateToStr,calendarDay_setter:dhx.Date.dateToStr, +calendarWeekHeader_setter:dhx.Date.dateToStr,calendarWeek_setter:dhx.Date.dateToStr,date_setter:function(a){typeof a=="string"&&(a=dhx.i18n.fullDateFormatDate(a));this.L=this.L||a;return a},$init:function(){this.fa={};this.ec=[];var a="%Y-%m-%d";this.rc=dhx.Date.dateToStr(a);this.Cd=dhx.Date.strToDate(a)},$getSize:function(){var a=this.a;if(a.cellHeight>0)a.height=this.Xd();return dhx.ui.view.prototype.$getSize.call(this)},cellHeight_setter:function(a){return a=="auto"?0:a},$setSize:function(a,b){dhx.ui.view.prototype.$setSize.call(this, +a,b)&&this.render()},Ac:function(){var a=this.a;if(!this.L)this.L=new Date;var b=new Date(this.L);b.setDate(1);var c=b.getDay();this.ke=new Date(b);this.vd=a.startOnMonday?1:0;this.lb=(c-this.vd+7)%7;this.Nb=32-(new Date(b.getFullYear(),b.getMonth(),32)).getDate();var d=42-this.lb-this.Nb;this.df=new Date(b.setDate(this.Nb));this.G=a.skipEmptyWeeks?6-Math.floor(d/7):6;this.Ob=this.G*7-this.lb-this.Nb;this.cf=new Date(b.setDate(b.getDate()+d));this.Dc=this.skin.monthHeaderHeight+(a.weekHeader?this.skin.weekHeaderHeight: +0)+(a.timeSelect?this.skin.timeSelectHeight:0)},Xd:function(){this.Ac();return this.Dc+this.G*this.a.cellHeight},Td:function(){this.Ac();var a=this.a;this.Da=[];this.W=[];var b=this.j;b+=1;for(var c=this.m,d=a.weekNumber?8:7,e=0;e";a.weekHeader&&(b+="
"+this.Xe()+"
");b+="
"+this.Bd()+"
";a.timeSelect&&(b+="
"+this.Ue()+"
");b+="
";this.g.innerHTML=b;if(a.timeSelect){for(var c=this.g.getElementsByTagName("select"),d=this.ec,e=0;e"+f+"";d+=this.W[0]}for(var g=0;g<7;g++){var h=(c+g)%7,i=dhx.Date.Locale.day_short[h], +j="dhx_cal_day_name",k=this.W[g+e]-1;g==6&&(j+=" dhx_cal_day_name_last",k+=1);h===0&&(j+=" dhx_sunday");h==6&&(j+=" dhx_saturday");b+="
"+i+"
";d+=this.W[g+e]}return b},Bd:function(){var a=this.a,b=0,c=dhx.Date.add(this.ke,-this.lb,"day"),c=dhx.Date.datePart(c),d=0,e="";if(a.weekNumber){var d=1,f=dhx.Date.add(c,(this.vd+1)%2,"day");e+='';for(var g= +0;g=7||g==this.G-2&&this.Ob==14))k="dhx_next_month",j="";g==this.G-1&&(k+=" dhx_cal_day_num_bborder",h+=1);e+="";f=dhx.Date.add(f,7,"day")}e+="
";e+="
"+j+"
";e+="
"}var o=dhx.Date.datePart(new Date);e+='';for(var m= +this.G*7-1,g=0;g";for(var l=0;l<7;l++){var n=a.calendarDay(c),p=this.rc(c),k="dhx_cal_day_num";bm-this.Ob&&(k="dhx_next_month",p=n="");h=this.Da[g]-2;i=this.W[l+d]-2;l==6&&(k+=" dhx_cal_day_num_rborder",i+=1);g==this.G-1&&(k+=" dhx_cal_day_num_bborder",h+=1);e+=""; +c=dhx.Date.add(c,1,"day");b++}e+=""}e+="
";o.valueOf()==c.valueOf()&&(k+=" dhx_cal_current_day");e+="
"+n+"
";e+="
";return e},Ue:function(){for(var a=this.a,b="";b+="";return b},le:function(){var a="
";return a+"prev"+b+a+"next"+b},on_click:{dhx_cal_arrow:function(a,b,c){var d=c.className.match(/prev/i)?-1:1,e=new Date(this.L),f=new Date(e);f.setDate(1);f=dhx.Date.add(f,d,"month");this.callEvent("onBeforeMonthChange",[e,f])&&(this.showCalendar(f),this.selectDate(this.a.date,!1),this.callEvent("onAfterMonthChange",[f,e]))},dhx_cal_day_num:function(a,b,c){var d=c.getAttribute("date"),e=this.Cd(d);if(this.a.timeSelect){var f=this.ec;e.setMinutes(f[0].value*60+f[1].value* +1)}this.selectDate(e);this.callEvent("onDateSelect",[e]);this.callEvent("onChange",[e])}}},dhx.MouseEvents,dhx.Settings,dhx.EventSystem,dhx.Movable,dhx.ui.view);dhx.Modality={modal_setter:function(a){if(a){if(!this.qa)this.qa=dhx.html.create("div",{"class":a=="rich"?"dhx_modal_rich":"dhx_modal"}),this.qa.style.zIndex=dhx.ui.zIndex(),this.b.style.zIndex=dhx.ui.zIndex(),document.body.appendChild(this.qa)}else this.qa&&dhx.html.remove(this.qa),this.qa=null;return a}}; +dhx.protoUI({name:"window",$init:function(a){this.b.innerHTML="
";this.g=this.b.firstChild;this.eb=this.g.childNodes[0];this.pc=this.g.childNodes[1];this.b.className+=" dhx_window";this.R=this.h=null;this.a.k={top:!1,left:!1,right:!1,bottom:!1};if(!a.id)a.id=dhx.uid()},Zc:function(){this.h={destructor:function(){}}},ac:function(a){this.h.destructor();this.h=a;this.h.D=this;this.pc.appendChild(this.h.b); +this.resize()},show:function(a,b,c){this.a.hidden=!1;this.b.style.zIndex=dhx.ui.zIndex();this.a.modal&&this.modal_setter(!0);var d,e,f;if(a){typeof a=="object"&&!a.tagName?(d={x:a.clientX-this.$[0]/2,y:a.clientY},e=document.body.offsetWidth,f=1):a=dhx.toNode(a);var g=document.body.offsetWidth,h=document.body.offsetHeight;e=e||a.offsetWidth;f=f||a.offsetHeight;var i=this.$;d=d||dhx.html.offset(a);var j=6,k=6,o=6,c="top",m=0,l=0,n=0,p=0;b=="right"?(p=d.x+j+e,k=-f,c="left",m=Math.round(d.y+f/2),l=p- +o):b=="left"?(p=d.x-j-i[0]-1,k=-f,c="right",m=Math.round(d.y+f/2),l=p+i[0]+1):(p=g-d.x>i[0]?d.x:g-j-i[0],l=Math.round(d.x+e/2),l>p+i[0]&&(l=p+i[0]/2));h-f-d.y-k>i[1]?(n=f+d.y+k,m||(c="top",m=n-o)):(n=d.y-k-i[1],n<0?(n=0,c=!1):m||(c="bottom",n--,m=n+i[1]+1));this.setPosition(p,n);c&&this.cd&&this.cd(c,l,m)}this.Le=new Date;this.b.style.display="block";if(this.la){for(var q=0;q250&&this.hide()},$getSize:function(){var a=this.h.$getSize();if(a[3])this.a.height=a[3]+this.a.padding*2;if(a[1])this.a.width=a[1]+this.a.padding*2;if(a[0]||a[2])this.a.gravity=Math.max(a[0],a[2]);return dhx.ui.view.prototype.$getSize.call(this)}, +$setSize:function(a,b){if(dhx.ui.view.prototype.$setSize.call(this,a,b))a=this.j-this.a.padding*2,b=this.m-this.a.padding*2,this.g.style.padding=this.a.padding+"px",this.eb.style.display="none",this.h.$setSize(a,b)},body_setter:function(a){a=dhx.ui.window.prototype.body_setter.call(this,a);this.h.a.k={top:!1,left:!1,right:!1,bottom:!1};return a},defaults:{padding:8},head_setter:null,cd:function(a,b,c){this.Fc();document.body.appendChild(this.Ka=dhx.html.create("DIV",{"class":"dhx_point_"+a},"")); +this.Ka.style.zIndex=dhx.ui.zIndex();this.Ka.style.top=c+"px";this.Ka.style.left=b+"px"},Fc:function(){this.Ka=dhx.html.remove(this.Ka)}},dhx.ui.window); +dhx.protoUI({name:"alert",defaults:{position:"center",head:{template:"Info",css:"dhx_alert_template"},height:170,modal:!0,callback:null,body:{type:"clean",rows:[{template:"
#text#
",data:{text:"You have forgot to define the text :) "}},{view:"button",height:60,id:"dhx_alert_ok",type:"big",label:"Ok",click:function(){this.getParent().getParent().Bb(!0)}}]}},$init:function(){(!this.b.parentNode||!this.b.parentNode.tagName)&&document.body.appendChild(this.b);this.$ready.push(this.resize)}, +Yc:function(a){typeof a=="string"&&(a={title:this.defaults.head.template,message:a});dhx.extend(a,this.defaults);delete a.head;delete a.body;this.Rb(a,{});this.resize();this.show()},title_setter:function(a){this.R.define("template",a);this.R.render()},message_setter:function(a){var b=this.h.c[0];b.data={text:a};b.render()},labelOk_setter:function(a){var b=this.h.c[1];b.config.label=a;b.render()},labelCancel_setter:function(a){var b=this.h.c[2];b.config.label=a;b.render()},Bb:function(a){this.hide(); +this.a.callback&&dhx.toFunctor(this.a.callback).call(this,a,this.a.details)}},dhx.ui.window);dhx.alert=dhx.single(dhx.ui.alert); +dhx.protoUI({name:"confirm",defaults:{height:210,body:{type:"clean",rows:[{id:"dhx_confirm_message",template:"
#text#
",data:{text:"You have forgot to define the text :) "}},{height:53,view:"button",type:"big",id:"dhx_confirm_ok",label:"Ok",click:function(){this.getParent().getParent().Bb(!0)}},{height:55,view:"button",type:"biground",id:"dhx_confirm_cancel",label:"Cancel",click:function(){this.getParent().getParent().Bb(!1)}}]}}},dhx.ui.alert);dhx.confirm=dhx.single(dhx.ui.confirm); +dhx.dp=function(a){if(typeof a=="object"&&a.a)a=a.a.id;if(dhx.dp.Tb[a])return dhx.dp.Tb[a];if(typeof a=="string"||typeof a=="number")a={master:dhx.ui.get(a)};var b=new dhx.DataProcessor(a);return dhx.dp.Tb[b.a.master.a.id]=b};dhx.dp.Tb={}; +dhx.DataProcessor=dhx.proto({defaults:{autoupdate:!0,mode:"post"},$init:function(){this.V=[];this.bf=[];this.X=null;this.na=!1;this.name="DataProcessor";this.$ready.push(this.zb)},master_setter:function(a){var b=a;if(a.name!="DataStore")b=a.data;this.a.store=b;return a},zb:function(){this.a.store.attachEvent("onStoreUpdated",dhx.bind(this.Sc,this))},ignore:function(a,b){var c=this.na;this.na=!0;a.call(b||this);this.na=c},off:function(){this.na=!0},on:function(){this.na=!1},Kd:function(a){var b={}, +c;for(c in a)c.indexOf("$")!==0&&(b[c]=a[c]);return b},save:function(a,b){b=b||"update";this.Sc(a,this.a.store.item(a),b)},Sc:function(a,b,c){if(this.na===!0||!c)return!0;var d={id:a,data:this.Kd(b)};switch(c){case "update":d.operation="update";break;case "add":d.operation="insert";break;case "delete":d.operation="delete";break;default:return!0}if(d.operation!="delete"&&!this.validate(d.data))return!1;this.Gd(d)&&this.V.push(d);this.a.autoupdate&&this.send();return!0},Gd:function(a){for(var b=0;b< +this.V.length;b++){var c=this.V[b];if(c.id==a.id){if(a.operation=="delete")c.operation=="insert"?this.V.splice(b,1):c.operation="delete";c.data=a.data;return!1}}return!0},send:function(){this.Ge()},Ge:function(){if(this.a.url){for(var a=this.V,b=[],c=0;c=0&&this.V.splice(i,1),h.tid!=h.sid&&this.a.store.changeId(h.sid,h.tid),this.callEvent("onAfter"+h.type,[h])}this.callEvent("onAfterSync",[f,a,b,c])},escape:function(a){return this.a.escape?this.a.escape(a):encodeURIComponent(a)}},dhx.Settings,dhx.EventSystem,dhx.ValidateData); +(function(){var a=dhx.Touch={config:{longTouchDelay:1E3,scrollDelay:150,gravity:500,deltaStep:30,speed:"0ms",finish:1500},disable:function(){a.Fb=!0},enable:function(){a.Fb=!1},$init:function(){dhx.env.touch?(dhx.event(document.body,"touchstart",a.nd),dhx.event(document.body,"touchmove",a.gc),dhx.event(document.body,"touchend",a.md)):(a.bb=a.Wd,dhx.event(document.body,"mousedown",a.nd),dhx.event(document.body,"mousemove",a.gc),dhx.event(document.body,"mouseup",a.md),document.body.style.overflowX= +document.body.style.overflowY="hidden");dhx.event(document.body,"dragstart",function(a){return dhx.html.preventEvent(a)});dhx.event(document.body,"touchstart",function(b){if(!a.Fb&&dhx.env.isSafari)return b.srcElement.tagName=="SELECT"?!0:dhx.html.preventEvent(b)});a.Ca()},Ca:function(){a.A=a.w=a.ca=null;a.H=a.v=a.n=null;a.I={wb:0,xb:0,Na:0};if(a.Xa)dhx.html.removeCss(a.Xa,"dhx_touch"),a.Xa=null;window.clearTimeout(a.Kc);a.ud=!0;a.Sa=!0;a.Ta=!0;a.ic||a.ua()},md:function(b){if(a.A){if(a.H){var c=a.Hb(a.v), +d=c.e,e=c.f,f=a.config.finish,g=a.Bc(b,!0);if(g.Na){var h=d+a.config.gravity*g.wb/g.Na,i=e+a.config.gravity*g.xb/g.Na,j=a.q[0]?a.Wa(h,!1,!1,a.n.dx,a.n.px):d,k=a.q[1]?a.Wa(i,!1,!1,a.n.dy,a.n.py):e,o=Math.max(Math.abs(j-d),Math.abs(k-e));o<150&&(f=f*o/150);if(j!=d||k!=e)f=Math.round(f*Math.max((j-d)/(h-d),(k-e)/(i-e)));var m={e:j,f:k},l=dhx.ui.get(a.v);l&&l.callEvent&&l.callEvent("onAfterScroll",[m]);f=Math.max(100,f);d!=m.e||e!=m.f?(a.wa(a.v,m.e,m.f,f+"ms"),a.dd(m.e,m.f,f+"ms")):a.ua()}else a.ua()}else if(a.Ta&& +!a.Sa)a.ya("onSwipeX");else if(a.Sa&&!a.Ta)a.ya("onSwipeY");else if(dhx.env.isSafari){var n=a.A.target;dhx.delay(function(){var a=document.createEvent("MouseEvents");a.initEvent("click",!0,!0);n.dispatchEvent(a)})}a.ya("onTouchEnd");a.Ca()}},gc:function(b){if(a.A){var c=a.Bc(b);a.ya("onTouchMove");if(a.H)a.ed(c);else if(a.Sa=a.lc(c.Ye,"x",a.Sa),a.Ta=a.lc(c.Ze,"y",a.Ta),a.H){var d=a.Cc("onBeforeScroll");if(d){var e={};d.callEvent("onBeforeScroll",[e]);if(e.update)a.config.speed=e.speed,a.config.scale= +e.scale}a.ce(c)}return dhx.html.preventEvent(b)}},ed:function(){if(a.v){var b=a.Hb(a.v),c=b.e,d=b.f,e=a.ca||a.A;if(a.q[0])b.e=a.Wa(b.e-e.x+a.w.x,!0,b.e,a.n.dx,a.n.px);if(a.q[1])b.f=a.Wa(b.f-e.y+a.w.y,!0,b.f,a.n.dy,a.n.py);a.wa(a.v,b.e,b.f,"0ms");a.dd(b.e,b.f,"0ms")}},dd:function(b,c,d){var e=a.n.px/a.n.dx*-b,f=a.n.py/a.n.dy*-c;a.q[0]&&a.wa(a.q[0],e,0,d);a.q[1]&&a.wa(a.q[1],0,f,d)},wa:function(b,c,d,e){a.ic=!0;b.style[dhx.env.transformPrefix+"Transform"]=dhx.env.translate+"("+Math.round(c)+"px, "+ +Math.round(d)+"px"+(dhx.env.translate=="translate3d"?", 0":"")+")";b.style[dhx.env.transformPrefix+"TransitionDuration"]=e},Hb:function(a){var c=window.getComputedStyle(a)[dhx.env.transformPrefix+"Transform"];if(c=="none")return{e:0,f:0};else{if(window.WebKitCSSMatrix)return new WebKitCSSMatrix(c);for(var d=c.replace(/(matrix\()(.*)(\))/gi,"$2"),d=d.replace(/\s/gi,""),d=d.split(","),e={},f="a,b,c,d,e,f".split(","),g=0;g0)return c?d+h*Math.sqrt(g):0;var i=e-f;return i+a<0?c?d-Math.sqrt(-(a-d)):-i:a},ce:function(){a.H.indexOf("x")!=-1&&(a.q[0]=a.vc("x",a.n.dx,a.n.px,"width"));a.H.indexOf("y")!=-1&&(a.q[1]=a.vc("y",a.n.dy,a.n.py,"height"));if(!a.v.scroll_enabled){a.v.scroll_enabled=!0;a.v.parentNode.style.position="relative";var b=dhx.env.transformCSSPrefix;a.v.style.cssText+=b+"transition: "+b+"transform; "+b+"user-select:none; "+b+"transform-style:flat;";a.v.addEventListener(dhx.env.transitionEnd, +a.ua,!1)}window.setTimeout(a.ed,1)},vc:function(b,c,d,e){if(c-d<2)return a.H="";var f=dhx.html.create("DIV",{"class":"dhx_scroll_"+b},"");f.style[e]=d*d/c-7+"px";a.v.parentNode.appendChild(f);return f},lc:function(b,c,d){if(b>a.config.deltaStep){if(a.ud&&(a.he(c),(a.H||"").indexOf(c)==-1))a.H="";return!1}return d},ua:function(){if(!a.H)dhx.html.remove(a.q),a.q=[null,null];a.ic=!1},he:function(b){window.clearTimeout(a.Kc);a.ud=!1;a.Jc(b)},nd:function(b){if(!a.Fb){a.A=a.bb(b);a.ya("onTouchStart");a.q[0]|| +a.q[1]?a.Re(b,a.q[0]?"x":"y"):a.Kc=window.setTimeout(a.ie,a.config.longTouchDelay);var c=dhx.ui.get(b);if(c&&c.touchable&&(!b.target.className||b.target.className.indexOf("dhx_view")!==0))a.Xa=c.getNode(b),dhx.html.addCss(a.Xa,"dhx_touch")}},ie:function(){a.ya("onLongTouch");dhx.callEvent("onClick",[a.A]);a.Ca()},Re:function(b,c){a.Jc(c);var d=a.q[0]||a.q[1];if(d&&(!a.v||d.parentNode!=a.v.parentNode))a.Ca(),a.ua(),a.A=a.bb(b);a.gc(b)},Bc:function(b){a.ca=a.w;a.w=a.bb(b);a.I.Ye=Math.abs(a.A.x-a.w.x); +a.I.Ze=Math.abs(a.A.y-a.w.y);if(a.ca)a.w.time-a.ca.time";this.g=this.b.firstChild;this.map=null;this.$ready.push(this.render)},render:function(){var a=this.a,b={zoom:a.zoom,center:a.center,mapTypeId:a.mapType};this.map=new google.maps.Map(this.g,b)},center_setter:function(a){typeof a!="object"&&(a={});this.Ia(a,{x:48.724,y:8.215});a=new google.maps.LatLng(a.x,a.y);this.map&&this.map.setCenter(a);return a}, +mapType_setter:function(a){a=google.maps.MapTypeId[a];this.map&&this.map.setMapTypeId(a);return a},zoom_setter:function(a){this.map&&this.map.setZoom(a);return a},defaults:{zoom:5,center:{},mapType:"ROADMAP"},$setSize:function(){dhx.ui.view.prototype.$setSize.apply(this,arguments);google.maps.event.trigger(this.map,"resize")}},dhx.ui.view);if(!window.scheduler)window.scheduler={config:{},templates:{},xy:{},locale:{}};if(!scheduler.locale)scheduler.locale={}; +scheduler.locale.labels={list_tab:"List",day_tab:"Day",month_tab:"Month",icon_today:"Today",icon_save:"Save",icon_delete:"Delete event",icon_cancel:"Cancel",icon_edit:"Edit",icon_back:"Back",icon_close:"Close form",icon_yes:"Yes",icon_no:"No",confirm_closing:"Your changes will be lost, are your sure ?",confirm_deleting:"Event will be deleted permanently, are you sure?",label_event:"Event",label_start:"Start",label_end:"End",label_details:"Notes",label_from:"from",label_to:"to"}; +scheduler.config={init_date:new Date,form_date:"%d-%m-%Y %H:%i",xml_date:"%Y-%m-%d %H:%i",item_date:"%d.%m.%Y",header_date:"%d.%m.%Y",hour_date:"%H:%i",scale_hour:"%H",calendar_date:"%F %Y"};scheduler.config.form_rules={end_date:function(a,b){return b.start_date.valueOf()";if(dhx.Date.datePart(a.start_date).valueOf()==dhx.Date.datePart(a.end_date).valueOf()){var c=dhx.i18n.dateFormatStr(a.start_date),d=dhx.i18n.timeFormatStr(a.start_date),e=dhx.i18n.timeFormatStr(a.end_date);b+="
"+c+"
";b+="
"+scheduler.locale.labels.label_from+" "+d+" "+scheduler.locale.labels.label_to+ +" "+e+"
"}else{var f=dhx.i18n.longDateFormatStr(a.start_date),g=dhx.i18n.longDateFormatStr(a.end_date),d=dhx.i18n.timeFormatStr(a.start_date),e=dhx.i18n.timeFormatStr(a.end_date);b+="
"+scheduler.locale.labels.label_from+" "+d+" "+f+"
";b+="
"+scheduler.locale.labels.label_to+" "+e+" "+g+"
"}a.details&&a.details!==""&&(b+="
"+scheduler.locale.labels.label_details+"
",b+="
"+a.details+"
"); +b+="";return b},calendar_event:function(a){return a+"
"},event_date:function(a){return dhx.i18n.dateFormatStr(a)},event_long_date:function(a){return dhx.i18n.longDateFormatStr(a)},event_time:function(a){return dhx.i18n.timeFormatStr(a)},event_color:function(a){return a.color?"background-color:"+a.color:""},event_marker:function(a,b){return"
"},event_title:function(a,b){return"
"+ +b.dateStart(a.start_date)+"
"+b.timeStart(a.start_date)+"
"+b.marker(a,b)+"
"+a.text+"
"},month_event_title:function(a,b){return b.marker(a,b)+"
"+b.timeStart(a.start_date)+"
"+a.text+"
"},day_event:function(a){return a.text}};scheduler.config.views=[]; +dhx.ready(function(){if(scheduler.locale&&scheduler.locale.date)dhx.Date.Locale=scheduler.locale.date;if(!scheduler.config.form)scheduler.config.form=[{view:"text",label:scheduler.locale.labels.label_event,name:"text"},{view:"datepicker",label:scheduler.locale.labels.label_start,name:"start_date",timeSelect:1,dateFormat:scheduler.config.form_date},{view:"datepicker",label:scheduler.locale.labels.label_end,name:"end_date",timeSelect:1,dateFormat:scheduler.config.form_date},{view:"textarea",label:scheduler.locale.labels.label_details, +name:"details",width:300,height:150},{view:"button",label:scheduler.locale.labels.icon_delete,id:"delete",type:"form",css:"delete"}];if(!scheduler.config.bottom_toolbar)scheduler.config.bottom_toolbar=[{view:"button",id:"today",label:scheduler.locale.labels.icon_today,inputWidth:scheduler.xy.icon_today,align:"left",width:scheduler.xy.icon_today+6},{view:"segmented",id:"buttons",selected:"list",align:"center",multiview:!0,options:[{value:"list",label:scheduler.locale.labels.list_tab,width:scheduler.xy.list_tab}, +{value:"day",label:scheduler.locale.labels.day_tab,width:scheduler.xy.day_tab},{value:"month",label:scheduler.locale.labels.month_tab,width:scheduler.xy.month_tab}]},{view:"button",css:"add",id:"add",align:"right",label:"",inputWidth:42,width:50},{view:"label",label:"",inputWidth:42,width:50,batch:"readonly"}];if(!scheduler.config.day_toolbar)scheduler.config.day_toolbar=[{view:"label",id:"prev",align:"left",label:"
"},{view:"label",id:"date",align:"center", +width:200},{view:"label",id:"next",align:"right",label:"
"}];if(!scheduler.config.selected_toolbar)scheduler.config.selected_toolbar=[{view:"button",inputWidth:scheduler.xy.icon_back,type:"prev",id:"back",align:"left",label:scheduler.locale.labels.icon_back},{view:"button",inputWidth:scheduler.xy.icon_edit,id:"edit",align:"right",label:scheduler.locale.labels.icon_edit}];if(!scheduler.config.form_toolbar)scheduler.config.form_toolbar=[{view:"button", +inputWidth:scheduler.xy.icon_cancel,id:"cancel",css:"cancel",align:"left",label:scheduler.locale.labels.icon_cancel},{view:"button",inputWidth:scheduler.xy.icon_save,id:"save",align:"right",label:scheduler.locale.labels.icon_save}];scheduler.types={event_list:{name:"EventsList",css:"events",cssNoEvents:"no_events",padding:0,height:scheduler.xy.list_height,width:"auto",dateStart:scheduler.templates.event_date,timeStart:scheduler.templates.event_time,color:scheduler.templates.event_color,marker:scheduler.templates.event_marker, +template:scheduler.templates.event_title},day_event_list:{name:"DayEventsList",css:"day_events",cssNoEvents:"no_events",padding:0,height:scheduler.xy.month_list_height,width:"auto",timeStart:scheduler.templates.event_time,color:scheduler.templates.event_color,marker:scheduler.templates.event_marker,template:scheduler.templates.month_event_title}};dhx.Type(dhx.ui.list,scheduler.types.event_list);dhx.Type(dhx.ui.list,scheduler.types.day_event_list);dhx.DataDriver.scheduler={records:"/*/event"};dhx.extend(dhx.DataDriver.scheduler, +dhx.DataDriver.xml);var a=[{id:"list",view:"list",type:"EventsList",startDate:new Date},{id:"day",rows:[{id:"dayBar",view:"toolbar",css:"dhx_topbar",elements:scheduler.config.day_toolbar},{id:"dayList",view:"dayevents"}]},{id:"month",rows:[{id:"calendar",view:"calendar",dayWithEvents:scheduler.templates.calendar_event,calendarHeader:scheduler.config.calendar_date},{id:"calendarDayEvents",view:"list",type:"DayEventsList"}]},{id:"event",animate:{type:"slide",subtype:"in",direction:"top"},rows:[{id:"eventBar", +view:"toolbar",type:"TopBar",css:"single_event",elements:scheduler.config.selected_toolbar},{id:"eventTemplate",view:"template",template:scheduler.templates.selected_event}]},{id:"form",rows:[{id:"editBar",view:"toolbar",type:"TopBar",elements:scheduler.config.form_toolbar},{id:"editForm",view:"form",elements:scheduler.config.form,rules:scheduler.config.form_rules}]}].concat(scheduler.config.views);dhx.protoUI({name:"scheduler",defaults:{rows:[{view:"multiview",id:"views",cells:a},{view:"toolbar", +id:"bottomBar",type:"SchedulerBar",visibleBatch:"default",elements:scheduler.config.bottom_toolbar}],color:"#color#",textColor:"#textColor#"},$init:function(){this.name="Scheduler";this.b.className+=" dhx_scheduler";dhx.i18n.dateFormat=scheduler.config.item_date;dhx.i18n.timeFormat=scheduler.config.hour_date;dhx.i18n.fullDateFormat=scheduler.config.xml_date;dhx.i18n.headerFormatStr=dhx.Date.dateToStr(scheduler.config.header_date);dhx.i18n.setLocale();this.data.provideApi(this);this.data.extraParser= +dhx.bind(function(a){a.start_date=dhx.i18n.fullDateFormatDate(a.start_date);a.end_date=dhx.i18n.fullDateFormatDate(a.end_date)},this);this.$ready.push(this.$d);this.data.attachEvent("onStoreUpdated",dhx.bind(this.Oe,this))},$d:function(){this.ae();this.de();this.coreData=new dhx.DataValue;this.coreData.setValue(scheduler.config.init_date);this.$$("dayList").define("date",this.coreData);this.selectedEvent=new dhx.DataRecord;this.config.readonly?this.define("readonly",this.config.readonly):scheduler.config.readonly&& +this.define("readonly",!0);if(this.config.save){var a=new dhx.DataProcessor({master:this,url:this.config.save});a.attachEvent("onBeforeDataSend",this.re)}this.$$("date")&&this.$$("date").bind(this.coreData,null,dhx.i18n.headerFormatStr);this.$$("list").sync(this);this.$$("list").bind(this.coreData,function(a,b){return ba.start_date}); +this.$$("calendar").bind(this.coreData);this.$$("calendarDayEvents").sync(this,!0);this.$$("calendarDayEvents").bind(this.coreData,function(a,b){var e=dhx.Date.datePart(b);return ea.start_date});this.$$("eventTemplate").bind(this);this.$$("editForm").bind(this);this.$$("list").attachEvent("onItemClick",dhx.bind(this.Qb,this));this.$$("dayList").attachEvent("onItemClick",dhx.bind(this.Qb,this));this.$$("calendarDayEvents").attachEvent("onItemClick",dhx.bind(this.Qb, +this))},Qb:function(a){this.setCursor(a);this.$$("event").show()},Oe:function(){this.data.blockEvent();this.data.sort(function(a,b){return a.start_date";e+="
"+a+"
";e+="
";e+="
"+c+"
";e+="
"+d+"
";e+="
";e+="
";e+="
";e+="
";e+="
";e+="";return e},type:{templateStart:dhx.Template("
"),template:scheduler.templates.day_event,templateEnd:dhx.Template("
"),templateCss:dhx.Template(""),templateColor:dhx.Template("#color#"), +templateTextColor:dhx.Template("#textColor#"),padding:2},we:function(){var a=this.data.getRange(),b=[],c,d,e,f,g;for(d=0;dg)g=b[e].$sorder;c.$sorder=g+1;c.$inner=!1}else c.$sorder=0;b.push(c);if(b.length>(b.max_count||0))b.max_count=b.length}for(d=0;ddhx.Date.datePart(d).valueOf()&&(d=c);dhx.Date.datePart(c).valueOf()dhx.Date.datePart(b).valueOf()&&(d=dhx.Date.datePart(b),d.setMinutes(0),d.setHours(this.config.lastHour));if(e=this.config.lastHour)e=this.config.lastHour&&(d.setMinutes(0), +d.setHours(this.config.lastHour));var g=Math.floor((this.j-this.config.timeScaleWidth-this.config.eventOffset-8)/a.$count);a.$left=a.$sorder*g+this.config.timeScaleWidth+this.config.eventOffset;a.$inner||(g*=a.$count-a.$sorder);a.$width=g-this.config.eventOffset-this.type.padding*2;var h=c.getHours()*60+c.getMinutes(),i=d.getHours()*60+d.getMinutes()||this.config.lastHour*60;a.$top=Math.round((h-this.config.firstHour/60)*(this.config.timeScaleHeight+1)/60);a.$height=Math.max(10,(i-h)*(this.config.timeScaleHeight+ +1)/60-2)-this.type.padding*2}},dhx.MouseEvents,dhx.SelectionModel,dhx.Scrollable,dhx.RenderStack,dhx.DataLoader,dhx.ui.view,dhx.EventSystem,dhx.Settings); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_active_links.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_active_links.js index d7889307153..6499338d09b 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_active_links.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_active_links.js @@ -1,9 +1,6 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.attachEvent("onTemplatesReady",function(){var B=scheduler.date.str_to_date(scheduler.config.api_date);var C=scheduler.date.date_to_str(scheduler.config.api_date);var D=scheduler.templates.month_day;scheduler.templates.month_day=function(E){return""+D(E)+""};var A=scheduler.templates.week_scale_date;scheduler.templates.week_scale_date=function(E){return""+A(E)+""};dhtmlxEvent(this._obj,"click",function(E){var G=E.target||event.srcElement;var F=G.getAttribute("jump_to");if(F){scheduler.setCurrentView(B(F),"day")}})}); \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.attachEvent("onTemplatesReady",function(){var d=scheduler.date.str_to_date(scheduler.config.api_date),b=scheduler.date.date_to_str(scheduler.config.api_date),e=scheduler.templates.month_day;scheduler.templates.month_day=function(a){return""+e(a)+""};var f=scheduler.templates.week_scale_date;scheduler.templates.week_scale_date=function(a){return""+f(a)+""};dhtmlxEvent(this._obj,"click",function(a){var b=a.target||event.srcElement, +c=b.getAttribute("jump_to");if(c)return scheduler.setCurrentView(d(c),"day"),a&&a.preventDefault&&a.preventDefault(),!1})}); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_agenda_view.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_agenda_view.js index c0293e8a2a8..c0eb363b8d5 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_agenda_view.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_agenda_view.js @@ -1,9 +1,10 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.date.add_agenda=function(A){return(new Date(A.valueOf()))};scheduler.dblclick_dhx_agenda_area=function(){if(!this.config.readonly&&this.config.dblclick_create){this.addEventNow()}};scheduler.templates.agenda_time=function(C,A,B){if(B._timed){return this.day_date(B.start_date,B.end_date,B)+" "+this.event_date(C)}else{return scheduler.templates.day_date(C)+" – "+scheduler.templates.day_date(A)}};scheduler.templates.agenda_text=function(A){return A.text};scheduler.date.agenda_start=function(A){return A};scheduler.attachEvent("onTemplatesReady",function(){scheduler.attachEvent("onSchedulerResize",function(){if(this._mode=="agenda"){this.agenda_view(true);return false}return true});var A=scheduler.render_data;scheduler.render_data=function(D){if(this._mode=="agenda"){B()}else{return A.apply(this,arguments)}};function C(E){if(E){var D=scheduler.locale.labels;scheduler._els.dhx_cal_header[0].innerHTML="
"+D.date+"
"+D.description+"
";scheduler._table_view=true;scheduler.set_sizes()}}function B(){var D=scheduler._date;var H=scheduler.get_visible_events();H.sort(function(J,I){return J.start_date>I.start_date?1:-1});var G="
";for(var F=0;F
"+scheduler.templates.agenda_time(H[F].start_date,H[F].end_date,H[F])+"
";G+="
 
";G+=""+scheduler.templates.agenda_text(H[F])+"
"}G+="
";scheduler._els.dhx_cal_data[0].scrollTop=0;scheduler._els.dhx_cal_data[0].innerHTML=G;var E=scheduler._els.dhx_cal_data[0].firstChild.childNodes;scheduler._els.dhx_cal_date[0].innerHTML="";scheduler._rendered=[];for(var F=0;F
"+a.date+"
"+a.description+"";scheduler._table_view=!0;scheduler.set_sizes()}}function d(){var b=scheduler._date,a=scheduler.get_visible_events();a.sort(function(a,b){return a.start_date>b.start_date?1:-1});for(var d="
",e=0;e
"+scheduler.templates.agenda_time(c.start_date,c.end_date,c)+"
";d+="
 
";d+=""+scheduler.templates.agenda_text(c.start_date,c.end_date,c)+"
"}d+="
";scheduler._els.dhx_cal_data[0].innerHTML=d;scheduler._els.dhx_cal_data[0].childNodes[0].scrollTop= +scheduler._agendaScrollTop||0;var g=scheduler._els.dhx_cal_data[0].firstChild.childNodes;scheduler._els.dhx_cal_date[0].innerHTML="";scheduler._rendered=[];for(e=0;escheduler.config.collision_limit){scheduler._drag_event.start_date=D;N[G]=C;P=false}}else{if(Q.length>scheduler.config.collision_limit){P=false}}if(!P){return !scheduler.callEvent("onEventCollision",[N,Q])}return P}})(); \ No newline at end of file +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +(function(){function h(a){var b=scheduler._props?scheduler._props[scheduler._mode]:null,f=scheduler.matrix?scheduler.matrix[scheduler._mode]:null,c=b||f;if(b)var d=c.map_to;if(f)d=c.y_property;c&&a&&(n=scheduler.getEvent(a)[d])}function g(a){var b=[];if(a.rec_type){for(var f=scheduler.getRecDates(a),c=0;c=scheduler.config.collision_limit&&(a[j]=n,k=!1)}else b.length>scheduler.config.collision_limit&&(k=!1);return!k?!scheduler.callEvent("onEventCollision",[a,b]):k}var n,e;scheduler.config.collision_limit=1;scheduler.attachEvent("onBeforeDrag",function(a){h(a); +return!0});scheduler.attachEvent("onBeforeLightbox",function(a){var b=scheduler.getEvent(a);e=[b.start_date,b.end_date];h(a);return!0});scheduler.attachEvent("onEventChanged",function(a){if(!a)return!0;var b=scheduler.getEvent(a);if(!g(b)){if(!e)return!1;b.start_date=e[0];b.end_date=e[1];b._timed=this.is_one_day_event(b)}return!0});scheduler.attachEvent("onBeforeEventChanged",function(a){return g(a)});scheduler.attachEvent("onEventSave",function(a,b){return b.rec_type?(scheduler._roll_back_dates(b), +g(b)):!0})})(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_cookie.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_cookie.js index 0e58357f735..ef80ea8e8d0 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_cookie.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_cookie.js @@ -1,9 +1,6 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -(function(){function B(E,D,F){var G=E+"="+F+(D?("; "+D):"");document.cookie=G}function A(E){var F=E+"=";if(document.cookie.length>0){var G=document.cookie.indexOf(F);if(G!=-1){G+=F.length;var D=document.cookie.indexOf(";",G);if(D==-1){D=document.cookie.length}return document.cookie.substring(G,D)}}return""}var C=true;scheduler.attachEvent("onBeforeViewChange",function(F,E,D,I){if(C){C=false;var G=A("scheduler_settings");if(G){G=G.split("@");G[0]=this.templates.xml_date(G[0]);this.setCurrentView(G[0],G[1]);return false}}var H=this.templates.xml_format(I||E)+"@"+(D||F);B("scheduler_settings","expires=Sun, 31 Jan 9999 22:00:00 GMT",H);return true})})(); \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +(function(){function g(e,b,a){var c=e+"="+a+(b?"; "+b:"");document.cookie=c}function h(e){var b=e+"=";if(document.cookie.length>0){var a=document.cookie.indexOf(b);if(a!=-1){a+=b.length;var c=document.cookie.indexOf(";",a);if(c==-1)c=document.cookie.length;return document.cookie.substring(a,c)}}return""}var f=!0;scheduler.attachEvent("onBeforeViewChange",function(e,b,a,c){if(f){f=!1;var d=h("scheduler_settings");if(d)return d=d.split("@"),d[0]=this.templates.xml_date(d[0]),this.setCurrentView(d[0], +d[1]),!1}var i=this.templates.xml_format(c||b)+"@"+(a||e);g("scheduler_settings","expires=Sun, 31 Jan 9999 22:00:00 GMT",i);return!0})})(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_editors.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_editors.js index ad4d85b0a8e..38ba960c470 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_editors.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_editors.js @@ -1,9 +1,10 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.form_blocks.combo={render:function(B){var A="";A+="
";return A},set_value:function(F,H,E,C){if(F._combo){F._combo.destructor()}window.dhx_globalImgPath=C.image_path||"/";F._combo=new dhtmlXCombo(F,C.name,F.offsetWidth-8);F._combo.enableFilteringMode(!!C.filtering,C.script_path||null,!!C.cache);if(!C.script_path){var G=[];for(var D=0;D";for(var A=0;A";if(C.vertical){B+="
"}}B+="";return B},set_value:function(D,F,C,A){var E=D.getElementsByTagName("input");for(var B=0;B"},get_value:function(C,B,A){var D=C.previousSibling.getElementsByTagName("input")[0];return(D.checked)?(A.checked_value||true):(A.unchecked_value||false)},focus:function(A){}}; \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.form_blocks.combo={render:function(a){var d="";d+="
";return d},set_value:function(a,d,c,b){a._combo&&a._combo.destructor();window.dhx_globalImgPath=b.image_path||"/";a._combo=new dhtmlXCombo(a,b.name,a.offsetWidth-8);a._combo.enableFilteringMode(!!b.filtering,b.script_path||null,!!b.cache);if(b.script_path)a._combo.setComboValue(c[b.map_to]||null);else{for(var f=[],e=0;e";for(var c=0;c";a.vertical&&(d+="
")}d+="";return d},set_value:function(a,d,c,b){for(var f=a.getElementsByTagName("input"),e=0;e':""},set_value:function(a,d,c,b){var a=document.getElementById(b.id),f=scheduler.uid(),e=!1;typeof b.checked_value!="undefined"&&c[b.map_to]==b.checked_value&&(e=!0);a.className+=" dhx_cal_checkbox";var g="",h="";scheduler.config.wide_form?(a.innerHTML=h,a.nextSibling.innerHTML=g):a.innerHTML=g+h},get_value:function(a,d,c){var a=document.getElementById(c.id),b=a.getElementsByTagName("input")[0];b||(b=a.nextSibling.getElementsByTagName("input")[0]);return b.checked?c.checked_value||!0:c.unchecked_value||!1},focus:function(){}}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_expand.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_expand.js index e05c11401d7..06a1187a723 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_expand.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_expand.js @@ -1,9 +1,8 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.expand=function(){var A=scheduler._obj;do{A._position=A.style.position||"";A.style.position="static"}while((A=A.parentNode)&&A.style);A=scheduler._obj;A.style.position="absolute";A._width=A.style.width;A._height=A.style.height;A.style.width=A.style.height="100%";A.style.top=A.style.left="0px";var B=document.body;B.scrollTop=0;B=B.parentNode;if(B){B.scrollTop=0}document.body._overflow=document.body.style.overflow||"";document.body.style.overflow="hidden";scheduler._maximize()};scheduler.collapse=function(){var A=scheduler._obj;do{A.style.position=A._position}while((A=A.parentNode)&&A.style);A=scheduler._obj;A.style.width=A._width;A.style.height=A._height;document.body.style.overflow=document.body._overflow;scheduler._maximize()};scheduler.attachEvent("onTemplatesReady",function(){var A=document.createElement("DIV");A.className="dhx_expand_icon";scheduler.toggleIcon=A;scheduler._obj.appendChild(A);A.onclick=function(){if(!scheduler.expanded){scheduler.expand()}else{scheduler.collapse()}}});scheduler._maximize=function(){this.expanded=!this.expanded;this.toggleIcon.style.backgroundPosition="0px "+(this._expand?"0":"18")+"px";if(scheduler.callEvent("onSchedulerResize",[])){scheduler.update_view()}}; \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.expand=function(){var a=scheduler._obj;do a._position=a.style.position||"",a.style.position="static";while((a=a.parentNode)&&a.style);a=scheduler._obj;a.style.position="absolute";a._width=a.style.width;a._height=a.style.height;a.style.width=a.style.height="100%";a.style.top=a.style.left="0px";var b=document.body;b.scrollTop=0;if(b=b.parentNode)b.scrollTop=0;document.body._overflow=document.body.style.overflow||"";document.body.style.overflow="hidden";scheduler._maximize()}; +scheduler.collapse=function(){var a=scheduler._obj;do a.style.position=a._position;while((a=a.parentNode)&&a.style);a=scheduler._obj;a.style.width=a._width;a.style.height=a._height;document.body.style.overflow=document.body._overflow;scheduler._maximize()};scheduler.attachEvent("onTemplatesReady",function(){var a=document.createElement("DIV");a.className="dhx_expand_icon";scheduler.toggleIcon=a;scheduler._obj.appendChild(a);a.onclick=function(){scheduler.expanded?scheduler.collapse():scheduler.expand()}}); +scheduler._maximize=function(){this.expanded=!this.expanded;this.toggleIcon.style.backgroundPosition="0px "+(this.expanded?"0":"18")+"px";for(var a=["left","top"],b=0;bscheduler.config.limit_end.valueOf()||this.date.add(F,1,C)<=scheduler.config.limit_start.valueOf()){setTimeout(function(){scheduler.setCurrentView(scheduler._date,C)},1);return false}}return true});var A=function(D){var E=scheduler.config;var C=(D.start_date.valueOf()>=E.limit_start.valueOf()&&D.end_date.valueOf()<=E.limit_end.valueOf());if(!C){scheduler._drag_id=null;scheduler._drag_mode=null;scheduler.callEvent("onLimitViolation",[D.id,D])}return C};scheduler.attachEvent("onBeforeDrag",function(C){if(!C){return true}return A(scheduler.getEvent(C))});scheduler.attachEvent("onClick",function(D,C){return A(scheduler.getEvent(D))});scheduler.attachEvent("onBeforeLightbox",function(D){var C=scheduler.getEvent(D);B=[C.start_date,C.end_date];return A(C)});scheduler.attachEvent("onEventAdded",function(D){if(!D){return true}var C=scheduler.getEvent(D);if(!A(C)){if(C.start_datescheduler.config.limit_end){C.end_date=new Date(scheduler.config.limit_end);C._timed=this.is_one_day_event(C)}if(C.start_date>C.end_date){C.end_date=this.date.add(C.start_date,(this.config.event_duration||this.config.time_step),"minute")}}return true});scheduler.attachEvent("onEventChanged",function(D){if(!D){return true}var C=scheduler.getEvent(D);if(!A(C)){if(!B){return false}C.start_date=B[0];C.end_date=B[1];C._timed=this.is_one_day_event(C)}return true});scheduler.attachEvent("onBeforeEventChanged",function(D,C,E){return A(D)})})(); \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.config.limit_start=new Date(-3999,0,0);scheduler.config.limit_end=new Date(3999,0,0);scheduler.config.limit_view=!1; +(function(){var g=null,k={},l={},m=!1;scheduler.blockTime=function(b,a){var c=this.config.first_hour*60,d=this.config.last_hour*60;a=="fullday"&&(a=[c,d]);typeof b=="object"?k[this.date.date_part(b).valueOf()]=a:l[b]=a;for(var e=0;ed&&(a[e+1]=d);m=!0};scheduler.attachEvent("onScaleAdd",function(b,a){var c=k[a.valueOf()]||l[a.getDay()];if(c)for(var d=0;dscheduler.config.limit_end.valueOf()||this.date.add(d,1,c)<=scheduler.config.limit_start.valueOf())?(setTimeout(function(){scheduler.setCurrentView(scheduler._date, +c)},1),!1):!0});var f=function(b){var a=scheduler.config,c=b.start_date.valueOf()>=a.limit_start.valueOf()&&b.end_date.valueOf()<=a.limit_end.valueOf();if(c&&m&&b._timed){var d=scheduler.date.date_part(new Date(b.start_date.valueOf())),e=k[d.valueOf()]||l[d.getDay()],f=b.start_date.getHours()*60+b.start_date.getMinutes(),h=b.end_date.getHours()*60+b.end_date.getMinutes();if(e)for(var j=0;jf){if(f<=i&&f>=g){if(i==1440||h=g&&h=scheduler.config.limit_end.valueOf())a.start_date=this.date.add(scheduler.config.limit_end,-1,"day");if(a.end_date=scheduler.config.limit_end.valueOf())a.end_date=this.date.add(scheduler.config.limit_end,-1,"day");if(a.start_date.valueOf()>=a.end_date.valueOf())a.end_date=this.date.add(a.start_date,this.config.event_duration||this.config.time_step,"minute");a._timed=this.is_one_day_event(a)}return!0});scheduler.attachEvent("onEventChanged",function(b){if(!b)return!0;var a=scheduler.getEvent(b);if(!f(a)){if(!g)return!1;a.start_date=g[0];a.end_date= +g[1];a._timed=this.is_one_day_event(a)}return!0});scheduler.attachEvent("onBeforeEventChanged",function(b){return f(b)})})(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_map_view.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_map_view.js index 4404ea13eb4..57735c07a0e 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_map_view.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_map_view.js @@ -1,9 +1,29 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.xy.map_date_width=188;scheduler.xy.map_description_width=400;scheduler.config.map_resolve_event_location=true;scheduler.config.map_resolve_user_location=true;scheduler.config.map_initial_position=new google.maps.LatLng(48.724,8.215);scheduler.config.map_error_position=new google.maps.LatLng(15,15);scheduler.config.map_infowindow_max_width=300;scheduler.config.map_type=google.maps.MapTypeId.ROADMAP;scheduler.config.map_zoom_after_resolve=15;scheduler.locale.labels.marker_geo_success="It seems you are here.";scheduler.locale.labels.marker_geo_fail="Sorry, could not get your current position using geolocation.";scheduler.templates.marker_date=scheduler.date.date_to_str("%Y-%m-%d %H:%i");scheduler.templates.marker_text=function(C,A,B){return"
"+B.text+"

"+(B.event_location||"")+"

"+scheduler.templates.marker_date(C)+" - "+scheduler.templates.marker_date(A)+"
"};scheduler.dblclick_dhx_map_area=function(){if(!this.config.readonly&&this.config.dblclick_create){this.addEventNow()}};scheduler.templates.map_time=function(C,A,B){if(B._timed){return this.day_date(B.start_date,B.end_date,B)+" "+this.event_date(C)}else{return scheduler.templates.day_date(C)+" – "+scheduler.templates.day_date(A)}};scheduler.templates.map_text=function(A){return A.text};scheduler.date.map_start=function(A){return A};scheduler.attachEvent("onTemplatesReady",function(){function D(){_isPositionSet=false;var H=document.createElement("div");H.className="dhx_map";H.id="dhx_gmap";H.style.dispay="none";node=document.getElementById("scheduler_here");node.appendChild(H);scheduler._els.dhx_gmap=[];scheduler._els.dhx_gmap.push(H);C("dhx_gmap");var G={zoom:scheduler.config.map_inital_zoom||10,center:scheduler.config.map_initial_position,mapTypeId:scheduler.config.map_type||google.maps.MapTypeId.ROADMAP};map=new google.maps.Map(document.getElementById("dhx_gmap"),G);map.disableDefaultUI=false;map.disableDoubleClickZoom=true;google.maps.event.addListener(map,"dblclick",function(J){if(!scheduler.config.readonly&&scheduler.config.dblclick_create){point=J.latLng;geocoder.geocode({latLng:point},function(L,K){if(K==google.maps.GeocoderStatus.OK){point=L[0].geometry.location;scheduler.addEventNow({lat:point.lat(),lng:point.lng(),event_location:L[0].formatted_address})}})}});var I={content:""};if(scheduler.config.map_infowindow_max_width){I.maxWidth=scheduler.config.map_infowindow_max_width}scheduler.map={_points:[],_markers:[],_infowindow:new google.maps.InfoWindow(I),_infowindows_content:[],_initialization_count:-1};geocoder=new google.maps.Geocoder();if(scheduler.config.map_resolve_user_location){if(navigator.geolocation){if(!_isPositionSet){navigator.geolocation.getCurrentPosition(function(J){var K=new google.maps.LatLng(J.coords.latitude,J.coords.longitude);map.setCenter(K);map.setZoom(scheduler.config.map_zoom_after_resolve||10);scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_success);scheduler.map._infowindow.position=map.getCenter();scheduler.map._infowindow.open(map);_isPositionSet=true},function(){scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_fail);scheduler.map._infowindow.setPosition(map.getCenter());scheduler.map._infowindow.open(map);_isPositionSet=true})}}}google.maps.event.addListener(map,"resize",function(J){H.style.zIndex="5";map.setZoom(map.getZoom())});google.maps.event.addListener(map,"tilesloaded",function(J){H.style.zIndex="5"})}D();scheduler.attachEvent("onSchedulerResize",function(){if(this._mode=="map"){this.map_view(true)}});var A=scheduler.render_data;scheduler.render_data=function(G,J){if(this._mode=="map"){E();var I=scheduler.get_visible_events();for(var H=0;H
"+G.date+"
"+G.description+"
";scheduler._table_view=true;scheduler.set_sizes()}}function E(){var H=scheduler._date;var L=scheduler.get_visible_events();L.sort(function(N,M){return N.start_date>M.start_date?1:-1});var K="
";for(var J=0;J
"+scheduler.templates.map_time(L[J].start_date,L[J].end_date,L[J])+"
";K+="
 
";K+="
"+scheduler.templates.map_text(L[J])+"
"}K+="
";scheduler._els.dhx_cal_data[0].scrollTop=0;scheduler._els.dhx_cal_data[0].innerHTML=K;scheduler._els.dhx_cal_data[0].style.width=(scheduler.xy.map_date_width+scheduler.xy.map_description_width+1)+"px";var I=scheduler._els.dhx_cal_data[0].firstChild.childNodes;scheduler._els.dhx_cal_date[0].innerHTML="";scheduler._rendered=[];for(var J=0;J"+e.text+"

"+(e.event_location||"")+"

"+scheduler.templates.marker_date(f)+" - "+scheduler.templates.marker_date(g)+""}; +scheduler.dblclick_dhx_map_area=function(){!this.config.readonly&&this.config.dblclick_create&&this.addEventNow({start_date:scheduler._date,end_date:scheduler.date.add(scheduler._date,1,"hour")})};scheduler.templates.map_time=function(f,g,e){return e._timed?this.day_date(e.start_date,e.end_date,e)+" "+this.event_date(f):scheduler.templates.day_date(f)+" – "+scheduler.templates.day_date(g)};scheduler.templates.map_text=function(f,g,e){return e.text};scheduler.date.map_start=function(f){return f}; +scheduler.date.add_map=function(f){return new Date(f.valueOf())};scheduler.templates.map_date=function(){return""};scheduler._latLngUpdate=!1; +scheduler.attachEvent("onSchedulerReady",function(){function f(a){if(a){var c=scheduler.locale.labels;scheduler._els.dhx_cal_header[0].innerHTML="
"+c.date+"
"+c.description+"
";scheduler._table_view=!0;scheduler.set_sizes()}} +function g(){scheduler._selected_event_id=null;scheduler.map._infowindow.close();for(var a in scheduler.map._markers)scheduler.map._markers[a].setMap(null),delete scheduler.map._markers[a],scheduler.map._infowindows_content[a]&&delete scheduler.map._infowindows_content[a]}function e(){var a=scheduler.get_visible_events();a.sort(function(a,b){return a.start_date
"+scheduler.templates.map_time(b.start_date,b.end_date,b)+"
";c+="
 
"; +c+="
"+scheduler.templates.map_text(b.start_date,b.end_date,b)+"
"}c+="
";scheduler._els.dhx_cal_data[0].scrollTop=0;scheduler._els.dhx_cal_data[0].innerHTML=c;scheduler._els.dhx_cal_data[0].style.width=scheduler.xy.map_date_width+scheduler.xy.map_description_width+ +1+"px";var g=scheduler._els.dhx_cal_data[0].firstChild.childNodes;scheduler._els.dhx_cal_date[0].innerHTML=scheduler.templates[scheduler._mode+"_date"](scheduler._min_date,scheduler._max_date,scheduler._mode);scheduler._rendered=[];for(d=0;dscheduler._min_date||c.start_datescheduler._max_date||c.start_date.valueOf()>=scheduler._min_date&&c.end_date.valueOf()<=scheduler._max_date? +(scheduler.map._markers[a]&&scheduler.map._markers[a].setMap(null),j(c)):(scheduler._selected_event_id=null,scheduler.map._infowindow.close(),scheduler.map._markers[a]&&scheduler.map._markers[a].setMap(null))}return!0});scheduler.attachEvent("onEventIdChange",function(a,c){var d=scheduler.getEvent(c);if(d.start_datescheduler._min_date||d.start_datescheduler._max_date||d.start_date.valueOf()>=scheduler._min_date&&d.end_date.valueOf()<= +scheduler._max_date)scheduler.map._markers[a]&&(scheduler.map._markers[a].setMap(null),delete scheduler.map._markers[a]),scheduler.map._infowindows_content[a]&&delete scheduler.map._infowindows_content[a],j(d);return!0});scheduler.attachEvent("onEventAdded",function(a,c){if(!scheduler._dataprocessor&&(c.start_datescheduler._min_date||c.start_datescheduler._max_date||c.start_date.valueOf()>=scheduler._min_date&&c.end_date.valueOf()<= +scheduler._max_date))scheduler.map._markers[a]&&scheduler.map._markers[a].setMap(null),j(c);return!0});scheduler.attachEvent("onBeforeEventDelete",function(a){scheduler.map._markers[a]&&scheduler.map._markers[a].setMap(null);scheduler._selected_event_id=null;scheduler.map._infowindow.close();return!0});scheduler._event_resolve_delay=1500;scheduler.attachEvent("onEventLoading",function(a){scheduler.config.map_resolve_event_location&&a.event_location&&!a.lat&&!a.lng&&(scheduler._event_resolve_delay+= +1500,o(n,this,[a],scheduler._event_resolve_delay));return!0});scheduler.attachEvent("onEventCancel",function(a,c){c&&(scheduler.map._markers[a]&&scheduler.map._markers[a].setMap(null),scheduler.map._infowindow.close());return!0})}); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_minical.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_minical.js index 99289260210..5bf564980f9 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_minical.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_minical.js @@ -1,9 +1,26 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.templates.calendar_month=scheduler.date.date_to_str("%F %Y");scheduler.templates.calendar_scale_date=scheduler.date.date_to_str("%D");scheduler.templates.calendar_date=scheduler.date.date_to_str("%d");scheduler.renderCalendar=function(G,A){var B=null;var D=G.date||(new Date());if(typeof D=="string"){D=this.templates.api_date(D)}if(!A){var M=G.container;var K=G.position;if(typeof M=="string"){M=document.getElementById(M)}if(typeof K=="string"){K=document.getElementById(K)}if(K&&(typeof K.left=="undefined")){var H=getOffset(K);K={top:H.top+K.offsetHeight,left:H.left}}if(!M){M=scheduler._get_def_cont(K)}B=this._render_calendar(M,D,G);B.onclick=function(P){P=P||event;var Q=P.target||P.srcElement;if(Q.className.indexOf("dhx_month_head")!=-1){var O=Q.parentNode.className;if(O.indexOf("dhx_after")==-1&&O.indexOf("dhx_before")==-1){var N=scheduler.templates.xml_date(this.getAttribute("date"));N.setDate(parseInt(Q.innerHTML,10));scheduler.unmarkCalendar(this);scheduler.markCalendar(this,N,"dhx_calendar_click");this._last_date=N;if(this.conf.handler){this.conf.handler.call(scheduler,N,this)}}}}}else{B=this._render_calendar(A.parentNode,D,G,A);scheduler.unmarkCalendar(B)}var C=scheduler.date.month_start(D);var E=scheduler.date.add(C,1,"month");var L=this.getEvents(C,E);for(var F=0;F=E.valueOf()){break}}}B.conf=G;return B};scheduler._get_def_cont=function(A){if(!this._def_count){this._def_count=document.createElement("DIV");this._def_count.style.cssText="position:absolute;z-index:10100;width:251px; height:175px;";this._def_count.onclick=function(B){(B||event).cancelBubble=true};document.body.appendChild(this._def_count)}this._def_count.style.left=A.left+"px";this._def_count.style.top=A.top+"px";this._def_count._created=new Date();return this._def_count};scheduler._locateCalendar=function(C,A){var B=C.childNodes[2].childNodes[0];if(typeof A=="string"){A=scheduler.templates.api_date(A)}var D=C.week_start+A.getDate()-1;return B.rows[Math.floor(D/7)].cells[D%7].firstChild};scheduler.markCalendar=function(C,A,B){this._locateCalendar(C,A).className+=" "+B};scheduler.unmarkCalendar=function(D,A,B){A=A||D._last_date;B=B||"dhx_calendar_click";if(!A){return }var C=this._locateCalendar(D,A);C.className=(C.className||"").replace(RegExp(B,"g"))};scheduler._week_template=function(B){var F=(B||250);var E=0;var C=document.createElement("div");var D=this.date.week_start(new Date());for(var A=0;A<7;A++){this._cols[A]=Math.floor(F/(7-A));this._render_x_header(A,E,D,C);D=this.date.add(D,1,"day");F-=this._cols[A];E+=this._cols[A]}C.lastChild.className+=" dhx_scale_bar_last";return C};scheduler.updateCalendar=function(B,A){B.conf.date=A;this.renderCalendar(B.conf,B)};scheduler._mini_cal_arrows=[" "," "];scheduler._render_calendar=function(G,A,F,D){var B=scheduler.templates;var K=this._cols;this._cols=[];var S=this._mode;this._mode="calendar";var R=this._colsS;this._colsS={height:0};var Q=new Date(this._min_date);var O=new Date(this._max_date);var N=new Date(scheduler._date);var L=B.month_day;B.month_day=B.calendar_date;A=this.date.month_start(A);var E=this._week_template(G.offsetWidth-1);var M;if(D){M=D}else{var M=document.createElement("DIV");M.className="dhx_cal_container dhx_mini_calendar"}M.setAttribute("date",this.templates.xml_format(A));M.innerHTML="
"+E.innerHTML+"
";M.childNodes[0].innerHTML=this.templates.calendar_month(A);if(F.navigation){var C=document.createElement("DIV");C.className="dhx_cal_prev_button";C.style.cssText="left:1px;top:2px;position:absolute;";C.innerHTML=this._mini_cal_arrows[0];M.firstChild.appendChild(C);C.onclick=function(){scheduler.updateCalendar(M,scheduler.date.add(M._date,-1,"month"))};C=document.createElement("DIV");C.className="dhx_cal_next_button";C.style.cssText="left:auto; right:1px;top:2px;position:absolute;";C.innerHTML=this._mini_cal_arrows[1];M.firstChild.appendChild(C);C.onclick=function(){scheduler.updateCalendar(M,scheduler.date.add(M._date,1,"month"))};M._date=new Date(A)}M.week_start=(A.getDay()-(this.config.start_on_monday?1:0)+7)%7;var P=this.date.week_start(A);this._reset_month_scale(M.childNodes[2],A,P);var I=M.childNodes[2].firstChild.rows;for(var J=I.length;J<6;J++){I[0].parentNode.appendChild(I[0].cloneNode(true));for(var H=0;H500){B=this._def_count.firstChild}}if(!B){return }B.onclick=null;B.innerHTML="";if(B.parentNode){B.parentNode.removeChild(B)}if(this._def_count){this._def_count.style.top="-1000px"}};scheduler.isCalendarVisible=function(){if(this._def_count&&parseInt(this._def_count.style.top,10)>0){return this._def_count}return false};scheduler.attachEvent("onTemplatesReady",function(){dhtmlxEvent(document.body,"click",function(){scheduler.destroyCalendar()})});scheduler.templates.calendar_time=scheduler.date.date_to_str("%d-%m-%Y");scheduler.form_blocks.calendar_time={render:function(){var D="";var B=scheduler.config;var E=this.date.date_part(new Date());if(B.first_hour){E.setHours(B.first_hour)}D+=" ";var A=scheduler.config.full_day;return"
"+D+"  –  "+D+"
"},set_value:function(B,K,H){var D=B.getElementsByTagName("input");var F=B.getElementsByTagName("select");var A=function(N,L,M){N.onclick=function(){scheduler.destroyCalendar(null,true);scheduler.renderCalendar({position:N,date:new Date(this._date),navigation:true,handler:function(O){N.value=scheduler.templates.calendar_time(O);N._date=new Date(O);scheduler.destroyCalendar();if(scheduler.config.event_duration&&M==0){J()}}})}};if(scheduler.config.full_day){if(!B._full_day){B.previousSibling.innerHTML+="
";B._full_day=true}var I=B.previousSibling.getElementsByTagName("input")[0];var E=(scheduler.date.time_part(H.start_date)==0&&scheduler.date.time_part(H.end_date)==0&&H.end_date.valueOf()-H.start_date.valueOf()<2*24*60*60*1000);I.checked=E;for(var C in F){F[C].disabled=I.checked}for(var C=0;C0){continue}scheduler.markCalendar(B,F,"dhx_calendar_click");F=scheduler.date.add(F,1,"day")}}}}return true};scheduler.attachEvent("onViewChange",A);scheduler.attachEvent("onXLE",A);scheduler.attachEvent("onEventAdded",A);scheduler.attachEvent("onEventChanged",A);scheduler.attachEvent("onAfterEventDelete",A);A()}; \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.templates.calendar_month=scheduler.date.date_to_str("%F %Y");scheduler.templates.calendar_scale_date=scheduler.date.date_to_str("%D");scheduler.templates.calendar_date=scheduler.date.date_to_str("%d"); +scheduler.renderCalendar=function(b,c){var a=null,d=b.date||new Date;typeof d=="string"&&(d=this.templates.api_date(d));if(c)a=this._render_calendar(c.parentNode,d,b,c),scheduler.unmarkCalendar(a);else{var e=b.container,f=b.position;typeof e=="string"&&(e=document.getElementById(e));typeof f=="string"&&(f=document.getElementById(f));if(f&&typeof f.left=="undefined")var n=getOffset(f),f={top:n.top+f.offsetHeight,left:n.left};e||(e=scheduler._get_def_cont(f));a=this._render_calendar(e,d,b);a.onclick= +function(a){var a=a||event,b=a.target||a.srcElement;if(b.className.indexOf("dhx_month_head")!=-1){var c=b.parentNode.className;if(c.indexOf("dhx_after")==-1&&c.indexOf("dhx_before")==-1){var d=scheduler.templates.xml_date(this.getAttribute("date"));d.setDate(parseInt(b.innerHTML,10));scheduler.unmarkCalendar(this);scheduler.markCalendar(this,d,"dhx_calendar_click");this._last_date=d;this.conf.handler&&this.conf.handler.call(scheduler,d,this)}}}}for(var m=scheduler.date.month_start(d),k=scheduler.date.add(m, +1,"month"),p=this.getEvents(m,k),i=0;i=k.valueOf())break}this._markCalendarCurrentDate(a);a.conf=b;return a}; +scheduler._get_def_cont=function(b){if(!this._def_count)this._def_count=document.createElement("DIV"),this._def_count.style.cssText="position:absolute;z-index:10100;width:251px; height:175px;",this._def_count.onclick=function(b){(b||event).cancelBubble=!0},document.body.appendChild(this._def_count);this._def_count.style.left=b.left+"px";this._def_count.style.top=b.top+"px";this._def_count._created=new Date;return this._def_count}; +scheduler._locateCalendar=function(b,c){var a=b.childNodes[2].childNodes[0];typeof c=="string"&&(c=scheduler.templates.api_date(c));var d=b.week_start+c.getDate()-1;return a.rows[Math.floor(d/7)].cells[d%7].firstChild};scheduler.markCalendar=function(b,c,a){this._locateCalendar(b,c).className+=" "+a};scheduler.unmarkCalendar=function(b,c,a){c=c||b._last_date;a=a||"dhx_calendar_click";if(c){var d=this._locateCalendar(b,c);d.className=(d.className||"").replace(RegExp(a,"g"))}}; +scheduler._week_template=function(b){for(var c=b||250,a=0,d=document.createElement("div"),e=this.date.week_start(new Date),f=0;f<7;f++)this._cols[f]=Math.floor(c/(7-f)),this._render_x_header(f,a,e,d),e=this.date.add(e,1,"day"),c-=this._cols[f],a+=this._cols[f];d.lastChild.className+=" dhx_scale_bar_last";return d};scheduler.updateCalendar=function(b,c){b.conf.date=c;this.renderCalendar(b.conf,b)};scheduler._mini_cal_arrows=[" "," "]; +scheduler._render_calendar=function(b,c,a,d){var e=scheduler.templates,f=this._cols;this._cols=[];var n=this._mode;this._mode="calendar";var m=this._colsS;this._colsS={height:0};var k=new Date(this._min_date),p=new Date(this._max_date),i=new Date(scheduler._date),o=e.month_day;e.month_day=e.calendar_date;var c=this.date.month_start(c),l=this._week_template(b.offsetWidth-1),g;d?g=d:(g=document.createElement("DIV"),g.className="dhx_cal_container dhx_mini_calendar");g.setAttribute("date",this.templates.xml_format(c)); +g.innerHTML="
"+l.innerHTML+"
";g.childNodes[0].innerHTML=this.templates.calendar_month(c);if(a.navigation){var h=document.createElement("DIV");h.className="dhx_cal_prev_button";h.style.cssText="left:1px;top:2px;position:absolute;";h.innerHTML=this._mini_cal_arrows[0];g.firstChild.appendChild(h);h.onclick=function(){scheduler.updateCalendar(g,scheduler.date.add(g._date,-1,"month"));scheduler._date.getMonth()== +g._date.getMonth()&&scheduler._date.getFullYear()==g._date.getFullYear()&&scheduler._markCalendarCurrentDate(g)};h=document.createElement("DIV");h.className="dhx_cal_next_button";h.style.cssText="left:auto; right:1px;top:2px;position:absolute;";h.innerHTML=this._mini_cal_arrows[1];g.firstChild.appendChild(h);h.onclick=function(){scheduler.updateCalendar(g,scheduler.date.add(g._date,1,"month"));scheduler._date.getMonth()==g._date.getMonth()&&scheduler._date.getFullYear()==g._date.getFullYear()&&scheduler._markCalendarCurrentDate(g)}}g._date= +new Date(c);g.week_start=(c.getDay()-(this.config.start_on_monday?1:0)+7)%7;var u=this.date.week_start(c);this._reset_month_scale(g.childNodes[2],c,u);for(var j=g.childNodes[2].firstChild.rows,q=j.length;q<6;q++){var t=j[j.length-1];j[0].parentNode.appendChild(t.cloneNode(!0));for(var r=parseInt(t.childNodes[t.childNodes.length-1].childNodes[0].innerHTML),r=r<10?r:0,s=0;s500))b=this._def_count.firstChild;if(b&&(b.onclick=null,b.innerHTML="",b.parentNode&&b.parentNode.removeChild(b),this._def_count))this._def_count.style.top="-1000px"};scheduler.isCalendarVisible=function(){return this._def_count&&parseInt(this._def_count.style.top,10)>0?this._def_count:!1}; +scheduler.attachEvent("onTemplatesReady",function(){dhtmlxEvent(document.body,"click",function(){scheduler.destroyCalendar()})});scheduler.templates.calendar_time=scheduler.date.date_to_str("%d-%m-%Y"); +scheduler.form_blocks.calendar_time={render:function(){var b="",c=scheduler.config,a=this.date.date_part(new Date);c.first_hour&&a.setHours(c.first_hour);b+=" ";var f=scheduler.config.full_day;return"
"+ +b+"  –  "+b+"
"},set_value:function(b,c,a){function d(a,b,c){n(a,b,c);a.value=scheduler.templates.calendar_time(b);a._date=scheduler.date.date_part(new Date(b))}var e=b.getElementsByTagName("input"),f=b.getElementsByTagName("select"),n=function(a,b,c){a.onclick=function(){scheduler.destroyCalendar(null,!0);scheduler.renderCalendar({position:a,date:new Date(this._date),navigation:!0,handler:function(b){a.value=scheduler.templates.calendar_time(b); +a._date=new Date(b);scheduler.destroyCalendar();scheduler.config.event_duration&&scheduler.config.auto_end_date&&c==0&&o()}})}};if(scheduler.config.full_day){if(!b._full_day){var m="";scheduler.config.wide_form||(m=b.previousSibling.innerHTML+m);b.previousSibling.innerHTML=m;b._full_day=!0}var k=b.previousSibling.getElementsByTagName("input")[0],p=scheduler.date.time_part(a.start_date)== +0&&scheduler.date.time_part(a.end_date)==0&&a.end_date.valueOf()-a.start_date.valueOf()<1728E5;k.checked=p;for(var i in f)f[i].disabled=k.checked;for(i=0;i";for(var A=0;A"+C.options[A].label+"";if(convertStringToBoolean(C.vertical)){B+="
"}}B+="";return B},set_value:function(C,J,I,A){var E=C.getElementsByTagName("input");for(var G=0;G",b=0;b"+d.options[b].label+"",convertStringToBoolean(d.vertical)&&(a+="
");a+="";return a},set_value:function(d,a,b,c){function h(b){for(var c=d.getElementsByTagName("input"),a=0;a"}I=U[0].offsetWidth;return T}function G(V,W){var T=parseInt(V.style.left);for(var U=0;UV){return T}}return W}function A(W){var U="";var X=W.firstChild.rows;for(var V=0;V";H=W.firstChild.rows[0].cells[0].offsetHeight}return U}function S(X){var U="";if(scheduler._mode=="agenda"){var T=scheduler._els.dhx_cal_header[0].childNodes[0].childNodes;U+=""+T[0].innerHTML+""+T[1].innerHTML+""}else{if(scheduler._mode=="year"){var T=scheduler._els.dhx_cal_data[0].childNodes;for(var V=0;V";U+=O(T[V].childNodes[1].childNodes);U+=A(T[V].childNodes[2]);U+=""}}else{U+="";var T=scheduler._els.dhx_cal_header[0].childNodes;U+=O(T);U+="";var W=scheduler._els.dhx_cal_data[0];if(W.firstChild.tagName=="TABLE"){U+=A(W)}else{W=W.childNodes[W.childNodes.length-1];while(W.className.indexOf("dhx_scale_holder")==-1){W=W.previousSibling}W=W.childNodes;U+="";for(var V=0;V"}U+="";H=W[0].offsetHeight}}}U+="";return U}function E(U,T){return(window.getComputedStyle?(window.getComputedStyle(U,null)[T]):(U.currentStyle?U.currentStyle[T]:null))||""}function B(){var b="";var j=scheduler._rendered;if(scheduler._mode=="agenda"){for(var Z=0;Z"+j[Z].childNodes[0].innerHTML+""+j[Z].childNodes[2].innerHTML+""}}else{if(scheduler._mode=="year"){var j=scheduler.get_visible_events();for(var Z=0;Z";scheduler._mark_year_date(f);f=scheduler.date.add(f,1,"day");if(f.valueOf()>=scheduler._max_date.valueOf()){break}}}}else{for(var Z=0;Z";if(Y=="event"){b+="
";var W=F?E(j[Z].childNodes[2],"color"):"";var h=F?E(j[Z].childNodes[2],"backgroundColor"):"";b+=""}else{var W=F?E(j[Z],"color"):"";var h=F?E(j[Z],"backgroundColor"):"";b+=""}b+=""}}}return b}function K(){var T="
";return T}var D=(new Date()).valueOf();var R=document.createElement("div");R.style.display="none";document.body.appendChild(R);R.innerHTML='
';document.getElementById(D).firstChild.value=S(J).replace("\u2013","-")+B()+K();document.getElementById(D).submit();R.parentNode.removeChild(R);grid=null}; \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.toPDF=function(x,f,m,n){function g(c){return c.replace(html_regexp,"")}function j(c){c=parseFloat(c);return isNaN(c)?"auto":100*c/(o+1)}function t(c){c=parseFloat(c);return isNaN(c)?"auto":100*c/k}function q(c){var a="";if(scheduler.matrix&&scheduler.matrix[scheduler._mode])c=c[0].childNodes;for(var b=0;b";o=c[0].offsetWidth;return a}function y(c,a){for(var b=parseInt(c.style.left),d=0;db)return d;return a}function w(c){for(var a="",b=c.firstChild.rows,d=0;d";k=c.firstChild.rows[0].cells[0].offsetHeight}return a}function A(c){var a= +"";if(scheduler._mode=="agenda"){var b=scheduler._els.dhx_cal_header[0].childNodes[0].childNodes;a+=""+g(b[0].innerHTML)+""+g(b[1].innerHTML)+""}else if(scheduler._mode=="year")for(var b=scheduler._els.dhx_cal_data[0].childNodes,d=0;d",a+=q(b[d].childNodes[1].childNodes),a+=w(b[d].childNodes[2]),a+="";else{a+="";b=scheduler._els.dhx_cal_header[0].childNodes;a+=q(b);a+="";var e=scheduler._els.dhx_cal_data[0];if(scheduler.matrix&&scheduler.matrix[scheduler._mode]){a+="";for(d=0;d";a+="";k=e.firstChild.rows[0].cells[0].offsetHeight}else if(e.firstChild.tagName=="TABLE")a+=w(e);else{for(e=e.childNodes[e.childNodes.length- +1];e.className.indexOf("dhx_scale_holder")==-1;)e=e.previousSibling;e=e.childNodes;a+="";for(d=0;d";a+="";k=e[0].offsetHeight}}a+="";return a}function r(c,a){return(window.getComputedStyle?window.getComputedStyle(c,null)[a]:c.currentStyle?c.currentStyle[a]:null)||""}function B(){var c="",a=scheduler._rendered;if(scheduler._mode=="agenda")for(var b=0;b"+g(a[b].childNodes[0].innerHTML)+""+ +g(a[b].childNodes[2].innerHTML)+"";else if(scheduler._mode=="year"){a=scheduler.get_visible_events();for(b=0;b";d=scheduler.date.add(d,1,"day"); +if(d.valueOf()>=scheduler._max_date.valueOf())break}}}else for(b=0;b";if(n=="event"){c+="
";var u=p?r(a[b].childNodes[2],"color"):"",v=p?r(a[b].childNodes[2],"backgroundColor"): +"";c+=""}else u=p?r(a[b],"color"):"",v=p?r(a[b],"backgroundColor"):"",c+="";c+=""}return c}function C(){var c="
";return c}var o=0,k=0,p=!1;f=="fullcolor"&&(p=!0,f="color");f=f||"color";html_regexp=RegExp("<[^>]*>","g");var l=(new Date).valueOf(),i=document.createElement("div");i.style.display="none";document.body.appendChild(i); +i.innerHTML='
';document.getElementById(l).firstChild.value=A(f).replace("\u2013","-")+B()+C();document.getElementById(l).submit();i.parentNode.removeChild(i);grid=null}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_readonly.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_readonly.js index cc182b4b12a..066e5e5a57b 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_readonly.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_readonly.js @@ -1,9 +1,9 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.attachEvent("onTemplatesReady",function(){scheduler.attachEvent("onBeforeLightbox",function(F){if(this.config.readonly_form||this.getEvent(F).readonly){this.config.readonly_active=true}else{this.config.readonly_active=false;return true}for(var E=0;E=0;I--){var L=F[I];if(!J){L.disabled=true}else{var H=document.createElement("SPAN");H.className="dhx_text_disabled";H.innerHTML=J(G[I]);L.parentNode.insertBefore(H,L);L.parentNode.removeChild(L)}}}var B=scheduler._fill_lightbox;scheduler._fill_lightbox=function(){var H=this.config.lightbox.sections;if(this.config.readonly_active){for(var F=0;F=0;g--)if(c=a[g],f){var i=document.createElement("SPAN");i.className="dhx_text_disabled";i.innerHTML=f(e[g]);c.parentNode.insertBefore(i,c);c.parentNode.removeChild(c)}else c.disabled=!0}scheduler.attachEvent("onBeforeLightbox",function(d){if(this.config.readonly_form||this.getEvent(d).readonly)this.config.readonly_active=!0;else return this.config.readonly_active= +!1,!0;for(var b=0;bA){return G.setDate(G.getDate()+D[B]*1-A-(C?F:E))}}this.transpose_day_week(G,D,F+C,null,F)};scheduler.transpose_type=function(D){var F="transpose_"+D;if(!this.date[F]){var G=D.split("_");var A=60*60*24*1000;var C="add_"+D;var E=this.transponse_size[G[0]]*G[1];if(G[0]=="day"||G[0]=="week"){var H=null;if(G[4]){H=G[4].split(",");if(scheduler.config.start_on_monday){for(var B=0;B0){I.setDate(I.getDate()+J*E)}if(H){scheduler.transpose_day_week(I,H,1,E)}};this.date[C]=function(K,J){var L=new Date(K.valueOf());if(H){for(var I=0;I=0){I.setMonth(I.getMonth()+J*E)}if(G[3]){scheduler.date.day_week(I,G[2],G[3])}};this.date[C]=function(J,I){var K=new Date(J.valueOf());K.setMonth(K.getMonth()+I*E);if(G[3]){scheduler.date.day_week(K,G[2],G[3])}return K}}}}};scheduler.repeat_date=function(F,G,C,I,J){I=I||this._min_date;J=J||this._max_date;var E=new Date(F.start_date.valueOf());if(!F.rec_pattern&&F.rec_type){F.rec_pattern=F.rec_type.split("#")[0]}this.transpose_type(F.rec_pattern);scheduler.date["transpose_"+F.rec_pattern](E,I);while(E0){B.end_date=new Date(E.valueOf()+F.event_length*1000-D*60*1000)}else{B.end_date=new Date(B.end_date.valueOf()+D*60*1000)}}B._timed=this.is_one_day_event(B);if(!B._timed&&!this._table_view&&!this.config.multi_day){return }G.push(B);if(!C){this._events[B.id]=B;this._rec_temp.push(B)}}else{if(C){G.push(A)}}E=this.date.add(E,1,F.rec_pattern)}};scheduler.getRecDates=function(B,H){var G=typeof B=="object"?B:scheduler.getEvent(B);var E=0;var J=[];H=H||1000;var C=new Date(G.start_date.valueOf());var I=new Date(C.valueOf());if(!G.rec_type){return[{start_date:G.start_date,end_date:G.end_date}]}this.transpose_type(G.rec_pattern);scheduler.date["transpose_"+G.rec_pattern](C,I);while(CG){if(D.rec_pattern){if(D.rec_pattern=="none"){continue}var E=[];this.repeat_date(D,E,true,G,F);for(var C=0;CG){A.push(E[C])}}}else{if(!D.event_pid||D.event_pid==0){A.push(D)}}}}return A};scheduler.config.repeat_date="%m.%d.%Y";scheduler.config.lightbox.sections=[{name:"description",height:130,map_to:"text",type:"textarea",focus:true},{name:"recurring",height:115,type:"recurring",map_to:"rec_type",button:"recurring"},{name:"time",height:72,type:"time",map_to:"auto"}];scheduler._copy_dummy=function(A){this.start_date=new Date(this.start_date);this.end_date=new Date(this.end_date);this.event_length=this.event_pid=this.rec_pattern=this.rec_type=this._timed=null};scheduler.__recurring_template='



day everymonth
everymonth

occurrences

'; \ No newline at end of file +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.form_blocks.recurring={render:function(){return scheduler.__recurring_template},_ds:{},_init_set_value:function(a,b,c){function d(a){for(var b=0;be)return a.setDate(a.getDate()+b[h]*1-e-(d?c:f));this.transpose_day_week(a,b,c+d,null,c)}; +scheduler.transpose_type=function(a){var b="transpose_"+a;if(!this.date[b]){var c=a.split("_"),d=864E5,f="add_"+a,e=this.transponse_size[c[0]]*c[1];if(c[0]=="day"||c[0]=="week"){var h=null;if(c[4]&&(h=c[4].split(","),scheduler.config.start_on_monday)){for(var j=0;j0&&a.setDate(a.getDate()+c*e);h&&scheduler.transpose_day_week(a,h,1,e)};this.date[f]=function(a,b){var c=new Date(a.valueOf()); +if(h)for(var d=0;d=0&&a.setMonth(a.getMonth()+d*e);c[3]&&scheduler.date.day_week(a,c[2],c[3])},this.date[f]=function(a,b){var d=new Date(a.valueOf());d.setMonth(d.getMonth()+b*e);c[3]&&scheduler.date.day_week(d,c[2],c[3]);return d}}}; +scheduler.repeat_date=function(a,b,c,d,f){var d=d||this._min_date,f=f||this._max_date,e=new Date(a.start_date.valueOf());if(!a.rec_pattern&&a.rec_type)a.rec_pattern=a.rec_type.split("#")[0];this.transpose_type(a.rec_pattern);for(scheduler.date["transpose_"+a.rec_pattern](e,d);e0?new Date(e.valueOf()+a.event_length*1E3-k*6E4):new Date(i.end_date.valueOf()+k*6E4);i._timed=this.is_one_day_event(i);if(!i._timed&&!this._table_view&&!this.config.multi_day)break;b.push(i);c||(this._events[i.id]=i,this._rec_temp.push(i))}e=this.date.add(e,1,a.rec_pattern)}}; +scheduler.getRecDates=function(a,b){var c=typeof a=="object"?a:scheduler.getEvent(a),d=0,f=[],b=b||1E3,e=new Date(c.start_date.valueOf()),h=new Date(e.valueOf());if(!c.rec_type)return[{start_date:c.start_date,end_date:c.end_date}];this.transpose_type(c.rec_pattern);for(scheduler.date["transpose_"+c.rec_pattern](e,h);ea)if(f.rec_pattern){if(f.rec_pattern!="none"){var e=[];this.repeat_date(f,e,!0,a,b);for(var h=0;ha&&!this._rec_markers[e[h].id]&&c.push(e[h])}}else f.id.toString().indexOf("#")==-1&&c.push(f)}return c};scheduler.config.repeat_date="%m.%d.%Y"; +scheduler.config.lightbox.sections=[{name:"description",height:130,map_to:"text",type:"textarea",focus:!0},{name:"recurring",type:"recurring",map_to:"rec_type",button:"recurring"},{name:"time",height:72,type:"time",map_to:"auto"}];scheduler._copy_dummy=function(){this.start_date=new Date(this.start_date);this.end_date=new Date(this.end_date);this.event_length=this.event_pid=this.rec_pattern=this.rec_type=this._timed=null}; +scheduler.__recurring_template='



day everymonth
everymonth

occurrences

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_serialize.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_serialize.js index 2e041981b10..fd3b34913bb 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_serialize.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_serialize.js @@ -1,9 +1,8 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.data_attributes=function(){var C=[];var E=scheduler.templates.xml_format;for(var A in this._events){var D=this._events[A];for(var B in D){if(B.substr(0,1)!="_"){C.push([B,((B=="start_date"||B=="end_date")?E:null)])}}break}return C};scheduler.toXML=function(F){var C=[];var B=this.data_attributes();for(var A in this._events){var E=this._events[A];if(E.id.toString().indexOf("#")!=-1){continue}C.push("");for(var D=0;D")}C.push("")}return(F||"")+""+C.join("\n")+""};scheduler.toJSON=function(){var E=[];var C=this.data_attributes();for(var B in this._events){var F=this._events[B];if(F.id.toString().indexOf("#")!=-1){continue}var F=this._events[B];var A=[];for(var D=0;D");for(var b=0;b");d.push("")}}return(f||"")+""+d.join("\n")+""}; +scheduler.toJSON=function(){var f=[],d=this.data_attributes(),c;for(c in this._events){var e=this._events[c];if(e.id.toString().indexOf("#")==-1){for(var e=this._events[c],a=[],b=0;bU.x){break}}T=0;for(Q;QU.y){break}}U.fields={};U.fields[O.y_property]=P[O.y_property]=O.y_unit[Q].key;U.x=Q/10000000;if(this._drag_mode=="new-size"&&P.start_date*1==this._drag_start*1){S++}if(S>=O._trace_x.length){var R=scheduler.date.add(O._trace_x[O._trace_x.length-1],O.x_step,O.x_unit)}else{var R=O._trace_x[S]}U.y=Math.round((R-this._min_date)/(1000*60*this.config.time_step));U.custom=true;U.shift=M;return U}}};scheduler.render_timeline_event=function(U,V,R){var N=E(U,false,this._step);var L=E(U,true,this._step);var P=scheduler.xy.bar_height;var T=2+V*P;var Q=scheduler.templates.event_class(U.start_date,U.end_date,U);Q="dhx_cal_event_line "+(Q||"");var O='
'+scheduler.templates.event_bar_text(U.start_date,U.end_date,U)+"
";if(!R){return O}else{var S=document.createElement("DIV");S.innerHTML=O;var M=this.order[U[this.y_property]];var W=scheduler._els.dhx_cal_data[0].firstChild.rows[M].cells[1].firstChild;scheduler._rendered.push(S.firstChild);W.appendChild(S.firstChild)}};function K(){var N=scheduler.getEvents(scheduler._min_date,scheduler._max_date);var M=[];for(var O=0;O=this._trace_x[L+1]){L++}while(this._trace_x[L]&&N[O].end_date>this._trace_x[L]){if(!M[P][L]){M[P][L]=[]}M[P][L].push(N[O]);L++}}return M}function E(S,Q,L){var T=0;var O=(Q)?S.end_date:S.start_date;if(O.valueOf()>scheduler._max_date.valueOf()){O=scheduler._max_date}var U=O-scheduler._min_date_timeline;if(U<0){M=0}else{var R=Math.round(U/(L*scheduler._cols[0]));if(R>scheduler._cols.length){R=scheduler._cols.length}for(var P=0;P"+Q.td_content+"";if(this.render=="cell"){for(var O=0;O
"+scheduler.templates[this.name+"_cell_value"](Z[P][O])+"
"}}else{R+="
";if(Z[P]){Z[P].sort(function(d,c){return d.start_date>c.start_date?1:-1});var X=[];for(var O=0;OW.start_date){L++}X[L]=W;R+=scheduler.render_timeline_event.call(this,W,L)}}R+="";for(var O=0;O
"}R+="
";R+="
"}R+=""}R+="";this._matrix=Z;S.scrollTop=0;S.innerHTML=R;scheduler._rendered=[];var U=document.getElementsByTagName("DIV");for(var P=0;PT.start_date?1:-1});if(scheduler._tooltip){if(scheduler._tooltip.date==R){return }scheduler._tooltip.innerHTML=""}else{var O=scheduler._tooltip=document.createElement("DIV");O.className="dhx_tooltip";document.body.appendChild(O);O.onclick=scheduler._click.dhx_cal_data}var N="";for(var M=0;M";N+="
"+(L[M]._timed?scheduler.templates.event_date(L[M].start_date):"")+"
";N+="
 
";N+=scheduler.templates[P.name+"_tooltip"](L[M].start_date,L[M].end_date,L[M])+"
"}scheduler._tooltip.style.display="";scheduler._tooltip.style.top="0px";if(document.body.offsetWidth-Q.left-scheduler._tooltip.offsetWidth<0){scheduler._tooltip.style.left=Q.left-scheduler._tooltip.offsetWidth+"px"}else{scheduler._tooltip.style.left=Q.left+S.src.offsetWidth+"px"}scheduler._tooltip.date=R;scheduler._tooltip.innerHTML=N;if(document.body.offsetHeight-Q.top-scheduler._tooltip.offsetHeight<0){scheduler._tooltip.style.top=Q.top-scheduler._tooltip.offsetHeight+S.src.offsetHeight+"px"}else{scheduler._tooltip.style.top=Q.top+"px"}}function F(){dhtmlxEvent(scheduler._els.dhx_cal_data[0],"mouseover",function(M){var L=scheduler.matrix[scheduler._mode];if(L){var O=scheduler._locate_cell_timeline(M);var M=M||event;var N=M.target||M.srcElement;if(O){return J(L,O,getOffset(O.src))}}H()});F=function(){}}scheduler.renderMatrix=function(M){var L=scheduler.date[this.name+"_start"](scheduler._date);scheduler._min_date=scheduler.date.add(L,this.x_start*this.x_step,this.x_unit);scheduler._max_date=scheduler.date.add(scheduler._min_date,this.x_size*this.x_step,this.x_unit);scheduler._table_view=true;C.call(this,M)};function G(M){var N=M.parentNode.childNodes;for(var L=0;L=this._trace_x[d+1];)d++;for(;this._trace_x[d]&&a[c].end_date>this._trace_x[d];)b[f][d]||(b[f][d]=[]),b[f][d].push(a[c]),d++}return b}function v(a,b,c){var f=0,d=b?a.end_date:a.start_date;if(d.valueOf()>scheduler._max_date.valueOf())d=scheduler._max_date;var i=d-scheduler._min_date_timeline; +if(i<0)k=0;else{var g=Math.round(i/(c*scheduler._cols[0]));if(g>scheduler._cols.length)g=scheduler._cols.length;for(var e=0;ed.start_date?1:-1});for(var l=[],d=0;dm.start_date;)n++;l[n]=m;o+=scheduler.render_timeline_event.call(this,m,n)}}if(this.fit_events){var w=this._events_height[this.y_unit[e].key]||0;h.height=w>h.height?w:h.height;h.style_height="height:"+ +h.height+"px;"}b+=""+h.td_content+"";if(this.render=="cell")for(d=0;d
"+scheduler.templates[this.name+"_cell_value"](c[e][d])+ +"
";else{b+="
";b+=o;b+="";for(d=0;d
"; +b+="
";b+="
"}b+=""}b+="";this._matrix=c;a.innerHTML=b;scheduler._rendered=[];for(var q=document.getElementsByTagName("DIV"),e=0;e
";if(this.second_scale){for(var j=this.second_scale.x_unit,k=[this._trace_x[0]],h=[],o=[this.dx,this.dx],l=0,m=0;m
";var p=a.firstChild;p.style.height=c+"px";var v=a.lastChild;v.style.position="relative";for(var r=0;rd.start_date?1:-1});if(scheduler._tooltip){if(scheduler._tooltip.date== +f)return;scheduler._tooltip.innerHTML=""}else{var i=scheduler._tooltip=document.createElement("DIV");i.className="dhx_tooltip";document.body.appendChild(i);i.onclick=scheduler._click.dhx_cal_data}for(var g="",e=0;e";g+="
"+(d[e]._timed?scheduler.templates.event_date(d[e].start_date): +"")+"
";g+="
 
";g+=scheduler.templates[a.name+"_tooltip"](d[e].start_date,d[e].end_date,d[e])+""}scheduler._tooltip.style.display="";scheduler._tooltip.style.top="0px";scheduler._tooltip.style.left=document.body.offsetWidth-c.left-scheduler._tooltip.offsetWidth<0?c.left-scheduler._tooltip.offsetWidth+"px":c.left+b.src.offsetWidth+"px";scheduler._tooltip.date=f;scheduler._tooltip.innerHTML=g;scheduler._tooltip.style.top=document.body.offsetHeight- +c.top-scheduler._tooltip.offsetHeight<0?c.top-scheduler._tooltip.offsetHeight+b.src.offsetHeight+"px":c.top+"px"}}function t(){dhtmlxEvent(scheduler._els.dhx_cal_data[0],"mouseover",function(a){var b=scheduler.matrix[scheduler._mode];if(b){var c=scheduler._locate_cell_timeline(a),a=a||event,f=a.target||a.srcElement;if(c)return F(b,c,getOffset(c.src))}u()});t=function(){}}function G(a){for(var b=a.parentNode.childNodes,c=0;cb.x)break;for(g=0;jb.y)break;b.fields={};a.y_unit[j]||(j=a.y_unit.length-1);b.fields[a.y_property]=c[a.y_property]=a.y_unit[j].key;b.x=0;this._drag_mode=="new-size"&&c.start_date*1==this._drag_start*1&&e++;var k=e>=a._trace_x.length?scheduler.date.add(a._trace_x[a._trace_x.length-1],a.x_step,a.x_unit):a._trace_x[e];b.y=Math.round((k-this._min_date)/(6E4*this.config.time_step));b.custom=!0;b.shift=f;return b}}};scheduler.render_timeline_event=function(a,b,c){var f=v(a,!1,this._step),d=v(a,!0, +this._step),i=scheduler.xy.bar_height,g=2+b*i,e=i+g-2,j=a[this.y_property];if(!this._events_height[j]||this._events_height[j]'+scheduler.templates.event_bar_text(a.start_date, +a.end_date,a)+"";if(c){var m=document.createElement("DIV");m.innerHTML=l;var n=this.order[j],p=scheduler._els.dhx_cal_data[0].firstChild.rows[n].cells[1].firstChild;scheduler._rendered.push(m.firstChild);p.appendChild(m.firstChild)}else return l};scheduler.renderMatrix=function(a){scheduler._els.dhx_cal_data[0].scrollTop=0;var b=scheduler.date[this.name+"_start"](scheduler._date);scheduler._min_date=scheduler.date.add(b,this.x_start*this.x_step,this.x_unit);scheduler._max_date=scheduler.date.add(scheduler._min_date, +this.x_size*this.x_step,this.x_unit);scheduler._table_view=!0;if(this.second_scale){if(a&&!this._header_resized)this._header_resized=scheduler.xy.scale_height,scheduler.xy.scale_height*=2,scheduler._els.dhx_cal_header[0].className+=" dhx_second_cal_header";if(!a&&this._header_resized){scheduler.xy.scale_height/=2;this._header_resized=!1;var c=scheduler._els.dhx_cal_header[0];c.className=c.className.replace(/ dhx_second_cal_header/gi,"")}}p.call(this,a)};scheduler._locate_cell_timeline=function(a){for(var a= +a||event,b=a.target?a.target:a.srcElement;b&&b.tagName!="TD";)b=b.parentNode;if(b&&b.tagName=="TD"){var c=b.className.split(" ")[0];if(c=="dhx_matrix_cell")if(scheduler._isRender("cell"))return{x:b.cellIndex-1,y:b.parentNode.rowIndex,src:b};else{for(var f=b.parentNode;f&&f.tagName!="TD";)f=f.parentNode;return{x:b.cellIndex,y:f.parentNode.rowIndex,src:b}}else if(c=="dhx_matrix_scell")return{x:-1,y:b.parentNode.rowIndex,src:b,scale:!0}}return!1};var H=scheduler._click.dhx_cal_data;scheduler._click.dhx_cal_data= +function(a){var b=H.apply(this,arguments),c=scheduler.matrix[scheduler._mode];if(c){var f=scheduler._locate_cell_timeline(a);f&&(f.scale?scheduler.callEvent("onYScaleClick",[f.y,c.y_unit[f.y],a||event]):scheduler.callEvent("onCellClick",[f.x,f.y,c._trace_x[f.x],(c._matrix[f.y]||{})[f.x]||[],a||event]))}return b};scheduler.dblclick_dhx_matrix_cell=function(a){var b=scheduler.matrix[scheduler._mode];if(b){var c=scheduler._locate_cell_timeline(a);c&&(c.scale?scheduler.callEvent("onYScaleDblClick",[c.y, +b.y_unit[c.y],a||event]):scheduler.callEvent("onCellDblClick",[c.x,c.y,b._trace_x[c.x],(b._matrix[c.y]||{})[c.x]||[],a||event]))}};scheduler.dblclick_dhx_matrix_scell=function(a){return scheduler.dblclick_dhx_matrix_cell(a)};scheduler._isRender=function(a){return scheduler.matrix[scheduler._mode]&&scheduler.matrix[scheduler._mode].render==a};scheduler.attachEvent("onCellDblClick",function(a,b,c,f,d){if(!(this.config.readonly||d.type=="dblclick"&&!this.config.dblclick_create)){var i=scheduler.matrix[scheduler._mode], +g={};g.start_date=i._trace_x[a];g.end_date=i._trace_x[a+1]?i._trace_x[a+1]:scheduler.date.add(i._trace_x[a],i.x_step,i.x_unit);g[scheduler.matrix[scheduler._mode].y_property]=i.y_unit[b].key;scheduler.addEventNow(g,null,d)}});scheduler.attachEvent("onBeforeDrag",function(){return scheduler._isRender("cell")?!1:!0})})(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_tooltip.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_tooltip.js index e24ad910174..2458d37e841 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_tooltip.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_tooltip.js @@ -1 +1,11 @@ -window.dhtmlXTooltip={version:0.1};dhtmlXTooltip.config={className:"dhtmlXTooltip tooltip",timeout_to_display:50,delta_x:15,delta_y:-20};dhtmlXTooltip.tooltip=document.createElement("div");dhtmlXTooltip.tooltip.className=dhtmlXTooltip.config.className;dhtmlXTooltip.show=function(D,G){dhtmlXTooltip.tooltip.className=dhtmlXTooltip.config.className;var H=this.position(D);var E=D.target||D.srcElement;if(this.isTooltip(E)){return }var C=H.x+dhtmlXTooltip.config.delta_x||0;var B=H.y-dhtmlXTooltip.config.delta_y||0;this.tooltip.style.visibility="hidden";if(this.tooltip.style.removeAttribute){this.tooltip.style.removeAttribute("right");this.tooltip.style.removeAttribute("bottom")}else{this.tooltip.style.removeProperty("right");this.tooltip.style.removeProperty("bottom")}this.tooltip.style.left="0px";this.tooltip.style.top="0px";this.tooltip.innerHTML=G;scheduler._obj.appendChild(this.tooltip);var A=this.tooltip.offsetWidth;var F=this.tooltip.offsetHeight;if(document.body.offsetWidth-C-A<0){if(this.tooltip.style.removeAttribute){this.tooltip.style.removeAttribute("left")}else{this.tooltip.style.removeProperty("left")}this.tooltip.style.right=(document.body.offsetWidth-C+2*dhtmlXTooltip.config.delta_x||0)+"px"}else{if(C<0){this.tooltip.style.left=(H.x+Math.abs(dhtmlXTooltip.config.delta_x||0))+"px"}else{this.tooltip.style.left=C+"px"}}if(document.body.offsetHeight-B-F<0){if(this.tooltip.style.removeAttribute){this.tooltip.style.removeAttribute("top")}else{this.tooltip.style.removeProperty("top")}this.tooltip.style.bottom=(document.body.offsetHeight-B-2*dhtmlXTooltip.config.delta_y||0)+"px"}else{if(B<0){this.tooltip.style.top=(H.y+Math.abs(dhtmlXTooltip.config.delta_y||0))+"px"}else{this.tooltip.style.top=B+"px"}}this.tooltip.style.visibility="visible"};dhtmlXTooltip.hide=function(){if(this.tooltip.parentNode){this.tooltip.parentNode.removeChild(this.tooltip)}};dhtmlXTooltip.delay=function(D,B,C,A){if(this.tooltip._timeout_id){window.clearTimeout(this.tooltip._timeout_id)}this.tooltip._timeout_id=setTimeout(function(){var E=D.apply(B,C);D=obj=C=null;return E},A||this.config.timeout_to_display)};dhtmlXTooltip.isTooltip=function(B){var A=false;while(B&&!A){A=(B.className==this.tooltip.className);B=B.parentNode}return A};dhtmlXTooltip.position=function(A){var A=A||window.event;if(A.pageX||A.pageY){return{x:A.pageX,y:A.pageY}}var B=((dhtmlx._isIE)&&(document.compatMode!="BackCompat"))?document.documentElement:document.body;return{x:A.clientX+B.scrollLeft-B.clientLeft,y:A.clientY+B.scrollTop-B.clientTop}};scheduler.attachEvent("onMouseMove",function(D,F){var C=F||window.event;var E=C.target||C.srcElement;if(D||dhtmlXTooltip.isTooltip(E)){var B=scheduler.getEvent(D)||scheduler.getEvent(dhtmlXTooltip.tooltip.event_id);dhtmlXTooltip.tooltip.event_id=B.id;var G=scheduler.templates.tooltip_text(B.start_date,B.end_date,B);if(_isIE){var A=document.createEventObject(C)}dhtmlXTooltip.delay(dhtmlXTooltip.show,dhtmlXTooltip,[A||C,G])}else{dhtmlXTooltip.delay(dhtmlXTooltip.hide,dhtmlXTooltip,[])}});scheduler.templates.tooltip_text=function(C,A,B){return"Event: "+B.text+"
Start date: "+scheduler.templates.tooltip_date_format(C)+"
End date: "+scheduler.templates.tooltip_date_format(A)}; \ No newline at end of file +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +window.dhtmlXTooltip={};dhtmlXTooltip.config={className:"dhtmlXTooltip tooltip",timeout_to_display:50,delta_x:15,delta_y:-20};dhtmlXTooltip.tooltip=document.createElement("div");dhtmlXTooltip.tooltip.className=dhtmlXTooltip.config.className; +dhtmlXTooltip.show=function(b,d){var c=dhtmlXTooltip,f=this.tooltip,a=f.style;c.tooltip.className=c.config.className;var e=this.position(b),k=b.target||b.srcElement;if(!this.isTooltip(k)){var g=0,l=0,h=scheduler._obj;if(h.offsetParent){do g+=h.offsetLeft,l+=h.offsetTop;while(h=h.offsetParent)}var i=e.x+(c.config.delta_x||0)-g,j=e.y-(c.config.delta_y||0)-l;a.visibility="hidden";a.removeAttribute?(a.removeAttribute("right"),a.removeAttribute("bottom")):(a.removeProperty("right"),a.removeProperty("bottom")); +a.left="0";a.top="0";this.tooltip.innerHTML=d;scheduler._obj.appendChild(this.tooltip);var m=this.tooltip.offsetWidth,n=this.tooltip.offsetHeight;scheduler._obj.offsetWidth-i-(scheduler.xy.margin_left||0)-m<0?(a.removeAttribute?a.removeAttribute("left"):a.removeProperty("left"),a.right=scheduler._obj.offsetWidth-i+2*(c.config.delta_x||0)+"px"):a.left=i<0?e.x+Math.abs(c.config.delta_x||0)+"px":i+"px";scheduler._obj.offsetHeight-j-(scheduler.xy.margin_top||0)-n<0?(a.removeAttribute?a.removeAttribute("top"): +a.removeProperty("top"),a.bottom=scheduler._obj.offsetHeight-j-2*(c.config.delta_y||0)+"px"):a.top=j<0?e.y+Math.abs(c.config.delta_y||0)+"px":j+"px";a.visibility="visible"}};dhtmlXTooltip.hide=function(){this.tooltip.parentNode&&this.tooltip.parentNode.removeChild(this.tooltip)};dhtmlXTooltip.delay=function(b,d,c,f){this.tooltip._timeout_id&&window.clearTimeout(this.tooltip._timeout_id);this.tooltip._timeout_id=setTimeout(function(){var a=b.apply(d,c);b=d=c=null;return a},f||this.config.timeout_to_display)}; +dhtmlXTooltip.isTooltip=function(b){for(var d=!1;b&&!d;)d=b.className==this.tooltip.className,b=b.parentNode;return d};dhtmlXTooltip.position=function(b){b=b||window.event;if(b.pageX||b.pageY)return{x:b.pageX,y:b.pageY};var d=dhtmlx._isIE&&document.compatMode!="BackCompat"?document.documentElement:document.body;return{x:b.clientX+d.scrollLeft-d.clientLeft,y:b.clientY+d.scrollTop-d.clientTop}}; +scheduler.attachEvent("onMouseMove",function(b,d){var c=window.event||d,f=c.target||c.srcElement,a=dhtmlXTooltip;if(b||a.isTooltip(f)){var e=scheduler.getEvent(b)||scheduler.getEvent(a.tooltip.event_id);if(e){a.tooltip.event_id=e.id;var k=scheduler.templates.tooltip_text(e.start_date,e.end_date,e),g=void 0;_isIE&&(g=document.createEventObject(c));a.delay(a.show,a,[g||c,k])}}else a.delay(a.hide,a,[])});scheduler.attachEvent("onBeforeDrag",function(){dhtmlXTooltip.hide();return!0}); +scheduler.templates.tooltip_date_format=scheduler.date.date_to_str("%Y-%m-%d %H:%i");scheduler.templates.tooltip_text=function(b,d,c){return"Event: "+c.text+"
Start date: "+scheduler.templates.tooltip_date_format(b)+"
End date: "+scheduler.templates.tooltip_date_format(d)}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.css b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.css index e72e38213d0..212423da5d1 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.css +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.css @@ -1,9 +1,5 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ .dhx_cal_prev_button,.dhx_cal_next_button,.dhx_cal_today_button,.dhx_cal_add_button{top:6px!important;left:10px;border:1px solid #575D65;border-top:1px solid #4E5052;color:#FFF;text-shadow:0 -1px 0 #65696E;background-image:-webkit-gradient(linear,left top,left bottom,from(#B2B6BC),to(#6B737E));background-color:#989B9F;background-position:0 1px;background-repeat:repeat-x;-webkit-border-radius:5px;padding:3px;text-align:center;text-decoration:none;}.dhx_cal_today_button{left:55px;}.dhx_cal_next_button{left:146px;}.dhx_cal_add_button{right:9px;left:auto;width:20px;font-size:20px;padding:1px 2px 2px 2px;}.dhx_cal_navline .dhx_cal_date{top:7px;left:160px;right:350px;padding-top:4px;width:auto;text-align:center;color:#4F5459;}.dhx_cal_navline{background:-webkit-gradient(linear,0% 0,0% 100%,color-stop(0,#F4F5F8),color-stop(0.3,#F1F2F4),color-stop(0.7,#C4C7D0),color-stop(1,#A6AAB7));border-bottom:1px solid #797F90;height:40px!important;font-family:Helvetica;font-weight:bold;font-size:13px;}.dhx_cal_tab{top:6px!important;color:#4F5459;text-align:center;padding:5px 10px;width:80px;background-image:-webkit-gradient(linear,0% 0,0% 100%,from(#F7F7F7),to(#B9BDC7));background-color:#CFD0D1;background-position:0 1px;background-repeat:repeat-x;text-decoration:none;border:1px solid #95989F;border-top:1px solid #686A6A;height:16px;}.dhx_cal_tab.active{background-image:-webkit-gradient(linear,0% 0,0% 100%,from(#B0B2B6),to(#666D74));background-color:#949799;background-position:0 1px;background-repeat:repeat-x;border:1px solid #4C4D4F;border-top:1px solid #52585C;color:#F8F8F8;text-shadow:0 -1px 0 #5E6063;text-decoration:none;height:16px;padding:5px 10px;z-index:100;}.dhx_cal_light{-webkit-transition:-webkit-transform;-webkit-transform-style:preserve-3d;}.dhx_cal_cover{opacity:.5;}.dhx_cal_ltext{padding-top:0;padding-bottom:0;}.dhx_cal_ltext textarea{-webkit-background-size:0;-webkit-border-radius:0;height:94%;}.dhx_mini_calendar .dhx_month_head{height:35px;line-height:35px;text-align:center;padding-right:0;padding-left:0;}.dhx_mini_calendar .dhx_year_month{height:35px;line-height:30px;background:-webkit-gradient(linear,0% 0,0% 100%,from(#F4F5F8),to(#8A8E9A));font-family:Helvetica;font-weight:bold;font-size:13px;}.dhx_mini_calendar .dhx_year_month .dhx_cal_prev_button,.dhx_mini_calendar .dhx_year_month .dhx_cal_next_button{line-height:normal;} \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.js index 9004dfcee68..70b4abeda7c 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_touch.js @@ -1,9 +1,26 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -TouchScroll=function(D,E,A,B){this.debug=!!E;this.compat=!!B;this.rough=!!A;this.axisX=this.axisY=true;if(typeof D!="object"){D=document.getElementById(D)}this._init();D.addEventListener("touchstart",this,false);D.addEventListener("webkitTransitionEnd",this,false);if(this.debug){D.addEventListener("mousedown",this,false)}this.node=D;for(var C=0;C50){this.scroll_x=true}if(Math.abs(A)>50){this.scroll_y=true}if(this.scroll_x||this.scroll_y){this.x=G.pageX;this.y=G.pageY;this.scroll=true;var C=this.get_matrix();D=D+(this.target_x-C.e);A=A+(this.target_y-C.f);var F="2000ms";var B="500ms";this.target_x=D+C.e;this.target_y=A+C.f;if(this.target_x>0){this.target_x=0;F=B}if(this.target_y>0){this.target_y=0;F=B}if(this.mx-this.dx+this.target_x<0){this.target_x=-this.mx+this.dx;F=B}if(this.my-this.dy+this.target_y<0){this.target_y=-this.my+this.dy;F=B}this.set_matrix({e:this.target_x,f:this.target_y},F);this._add_scroll(C.e,C.f);this._correct_scroll(this.target_x,this.target_y,F);this.onscroll(this.target_x,this.target_y)}return false},_correct_scroll:function(A,F,B){if(this.scrolls.x){var E=this.get_matrix(this.scrolls.x);var D=this.dx*A/this.mx;this.set_matrix({e:-1*D,f:0},B,this.scrolls.x)}if(this.scrolls.y){var E=this.get_matrix(this.scrolls.y);var C=this.dy*F/this.my;this.set_matrix({e:0,f:-1*C},B,this.scrolls.y)}},_remove_scroll:function(){if(this.scrolls.x){this.scrolls.x.parentNode.removeChild(this.scrolls.x)}if(this.scrolls.y){this.scrolls.y.parentNode.removeChild(this.scrolls.y)}this.scrolls={}},_add_scroll:function(){if(this.scrolls.ready){return }var C;if(this.my>5&&this.axisY){var B=this.dy*this.dy/this.my-1;this.scrolls.y=C=document.createElement("DIV");C.className="dhx_scroll_y";C.style.height=B+"px";this.node.appendChild(C)}if(this.mx>5&&this.axisX){var B=this.dx*this.dx/this.mx;this.scrolls.x=C=document.createElement("DIV");C.className="dhx_scroll_x";C.style.width=B+"px";this.node.appendChild(C)}var A=this.get_matrix();this._correct_scroll(A.e,A.f,0);this.scrolls.ready=true},_init_events:function(){document.addEventListener("touchmove",this,false);document.addEventListener("touchend",this,false);if(this.debug){document.addEventListener("mousemove",this,false);document.addEventListener("mouseup",this,false)}},_deinit_events:function(){document.removeEventListener("touchmove",this,false);document.removeEventListener("touchend",this,false);if(this.debug){document.removeEventListener("mousemove",this,false);document.removeEventListener("mouseup",this,false)}},_init:function(){document.styleSheets[0].insertRule(".dhx_scroll_x { width:50px;height:4px;background:rgba(0, 0, 0, 0.4);position:absolute; left:0px; bottom:3px; border:1px solid transparent; -webkit-border-radius:4px;-webkit-transition: -webkit-transform;}",0);document.styleSheets[0].insertRule(".dhx_scroll_y { width:4px;height:50px;background:rgba(0, 0, 0, 0.4);position:absolute; top:0px; right:3px; border:1px solid transparent; -webkit-border-radius:4px;-webkit-transition: -webkit-transform;}",0);this._init=function(){}}};scheduler._ipad_before_init=function(){scheduler._ipad_before_init=function(){};scheduler.xy.scroll_width=0;var C=scheduler._els.dhx_cal_tab;var B=42;for(var A=C.length-1;A>=0;A--){C[A].style.cssText+="top:4px;";C[A].style.left="auto";C[A].style.right=B+"px";if(A==0){C[A].style.cssText+=";-webkit-border-top-left-radius: 5px; -webkit-border-bottom-left-radius: 5px;"}if(A==C.length-1){C[A].style.cssText+=";-webkit-border-top-right-radius: 5px; -webkit-border-bottom-right-radius: 5px;"}B+=100}scheduler._els.dhx_cal_prev_button[0].innerHTML="<";scheduler._els.dhx_cal_next_button[0].innerHTML=">";var F=document.createElement("div");F.className="dhx_cal_add_button";F.innerHTML="+ ";F.onclick=function(){var G=new Date();if(G>scheduler._min_date&&G50||G>50){D=window.clearTimeout(D)}}if(scheduler.config.touch_actions){scheduler._on_mouse_move(I.touches[0])}};this._obj.ontouchstart=function(G){if(scheduler._lightbox_id){return }D=window.setTimeout(function(){scheduler._on_dbl_click(G.touches[0],(G.target.className?G.target:G.target.parentNode))},400);E=[G.touches[0].pageX,G.touches[0].pageY];if(scheduler.config.touch_actions){scheduler._on_mouse_down(G.touches[0])}};this._obj.ontouchend=function(G){if(D){D=window.clearTimeout(D)}if(scheduler.config.touch_actions){scheduler._on_mouse_up(G.touches[0])}}};scheduler._ipad_init=function(){var C=document.createElement("DIV");var B=scheduler._els.dhx_cal_data[0];C.appendChild(B);C.style.cssText="overflow:hidden; width:100%; overflow:hidden;position:relative;";this._obj.appendChild(C);B.style.overflowY="hidden";var A=new TouchScroll(C);A.axisX=false;scheduler._ipad_init=function(){B.parentNode.style.height=B.style.height;B.parentNode.style.top=B.style.top;B.style.height=B.scrollHeight+"px";B.style.top="0px";if(Math.abs(B.parentNode.offsetHeight-B.offsetHeight)<5){A.axisY=false;A.scrollTo(0,0,0)}else{A.axisY=true}A.refresh()};scheduler.attachEvent("onSchedulerResize",function(){setTimeout(function(){scheduler._ipad_init()});return true});scheduler._ipad_init()};scheduler.attachEvent("onViewChange",function(){scheduler._ipad_init()});scheduler.attachEvent("onBeforeViewChange",function(){scheduler._ipad_before_init();return true});scheduler.showCover=function(B){this.show_cover();if(B){B.style.display="block";var C=getOffset(this._obj);B.style.top=B.offsetHeight*-1+"px";B.style.left=Math.round(C.left+(this._obj.offsetWidth-B.offsetWidth)/2)+"px"}var A=this._get_lightbox();A.style.webkitTransform="translate(0px,"+(B.offsetHeight+41)+"px)";A.style.webkitTransitionDuration="500ms"};scheduler.hideCover=function(A){if(A){A.style.webkitTransform="translate(0px,"+(A.offsetHeight+41)*-1+"px)";A.style.webkitTransitionDuration="500ms"}this.hide_cover()};scheduler.config.lightbox.sections[0].height=100;if(scheduler.form_blocks.calendar_time){scheduler.config.lightbox.sections[1].type="calendar_time";scheduler._mini_cal_arrows=["<",">"]}scheduler.xy.menu_width=0;scheduler.attachEvent("onClick",function(){return false});scheduler.locale.labels.new_event="";scheduler._mouse_coords=function(C){var F;var A=document.body;var E=document.documentElement;if(C.pageX||C.pageY){F={x:C.pageX,y:C.pageY}}else{F={x:C.clientX+(A.scrollLeft||E.scrollLeft||0)-A.clientLeft,y:C.clientY+(A.scrollTop||E.scrollTop||0)-A.clientTop}}F.x-=getAbsoluteLeft(this._obj)+(this._table_view?0:this.xy.scale_width);var D=F.y-=getAbsoluteTop(this._obj)+this.xy.nav_height+this._dy_shift+this.xy.scale_height-(this._els.dhx_cal_data[0]._scrollTop||0);if(!this._table_view){F.x=Math.max(0,Math.ceil(F.x/this._cols[0])-1);F.y=Math.max(0,Math.ceil(F.y*60/(this.config.time_step*this.config.hour_size_px))-1)+this.config.first_hour*(60/this.config.time_step)}else{var B=0;for(B=1;BF.y){break}}F.y=(Math.max(0,Math.ceil(F.x/this._cols[0])-1)+Math.max(0,B-1)*7)*24*60/this.config.time_step;F.x=0}return F}; \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +TouchScroll=function(a,b,c,e){this.debug=!!b;this.compat=!!e;this.rough=!!c;this.axisX=this.axisY=!0;typeof a!="object"&&(a=document.getElementById(a));this._init();a.addEventListener("touchstart",this,!1);a.addEventListener("webkitTransitionEnd",this,!1);this.debug&&a.addEventListener("mousedown",this,!1);this.node=a;for(var d=0;d50)this.scroll_x=!0;if(Math.abs(e)>50)this.scroll_y=!0;if(this.scroll_x|| +this.scroll_y){this.x=b.pageX;this.y=b.pageY;this.scroll=!0;var d=this.get_matrix();c+=this.target_x-d.e;e+=this.target_y-d.f;var f="2000ms",g="500ms";this.target_x=c+d.e;this.target_y=e+d.f;if(this.target_x>0)this.target_x=0,f=g;if(this.target_y>0)this.target_y=0,f=g;if(this.mx-this.dx+this.target_x<0)this.target_x=-this.mx+this.dx,f=g;if(this.my-this.dy+this.target_y<0)this.target_y=-this.my+this.dy,f=g;this.set_matrix({e:this.target_x,f:this.target_y},f);this._add_scroll(d.e,d.f);this._correct_scroll(this.target_x, +this.target_y,f);this.onscroll(this.target_x,this.target_y)}return!1}}},_correct_scroll:function(a,b,c){if(this.scrolls.x){var e=this.get_matrix(this.scrolls.x),d=this.dx*a/this.mx;this.set_matrix({e:-1*d,f:0},c,this.scrolls.x)}if(this.scrolls.y){var e=this.get_matrix(this.scrolls.y),f=this.dy*b/this.my;this.set_matrix({e:0,f:-1*f},c,this.scrolls.y)}},_remove_scroll:function(){this.scrolls.x&&this.scrolls.x.parentNode.removeChild(this.scrolls.x);this.scrolls.y&&this.scrolls.y.parentNode.removeChild(this.scrolls.y); +this.scrolls={}},_add_scroll:function(){if(!this.scrolls.ready){var a;if(this.my>5&&this.axisY){var b=this.dy*this.dy/this.my-1;this.scrolls.y=a=document.createElement("DIV");a.className="dhx_scroll_y";a.style.height=b+"px";this.node.appendChild(a)}if(this.mx>5&&this.axisX)b=this.dx*this.dx/this.mx,this.scrolls.x=a=document.createElement("DIV"),a.className="dhx_scroll_x",a.style.width=b+"px",this.node.appendChild(a);var c=this.get_matrix();this._correct_scroll(c.e,c.f,0);this.scrolls.ready=!0}},_init_events:function(){document.addEventListener("touchmove", +this,!1);document.addEventListener("touchend",this,!1);this.debug&&(document.addEventListener("mousemove",this,!1),document.addEventListener("mouseup",this,!1))},_deinit_events:function(){document.removeEventListener("touchmove",this,!1);document.removeEventListener("touchend",this,!1);this.debug&&(document.removeEventListener("mousemove",this,!1),document.removeEventListener("mouseup",this,!1))},_init:function(){document.styleSheets[0].insertRule(".dhx_scroll_x { width:50px;height:4px;background:rgba(0, 0, 0, 0.4);position:absolute; left:0px; bottom:3px; border:1px solid transparent; -webkit-border-radius:4px;-webkit-transition: -webkit-transform;}", +0);document.styleSheets[0].insertRule(".dhx_scroll_y { width:4px;height:50px;background:rgba(0, 0, 0, 0.4);position:absolute; top:0px; right:3px; border:1px solid transparent; -webkit-border-radius:4px;-webkit-transition: -webkit-transform;}",0);this._init=function(){}}}; +scheduler._ipad_before_init=function(){scheduler._ipad_before_init=function(){};scheduler.xy.scroll_width=0;for(var a=scheduler._els.dhx_cal_tab,b=42,c=a.length-1;c>=0;c--)a[c].style.cssText+="top:4px;",a[c].style.left="auto",a[c].style.right=b+"px",c==0&&(a[c].style.cssText+=";-webkit-border-top-left-radius: 5px; -webkit-border-bottom-left-radius: 5px;"),c==a.length-1&&(a[c].style.cssText+=";-webkit-border-top-right-radius: 5px; -webkit-border-bottom-right-radius: 5px;"),b+=100;scheduler._els.dhx_cal_prev_button[0].innerHTML= +"<";scheduler._els.dhx_cal_next_button[0].innerHTML=">";var e=document.createElement("div");e.className="dhx_cal_add_button";e.innerHTML="+ ";e.onclick=function(){var a=new Date;a>scheduler._min_date&&a50||c>50)d=window.clearTimeout(d)}scheduler.config.touch_actions&&scheduler._on_mouse_move(a.touches[0])};this._obj.ontouchstart=function(a){scheduler._lightbox_id||(d=window.setTimeout(function(){scheduler._on_dbl_click(a.touches[0],a.target.className?a.target:a.target.parentNode)},400),f=[a.touches[0].pageX,a.touches[0].pageY],scheduler.config.touch_actions&&scheduler._on_mouse_down(a.touches[0]))};this._obj.ontouchend=function(a){d&&(d=window.clearTimeout(d)); +scheduler.config.touch_actions&&scheduler._on_mouse_up(a.touches[0])}}; +scheduler._ipad_init=function(){var a=document.createElement("DIV"),b=scheduler._els.dhx_cal_data[0];a.appendChild(b);a.style.cssText="overflow:hidden; width:100%; overflow:hidden;position:relative;";this._obj.appendChild(a);b.style.overflowY="hidden";var c=new TouchScroll(a);c.axisX=!1;scheduler._ipad_init=function(){b.parentNode.style.height=b.style.height;b.parentNode.style.top=b.style.top;b.style.height=b.scrollHeight+"px";b.style.top="0px";Math.abs(b.parentNode.offsetHeight-b.offsetHeight)<5? +(c.axisY=!1,c.scrollTo(0,0,0)):c.axisY=!0;c.refresh()};scheduler.attachEvent("onSchedulerResize",function(){setTimeout(function(){scheduler._ipad_init()});return!0});scheduler._ipad_init()};scheduler.attachEvent("onViewChange",function(){scheduler._ipad_init()});scheduler.attachEvent("onBeforeViewChange",function(){scheduler._ipad_before_init();return!0}); +scheduler.showCover=function(a){this.show_cover();if(a){a.style.display="block";var b=getOffset(this._obj);a.style.top=a.offsetHeight*-1+"px";a.style.left=Math.round(b.left+(this._obj.offsetWidth-a.offsetWidth)/2)+"px"}var c=this._get_lightbox(),e=c.addEventListener("webkitTransitionEnd",function(){c.style.top="41px";c.style.webkitTransform="";c.style.webkitTransition="";c.removeEventListener(e)},!1);c.style.webkitTransform="translate(0px,"+(a.offsetHeight+41)+"px)";c.style.webkitTransitionDuration= +"500ms"};scheduler.hideCover=function(a){if(a){var b=a.addEventListener("webkitTransitionEnd",function(){a.style.top=(a.offsetHeight+41)*-1+"px";a.style.webkitTransform="";a.style.webkitTransition="";a.removeEventListener(b)},!1);a.style.webkitTransform="translate(0px,"+(a.offsetHeight+41)*-1+"px)";a.style.webkitTransitionDuration="500ms"}this.hide_cover()};scheduler.config.lightbox.sections[0].height=100; +if(scheduler.form_blocks.calendar_time)scheduler.config.lightbox.sections[1].type="calendar_time",scheduler._mini_cal_arrows=["<",">"];scheduler.xy.menu_width=0;scheduler.attachEvent("onClick",function(){return!1});scheduler.locale.labels.new_event=""; +scheduler._mouse_coords=function(a){var b,c=document.body,e=document.documentElement;b=a.pageX||a.pageY?{x:a.pageX,y:a.pageY}:{x:a.clientX+(c.scrollLeft||e.scrollLeft||0)-c.clientLeft,y:a.clientY+(c.scrollTop||e.scrollTop||0)-c.clientTop};b.x-=getAbsoluteLeft(this._obj)+(this._table_view?0:this.xy.scale_width);var d=b.y-=getAbsoluteTop(this._obj)+this.xy.nav_height+this._dy_shift+this.xy.scale_height-(this._els.dhx_cal_data[0]._scrollTop||0);if(this._table_view){for(var f=0,f=1;f +b.y)break;b.y=(Math.max(0,Math.ceil(b.x/this._cols[0])-1)+Math.max(0,f-1)*7)*1440/this.config.time_step;b.x=0}else b.x=Math.max(0,Math.ceil(b.x/this._cols[0])-1),b.y=Math.max(0,Math.ceil(b.y*60/(this.config.time_step*this.config.hour_size_px))-1)+this.config.first_hour*(60/this.config.time_step);return b}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_treetimeline.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_treetimeline.js index ecd08cc8cdd..c131cb1eb13 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_treetimeline.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_treetimeline.js @@ -1 +1,19 @@ -scheduler.attachEvent("onTimelineCreated",function(A){if(A.render=="tree"){A.y_unit_original=A.y_unit;A.y_unit=scheduler._getArrayToDisplay(A.y_unit_original);scheduler.form_blocks[A.name]={render:function(C){var B="
";return B},set_value:function(D,I,G,C){var J=scheduler._getArrayForSelect(scheduler.matrix[C.type].y_unit_original,C.type);D.innerHTML="";var F=document.createElement("select");D.appendChild(F);var H=D.getElementsByTagName("select")[0];for(var E=0;E";G=(H.folder_events_available)?"dhx_data_table folder_events":"dhx_data_table folder"}else{I=H.dy;D="dhx_row_item";B="dhx_matrix_scell item";C="";G="dhx_data_table"}td_content="
"+C+"
"+(scheduler.templates[H.name+"_scale_label"](E.key,E.label,H)||E.label)+"
";F={height:I,style_height:A,tr_className:D,td_className:B,td_content:td_content,table_className:G}}return F});var section_id_before;scheduler.attachEvent("onBeforeEventChanged",function(D,A,C){if(scheduler._isRender("tree")){var B=scheduler.getSection(D.section_id);if(typeof B.children!="undefined"&&!scheduler.matrix[scheduler._mode].folder_events_available){if(!C){D[scheduler.matrix[scheduler._mode].y_property]=section_id_before}return false}}return true});scheduler.attachEvent("onBeforeDrag",function(D,E,C){var A=scheduler._locate_cell_timeline(C);if(A){var B=scheduler.matrix[scheduler._mode].y_unit[A.y].key;if(typeof scheduler.matrix[scheduler._mode].y_unit[A.y].children!="undefined"&&!scheduler.matrix[scheduler._mode].folder_events_available){return false}}if(scheduler._isRender("tree")){ev=scheduler.getEvent(D);section_id_before=B||ev[scheduler.matrix[scheduler._mode].y_property]}return true});scheduler._getArrayToDisplay=function(C){var A=[];var B=function(G,D){var F=D||0;for(var E=0;E";return c},set_value:function(b,c,g,e){var d=scheduler._getArrayForSelect(scheduler.matrix[e.type].y_unit_original, +e.type);b.innerHTML="";var a=document.createElement("select");b.appendChild(a);for(var i=b.getElementsByTagName("select")[0],j=0;j",h=c.folder_events_available?"dhx_data_table folder_events":"dhx_data_table folder"):(e=c.dy,d="dhx_row_item",i="dhx_matrix_scell item",j="",h="dhx_data_table");td_content="
"+j+"
"+(scheduler.templates[c.name+"_scale_label"](b.key,b.label,b)||b.label)+"
";g={height:e,style_height:f,tr_className:d,td_className:i,td_content:td_content,table_className:h}}return g});var section_id_before; +scheduler.attachEvent("onBeforeEventChanged",function(a,b,c){if(scheduler._isRender("tree")){var g=scheduler.getSection(a[scheduler.matrix[scheduler._mode].y_property]);if(typeof g.children!="undefined"&&!scheduler.matrix[scheduler._mode].folder_events_available)return c||(a[scheduler.matrix[scheduler._mode].y_property]=section_id_before),!1}return!0}); +scheduler.attachEvent("onBeforeDrag",function(a,b,c){var g=scheduler._locate_cell_timeline(c);if(g){var e=scheduler.matrix[scheduler._mode].y_unit[g.y].key;if(typeof scheduler.matrix[scheduler._mode].y_unit[g.y].children!="undefined"&&!scheduler.matrix[scheduler._mode].folder_events_available)return!1}scheduler._isRender("tree")&&(ev=scheduler.getEvent(a),section_id_before=e||ev[scheduler.matrix[scheduler._mode].y_property]);return!0}); +scheduler._getArrayToDisplay=function(a){var b=[],c=function(a,e){for(var d=e||0,f=0;f"+D[F].label+""}else{return D[F].label}};scheduler.date["add_"+A]=function(F,G){return scheduler.date.add(F,G,"day")};scheduler.date["get_"+A+"_end"]=function(F){return scheduler.date.add(F,B||D.length,"day")};scheduler._props[A]={map_to:E,options:D,size:B,step:C,position:0};scheduler.attachEvent("onOptionsLoad",function(){var F=scheduler._props[A].order={};for(var G=0;G=K.size+K.position){return false}}}return H};scheduler._reset_scale=function(){var M=scheduler._props[this._mode];var H=B.apply(this,arguments);if(M){this._max_date=this.date.add(this._min_date,1,"day");var L=this._els.dhx_cal_data[0].childNodes;for(var I=0;II.order[J[I.map_to]]?1:-1})}else{G.apply(this,arguments)}};scheduler.attachEvent("onEventAdded",function(K,I){if(this._loading){return true}for(var H in scheduler._props){var J=scheduler._props[H];if(typeof I[J.map_to]=="undefined"){I[J.map_to]=J.options[0].key}}return true});scheduler.attachEvent("onEventCreated",function(K,H){var J=scheduler._props[this._mode];if(J){var I=this.getEvent(K);this._mouse_coords(H);D(J,I);this.event_updated(I)}return true})})(); \ No newline at end of file +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler._props={}; +scheduler.createUnitsView=function(a,f,j,g,k,l){if(typeof a=="object")j=a.list,f=a.property,g=a.size||0,k=a.step||1,l=a.skip_incorrect,a=a.name;scheduler._props[a]={map_to:f,options:j,step:k,position:0};if(g>scheduler._props[a].options.length)scheduler._props[a]._original_size=g,g=0;scheduler._props[a].size=g;scheduler._props[a].skip_incorrect=l||!1;scheduler.date[a+"_start"]=scheduler.date.day_start;scheduler.templates[a+"_date"]=function(a){return scheduler.templates.day_date(a)};scheduler.templates[a+ +"_scale_date"]=function(c){var h=scheduler._props[a].options;if(!h.length)return"";var f=(scheduler._props[a].position||0)+Math.floor((scheduler._correct_shift(c.valueOf(),1)-scheduler._min_date.valueOf())/864E5);return h[f].css?""+h[f].label+"":h[f].label};scheduler.date["add_"+a]=function(a,f){return scheduler.date.add(a,f,"day")};scheduler.date["get_"+a+"_end"]=function(c){return scheduler.date.add(c,scheduler._props[a].size||scheduler._props[a].options.length, +"day")};scheduler.attachEvent("onOptionsLoad",function(){for(var c=scheduler._props[a],f=c.order={},g=c.options,i=0;ig.length?(c._original_size=c.size,c.size=0):c.size=c._original_size||c.size;scheduler._date&&scheduler._mode==a&&scheduler.setCurrentView(scheduler._date,scheduler._mode)});scheduler.callEvent("onOptionsLoad",[])}; +scheduler.scrollUnit=function(a){var f=scheduler._props[this._mode];if(f)f.position=Math.min(Math.max(0,f.position+a),f.options.length-f.size),this.update_view()}; +(function(){var a=function(b){var d=scheduler._props[scheduler._mode];if(d&&d.order&&d.skip_incorrect){for(var a=[],e=0;e=a.size+a.position)return!1}}return d};scheduler._reset_scale=function(){var b= +scheduler._props[this._mode],a=k.apply(this,arguments);if(b){this._max_date=this.date.add(this._min_date,1,"day");for(var c=this._els.dhx_cal_data[0].childNodes,e=0;ed.order[b[d.map_to]]?1:-1}):i.apply(this,arguments)};scheduler.attachEvent("onEventAdded",function(a,d){if(this._loading)return!0;for(var c in scheduler._props){var e=scheduler._props[c];if(typeof d[e.map_to]=="undefined")d[e.map_to]=e.options[0].key}return!0});scheduler.attachEvent("onEventCreated",function(a,c){var f=scheduler._props[this._mode]; +if(f){var e=this.getEvent(a);this._mouse_coords(c);g(f,e);this.event_updated(e)}return!0})})(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_url.js b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_url.js index 8992c37f373..bb342e484e0 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_url.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/ext/dhtmlxscheduler_url.js @@ -1,9 +1,6 @@ -/* -dhtmlxScheduler v.2.3 - +/* This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - -(c) DHTMLX Ltd. -*/ -scheduler.attachEvent("onTemplatesReady",function(){var C=true;var A=scheduler.date.str_to_date("%Y-%m-%d");var B=scheduler.date.date_to_str("%Y-%m-%d");scheduler.attachEvent("onBeforeViewChange",function(K,D,F,J){if(C){C=false;var E={};var G=(document.location.hash||"").replace("#","").split(",");for(var H=0;H";for(var h=0;h
"}b+=""}scheduler._els.dhx_cal_date[0].innerHTML=scheduler.templates[scheduler._mode+ +"_date"](scheduler._min_date,scheduler._max_date,scheduler._mode);scheduler._els.dhx_cal_data[0].innerHTML=b;for(var i=scheduler._els.dhx_cal_data[0].getElementsByTagName("div"),l=[],a=0;aj&&o.push(r)}o.sort(function(a,b){return a.start_date.valueOf()==b.start_date.valueOf()?a.id>b.id?1:-1:a.start_date>b.start_date?1:-1});for(h=0;h=j.valueOf()&&d.start_date.valueOf()<=n.valueOf()&&(p="start"),d.end_date.valueOf()>=j.valueOf()&&d.end_date.valueOf()<=n.valueOf()&&(p="end"));g.innerHTML=scheduler.templates.week_agenda_event_text(d.start_date,d.end_date,d,j,p);g.setAttribute("event_id",d.id);t.appendChild(g)}j=scheduler.date.add(j,1,"day");n=scheduler.date.add(n,1,"day")}};scheduler.week_agenda_view= +function(b){scheduler._min_date=scheduler.date.week_start(scheduler._date);scheduler._max_date=scheduler.date.add(scheduler._min_date,1,"week");scheduler.set_sizes();if(b)scheduler._table_view=!0,scheduler._wa._prev_data_border=scheduler._els.dhx_cal_data[0].style.borderTop,scheduler._els.dhx_cal_data[0].style.borderTop=0,scheduler._els.dhx_cal_data[0].style.overflowY="hidden",scheduler._els.dhx_cal_date[0].innerHTML="",scheduler._els.dhx_cal_data[0].style.top=parseInt(scheduler._els.dhx_cal_data[0].style.top)- +scheduler.xy.bar_height-1+"px",scheduler._els.dhx_cal_data[0].style.height=parseInt(scheduler._els.dhx_cal_data[0].style.height)+scheduler.xy.bar_height+1+"px",scheduler._els.dhx_cal_header[0].style.display="none",e(),f();else{scheduler._table_view=!1;if(scheduler._wa._prev_data_border)scheduler._els.dhx_cal_data[0].style.borderTop=scheduler._wa._prev_data_border;scheduler._els.dhx_cal_data[0].style.overflowY="auto";scheduler._els.dhx_cal_data[0].style.top=parseInt(scheduler._els.dhx_cal_data[0].style.top)+ +scheduler.xy.bar_height+"px";scheduler._els.dhx_cal_data[0].style.height=parseInt(scheduler._els.dhx_cal_data[0].style.height)-scheduler.xy.bar_height+"px";scheduler._els.dhx_cal_header[0].style.display="block"}};scheduler.mouse_week_agenda=function(b){for(var a=b.ev,c=a.srcElement||a.target;c.parentNode;){if(c._date)var e=c._date;c=c.parentNode}if(!e)return b;b.x=0;var h=e.valueOf()-scheduler._min_date.valueOf();b.y=Math.ceil(h/6E4/this.config.time_step);if(this._drag_mode=="move"){this._drag_event._dhx_changed= +!0;this._select_id=this._drag_id;for(var k=0;k";K+="
"+(H[J]._timed?this.templates.event_date(H[J].start_date):"")+"
";K+="
 
";K+=this.templates.year_tooltip(H[J].start_date,H[J].end_date,H[J])+""}this._tooltip.style.display="";this._tooltip.style.top="0px";if(document.body.offsetWidth-O.left-this._tooltip.offsetWidth<0){this._tooltip.style.left=O.left-this._tooltip.offsetWidth+"px"}else{this._tooltip.style.left=O.left+N.offsetWidth+"px"}this._tooltip.date=I;this._tooltip.innerHTML=K;if(document.body.offsetHeight-O.top-this._tooltip.offsetHeight<0){this._tooltip.style.top=O.top-this._tooltip.offsetHeight+N.offsetHeight+"px"}else{this._tooltip.style.top=O.top+"px"}};scheduler._init_year_tooltip=function(){dhtmlxEvent(scheduler._els.dhx_cal_data[0],"mouseover",function(H){if(!F()){return }var H=H||event;var I=H.target||H.srcElement;if((I.className||"").indexOf("dhx_year_event")!=-1){scheduler.showToolTip(E(I.getAttribute("date")),getOffset(I),H,I)}else{scheduler.hideToolTip()}});this._init_year_tooltip=function(){}};scheduler.attachEvent("onSchedulerResize",function(){if(F()){this.year_view(true);return false}return true});scheduler._get_year_cell=function(J){var H=J.getMonth()+12*(J.getFullYear()-this._min_date.getFullYear())-this.week_starts._month;var I=this._els.dhx_cal_data[0].childNodes[H];var J=this.week_starts[H]+J.getDate()-1;return I.childNodes[2].firstChild.rows[Math.floor(J/7)].cells[J%7].firstChild};var D=[];scheduler._mark_year_date=function(I,H){var J=this._get_year_cell(I);J.className="dhx_month_head dhx_year_event "+this.templates.event_class(H.start_date,H.end_date,H);J.setAttribute("date",G(I));D.push(J)};scheduler._unmark_year_date=function(H){this._get_year_cell(H).className="dhx_month_head"};scheduler._year_render_event=function(H){var I=H.start_date;if(I.valueOf()=this._max_date.valueOf()){return }}};scheduler.year_view=function(I){if(I){var H=scheduler.xy.scale_height;scheduler.xy.scale_height=-1}scheduler._els.dhx_cal_header[0].style.display=I?"none":"";scheduler.set_sizes();if(I){scheduler.xy.scale_height=H}scheduler._table_view=I;if(this._load_mode&&this._load()){return }if(I){scheduler._init_year_tooltip();scheduler._reset_year_scale();scheduler.render_view_data()}else{scheduler.hideToolTip()}};scheduler._reset_year_scale=function(){this._cols=[];this._colsS={};var T=[];var Z=this._els.dhx_cal_data[0];var X=this.config;Z.scrollTop=0;Z.innerHTML="";var M=Math.floor(parseInt(Z.style.width)/X.year_x);var L=Math.floor((parseInt(Z.style.height)-scheduler.xy.year_top)/X.year_y);if(L<190){L=190;M=Math.floor((parseInt(Z.style.width)-scheduler.xy.scroll_width)/X.year_x)}var Q=M-11;var I=0;var K=document.createElement("div");var a=this.date.week_start(new Date());for(var V=0;V<7;V++){this._cols[V]=Math.floor(Q/(7-V));this._render_x_header(V,I,a,K);a=this.date.add(a,1,"day");Q-=this._cols[V];I+=this._cols[V]}K.lastChild.className+=" dhx_scale_bar_last";var H=this.date[this._mode+"_start"](this.date.copy(this._date));var R=H;for(var V=0;V
"+K.innerHTML+"
";W.childNodes[0].innerHTML=this.templates.year_month(H);var Y=this.date.week_start(H);var J=this._reset_month_scale(W.childNodes[2],H,Y);var P=W.childNodes[2].firstChild.rows;for(var S=P.length;S<6;S++){P[0].parentNode.appendChild(P[0].cloneNode(true));for(var O=0;O";l+="
"+(h[f]._timed?this.templates.event_date(h[f].start_date):"")+"
";l+="
 
";l+=this.templates.year_tooltip(h[f].start_date,h[f].end_date,h[f])+""}this._tooltip.style.display= +"";this._tooltip.style.top="0px";this._tooltip.style.left=document.body.offsetWidth-b.left-this._tooltip.offsetWidth<0?b.left-this._tooltip.offsetWidth+"px":b.left+c.offsetWidth+"px";this._tooltip.date=a;this._tooltip.innerHTML=l;this._tooltip.style.top=document.body.offsetHeight-b.top-this._tooltip.offsetHeight<0?b.top-this._tooltip.offsetHeight+c.offsetHeight+"px":b.top+"px"};scheduler._init_year_tooltip=function(){dhtmlxEvent(scheduler._els.dhx_cal_data[0],"mouseover",function(a){if(c()){var a= +a||event,b=a.target||a.srcElement;if(b.tagName.toLowerCase()=="a")b=b.parentNode;(b.className||"").indexOf("dhx_year_event")!=-1?scheduler.showToolTip(w(b.getAttribute("date")),getOffset(b),a,b):scheduler.hideToolTip()}});this._init_year_tooltip=function(){}};scheduler.attachEvent("onSchedulerResize",function(){return c()?(this.year_view(!0),!1):!0});scheduler._get_year_cell=function(a){var b=a.getMonth()+12*(a.getFullYear()-this._min_date.getFullYear())-this.week_starts._month,d=this._els.dhx_cal_data[0].childNodes[b], +a=this.week_starts[b]+a.getDate()-1;return d.childNodes[2].firstChild.rows[Math.floor(a/7)].cells[a%7].firstChild};var j=[];scheduler._mark_year_date=function(a,b){var d=this._get_year_cell(a);d.className="dhx_month_head dhx_year_event "+this.templates.event_class(b.start_date,b.end_date,b);d.setAttribute("date",v(a));j.push(d)};scheduler._unmark_year_date=function(a){this._get_year_cell(a).className="dhx_month_head"};scheduler._year_render_event=function(a){for(var b=a.start_date,b=b.valueOf()=this._max_date.valueOf())break};scheduler.year_view=function(a){if(a){var b=scheduler.xy.scale_height;scheduler.xy.scale_height=-1}scheduler._els.dhx_cal_header[0].style.display=a?"none":"";scheduler.set_sizes();if(a)scheduler.xy.scale_height=b;scheduler._table_view=a;if(!this._load_mode||!this._load())a?(scheduler._init_year_tooltip(),scheduler._reset_year_scale(),scheduler.render_view_data()): +scheduler.hideToolTip()};scheduler._reset_year_scale=function(){this._cols=[];this._colsS={};var a=[],b=this._els.dhx_cal_data[0],d=this.config;b.scrollTop=0;b.innerHTML="";var c=Math.floor(parseInt(b.style.width)/d.year_x),k=Math.floor((parseInt(b.style.height)-scheduler.xy.year_top)/d.year_y);k<190&&(k=190,c=Math.floor((parseInt(b.style.width)-scheduler.xy.scroll_width)/d.year_x));for(var h=c-11,l=0,f=document.createElement("div"),m=this.date.week_start(new Date),e=0;e<7;e++)this._cols[e]=Math.floor(h/ +(7-e)),this._render_x_header(e,l,m,f),m=this.date.add(m,1,"day"),h-=this._cols[e],l+=this._cols[e];f.lastChild.className+=" dhx_scale_bar_last";for(var g=this.date[this._mode+"_start"](this.date.copy(this._date)),j=g,e=0;e
"+f.innerHTML+"
"; +i.childNodes[0].innerHTML=this.templates.year_month(g);for(var p=this.date.week_start(g),t=this._reset_month_scale(i.childNodes[2],g,p),n=i.childNodes[2].firstChild.rows,q=n.length;q<6;q++){n[0].parentNode.appendChild(n[0].cloneNode(!0));for(var s=0;sY#!2~4#WHWmMDajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MPZ&Ujv*Ddl59%8@-s`w+}?lZlwr|_$pY7nnC|wTk^jT+ zD9Wv(f?xLlOUb_p#U>ZdE`De$bq^Y#!2~4#WHWmMDb50q$YKTtZeb8+WSBKaf`Nfi z!PCVtq~g}wu!CNQ9RzCggFB`yyW#yZUF4T;o#X$b@t>AytoXugQ~5O|lY5y*&?Z^_ zOFMSo49&1n*-(6HcIE6nGv~5DJnYTd!ND+r;Rd$_!-D=SqdV#1OYPKDc4>yNbY7~Q z_|DF~Q;0QT*3-zSu&9Ym>)14>hArMQr`Mk0!`EEltS{DC7bKW7@A&<#X?i|6+v&mX z<+g^qnG}*Zx6k^ZDzhmz&$aC;YvcS+2aa>yox*+AXLFU=&65>hHNF_zd=_imdtc6p z!zw*`QoZEP#nC;fpXAKmI^DMYqrd6=bc5-;S6crvLV}<2&^>LliG7K>pl(rSzno3KoOa=R6OQ;>i`)H-Zq+|- rem;NCMy?*i15f`I>27?rBbrhEz?;bOtEaj?aro^_LoO#n0oLiZ?RyuPUpS?GqslgVeZo@nfDPL>Z59ly6Z$XQd?Wp%_+|rv zAin+&({_B_Y(4LETD{imw~SIs%Zs#+$MK)Oc_XY_)5OIud&1wMy*F!&Hls+*7R9w&bR`KG0FOwjF-VBE?4X&3fUtYA4 zZOCxh+_YJ5b5rp9hAQ(dF0b>sFK%4)^arb~S3yWRWAq}R%Naaf{an^LB{Ts5d(dK@ literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/but_repeat.gif b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/but_repeat.gif new file mode 100644 index 0000000000000000000000000000000000000000..dd6595e5d9ef43bd03c486ff87079f398267e085 GIT binary patch literal 1149 zcmZ?wbhEHblw#0e_|Cu(?klqTfBEyoYklCmVoqenVS|Pe!)>e59cFWsU9>AW zZP8U{yyh;8RlNr303RUE2#_d#_^)>0%x$Xs10t-?UO*$CP9jc$w;rijn>#HZ* ziuOA9HrlOUoN#1EY26vWko7W`kGGuIQyH^LXXo0ihgT<^dANV+jn?#K4u`fCUwwP* z-M5!ZXNH}5yl>s2_-m)ym(2>l`}us|%dq{M3y$q7@2KifR>Y}Mw6)3c8m-~M#w=7-a1 z2lYB02kd$=@8hpG|NsAI7zM*O1QdU=FfuSCFzA512+9-e9RC>(a>#gWSa7hJLs%<@ z!>y62jYpg%f??u==`spD872Y>4UJt1VGkBu+W4e}lTpRt$^pd#JWK}3LKB3T9*Ht> z{5N>MH5zv}sFyVmL)JDz@z9|n~A2ze=aoMTfc#?RCTa!a?fk(jUuvRNSo+m#7 zABgF&Eo)ezv2bzAcA+K}&I`<}M+6xCroGv*gqxjLp!QVD$^#6OloTdwc^t4{g{)f>K6CCawk>Cl{7Cw?#BK3K$BV zSs5kRIOOdXxUhBTvni|)Xl*QJN-QjLPzCavSUfPI0sfDy@jpkeH{?dy!N3 zhQbX7(}VJFMYr8B{IE5rQKCY`;NikW%s2R0UNrDKaC~s&6i8KY$lHF<>b{ktD z&gisyeO}}wWwu=IPQcysynfG5*AoY441ID30dRqYbB2hDj*oeU0SAKw43?OemjIca zmy8XQ2$l?`rlkO-{A0vp~mdytYTbG?msW^U zr#j6lvq09dT+^yuJJf1X0dM0fC;-4L+`9_kQoUzXuU`e6%*y?X_HW+7hz~0^%s6r5 zqF(Vz#(P-uVW*ZU-_3lP;(^MbIg1WWdbDW)xdf)NP2)85Uy zx9{J;VH*OpAUN;?ZyFFc{+kM-;>@E-IQ3E2UV#jV2dz}|K7IbH;;QNrz*VAWT z&%M2R_w3)xkI!-mk0eEOoX77&KNJ1{1{YYw5-_xof)G1|V4wyF7P#Pp5RRZj1OPka Cm_4ij literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/calendar.gif b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/calendar.gif new file mode 100644 index 0000000000000000000000000000000000000000..67257083540f7ea06881718da65d749f7284e165 GIT binary patch literal 622 zcmZ?wbhEHb6k-r!c*ek>prLT)%o*dfGgj$`HW)Az6cjY9_^@!{!iEJG{{Q%I;E^z4 z!G;SD{sW1G2@e`(9Qfam@FBrq!iozH0SOHY9(?%lzo28ogbn{4Djqzr5a{jgov`A= zh65M&@85s>_U->O8UiXVBt#?>EcoD1aG_wvg9k7EH#9UXSaD#%jt2)U1ZK{h8PM>c zVZn$0|NmdSa?Qab;lPOt4J-aPEI9Dt$A5={2S5dnpFCc$;lTAP*C%YaV3lz(dCI*9 z4g$qf)-Kp_;lhmv7j9e#Xtg?cw=gYN-LX^L zkc~}ezmnDRmHU*|uGiL?1^(|-fE8lblbd4od4L*O>-Nnixo_MTBMAhPt^YXsC%yN=J0u$6;9q86(1O;^YnlA`!OMrv9(1`BVyeag@*_CuyPgcJ8^Pz`Z*T|W<~~U06^u> AiU0rr literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/clock_big.gif b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/clock_big.gif new file mode 100644 index 0000000000000000000000000000000000000000..61f7dc2e5ac32fc064ffb4e231f344df03d07baf GIT binary patch literal 1321 zcmeH``!m}I0KmVIhu6+xXQh>06V%F?qh)EkZW3)hs&#ZarWvxNoo;QVXEiO_5K$#2 z#3Qb$#AB(~2ueM&NkRnmh*v}-2#b)=1sRIUu7ARQ-{<$wFQ2=Qf1ux~)A*ynQDB=1 z7>!1;SX|9t2@eksi-{YQYbGWpD%+Ooy0mdgS<1zCJfSY5{B?FQxA1qBY<91EWb?-a zY8rbwzjh9PJ6SZWBoGLOt+$f#1qQo*dVaraXydP?75Us=W`#mAuhFjQXBQ7zgwj7H zW17`X{rYA`ei^f}d1T@>wM?E_P*GGfRK%{yd9KW5)d%C^N}J`67;V{XQ8rguRaM1p z=*(bL)_3$%*i-#7jbe7Os&koL+aZu@cm^7wXN@X-Xe8PN?$>z29$mX=EIjrQ&;<*L&i(WN_EhjyG@vvlM zVrG|C$maLSMy7XEnzc#gZu(Qn+TR;gmL!W=PhrdQN*g*QvP4=#R@q>yX!J>8Wo_F) zgFwd@_T@dRlT5CZ)^lYoT|sVFFT;WtZ~AVk=f!jOFMXfDCf7J;?tQP z5%C`}U?5*ByZ}z^p*jFrIHdJ;4H9K?#)Xs)cZ{N1@4aZ2nl#MPhsy56Hr+^JoodF;gB)*blVN`(U9opG zg#^RL$q+kY!O!_tBK$bY7vcjlyJm!XVe*uEfFDFU_%yX* zBpYUP0@)s#hIx?ggB9V?0Qis;U5pAiJBn~N^+G`r2k&g>aq$78=Sj?4a6hoO*D{Cv z^`sPI*MctxtcXOw_a`=p`S@ET5d*XO*gT#5!C_1p3doCqUVxp5`J8S`X!C$rpo6I* zxI0Y+y%=3Z&#dh{Q3Xy-~T6X|NCUj z-+AKAj$^O4oc%v(-P4P=e*FLcf6~g^o6r1jUwo^5;nm*dx0CC)-F@*tt7XTEoe$67 z_;%s`|Hp6s*U!GR{=kbx`@T+Hb}p-J@5KlIx1IZ+(X#u*#rLa^|4XUcG-vJAQ(#*m&j9|EU{aOxyJG*p2@MJ%=AY`_F&_DE?$& zWMD97&;iMV{KUYv@WAW>4;`s~kH?3FUzRA%b1$-r3GorDP~irs!TK&W1KgS zYyNz(**XTyD^~EWWH!*5t)a)Vc?;hbJ&oC#61;5t_V44B(41|qt0=^I>a>ue?olUw ebzx;08D(L0{R_^j3Wi)SnAsUe&p%Yv$JM$_W8+`K+vL zQy1@KV`DF|zZPaRp-Va7Es`fWH{!n_taqfi)L%}l+!NRT_gf~c5vTfPAO=yP@zY`zB-u?Ry@*U>$I(GcT$y28*)fmoQIDhHFx$tYDF7dZ+ zoj;d(|GrD{K0OuZ-`~Uy| literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/controlls5.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/controlls5.png new file mode 100644 index 0000000000000000000000000000000000000000..24957208fdcb6ec0fdc02a6468100c686eb9ecf2 GIT binary patch literal 2835 zcmV+u3+(iXP)eI3b~U|9Lw@OaL0=-?F-$J$v?G>(;HhdOLUSWc=Euekkkj zGgZlDI8+qDuC{u3+`a+m3yDN;_(BX$^LuRIm$j6!GEEs)2Cme-LmKTkZ2s~N3k?kw zASsnfkq8{(bdQJt85|rGpb)1-_sYx5@#!1EHg`TPEsZTnOaS}q-w?ETj#;4c^Yd9| zW+oOaSU`ERJTWnm@@D&|x{}SDa=(UhsxzeN(*X~U;RhNG*u#eyZ0kaI+zRx*94|c% zfIcbyMC6af9g_@N5(&Jzy4og7qPi0Ws9Dp3te_wye0m)I@o$-|)7I8z)jKRH?~tF# z9Mk^=#q-ZY^ZoZ|K6w(Yw{MGQZv39-3opQZ)(kkFIReIpSl@!gNdu}>Q_6M}?!eNe zOL6w>S>w|k34Z@O5jMT#%{{p`)oaUrj&0a*7bu*K6Ir`)@7_K5r>C18Jhu!fH8quy zm5f-HNj`ciH0VJ+sA2Z$$Dj-dK>f9A(6sizC3zG4Ut1;WHGTMN=ER8Y~`kY;3Hsa0dqmoyAikWut!e z_V$WoN#CTaxsdD?Xs@kBd)E*=x9x+{*I)F-Ir}T-t>^|45>U8h3+60e4izs;b&#~y zWV>Hfe8IxJ!w}{bW^i0Lnr^U&_ELyi z@R;xb!Q)>J#gc{dME=LGMBpcJQKHV+hOGstun>s*puuXbB%t#0@(>Xbfph21AtWRO zIXO894-W@rPpyfZG#*XjY}oRg*l$UAAZC_`nbjyXC~dIX!#Z$?Q& z2^;&2?$I*>sI|3~8)zR+pFWLUKip*+q<${^o8M`mQUb-5^(d&QLw?zPaecn1Qt*t+ zr8tvUBJ%&vEfjUE0co-TB5N_kZK3``_JD?4UdXIzx@UA9 zJ%5hiu~GAM_Yz{FtO9AW0MgSm#l-jI{al!QzJbcw8O8u||IHsnKSdc{mg*?YwaevF zQ&WTFtk#lzyodJ& zln?Mz3m!5%;88h#9UT#_cWus+yubdKd9R;*fJR%AF^jSUL`7r_+OyN(>Ei|tDT^$thKR4U%zSs6)!>J93i;F{9S(yMw?1^}uC^t732a*mTQXMH-bap2; zseC*S8a0B~)YYT6{(xqZ^XgB+D}SwQ=NNd?H% znxwt9WID9}(d%gG89)zhTDcoe0L}f~BY+$V&ok%ad*M`9CCX4)s$-6#XGBW`LPkc0 zP~_{^uZu)^x<}8bjK#-7S{K}d@3M(cn>M^AQ9dBxktNYJc~8Wn_`ZR-x#{j8{d{nc zYf{vtThOGOkNF2ns^oWB?Y`|$a{)$?S9q%cP9ML?Ml_hF3v_UR>i9-i_3jQ)$C9=Q zgwI!e&eon-D=bQDK}UXZ#4JGLK#G{9#ILp=f~&I%Q(c_k<~p2Qom6mC*$*FN_VSK) z_oB6ve(fQrQix>4avZFV%Jv}`l z9}^Q}(Yc*&jjgI+otY=motJ^WiW|d6Mj>Hvid_Pi#Gk=FFyw!Fx-Q9IW}kkNKl;fa z$s~g$gCvs-l1!HG;hvR&$bl$wAc`D_LL>*G$bl$wAPSKjh+;d*fhckyiX4byj%*1; zIhAxuG6|9#i1K6uQPNkWn~rgi15uuAAj*X`7tF^v$bl$NE)XUE?R?3i&Fqs1MBxHv zBxG$Os~Fh=NY+}?(-??C!jJrCBr_F=Qnay1vgquNBhDroh(c``d(qfHlsT)5$kbUa z_onLjfGN@3+|tq_zNqr{m`Tka_1uy`6jBCL?K!Ray<{j5Mft{WX;Ei}0#T@rB}zmf z7z;!(2auj6k#{lCK$Pa@X83ST9827_WTOL7YSsV1J>EfgiXm`y#gr*ibX<}oOQsOk z(a~YmT14(Gw*aP8DviFthh#8v$|LE4L|Qk|KoqT?KbALit;cB!ljA3T9$ zYLF%z1x6FMcWVKx_tLPUEJnhmttX~;6EE#f2xYJc(B&-4OOG85Ke=FFKwvB>JD z^1TvqE>y|bluY1LAKKg7g`yB(Bu_UtHz5ZCWb|37c1<2F7ad46aP2u9B?3UV8y^8@ z^tIkba0EDdp*0KsM2M7%)-wX0-aod_x)W_aa8d}eA}$o8!XyujKq46sCxGdmaK}g7 zavGynfRsqvN&78PGOdH8wR}U$V)Qgbjuv|QN&Ye`gCx^q1&O|rdS@SEvWT8M8C;Xh zeI>nGrD4q-edFqRx;h{_(8K1kGFfmeqyuP4BHxE-jD960p~pr3U|eIlMYqQ9XL#9H zBgU6KSA0vBzAe+;@K@4A1UAn`R#ukDucSQ#3e0d<>TzSlBnA9DlzLny8!XA%ucW;L zK-mL^+1`@iy(SL9X%|u3%HZoJ2`-ZjmP9Ai)_y`DQ0DqbD8A1GHwBU%e+vOr-#!eK zooqGrPwWzF2 lR=D6Y$tMmnSxNsDU;ytXnYZ<(0)+qo002ovPDHLkV1l_%QG@^h literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg.png new file mode 100644 index 0000000000000000000000000000000000000000..f0ffbdabc108e650383ef3df89eacc043db5d9b8 GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf#$P6SsHY~OWQfvV}A+B%Uefj_Yf7JdxSwIm! mPZ!4!j+x0B2?}CDybM!6aWy6%oWKf{VeoYIb6Mw<&;$Uo3K%*7 literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg_now.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/databg_now.png new file mode 100644 index 0000000000000000000000000000000000000000..9f371b4df716915175019c9422df7c12c27f64ba GIT binary patch literal 89 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf#$P6SsHY~OWQfvV}A+C3xefj_Yf8N#)Y(Nn{ mPZ!4!j+x0B2?}CDybM!6aWy6%oWKf{VeoYIb6Mw<&;$UeBp3Vu literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/event-bg.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/event-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..a3bae3e018613bfa0c160ea6a36723d641e3a415 GIT binary patch literal 148 zcmeAS@N?(olHy`uVBq!ia0vp^j371(GmxD1Q}Q5?(hcwlasB`Q|B`)I{(pP)|LfiV zpKt#Ebmjkt3;*Ar{{Qy)|2K#JzuNo%<<9@lxBP#$;s2A>$=A-j2WnLEba4#fn3)`q yV31Idz>(mQpplS~Fyp|6hD7GWjBVUJ{0z3Y*cxAN?N9-#X7F_Nb6Mw<&;$TzL__TW literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/icon.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..31d6626cdd40848c6d900eeb8e8d4057f6dfd553 GIT binary patch literal 230 zcmVsi?L4DSwy6=Gyw9+ zFovGaHzsTy&(`(mA|C-TpGSSX^ClSheK+Y%@EY4KGI}?S^dBdHlI7}ny*~iZxu7XL g^hQK^3Fvj(FC=_u*5-+h;{X5v07*qoM6N<$f}pKl{{R30 literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/left-separator.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/left-separator.png new file mode 100644 index 0000000000000000000000000000000000000000..22d630927f32a8d4c66b4cbb851f20002aad0e9c GIT binary patch literal 230 zcmeAS@N?(olHy`uVBq!ia0vp^#z4%(!2~3$o)(t^DajJoh?3y^w370~qErUQl>DSr z1<%~X^wgl##FWaylc_d9MID|ljv*DdZ2WHv9#-I)EPr>QcFBix7yH*t@Vh9Pq$SxT zu<3%V-R-{5>$oF!%xaa|x+_&9hR3^f$)(@tYA>xRzwqPwv(VfP!nqvDPIKS5)_mcq ep0}TYnc VW}y=sH5X_cgQu&X%Q~loCII&SCFTGC literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/lightbox.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/lightbox.png new file mode 100644 index 0000000000000000000000000000000000000000..f0314fa609946421251eeafe1bd88b61216e671d GIT binary patch literal 207 zcmeAS@N?(olHy`uVBq!ia0vp^j6f{S!3-q3+C<%eR8)XZi0hJlSN;RRw?{v|y!`n2 z!>f?N^}pM%{@r@@@5al2*I)d*`uyLO=l?E0`*-o_ zzY9v zum3Ng%&d+z7H&;jaY@O1TaS?83{1OTQT Bb#(v$ literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/loading.gif b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/loading.gif new file mode 100644 index 0000000000000000000000000000000000000000..f5e71df6aa432e63b71dc708a929027822689ba0 GIT binary patch literal 3951 zcmc(iXH*l|w#Oqe7GM&`C^Co&I;dm2%rFjeMX#u+IM_x-utcd!QIMgFv=BOkE;T^t z1VTwjC8Sq+Cxiq-3rH_g6&}u7_rt7r%Y1q3?N4W&bOz5mxuuAMWm3;;j? za{$1`W{CCHKeepSG1muPZmt1;g!YEYZQ}>`uNd7m{^^V^aLeYV_PWLuS6fRrTN^D; zd$(6wmJXI)PR^D#XYAkDIRms;w(eBkJay{p^{d4ahOC7h>j}W4MdA!TRX4TF37~VV5toY{8&jyL>s7Khd zXWlB|uVA z!Ra58vf^`+(^7I{3o`)esQhd!x*{*LpsI*aQid<5R?={o(i$e4!l~smcy-luVk5ah z$SUq2bvAdmwQyVOSt8khbV$%QGB`Ti-=mO^H%TVPraz+Dbd6=xX&U^RpXar9X~l3JCkRd2i=$ z=N)M8>FWN*B`Q4nTSP#7P)L|Z1Uys&l#vPA1I$4KvvYIu3yN|}(4~ctf^u+WUPUFg z8dr(RB-Ij%85mX>rwV|lQL~+v~d(}VP_k@B}+ac>*^mJ=onY@ z_EB3V#2;tICYKf@i(lqy)+l4|6y>nmpwD2LQkb?x4+16|^)6Ou8;7fb%xpkfTekdL zDy0{WIb^mgt1j>k?h8sYk55iTKjN5T6Qk!X%9lQQ`K+%%W#w#@IjgPa^*4_Ef-p_L zuPohL)`Wo+yBWW|@3J>6-+_H$!KHNMaa8pZ&I`w%?8ngU-MwAmfu24Zettn= z!O|!n9XcHgj3Mf-rCtwCvO;R8g6Nmc1d_evM~jHcDlcBU~y=9 zWEC^fBc5*uX$tPZjC_{*_bw;`It{eg*$E;kmnkj+|U5wL& zZffd(tLBf)*;I|t?XW^+p%%qJ)wGCozc zN>d}VXb`847<5?-$2BhTWGk-ocj@6p4g)jH+GJG|EK;J5RixGhE5I(ChDWB|`ZvUNdi z()1;HfSK=AS3`Fnn=rcwPdF^tImj>8KR)DLly_)o;M3$RRE~p5N_u`uW-c0$U4lIT zs;mM*aaGj>JcLXE1L+JPl*wRoSP;ITme1ofGMgDSBti$SizsZ6G)Y_fxN>^y&|n=v z)J`RfE2n56dKlo}Nc1IIPDZq;?krvJXN`|wl2^mC@iM5!@{cNcaca!Gfj zjf6aDP4_-{=;odsaYHwd%KOa>i>h=)2}k>$1(?L5fBt6Qth~Nx{_^eU^N~9LjbDi` zVyS1lhn0DJRx0|1j%CNt z;E_NYbsYTuO2cnQ9!7Umk*7}96gr{CtseW0uMuc({eE|JJ?QnyIyAyE=zSnEATBss zDbhCCGb%PA-9ID#aEkpqkK8byMBgjUG1+j`VNewg1jXYB#A*nI3Z_AUEH;qIVe$Av z&Ss$!K=>?14TVhX!iz~Qtxa61NM1kKINS_w1-8>WJG!TPW_!nEivCXnD?@7|Uq%7# zl|bE!Y^ul1x?JVe9XT;{srEb58#6DABY+)7Zt9h%k6cGUhqd>3$Jy{gR6pep5nG@C z8lZ9HH_b6eR7k3h<6>L3s{(;K?OoNI`rip+)U=inEcLVjES!~*Cr1NuGVnQ+EaC#C?f=#wC&Ns?Zwmg z7E(`1_bM(ry9EXMyDNF!_xAO%wu=b~Hj1}!Nel>!MB0Yir#ZysIHBK|WEDmfqxAEV z%i!f&ARHb9t;Q2c1PHYTTuUKAfm|Mt!{-V`_54O&GnYxDvZ}kt9c)QAL{!(;-zper z7-<^iwKF=UJ(In&viTW6|1fxY=<`SUYJc~ZT{oJa(JaKfR_i>Sds%*fCSyahyRu90 zeW%Uxy6);(@!g=g7c{?f)!;=h-aTQsJf16vS6zy8TR|TEDe}|L{q>}|%-b>AXT4N? zEQ@~4Y1;i4I4*wBis-o!VwZ{@+-6l?$Hdi}CSC1AiWe_3zdycpHH4V~if5lq{V`u} z)ooYY^+AyaCoQj8!>bUN#2?Yor^=MDJ z-}zZ|Ao8L|#LJNI)X0Q4?=xJpVy-5oeMoljvP?&n#zqDFS;?ECW#InIkxnJEh;7U+ zwz#vl{SS`Ka&W(3K-4Pjp6HqC1&q(hW-5n9M+V25KJ%96l{#~~V*1a+XGb#G{O0Ed z0L50dM6XyYR-np(5jg42ndf@ZYSXWw_T~F7#~-_OVnQ&R%lG@+hW*u|9IcwP?ar_Y zllh=u{Wbh}s;j5|Q-9qj{O82A^ZVkY5rpzFN}&4Z2tB=rznKoI1tU*(9y#u|EAXUj zQjzdO`uT#!ZTTAT8(q7ow{AKbxHxP0#q$U9C%QXekHql?&rbU*me)Rf@c=IS8+qUM z2@bgzY8L47TIcN#?_CjLi4pK5567o*v5|gPKO`rh!&6gU1r(>FbU@g05VWGa3Rejs z5W(bX9Ib+mhX6TTAe6@y2>I;#O{Pq28wJozZEdNQFdBt*{e3(+ue+;9-1|{B!J2B9 zPLGZQ>KnjI!=gd1VqbDZ&T{!>_)K*hH{^LPI$DQ*(T8A|qlj%ih zK|-R=xmwYp4sz`uq{ctJ;Hd%I9c8d<1eE%d1=fjl2T1z&6WiCm`%iX(2`|!m!eJ#9 zapmfI*0x3--$?Wc3S_59+YN*;%sdsoX7J(Cp*?1&c9xwkNbJn;AwMx8=|evVJFHbO zt*E4aPyH$E^47|qhZ#^OT0;D>@p%s=4 z-#NzKBj;XN{v&cj^F+HKcK@@haHvkJ^@rO)q32O)QjJSh{!M`PxP3~>Uy3(^~ z@sfN89m^p#s@hQU{A)#xupr@3M2OzEp4SeX5?k-dyis)J_zq>{uf=5l86CM?25s~;9 z{_-E7>>Lmjos*ZJ3n?lFV+!-j(Uk=yMYwDzkU|BLYbe<23RV>dUq;}OM5O?xfZfam z(-*uuPgg)*6^6g_UGatCWjc-K2{h$!!``~ayT$mNq4V0D+f@Y+nvN9p)TyTC) zR&fR`2uVUjV%o;(hh*3=<@BuAtta?r-ucNi6T_}+? zHTMq6q;-9Yk%o_5qYZNM(AeDg!sLW_co9FdjN9M>te~S)vf7<9z4kLaCpkG}pZbZY pWf!ZHp$(dbz}SD8G>Wgb=uaa1zqEv)*f`MtlO;U=)dv3&{{wX{9B%*s literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/move.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/move.png new file mode 100644 index 0000000000000000000000000000000000000000..15681b311e095bcf71a016c10b98215d2f62fdeb GIT binary patch literal 145 zcmeAS@N?(olHy`uVBq!ia0vp^j371(GmxD1Q}Q5?(hBeias3Yj{~rDSclZCloB#h^ z`TzIA|G%gI|2_Wy@1g&H_x}I8^Z%bM|Nm_G|7SJho#WC#T}qxVjv*W~lLZn25)2Xw s5;zh(5;PJr5@sCO(2&S{n6ZtU!Ptv+qi^c>nLyPHp00i_>zopr08)lQEdT%j literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/multi-days-bg.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/multi-days-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..f43a46357b2b8a44c62bb6955413ca6c422397b1 GIT binary patch literal 350 zcmeAS@N?(olHy`uVBq!ia0vp^j6n2-gBi#={doIQAhj#NC&cyt|NoEQ|GW3*->p~w zu0H>F@#()akD%!6<9|SO4vfw}`3FH4p8UJ;6r>D-E%CiATwRVHQB_&GBsJyf6H$?=Q$jla?0-X33{vuFPP+`eJUrfnOyZZ0n`!f@W=oF literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/second-top-days-bg.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/second-top-days-bg.png new file mode 100644 index 0000000000000000000000000000000000000000..8f9a4f6da021cb45908bfe9e8d904e042b2f047a GIT binary patch literal 138 zcmeAS@N?(olHy`uVBq!ia0vp^j6kf#!3HFY>I`du6lZ})WHAE+-w_aIoT|+y4HUHT zba4#fxSkxb>HVqtw*L+XN*+8aW?NSO|37nQJx{^4`Zq~BXM7Zz1ZN)Ya^*R*tKh#R ivt*e81LI3EMh3oTj_Eal|F_ZNmx0r(h1H*=|U3OfpzvHi}DR`OfUbAABv-upo?U|K(>>jf7 X&0u(ba8}zzpe_baS3j3^P6`1px&CF4n_O8yr)Fq>iQ?Oe~R- ZJN}%psYOZYWQNhg04>pOR|ysdYXG(YZ0G<0 literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab.png new file mode 100644 index 0000000000000000000000000000000000000000..7ee9285229449c6b3361135be958566c494f600b GIT binary patch literal 290 zcmeAS@N?(olHy`uVBq!ia0vp^HbAVx!2~3uq|aRjQfwtbe!)N*2=bP(PXtoeJzX3_ zB3j>G-OY8#K%(uTzJx$wVG#S=qhjd?Up>&>QB}RGinHtkLtax@;ku5}S3yfIH9KFl zY%=}#!9Mud^!^DP4Bp4T{&^th_9K7kqBWtXYBy_6>*GFPB(-bulr??_@=7O=S3O<*T-G@yGywp3=X(MG literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab_wide.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_glossy/white_tab_wide.png new file mode 100644 index 0000000000000000000000000000000000000000..6e5ffb852f02941eeb6e6b7bf27e6509c93ad44f GIT binary patch literal 300 zcmeAS@N?(olHy`uVBq!ia0vp^Q9!K1!3HEb8+12=r~;43Vg?4jBOuH;Rhv&5D0t7) z#W5t~-rMWD`3@$?w0*2!+}Uxor7<$&j8OYQ-H5w#tGzEARNUyPVJLhsMNrZ9#q!Mc z2d+!ZyMO8Mk0)oRUz>2@jwRdm-_G;&!#`N>T%)K=Dy9 z8UiCN1S$f&%o!LM8A^iug8wrB^T7xPYptJY1LL2wz$3Dlfr0M`2s2LA=92~rvX^-J zy0YJ9;TPmqcHKEq1uWzmQQ}xyl96A;uyWlQ51tBm$KdF>F7ur5`BF0TK>REXvEwOJ_JB{j41*#tzY6T9lm1@b!Q5 zYnU?U{M_8syb^|QXQu53im`!|g=CiGq%y2{cS#*6qVMVA7$Pw>IpGMG1P7@BN BaBTnp literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_left.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_left.png new file mode 100644 index 0000000000000000000000000000000000000000..651215a15ae456fa3036d74224e7eddb127d51de GIT binary patch literal 1955 zcmaJ?Yfuws6paBQW5HUB2vX`2Dqw}Ykc6Z}3~T}nCcH8V29%I2BuaKeb|DeP2M)m( zTD1jfttbMmyiAe$2m+=ff{Kbr!BTA%N)>D|AjYB-+l>|NkJ6pl{a)vsd+&G8%2JgaK(#h7#tIA2+p<0i~Qv zUKJ#y3Dx0{LK&H>ff8~>Vp;Bb8Cy;cT?T~cIJkfc!lZysl?kI99hdw{mxIr3+f*{} z3WBZYlK)96Q5Xw^BN_+@qR;|lG$svT(kb-7r7RZ9A7IevG%Afjr85HPEKVSUL!$w& zA2J?IBTwhVgM!zw@D-P=z%Vt3O4Vw$6m1{{(PU8RY&P4b!C(a7hyZj0j7fC?FzP*} z079rtqf}!`1O{x1(ljI+KbefvAD-gdkv* z5|$%c^c7ktZBHcxHg-my*Jm=<5Wu{{LiUf1BJzB%_u9D!i(9tHBmy8hadwJUC|a%qp* zV$F_S+?C(xvZK*2i}(hM?Hr`rL)Afr(^W~_6mLpHjJ-CC8vV$t(7k5jn zR_lw&L6@spu7OvNO~h%|0!?l#Ju_QAJ^5^e$;eVBsjjmc4f_< zTsNn9^8TZ3ZT#`vW|vt7Ys`HmM~#bs?KxxZDf-5qo*u_oMyX4_)!lQu2>|0U9fQcn8$`+p`n@OX=LcRhC#m>~&0 zmhy?pm}^K8i^cCb+H=H|ku_gl^Kp@Ea->@5=hI<6*vOQE!bo zI;%77+lPAd@I|NWHO<0;Vo%ICN$@K4UY)$7bKce&#S4lAU!|Yga4W&*z+$82iR}5< zkLbv{{+QFmK)(Cl-) zwy}Lq;lS;dy90s78HyzrI>XD=#(00%pA7osPwKFtOkdBtk6bTY1FO5ZbjdspsiZ!#L6hj4pPCt8_eCF( z8Tqr)M(pS%g4P>$j=#^Zb0`i8J7mf<(S~Smay2tt&+y``2lKm9^6Q>I2SS0Uy%Zk7qpmoM1=zVJxRP Tx#+8xw%=wHUj){NrRM()d4nQp literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_right.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/arrow_right.png new file mode 100644 index 0000000000000000000000000000000000000000..901b5b7fb79f2623717d8673f12eb26e2ca35e55 GIT binary patch literal 1975 zcmaJ?YfuyC8V=>A2-Q}Of(2cpsYr9(++a;WAkqYr2qZ|FgG$IQ5J|EjSs>g7VPqIA zMFjK+Eyt=EDbOlsEK)!UUXZ4c0#+;tXg!wE3XT*wV7=hkSh4+aIJ>j^UFLb7_kF+j znfZz%r5}2@t#cy~2p%G#AQ~Ti@XvRd3;u73a%bR!H?~88$8i0SQQwM$accZtEZd z8kkRvWlQK1Ll}~*5oQ??S(a3;&Pq`S!o=VpfM0S<%8V6wPeE*Svn3_6Vt(ik9x!G)M0M5hC< zA0i&j2q!|(g7DX|@D-n!j9~_dM$5>^pk^?ss4O#diBXLuv4H@!Y4{J>~tm4U{f((NTJ0wt3F57p`3 zpiNjb@@KyPQ`jWWG$6ES#Du09)p+9)H`zlOpfDq%!ce0eMYW5k7@3S>s3{pW0AVsV z5UbI{Xol$(S|Wi&dK0G7s}YfaPsI6DjRuA|V4#2%4zk(d0Rarg4tgj9WQ5=^$YF%i z!`b1BTmh<1(;<3nkqiIHSlGZ)}g~ajzS3Q$M{~9!VfLQAC0ex%rkQcBfdT@eFDo zRr*sXK&6}V&?%>fr@y=6deHCE6Jg2W2!pzWajo!L;RmbNR)~pzPhwl)(c|KTGm>lK zL`Ja{7Jk+X69)u}-uV8hmw%prCMud# z@w;!?_9u>Y%swYgxZbS&vg1k4x3S9YE*_y}v%}g8V=*x?@~Ef~XJ==)d8F&`p;M7i z&6&Eot<}emf36_UZ3zCh`)Yp9^5*kFiREEUO-%)U71m{Y;^I90OFUdomTz9}QFMg` zf}!{B-OHQlYZvqCiyA9J{>kESZcRLVn5`}VR|EO~O=&^tA8R}f))#>K+R?U0wv<8xQDV53+1VJvJ*Luyw487&3 z=!B!^lMa679?WI2hJH&3+B-hIM$zdsrwrYP%Iaa75@Z>mpHy4F0s_Og;(`001D zNBukYgH?X(K2f^5xGYqD^Tj#l$+J_I0B`?CyIWJA)A?C*1!r>}Zy_y&{DTtENlL9v zZdQ<6rPYyZ51#VxYkov(K$vNF@`Nwl5AVNK;238FtFUTYVyYWO1P(_GkCV3)*&?_b zUWBi$e(%8#b?N?P?h|(0)T*XaACNy<8C!4llRbWi_Tt(5!u#u=3(zYAX}U`eRPRai zfeRLrU-2iF%x+G(*QWE8RVk#A^@ucfpmeGV6~=xawad3=?xsv!d`NnJw>;)=KH$DH zP;f9xrc!Ut8GM0;VZl$OzMEr<3(wps;%aAm^RGrB(!u`8$;ov1$T7=}+4_$8)(h7M zPg5$Ty|T^kS~WdBejk^~mCC0juC+fv;uT%|J-mx2^y`C#sie@~%yB=i@rnC5PsC=k zgMW5nGMUv)mTBx<<3|rhZdcscJ7J0R``rb;kmHe!-xqp=D!Z+JYQw{RvV~ o=Y}NKLi3ZOY1>y!oF+IDTK_c`b0jYRw*4vDX4gA6@@CTake(qgK=SYet7SF@B8MPv5xjV zwW~L-rYNd55tmbB_PC>_n*4k62R@Ri0Y@{q3*~S@u^|=KP!@uOq4dENRJ5TZ&tWS? zRRKMn!I|VjxEI^yAa)vu_dx> zp-^B7%?z^pSY8kWSHtJ?5`@7Ugk>CQg5+U|7qt zrn6KgQZTltSS-(QZc1ffGWma~VJxE^oPvM+{!`dV4_S~+K?mh+m0VnIvm441B^xRj z*=d9hm#f&(k1%rjkp-kKKj_s>4HcY4bTTO>Ob08b3KMdOCVWQMH8JRyq-Z22`D4K# z&quk46pjf&UW)hvd^8dcl({le^9D3=nXCQb$`!e8BN!HmEJIsA3bmMx46vB6s8{w9 zuBf-f)hc_5ROGV64C`L&U)NkdBE91-mz$PsmfIehq}OfI)GxlzKOzs}aY7EKi*K@X zrBYkf{h%N`xH>i(pO~C{&D=(*r;(e}Ok&fGl(OEaZp^Mbt2bQwvVDM?pZj)Y^z=kF zoL@+_3*BdCrb;8vGP6w|I$t%xi#^%7H7yO*8LKJR`*H`o(6PJoTz6HRKYwTcr-QuU zc~-x1Wc*kuackW|-6iGFlk4@-s`zJi)%)vjBddZIJeA|v* zq&i8L@KOh(f}l%S5lGRG6?E`Y5FwG8mr4*tjF6&o`(|~uL)*YN-w)68ywCf7?>E{R zKT%tAw1yyv+Gs>f;Ca6@_EzKnseJDuo{peU3U$E@Do7?E+7*}vWK@%~AOR$0XmA>| z5=0fLCQ~RCJ1NLeb4w1!ZEFT*6GUs9ZAfxIKx7(ZRXsqhKAxgTRS8hto){A|f*_|x zhE32l98b!_{W7mmZO6%0TfhPuKoV(d1G**H0ji`c;I(s1Q)CH(`UBLasZ^|!3_=r- z9yjBX881V6SvT9<;`8~MNRD9{n&D`cbFn_5nG+a>-1;aS%~Uc%LJV)k!n**KL&y+l zx=<*%3(an5W@(n^c}IieTo~c9hIAy^F5PMxL50$4C_%J||k4NfRS2%11b z&`d%&P_ANU4kBpfpg{(^JY=`3E3jad(6N{h)h#6HGKh)+3iI8nstA0jBkT<|cX+~n zKg)&~p7V#q4v`H9InL{C;mTYQ%6SdwsLWM%xWS5Crx7#*M;3vpo&!qQgc?~&SWqi_ z;VbHGah1wm+ADHtY=(BO^{;C#AK~6{mfKB>H`{FwblmGEZfctS`Wioo@u=9Iv_GW3 z7mICG_x(Ko=-TM{$mOxIw|X|)-F|2K%%ysIW8~-hO0h}2I`?^bxwlVM_kDR#msnm} z>gm(8+IsoL?f3KZPv6bV914x^xss;oyNMge*iWf@jq7V`jd{a(u6ufN-}JeMYsJMk z*9X%FUY(vC_)%P$^*uQ}Vb4x##gUC)(YlKV;li`u#npwW(U-)oY9jJ+cQF&cdCPgZ M(NJ8R=s0`f4|MHo@c;k- literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/noevents.png b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/imgs_mobile/noevents.png new file mode 100644 index 0000000000000000000000000000000000000000..05da890fe1cf4b98f8c955cfedeb53be9cba4462 GIT binary patch literal 1687 zcma)+c~sI_6vuyAxsaliCrivNCoFTxG)4EhJfHhXo8l|ZQjqe%C-O!{(^9W)90K84*Yi?P=kr31XJ%2u;F|Zb{=WM`n zem(LX9l?WcOpr{a1Ep1+9uU$7A%rC{&eAC~kV1_HHffn{hd4~d4^wFgbV@iG1S)hp zT_6hoPU)mjmDCiZM3Df;1zjyDqNR!iP|t&Lp>z^JpslLp8@?x}FwRDXLQ*w z<_!t})`xjw-Ei>*(}QB~fKVfiFGN{!mm||!|2K3~{CM5IJiioJ_GQaPJ#)Tu90B}X z%YJUd_v2;GOrLi`?78ldX~Ey`Jh9QF*3;_fmdb)eMC{yO=_w3Z@mk&91;(C2*;GHZ zJ-1ra(Q+1zMy~^|J;q6Z7PgMoI$y0H^in^$&XU-_RNrYvB9Od(?I%8HZ_gX5EATDF zVJ?2F;q#NE@2qch%r)mAY0 zD=y>WCvjXZxBZ4mwWDc~sJgN;D5tlt&maSPq6k9}gkXw@c)Xtbmb93aB_-M6)v{D7 zySx_H)TbnjNa&L$!D(? zqK*pfYzU1tvw>^mP!pe|(nq_!H4&N5=8e95lS}jRwnm@MAqBm=WffROcyg*d#D%-r zopxH&EESK(KaQIW2lyEt7Nvq~tKBB}%yD=Ioj3=SUO7yjNDhc?5y zaO;RLvnlraAeExjNyH>{{5hGq* zUH$l5e$0qELdz^ZDInl&17qSUnaQj@W3$Px;Y=`r@Dq>h@S&%thPwVqh#fh9yo=+c zyqO)DUt$!Jzk~QnkynziFhhuDkcVIVekdFSL0Xl>>nLt^A&Xu zAGZFAHNPWGq*85($xDhXWWgcxZ%fKYNfzcpJ2>7AmM(0p>L}%8S4bO;{*<~9FXTUW zB?^+KCnxRM1B+-ijg*u3_8KCQn=;y_rlxv&aPqRq*w`E-|8VwVP2@h-L^pTxf=nhG z+=4_tS`Z}2#wUBrv7<8OXrq%6Tm~9sJ{#Q#N?`sG5mt!a{${VHrlx0MSy%0$Bgt+^ zUQV>wIGiiY3WbBmSuFG_U2t)+?%nOQG(2%K*9QzMc?AQ(CTVBP&=I!sHB-cB}uChvDYVsKepkD zdskOidKnF0in{=U{|pP$FC7}1>VGu2)2V>waCACi}TZ1 z^QUMZb3+r8Tp@I`;CQ|H)O9YM)3LgpO@|KwEG z%F0SzU7devTjtAi_Wfe<#mSzXi*^EuX#XDV?RuI^~J@-r=lnt~IW6I)=tan0ou6VSU#UK$c12R?jIbTT3$B3LXA zS{%KQu?cm+*k`#~ZSt_%8eFTV_Ag!@ra$Hapi6;W-`XXmLjNz|dE^AP%01-rzn2#b AcK`qY literal 0 HcmV?d00001 diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/readme.txt b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/readme.txt new file mode 100644 index 00000000000..67cb13ff468 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/codebase/readme.txt @@ -0,0 +1,16 @@ +There are a lot of files here, but you need only part of them + +Desctop scheduler, default skin + dhtmlxscheduler.js + dhtmlxscheduler.css + imgs\ + +Desctop scheduler, glossy skin + dhtmlxscheduler.js + dhtmlxscheduler_glossy.css + imgs_glossy\ + +Mobile scheduler + dhtmlxscheduler_mobile.js + dhtmlxscheduler_mobile.css + imgs_mobile\ \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/license.txt b/addons/base_calendar/static/lib/dhtmlxScheduler/license.txt new file mode 100644 index 00000000000..4a7d08c91e4 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/license.txt @@ -0,0 +1,228 @@ + + GNU GENERAL PUBLIC LICENSE + +Version 2, June 1991 + +Copyright (C) 1989, 1991 Free Software Foundation, Inc. + +59 Temple Place - Suite 330, Boston, MA 02111-1307, USA + +Everyone is permitted to copy and distribute verbatim copies + +of this license document, but changing it is not allowed. + +TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + +0. This License applies to any program or other work which contains a +notice placed by the copyright holder saying it may be distributed under +the terms of this General Public License. The "Program", below, refers +to any such program or work, and a "work based on the Program" means +either the Program or any derivative work under copyright law: that is +to say, a work containing the Program or a portion of it, either +verbatim or with modifications and/or translated into another language. +(Hereinafter, translation is included without limitation in the term +"modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of running +the Program is not restricted, and the output from the Program is +covered only if its contents constitute a work based on the Program +(independent of having been made by running the Program). Whether that +is true depends on what the Program does. + +1. You may copy and distribute verbatim copies of the Program's source +code as you receive it, in any medium, provided that you conspicuously +and appropriately publish on each copy an appropriate copyright notice +and disclaimer of warranty; keep intact all the notices that refer to +this License and to the absence of any warranty; and give any other +recipients of the Program a copy of this License along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + +2. You may modify your copy or copies of the Program or any portion of +it, thus forming a work based on the Program, and copy and distribute +such modifications or work under the terms of Section 1 above, provided +that you also meet all of these conditions: + +a) You must cause the modified files to carry prominent notices stating +that you changed the files and the date of any change. + +b) You must cause any work that you distribute or publish, that in whole +or in part contains or is derived from the Program or any part thereof, +to be licensed as a whole at no charge to all third parties under the +terms of this License. + +c) If the modified program normally reads commands interactively when +run, you must cause it, when started running for such interactive use in +the most ordinary way, to print or display an announcement including an +appropriate copyright notice and a notice that there is no warranty (or +else, saying that you provide a warranty) and that users may +redistribute the program under these conditions, and telling the user +how to view a copy of this License. (Exception: if the Program itself is +interactive but does not normally print such an announcement, your work +based on the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, and +can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based on +the Program, the distribution of the whole must be on the terms of this +License, whose permissions for other licensees extend to the entire +whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of a +storage or distribution medium does not bring the other work under the +scope of this License. + +3. You may copy and distribute the Program (or a work based on it, under +Section 2) in object code or executable form under the terms of Sections +1 and 2 above provided that you also do one of the following: + +a) Accompany it with the complete corresponding machine-readable source +code, which must be distributed under the terms of Sections 1 and 2 +above on a medium customarily used for software interchange; or, + +b) Accompany it with a written offer, valid for at least three years, to +give any third party, for a charge no more than your cost of physically +performing source distribution, a complete machine-readable copy of the +corresponding source code, to be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, + +c) Accompany it with the information you received as to the offer to +distribute corresponding source code. (This alternative is allowed only +for noncommercial distribution and only if you received the program in +object code or executable form with such an offer, in accord with +Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source code +means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to control +compilation and installation of the executable. However, as a special +exception, the source code distributed need not include anything that is +normally distributed (in either source or binary form) with the major +components (compiler, kernel, and so on) of the operating system on +which the executable runs, unless that component itself accompanies the +executable. + +If distribution of executable or object code is made by offering access +to copy from a designated place, then offering equivalent access to copy +the source code from the same place counts as distribution of the source +code, even though third parties are not compelled to copy the source +along with the object code. + +4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt otherwise +to copy, modify, sublicense or distribute the Program is void, and will +automatically terminate your rights under this License. However, parties +who have received copies, or rights, from you under this License will +not have their licenses terminated so long as such parties remain in +full compliance. + +5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and all +its terms and conditions for copying, distributing or modifying the +Program or works based on it. + +6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further restrictions +on the recipients' exercise of the rights granted herein. You are not +responsible for enforcing compliance by third parties to this License. + +7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot distribute +so as to satisfy simultaneously your obligations under this License and +any other pertinent obligations, then as a consequence you may not +distribute the Program at all. For example, if a patent license would +not permit royalty-free redistribution of the Program by all those who +receive copies directly or indirectly through you, then the only way you +could satisfy both it and this License would be to refrain entirely from +distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is implemented +by public license practices. Many people have made generous +contributions to the wide range of software distributed through that +system in reliance on consistent application of that system; it is up to +the author/donor to decide if he or she is willing to distribute +software through any other system and a licensee cannot impose that choice. + +This section is intended to make thoroughly clear what is believed to be +a consequence of the rest of this License. + +8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License may +add an explicit geographical distribution limitation excluding those +countries, so that distribution is permitted only in or among countries +not thus excluded. In such case, this License incorporates the +limitation as if written in the body of this License. + +9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and +conditions either of that version or of any later version published by +the Free Software Foundation. If the Program does not specify a version +number of this License, you may choose any version ever published by the +Free Software Foundation. + +10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the +author to ask for permission. For software which is copyrighted by the +Free Software Foundation, write to the Free Software Foundation; we +sometimes make exceptions for this. Our decision will be guided by the +two goals of preserving the free status of all derivatives of our free +software and of promoting the sharing and reuse of software generally. + +NO WARRANTY + +11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER +EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE +ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH +YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL +NECESSARY SERVICING, REPAIR OR CORRECTION. + +12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN +WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY +AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR +DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL +DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM +(INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED +INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF +THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR +OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. + diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/readme.txt b/addons/base_calendar/static/lib/dhtmlxScheduler/readme.txt index 647f03a9958..ccda9adb09a 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/readme.txt +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/readme.txt @@ -1,7 +1,6 @@ -dhtmlxScheduler v.2.3 +dhtmlxScheduler v.3.0 build 110727 This software is allowed to use under GPL or you need to obtain Commercial or Enterise License -to use it in not GPL project. Please contact sales@dhtmlx.com for details - +to use it in non-GPL project. Please contact sales@dhtmlx.com for details (c) DHTMLX Ltd. \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/base.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/base.js index 350f83198a1..45a6dc0c820 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/base.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/base.js @@ -1,4 +1,19 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.date={ + init:function(){ + var s = scheduler.locale.date.month_short; + var t = scheduler.locale.date.month_short_hash = {}; + for (var i = 0; i < s.length; i++) + t[s[i]]=i; + + var s = scheduler.locale.date.month_full; + var t = scheduler.locale.date.month_full_hash = {}; + for (var i = 0; i < s.length; i++) + t[s[i]]=i; + }, date_part:function(date){ date.setHours(0); date.setMinutes(0); @@ -12,7 +27,7 @@ scheduler.date={ week_start:function(date){ var shift=date.getDay(); if (scheduler.config.start_on_monday){ - if (shift==0) shift=6 + if (shift===0) shift=6; else shift--; } return this.date_part(this.add(date,-1*shift,"day")); @@ -31,7 +46,14 @@ scheduler.date={ add:function(date,inc,mode){ var ndate=new Date(date.valueOf()); switch(mode){ - case "day": ndate.setDate(ndate.getDate()+inc); break; + case "day": + ndate.setDate(ndate.getDate()+inc); + if(date.getDate()==ndate.getDate() && !!inc) { + do { + ndate.setTime(ndate.getTime()+60*60*1000); + } while (date.getDate() == ndate.getDate()) + } + break; case "week": ndate.setDate(ndate.getDate()+7*inc); break; case "month": ndate.setMonth(ndate.getMonth()+inc); break; case "year": ndate.setYear(ndate.getFullYear()+inc); break; @@ -73,7 +95,7 @@ scheduler.date={ case "%W": return "\"+scheduler.date.to_fixed(scheduler.date.getISOWeek(date))+\""; default: return a; } - }) + }); if (utc) format=format.replace(/date\.get/g,"date.getUTC"); return new Function("date","return \""+format+"\";"); }, @@ -106,6 +128,12 @@ scheduler.date={ break; case "%s": splt+="set[5]=temp["+i+"]||0;"; break; + case "%M": splt+="set[1]=scheduler.locale.date.month_short_hash[temp["+i+"]]||0;"; + break; + case "%F": splt+="set[1]=scheduler.locale.date.month_full_hash[temp["+i+"]]||0;"; + break; + default: + break; } } var code ="set[0],set[1],set[2],set[3],set[4],set[5]"; @@ -116,18 +144,18 @@ scheduler.date={ getISOWeek: function(ndate) { if(!ndate) return false; var nday = ndate.getDay(); - if (nday == 0) { + if (nday === 0) { nday = 7; } var first_thursday = new Date(ndate.valueOf()); first_thursday.setDate(ndate.getDate() + (4 - nday)); var year_number = first_thursday.getFullYear(); // year of the first Thursday - var ordinal_date = Math.floor( (first_thursday.getTime() - new Date(year_number, 0, 1).getTime()) / 86400000); //ordinal date of the first Thursday - 1 (so not really ordinal date) + var ordinal_date = Math.round( (first_thursday.getTime() - new Date(year_number, 0, 1).getTime()) / 86400000); //ordinal date of the first Thursday - 1 (so not really ordinal date) var week_number = 1 + Math.floor( ordinal_date / 7); return week_number; }, getUTCISOWeek: function(ndate){ - return this.getISOWeek(ndate); - } -} + return this.getISOWeek(ndate); + } +}; \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/clear.css b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/clear.css index 728af2d65bd..3a3217e940a 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/clear.css +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/clear.css @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ .dhx_cal_ltext{ text-align:left; } diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/config.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/config.js index d9e5685a132..460b6771c00 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/config.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/config.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ /* %e Day of the month without leading zeros (01..31) %d Day of the month, 2 digits with leading zeros (01..31) @@ -39,27 +43,35 @@ scheduler.config={ edit_on_create:1, details_on_create:0, click_form_details:0, - + cascade_event_display: false, + cascade_event_count:4, + cascade_event_margin: 30, + drag_lightbox:true, + preserve_scroll:true, + server_utc:false, positive_closing:false, icons_edit:["icon_save","icon_cancel"], icons_select:["icon_details","icon_edit","icon_delete"], - + buttons_left:["dhx_save_btn","dhx_cancel_btn"], + buttons_right:["dhx_delete_btn"], lightbox:{ sections:[ {name:"description", height:200, map_to:"text", type:"textarea" , focus:true}, {name:"time", height:72, type:"time", map_to:"auto"} ] - } + }, + + repeat_date_of_end: "01.01.2010" }; -scheduler.templates={} +scheduler.templates={}; scheduler.init_templates=function(){ var d=scheduler.date.date_to_str; var c=scheduler.config; var f = function(a,b){ for (var c in b) if (!a[c]) a[c]=b[c]; - } + }; f(scheduler.templates,{ day_date:d(c.default_date), month_date:d(c.month_date), @@ -99,7 +111,7 @@ scheduler.init_templates=function(){ return ev.text; } }); - this.callEvent("onTemplatesReady",[]) -} + this.callEvent("onTemplatesReady",[]); +}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/connector.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/connector.js index 45afbf6d089..72462172908 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/connector.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/connector.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ /* dhx_sort[index]=direction dhx_filter[index]=mask @@ -7,10 +11,10 @@ if (window.dhtmlXGridObject){ dhtmlXGridObject.prototype._init_point=function(){ var clear_url=function(url){ url=url.replace(/(\?|\&)connector[^\f]*/g,""); - return url+(url.indexOf("?")!=-1?"&":"?")+"connector=true"+(mygrid.hdr.rows.length > 0 ? "&dhx_no_header=1":""); + return url+(url.indexOf("?")!=-1?"&":"?")+"connector=true"+(this.hdr.rows.length > 0 ? "&dhx_no_header=1":""); }; var combine_urls=function(url){ - return clear_url(url)+(this._connector_sorting||"")+(this._connector_filter||""); + return clear_url.call(this,url)+(this._connector_sorting||"")+(this._connector_filter||""); }; var sorting_url=function(url,ind,dir){ this._connector_sorting="&dhx_sort["+ind+"]="+dir; @@ -112,14 +116,10 @@ if (window.dhtmlXGridObject){ } if (this._con_f_used[f*1]) this._con_f_used[f*1]=v; - }; + } this._colls_loaded=true; } - }; - - - - + }; } if (window.dataProcessor){ @@ -131,7 +131,9 @@ if (window.dataProcessor){ this.setTransactionMode("POST",true); this.serverProcessor+=(this.serverProcessor.indexOf("?")!=-1?"&":"?")+"editing=true"; }; -}; +} dhtmlxError.catchError("LoadXML",function(a,b,c){ - alert(c[0].responseText); + if (c[0].status != 0) { + alert(c[0].responseText); + } }); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dataprocessor_hook.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dataprocessor_hook.js index 1fdfc17bb68..27741b6d147 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dataprocessor_hook.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dataprocessor_hook.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler._dp_init=function(dp){ dp._methods=["setEventTextStyle","","changeEventId","deleteEvent"]; @@ -5,7 +9,7 @@ scheduler._dp_init=function(dp){ if (!this._loading && this.validId(id)) dp.setUpdated(id,true,"inserted"); }); - this.attachEvent("onBeforeEventDelete",function(id){ + this.attachEvent("onConfirmedBeforeEventDelete", function(id){ if (!this.validId(id)) return; var z=dp.getState(id); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dayevents.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dayevents.js new file mode 100644 index 00000000000..4717fe2858b --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dayevents.js @@ -0,0 +1,200 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +dhx.protoUI({ + name:"dayevents", + defaults:{ + hourFormat:"%H", + hourClock:12, + firstHour:0, + lastHour:24, + timeScaleWidth:45, + timeScaleHeight: 30, + scroll:true, + scaleBorder:1, + eventOffset:5, + width:"auto", + date: new Date() + }, + $init:function(config){ + this.name = "DayEvents"; + + this._dataobj.style.position = "relative"; + this.data.provideApi(this,true); + this.data.attachEvent("onStoreUpdated",dhx.bind(this.render,this)); + + this.attachEvent("onBeforeRender", function(){ + this._renderScale(); + this.type.color = this.config.color; + this.type.textColor = this.config.textColor; + this._renderobj = this._dataobj.firstChild; + this._prepareEvents(); + if(window.scheduler) + this.type.template = scheduler.templates.day_event; + }); + if(window.scheduler){ + config.hourFormat = scheduler.config.scale_hour; + config.timeScaleWidth = scheduler.xy.scale_width; + config.timeScaleHeight = scheduler.xy.scale_height*2; + } + }, + _renderScale:function(){ + var html = "
"; + for(var h = this.config.firstHour; h"; + html += "
"+hour+"
"; + html += "
"; + html += "
"+top+"
"; + html += "
"+bottom+"
"; + html += "
"; + html += "
"; + html += "
"; + html += "
"; + html += "
"; + html += ""; + return html; + }, + type:{ + templateStart:dhx.Template("
"), + template:scheduler.templates.day_event, + templateEnd:dhx.Template("
"), + templateCss:dhx.Template(""), + templateColor:dhx.Template("#color#"), + templateTextColor:dhx.Template("#textColor#"), + padding:2 + }, + _prepareEvents:function(){ + var evs = this.data.getRange(); + var stack = []; + var ev,i,j,k,_is_sorder,_max_sorder,_sorder_set; + for(i=0; i< evs.length;i++){ + ev=evs[i]; + ev.$inner=false; + while (stack.length && stack[stack.length-1].end_date.valueOf()<=ev.start_date.valueOf()){ + stack.splice(stack.length-1,1); + } + _sorder_set = false; + + for(j=0;j< stack.length;j++){ + if(stack[j].end_date.valueOf()<=ev.start_date.valueOf()){ + _sorder_set = true; + ev.$sorder=stack[j].$sorder; + stack.splice(j,1); + ev.$inner=true; + break; + } + } + + if (stack.length) stack[stack.length-1].$inner=true; + + if(!_sorder_set){ + if(stack.length){ + if(stack.length<=stack[stack.length-1].$sorder){ + if(!stack[stack.length-1].$sorder) + ev.$sorder = 0; + else + for(j=0;j_max_sorder) + _max_sorder = stack[j].$sorder; + ev.$sorder = _max_sorder+1; + ev.$inner = false; + } + } + else + ev.$sorder = 0; + } + stack.push(ev); + if (stack.length>(stack.max_count||0)) stack.max_count=stack.length; + } + + for (var i=0; i < evs.length; i++){ + evs[i].$count=stack.max_count; + this._setPosition(evs[i]); + } + }, + _setPosition:function(ev){ + + var date = this.config.date.getValue?this.config.date.getValue():this.config.date; + + var start = dhx.Date.copy(ev.start_date); + var end = dhx.Date.copy(ev.end_date); + var sh = start.getHours(); + var eh = end.getHours(); + if(dhx.Date.datePart(start).valueOf()>dhx.Date.datePart(end).valueOf()){ + end = start; + } + + if(dhx.Date.datePart(start).valueOf()dhx.Date.datePart(date).valueOf()){ + end = dhx.Date.datePart(date); + end.setMinutes(0); + end.setHours(this.config.lastHour); + } + if (sh < this.config.firstHour || eh >= this.config.lastHour){ + if (sh < this.config.firstHour){ + end.setHours(this.config.firstHour); + ev.start_date.setMinutes(0); + } + if (eh >= this.config.lastHour){ + end.setMinutes(0); + end.setHours(this.config.lastHour); + } + } + var temp_width = Math.floor((this._content_width-this.config.timeScaleWidth-this.config.eventOffset-8)/ev.$count); + ev.$left=ev.$sorder*(temp_width)+this.config.timeScaleWidth+this.config.eventOffset; + if (!ev.$inner) temp_width=temp_width*(ev.$count-ev.$sorder); + ev.$width = temp_width-this.config.eventOffset-this.type.padding*2; + + var sm = start.getHours()*60+start.getMinutes(); + var em = (end.getHours()*60+end.getMinutes())||(this.config.lastHour*60); + ev.$top = Math.round((sm-this.config.firstHour/60)*(this.config.timeScaleHeight+1)/60); //42px/hour + ev.$height = Math.max(10,(em-sm)*(this.config.timeScaleHeight+1)/60-2)-this.type.padding*2; + } +}, dhx.MouseEvents, dhx.SelectionModel, dhx.Scrollable, dhx.RenderStack, dhx.DataLoader, dhx.ui.view, dhx.EventSystem, dhx.Settings); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxcommon.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxcommon.js index 0dcaa7a070c..ce3c3891f0f 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxcommon.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxcommon.js @@ -1,3 +1,37 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +dhtmlx=function(obj){ + for (var a in obj) dhtmlx[a]=obj[a]; + return dhtmlx; //simple singleton +}; +dhtmlx.extend_api=function(name,map,ext){ + var t = window[name]; + if (!t) return; //component not defined + window[name]=function(obj){ + if (obj && typeof obj == "object" && !obj.tagName && !(obj instanceof Array)){ + var that = t.apply(this,(map._init?map._init(obj):arguments)); + //global settings + for (var a in dhtmlx) + if (map[a]) this[map[a]](dhtmlx[a]); + //local settings + for (var a in obj){ + if (map[a]) this[map[a]](obj[a]); + else if (a.indexOf("on")==0){ + this.attachEvent(a,obj[a]); + } + } + } else + var that = t.apply(this,arguments); + if (map._patch) map._patch(this); + return that||this; + }; + window[name].prototype=t.prototype; + if (ext) + dhtmlXHeir(window[name].prototype,ext); +}; + dhtmlxAjax={ get:function(url,callback){ var t=new dtmlXMLLoaderObject(true); @@ -546,12 +580,15 @@ dhtmlDragAndDropObject.prototype.initFrameRoute=function(win, mode){ } } -var _isFF = false; -var _isIE = false; -var _isOpera = false; -var _isKHTML = false; -var _isMacOS = false; -var _isChrome = false; +_isFF = false; +_isIE = false; +_isOpera = false; +_isKHTML = false; +_isMacOS = false; +_isChrome = false; +_KHTMLrv = false; +_OperaRv = false; +_FFrv = false; if (navigator.userAgent.indexOf('Macintosh') != -1) _isMacOS=true; @@ -868,4 +905,10 @@ dhtmlxEventable=function(obj){ this[list[0]].removeEvent(list[1]); //remove event } } + obj.detachAllEvents = function(){ + for (var name in this){ + if (name.indexOf("ev_")==0) + delete this[name]; + } + } } diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor.js index 8dfc1cb0dd1..4a4143f947f 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ /** * @desc: constructor, data processor object * @param: serverProcessorURL - url used for update @@ -362,6 +366,8 @@ dataProcessor.prototype={ var soid = sid; switch (action) { + case "update": + case "updated": case "inserted": case "insert": if (tid != sid) { diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_debug.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_debug.js index 2b251515166..e26776e533a 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_debug.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_debug.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ dataProcessor.prototype._o_init = dataProcessor.prototype.init; dataProcessor.prototype.init=function(obj){ this._console=this._console||this._createConsole(); @@ -86,7 +90,7 @@ dataProcessor.wrap("sendData",function(rowId){ if (!this.obj._idpull[rowId]) this._log(" Error! item with such ID not exists "+rowId+""); } else { - if (!this.obj.rowsAr[rowId]) + if (this.rowsAr && !this.obj.rowsAr[rowId]) this._log(" Error! row with such ID not exists "+rowId+""); } } @@ -150,7 +154,7 @@ dataProcessor.wrap("afterUpdateCallback",function(sid,tid,action){ if (this.obj.mytype=="tree"){ if (!this.obj._idpull[sid]) this._log("Incorrect SID, item with such ID not exists in grid"); } else { - if (!this.obj.rowsAr[sid]) this._log("Incorrect SID, row with such ID not exists in grid"); + if (this.obj.rowsAr && !this.obj.rowsAr[sid]) this._log("Incorrect SID, row with such ID not exists in grid"); } this._log(" Action: "+action+" SID:"+sid+" TID:"+tid); },function(){ diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_jsonp.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_jsonp.js new file mode 100644 index 00000000000..19779666494 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/dhtmlxdataprocessor_jsonp.js @@ -0,0 +1,57 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +if(dataProcessor) { + dataProcessor.prototype.enableJSONP = function(mode) { + if(mode) { + this._jsonp_attach_id = this.attachEvent("onBeforeDataSending", function(rowId,rowIdState,a1){ + if (rowId) + this._in_progress[rowId]=(new Date()).valueOf(); + + var url = this.serverProcessor+(this._user?(getUrlSymbol(this.serverProcessor)+["dhx_user="+this._user,"dhx_version="+this.obj.getUserData(0,"version")].join("&")):""); + url += ((url.indexOf("?")!=-1)?"&":"?")+this.serialize(a1,rowId); + + this._jsonp(url, [], function(data){ + var xml = new dtmlXMLLoaderObject(this.afterUpdate,this,true); + xml.loadXMLString(data); + this.afterUpdate(this, null, null, null, xml); + }, this); + + this._waitMode++; + return false; + }); + } + else { + if(this._jsonp_attach_id) + this.detachEvent(this._jsonp_attach_id); + } + }; + dataProcessor.prototype._jsonp = function(url, params, callback, master){ + var global_obj = "dataProcessor"; + var id = "dp_jsonp_"+new Date().valueOf(); + var script = document.createElement('script'); + script.id = id; + script.type = 'text/javascript'; + + var head = document.getElementsByTagName("head")[0]; + + if (!params) + params = {}; + params.jsonp = global_obj+"."+id; // would be called as dataProcessor.dp_jsonp_1938948394 + dataProcessor[id]=function(){ + callback.apply(master||window, arguments); + script.parentNode.removeChild(script); + callback = head = master = script = null; + delete dataProcessor[id]; + }; + + var vals = []; + for (var key in params) vals.push(key+"="+encodeURIComponent(params[key])); + + url += (url.indexOf("?") == -1 ? "?" : "&")+vals.join("&"); + + script.src = url ; + head.appendChild(script); + }; +} diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/event.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/event.js index 202a6e5fcb9..18542ecbe3b 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/event.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/event.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.uid=function(){ if (!this._seed) this._seed=(new Date).valueOf(); return this._seed++; @@ -9,6 +13,8 @@ scheduler.clearAll=function(){ this.clear_view(); }; scheduler.addEvent=function(start_date,end_date,text,id,extra_data){ + if(!arguments.length) + return this.addEventNow(); var ev=start_date; if (arguments.length!=1){ ev=extra_data||{}; @@ -16,12 +22,17 @@ scheduler.addEvent=function(start_date,end_date,text,id,extra_data){ ev.end_date=end_date; ev.text=text; ev.id=id; - }; + } ev.id = ev.id||scheduler.uid(); ev.text = ev.text||""; - + if (typeof ev.start_date == "string") ev.start_date=this.templates.api_date(ev.start_date); if (typeof ev.end_date == "string") ev.end_date=this.templates.api_date(ev.end_date); + + var d = (this.config.event_duration||this.config.time_step)*60000; + if(ev.start_date.valueOf() == ev.end_date.valueOf()) + ev.end_date.setTime(ev.end_date.valueOf()+d); + ev._timed=this.is_one_day_event(ev); var is_new=!this._events[ev.id]; @@ -30,15 +41,17 @@ scheduler.addEvent=function(start_date,end_date,text,id,extra_data){ if (!this._loading) this.callEvent(is_new?"onEventAdded":"onEventChanged",[ev.id,ev]); }; -scheduler.deleteEvent=function(id,silent){ +scheduler.deleteEvent=function(id,silent){ var ev=this._events[id]; - if (!silent && !this.callEvent("onBeforeEventDelete",[id,ev])) return; - + if (!silent && (!this.callEvent("onBeforeEventDelete",[id,ev]) || !this.callEvent("onConfirmedBeforeEventDelete", [id,ev]))) + return; if (ev){ delete this._events[id]; this.unselect(id); this.event_updated(ev); } + + this.callEvent("onEventDeleted", [id]); }; scheduler.getEvent=function(id){ return this._events[id]; @@ -64,6 +77,7 @@ scheduler.changeEventId=function(id,new_id){ }); if (this._select_id==id) this._select_id=new_id; if (this._edit_id==id) this._edit_id=new_id; + //if (this._drag_id==id) this._drag_id=new_id; this.callEvent("onEventIdChange",[id,new_id]); }; @@ -92,8 +106,7 @@ scheduler.event_updated=function(ev,force){ else this.clear_event(ev.id); }; scheduler.is_visible_events=function(ev){ - if (ev.start_dateb.start_date?1:-1; }); + evs.sort(function(a,b){ + if(a.start_date.valueOf()==b.start_date.valueOf()) + return a.id>b.id?1:-1; + return a.start_date>b.start_date?1:-1; + }); var days=[]; //events by weeks var evs_originals = []; for (var i=0; i < evs.length; i++) { @@ -239,12 +268,70 @@ scheduler._pre_render_events_line=function(evs,hold){ if (!hold){ ev._inner=false; + var stack=days[ev._sday]; while (stack.length && stack[stack.length-1].end_date<=ev.start_date) stack.splice(stack.length-1,1); - if (stack.length) stack[stack.length-1]._inner=true; - ev._sorder=stack.length; stack.push(ev); - if (stack.length>(stack.max_count||0)) stack.max_count=stack.length; + + var sorderSet = false; + for(var j=0; j _max_sorder) + _max_sorder = stack[j]._sorder; + ev._sorder = _max_sorder + 1; + ev._inner = false; + } + + } + else + ev._sorder = 0; + } + + stack.push(ev); + + if (stack.length>(stack.max_count||0)) { + stack.max_count=stack.length; + ev._count=stack.length; + } + else { + ev._count=(ev._count)?ev._count:1; + } } if (sh < this.config.first_hour || eh >= this.config.last_hour){ @@ -262,23 +349,23 @@ scheduler._pre_render_events_line=function(evs,hold){ evs.splice(i,1); i--; continue; } } - } if (!hold){ - for (var i=0; i < evs.length; i++) - evs[i]._count=days[evs[i]._sday].max_count; - for (var i=0; i < evs_originals.length; i++) + for (var i=0; i < evs.length; i++) { + evs[i]._count = days[evs[i]._sday].max_count; + } + for (var i=0; i < evs_originals.length; i++) evs_originals[i]._count=days[evs_originals[i]._sday].max_count; } return evs; }; scheduler._time_order=function(evs){ - evs.sort(function(a,b){ + evs.sort(function(a,b){ if (a.start_date.valueOf()==b.start_date.valueOf()){ if (a._timed && !b._timed) return 1; if (!a._timed && b._timed) return -1; - return 0; + return a.id>b.id?1:-1; } return a.start_date>b.start_date?1:-1; }); @@ -317,8 +404,10 @@ scheduler._pre_render_events_table=function(evs,hold){ // max - max height of we for (stack_line=0; stack_line"; - var obj = this._render_v_bar(ev.id,left-menu+1,top,menu,icons.length*20+26,"","
",icons_str,true); + icons_str+="
"; + var obj = this._render_v_bar(ev.id,left-menu+1,top,menu,icons.length*20+26,"","
",icons_str,true); obj.style.left=left-menu+1; this._els["dhx_cal_data"][0].appendChild(obj); this._rendered.push(obj); @@ -445,17 +542,19 @@ scheduler.render_event=function(ev){ }; scheduler._render_v_bar=function(id,x,y,w,h,style,contentA,contentB,bottom){ var d=document.createElement("DIV"); - var ev = this.getEvent(id); var cs = "dhx_cal_event"; var cse = scheduler.templates.event_class(ev.start_date,ev.end_date,ev); if (cse) cs=cs+" "+cse; + + var bg_color = (ev.color?("background-color:"+ev.color+";"):""); + var color = (ev.textColor?("color:"+ev.textColor+";"):""); var html='
'; - html+='
 
'; - html+='
'+contentA+'
'; - html+='
'+contentB+'
'; - html+='
'; + html+='
 
'; + html+='
'+contentA+'
'; + html+='
'+contentB+'
'; + html+=''; d.innerHTML=html; return d.firstChild; @@ -471,22 +570,25 @@ scheduler.locate_holder_day=function(date,past){ return day; }; scheduler.render_event_bar=function(ev){ - var parent=this._els["dhx_cal_data"][0]; + var parent=this._rendered_location; var x=this._colsS[ev._sday]; var x2=this._colsS[ev._eday]; if (x2==x) x2=this._colsS[ev._eday+1]; var hb = this.xy.bar_height; - var y=this._colsS.heights[ev._sweek]+(this._colsS.height?(this.xy.month_scale_height+2):2)+ev._sorder*hb; + var y=this._colsS.heights[ev._sweek]+(this._colsS.height?(this.xy.month_scale_height+2):2)+(ev._sorder*hb); var d=document.createElement("DIV"); var cs = ev._timed?"dhx_cal_event_clear":"dhx_cal_event_line"; var cse = scheduler.templates.event_class(ev.start_date,ev.end_date,ev); - if (cse) cs=cs+" "+cse; + if (cse) cs=cs+" "+cse; + + var bg_color = (ev.color?("background-color:"+ev.color+";"):""); + var color = (ev.textColor?("color:"+ev.textColor+";"):""); + + var html='
'; - var html='
'; - if (ev._timed) html+=scheduler.templates.event_bar_date(ev.start_date,ev.end_date,ev); html+=scheduler.templates.event_bar_text(ev.start_date,ev.end_date,ev)+'
'; @@ -542,4 +644,4 @@ scheduler.getEvents = function(from,to){ result.push(ev); } return result; -}; \ No newline at end of file +}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext.css b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext.css index 402c5b38271..de19bca63ed 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext.css +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext.css @@ -1,6 +1,15 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +.dhx_scale_bar_header { + position: absolute; + border-bottom: 1px dotted #8894A3; + width: 100%; +} .dhx_expand_icon { position:absolute; top:0px; right:0px; - background-image:url(../codebase/imgs/colapce-expand-icon.gif); + background-image:url(./imgs/colapce-expand-icon.gif); width:18px; height:18px; cursor:pointer; background-position:0px 18px; @@ -10,7 +19,7 @@ width:100%; height:100%; overflow-y:auto; - background-image:url(../codebase/imgs/databg.png); + background-image:url(./imgs/databg.png); } .dhx_agenda_line{ height:21px; @@ -37,7 +46,7 @@ .dhx_agenda_line .dhx_event_icon{ width:20px; border-width:0px; - background:url(../codebase/imgs/icon.png) no-repeat; + background:url(./imgs/icon.png) no-repeat; background-position: 5px 4px; cursor:pointer; } @@ -51,7 +60,6 @@ border-left:1px dotted #586A7E; } .dhx_year_week{ - height:20px; position:relative; } .dhx_scale_bar_last{ @@ -79,7 +87,7 @@ } .dhx_tooltip{ border:1px solid #BBBBBB; - background-image:url(../codebase/imgs/databg.png); + background-image:url(./imgs/databg.png); position:absolute; z-index:9998; width:300px; @@ -101,7 +109,7 @@ float:left; border-width:0px; position:relative; - background:url(../codebase/imgs/icon.png) no-repeat; + background:url(./imgs/icon.png) no-repeat; background-position: 5px 4px; cursor:pointer; } @@ -136,10 +144,12 @@ left:190px; top:1px; cursor:pointer; - background-image:url(../imgs/calendar.gif); + background-image:url(./imgs/calendar.gif); } - +.dhx_matrix_scell { + height: 100%; +} .dhx_matrix_cell, .dhx_matrix_scell{ overflow:hidden; @@ -151,10 +161,12 @@ .dhx_matrix_cell{ background-color:white; } +.dhx_matrix_line{ + overflow: hidden; +} .dhx_matrix_cell div, .dhx_matrix_scell div{ overflow:hidden; text-align:center; - width:100%; height:auto; } @@ -179,12 +191,17 @@ .dhx_matrix_scell .dhx_scell_level2{ padding-left: 35px; } +.dhx_matrix_scell .dhx_scell_level3{ + padding-left: 50px; +} +.dhx_matrix_scell .dhx_scell_level4{ + padding-left: 65px; +} .dhx_matrix_scell.folder{ font-weight: bold; text-align: left; } - .dhx_matrix_scell.folder .dhx_scell_expand{ float: left; width: 10px; @@ -198,13 +215,17 @@ padding-left:15px; text-align: left; } -.dhx_section_timeline, .dhx_section_timeline2{ - overflow: hidden; - padding: 2px 0 2px 10px; +.dhx_data_table.folder .dhx_matrix_cell{ + border-right: 0; } -.dhx_section_timeline select, .dhx_section_timeline2 select{ +.dhx_section_timeline { + overflow: hidden; + padding: 4px 0 2px 10px; +} +.dhx_section_timeline select{ width: 552px; } + /* Tree view end*/ /* Map view */ @@ -213,12 +234,12 @@ height:100%; overflow-y: auto; overflow-x: hidden; - background-image:url(../codebase/imgs/databg.png); + background-image:url(./imgs/databg.png); } .dhx_map_line .dhx_event_icon{ width:20px; border-width:0px; - background:url(../codebase/imgs/icon.png) no-repeat; + background:url(./imgs/icon.png) no-repeat; background-position: 5px 4px; cursor:pointer; } @@ -247,7 +268,7 @@ } .dhx_map_line .dhx_map_description{ float:left; - border-right: 0px dotted #8894A3; + border-right: 0 dotted #8894A3; text-align:center; line-height:21px; overflow:hidden; @@ -271,8 +292,12 @@ /* dhtmlXTooltip start */ .dhtmlXTooltip.tooltip{ -moz-box-shadow:3px 3px 3px #888888; - -khtml-box-shadow:3px 3px 3px #888888; - + -webkit-box-shadow:3px 3px 3px #888888; + -o-box-shadow:3px 3px 3px #888888; + box-shadow:3px 3px 3px #888888; + filter: + progid:DXImageTransform.Microsoft.Shadow(color='#888888', Direction=135, Strength=5) + ; background-color:white; border-left:1px dotted #887A2E; border-top:1px dotted #887A2E; @@ -315,3 +340,47 @@ padding: 4px; } /* Lightbox dhtmlx combo section end */ + +/* Agenda week start */ +.dhx_wa_column { + float: left; +} +.dhx_wa_column_last .dhx_wa_day_cont{ + border-left: 1px dotted #8894A3; +} +.dhx_wa_scale_bar { + font-family: Tahoma; + padding-left: 10px; + font-size: 11px; + border-top: 1px dotted #8894A3; + border-bottom: 1px dotted #8894A3; +} +.dhx_wa_day_data { + background-color: #FCFEFC; + overflow-y: auto; +} +.dhx_wa_ev_body { + border-bottom: 1px dotted #778899; + font-size: 12px; + padding: 5px 0 5px 7px; +} +.dhx_wa_dnd { + font-family: Tahoma; + position: absolute; + padding-right: 7px; + color: #887AE2 !important; + background-color: #FFE763 !important; + border: 1px solid #B7A543; +} +.dhx_cal_event_selected{ + background-color: #9cc1db; + color: white; +} +/* Agenda week end */ + +/* timeline second scale start */ +.dhx_second_scale_bar { + border-bottom: 1px dotted #586A7E; + padding-top: 2px; +} +/* timeline second scale end */ \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_active_links.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_active_links.js index 79ebce494bb..46bc624c1ea 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_active_links.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_active_links.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.attachEvent("onTemplatesReady",function(){ var s_d = scheduler.date.str_to_date(scheduler.config.api_date); var d_s = scheduler.date.date_to_str(scheduler.config.api_date); @@ -5,17 +9,18 @@ scheduler.attachEvent("onTemplatesReady",function(){ var month_x = scheduler.templates.month_day; scheduler.templates.month_day=function(date){ return ""+month_x(date)+""; - } + }; var week_x = scheduler.templates.week_scale_date; scheduler.templates.week_scale_date=function(date){ return ""+week_x(date)+""; - } - - + }; dhtmlxEvent(this._obj,"click",function(e){ var start = e.target || event.srcElement; var to = start.getAttribute("jump_to"); - if (to) + if (to) { scheduler.setCurrentView(s_d(to),"day"); + if (e && e.preventDefault) e.preventDefault(); + return false; + } }) -}) \ No newline at end of file +}); \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_agenda_view.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_agenda_view.js index 6fcdd5cc106..08d06e0e644 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_agenda_view.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_agenda_view.js @@ -1,20 +1,24 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.date.add_agenda = function(date){ return (new Date(date.valueOf())); -} +}; scheduler.dblclick_dhx_agenda_area=function(){ if (!this.config.readonly && this.config.dblclick_create) this.addEventNow(); -} +}; scheduler.templates.agenda_time = function(start,end,ev){ if (ev._timed) return this.day_date(ev.start_date, ev.end_date, ev)+" "+this.event_date(start); else return scheduler.templates.day_date(start)+" – "+scheduler.templates.day_date(end); -} -scheduler.templates.agenda_text = function(ev){ - return ev.text; -} +}; +scheduler.templates.agenda_text = function(start,end,event){ + return event.text; +}; scheduler.date.agenda_start=function(d){ return d; }; scheduler.attachEvent("onTemplatesReady",function(){ @@ -37,6 +41,19 @@ scheduler.attachEvent("onTemplatesReady",function(){ else return old.apply(this,arguments); } + + var old_render_view_data = scheduler.render_view_data; + scheduler.render_view_data=function(){ + if(this._mode == "agenda") { + scheduler._agendaScrollTop = scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop; + scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop = 0; + scheduler._els["dhx_cal_data"][0].style.overflowY = 'hidden'; + } + else { + scheduler._els["dhx_cal_data"][0].style.overflowY = 'auto'; + } + return old_render_view_data.apply(this,arguments); + } function set_full_view(mode){ @@ -59,15 +76,18 @@ scheduler.attachEvent("onTemplatesReady",function(){ //generate html for the view var html="
"; for (var i=0; i
"+scheduler.templates.agenda_time(events[i].start_date, events[i].end_date,events[i])+"
"; + var ev = events[i]; + var bg_color = (ev.color?("background-color:"+ev.color+";"):""); + var color = (ev.textColor?("color:"+ev.textColor+";"):""); + html+="
"+scheduler.templates.agenda_time(ev.start_date, ev.end_date,ev)+"
"; html+="
 
"; - html+=""+scheduler.templates.agenda_text(events[i])+"
"; + html+=""+scheduler.templates.agenda_text(ev.start_date, ev.end_date, ev)+"
"; } html+="
"; //render html - scheduler._els["dhx_cal_data"][0].scrollTop = 0; //fix flickering in FF scheduler._els["dhx_cal_data"][0].innerHTML = html; + scheduler._els["dhx_cal_data"][0].childNodes[0].scrollTop = scheduler._agendaScrollTop||0; var t=scheduler._els["dhx_cal_data"][0].firstChild.childNodes; scheduler._els["dhx_cal_date"][0].innerHTML=""; @@ -90,4 +110,4 @@ scheduler.attachEvent("onTemplatesReady",function(){ //agenda tab de-activated } } -}) \ No newline at end of file +}) diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_collision.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_collision.js index d2582a05926..e1e5d0fb52f 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_collision.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_collision.js @@ -1,27 +1,35 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ (function(){ -var temp_section,temp_time; +var temp_section; var before; scheduler.config.collision_limit = 1; -scheduler.attachEvent("onBeforeDrag",function(id){ - var pr = scheduler._props?scheduler._props[this._mode]:null; - var matrix = scheduler.matrix?scheduler.matrix[this._mode]:null; - var checked_mode = pr||matrix; + +function _setTempSection(event_id) { // for custom views (matrix, timeline, units) + var pr = scheduler._props?scheduler._props[scheduler._mode]:null; + var matrix = scheduler.matrix?scheduler.matrix[scheduler._mode]:null; + var checked_mode = pr||matrix; // units or matrix mode if(pr) var map_to = checked_mode.map_to; if(matrix) var map_to = checked_mode.y_property; + if ((checked_mode) && event_id){ + temp_section = scheduler.getEvent(event_id)[map_to]; + } +} - if ((checked_mode) && id){ - temp_section = this.getEvent(id)[map_to]; - temp_time = this.getEvent(id).start_date; - } +scheduler.attachEvent("onBeforeDrag",function(id){ + _setTempSection(id); return true; }); scheduler.attachEvent("onBeforeLightbox",function(id){ var ev = scheduler.getEvent(id); before = [ev.start_date, ev.end_date]; + _setTempSection(id); return true; }); scheduler.attachEvent("onEventChanged",function(id){ @@ -39,17 +47,16 @@ scheduler.attachEvent("onBeforeEventChanged",function(ev,e,is_new){ return collision_check(ev); }); scheduler.attachEvent("onEventSave",function(id, edited_ev){ - //var ev = scheduler.getEvent(id); - if(edited_ev.rec_type) + if(edited_ev.rec_type){ scheduler._roll_back_dates(edited_ev); - - return collision_check(edited_ev); + return collision_check(edited_ev); + } + return true; + //return collision_check(edited_ev); }); - function collision_check(ev){ var evs = []; - if (ev.rec_type) { var evs_dates = scheduler.getRecDates(ev); for(var k=0; k scheduler.config.collision_limit) { - scheduler._drag_event.start_date = temp_time; - ev[map_to] = temp_section; + if (count >= scheduler.config.collision_limit) { + ev[map_to] = temp_section; // from _setTempSection for custom views single = false; } } else { - if (evs.length > scheduler.config.collision_limit) + if (evs.length > scheduler.config.collision_limit) single = false; } - if (!single) return !scheduler.callEvent("onEventCollision",[ev,evs]); return single; -}; +} -})(); \ No newline at end of file +})(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_cookie.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_cookie.js index 0df4852ccdc..71f1d5e6794 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_cookie.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_cookie.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ (function(){ function setCookie(name,cookie_param,value) { var str = name + "=" + value + (cookie_param?("; "+cookie_param):""); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_editors.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_editors.js index 8c64d13eddc..e76eff631f4 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_editors.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_editors.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.form_blocks['combo']={ render:function(sns) { var res = ''; @@ -40,7 +44,7 @@ scheduler.form_blocks['combo']={ scheduler.form_blocks['radio']={ render:function(sns) { var res = ''; - res += "
"; + res += "
"; for (var i=0; i"; @@ -74,20 +78,32 @@ scheduler.form_blocks['radio']={ scheduler.form_blocks['checkbox']={ render:function(sns) { - return ''; + if (scheduler.config.wide_form) + return '
'; + else + return ''; }, set_value:function(node,value,ev,config){ + node=document.getElementById(config.id); var id = scheduler.uid(); var isChecked = false; if (typeof config.checked_value != 'undefined' && ev[config.map_to] == config.checked_value) { isChecked = true; } - node.previousSibling.className += " dhx_cal_checkbox"; - node.previousSibling.innerHTML=""; - + node.className += " dhx_cal_checkbox"; + var check_html = ""; + var label_html = ""; + if (scheduler.config.wide_form){ + node.innerHTML = label_html; + node.nextSibling.innerHTML=check_html; + } else + node.innerHTML=check_html+label_html; }, get_value:function(node,ev,config){ - var checkbox = node.previousSibling.getElementsByTagName('input')[0]; // moved to the header + node=document.getElementById(config.id); + var checkbox = node.getElementsByTagName('input')[0]; // moved to the header + if (!checkbox) + checkbox = node.nextSibling.getElementsByTagName('input')[0]; return (checkbox.checked)?(config.checked_value||true):(config.unchecked_value||false); }, focus:function(node){ diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_expand.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_expand.js index 9224bef1af5..5e916128cf9 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_expand.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_expand.js @@ -1,27 +1,30 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.expand = function(){ - var t = scheduler._obj; - do { - t._position = t.style.position||""; - t.style.position = "static"; - } while ((t = t.parentNode) && t.style ); - t = scheduler._obj; - t.style.position="absolute"; - t._width = t.style.width; - t._height = t.style.height; - t.style.width = t.style.height = "100%"; - t.style.top = t.style.left = "0px"; - - var top =document.body; - top.scrollTop = 0; - - top = top.parentNode; - if (top) - top.scrollTop = 0; - document.body._overflow=document.body.style.overflow||""; - document.body.style.overflow = "hidden"; - scheduler._maximize() -} - + var t = scheduler._obj; + do { + t._position = t.style.position||""; + t.style.position = "static"; + } while ((t = t.parentNode) && t.style ); + t = scheduler._obj; + t.style.position="absolute"; + t._width = t.style.width; + t._height = t.style.height; + t.style.width = t.style.height = "100%"; + t.style.top = t.style.left = "0px"; + + var top = document.body; + top.scrollTop = 0; + + top = top.parentNode; + if (top) + top.scrollTop = 0; + document.body._overflow=document.body.style.overflow||""; + document.body.style.overflow = "hidden"; + scheduler._maximize(); +}; scheduler.collapse = function(){ var t = scheduler._obj; do { @@ -31,9 +34,8 @@ scheduler.collapse = function(){ t.style.width = t._width; t.style.height = t._height; document.body.style.overflow=document.body._overflow; - scheduler._maximize() -} - + scheduler._maximize(); +}; scheduler.attachEvent("onTemplatesReady",function(){ var t = document.createElement("DIV"); t.className="dhx_expand_icon"; @@ -46,9 +48,27 @@ scheduler.attachEvent("onTemplatesReady",function(){ scheduler.collapse(); } }); + scheduler._maximize = function(){ - this.expanded = !this.expanded; - this.toggleIcon.style.backgroundPosition="0px "+(this._expand?"0":"18")+"px"; - if (scheduler.callEvent("onSchedulerResize",[])) - scheduler.update_view(); -} + this.expanded = !this.expanded; + this.toggleIcon.style.backgroundPosition="0px "+(this.expanded?"0":"18")+"px"; + + var directions = ['left', 'top']; + for(var i=0; i= scheduler.config.collision_limit); + }); + + scheduler.addEvent=function(start_date,end_date,text,id,extra_data){ + var ev=start_date; + if (arguments.length!=1){ + ev=extra_data||{}; + ev.start_date=start_date; + ev.end_date=end_date; + ev.text=text; + ev.id=id; + ev.layer = this.defaultLayer; + }; + ev.id = ev.id||scheduler.uid(); + ev.text = ev.text||""; + + + if (typeof ev.start_date == "string") ev.start_date=this.templates.api_date(ev.start_date); + if (typeof ev.end_date == "string") ev.end_date=this.templates.api_date(ev.end_date); + ev._timed=this.is_one_day_event(ev); + + var is_new=!this._events[ev.id]; + this._events[ev.id]=ev; + this.event_updated(ev); + if (!this._loading) + this.callEvent(is_new?"onEventAdded":"onEventChanged",[ev.id,ev]); + }; + + this._evs_layer = {}; + for (var i = 0; i < this.layers.length; i++) { // array in object for each layer + this._evs_layer[this.layers[i].name] = []; + } + + scheduler.addEventNow=function(start,end,e){ + var base = {}; + if (typeof start == "object"){ + base = start; + start = null; + } + + var d = (this.config.event_duration||this.config.time_step)*60000; + if (!start) start = Math.round((new Date()).valueOf()/d)*d; + var start_date = new Date(start); + if (!end){ + var start_hour = this.config.first_hour; + if (start_hour > start_date.getHours()){ + start_date.setHours(start_hour); + start = start_date.valueOf(); + } + end = start+d; + } + + + base.start_date = base.start_date||start_date; + base.end_date = base.end_date||new Date(end); + base.text = base.text||this.locale.labels.new_event; + base.id = this._drag_id = this.uid(); + base.layer = this.defaultLayer; + this._drag_mode="new-size"; + + this._loading=true; + this.addEvent(base); + this.callEvent("onEventCreated",[this._drag_id,e]); + this._loading=false; + + this._drag_event={}; //dummy , to trigger correct event updating logic + this._on_mouse_up(e); + } + + scheduler._t_render_view_data = function(events) { // helper + if (this.config.multi_day && !this._table_view) { + var tvs = []; + var tvd = []; + for (var k = 0; k < events.length; k++) { + if (events[k]._timed) + tvs.push(events[k]); + else + tvd.push(events[k]); + } + this._table_view = true; + this.render_data(tvd); + this._table_view = false; + this.render_data(tvs); + } + else + this.render_data(events); + }; + + scheduler.render_view_data = function(){ + if (this._not_render) { + this._render_wait = true; + return; + } + this._render_wait = false; + + this.clear_view(); + + this._evs_layer = {}; + for (var i = 0; i < this.layers.length; i++) { // array in object for each layer + this._evs_layer[this.layers[i].name] = []; + } + + var evs = this.get_visible_events(); + for (var i = 0; i < evs.length; i++) { // filling layer arrays with events + if(this._evs_layer[evs[i].layer]) + this._evs_layer[evs[i].layer].push(evs[i]); + } + + if(this._mode == 'month') { // old logic is used + var tevs = []; + for (var i = 0; i < this.layers.length; i++) { + if (this.layers[i].visible) + tevs = tevs.concat(this._evs_layer[this.layers[i].name]); + } + this._t_render_view_data(tevs); + } + else { // week, day; should use new logic + for (var i = 0; i < this.layers.length; i++) { + if (this.layers[i].visible) { + var evs_layer = this._evs_layer[this.layers[i].name]; + this._t_render_view_data(evs_layer); + } + } + } + }; + + scheduler._render_v_bar=function(id,x,y,w,h,style,contentA,contentB,bottom){ + var ev = this.getEvent(id); + if(contentA.indexOf('
'; + html+='
 
'; + html+='
'+contentA+'
'; + html+='
'+contentB+'
'; + html+='
'; + + d.innerHTML=html; + d.style.zIndex = 100; + return d.firstChild; + }; + + scheduler.render_event_bar=function(ev){ + var parent=this._els["dhx_cal_data"][0]; + + var x=this._colsS[ev._sday]; + var x2=this._colsS[ev._eday]; + if (x2==x) x2=this._colsS[ev._eday+1]; + var hb = this.xy.bar_height; + + var y=this._colsS.heights[ev._sweek]+(this._colsS.height?(this.xy.month_scale_height+2):2)+ev._sorder*hb; + + var d=document.createElement("DIV"); + var cs = ev._timed?"dhx_cal_event_clear":"dhx_cal_event_line"; + var cse = (scheduler.templates['event_class_'+ev.layer])?scheduler.templates['event_class_'+ev.layer](ev.start_date,ev.end_date,ev):scheduler.templates.event_class(ev.start_date,ev.end_date,ev); + if (cse) cs=cs+" "+cse; + + var html='
'; + + if (ev._timed) + html+=(scheduler.templates['event_bar_date_'+ev.layer])?scheduler.templates['event_bar_date_'+ev.layer](ev.start_date,ev.end_date,ev):scheduler.templates.event_bar_date(ev.start_date,ev.end_date,ev); + html+=( (scheduler.templates['event_bar_text_'+ev.layer])?scheduler.templates['event_bar_text_'+ev.layer](ev.start_date,ev.end_date,ev):scheduler.templates.event_bar_text(ev.start_date,ev.end_date,ev) + '
)'); + html+='
'; + + d.innerHTML=html; + + this._rendered.push(d.firstChild); + parent.appendChild(d.firstChild); + }; + + scheduler.render_event=function(ev){ + var menu = scheduler.xy.menu_width; + if(scheduler.getLayer(ev.layer).noMenu) + menu = 0; + + if (ev._sday<0) return; //can occur in case of recurring event during time shift + var parent=scheduler.locate_holder(ev._sday); + if (!parent) return; //attempt to render non-visible event + var sm = ev.start_date.getHours()*60+ev.start_date.getMinutes(); + var em = (ev.end_date.getHours()*60+ev.end_date.getMinutes())||(scheduler.config.last_hour*60); + + var top = (Math.round((sm*60*1000-this.config.first_hour*60*60*1000)*this.config.hour_size_px/(60*60*1000)))%(this.config.hour_size_px*24)+1; //42px/hour + var height = Math.max(scheduler.xy.min_event_height,(em-sm)*this.config.hour_size_px/60)+1; //42px/hour + //var height = Math.max(25,Math.round((ev.end_date.valueOf()-ev.start_date.valueOf())*(this.config.hour_size_px+(this._quirks?1:0))/(60*60*1000))); //42px/hour + var width=Math.floor((parent.clientWidth-menu)/ev._count); + var left=ev._sorder*width+1; + if (!ev._inner) width=width*(ev._count-ev._sorder); + + + + var d=this._render_v_bar(ev.id,menu+left,top,width,height,ev._text_style,scheduler.templates.event_header(ev.start_date,ev.end_date,ev),scheduler.templates.event_text(ev.start_date,ev.end_date,ev)); + + this._rendered.push(d); + parent.appendChild(d); + + left=left+parseInt(parent.style.left,10)+menu; + + top+=this._dy_shift; //corrupt top, to include possible multi-day shift + d.style.zIndex = this._layers_zindex[ev.layer]; + + if (this._edit_id==ev.id){ + d.style.zIndex = parseInt(d.style.zIndex)+1; //fix overlapping issue + var new_zIndex = d.style.zIndex; + width=Math.max(width-4,scheduler.xy.editor_width); + var d=document.createElement("DIV"); + d.setAttribute("event_id",ev.id); + this.set_xy(d,width,height-20,left,top+14); + d.className="dhx_cal_editor"; + d.style.zIndex = new_zIndex; + var d2=document.createElement("DIV"); + this.set_xy(d2,width-6,height-26); + d2.style.cssText+=";margin:2px 2px 2px 2px;overflow:hidden;"; + + + d2.style.zIndex = new_zIndex; + d.appendChild(d2); + this._els["dhx_cal_data"][0].appendChild(d); + this._rendered.push(d); + + d2.innerHTML=""; + if (this._quirks7) d2.firstChild.style.height=height-12+"px"; //IEFIX + this._editor=d2.firstChild; + this._editor.onkeypress=function(e){ + if ((e||event).shiftKey) return true; + var code=(e||event).keyCode; + if (code==scheduler.keys.edit_save) scheduler.editStop(true); + if (code==scheduler.keys.edit_cancel) scheduler.editStop(false); + }; + this._editor.onselectstart=function(e){ return (e||event).cancelBubble=true; }; + d2.firstChild.focus(); + //IE and opera can add x-scroll during focusing + this._els["dhx_cal_data"][0].scrollLeft=0; + d2.firstChild.select(); + } + if (this._select_id==ev.id){ + d.style.zIndex = parseInt(d.style.zIndex)+1; //fix overlapping issue + var icons=this.config["icons_"+((this._edit_id==ev.id)?"edit":"select")]; + var icons_str=""; + for (var i=0; i
"; + var obj = this._render_v_bar(ev.id,left-menu+1,top,menu,icons.length*20+26,"","
",icons_str,true); + obj.style.left=left-menu+1; + obj.style.zIndex = d.style.zIndex; + this._els["dhx_cal_data"][0].appendChild(obj); + this._rendered.push(obj); + } + + }; + + scheduler.filter_agenda = function(id, event) { + var layer = scheduler.getLayer(event.layer); + return (layer && layer.visible); + }; +}); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_limit.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_limit.js index 4a8ad2fed6d..ad790cf3ea9 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_limit.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_limit.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.config.limit_start = new Date(-3999,0,0); scheduler.config.limit_end = new Date( 3999,0,0); scheduler.config.limit_view = false; @@ -5,6 +9,48 @@ scheduler.config.limit_view = false; (function(){ var before = null; + var block_days = {}; + var block_weeks = {}; + var time_block_set = false; + scheduler.blockTime = function(day, zones){ + var bottom = this.config.first_hour*60 + var top = this.config.last_hour*60 + if (zones == "fullday") + zones = [bottom,top]; + + if (typeof day == "object") + block_days[this.date.date_part(day).valueOf()] = zones; + else + block_weeks[day] = zones; + + for (var i=0; itop) + zones[i+1] = top; + } + + time_block_set = true; + }; + + scheduler.attachEvent("onScaleAdd", function(area, day){ + var zones = block_days[day.valueOf()] || block_weeks[day.getDay()]; + if (zones){ + for (var i = 0; i < zones.length; i+=2){ + var start = zones[i]; + var end = zones[i+1]; + var block = document.createElement("DIV"); + block.className = "dhx_time_block"; + + var h_px // FIXME + block.style.top = (Math.round((start*60*1000-this.config.first_hour*60*60*1000)*this.config.hour_size_px/(60*60*1000)))%(this.config.hour_size_px*24)+"px"; + block.style.height = (Math.round(((end-start-1)*60*1000)*this.config.hour_size_px/(60*60*1000)))%(this.config.hour_size_px*24)+"px"; + + area.appendChild(block); + } + } + }); + scheduler.attachEvent("onBeforeViewChange",function(om,od,nm,nd){ nd = nd||od; nm = nm||om; if (scheduler.config.limit_view){ @@ -20,6 +66,44 @@ scheduler.config.limit_view = false; var blocker = function(ev){ var c = scheduler.config; var res = (ev.start_date.valueOf() >= c.limit_start.valueOf() && ev.end_date.valueOf() <= c.limit_end.valueOf()); + if (res && time_block_set && ev._timed){ + var day = scheduler.date.date_part(new Date(ev.start_date.valueOf())); + var zones = block_days[day.valueOf()] || block_weeks[day.getDay()]; + var sm = ev.start_date.getHours()*60+ev.start_date.getMinutes(); + var em = ev.end_date.getHours()*60+ev.end_date.getMinutes(); + if (zones){ + for (var i = 0; i < zones.length; i+=2){ + var sz = zones[i]; + var ez = zones[i+1]; + if (szsm) { + if (sm<=ez && sm >=sz){ + if (ez == 24*60 || em=sz && em scheduler.config.limit_end) { - ev.end_date = new Date(scheduler.config.limit_end); - // as end date was changed need to recheck if event occuring during one day - ev._timed = this.is_one_day_event(ev); + if (ev.start_date.valueOf() >= scheduler.config.limit_end.valueOf()) { + ev.start_date = this.date.add(scheduler.config.limit_end, -1, "day"); + } + if (ev.end_date < scheduler.config.limit_start) { + ev.end_date = new Date(scheduler.config.limit_start); + } + if (ev.end_date.valueOf() >= scheduler.config.limit_end.valueOf()) { + ev.end_date = this.date.add(scheduler.config.limit_end, -1, "day"); } - // in case if both start and end date were specified < scheduler.config.limit_star - if (ev.start_date > ev.end_date) { + if (ev.start_date.valueOf() >= ev.end_date.valueOf()) { ev.end_date = this.date.add(ev.start_date, (this.config.event_duration||this.config.time_step), "minute"); } + ev._timed=this.is_one_day_event(ev); } return true; }); @@ -74,5 +163,4 @@ scheduler.config.limit_view = false; return blocker(ev); }); -})(); - +})(); \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_map_view.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_map_view.js index 05845b9c468..e2e17d14e03 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_map_view.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_map_view.js @@ -1,5 +1,7 @@ - - +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.xy.map_date_width = 188; // date column width scheduler.xy.map_description_width = 400; // description column width @@ -18,74 +20,90 @@ scheduler.config.map_zoom_after_resolve = 15; scheduler.locale.labels.marker_geo_success = "It seems you are here."; scheduler.locale.labels.marker_geo_fail = "Sorry, could not get your current position using geolocation."; -scheduler.templates.marker_date=scheduler.date.date_to_str("%Y-%m-%d %H:%i"); // date for map's infowindow will be formated following way +scheduler.templates.marker_date = scheduler.date.date_to_str("%Y-%m-%d %H:%i"); // date for map's infowindow will be formated following way -scheduler.templates.marker_text=function(start, end, ev){ - return "
"+ev.text+"

"+(ev.event_location||'')+"

"+scheduler.templates.marker_date(start)+" - "+scheduler.templates.marker_date(end)+"
"; +scheduler.templates.marker_text = function(start, end, ev) { + return "
" + ev.text + "

" + (ev.event_location || '') + "

" + scheduler.templates.marker_date(start) + " - " + scheduler.templates.marker_date(end) + "
"; }; -scheduler.dblclick_dhx_map_area=function(){ +scheduler.dblclick_dhx_map_area = function() { if (!this.config.readonly && this.config.dblclick_create) - this.addEventNow(); + this.addEventNow({ + start_date: scheduler._date, + end_date: scheduler.date.add(scheduler._date, 1, "hour") + }); }; -scheduler.templates.map_time = function(start,end,ev){ - if (ev._timed) - return this.day_date(ev.start_date, ev.end_date, ev)+" "+this.event_date(start); +scheduler.templates.map_time = function(start, end, ev) { + if (ev._timed) + return this.day_date(ev.start_date, ev.end_date, ev) + " " + this.event_date(start); else - return scheduler.templates.day_date(start)+" – "+scheduler.templates.day_date(end); + return scheduler.templates.day_date(start) + " – " + scheduler.templates.day_date(end); }; -scheduler.templates.map_text = function(ev){ +scheduler.templates.map_text = function(start, end, ev) { return ev.text; }; -scheduler.date.map_start=function(d){ return d; }; - -scheduler.attachEvent("onTemplatesReady",function(){ +scheduler.date.map_start = function(d) { + return d; +}; +scheduler.date.add_map = function(date, inc, mode) { + return (new Date(date.valueOf())); +}; + +scheduler.templates.map_date = function(dd, ed, mode) { + return ''; +}; + +scheduler._latLngUpdate = false; // flag for not displaying event second time in case of coordinates update + +scheduler.attachEvent("onSchedulerReady", function() { + + (function() { + scheduler._isMapPositionSet = false; // if user actual (geolocation) position was set on the map - function _append_map() { - _isPositionSet = false; // if user actual (geolocation) position was set on the map - var gmap = document.createElement('div'); - gmap.className='dhx_map'; - gmap.id='dhx_gmap'; + gmap.className = 'dhx_map'; + gmap.id = 'dhx_gmap'; gmap.style.dispay = "none"; - - node = document.getElementById('scheduler_here'); + + var node = scheduler._obj; node.appendChild(gmap); - + scheduler._els.dhx_gmap = []; scheduler._els.dhx_gmap.push(gmap); - + _setMapSize('dhx_gmap'); var mapOptions = { zoom: scheduler.config.map_inital_zoom || 10, center: scheduler.config.map_initial_position, - mapTypeId: scheduler.config.map_type||google.maps.MapTypeId.ROADMAP + mapTypeId: scheduler.config.map_type || google.maps.MapTypeId.ROADMAP }; - map = new google.maps.Map(document.getElementById('dhx_gmap'), mapOptions); + var map = new google.maps.Map(document.getElementById('dhx_gmap'), mapOptions); map.disableDefaultUI = false; - map.disableDoubleClickZoom = true; - + map.disableDoubleClickZoom = !scheduler.config.readonly; + google.maps.event.addListener(map, "dblclick", function(event) { if (!scheduler.config.readonly && scheduler.config.dblclick_create) { - point = event.latLng; + var point = event.latLng; geocoder.geocode( - { 'latLng': point }, - function(results, status) { - if (status == google.maps.GeocoderStatus.OK) { - point = results[0].geometry.location; - scheduler.addEventNow({ - lat: point.lat(), - lng: point.lng(), - event_location: results[0].formatted_address - }); + { 'latLng': point }, + function(results, status) { + if (status == google.maps.GeocoderStatus.OK) { + point = results[0].geometry.location; + scheduler.addEventNow({ + lat: point.lat(), + lng: point.lng(), + event_location: results[0].formatted_address, + start_date: scheduler._date, + end_date: scheduler.date.add(scheduler._date, 1, "hour") + }); + } } - } - ); - } + ); + } }); - + var infoWindowOptions = { content: '' }; @@ -93,304 +111,389 @@ scheduler.attachEvent("onTemplatesReady",function(){ if (scheduler.config.map_infowindow_max_width) { infoWindowOptions.maxWidth = scheduler.config.map_infowindow_max_width; } - + scheduler.map = { _points: [], _markers: [], _infowindow: new google.maps.InfoWindow(infoWindowOptions), _infowindows_content: [], - _initialization_count: -1 + _initialization_count: -1, + _obj: map }; - + geocoder = new google.maps.Geocoder(); - - if(scheduler.config.map_resolve_user_location) { - if(navigator.geolocation) { - if(!_isPositionSet) { + + if (scheduler.config.map_resolve_user_location) { + if (navigator.geolocation) { + if (!scheduler._isMapPositionSet) { navigator.geolocation.getCurrentPosition(function(position) { - var _userLocation = new google.maps.LatLng(position.coords.latitude,position.coords.longitude); + var _userLocation = new google.maps.LatLng(position.coords.latitude, position.coords.longitude); map.setCenter(_userLocation); - map.setZoom(scheduler.config.map_zoom_after_resolve||10); + map.setZoom(scheduler.config.map_zoom_after_resolve || 10); scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_success); scheduler.map._infowindow.position = map.getCenter(); scheduler.map._infowindow.open(map); - _isPositionSet = true; - }, - function() { - scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_fail); - scheduler.map._infowindow.setPosition(map.getCenter()); - scheduler.map._infowindow.open(map); - _isPositionSet = true; - }); + scheduler._isMapPositionSet = true; + }, + function() { + scheduler.map._infowindow.setContent(scheduler.locale.labels.marker_geo_fail); + scheduler.map._infowindow.setPosition(map.getCenter()); + scheduler.map._infowindow.open(map); + scheduler._isMapPositionSet = true; + }); } } } google.maps.event.addListener(map, "resize", function(event) { - gmap.style.zIndex='5'; - map.setZoom( map.getZoom() ); + gmap.style.zIndex = '5'; + map.setZoom(map.getZoom()); + }); google.maps.event.addListener(map, "tilesloaded", function(event) { - gmap.style.zIndex='5'; + gmap.style.zIndex = '5'; }); - } - _append_map(); - scheduler.attachEvent("onSchedulerResize",function(){ - if (this._mode == "map"){ - this.map_view(true); - } - }); - - var old = scheduler.render_data; - scheduler.render_data=function(evs,hold){ + gmap.style.display = 'none'; // property was changed after attaching map + })(); + + scheduler.attachEvent("onSchedulerResize", function() { if (this._mode == "map") { - fill_map_tab(); + this.map_view(true); + return false + } + return true; + }); + + var old = scheduler.render_data; + scheduler.render_data = function(evs, hold) { + if (this._mode == "map") { + fill_map_tab(); var events = scheduler.get_visible_events(); - for(var i=0; i
"+l.date+"
"+l.description+"
"; - scheduler._table_view=true; + scheduler._els["dhx_cal_header"][0].innerHTML = "
" + l.date + "
" + l.description + "
"; + scheduler._table_view = true; scheduler.set_sizes(); } } - function fill_map_tab(){ - //get current date - var date = scheduler._date; + function clear_map_tab() { + scheduler._selected_event_id = null; + scheduler.map._infowindow.close(); + for (var key in scheduler.map._markers) { + scheduler.map._markers[key].setMap(null); + delete scheduler.map._markers[key]; + if (scheduler.map._infowindows_content[key]) + delete scheduler.map._infowindows_content[key]; + } + } + + function fill_map_tab() { //select events for which data need to be printed var events = scheduler.get_visible_events(); - events.sort(function(a,b){ return a.start_date>b.start_date?1:-1; }); - + events.sort(function(a, b) { + if (a.start_date < b.start_date) + return -1; + if (a.start_date.valueOf() == b.start_date.valueOf()) { + if (a.text < b.text) + return -1 + else { + if (a.text == b.text) + return 0; + else + return 1; + } + } + else + return 1; + }); + //generate html for the view - var html="
"; - for (var i=0; i
"+scheduler.templates.map_time(events[i].start_date, events[i].end_date,events[i])+"
"; - html+="
 
"; - html+="
"+scheduler.templates.map_text(events[i])+"
"; // -25 = icon size 20 and padding 5 + var html = "
"; + for (var i = 0; i < events.length; i++) { + var ev = events[i]; + var event_class = (ev.id == scheduler._selected_event_id) ? 'dhx_map_line highlight' : 'dhx_map_line'; + var bg_color = (ev.color ? ("background-color:" + ev.color + ";") : ""); + var color = (ev.textColor ? ("color:" + ev.textColor + ";") : ""); + html += "
" + scheduler.templates.map_time(ev.start_date, ev.end_date, ev) + "
"; + html += "
 
"; + html += "
" + scheduler.templates.map_text(ev.start_date, ev.end_date, ev) + "
"; // -25 = icon size 20 and padding 5 } - html+="
"; - + html += "
"; + //render html scheduler._els["dhx_cal_data"][0].scrollTop = 0; //fix flickering in FF scheduler._els["dhx_cal_data"][0].innerHTML = html; scheduler._els["dhx_cal_data"][0].style.width = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px'; - - var t=scheduler._els["dhx_cal_data"][0].firstChild.childNodes; - scheduler._els["dhx_cal_date"][0].innerHTML=""; - - scheduler._rendered=[]; - for (var i=0; i < t.length-2; i++) { - scheduler._rendered[i]=t[i]; + + var t = scheduler._els["dhx_cal_data"][0].firstChild.childNodes; + scheduler._els["dhx_cal_date"][0].innerHTML = scheduler.templates[scheduler._mode + "_date"](scheduler._min_date, scheduler._max_date, scheduler._mode); + + scheduler._rendered = []; + for (var i = 0; i < t.length - 2; i++) { + scheduler._rendered[i] = t[i]; } - + } - + function _setMapSize(elem_id) { //input - map's div id var map = document.getElementById(elem_id); - map.style.height = (scheduler._y - scheduler.xy.nav_height) + 'px'; - map.style.width = (scheduler._x - scheduler.xy.map_date_width - scheduler.xy.map_description_width - 1) + 'px'; + var height = scheduler._y - scheduler.xy.nav_height; + if (height < 0) + height = 0; + var width = scheduler._x - scheduler.xy.map_date_width - scheduler.xy.map_description_width - 1; + if (width < 0) + width = 0; + map.style.height = height + 'px'; + map.style.width = width + 'px'; map.style.marginLeft = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px'; map.style.marginTop = (scheduler.xy.nav_height + 2) + 'px'; } - scheduler.map_view=function(mode){ + scheduler.map_view = function(mode) { scheduler.map._initialization_count++; var gmap = scheduler._els.dhx_gmap[0]; - scheduler._els.dhx_cal_data[0].style.width = (scheduler.xy.map_date_width + scheduler.xy.map_description_width + 1) + 'px'; - - scheduler._min_date = scheduler.config.map_start||(new Date()); - scheduler._max_date = scheduler.config.map_end||(new Date(9999,1,1)); + + scheduler._min_date = scheduler.config.map_start || (new Date()); + scheduler._max_date = scheduler.config.map_end || (new Date(9999, 1, 1)); + scheduler._table_view = true; set_full_view(mode); - - if (mode){ //map tab activated + + if (mode) { //map tab activated + clear_map_tab(); fill_map_tab(); gmap.style.display = 'block'; - + // need to resize block everytime window is resized _setMapSize('dhx_gmap'); - + var temp_center = scheduler.map._obj.getCenter(); + var events = scheduler.get_visible_events(); - for(var i=0; i scheduler._min_date) || (event.start_date < scheduler._max_date && event.end_date > scheduler._max_date) || (event.start_date.valueOf() >= scheduler._min_date && event.end_date.valueOf() <= scheduler._max_date)) { + if (scheduler.map._markers[event_id]) + scheduler.map._markers[event_id].setMap(null); + _displayEventOnMap(event); + } else { // event no longer should be displayed on the map view + scheduler._selected_event_id = null; + scheduler.map._infowindow.close(); + if (scheduler.map._markers[event_id]) + scheduler.map._markers[event_id].setMap(null); + } } + else + this._latLngUpdate = false; return true; - }); - - scheduler.attachEvent("onEventIdChange", function(old_event_id,new_event_id){ - if(scheduler.is_visible_events(scheduler.getEvent(new_event_id))) { - if(scheduler.map._markers[old_event_id]) scheduler.map._markers[old_event_id].setMap(null); - var event = scheduler.getEvent(new_event_id); + }); + + + scheduler.attachEvent("onEventIdChange", function(old_event_id, new_event_id) { + var event = scheduler.getEvent(new_event_id); + if ((event.start_date < scheduler._min_date && event.end_date > scheduler._min_date) || (event.start_date < scheduler._max_date && event.end_date > scheduler._max_date) || (event.start_date.valueOf() >= scheduler._min_date && event.end_date.valueOf() <= scheduler._max_date)) { + if (scheduler.map._markers[old_event_id]) { + scheduler.map._markers[old_event_id].setMap(null); + delete scheduler.map._markers[old_event_id]; + } + if (scheduler.map._infowindows_content[old_event_id]) + delete scheduler.map._infowindows_content[old_event_id]; _displayEventOnMap(event); } return true; }); - - /* Test/example - scheduler.attachEvent("onLocationError", function(event_id,event_object){ - return new google.maps.LatLng(8, 8); - }); - */ - - scheduler.attachEvent("onBeforeEventDelete", function(event_id,event_object){ - if (scheduler.map._markers[event_id]) { - scheduler.map._markers[event_id].setMap(null); // if new event is deleted tab != map then it doesn't have marker yet + + scheduler.attachEvent("onEventAdded", function(event_id, event_object) { + if (!scheduler._dataprocessor) { + if ((event_object.start_date < scheduler._min_date && event_object.end_date > scheduler._min_date) || (event_object.start_date < scheduler._max_date && event_object.end_date > scheduler._max_date) || (event_object.start_date.valueOf() >= scheduler._min_date && event_object.end_date.valueOf() <= scheduler._max_date)) { + if (scheduler.map._markers[event_id]) + scheduler.map._markers[event_id].setMap(null); + _displayEventOnMap(event_object); } - scheduler.map._infowindow.close(); - return true; - }); - - scheduler._event_resolve_delay = 500; - scheduler.attachEvent("onEventLoading", function(event){ - if(scheduler.config.map_resolve_event_location && event.event_location && !event.lat && !event.lng) { // don't delete !event.lat && !event.lng as location could change - scheduler._event_resolve_delay += 500; - _delay(_updateEventLocation,this,[event], scheduler._event_resolve_delay); } return true; - }); - - scheduler.attachEvent("onEventCancel", function(event_id, is_new){ - if(is_new) { - if(scheduler.map._markers[event_id]) + }); + + /* Test/example + scheduler.attachEvent("onLocationError", function(event_id,event_object){ + return new google.maps.LatLng(8, 8); + }); + */ + + scheduler.attachEvent("onBeforeEventDelete", function(event_id, event_object) { + if (scheduler.map._markers[event_id]) { + scheduler.map._markers[event_id].setMap(null); // if new event is deleted tab != map then it doesn't have marker yet + } + scheduler._selected_event_id = null; + scheduler.map._infowindow.close(); + return true; + }); + + scheduler._event_resolve_delay = 1500; + scheduler.attachEvent("onEventLoading", function(event) { + if (scheduler.config.map_resolve_event_location && event.event_location && !event.lat && !event.lng) { // don't delete !event.lat && !event.lng as location could change + scheduler._event_resolve_delay += 1500; + _delay(_updateEventLocation, this, [event], scheduler._event_resolve_delay); + } + return true; + }); + + scheduler.attachEvent("onEventCancel", function(event_id, is_new) { + if (is_new) { + if (scheduler.map._markers[event_id]) scheduler.map._markers[event_id].setMap(null); scheduler.map._infowindow.close(); } return true; - }); -}); \ No newline at end of file + }); +}); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_matrix.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_matrix.js index e36c6d68e75..07ea857c13f 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_matrix.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_matrix.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ (function(){ scheduler.matrix = {}; scheduler._merge=function(a,b){ @@ -24,6 +28,8 @@ scheduler.createTimelineView=function(obj){ render:"cell", dx:200, dy:50, + fit_events: true, + second_scale: false, _logic: function(render_name, y_unit, timeline) { var res = {}; if(scheduler.checkEvent("onBeforeViewRender")) { @@ -36,14 +42,10 @@ scheduler.createTimelineView=function(obj){ if (scheduler.checkEvent("onTimelineCreated")) { scheduler.callEvent("onTimelineCreated", [obj]); } - - //init custom wrappers - scheduler[obj.name+"_view"]=function(){ - scheduler.renderMatrix.apply(obj, arguments); - }; var old = scheduler.render_data; scheduler.render_data=function(evs, mode){ + if (this._mode == obj.name){ if (mode) //repaint single event, precision is not necessary for (var i=0; i < evs.length; i++) { @@ -58,20 +60,22 @@ scheduler.createTimelineView=function(obj){ scheduler.matrix[obj.name]=obj; scheduler.templates[obj.name+"_cell_value"] = function(ar){ return ar?ar.length:""; }; - scheduler.templates[obj.name+"_cell_class"] = function(ar){ return ""; }; - scheduler.templates[obj.name+"_scalex_class"] = function(ar){ return ""; }; + scheduler.templates[obj.name+"_cell_class"] = function(arr){ return ""; }; + scheduler.templates[obj.name+"_scalex_class"] = function(date){ return ""; }; + scheduler.templates[obj.name+"_second_scalex_class"] = function(date){ return ""; }; - scheduler.templates[obj.name+"_scaley_class"] = function(section_id, section_label, section_options){ return "class"; }; + scheduler.templates[obj.name+"_scaley_class"] = function(section_id, section_label, section_options){ return ""; }; scheduler.templates[obj.name+"_scale_label"] = function(section_id, section_label, section_options){ return section_label; }; scheduler.templates[obj.name+"_tooltip"] = function(a,b,e){ return e.text; }; scheduler.templates[obj.name+"_date"] = function(datea, dateb){ - if (datea.getDay()==dateb.getDay() && datea-dateb<(24*60*60*1000)) + if (datea.getDay()==dateb.getDay() && dateb-datea<(24*60*60*1000)) return scheduler.templates.day_date(datea); return scheduler.templates.week_date(datea, dateb); }; scheduler.templates[obj.name+"_scale_date"] = scheduler.date.date_to_str(obj.x_date||scheduler.config.hour_date); + scheduler.templates[obj.name+"_second_scale_date"] = scheduler.date.date_to_str((obj.second_scale && obj.second_scale.x_date)?obj.second_scale.x_date:scheduler.config.hour_date); scheduler.date["add_"+obj.name]=function(a,b,c){ return scheduler.date.add(a,(obj.x_length||obj.x_size)*b*obj.x_step,obj.x_unit); @@ -87,22 +91,27 @@ scheduler.createTimelineView=function(obj){ } return true; }); - + scheduler.attachEvent("onOptionsLoad",function(){ - obj.order = {}; - for(var i=0; i'+scheduler.templates.event_bar_text(ev.start_date,ev.end_date,ev)+''; + var html='
'+scheduler.templates.event_bar_text(ev.start_date,ev.end_date,ev)+'
'; if (!attach) return html; else { var d = document.createElement("DIV"); d.innerHTML = html; - - var ind = this.order[ev[this.y_property]]; + var ind = this.order[section]; var parent = scheduler._els["dhx_cal_data"][0].firstChild.rows[ind].cells[1].firstChild; scheduler._rendered.push(d.firstChild); @@ -181,15 +198,13 @@ scheduler.render_timeline_event = function(ev, stack, attach){ } }; - function trace_events(){ //minimize event set - var evs = scheduler.getEvents(scheduler._min_date, scheduler._max_date); + var evs = scheduler.get_visible_events(); var matrix =[]; for (var i=0; i < this.y_unit.length; i++) matrix[i]=[]; - //next code defines row for undefined key //most possible it is an artifact of incorrect configuration if (!matrix[y]) @@ -233,15 +248,15 @@ function _getX(ev, isEndPoint, step) { } -function y_scale(d){ - +function y_scale(d){ var html = ""; var evs=[]; - if (scheduler._load_mode && scheduler._load()) return; + if(scheduler._load_mode) + scheduler._load(); if (this.render == "cell") evs = trace_events.call(this); else { - var tevs = scheduler.getEvents(scheduler._min_date, scheduler._max_date); + var tevs = scheduler.get_visible_events(); for (var j=0; jb.start_date?1:-1; }); + var stack=[]; + for (var j=0; j ev.start_date) + stack_pointer++; + stack[stack_pointer]=ev; + //render line + + events_html+=scheduler.render_timeline_event.call(this, ev, stack_pointer); + } + } + + if(this.fit_events){ + var rendered_height = this._events_height[this.y_unit[i].key]||0; + stats.height = (rendered_height>stats.height)?rendered_height:stats.height; + stats.style_height = "height:"+stats.height+"px;"; + } // section 1 - html+=""; + html+=""; if (this.render == "cell"){ for (var j=0; j < scheduler._cols.length; j++) { - html+=""; + html+=""; } } else { //section 2 html+=""; } @@ -329,7 +356,7 @@ function y_scale(d){ } html += "
"+stats.td_content+"
"+stats.td_content+"
"+scheduler.templates[this.name+"_cell_value"](evs[i][j])+"
"+scheduler.templates[this.name+"_cell_value"](evs[i][j])+"
"; - if (evs[i]){ - evs[i].sort(function(a,b){ return a.start_date>b.start_date?1:-1; }); - var stack=[]; - for (var j=0; j ev.start_date) - stack_pointer++; - stack[stack_pointer]=ev; - //render line - - html+=scheduler.render_timeline_event.call(this, ev, stack_pointer); - } - } //section 3 html+=""; for (var j=0; j < scheduler._cols.length; j++) - html+=""; + html+=""; html+="
"; html+="
"; this._matrix = evs; - d.scrollTop = 0; //fix flickering in FF + //d.scrollTop = 0; //fix flickering in FF; disabled as it was impossible to create dnd event if scroll was used (window jumped to the top) d.innerHTML = html; scheduler._rendered = []; @@ -343,35 +370,82 @@ function y_scale(d){ } function x_scale(h){ - h.innerHTML = "
"; h=h.firstChild; - - scheduler._cols=[]; //store for data section - scheduler._colsS={height:0}; - this._trace_x =[]; - - scheduler._min_date_timeline = scheduler._min_date; - - var start = scheduler._min_date; - var summ = scheduler._x-this.dx-18; //border delta + var current_sh = scheduler.xy.scale_height; + var original_sh = this._header_resized||scheduler.xy.scale_height; + scheduler._cols=[]; //store for data section, each column width + scheduler._colsS={height:0}; // heights of the y sections + this._trace_x =[]; // list of dates per cells + var summ = scheduler._x-this.dx-18; //border delta, whole width + var left = [this.dx]; // left margins, initial left margin + var header = scheduler._els['dhx_cal_header'][0]; + header.style.width = (left[0]+summ)+'px'; + + scheduler._min_date_timeline = scheduler._min_date; - var left = this.dx; - - for (var i=0; i"; + var bg_color = (evs[i].color?("background-color:"+evs[i].color+";"):""); + var color = (evs[i].textColor?("color:"+evs[i].textColor+";"):""); + html+="
"; html+="
"+(evs[i]._timed?scheduler.templates.event_date(evs[i].start_date):"")+"
"; html+="
 
"; html+=scheduler.templates[obj.name+"_tooltip"](evs[i].start_date, evs[i].end_date,evs[i])+"
"; @@ -467,10 +557,24 @@ function _init_matrix_tooltip(){ } scheduler.renderMatrix = function(mode){ + scheduler._els['dhx_cal_data'][0].scrollTop=0; var start_date = scheduler.date[this.name+"_start"](scheduler._date); scheduler._min_date = scheduler.date.add(start_date, this.x_start*this.x_step, this.x_unit); scheduler._max_date = scheduler.date.add(scheduler._min_date, this.x_size*this.x_step, this.x_unit); scheduler._table_view = true; + if(this.second_scale) { + if(mode && !this._header_resized) { + this._header_resized = scheduler.xy.scale_height; + scheduler.xy.scale_height *= 2; + scheduler._els['dhx_cal_header'][0].className += " dhx_second_cal_header"; + } + if(!mode && this._header_resized) { + scheduler.xy.scale_height /= 2; + this._header_resized = false; + var header = scheduler._els['dhx_cal_header'][0]; + header.className = header.className.replace(/ dhx_second_cal_header/gi,""); + } + } set_full_view.call(this,mode); }; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_minical.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_minical.js index d978ec53bb8..a6a02b96445 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_minical.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_minical.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.templates.calendar_month = scheduler.date.date_to_str("%F %Y"); scheduler.templates.calendar_scale_date = scheduler.date.date_to_str("%D"); scheduler.templates.calendar_date = scheduler.date.date_to_str("%d"); @@ -25,7 +29,7 @@ scheduler.renderCalendar=function(obj, _prev){ top:tpos.top + pos.offsetHeight, left:tpos.left }; - }; + } if (!cont) cont = scheduler._get_def_cont(pos); @@ -50,7 +54,7 @@ scheduler.renderCalendar=function(obj, _prev){ cal = this._render_calendar(_prev.parentNode, date, obj, _prev); scheduler.unmarkCalendar(cal); } - + var start = scheduler.date.month_start(date); var end = scheduler.date.add(start,1,"month"); @@ -60,7 +64,8 @@ scheduler.renderCalendar=function(obj, _prev){ var d = ev.start_date; if (d.valueOf()=end.valueOf()) @@ -68,6 +73,8 @@ scheduler.renderCalendar=function(obj, _prev){ } } + + this._markCalendarCurrentDate(cal); cal.conf = obj; @@ -145,7 +152,7 @@ scheduler._render_calendar=function(obj,sd,conf, previous){ if (previous) d = previous; else { - var d = document.createElement("DIV"); + d = document.createElement("DIV"); d.className="dhx_cal_container dhx_mini_calendar"; } d.setAttribute("date",this.templates.xml_format(sd)); @@ -160,6 +167,9 @@ scheduler._render_calendar=function(obj,sd,conf, previous){ d.firstChild.appendChild(arrow); arrow.onclick=function(){ scheduler.updateCalendar(d, scheduler.date.add(d._date, -1, "month")); + if(scheduler._date.getMonth() == d._date.getMonth() && scheduler._date.getFullYear() == d._date.getFullYear()) { + scheduler._markCalendarCurrentDate(d); + } }; arrow = document.createElement("DIV"); @@ -169,10 +179,14 @@ scheduler._render_calendar=function(obj,sd,conf, previous){ d.firstChild.appendChild(arrow); arrow.onclick=function(){ scheduler.updateCalendar(d, scheduler.date.add(d._date, 1, "month")); + if(scheduler._date.getMonth() == d._date.getMonth() && scheduler._date.getFullYear() == d._date.getFullYear()) { + scheduler._markCalendarCurrentDate(d); + } }; - d._date = new Date(sd); + } - + d._date = new Date(sd); + d.week_start = (sd.getDay()-(this.config.start_on_monday?1:0)+7)%7; var dd = this.date.week_start(sd); @@ -180,14 +194,20 @@ scheduler._render_calendar=function(obj,sd,conf, previous){ var r=d.childNodes[2].firstChild.rows; for (var k=r.length; k<6; k++) { - r[0].parentNode.appendChild(r[0].cloneNode(true)); + var last_row = r[r.length-1]; + r[0].parentNode.appendChild(last_row.cloneNode(true)); + var last_day_number = parseInt(last_row.childNodes[last_row.childNodes.length-1].childNodes[0].innerHTML); + last_day_number = (last_day_number<10)?last_day_number:0; // previous week could end on 28-31, so we should start with 0 for (var ri=0; ri < r[k].childNodes.length; ri++) { r[k].childNodes[ri].className = "dhx_after"; - }; + r[k].childNodes[ri].childNodes[0].innerHTML = scheduler.date.to_fixed(++last_day_number); + } } if (!previous) obj.appendChild(d); + + d.childNodes[1].style.height = (d.childNodes[1].childNodes[0].offsetHeight-1)+"px"; // dhx_year_week should have height property so that day dates would get correct position. dhx_year_week height = height of it's child (with the day name) /*restore*/ this._cols=temp; this._mode = temp2; this._colsS = temp3; this._min_date=temp4; this._max_date=temp5; scheduler._date = temp6; ts.month_day=temp7; return d; @@ -235,7 +255,7 @@ scheduler.form_blocks.calendar_time={ var full_day = scheduler.config.full_day; - return "
"+html+"  –  "+html+"
"; + return "
"+html+"  –  "+html+"
"; }, set_value:function(node,value,ev){ @@ -253,7 +273,7 @@ scheduler.form_blocks.calendar_time={ inp.value = scheduler.templates.calendar_time(new_date); inp._date = new Date(new_date); scheduler.destroyCalendar(); - if(scheduler.config.event_duration && number == 0) { //first element = start date + if(scheduler.config.event_duration && scheduler.config.auto_end_date && number == 0) { //first element = start date _update_minical_select(); } } @@ -263,7 +283,10 @@ scheduler.form_blocks.calendar_time={ if(scheduler.config.full_day) { if (!node._full_day){ - node.previousSibling.innerHTML+="
"; + var html = ""; + if (!scheduler.config.wide_form) + html = node.previousSibling.innerHTML+html; + node.previousSibling.innerHTML=html; node._full_day=true; } var input=node.previousSibling.getElementsByTagName("input")[0]; @@ -272,7 +295,7 @@ scheduler.form_blocks.calendar_time={ input.checked = isFulldayEvent; for(var i in selects) selects[i].disabled=input.checked; - for(var i=0; i0) - continue; - scheduler.markCalendar(calendar, dateNew, "dhx_calendar_click"); - dateNew = scheduler.date.add(dateNew,1,"day"); - } - } - } return true; }; @@ -375,4 +380,23 @@ scheduler.linkCalendar=function(calendar, datediff){ scheduler.attachEvent("onEventChanged", action); scheduler.attachEvent("onAfterEventDelete", action); action(); -}; \ No newline at end of file +}; + +scheduler._markCalendarCurrentDate = function(calendar) { + var date = scheduler._date; + var mode = scheduler._mode; + + if(calendar._date.getMonth() == date.getMonth() && calendar._date.getFullYear() == date.getFullYear()) { + if (mode == 'day' || (this._props && !!this._props[mode])) { + scheduler.markCalendar(calendar,date, "dhx_calendar_click"); + } else if (mode == 'week') { + var dateNew = scheduler.date.week_start(new Date(date.valueOf())); + for (var i = 0; i < 7; i++) { + var diff = dateNew.getMonth() + dateNew.getYear()*12 - date.getMonth() - date.getYear()*12; + if (!diff) + scheduler.markCalendar(calendar, dateNew, "dhx_calendar_click"); + dateNew = scheduler.date.add(dateNew,1,"day"); + } + } + } +}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_monthheight.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_monthheight.js index 52060ffdde4..6b86b7524d2 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_monthheight.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_monthheight.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.attachEvent("onTemplatesReady",function(){ scheduler.xy.scroll_width = 0; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multiselect.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multiselect.js index 98b14168996..2890d0180a6 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multiselect.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multiselect.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.form_blocks["multiselect"]={ render:function(sns) { var _result = "
"; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multisource.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multisource.js index 0773d264e2c..2205f0553a0 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multisource.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_multisource.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ (function(){ function backup(obj){ diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_offline.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_offline.js new file mode 100644 index 00000000000..f9e5f946476 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_offline.js @@ -0,0 +1,102 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler._extra_xle = false; // flag if we are calling xle once again (we don't want to get into loop with scheduler.parse) +scheduler.attachEvent("onXLE", function(){ + if(!scheduler._extra_xle){ + var isEventsLoaded = false; + for(var key in scheduler._events){ + if(scheduler._events[key].text) { + isEventsLoaded = true; + break; + } + } + if((localStorage._updated_events || !isEventsLoaded) && localStorage._events) { + scheduler._extra_xle = true; + scheduler.parse(localStorage._events, "json"); + scheduler._extra_xle = false; + var dp = scheduler._dataprocessor; + var updatedEvents = JSON.parse(localStorage._updated_events); + dp.setUpdateMode("off"); + for(var id in updatedEvents) + dp.setUpdated(id,true,updatedEvents[id]); + dp.sendData(); + dp.setUpdateMode("cell"); + } + } +}); +scheduler.attachEvent("onBeforeEventDelete", function(id, object){ + var status = scheduler._dataprocessor.getState(id); + if(status == 'inserted' && localStorage._updated_events) { + var updated_events = JSON.parse(localStorage._updated_events); + delete updated_events[id]; + for(var id in updated_events){ + localStorage._updated_events = JSON.stringify(updated_events); + break; + } + } + return true; +}); + +var old_delete_event = scheduler.deleteEvent; +scheduler.deleteEvent = function(id, silent){ + old_delete_event.apply(this, arguments); + localStorage._events = scheduler.toJSON(); +}; + +scheduler._offline = {}; +scheduler._offline._after_update_events = []; + +var old_dp_init = scheduler._dp_init; +scheduler._dp_init = function(dp){ + old_dp_init.apply(this, arguments); + + dp.attachEvent("onAfterUpdate",function(sid,action,tid,xml_node){ + scheduler._offline._after_update_events.push(sid); + return true; + }); + dp.attachEvent("onAfterUpdateFinish",function(sid,action,tid,xml_node){ + localStorage._events = scheduler.toJSON(); + var updated_events = JSON.parse(localStorage._updated_events); + for(var i=0; i]*>","g"); + function clean_html(val){ + return val.replace(html_regexp,""); + } function x_norm(x) { x = parseFloat(x); if (isNaN(x)) return "auto"; - return 100 * x / dx; + return 100 * x / (dx + 1); } function y_norm(y) { y = parseFloat(y); @@ -21,8 +28,10 @@ scheduler.toPDF=function(url,mode,header,footer){ } function xml_month_scale(xh){ var xml=""; + if (scheduler.matrix && scheduler.matrix[scheduler._mode]) + xh = xh[0].childNodes; for (var i = 0; i < xh.length; i++) - xml += "\n"; + xml += "\n"; dx = xh[0].offsetWidth; return xml; } @@ -56,7 +65,7 @@ scheduler.toPDF=function(url,mode,header,footer){ days.push(r[i].cells[j].firstChild.innerHTML); } - xml += "\n"; + xml += "\n"; dy = yh.firstChild.rows[0].cells[0].offsetHeight; } return xml; @@ -73,11 +82,11 @@ scheduler.toPDF=function(url,mode,header,footer){ if (scheduler._mode == "agenda"){ var xh = scheduler._els.dhx_cal_header[0].childNodes[0].childNodes; - xml+=""+xh[0].innerHTML+""+xh[1].innerHTML+"" + xml+=""+clean_html(xh[0].innerHTML)+""+clean_html(xh[1].innerHTML)+"" } else if (scheduler._mode == "year"){ var xh = scheduler._els.dhx_cal_data[0].childNodes; for (var i=0; i < xh.length; i++) { - xml+=""; + xml+=""; xml+=xml_month_scale(xh[i].childNodes[1].childNodes); xml+=xml_month(xh[i].childNodes[2]); xml+=""; @@ -89,7 +98,14 @@ scheduler.toPDF=function(url,mode,header,footer){ xml += ""; var yh = scheduler._els.dhx_cal_data[0]; - if (yh.firstChild.tagName == "TABLE") { + if (scheduler.matrix && scheduler.matrix[scheduler._mode]) { + xml += "" + for (var i=0; i < yh.firstChild.rows.length; i++) { + xml+=""; + }; + xml+=""; + dy = yh.firstChild.rows[0].cells[0].offsetHeight; + } else if (yh.firstChild.tagName == "TABLE") { xml += xml_month(yh); } else { yh = yh.childNodes[yh.childNodes.length - 1]; @@ -99,7 +115,7 @@ scheduler.toPDF=function(url,mode,header,footer){ xml += ""; for (var i = 0; i < yh.length; i++) - xml += "\n"; + xml += "\n"; xml += ""; dy = yh[0].offsetHeight; } @@ -117,7 +133,7 @@ scheduler.toPDF=function(url,mode,header,footer){ if (scheduler._mode == "agenda"){ for (var i=0; i < evs.length; i++) - xml+=""+evs[i].childNodes[0].innerHTML+""+evs[i].childNodes[2].innerHTML+""; + xml+=""+clean_html(evs[i].childNodes[0].innerHTML)+""+clean_html(evs[i].childNodes[2].innerHTML)+""; } else if (scheduler._mode == "year"){ var evs = scheduler.get_visible_events(); for (var i=0; i < evs.length; i++) { @@ -129,7 +145,6 @@ scheduler.toPDF=function(url,mode,header,footer){ var day = scheduler.week_starts[m]+d.getDate()-1; xml+=""; - scheduler._mark_year_date(d); d = scheduler.date.add(d,1,"day"); if (d.valueOf()>=scheduler._max_date.valueOf()) break; @@ -138,21 +153,32 @@ scheduler.toPDF=function(url,mode,header,footer){ } else { for (var i = 0; i < evs.length; i++) { var zx = x_norm(evs[i].style.left); - var zy = y_norm(evs[i].style.top); var zdx = x_norm(evs[i].style.width); + var zy = y_norm(evs[i].style.top); var zdy = y_norm(evs[i].style.height); var e_type = evs[i].className.split(" ")[0].replace("dhx_cal_", ""); var dets = scheduler.getEvent(evs[i].getAttribute("event_id")) var day = dets._sday; var week = dets._sweek; if (scheduler._mode != "month") { - if (parseInt(evs[i].style.left) <= 26) { - zx = 2; - zdx += x_norm(evs[i].style.left)-1; - } - if (evs[i].parentNode == scheduler._els.dhx_cal_data[0]) continue; - zx += x_norm(evs[i].parentNode.style.left); - zx -= x_norm(51); + if (scheduler.matrix && scheduler.matrix[scheduler._mode]){ + day = 0; + week = evs[i].parentNode.parentNode.parentNode.rowIndex; + zdx += x_norm(10); + } else { + zdx+=x_norm(zdx*20/100); + zx-=x_norm(20-zx*20/100); + + if (evs[i].parentNode == scheduler._els.dhx_cal_data[0]) continue; + zx += x_norm(evs[i].parentNode.style.left); + zx -= x_norm(51); + } + if (scheduler._mode == "timeline") { + var dy_copy = dy; + dy = 180; + zy = y_norm(evs[i].style.top); + dy = dy_copy; + } } else { zdy = parseInt(evs[i].offsetHeight); zy = parseInt(evs[i].style.top) - 22; @@ -165,14 +191,14 @@ scheduler.toPDF=function(url,mode,header,footer){ if (e_type == "event") { - xml += "
"; + xml += "
"; var text_color = colors?get_style(evs[i].childNodes[2],"color"):""; var bg_color = colors?get_style(evs[i].childNodes[2],"backgroundColor"):""; - xml += ""; + xml += ""; } else { var text_color = colors?get_style(evs[i],"color"):""; var bg_color = colors?get_style(evs[i],"backgroundColor"):""; - xml += ""; + xml += ""; } xml += ""; } @@ -189,7 +215,7 @@ scheduler.toPDF=function(url,mode,header,footer){ d.style.display="none"; document.body.appendChild(d); - d.innerHTML = '
'; + d.innerHTML = '
'; document.getElementById(uid).firstChild.value = xml_top(mode).replace("\u2013", "-") + xml_body() + xml_end(); document.getElementById(uid).submit(); d.parentNode.removeChild(d);grid = null; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_readonly.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_readonly.js index b11c4fe8048..9bd1df9d859 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_readonly.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_readonly.js @@ -1,100 +1,111 @@ -scheduler.attachEvent("onTemplatesReady",function(){ - scheduler.attachEvent("onBeforeLightbox",function(id){ - if (this.config.readonly_form || this.getEvent(id).readonly) - this.config.readonly_active = true; - else { - this.config.readonly_active = false; - return true; - } - - for (var i=0; i < this.config.lightbox.sections.length; i++) { - this.config.lightbox.sections[i].focus = false; - }; - - return true; - }); - - function txt_replace(tag,d,n,text){ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.attachEvent("onTemplatesReady", function() { + scheduler.attachEvent("onBeforeLightbox", function(id) { + if (this.config.readonly_form || this.getEvent(id).readonly) + this.config.readonly_active = true; + else { + this.config.readonly_active = false; + return true; + } + + for (var i = 0; i < this.config.lightbox.sections.length; i++) { + this.config.lightbox.sections[i].focus = false; + } + + return true; + }); + + function txt_replace(tag, d, n, text) { var txts = d.getElementsByTagName(tag); var txtt = n.getElementsByTagName(tag); - for (var i=txtt.length-1; i>=0; i--){ + for (var i = txtt.length - 1; i >= 0; i--) { var n = txtt[i]; if (!text) n.disabled = true; else { var t = document.createElement("SPAN"); t.className = "dhx_text_disabled"; - t.innerHTML=text(txts[i]); - n.parentNode.insertBefore(t,n); - n.parentNode.removeChild(n); + t.innerHTML = text(txts[i]); + n.parentNode.insertBefore(t, n); + n.parentNode.removeChild(n); } } } - - var old = scheduler._fill_lightbox; - scheduler._fill_lightbox=function(){ - var sns = this.config.lightbox.sections; - if (this.config.readonly_active){ - for (var i=0; i < sns.length; i++) { - if (sns[i].type == 'recurring') { - var s = document.getElementById(sns[i].id); - s.style.display=s.nextSibling.style.display='none'; - sns.splice(i,1); - i--; - } - }; - } - - var res = old.apply(this,arguments); - if (this.config.readonly_active){ - - var d = this._get_lightbox(); - var n = this._lightbox_r = d.cloneNode(true); - - txt_replace("textarea",d,n,function(a){ return a.value; }); - txt_replace("input",d,n,false); - txt_replace("select",d,n,function(a){ return a.options[Math.max((a.selectedIndex||0),0)].text; }); - - n.removeChild(n.childNodes[2]); - n.removeChild(n.childNodes[3]); - - d.parentNode.insertBefore(n,d); - - olds.call(this,n); - this._lightbox = n; - this.setLightboxSize(); - this._lightbox = null; - n.onclick=function(e){ - var src=e?e.target:event.srcElement; - if (!src.className) src=src.previousSibling; - if (src && src.className) - switch(src.className){ - case "dhx_cancel_btn": - scheduler.callEvent("onEventCancel",[scheduler._lightbox_id]); - scheduler._edit_stop_event(scheduler.getEvent(scheduler._lightbox_id),false); - scheduler.hide_lightbox(); - break; - } - }; - } - return res; - }; - - var olds = scheduler.showCover; - scheduler.showCover=function(){ - if (!this.config.readonly_active) - olds.apply(this,arguments); + + var old = scheduler._fill_lightbox; + scheduler._fill_lightbox = function() { + var sns = this.config.lightbox.sections; + if (this.config.readonly_active) { + for (var i = 0; i < sns.length; i++) { + if (sns[i].type == 'recurring') { + var s = document.getElementById(sns[i].id); + s.style.display = s.nextSibling.style.display = 'none'; + sns.splice(i, 1); + i--; + } + } + } + + var res = old.apply(this, arguments); + + if (this.config.readonly_active) { + + var d = this._get_lightbox(); + var n = this._lightbox_r = d.cloneNode(true); + n.id = scheduler.uid(); + n.style.color = "red"; + + txt_replace("textarea", d, n, function(a) { + return a.value; + }); + txt_replace("input", d, n, false); + txt_replace("select", d, n, function(a) { + return a.options[Math.max((a.selectedIndex || 0), 0)].text; + }); + + n.removeChild(n.childNodes[2]); + n.removeChild(n.childNodes[3]); + + d.parentNode.insertBefore(n, d); + + olds.call(this, n); + if (scheduler._lightbox) + scheduler._lightbox.parentNode.removeChild(scheduler._lightbox); + this._lightbox = n; + this.setLightboxSize(); + this._lightbox = null; + n.onclick = function(e) { + var src = e ? e.target : event.srcElement; + if (!src.className) src = src.previousSibling; + if (src && src.className) + switch (src.className) { + case "dhx_cancel_btn": + scheduler.callEvent("onEventCancel", [scheduler._lightbox_id]); + scheduler._edit_stop_event(scheduler.getEvent(scheduler._lightbox_id), false); + scheduler.hide_lightbox(); + break; + } + }; + } + return res; }; - - var hold = scheduler.hide_lightbox; - scheduler.hide_lightbox=function(){ - if (this._lightbox_r){ - this._lightbox_r.parentNode.removeChild(this._lightbox_r); - this._lightbox_r = null; - } - - return hold.apply(this,arguments); - }; - - -}); \ No newline at end of file + + var olds = scheduler.showCover; + scheduler.showCover = function() { + if (!this.config.readonly_active) + olds.apply(this, arguments); + }; + + var hold = scheduler.hide_lightbox; + scheduler.hide_lightbox = function() { + if (this._lightbox_r) { + this._lightbox_r.parentNode.removeChild(this._lightbox_r); + this._lightbox_r = null; + } + + return hold.apply(this, arguments); + }; +}); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_serialize.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_serialize.js index 879ab661c62..9d19f520861 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_serialize.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_serialize.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ //redefine this method, if you want to provide a custom set of attributes for serialization scheduler.data_attributes=function(){ var attrs = []; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_tooltip.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_tooltip.js index 2146c8f9414..512cafebd5f 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_tooltip.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_tooltip.js @@ -1,4 +1,8 @@ -window.dhtmlXTooltip={version:0.1}; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +window.dhtmlXTooltip={}; dhtmlXTooltip.config = { className: 'dhtmlXTooltip tooltip', @@ -11,64 +15,77 @@ dhtmlXTooltip.tooltip = document.createElement('div'); dhtmlXTooltip.tooltip.className = dhtmlXTooltip.config.className; dhtmlXTooltip.show = function(event, text) { //browser event, text to display - dhtmlXTooltip.tooltip.className = dhtmlXTooltip.config.className; + var dhxTooltip = dhtmlXTooltip; + var tooltip_div = this.tooltip; + var tooltip_div_style = tooltip_div.style; + dhxTooltip.tooltip.className = dhxTooltip.config.className; var pos=this.position(event); - + var target = event.target||event.srcElement; if (this.isTooltip(target)) {return;} // if we are over tooltip -- do nothing, just return (so tooltip won't move) - var actual_x = pos.x+dhtmlXTooltip.config.delta_x||0; - var actual_y = pos.y-dhtmlXTooltip.config.delta_y||0; + var offsetleft = 0; + var offsettop = 0; + var pobj = scheduler._obj; + if(pobj.offsetParent) { + do { + offsetleft += pobj.offsetLeft; + offsettop += pobj.offsetTop; + } while (pobj = pobj.offsetParent); + } - this.tooltip.style.visibility = "hidden"; + var actual_x = pos.x + (dhxTooltip.config.delta_x||0) - offsetleft; + var actual_y = pos.y - (dhxTooltip.config.delta_y||0) - offsettop; - if(this.tooltip.style.removeAttribute) { - this.tooltip.style.removeAttribute("right"); - this.tooltip.style.removeAttribute("bottom"); + tooltip_div_style.visibility = "hidden"; + + if(tooltip_div_style.removeAttribute) { + tooltip_div_style.removeAttribute("right"); + tooltip_div_style.removeAttribute("bottom"); } else { - this.tooltip.style.removeProperty("right"); - this.tooltip.style.removeProperty("bottom"); + tooltip_div_style.removeProperty("right"); + tooltip_div_style.removeProperty("bottom"); } - this.tooltip.style.left = "0px"; - this.tooltip.style.top = "0px"; + tooltip_div_style.left = "0"; + tooltip_div_style.top = "0"; this.tooltip.innerHTML = text; scheduler._obj.appendChild(this.tooltip); var tooltip_width = this.tooltip.offsetWidth; var tooltip_height = this.tooltip.offsetHeight; - - if (document.body.offsetWidth - actual_x - tooltip_width < 0) { // tooltip is out of the right page bound - if(this.tooltip.style.removeAttribute) - this.tooltip.style.removeAttribute("left"); + + if ((scheduler._obj.offsetWidth - actual_x - (scheduler.xy.margin_left||0) - tooltip_width) < 0) { // tooltip is out of the right page bound + if(tooltip_div_style.removeAttribute) + tooltip_div_style.removeAttribute("left"); else - this.tooltip.style.removeProperty("left"); - this.tooltip.style.right = (document.body.offsetWidth - actual_x + 2 * dhtmlXTooltip.config.delta_x||0) + "px"; + tooltip_div_style.removeProperty("left"); + tooltip_div_style.right = (scheduler._obj.offsetWidth - actual_x + 2 * (dhxTooltip.config.delta_x||0)) + "px"; } else { if (actual_x < 0) { // tooltips is out of the left page bound - this.tooltip.style.left = (pos.x + Math.abs(dhtmlXTooltip.config.delta_x||0)) + "px"; + tooltip_div_style.left = (pos.x + Math.abs(dhxTooltip.config.delta_x||0)) + "px"; } else { // normal situation - this.tooltip.style.left = actual_x + "px"; + tooltip_div_style.left = actual_x + "px"; } } - - if (document.body.offsetHeight - actual_y - tooltip_height < 0) { // tooltip is below bottom of the page - if(this.tooltip.style.removeAttribute) - this.tooltip.style.removeAttribute("top"); + + if ((scheduler._obj.offsetHeight - actual_y - (scheduler.xy.margin_top||0) - tooltip_height) < 0) { // tooltip is below bottom of the page + if(tooltip_div_style.removeAttribute) + tooltip_div_style.removeAttribute("top"); else - this.tooltip.style.removeProperty("top"); - this.tooltip.style.bottom = (document.body.offsetHeight - actual_y - 2 * dhtmlXTooltip.config.delta_y||0) + "px"; + tooltip_div_style.removeProperty("top"); + tooltip_div_style.bottom = (scheduler._obj.offsetHeight - actual_y - 2 * (dhxTooltip.config.delta_y||0)) + "px"; } else { if (actual_y < 0) { // tooltip is higher then top of the page - this.tooltip.style.top = (pos.y + Math.abs(dhtmlXTooltip.config.delta_y||0)) + "px"; + tooltip_div_style.top = (pos.y + Math.abs(dhxTooltip.config.delta_y||0)) + "px"; } else { // normal situation - this.tooltip.style.top = actual_y + "px"; + tooltip_div_style.top = actual_y + "px"; } } - this.tooltip.style.visibility = "visible"; + tooltip_div_style.visibility = "visible"; }; dhtmlXTooltip.hide = function() { @@ -82,7 +99,7 @@ dhtmlXTooltip.delay = function(method, object, params, delay) { } this.tooltip._timeout_id = setTimeout(function(){ var ret = method.apply(object,params); - method = obj = params = null; + method = object = params = null; return ret; },delay||this.config.timeout_to_display); }; @@ -97,7 +114,7 @@ dhtmlXTooltip.isTooltip = function(node){ }; dhtmlXTooltip.position = function(ev) { - var ev = ev || window.event; + ev = ev || window.event; if(ev.pageX || ev.pageY) //FF, KHTML return {x:ev.pageX, y:ev.pageY}; //IE @@ -109,25 +126,35 @@ dhtmlXTooltip.position = function(ev) { }; scheduler.attachEvent("onMouseMove", function(event_id, e){ // (scheduler event_id, browser event) - var ev = e||window.event; + var ev = window.event||e; var target = ev.target||ev.srcElement; + var dhxTooltip = dhtmlXTooltip; - if (event_id || dhtmlXTooltip.isTooltip(target)) { // if we are over event or tooltip - var event = scheduler.getEvent(event_id) || scheduler.getEvent(dhtmlXTooltip.tooltip.event_id); - dhtmlXTooltip.tooltip.event_id = event.id; + if (event_id || dhxTooltip.isTooltip(target)) { // if we are over event or tooltip + var event = scheduler.getEvent(event_id) || scheduler.getEvent(dhxTooltip.tooltip.event_id); + if(!event) + return; + dhxTooltip.tooltip.event_id = event.id; var text = scheduler.templates.tooltip_text(event.start_date, event.end_date, event); - if (_isIE) { //make a copy of event, will be used in timed call - var evt = document.createEventObject(ev); + var evt = undefined; + if (_isIE) { //make a copy of event, will be used in timed call + evt = document.createEventObject(ev); } - - dhtmlXTooltip.delay(dhtmlXTooltip.show, dhtmlXTooltip, [ evt||ev , text]); // showing tooltip + + dhxTooltip.delay(dhxTooltip.show, dhxTooltip, [(evt||ev), text]); // showing tooltip } else { - dhtmlXTooltip.delay(dhtmlXTooltip.hide, dhtmlXTooltip, []); + dhxTooltip.delay(dhxTooltip.hide, dhxTooltip, []); } }); +scheduler.attachEvent("onBeforeDrag", function(){ + dhtmlXTooltip.hide(); + return true; +}); /* Could be redifined */ +scheduler.templates.tooltip_date_format=scheduler.date.date_to_str("%Y-%m-%d %H:%i"); + scheduler.templates.tooltip_text = function(start,end,event) { return "Event: "+event.text+"
Start date: "+scheduler.templates.tooltip_date_format(start)+"
End date: "+scheduler.templates.tooltip_date_format(end); -}; \ No newline at end of file +}; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_touch.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_touch.js deleted file mode 100644 index 9dde6fd89b4..00000000000 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_touch.js +++ /dev/null @@ -1,411 +0,0 @@ -TouchScroll=function(node, nontouch, scroll, compat){ - this.debug = !!nontouch; - this.compat = !!compat; - this.rough = !!scroll; - - - this.axisX = this.axisY = true; - - if (typeof node!= "object") - node = document.getElementById(node); - - this._init(); - node.addEventListener("touchstart",this,false); - node.addEventListener("webkitTransitionEnd",this,false); - if (this.debug) - node.addEventListener("mousedown",this,false); - - - this.node = node; - for (var i=0; i < node.childNodes.length; i++) - if (node.childNodes[i].nodeType == 1){ - this.area = node.childNodes[i]; - break; - } - - if (window.getComputedStyle(this.node).position == "static") - this.node.style.position = "relative" - this.area.style.cssText += "-webkit-transition: -webkit-transform; -webkit-user-select:none; -webkit-transform-style:preserve-3d;"; - this.scrolls={}; -}; - -TouchScroll.prototype = { - refresh:function(){ - this.node.style.webkitTransformStyle="flat"; - this.node.style.webkitTransformStyle="preserve-3d"; - }, - scrollTo:function(x,y,speed){ - this.set_matrix({e:x,f:y}, (speed||0)); - }, - onscroll:function(x,y){}, - handleEvent:function(ev){ - return this["ev_"+ev.type](ev); - }, - get_matrix:function(node){ - return new WebKitCSSMatrix(window.getComputedStyle(node||this.area).webkitTransform); - }, - set_matrix:function(value,speed,node){ - (node||this.area).style.webkitTransform = "translate("+Math.round(value.e)+"px,"+Math.round(value.f)+"px)"; - (node||this.area).style.webkitTransitionDuration= speed; - }, - ev_touchstart:function(ev){ - this.ev_mousedown(ev.touches[0]); - ev.preventDefault(); - return false; - }, - ev_mousedown:function(ev){ - var touch = ev; - - this.x = touch.pageX; - this.y = touch.pageY; - this.dx = this.node.offsetWidth; - this.dy = this.node.offsetHeight; - this.mx = this.area.scrollWidth; - this.my = this.area.scrollHeight; - this.target = touch.target; - - if (!this.rough){ - var temp = this.get_matrix(); - this.target_x = temp.e; - this.target_y = temp.f; - if (!this.scroll && this.compat){ - temp.e = this.node.scrollLeft*-1; - temp.f = this.node.scrollTop*-1; - this.node.scrollTop = this.node.scrollLeft = 0; - } - - this.set_matrix(temp,0); - this._correct_scroll(this.target_x, this.target_y); - } - this.scroll_x = this.scroll_y = this.scroll = false; - - - this._init_events(); - }, - ev_touchend:function(){ - return this.ev_mouseup(); - }, - ev_mouseup:function(){ - this._deinit_events(); - if (!this.scroll){ - this._remove_scroll(); - var ev = document.createEvent("MouseEvent"); - ev.initMouseEvent("click",true, true); - this.target.dispatchEvent(ev); - } - this.target = null; - }, - ev_webkitTransitionEnd:function(){ - if (this.target || !this.scroll) return; - - this._remove_scroll(); - var temp = this.get_matrix(); - this.node.firstChild._scrollTop = -1*temp.f; - - if (this.compat && (temp.e||temp.f)){ - var y = temp.f; var x = temp.e; - temp.e = temp.f = 0; - this.set_matrix(temp,0); - - this.node.scrollTop = -1*y; - this.node.scrollLeft = -1*x; - } - - this.scroll = false; - }, - ev_touchmove:function(ev){ - return this.ev_mousemove(ev.touches[0]); - }, - ev_mousemove:function(ev){ - if (!this.target) return; - var touch = ev; - - var dx = (touch.pageX - this.x)*(this.axisX?5:0);//Math.min(3,this.mx/this.dx); - var dy = (touch.pageY - this.y)*(this.axisY?5:0);//Math.min(3,this.my/this.dy); - - if (Math.abs(dx)<10 && Math.abs(dy)<10) return; - - if (Math.abs(dx)>50) - this.scroll_x=true; - if (Math.abs(dy)>50) - this.scroll_y=true; - - - if (this.scroll_x || this.scroll_y){ - this.x = touch.pageX; this.y = touch.pageY; - this.scroll = true; - var temp = this.get_matrix(); - dx = dx + (this.target_x - temp.e); - dy = dy + (this.target_y - temp.f); - - var speed = "2000ms"; - var fast = "500ms"; - this.target_x = dx+temp.e; - this.target_y = dy+temp.f; - - if (this.target_x > 0) { - this.target_x = 0; - speed = fast; - } - if (this.target_y > 0) { - this.target_y = 0; - speed = fast; - } - if (this.mx - this.dx + this.target_x < 0){ - this.target_x = - this.mx + this.dx; - speed = fast; - } - if (this.my - this.dy + this.target_y < 0){ - this.target_y = - this.my + this.dy; - speed = fast; - } - - - this.set_matrix({e:this.target_x,f:this.target_y},speed); - this._add_scroll(temp.e, temp.f); - this._correct_scroll(this.target_x, this.target_y, speed); - this.onscroll(this.target_x, this.target_y); - } - return false; - }, - _correct_scroll:function(x,y,speed){ - if (this.scrolls.x){ - var stemp = this.get_matrix(this.scrolls.x); - var sx = this.dx*x/this.mx; - this.set_matrix({e:-1*sx,f:0}, speed, this.scrolls.x); - } - if (this.scrolls.y){ - var stemp = this.get_matrix(this.scrolls.y); - var sy = this.dy*y/this.my; - this.set_matrix({e:0,f:-1*sy}, speed, this.scrolls.y); - } - }, - _remove_scroll:function(){ - if (this.scrolls.x) - this.scrolls.x.parentNode.removeChild(this.scrolls.x); - if (this.scrolls.y) - this.scrolls.y.parentNode.removeChild(this.scrolls.y); - this.scrolls = {}; - }, - _add_scroll:function(){ - if (this.scrolls.ready) return; - - var d; - if (this.my>5 && this.axisY){ - var h = this.dy*this.dy/this.my-1; - this.scrolls.y = d = document.createElement("DIV"); - d.className="dhx_scroll_y"; - d.style.height = h +"px"; - this.node.appendChild(d); - } - if (this.mx>5 && this.axisX){ - var h = this.dx*this.dx/this.mx; - this.scrolls.x = d = document.createElement("DIV"); - d.className="dhx_scroll_x"; - d.style.width = h +"px"; - this.node.appendChild(d); - } - - var temp = this.get_matrix(); - this._correct_scroll(temp.e, temp.f, 0); - this.scrolls.ready = true; - }, - _init_events:function(){ - document.addEventListener("touchmove",this,false); - document.addEventListener("touchend",this,false); - if (this.debug){ - document.addEventListener("mousemove",this,false); - document.addEventListener("mouseup",this,false); - } - }, - _deinit_events:function(){ - document.removeEventListener("touchmove",this,false); - document.removeEventListener("touchend",this,false); - if (this.debug){ - document.removeEventListener("mousemove",this,false); - document.removeEventListener("mouseup",this,false); - } - }, - _init:function(){ - document.styleSheets[0].insertRule(".dhx_scroll_x { width:50px;height:4px;background:rgba(0, 0, 0, 0.4);position:absolute; left:0px; bottom:3px; border:1px solid transparent; -webkit-border-radius:4px;-webkit-transition: -webkit-transform;}",0); - document.styleSheets[0].insertRule(".dhx_scroll_y { width:4px;height:50px;background:rgba(0, 0, 0, 0.4);position:absolute; top:0px; right:3px; border:1px solid transparent; -webkit-border-radius:4px;-webkit-transition: -webkit-transform;}",0); - this._init = function(){}; - } -}; - - - - - -scheduler._ipad_before_init=function(){ - scheduler._ipad_before_init=function(){}; - scheduler.xy.scroll_width = 0; - - var tabs = scheduler._els["dhx_cal_tab"]; - var right = 42; - for (var i=tabs.length-1; i >=0; i--) { - tabs[i].style.cssText+="top:4px;"; - tabs[i].style.left="auto"; - tabs[i].style.right = right+"px"; - if (i==0) - tabs[i].style.cssText+=";-webkit-border-top-left-radius: 5px; -webkit-border-bottom-left-radius: 5px;"; - if (i==tabs.length-1) - tabs[i].style.cssText+=";-webkit-border-top-right-radius: 5px; -webkit-border-bottom-right-radius: 5px;"; - - right+=100; - }; - - scheduler._els["dhx_cal_prev_button"][0].innerHTML = "<"; - scheduler._els["dhx_cal_next_button"][0].innerHTML = ">"; - var d = document.createElement("div"); - d.className = "dhx_cal_add_button"; - d.innerHTML = "+ "; - d.onclick = function(){ - var now = new Date(); - if (now > scheduler._min_date && now < scheduler._max_date) - scheduler.addEventNow(); - else - scheduler.addEventNow(scheduler._min_date.valueOf()); - } - scheduler._els["dhx_cal_navline"][0].appendChild(d); - - - this._obj.onmousedown = this._obj.onmouseup = this._obj.onmousemove = function(){}; - - var long_tap = null; - var long_tap_pos = []; - this._obj.ontouchmove=function(e){ - if (long_tap){ - var dx = Math.abs(e.touches[0].pageX - long_tap_pos[0]); - var dy = Math.abs(e.touches[0].pageY - long_tap_pos[1]); - if (dx>50 || dy>50) - long_tap = window.clearTimeout(long_tap); - } - if (scheduler.config.touch_actions) - scheduler._on_mouse_move(e.touches[0]); - } - this._obj.ontouchstart = function(e){ - if (scheduler._lightbox_id) return; - - long_tap = window.setTimeout(function(){ - scheduler._on_dbl_click(e.touches[0],(e.target.className?e.target:e.target.parentNode)); - },400); - long_tap_pos = [e.touches[0].pageX, e.touches[0].pageY]; - if (scheduler.config.touch_actions) - scheduler._on_mouse_down(e.touches[0]); - } - this._obj.ontouchend = function(e){ - if (long_tap) - long_tap = window.clearTimeout(long_tap); - if (scheduler.config.touch_actions) - scheduler._on_mouse_up(e.touches[0]); - } -} -scheduler._ipad_init=function(){ - var d = document.createElement("DIV"); - var data = scheduler._els["dhx_cal_data"][0]; - d.appendChild(data); - d.style.cssText = "overflow:hidden; width:100%; overflow:hidden;position:relative;"; - this._obj.appendChild(d); - - data.style.overflowY = "hidden"; - - var scroll = new TouchScroll(d); - scroll.axisX = false; - scheduler._ipad_init = function(){ - data.parentNode.style.height = data.style.height; - data.parentNode.style.top = data.style.top; - data.style.height = data.scrollHeight+"px"; - data.style.top = "0px"; - - if (Math.abs(data.parentNode.offsetHeight - data.offsetHeight)<5){ - scroll.axisY=false; - scroll.scrollTo(0,0,0); - } else - scroll.axisY=true; - - scroll.refresh(); - }; - - scheduler.attachEvent("onSchedulerResize", function(){ - setTimeout(function(){ - scheduler._ipad_init(); - }); - return true; - }) - - scheduler._ipad_init(); -}; - -scheduler.attachEvent("onViewChange",function(){ - scheduler._ipad_init(); -}); -scheduler.attachEvent("onBeforeViewChange",function(){ - scheduler._ipad_before_init(); - return true; -}); - -scheduler.showCover=function(box){ - this.show_cover(); - if (box){ - box.style.display="block"; - var pos = getOffset(this._obj); - box.style.top = box.offsetHeight*-1+"px"; - box.style.left = Math.round(pos.left+(this._obj.offsetWidth-box.offsetWidth)/2)+"px"; - } - - var node =this._get_lightbox(); - node.style.webkitTransform = "translate(0px,"+(box.offsetHeight+41)+"px)"; - node.style.webkitTransitionDuration = "500ms"; -}; - -scheduler.hideCover=function(box){ - if (box){ - box.style.webkitTransform = "translate(0px,"+(box.offsetHeight+41)*-1+"px)"; - box.style.webkitTransitionDuration = "500ms"; - } - this.hide_cover(); -} - -scheduler.config.lightbox.sections[0].height = 100; -if (scheduler.form_blocks.calendar_time){ - scheduler.config.lightbox.sections[1].type = "calendar_time"; - scheduler._mini_cal_arrows = ["<", ">"]; -} - -scheduler.xy.menu_width = 0; -scheduler.attachEvent("onClick", function(){ - return false; -}); - -scheduler.locale.labels.new_event=""; - -scheduler._mouse_coords=function(ev){ - var pos; - var b=document.body; - var d = document.documentElement; - if(ev.pageX || ev.pageY) - pos={x:ev.pageX, y:ev.pageY}; - else pos={ - x:ev.clientX + (b.scrollLeft||d.scrollLeft||0) - b.clientLeft, - y:ev.clientY + (b.scrollTop||d.scrollTop||0) - b.clientTop - } - - //apply layout - pos.x-=getAbsoluteLeft(this._obj)+(this._table_view?0:this.xy.scale_width); - var top = - pos.y-=getAbsoluteTop(this._obj)+this.xy.nav_height+this._dy_shift+this.xy.scale_height-(this._els["dhx_cal_data"][0]._scrollTop||0); - //transform to date - if (!this._table_view){ - pos.x=Math.max(0,Math.ceil(pos.x/this._cols[0])-1); - pos.y=Math.max(0,Math.ceil(pos.y*60/(this.config.time_step*this.config.hour_size_px))-1)+this.config.first_hour*(60/this.config.time_step); - } else { - var dy=0; - for (dy=1; dy < this._colsS.heights.length; dy++) - if (this._colsS.heights[dy]>pos.y) break; - - pos.y=(Math.max(0,Math.ceil(pos.x/this._cols[0])-1)+Math.max(0,dy-1)*7)*24*60/this.config.time_step; - pos.x=0; - } - return pos; -} diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_treetimeline.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_treetimeline.js index 9fb08261470..d92a4be8428 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_treetimeline.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_treetimeline.js @@ -1,8 +1,16 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.attachEvent("onTimelineCreated", function (obj){ if(obj.render == "tree") { obj.y_unit_original = obj.y_unit; obj.y_unit = scheduler._getArrayToDisplay(obj.y_unit_original); + + scheduler.attachEvent('onOptionsLoadStart', function(){ + obj.y_unit = scheduler._getArrayToDisplay(obj.y_unit_original); + }); scheduler.form_blocks[obj.name]={ render:function(sns) { @@ -33,7 +41,7 @@ scheduler.attachEvent("onTimelineCreated", function (obj){ focus:function(node){ } }; - }; + } }); scheduler.attachEvent("onBeforeViewRender", function (render_name, y_unit, timeline){ @@ -61,7 +69,7 @@ scheduler.attachEvent("onBeforeViewRender", function (render_name, y_unit, timel div_expand = ''; table_className = "dhx_data_table"; } - td_content = "
"+div_expand+"
"+(scheduler.templates[timeline.name+'_scale_label'](y_unit.key, y_unit.label, timeline)||y_unit.label)+"
"; + td_content = "
"+div_expand+"
"+(scheduler.templates[timeline.name+'_scale_label'](y_unit.key, y_unit.label, y_unit)||y_unit.label)+"
"; res = { height: height, @@ -81,7 +89,7 @@ var section_id_before; // section id of the event before dragging (to bring it b scheduler.attachEvent("onBeforeEventChanged", function(event_object, native_event, is_new) { if (scheduler._isRender("tree")) { // if mode's render == tree - var section = scheduler.getSection(event_object.section_id); + var section = scheduler.getSection(event_object[scheduler.matrix[scheduler._mode].y_property]); if (typeof section.children != 'undefined' && !scheduler.matrix[scheduler._mode].folder_events_available) { if (!is_new) { //if old - move back event_object[scheduler.matrix[scheduler._mode].y_property] = section_id_before; @@ -140,7 +148,7 @@ scheduler._getArrayForSelect = function(array, mode){ // function to flatten out } if(array[i].children) fillResultArray(array[i].children, mode); - }; + } }; fillResultArray(array); return result; @@ -228,6 +236,14 @@ scheduler.deleteSection = function(id){ } }; +scheduler.deleteAllSections = function(){ + if(scheduler._isRender("tree")) { + scheduler.matrix[scheduler._mode].y_unit_original = []; + scheduler.matrix[scheduler._mode].y_unit = scheduler._getArrayToDisplay(scheduler.matrix[scheduler._mode].y_unit_original); + scheduler.callEvent("onOptionsLoad",[]); + } +}; + scheduler.addSection = function(obj, parent_id){ if(scheduler._isRender("tree")) { var result = false; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_url.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_url.js index 744fe2c27ae..01d030ec83b 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_url.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_url.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.attachEvent("onTemplatesReady",function(){ var first = true; var s2d = scheduler.date.str_to_date("%Y-%m-%d"); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_week_agenda.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_week_agenda.js new file mode 100644 index 00000000000..9aa8b46d4cc --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ext/ext_week_agenda.js @@ -0,0 +1,255 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler._wa = {}; +scheduler.xy.week_agenda_scale_height = 20; +scheduler.templates.week_agenda_event_text = function(start_date, end_date, event, date) { + return scheduler.templates.event_date(start_date) + " " + event.text; +}; +scheduler.date.week_agenda_start = scheduler.date.week_start; +scheduler.date.week_agenda_end = function(date){ + return scheduler.date.add(date, 7, "day"); +}; +scheduler.date.add_week_agenda = function(date, inc){ + return scheduler.date.add(date, inc*7, "day"); +}; + +scheduler.attachEvent("onSchedulerReady", function(){ + var t = scheduler.templates; + if(!t.week_agenda_date) + t.week_agenda_date = t.week_date; +}); + +(function(){ + var scale_date_format = scheduler.date.date_to_str("%l, %F %d"); + scheduler.templates.week_agenda_scale_date = function(date) { + return scale_date_format(date); + }; +})(); + +scheduler.attachEvent("onTemplatesReady", function() { + + scheduler.attachEvent("onSchedulerResize", function() { + if (this._mode == "week_agenda") { + this.week_agenda_view(true); + return false; + } + return true; + }); + + var old = scheduler.render_data; + scheduler.render_data = function(evs) { + if (this._mode == "week_agenda") { + fillWeekAgendaTab(); + } + else + return old.apply(this, arguments); + }; + + var getColumnSizes = function() { + // widths + scheduler._cols = []; + var twidth = parseInt(scheduler._els['dhx_cal_data'][0].style.width); + scheduler._cols.push(Math.floor(twidth / 2)); + scheduler._cols.push(twidth - scheduler._cols[0] - 1); // To add border between columns + + // heights + scheduler._colsS = { + 0: [], + 1: [] + }; + var theight = parseInt(scheduler._els['dhx_cal_data'][0].style.height); + for (var i = 0; i < 3; i++) { + scheduler._colsS[0].push(Math.floor(theight / (3 - scheduler._colsS[0].length))); + theight -= scheduler._colsS[0][i]; + } + scheduler._colsS[1].push(scheduler._colsS[0][0]); + scheduler._colsS[1].push(scheduler._colsS[0][1]); + // last two days + theight = scheduler._colsS[0][scheduler._colsS[0].length - 1]; + scheduler._colsS[1].push(Math.floor(theight / 2)); + scheduler._colsS[1].push(theight - scheduler._colsS[1][scheduler._colsS[1].length - 1]); + }; + var fillWeekAgendaTab = function() { + scheduler._els["dhx_cal_data"][0].innerHTML = ''; + var html = ''; + for (var i = 0; i < 2; i++) { + var width = scheduler._cols[i]; + var column_css = 'dhx_wa_column'; + if (i == 1) + column_css += ' dhx_wa_column_last'; + html += "
"; + for (var k = 0; k < scheduler._colsS[i].length; k++) { + var scale_height = scheduler.xy.week_agenda_scale_height - 2; + var height = scheduler._colsS[i][k] - scale_height - 2; + html += "
"; + } + html += "
"; + } + scheduler._els["dhx_cal_date"][0].innerHTML = scheduler.templates[scheduler._mode+"_date"](scheduler._min_date, scheduler._max_date, scheduler._mode); + scheduler._els["dhx_cal_data"][0].innerHTML = html; + var all_divs = scheduler._els["dhx_cal_data"][0].getElementsByTagName('div'); + var day_divs = []; + for (var i = 0; i < all_divs.length; i++) { + if (all_divs[i].className == 'dhx_wa_day_cont') + day_divs.push(all_divs[i]); + } + scheduler._wa._selected_divs = []; + var events = scheduler.get_visible_events(); // list of events to be displayed in current week + var tstart = scheduler.date.week_start(scheduler._date); + var tend = scheduler.date.add(tstart, 1, "day"); + for (var i = 0; i < 7; i++) { + day_divs[i]._date = tstart; + var scale_bar = day_divs[i].childNodes[0]; + var events_div = day_divs[i].childNodes[1]; + scale_bar.innerHTML = scheduler.templates.week_agenda_scale_date(tstart); + var evs = []; // events which will be displayed in the current day + for (var j = 0; j < events.length; j++) { + var tev = events[j]; + if(tev.start_datetstart) + evs.push(tev); + } + evs.sort(function(a,b){ + if(a.start_date.valueOf()==b.start_date.valueOf()) + return a.id>b.id?1:-1; + return a.start_date>b.start_date?1:-1; + }); + for (var k = 0; k < evs.length; k++) { + var ev = evs[k]; + var ev_div = document.createElement('div'); + scheduler._rendered.push(ev_div); + ev_div.className = 'dhx_wa_ev_body'; + if(ev._text_style) + ev_div.style.cssText = ev._text_style; + if(ev.color) + ev_div.style.backgroundColor = ev.color; + if(ev.textColor) + ev_div.style.color = ev.textColor; + if(scheduler._select_id && ev.id == scheduler._select_id) { + ev_div.className += " dhx_cal_event_selected"; + scheduler._wa._selected_divs.push(ev_div); + } + var position = ""; + if(!ev._timed){ + position = "middle"; + if(ev.start_date.valueOf() >= tstart.valueOf() && ev.start_date.valueOf() <= tend.valueOf()) + position = "start"; + if(ev.end_date.valueOf() >= tstart.valueOf() && ev.end_date.valueOf() <= tend.valueOf()) + position = "end"; + } + ev_div.innerHTML = scheduler.templates.week_agenda_event_text(ev.start_date, ev.end_date, ev, tstart, position); + ev_div.setAttribute('event_id', ev.id); + events_div.appendChild(ev_div); + } + tstart = scheduler.date.add(tstart, 1, "day"); + tend = scheduler.date.add(tend, 1, "day"); + } + }; + scheduler.week_agenda_view = function(mode) { + scheduler._min_date = scheduler.date.week_start(scheduler._date); + scheduler._max_date = scheduler.date.add(scheduler._min_date, 1, "week"); + scheduler.set_sizes(); + if (mode) { // mode enabled + scheduler._table_view=true; + + // hiding default top border from dhx_cal_data + scheduler._wa._prev_data_border = scheduler._els['dhx_cal_data'][0].style.borderTop; + scheduler._els['dhx_cal_data'][0].style.borderTop = 0; + scheduler._els['dhx_cal_data'][0].style.overflowY = 'hidden'; + + // cleaning dhx_cal_date from the previous date + scheduler._els['dhx_cal_date'][0].innerHTML = ""; + + // 1 to make navline to be over data + scheduler._els['dhx_cal_data'][0].style.top = (parseInt(scheduler._els['dhx_cal_data'][0].style.top)-scheduler.xy.bar_height-1) + 'px'; + scheduler._els['dhx_cal_data'][0].style.height = (parseInt(scheduler._els['dhx_cal_data'][0].style.height)+scheduler.xy.bar_height+1) + 'px'; + + scheduler._els['dhx_cal_header'][0].style.display = 'none'; + getColumnSizes(); + fillWeekAgendaTab(); + } + else { // leaving week_agenda mode + scheduler._table_view=false; + + // restoring default top border to dhx_cal_data + if (scheduler._wa._prev_data_border) + scheduler._els['dhx_cal_data'][0].style.borderTop = scheduler._wa._prev_data_border; + + scheduler._els['dhx_cal_data'][0].style.overflowY = 'auto'; + scheduler._els['dhx_cal_data'][0].style.top = (parseInt(scheduler._els['dhx_cal_data'][0].style.top)+scheduler.xy.bar_height) + 'px'; + scheduler._els['dhx_cal_data'][0].style.height = (parseInt(scheduler._els['dhx_cal_data'][0].style.height)-scheduler.xy.bar_height) + 'px'; + scheduler._els['dhx_cal_header'][0].style.display = 'block'; + } + }; + scheduler.mouse_week_agenda = function(pos) { + var native_event = pos.ev; + var src = native_event.srcElement || native_event.target; + while (src.parentNode) { + if (src._date) + var date = src._date; + src = src.parentNode; + } + if(!date) + return pos; + pos.x = 0; + var diff = date.valueOf() - scheduler._min_date.valueOf(); + pos.y = Math.ceil(( diff / (1000 * 60) ) / this.config.time_step); + if (this._drag_mode == 'move') { + this._drag_event._dhx_changed = true; + this._select_id = this._drag_id; + for (var i = 0; i < scheduler._rendered.length; i++) { + if (scheduler._drag_id == this._rendered[i].getAttribute('event_id')) + var event_div = this._rendered[i]; + } + if (!scheduler._wa._dnd) { + var div = event_div.cloneNode(true); + this._wa._dnd = div; + div.className = event_div.className; + div.id = 'dhx_wa_dnd'; + div.className += ' dhx_wa_dnd'; + document.body.appendChild(div); + } + var dnd_div = document.getElementById('dhx_wa_dnd'); + dnd_div.style.top = ((native_event.pageY || native_event.clientY) + 20) + "px"; + dnd_div.style.left = ((native_event.pageX || native_event.clientX) + 20) + "px"; + } + return pos; + }; + scheduler.attachEvent('onBeforeEventChanged', function(event_object, native_event, is_new) { + if (this._mode == 'week_agenda') { + if (this._drag_mode == 'move') { + var dnd = document.getElementById('dhx_wa_dnd'); + dnd.parentNode.removeChild(dnd); + scheduler._wa._dnd = false; + } + } + return true; + }); + + scheduler.attachEvent("onEventSave",function(id,data,is_new_event){ + if(is_new_event) + this._select_id = id; + return true; + }); + + scheduler._wa._selected_divs = []; + + scheduler.attachEvent("onClick",function(event_id, native_event_object){ + if(this._mode == 'week_agenda'){ + if(scheduler._wa._selected_divs) { + for(var i=0; i"; + html += "
" + (evs[i]._timed ? this.templates.event_date(evs[i].start_date) : "") + "
"; + html += "
 
"; + html += this.templates.year_tooltip(evs[i].start_date, evs[i].end_date, evs[i]) + "
"; + } + + this._tooltip.style.display = ""; + this._tooltip.style.top = "0px"; -scheduler.hideToolTip=function(){ - if (this._tooltip){ - this._tooltip.style.display = "none"; - this._tooltip.date = new Date(9999,1,1); - } - -} -scheduler.showToolTip=function(date,pos,e,src){ - if (this._tooltip){ - if (this._tooltip.date.valueOf() == date.valueOf()) return; - this._tooltip.innerHTML=""; - } else { - var t = this._tooltip = document.createElement("DIV"); - t.className = "dhx_tooltip"; - document.body.appendChild(t); - t.onclick = scheduler._click.dhx_cal_data; - - } - var evs = this.getEvents(date,this.date.add(date,1,"day")); - var html = ""; - - for (var i=0; i" - html+="
"+(evs[i]._timed?this.templates.event_date(evs[i].start_date):"")+"
"; - html+="
 
"; - html+=this.templates.year_tooltip(evs[i].start_date, evs[i].end_date,evs[i])+""; - } - - this._tooltip.style.display=""; - this._tooltip.style.top = "0px"; - - - if (document.body.offsetWidth-pos.left-this._tooltip.offsetWidth < 0) - this._tooltip.style.left = pos.left-this._tooltip.offsetWidth+"px"; - else - this._tooltip.style.left = pos.left+src.offsetWidth+"px"; - - this._tooltip.date = date; - this._tooltip.innerHTML = html; - - if (document.body.offsetHeight-pos.top-this._tooltip.offsetHeight < 0) - this._tooltip.style.top= pos.top-this._tooltip.offsetHeight+src.offsetHeight+"px"; - else - this._tooltip.style.top= pos.top+"px"; -} + if (document.body.offsetWidth - pos.left - this._tooltip.offsetWidth < 0) + this._tooltip.style.left = pos.left - this._tooltip.offsetWidth + "px"; + else + this._tooltip.style.left = pos.left + src.offsetWidth + "px"; -scheduler._init_year_tooltip=function(){ - dhtmlxEvent(scheduler._els["dhx_cal_data"][0], "mouseover", function(e){ - if (!is_year_mode()) return; - - var e = e || event; - var src = e.target||e.srcElement; - if ((src.className||"").indexOf("dhx_year_event")!=-1) - scheduler.showToolTip(from_attr(src.getAttribute("date")),getOffset(src),e,src); - else - scheduler.hideToolTip(); - }) - this._init_year_tooltip=function(){}; -} + this._tooltip.date = date; + this._tooltip.innerHTML = html; -scheduler.attachEvent("onSchedulerResize",function(){ - if (is_year_mode()){ - this.year_view(true); - return false; - } - return true; -}); -scheduler._get_year_cell=function(d){ - //there can be more than 1 year in view - //year can start not from January - var m = d.getMonth()+12*(d.getFullYear()-this._min_date.getFullYear())-this.week_starts._month; - var t = this._els["dhx_cal_data"][0].childNodes[m]; - var d = this.week_starts[m]+d.getDate()-1; - - - return t.childNodes[2].firstChild.rows[Math.floor(d/7)].cells[d%7].firstChild; -} + if (document.body.offsetHeight - pos.top - this._tooltip.offsetHeight < 0) + this._tooltip.style.top = pos.top - this._tooltip.offsetHeight + src.offsetHeight + "px"; + else + this._tooltip.style.top = pos.top + "px"; + }; + + scheduler._init_year_tooltip = function() { + dhtmlxEvent(scheduler._els["dhx_cal_data"][0], "mouseover", function(e) { + if (!is_year_mode()) return; + + var e = e || event; + var src = e.target || e.srcElement; + if (src.tagName.toLowerCase() == 'a') // fix for active links extension (it adds links to the date in the cell) + src = src.parentNode; + if ((src.className || "").indexOf("dhx_year_event") != -1) + scheduler.showToolTip(from_attr(src.getAttribute("date")), getOffset(src), e, src); + else + scheduler.hideToolTip(); + }); + this._init_year_tooltip = function() { + }; + }; + + scheduler.attachEvent("onSchedulerResize", function() { + if (is_year_mode()) { + this.year_view(true); + return false; + } + return true; + }); + scheduler._get_year_cell = function(d) { + //there can be more than 1 year in view + //year can start not from January + var m = d.getMonth() + 12 * (d.getFullYear() - this._min_date.getFullYear()) - this.week_starts._month; + var t = this._els["dhx_cal_data"][0].childNodes[m]; + var d = this.week_starts[m] + d.getDate() - 1; -var marked = []; -scheduler._mark_year_date=function(d,ev){ - var c = this._get_year_cell(d); - c.className = "dhx_month_head dhx_year_event "+this.templates.event_class(ev.start_date,ev.end_date,ev); - c.setAttribute("date",to_attr(d)) - marked.push(c); -} -scheduler._unmark_year_date=function(d){ - this._get_year_cell(d).className = "dhx_month_head"; -} -scheduler._year_render_event=function(ev){ - var d = ev.start_date; - if (d.valueOf()=this._max_date.valueOf()) - return; - } -} -scheduler.year_view=function(mode){ - if (mode){ - var temp = scheduler.xy.scale_height; - scheduler.xy.scale_height = -1; - } - - scheduler._els["dhx_cal_header"][0].style.display=mode?"none":""; - scheduler.set_sizes(); - - if (mode) - scheduler.xy.scale_height = temp; - - - scheduler._table_view = mode; - if (this._load_mode && this._load()) return; - - if (mode){ - scheduler._init_year_tooltip(); - scheduler._reset_year_scale(); - scheduler.render_view_data(); - } else { - scheduler.hideToolTip(); - } -} -scheduler._reset_year_scale = function(){ - this._cols=[]; this._colsS={}; - var week_starts = []; //start day of first week in each month - var b=this._els["dhx_cal_data"][0]; - - var c = this.config; - b.scrollTop=0; //fix flickering in FF - b.innerHTML=""; - - var dx = Math.floor(parseInt(b.style.width)/c.year_x); - var dy = Math.floor((parseInt(b.style.height)-scheduler.xy.year_top)/c.year_y); - if (dy<190) { - dy = 190; - dx = Math.floor((parseInt(b.style.width)-scheduler.xy.scroll_width)/c.year_x); - } - - var summ = dx-11; - var left = 0; - var week_template = document.createElement("div"); - var dummy_date = this.date.week_start(new Date()); - for (var i=0; i<7; i++){ - this._cols[i]=Math.floor(summ/(7-i)); - this._render_x_header(i,left,dummy_date,week_template); - dummy_date = this.date.add(dummy_date,1,"day"); - summ-=this._cols[i]; - left+=this._cols[i]; - } - week_template.lastChild.className+=" dhx_scale_bar_last"; - - var sd = this.date[this._mode+"_start"](this.date.copy(this._date)); - var ssd=sd; - - for (var i=0; i
"; - d.childNodes[0].innerHTML=this.templates.year_month(sd); - - var dd = this.date.week_start(sd); - var ed = this._reset_month_scale(d.childNodes[2],sd,dd); - - var r=d.childNodes[2].firstChild.rows; - for (var k=r.length; k<6; k++) { - r[0].parentNode.appendChild(r[0].cloneNode(true)); - for (var ri=0; ri < r[k].childNodes.length; ri++) { - r[k].childNodes[ri].className = "dhx_after"; - r[k].childNodes[ri].firstChild.innerHTML = scheduler.templates.month_day(ed); - ed = scheduler.date.add(ed,1,"day"); - }; - } - - - b.appendChild(d); - - var dt = Math.round((dy-190)/2); - d.style.marginTop=dt+"px"; - this.set_xy(d,dx-10,dy-dt-10,dx*j+5,dy*i+5+scheduler.xy.year_top); - - week_starts[i*c.year_x+j] = (sd.getDay()-(this.config.start_on_monday?1:0)+7)%7; - sd = this.date.add(sd,1,"month"); - - } - this._els["dhx_cal_date"][0].innerHTML=this.templates[this._mode+"_date"](ssd,sd,this._mode); - this.week_starts = week_starts; - week_starts._month = ssd.getMonth(); - this._min_date = ssd; - this._max_date = sd; -} + return t.childNodes[2].firstChild.rows[Math.floor(d / 7)].cells[d % 7].firstChild; + }; + + var marked = []; + scheduler._mark_year_date = function(d, ev) { + var c = this._get_year_cell(d); + c.className = "dhx_month_head dhx_year_event " + this.templates.event_class(ev.start_date, ev.end_date, ev); + c.setAttribute("date", to_attr(d)) + marked.push(c); + }; + scheduler._unmark_year_date = function(d) { + this._get_year_cell(d).className = "dhx_month_head"; + }; + scheduler._year_render_event = function(ev) { + var d = ev.start_date; + if (d.valueOf() < this._min_date.valueOf()) + d = this._min_date; + else d = this.date.date_part(new Date(d)); + + while (d < ev.end_date) { + this._mark_year_date(d, ev); + d = this.date.add(d, 1, "day"); + if (d.valueOf() >= this._max_date.valueOf()) + return; + } + }; + + scheduler.year_view = function(mode) { + if (mode) { + var temp = scheduler.xy.scale_height; + scheduler.xy.scale_height = -1; + } + + scheduler._els["dhx_cal_header"][0].style.display = mode ? "none" : ""; + scheduler.set_sizes(); + + if (mode) + scheduler.xy.scale_height = temp; + + + scheduler._table_view = mode; + if (this._load_mode && this._load()) return; + + if (mode) { + scheduler._init_year_tooltip(); + scheduler._reset_year_scale(); + scheduler.render_view_data(); + } else { + scheduler.hideToolTip(); + } + }; + scheduler._reset_year_scale = function() { + this._cols = []; + this._colsS = {}; + var week_starts = []; //start day of first week in each month + var b = this._els["dhx_cal_data"][0]; + + var c = this.config; + b.scrollTop = 0; //fix flickering in FF + b.innerHTML = ""; + + var dx = Math.floor(parseInt(b.style.width) / c.year_x); + var dy = Math.floor((parseInt(b.style.height) - scheduler.xy.year_top) / c.year_y); + if (dy < 190) { + dy = 190; + dx = Math.floor((parseInt(b.style.width) - scheduler.xy.scroll_width) / c.year_x); + } + + var summ = dx - 11; + var left = 0; + var week_template = document.createElement("div"); + var dummy_date = this.date.week_start(new Date()); + for (var i = 0; i < 7; i++) { + this._cols[i] = Math.floor(summ / (7 - i)); + this._render_x_header(i, left, dummy_date, week_template); + dummy_date = this.date.add(dummy_date, 1, "day"); + summ -= this._cols[i]; + left += this._cols[i]; + } + week_template.lastChild.className += " dhx_scale_bar_last"; + + var sd = this.date[this._mode + "_start"](this.date.copy(this._date)); + var ssd = sd; + + for (var i = 0; i < c.year_y; i++) + for (var j = 0; j < c.year_x; j++) { + var d = document.createElement("DIV"); + d.style.cssText = "position:absolute;"; + d.setAttribute("date", this.templates.xml_format(sd)); + d.innerHTML = "
" + week_template.innerHTML + "
"; + d.childNodes[0].innerHTML = this.templates.year_month(sd); + + var dd = this.date.week_start(sd); + var ed = this._reset_month_scale(d.childNodes[2], sd, dd); + + var r = d.childNodes[2].firstChild.rows; + for (var k=r.length; k<6; k++) { + r[0].parentNode.appendChild(r[0].cloneNode(true)); + for (var ri=0; ri < r[k].childNodes.length; ri++) { + r[k].childNodes[ri].className = "dhx_after"; + r[k].childNodes[ri].firstChild.innerHTML = scheduler.templates.month_day(ed); + ed = scheduler.date.add(ed,1,"day"); + } + } + b.appendChild(d); + + d.childNodes[1].style.height = d.childNodes[1].childNodes[0].offsetHeight + "px"; // dhx_year_week should have height property so that day dates would get correct position. dhx_year_week height = height of it's child (with the day name) + var dt = Math.round((dy - 190) / 2); + d.style.marginTop = dt + "px"; + this.set_xy(d, dx - 10, dy - dt - 10, dx * j + 5, dy * i + 5 + scheduler.xy.year_top); + + week_starts[i * c.year_x + j] = (sd.getDay() - (this.config.start_on_monday ? 1 : 0) + 7) % 7; + sd = this.date.add(sd, 1, "month"); + + } + this._els["dhx_cal_date"][0].innerHTML = this.templates[this._mode + "_date"](ssd, sd, this._mode); + this.week_starts = week_starts; + week_starts._month = ssd.getMonth(); + this._min_date = ssd; + this._max_date = sd; + } })(); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/glossy.css b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/glossy.css new file mode 100644 index 00000000000..51c4e99d668 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/glossy.css @@ -0,0 +1,294 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +.dhx_cal_tab.active{ + border:none; +} +.dhx_multi_day{ + border:none; + border-top:1px solid #A4BED4; +} +.dhx_multi_day_icon, .dhx_multi_day_icon_small{ + border-right:none; +} +.dhx_cal_container { + background-image:url(imgs_glossy/top-days-bg.png); + background-position:0 24px; + background-repeat:repeat-x; + background-color:#EBEBEB; +} +.dhx_cal_navline{ + background-color:#EBEBEB; + height:23px !important; +} +.dhx_cal_prev_button{ + background-image:url(imgs_glossy/buttons.gif); + width:30px; + height:20px; +} +.dhx_cal_next_button{ + background-image:url(imgs_glossy/buttons.gif); + width:30px; + height:20px; +} +.dhx_cal_today_button{ + padding-top:3px; + background-image:url(imgs_glossy/buttons.gif); + width:67px; + left:110px; + text-decoration:none; +} +.dhx_cal_navline .dhx_cal_date{ + padding-top:4px; + left:230px; +} +.dhx_cal_tab{ + background-image:url(imgs_glossy/white_tab.png); + width:60px; + height:15px; + text-decoration:none; + padding-top:4px; + margin-top: 4px; +} +.dhx_cal_tab.active{ + background-image:url(imgs_glossy/blue_tab.png); + height:18px; + width:60px; + padding-top:4px; + margin-top: 2px; +} +.dhx_cal_data{ + border-top: 1px solid #A4BED4; +} +.dhx_cal_header{ + background-image:url(imgs_glossy/top-days-bg.png); + background-repeat:repeat-x; + border-top: 0px; + border-right: 0px; +} +.dhx_scale_bar{ + background-image:url(imgs_glossy/top-separator.gif); + background-position: 0px 0px; + background-repeat:no-repeat; + background-color: transparent; + padding-top:3px; + border-left:0px; +} + +.dhx_scale_holder { + border-right:1px solid #A4BED4; +} +.dhx_scale_holder_now{ + border-right:1px solid #A4BED4; +} +.dhx_scale_hour{ + background-image:url(imgs_glossy/left-time-bg.png); + border-bottom:1px solid #A4BED4; + color:#2F3A48; +} +.dhx_multi_day{ + background-image:url(imgs_glossy/multi-days-bg.png); + background-repeat:repeat; + border-bottom:1px solid #A4BED4; + border-left:0px; +} +.dhx_multi_day_icon,.dhx_multi_day_icon_small{ + background-image:url(imgs_glossy/multi-days-bg.png); + border-bottom:1px solid #A4BED4; + border-left:1px solid #ffffff; + background-position:0 0; + background-repeat:repeat; +} +.dhx_month_head{ + background-color:#FFFFFF; +} +.dhx_after .dhx_month_head,.dhx_before .dhx_month_head{ + background-color:#EFEDE2; +} +.dhx_now .dhx_month_head{ + background-color:#E4EFFF; +} +.dhx_after .dhx_month_body,.dhx_before .dhx_month_body{ + background-color:#EFEDE2; +} +.dhx_cal_event div{ + border:1px solid #FFBD51; + background-color:#FFE4AB; + color:#000000; +} +.dhx_cal_event_clear{ + color:#000000; +} +.dhx_cal_event_line{ + background-image:url(imgs_glossy/event-bg.png); + border:1px solid #FFBD51; + color:#000000; +} +.dhx_in_move{ + background-image:url(imgs_glossy/move.png); +} +.dhx_cal_event .dhx_body{ + background-color:#FFE4AB; +} +.dhx_cal_event .dhx_title{ + background-color:#FFE4AB; +} +.dhx_cal_light{ + -moz-box-shadow:5px 5px 5px #888888; + -khtml-box-shadow: 5px 5px 5px #888; + background-color:#EBEBEB; + border:2px solid #A4BED4; + color:#000000; +} +.dhx_cal_larea{ + border:1px solid #A4BED4; + border-width:0 1px 1px; + background-color:#FFFFFF; +} + +.dhx_cal_lsection{ + background-image:url(imgs_glossy/lightbox.png); + font-size:14px; + padding:5px 0 5px 10px; + color:#000000; +} +.dhx_cal_light_wide .dhx_cal_lsection{ + background-image:url(imgs_glossy/multi-days-bg.png); +} + + +.dhx_cal_ltext textarea{ + background-color:#ffffff; + color:#000000; +} + +.dhx_cal_light select, .dhx_cal_light input{ + color:#000000; +} +.dhx_save_btn{ + background-image:url(imgs_glossy/controlls5.png); +} +.dhx_cancel_btn{ + background-image:url(imgs_glossy/controlls5.png); +} +.dhx_delete_btn{ + background-image:url(imgs_glossy/controlls5.png); +} +div.dhx_menu_head{ + background-image:url(imgs_glossy/controlls5.png); + border:1px solid #FFE4AB; +} +div.dhx_menu_icon{ + background-image:url(imgs_glossy/controlls5.png); + border:medium none; +} +.dhx_section_time{ + height:20px !important; + padding:7px 0 !important; + text-align:center; + background:white; +} + +div.dhx_cal_editor{ + background-color:#FFE4AB; +} +.dhx_year_month{ + background-image:url(imgs_glossy/top-days-bg.png); + border: 0px; +} +.dhx_year_week{ + background-image:url(imgs_glossy/top-days-bg.png); +} +.dhx_month_head{ + border-right:1px solid #A4BED4; +} +.dhx_month_body{ + border-right:1px solid #A4BED4; + border-bottom:1px solid #A4BED4; +} +.dhx_year_body{ + border-left:1px solid #A4BED4; +} +.dhx_scale_bar_last{ + border-right: none; +} +.dhx_month_head.dhx_year_event{ + background-color:#FFE4AB; +} +.dhx_year_body .dhx_before .dhx_month_head, .dhx_year_body .dhx_after .dhx_month_head, .dhx_year_body .dhx_before .dhx_month_head a, .dhx_year_body .dhx_after .dhx_month_head a{ + color:#EFEDE2 !important; +} +.dhx_cal_lsection .dhx_readonly{ + color:#000000; +} +.dhx_tooltip{ + -moz-box-shadow:2px 2px 2px #888; /*Doesn't work in IE*/ + -khtml-box-shadow: 2px 2px 2px #888; +} +.dhx_custom_button { + margin-top: -2px; +} +/*2.3*/ +.dhx_cal_lsection .dhx_fullday{ + color:#000000; +} + +.dhx_cal_lsection.dhx_cal_checkbox{ + height:16px; + line-height:18px; +} +.dhx_cal_light_wide .dhx_cal_lsection.dhx_cal_checkbox{ + height:20px; +} +.dhx_cal_checkbox label{ + vertical-align:top; +} + +.dhx_cal_light_wide .dhx_cal_lsection{ + color:black; +} + +.dhx_cal_light_wide .dhx_wrap_section{ + border-top:1px solid #A4BED4; + background-image:url(imgs_glossy/multi-days-bg.png); +} +.dhx_cal_light_wide .dhx_cal_ltext{ + border-left:1px solid #A4BED4; +} +.dhx_cal_light_wide .dhx_cal_ltext { + background-color:white; +} +.dhx_custom_button{ + background:white; + color:black; +} +.dhx_form_repeat{ + background:white; +} +.dhx_repeat_divider{ + border-left:1px solid #A4BED4; +} + +/* timeline second scale start */ +.dhx_cal_header.dhx_second_cal_header { + background-image: url("imgs_glossy/second-top-days-bg.png"); + padding-right: 20px; +} +.dhx_scale_bar { + padding-top: 4px; +} +.dhx_second_scale_bar { + border-bottom: 0; + padding-top: 4px; +} + +/* timeline second scale end */ +.dhx_cal_light_wide .dhx_cal_lsection .dhx_fullday, .dhx_cal_lsection .dhx_fullday{ + color:#000000; + font-size: 14px; +} +.dhx_cal_light_wide .dhx_cal_lsection { + font-size: 14px; + padding-right:10px; +} \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ical.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ical.js index ab6fdb0101c..60dbfef8626 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ical.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/ical.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.ical={ parse:function(str){ var data = str.match(RegExp(this.c_start+"[^\f]*"+this.c_end,"")); diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/layout.css b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/layout.css index 4818d92db21..a888f4d0c79 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/layout.css +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/layout.css @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ .dhx_cal_container{ background-color:#C2D5FC; font-family:Tahoma; @@ -52,18 +56,28 @@ text-decoration:underline; } .dhx_cal_tab{ - background-image:url(imgs/white_tab.png); - width:61px; height:19px; + width:59px; height:19px; text-align:center; text-decoration:underline; - padding-top:3px; cursor:pointer; + padding-top:2px; + cursor:pointer; + background-color: #D8E1EA; + + -webkit-border-top-left-radius: 4px; + -webkit-border-top-right-radius: 4px; + -moz-border-radius-topleft: 4px; + -moz-border-radius-topright: 4px; + border-top-left-radius: 4px; + border-top-right-radius: 4px; } .dhx_cal_tab.active{ - background-image:url(imgs/blue_tab.png); text-decoration:none; - height:20px; - padding-top:2px; cursor:default; + + cursor:default; font-weight:bold; + border: 1px dotted #586A7E; + border-bottom: 0; + background-color: #C2D5FC; } .dhx_cal_header{ position:absolute; @@ -154,11 +168,13 @@ z-index:9999; } .dhx_multi_day_icon, .dhx_multi_day{ - position:absolute; background-color:#E1E6FF; background-repeat:no-repeat; - border-bottom:1px dotted #8894A3; - border-left:1px dotted #8894A3; + border-right:1px dotted #8894A3; +} +.dhx_multi_day{ + position: absolute; + border-top:1px dotted #8894A3; } .dhx_multi_day_icon{ background-image:url(imgs/clock_big.gif); @@ -168,11 +184,10 @@ } .dhx_multi_day_icon, .dhx_multi_day_icon_small{ background-position: center center; - position:absolute; background-color:#E1E6FF; background-repeat:no-repeat; border-bottom:1px dotted #8894A3; - border-left:1px dotted #8894A3; + border-right:1px dotted #8894A3; } .dhtmlxLayoutPolyContainer_dhx_skyblue .dhx_cal_container { background-color: #d0e5ff; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.css b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.css index 5781bc3d3b5..afb83295be3 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.css +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.css @@ -1,151 +1,239 @@ - .dhx_cal_light{ - height:400px; - light:300px; - background-color:#FFE763; - - font-family:Tahoma; - font-size:8pt; - border:1px solid #B7A64B; - color:#887A2E; - - position:absolute; - z-index:10001; - - width:580px; - height:300px; - } - .dhx_mark{ - position:relative; top:3px; - background-image:url('./imgs/controls.gif'); - background-position: 0px -43px; - padding-left:10px; - } - .dhx_ie6 .dhx_mark{ - background-position: 6px -41px; - } - - .dhx_cal_light select{ - font-family:Tahoma; - font-size:8pt; - color:#887A2E; - padding:2px; - margin:0px; - } - .dhx_cal_ltitle{ - padding:2px 0px 2px 5px; - overflow:hidden; - white-space:nowrap; - } - .dhx_cal_ltitle span{ - white-space:nowrap; - } - .dhx_cal_lsection{ - background-color:#DBCF8C; - color:#FFF4B5; - font-size:18pt; - font-weight:bold; - padding:5px 0px 3px 10px; - } - .dhx_cal_ltext{ - padding:2px 0px 2px 10px; - height:130px; - height=140px; - overflow:hidden; - } - .dhx_cal_ltext textarea{ - background-color:transparent; - overflow:auto; - border:none; - color:#887A2E; - height:100%; - width:100%; - outline:none !important; - } - .dhx_time{ - font-weight:bold; - } - .dhx_cal_light .dhx_title{ - padding-left:10px; - } - .dhx_cal_larea{ - border:1px solid #DCC43E; - background-color:#FFF4B5; - overflow:hidden; - - margin-left:3px; - - width:572px; - height:1px; - } - .dhx_btn_set{ - padding:5px 10px 0px 10px; - float:left; - } - .dhx_btn_set div{ - float:left; - height:21px; - line-height:21px; - vertical-align:middle; - cursor:pointer; - } - .dhx_save_btn{ - background-image:url('./imgs/controls.gif'); - background-position:-84px 0px; - width:21px; - - } - .dhx_cancel_btn{ - background-image:url('./imgs/controls.gif'); - background-position:-63px 0px; - width:20px; - } - .dhx_delete_btn{ - background-image:url('./imgs/controls.gif'); - background-position:-42px 0px; - width:20px; - } - .dhx_cal_cover{ - width:100%; - height:100%; - position:absolute; - z-index:10000; - top:0px; - left:0px; - background-color:black; - - opacity:0.1; - filter:alpha(opacity=10); - } - .dhx_custom_button{ - padding:0px 3px 0px 3px; - color:#887A2E; - font-family:Tahoma; - font-size:8pt; - background-color:#FFE763; - font-weight:normal; - margin-right:5px; - margin-top:5px; - cursor:pointer; - } - .dhx_custom_button div{ - cursor:pointer; - float:left; - height:21px; - line-height:21px; - vertical-align:middle; - } - - .dhx_fullday_checkbox { - padding-top: 5px; - float:right; - } - - .dhx_fullday_checkbox input{ - vertical-align: middle; - } - - .dhx_fullday_checkbox label{ - font-size: 12pt; - font-weight: bold; - vertical-align: middle; - } \ No newline at end of file +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +.dhx_unselectable, .dhx_unselectable div{ + -webkit-user-select:none; + -moz-user-select:none; + -moz-user-select:-moz-none; +} +.dhx_cal_light{ + background-color:#FFE763; + border-radius:5px; + font-family:Tahoma; + font-size:8pt; + border:1px solid #B7A64B; + color:#887A2E; + + position:absolute; + z-index:10001; + + width:580px; + height:300px; + + box-shadow:5px 5px 5px #888; +} +.dhx_cal_light_wide{ + width:650px; +} +.dhx_mark{ + position:relative; top:3px; + background-image:url('./imgs/controls.gif'); + background-position: 0px -43px; + padding-left:10px; +} +.dhx_ie6 .dhx_mark{ + background-position: 6px -41px; +} + +.dhx_cal_light select{ + font-family:Tahoma; + font-size:8pt; + color:#887A2E; + padding:2px; + margin:0px; +} +.dhx_cal_ltitle{ + padding:2px 0px 2px 5px; + overflow:hidden; + white-space:nowrap; +} +.dhx_cal_ltitle span{ + white-space:nowrap; +} +.dhx_cal_lsection{ + background-color:#DBCF8C; + color:#FFF4B5; + font-weight:bold; + padding:5px 0px 3px 10px; +} +.dhx_section_time{ + background-color:#DBCF8C; +} +.dhx_cal_lsection .dhx_fullday{ + float:right; + margin-right:5px; + color:#887A2E; + font-size:12px; + font-weight:normal; + line-height:20px; + vertical-align:top; + cursor:pointer; +} +.dhx_cal_lsection{ + font-size:18px; + font-family:Arial; +} +.dhx_cal_ltext{ + padding:2px 0px 2px 10px; + overflow:hidden; +} +.dhx_cal_ltext textarea{ + background-color: #FFF4B5; /* #FFF4B5; should be the same for dhx_cal_larea, was transperent */ + overflow:auto; + border:none; + color:#887A2E; + height:100%; + width:100%; + outline:none !important; +} +.dhx_time{ + font-weight:bold; +} +.dhx_cal_light .dhx_title{ + padding-left:10px; +} +.dhx_cal_larea{ + border:1px solid #DCC43E; + background-color:#FFF4B5; + overflow:hidden; + + margin-left:3px; + + width:572px; + height:1px; +} +.dhx_btn_set{ + padding:5px 10px 0px 10px; + float:left; +} +.dhx_btn_set div{ + float:left; + height:21px; + line-height:21px; + vertical-align:middle; + cursor:pointer; +} +.dhx_save_btn{ + background-image:url('./imgs/controls.gif'); + background-position:-84px 0px; + width:21px; + +} +.dhx_cancel_btn{ + background-image:url('./imgs/controls.gif'); + background-position:-63px 0px; + width:20px; +} +.dhx_delete_btn{ + background-image:url('./imgs/controls.gif'); + background-position:-42px 0px; + width:20px; +} +.dhx_cal_cover{ + width:100%; + height:100%; + position:absolute; + z-index:10000; + top:0px; + left:0px; + background-color:black; + + opacity:0.1; + filter:alpha(opacity=10); +} +.dhx_custom_button{ + padding:0px 3px 0px 3px; + color:#887A2E; + font-family:Tahoma; + font-size:8pt; + background-color:#FFE763; + font-weight:normal; + margin-right:5px; + margin-top:0px; + cursor:pointer; +} +.dhx_custom_button div{ + cursor:pointer; + float:left; + height:21px; + line-height:21px; + vertical-align:middle; +} + + +.dhx_cal_light_wide .dhx_cal_larea{ + border-top-width:0px; +} +.dhx_cal_light_wide .dhx_cal_lsection{ + border:0px; + float:left; + text-align:right; + width:100px; + height:20px; + font-size:16px; + padding: 5px 0px 0px 10px; +} +.dhx_cal_light_wide .dhx_wrap_section{ + border-top:1px solid #DBCF8C; + position:relative; + background-color:#DBCF8C; + overflow:hidden; +} +.dhx_cal_light_wide .dhx_section_time{ + padding-top:2px !important; + height:20px !important; +} +.dhx_section_time{ + text-align: center; +} +.dhx_cal_light_wide .dhx_cal_larea{ + width:730px; +} +.dhx_cal_light_wide{ + width:738px; +} + +.dhx_cal_light_wide .dhx_section_time{ + background:transparent; +} +.dhx_cal_light_wide .dhx_cal_checkbox label{ + padding-left:0px; +} +.dhx_cal_wide_checkbox input{ + margin-top:8px; + margin-left:14px; +} +.dhx_cal_light input{ + font-family:Tahoma; + font-size:8pt; + color:#887A2E; +} +.dhx_cal_light_wide .dhx_cal_lsection .dhx_fullday{ + float:none; + margin-right:0px; + color:#FFF4B5; + font-weight:bold; + font-size:16px; + font-family:Arial; + cursor:pointer; +} +.dhx_custom_button{ + float: right; + height: 21px; + width:90px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; +} +.dhx_cal_light_wide .dhx_custom_button { + position:absolute; + top:0; + right:0; + margin-top: 2px; +} +.dhx_cal_light_wide .dhx_repeat_right { + margin-right: 55px; +} \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.js index 2a928a34831..7749ff6708c 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/lightbox.js @@ -1,4 +1,40 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.formSection = function(name){ + var config = this.config.lightbox.sections; + var i =0; + for (i; i < config.length; i++) + if (config[i].name == name) + break; + var section = config[i]; + var node = document.getElementById(section.id).nextSibling; + + return { + getValue:function(ev){ + return scheduler.form_blocks[section.type].get_value(node, (ev||{}), section); + }, + setValue:function(value, ev){ + return scheduler.form_blocks[section.type].set_value(node, value, (ev||{}), section); + } + }; +}; scheduler.form_blocks={ + template:{ + render: function(sns){ + var height=(sns.height||"30")+"px"; + return "
"; + }, + set_value:function(node,value,ev,config){ + node.innerHTML = value||""; + }, + get_value:function(node,ev,config){ + return node.innerHTML||""; + }, + focus: function(node){ + } + }, textarea:{ render:function(sns){ var height=(sns.height||"130")+"px"; @@ -17,7 +53,7 @@ scheduler.form_blocks={ select:{ render:function(sns){ var height=(sns.height||"23")+"px"; - var html="
"; for (var i=0; i < sns.options.length; i++) html+=""; html+="
"; @@ -48,10 +84,16 @@ scheduler.form_blocks={ } var html=" "; - return "
"+html+"  –  "+html+"
"; + return "
"+html+"  –  "+html+"
"; }, set_value:function(node,value,ev){ + var s=node.getElementsByTagName("select"); if(scheduler.config.full_day) { if (!node._full_day){ - node.previousSibling.innerHTML+="
"; + var html = ""; + if (!scheduler.config.wide_form) + html = node.previousSibling.innerHTML+html; + node.previousSibling.innerHTML=html; node._full_day=true; } var input=node.previousSibling.getElementsByTagName("input")[0]; - var isFulldayEvent = (scheduler.date.time_part(ev.start_date)==0 && scheduler.date.time_part(ev.end_date)==0 && ev.end_date.valueOf()-ev.start_date.valueOf() < 2*24*60*60*1000); + var isFulldayEvent = (scheduler.date.time_part(ev.start_date)===0 && scheduler.date.time_part(ev.end_date)===0 && ev.end_date.valueOf()-ev.start_date.valueOf() < 2*24*60*60*1000); input.checked = isFulldayEvent; for(var k in s) @@ -96,14 +142,14 @@ scheduler.form_blocks={ var end_date = new Date(ev.end_date); scheduler.date.date_part(start_date); - end_date = scheduler.date.add(start_date, 1, "day") + end_date = scheduler.date.add(start_date, 1, "day"); } for(var i in s) s[i].disabled=input.checked; _fill_lightbox_select(s,0,start_date||ev.start_date); _fill_lightbox_select(s,4,end_date||ev.end_date); - } + }; } if(scheduler.config.auto_end_date && scheduler.config.event_duration) { @@ -138,16 +184,29 @@ scheduler.form_blocks={ node.getElementsByTagName("select")[0].focus(); } } -} +}; scheduler.showCover=function(box){ - this.show_cover(); if (box){ box.style.display="block"; - var pos = getOffset(this._obj); - box.style.top=Math.round(pos.top+(this._obj.offsetHeight-box.offsetHeight)/2)+"px"; - box.style.left=Math.round(pos.left+(this._obj.offsetWidth-box.offsetWidth)/2)+"px"; + + var scroll_top = window.pageYOffset||document.body.scrollTop||document.documentElement.scrollTop; + var scroll_left = window.pageXOffset||document.body.scrollLeft||document.documentElement.scrollLeft; + + var view_height = window.innerHeight||document.documentElement.clientHeight; + + if(scroll_top) // if vertical scroll on window + box.style.top=Math.round(scroll_top+Math.max((view_height-box.offsetHeight)/2, 0))+"px"; + else // vertical scroll on body + box.style.top=Math.round(Math.max(((view_height-box.offsetHeight)/2), 0) + 9)+"px"; // +9 for compatibility with auto tests + + // not quite accurate but used for compatibility reasons + if(document.documentElement.scrollWidth > document.body.offsetWidth) // if horizontal scroll on the window + box.style.left=Math.round(scroll_left+(document.body.offsetWidth-box.offsetWidth)/2)+"px"; + else // horizontal scroll on the body + box.style.left=Math.round((document.body.offsetWidth-box.offsetWidth)/2)+"px"; } -} + this.show_cover(); +}; scheduler.showLightbox=function(id){ if (!id) return; if (!this.callEvent("onBeforeLightbox",[id])) return; @@ -155,7 +214,7 @@ scheduler.showLightbox=function(id){ this.showCover(box); this._fill_lightbox(id,box); this.callEvent("onLightbox",[id]); -} +}; scheduler._fill_lightbox=function(id,box){ var ev=this.getEvent(id); var s=box.getElementsByTagName("span"); @@ -172,24 +231,25 @@ scheduler._fill_lightbox=function(id,box){ for (var i=0; i < sns.length; i++) { var node=document.getElementById(sns[i].id).nextSibling; var block=this.form_blocks[sns[i].type]; - block.set_value.call(this,node,ev[sns[i].map_to],ev, sns[i]) + block.set_value.call(this,node,ev[sns[i].map_to],ev, sns[i]); if (sns[i].focus) block.focus.call(this,node); - }; + } scheduler._lightbox_id=id; -} +}; scheduler._lightbox_out=function(ev){ var sns = this.config.lightbox.sections; for (var i=0; i < sns.length; i++) { - var node=document.getElementById(sns[i].id).nextSibling; + var node = document.getElementById(sns[i].id); + node=(node?node.nextSibling:node); var block=this.form_blocks[sns[i].type]; var res=block.get_value.call(this,node,ev, sns[i]); if (sns[i].map_to!="auto") ev[sns[i].map_to]=res; } return ev; -} +}; scheduler._empty_lightbox=function(){ var id=scheduler._lightbox_id; var ev=this.getEvent(id); @@ -199,38 +259,41 @@ scheduler._empty_lightbox=function(){ ev._timed=this.is_one_day_event(ev); this.setEvent(ev.id,ev); - this._edit_stop_event(ev,true) + this._edit_stop_event(ev,true); this.render_view_data(); -} +}; scheduler.hide_lightbox=function(id){ this.hideCover(this._get_lightbox()); this._lightbox_id=null; this.callEvent("onAfterLightbox",[]); -} +}; scheduler.hideCover=function(box){ if (box) box.style.display="none"; this.hide_cover(); -} +}; scheduler.hide_cover=function(){ if (this._cover) this._cover.parentNode.removeChild(this._cover); this._cover=null; -} +}; scheduler.show_cover=function(){ this._cover=document.createElement("DIV"); this._cover.className="dhx_cal_cover"; + var _document_height = ((document.height !== undefined) ? document.height : document.body.offsetHeight); + var _scroll_height = ((document.documentElement) ? document.documentElement.scrollHeight : 0); + this._cover.style.height = Math.max(_document_height, _scroll_height) + 'px'; document.body.appendChild(this._cover); -} +}; scheduler.save_lightbox=function(){ - if (this.checkEvent("onEventSave") && !this.callEvent("onEventSave",[this._lightbox_id,this._lightbox_out({ id: this._lightbox_id}), this._new_event])) + if (this.checkEvent("onEventSave") && !this.callEvent("onEventSave",[this._lightbox_id,this._lightbox_out({ id: this._lightbox_id}), this._new_event])) return; - this._empty_lightbox() + this._empty_lightbox(); this.hide_lightbox(); }; scheduler.startLightbox = function(id, box){ this._lightbox_id=id; this.showCover(box); -} +}; scheduler.endLightbox = function(mode, box){ this._edit_stop_event(scheduler.getEvent(this._lightbox_id),mode); if (mode) @@ -238,6 +301,8 @@ scheduler.endLightbox = function(mode, box){ this.hideCover(box); }; scheduler.resetLightbox = function(){ + if (scheduler._lightbox) + scheduler._lightbox.parentNode.removeChild(scheduler._lightbox); scheduler._lightbox = null; }; scheduler.cancel_lightbox=function(){ @@ -267,15 +332,18 @@ scheduler._init_lightbox_events=function(){ break; default: - if (src.className.indexOf("dhx_custom_button_")!=-1){ + if (src.getAttribute("dhx_button")){ + scheduler.callEvent("onLightboxButton", [src.className, src, e]); + } else if (src.className.indexOf("dhx_custom_button_")!=-1){ var index = src.parentNode.getAttribute("index"); var block=scheduler.form_blocks[scheduler.config.lightbox.sections[index].type]; var sec = src.parentNode.parentNode; block.button_click(index,src,sec,sec.nextSibling); } + break; } }; - this._get_lightbox().onkeypress=function(e){ + this._get_lightbox().onkeydown=function(e){ switch((e||event).keyCode){ case scheduler.keys.edit_save: if ((e||event).shiftKey) return; @@ -284,9 +352,11 @@ scheduler._init_lightbox_events=function(){ case scheduler.keys.edit_cancel: scheduler.cancel_lightbox(); break; + default: + break; } - } -} + }; +}; scheduler.setLightboxSize=function(){ var d = this._lightbox; if (!d) return; @@ -296,36 +366,92 @@ scheduler.setLightboxSize=function(){ con.style.height=con.scrollHeight+"px"; d.style.height=con.scrollHeight+50+"px"; con.style.height=con.scrollHeight+"px"; //it is incredible , how ugly IE can be -} +}; -scheduler._get_lightbox=function(){ +scheduler._init_dnd_events = function(){ + dhtmlxEvent(document.body, "mousemove", scheduler._move_while_dnd); + dhtmlxEvent(document.body, "mouseup", scheduler._finish_dnd); + scheduler._init_dnd_events = function(){}; +}; +scheduler._move_while_dnd = function(e){ + if (scheduler._dnd_start_lb){ + if (!document.dhx_unselectable){ + document.body.className += " dhx_unselectable"; + document.dhx_unselectable = true; + } + var lb = scheduler._get_lightbox(); + var now = (e&&e.target)?[e.pageX, e.pageY]:[event.clientX, event.clientY]; + lb.style.top = scheduler._lb_start[1]+now[1]-scheduler._dnd_start_lb[1]+"px"; + lb.style.left = scheduler._lb_start[0]+now[0]-scheduler._dnd_start_lb[0]+"px"; + } +}; +scheduler._ready_to_dnd = function(e){ + var lb = scheduler._get_lightbox(); + scheduler._lb_start = [parseInt(lb.style.left,10), parseInt(lb.style.top,10)]; + scheduler._dnd_start_lb = (e&&e.target)?[e.pageX, e.pageY]:[event.clientX, event.clientY]; +}; +scheduler._finish_dnd = function(){ + if (scheduler._lb_start){ + scheduler._lb_start = scheduler._dnd_start_lb = false; + document.body.className = document.body.className.replace(" dhx_unselectable",""); + document.dhx_unselectable = false; + } +}; +scheduler._get_lightbox=function(){ //scheduler.config.wide_form=true; if (!this._lightbox){ var d=document.createElement("DIV"); d.className="dhx_cal_light"; + if (scheduler.config.wide_form) + d.className+=" dhx_cal_light_wide"; + if (scheduler.form_blocks.recurring) + d.className+=" dhx_cal_light_rec"; + if (/msie|MSIE 6/.test(navigator.userAgent)) d.className+=" dhx_ie6"; d.style.visibility="hidden"; - d.innerHTML=this._lightbox_template; + var html = this._lightbox_template + var buttons = this.config.buttons_left; + scheduler.locale.labels["dhx_save_btn"] = scheduler.locale.labels.icon_save; + scheduler.locale.labels["dhx_cancel_btn"] = scheduler.locale.labels.icon_cancel; + scheduler.locale.labels["dhx_delete_btn"] = scheduler.locale.labels.icon_delete; + for (var i = 0; i < buttons.length; i++) + html+="
"+scheduler.locale.labels[buttons[i]]+"
"; + buttons = this.config.buttons_right; + for (var i = 0; i < buttons.length; i++) + html+="
"+scheduler.locale.labels[buttons[i]]+"
"; + + html+=""; + d.innerHTML=html; + if (scheduler.config.drag_lightbox){ + d.firstChild.onmousedown = scheduler._ready_to_dnd; + d.firstChild.onselectstart = function(){ return false; }; + d.firstChild.style.cursor = "pointer"; + scheduler._init_dnd_events(); + + } document.body.insertBefore(d,document.body.firstChild); this._lightbox=d; var sns=this.config.lightbox.sections; - var html=""; + html=""; for (var i=0; i < sns.length; i++) { var block=this.form_blocks[sns[i].type]; if (!block) continue; //ignore incorrect blocks sns[i].id="area_"+this.uid(); var button = ""; - if (sns[i].button) button = "
"+this.locale.labels["button_"+sns[i].button]+"
"; + if (sns[i].button){ + button = "
"+this.locale.labels["button_"+sns[i].button]+"
"; + } + + if (this.config.wide_form){ + html+="
"; + } html+="
"+button+this.locale.labels["section_"+sns[i].name]+"
"+block.render.call(this,sns[i]); - }; + html+="
" + } - //localization var ds=d.getElementsByTagName("div"); - ds[4].innerHTML=scheduler.locale.labels.icon_save; - ds[7].innerHTML=scheduler.locale.labels.icon_cancel; - ds[10].innerHTML=scheduler.locale.labels.icon_delete; //sections ds[1].innerHTML=html; //sizes @@ -336,5 +462,5 @@ scheduler._get_lightbox=function(){ d.style.visibility="visible"; } return this._lightbox; -} -scheduler._lightbox_template="
 
 
 
 
"; \ No newline at end of file +}; +scheduler._lightbox_template="
 
"; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/load.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/load.js index cb81b4ee2ee..6d1579862ff 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/load.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/load.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler._loaded={}; scheduler._load=function(url,from){ url=url||this._load_url; @@ -38,13 +42,14 @@ scheduler._load=function(url,from){ dhtmlxAjax.get(url,function(l){scheduler.on_load(l);}); this.callEvent("onXLS",[]); return true; -} +}; scheduler.on_load=function(loader){ this._loading=true; + var evs; if (this._process) - var evs=this[this._process].parse(loader.xmlDoc.responseText); + evs=this[this._process].parse(loader.xmlDoc.responseText); else - var evs=this._magic_parser(loader); + evs=this._magic_parser(loader); this._not_render=true; for (var i=0; i
'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_cs.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_cs.js index 69fd9d50454..310f5c508fb 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_cs.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_cs.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.__recurring_template='
@@ -145,7 +149,7 @@ scheduler.__recurring_template=' -
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_da.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_da.js new file mode 100644 index 00000000000..1d3e272a936 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_da.js @@ -0,0 +1,6 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



i hvermåned
hvermåned

gentagelse

'; + diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_de.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_de.js index f74afa55dc1..71929e988ea 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_de.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_de.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



Tag eines jedenMonats
jedenMonats

Ereignissen

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



Tag eines jedenMonats
jedenMonats

Ereignissen

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_el.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_el.js new file mode 100644 index 00000000000..d3d18ab4358 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_el.js @@ -0,0 +1,6 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



ημέρα κάθεμήνα
κάθεμήνα

επαναλήψεις

'; + diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_es.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_es.js index 77b3539d21a..99bb3fdbfa5 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_es.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_es.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



dia cada mes
cadames

occurencias

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



dia cada mes
cadames

occurencias

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fi.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fi.js index 93d4675df3b..02184e9b601 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fi.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fi.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



päivänä jokakuukausi
jokakuukausi

Toiston jälkeen

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



päivänä jokakuukausi
jokakuukausi

Toiston jälkeen

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fr.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fr.js index 66601553fdb..d11418acba3 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fr.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_fr.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



jour chaquemois
chaquemois

occurrences

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



jour chaquemois
chaquemois

occurrences

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_it.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_it.js index 8c0e82b7c12..a40b63939d3 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_it.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_it.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



giorno ognimese
ognimese

occorenze

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



giorno ognimese
ognimese

occorenze

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nb.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nb.js new file mode 100644 index 00000000000..65078dbc0b7 --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nb.js @@ -0,0 +1,5 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



dag hvermåned
hvermåned

forekomst

'; \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nl.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nl.js index 4ccfb09e526..314e1b083ad 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nl.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_nl.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



dag iederemaanden
iederemaanden

keren

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



dag iederemaanden
iederemaanden

keren

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pl.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pl.js index b11a117a507..f3f27bf4eb1 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pl.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pl.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



dnia ka�degomiesi�ca
ka�degomiesi�ca

wyst�pieniu/ach

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



dnia ka�degomiesi�ca
ka�degomiesi�ca

wyst�pieniu/ach

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pt.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pt.js index 665e26d7a43..c15c10cbea4 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pt.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_pt.js @@ -1 +1,5 @@ -scheduler.__recurring_template='



todo diamês
todomês

ocorrências

'; \ No newline at end of file +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



todo diamês
todomês

ocorrências

'; \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ru.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ru.js index 1919fe21b28..0bff7bde13a 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ru.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ru.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



числа каждый месяц
каждый месяц

повторений

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



числа каждый месяц
каждый месяц

повторений

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_sv.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_sv.js index 3087f904bcb..bb16adafb12 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_sv.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_sv.js @@ -1 +1,5 @@ -scheduler.__recurring_template='



dagen varmånad
varmånad

upprepningar

'; \ No newline at end of file +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



dagen varmånad
varmånad

upprepningar

'; \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ua.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ua.js index 5b723675b69..fbe032f3e32 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ua.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_ua.js @@ -1,2 +1,6 @@ -scheduler.__recurring_template='



числа кожний місяць
кожен місяць

повторень

'; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.__recurring_template='



числа кожний місяць
кожен місяць

повторень

'; diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ru.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ru.js index 485cd795488..f199ae683e4 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ru.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ru.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.locale={ date:{ month_full:["Январь", "Февраль", "Март", "Апрель", "Maй", "Июнь", "Июль", "Август", "Сентябрь", "Oктябрь", "Ноябрь", "Декабрь"], @@ -33,6 +37,9 @@ scheduler.locale={ description:"Описание", /*year view extension*/ - year_tab:"Год" + year_tab:"Год", + + /*week agenda view extension*/ + week_agenda_tab: "Список" } } diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_si.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_si.js index 29da1a35bc0..1225b6ece32 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_si.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_si.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.locale={ date:{ month_full:["Januar", "Februar", "Marec", "April", "Maj", "Junij", "Julij", "Avgust", "September", "Oktober", "November", "December"], @@ -34,7 +38,10 @@ scheduler.locale={ description:"Opis", /*year view extension*/ - year_tab:"Leto" + year_tab:"Leto", + + /*week agenda view extension*/ + week_agenda_tab: "Agenda" } } diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_sv.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_sv.js index 76bf908acec..bcb120831e9 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_sv.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_sv.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ /* Copyright DHTMLX LTD. http://www.dhtmlx.com You allowed to use this component or parts of it under GPL terms @@ -40,6 +44,9 @@ scheduler.locale={ description:"Beskrivning", /*year view extension*/ - year_tab:"År" + year_tab:"År", + + /*week agenda view extension*/ + week_agenda_tab: "Dagordning" } } \ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_tr.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_tr.js new file mode 100644 index 00000000000..5548a6f0dfc --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_tr.js @@ -0,0 +1,47 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +scheduler.locale={ + date:{ + month_full:["Ocak", "ubat", "Mart", "Nisan", "Mays", "Haziran", "Temmuz", "Austos", "Eyll", "Ekim", "Kasm", "Aralk"], + month_short:["Oca", "ub", "Mar", "Nis", "May", "Haz", "Tem", "Au", "Eyl", "Eki", "Kas", "Ara"], + day_full:["Pazar", "Pazartes,", "Sal", "aramba", "Perembe", "Cuma", "Cumartesi"], + day_short:["Paz", "Pts", "Sal", "ar", "Per", "Cum", "Cts"] + }, + labels:{ + dhx_cal_today_button:"Bugn", + day_tab:"Gn", + week_tab:"Hafta", + month_tab:"Ay", + new_event:"Uygun", + icon_save:"Kaydet", + icon_cancel:"ptal", + icon_details:"Detaylar", + icon_edit:"Dzenle", + icon_delete:"Sil", + confirm_closing:"",//Your changes will be lost, are your sure ? + confirm_deleting:"Etkinlik silinecek, devam?", + section_description:"Aklama", + section_time:"Zaman aral", + full_day:"Tam gn", + + /*recurring events*/ + confirm_recurring:"Tm tekrar eden etkinlikler silinecek, devam?", + section_recurring:"Etkinlii tekrarla", + button_recurring:"Pasif", + button_recurring_open:"Aktif", + + /*agenda view extension*/ + agenda_tab:"Ajanda", + date:"Tarih", + description:"Aklama", + + /*year view extension*/ + year_tab:"Yl", + + /*week agenda view extension*/ + week_agenda_tab: "Ajanda" + } +} + diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ua.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ua.js index a7c946159e1..4009969d298 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ua.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/locale_ua.js @@ -1,3 +1,7 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ scheduler.locale={ date:{ month_full:["Січень", "Лютий", "Березень", "Квітень", "Травень", "Червень", "Липень", "Серпень", "Вересень", "Жовтень", "Листопад", "Грудень"], @@ -34,7 +38,10 @@ scheduler.locale={ description:"Опис", /*year view extension*/ - year_tab:"Рік" + year_tab:"Рік", + + /*week agenda view extension*/ + week_agenda_tab: "Перелік" } } diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/mobile.css b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/mobile.css new file mode 100644 index 00000000000..8f543f20fee --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/mobile.css @@ -0,0 +1,380 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +/**Toolbar**/ + +.dhx_schedulerbar{ + background: -webkit-gradient(linear, left top, left bottom,from(#d7d7d7), to(#b7b7b7)); + background: -moz-linear-gradient(top, #d7d7d7, #b7b7b7); +} +.dhx_el_button input { + border-radius:4px; + -moz-border-radius:4px; + -webkit-border-radius:4px; + background: -webkit-gradient(linear, left top, left bottom, from(#9dbcc7),color-stop(0.4,#80a9b8),color-stop(0.6,#6799aa),to(#4f899d)); + background: -moz-linear-gradient(top, #9dbcc7, #518a9e); + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.6); + font-size: 14px; + color: #ffffff; + padding: 0px 10px; + border:1px solid #636363; + -moz-box-shadow: 0px 1px #ffffff; + -webkit-box-shadow:0px 1px #ffffff; + box-shadow: 0px 1px #ffffff; +} +.add .dhx_el_button input{ + background-image: url(./imgs_mobile/add.png),-webkit-gradient(linear, left top, left bottom, from(#9dbcc7),color-stop(0.4,#80a9b8),color-stop(0.6,#6799aa),to(#4f899d)); + background-image: url(./imgs_mobile/add.png),-moz-linear-gradient(top, #9dbcc7, #518a9e); + background-position: center center; + background-repeat:no-repeat; + width:34px; +} +.dhx_schedulerbar .dhx_el_segmented{ + border-radius:4px; + -moz-border-radius:4px; + -webkit-border-radius:4px; + float:none !important; + border:1px solid #636363; + -moz-box-shadow: 0px 1px #ffffff; + -webkit-box-shadow:0px 1px #ffffff; + height:32px; +} + + +.dhx_schedulerbar .dhx_el_segmented .segment_0,.dhx_schedulerbar .dhx_el_segmented .segment_1, .dhx_schedulerbar .dhx_el_segmented .segment_N { + background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8),color-stop(0.3,#eeeeee),color-stop(0.6,#dcdcdc),to(#d5d5d5)); + background: -moz-linear-gradient(top, #f8f8f8, #d5d5d5); + +} +.dhx_schedulerbar .dhx_el_segmented .selected.segment_0 ,.dhx_schedulerbar .dhx_el_segmented .selected.segment_1, .dhx_schedulerbar .dhx_el_segmented .selected.segment_N { + background: -webkit-gradient(linear, left top, left bottom, from(#9dbcc7),color-stop(0.4,#80a9b8),color-stop(0.6,#6799aa),to(#4f899d)); + background: -moz-linear-gradient(top, #9dbcc7, #518a9e); +} +.dhx_el_segmented .segment_N, .dhx_el_segmented .selected.segment_N { + border-left: 0; +} +.dhx_schedulerbar .dhx_el_segmented div { + text-shadow: 0 1px 0 #ffffff; + font-size: 14px; + color: #757575; + border:0px; + height:30px; +} +.dhx_schedulerbar .dhx_el_segmented div.selected { + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.6); + color: #ffffff; + height:30px; +} + + +.dhx_schedulerbar .dhx_el_segmented .segment_0{ + -webkit-border-top-left-radius: 4px; + -webkit-border-bottom-left-radius: 4px; + -moz-border-radius-topleft: 4px; + -moz-border-radius-bottomleft: 4px; + border-top-left-radius: 4px; + border-bottom-left-radius: 4px; + padding:0 11px 0 14px; +} +.dhx_schedulerbar .dhx_el_segmented .segment_1{ + border-left:1px solid #ababab; + border-right:1px solid #ababab; + padding:0 11px; +} +.dhx_schedulerbar .dhx_el_segmented .segment_N{ + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + padding:0 14px 0 11px; +} + + +/**Day Events**/ + +/*scale:*/ +/*scale item container*/ +.dhx_dayevents_scale_item { + -moz-user-select:-moz-none; + border-bottom:1px solid #D4D4D4; + color:#303030; + font-family:"Helvetica World","HelveticaNeue","Helvetica Neue","HelveticaNeueRoman","Helvetica","Tahoma","Geneva","Arial",sans-serif; + white-space:nowrap; +} +/*hour container*/ +.dhx_dayevents_scale_hour{ + float: left; + text-align: center; + font-size: 16px; + vertical-align:middle; + font-weight: bold; + /*background-color:#E1E6FF;*/ + /*background-color: #EEE;*/ +} +/*scale items*/ +.dhx_dayevents_scale_top, .dhx_dayevents_scale_bottom { + font-size: 10px; + float: left; + text-align:center; +} +.dhx_dayevents_scale_top{ + border-bottom:1px dotted #D4D4D4; +} +/*minutes container*/ +.dhx_dayevents_scale_minute{ + /*background-color:#E1E6FF;*/ + background-color: #EEE; + border-right:1px dotted #D4D4D4; + float:left; +} +/*event container*/ +.dhx_dayevents_scale_event { + float:left; +} +/*event:*/ +.dhx_dayevents_event_item{ + position:absolute; + border-radius: 4px; + -moz-border-radius: 4px; + -webkit-border-radius:4px; + font-size: 12px; + background-color: #e6f8ff; + border:1px solid #78a5b4; + font-family:"Helvetica World","HelveticaNeue","Helvetica Neue","HelveticaNeueRoman","Helvetica","Tahoma","Geneva","Arial",sans-serif; + /*-moz-box-shadow: 1px 1px 1px #888; + -webkit-box-shadow: 1px 1px 1px #888; + box-shadow: 1px 1px 1px #888;*/ +} +/*toolbar*/ +.dhx_topbar{ + font-size:18px; + background: -webkit-gradient(linear, left top, left bottom, from(#fdfdfd),color-stop(0.5, #ededed), to(#c8c8c8)) !important; + background: -moz-linear-gradient(top, #fdfdfd, #c8c8c8) !important; +} + + +/**List view**/ +.dhx_list_events_item{ + position:relative; + background-color:#ffffff; +} +.dhx_list_events_item .dhx_day_title{ + height:16px; + line-height:16px; + width:75px; + position:absolute; + left:1px; + top:0px; + /*background-color: #d23530;*/ + background: #518A9E; + border-radius: 2px; + text-align:center; + -moz-border-radius: 2px; + -moz-box-shadow: 1px 1px 1px #1c2329; + -webkit-box-shadow: 1px 1px 1px #1c2329; + box-shadow: 1px 1px 1px #1c2329; + -webkit-border-radius:2px; + text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.6); + font-size: 14px; + color: #ffffff; +} +.dhx_list_events_item .dhx_event_marker{ + display:inline-block; + margin-left:5px; + margin-top:5px; + height:10px; + /*line-height:22px;*/ + width:10px; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius:6px; + background-color: #e6f8ff; + border:1px solid #78a5b4; + vertical-align:top; +} + +.dhx_list_events_item .dhx_event_time{ + display:inline-block; + width:70px; + font-size:16px; + padding-top:8px; +} + +.dhx_list_events_item .dhx_event_text{ + display:inline-block; + padding-left:4px; + overflow:hidden; + height:22px; + vertical-align:top; + /*width:208px;*/ + white-space:nowrap; +} + + +/**Month events**/ + +/*calendar*/ +.dhx_cal_day_num.dhx_cal_selected_day, .dhx_cal_day_num.dhx_cal_current_day.dhx_cal_selected_day{ + background: -webkit-gradient(linear, left top, left bottom, from(#a0bfc9), to(#4f899d)) !important; + background: -moz-linear-gradient(top, #a0bfc9, #4f899d); + text-shadow:0 1px 0 rgba(0, 0, 0, 0.6); +} +.dhx_cal_day_num.dhx_cal_current_day { + background: -webkit-gradient(linear, left top, left bottom, from(#bababa), to(#eeeeee)) !important; + background: -moz-linear-gradient(top, #bababa, #eeeeee); + border-color:#636363; + text-shadow: 0 1px 0 rgba(0, 0, 0, 0.6); +} +.dhx_cal_day_num.dhx_cal_selected_day span{ + color:#ffffff; +} +.dhx_cal_day_num{ + position:relative; +} +.dhx_cal_day_num .day_with_events{ + position:absolute; + bottom:0px; + right:0px; + background-image:url(./imgs_mobile/event.png); + background-repeat:no-repeat; + width:12px; + height:12px; +} +.dhx_cal_day_num.dhx_cal_selected_day .day_with_events{ + background-image:url(./imgs_mobile/event_focus.png); +} +.dhx_cal_prev_button div { + background-image:url("./imgs_mobile/arrow_left.png"); + background-position:0; + width:28px; + height:29px; + top:6px; +} +.dhx_cal_next_button div { + background-image:url("./imgs_mobile/arrow_right.png"); + background-position:0; + width:28px; + height:29px; + top:6px; +} +/*events list*/ +.dhx_list_day_events_item{ + background-color:#ffffff; +} +.dhx_list_day_events_item .dhx_event_marker{ + display:inline-block; + margin-top:16px; + margin-left:5px; + height:10px; + width:10px; + border-radius: 6px; + -moz-border-radius: 6px; + -webkit-border-radius:6px; + background-color: #e6f8ff; + border:1px solid #78a5b4; +} +.dhx_list_day_events_item .dhx_event_time{ + display:inline-block; + width:auto; + height:42px; + line-height:42px; + padding-left:5px; +} + +.dhx_list_day_events_item .dhx_event_text{ + display:inline-block; + padding-left:10px; + line-height:42px; +} + +/*No events BG*/ +.no_events{ + background-image:url(./imgs_mobile/noevents.png); + background-repeat:no-repeat; +} + + +/**Selected event view**/ +.selected_event{ + width: 290px; + margin:5px; + background-color: #e6f8ff; + border:1px solid #78a5b4; + border-radius: 5px; + -moz-border-radius: 5px; + -webkit-border-radius:5px; + padding:3px 6px; +} +.selected_event .event_title{ + font-weight:bold +} +.selected_event .event_text{ + font-size:12px; +} +/*toolbar*/ +/* +.dhx_topbar.single_event{ + background: -webkit-gradient(linear, left top, left bottom,from(#d6d6d6), to(#b8b8b8)) !important; + background: -moz-linear-gradient(top, #d6d6d6, #b8b8b8) !important; +} +*/ + + +/**Editing form**/ +.dhx_el_formbutton.delete .dhx_inp_form_button{ + background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8), to(#d4d4d4)); + background: -moz-linear-gradient(top, #f8f8f8, #d4d4d4); + border-top:1px solid #888; + font-size:18px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + border:1px solid #8f8f8f; + color:#606060; + text-shadow: 0 1px 0 #ffffff; + height:40px; + +} +.dhx_el_button.cancel input{ + background: -webkit-gradient(linear, left top, left bottom, from(#f8f8f8),color-stop(0.3,#eeeeee),color-stop(0.6,#dcdcdc),to(#d5d5d5)); + background: -moz-linear-gradient(top, #f8f8f8, #d5d5d5); + color:#6E6E6E; + text-shadow:0 1px 0 #FFFFFF +} +.invalid .dhx_inp_text_border{ + border-color:#cc0000; +} +.invalid .dhx_inp_list { + color:#cc0000; +} + +/*confirm*/ + + + + +.dhx_win_body{ + font-weight:bold; + color:#3f2317; + text-shadow: 0px 1px #e2d3b6; + background:url(../images/confirm_main_bgr.png); +} +.dhx_win_body .dhx_view{ + background:transparent; +} +.dhx_el_bigbutton input, .dhx_el_bigroundbutton input{ + height:40px; + line-height:40px; +} +.dhx_el_bigroundbutton input, .alert .dhx_el_bigbutton input{ + background: #83a41f; + background: -webkit-gradient(linear, left top, left bottom, from(#9dbcc7),color-stop(0.4,#80a9b8),color-stop(0.6,#6799aa),to(#4f899d)); + background: -moz-linear-gradient(top, #9dbcc7, #518a9e); +} +.dhx_el_bigroundbutton{ + padding-top:0px; +} + diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/mobile.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/mobile.js new file mode 100644 index 00000000000..4455ef939be --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/mobile.js @@ -0,0 +1,626 @@ +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +if (!window.scheduler){ + window.scheduler = { + config:{ + }, + templates:{ + }, + xy:{ + }, + locale:{ + } + }; +} +/*Locale*/ +if(!scheduler.locale) + scheduler.locale = {}; +scheduler.locale.labels = { + list_tab : "List", + day_tab : "Day", + month_tab : "Month", + icon_today : "Today", + icon_save : "Save", + icon_delete : "Delete event", + icon_cancel : "Cancel", + icon_edit : "Edit", + icon_back : "Back", + icon_close : "Close form", + icon_yes : "Yes", + icon_no : "No", + confirm_closing : "Your changes will be lost, are your sure ?", + confirm_deleting : "Event will be deleted permanently, are you sure?", + label_event:"Event", + label_start:"Start", + label_end:"End", + label_details:"Notes", + label_from: "from", + label_to: "to" +}; + +/*Config*/ + +/*date*/ + +scheduler.config = { + init_date : new Date(), + form_date : "%d-%m-%Y %H:%i", + xml_date : "%Y-%m-%d %H:%i", + item_date : "%d.%m.%Y", + header_date : "%d.%m.%Y", + hour_date : "%H:%i", + scale_hour : "%H", + calendar_date : "%F %Y" +}; + +scheduler.config.form_rules = { + end_date:function(value,obj){ + return (obj.start_date.valueOf() < value.valueOf()); + } +}; + +/*Dimentions*/ +scheduler.xy = { + confirm_height : 231, + confirm_width : 250, + scale_width : 45, + scale_height : 15, + list_tab:54, + day_tab:54, + month_tab:68, + icon_today : 72, + icon_save : 100, + icon_cancel : 100, + icon_edit : 100, + icon_back : 100, + list_height: 42, + month_list_height: 42 +} + +/*Templates*/ +scheduler.templates = { + selected_event : function(obj){ + var html = ""; + if(!obj.start_date) return html; + html += "
"; + html += "
"+obj.text+"
"; + if(dhx.Date.datePart(obj.start_date).valueOf()==dhx.Date.datePart(obj.end_date).valueOf()){ + var fd = dhx.i18n.dateFormatStr(obj.start_date); + var fts = dhx.i18n.timeFormatStr(obj.start_date); + var fte = dhx.i18n.timeFormatStr(obj.end_date); + html += "
"+fd+"
"; + html += "
"+scheduler.locale.labels.label_from+" "+fts+" "+scheduler.locale.labels.label_to+" "+fte+"
"; + } + else{ + var fds = dhx.i18n.longDateFormatStr(obj.start_date); + var fde = dhx.i18n.longDateFormatStr(obj.end_date); + var fts = dhx.i18n.timeFormatStr(obj.start_date); + var fte = dhx.i18n.timeFormatStr(obj.end_date); + html += "
"+scheduler.locale.labels.label_from+" "+fts+" "+fds+"
"; + html += "
"+scheduler.locale.labels.label_to+" "+fte+" "+fde+"
"; + } + if(obj.details&&obj.details!==""){ + html += "
"+scheduler.locale.labels.label_details+"
"; + html += "
"+obj.details+"
"; + } + html += "
"; + return html; + }, + calendar_event : function(date){ + return date+"
"; + }, + event_date: function(date){ + return dhx.i18n.dateFormatStr(date); + }, + event_long_date: function(date){ + return dhx.i18n.longDateFormatStr(date); + }, + event_time : function(date){ + return dhx.i18n.timeFormatStr(date); + }, + event_color : function(obj,type){ + return (obj.color?"background-color:"+obj.color:""); + }, + event_marker : function(obj,type){ + return "
"; + }, + event_title: function(obj,type){ + return "
"+type.dateStart(obj.start_date)+"
"+type.timeStart(obj.start_date)+"
"+type.marker(obj,type)+"
"+obj.text+"
"; + }, + month_event_title : function(obj,type){ + return type.marker(obj,type)+"
"+type.timeStart(obj.start_date)+"
"+obj.text+"
" + }, + day_event: function(obj,type){ + return obj.text + } +}; + +/*Views of scheduler multiview*/ +scheduler.config.views = []; + + +dhx.ready(function(){ + if (scheduler.locale&&scheduler.locale.date) + dhx.Date.Locale = scheduler.locale.date; + + if(!scheduler.config.form){ + scheduler.config.form = [ + {view:"text", label:scheduler.locale.labels.label_event, name:'text'}, + {view:"datepicker", label:scheduler.locale.labels.label_start, name:'start_date', timeSelect:1, dateFormat:scheduler.config.form_date}, + {view:"datepicker", label:scheduler.locale.labels.label_end, name:'end_date', timeSelect:1, dateFormat:scheduler.config.form_date}, + {view:"textarea", label:scheduler.locale.labels.label_details, name:'details', width:300, height:150}, + {view:"button", label:scheduler.locale.labels.icon_delete, id:'delete',type:"form" ,css:"delete"} + ]; + } + if(!scheduler.config.bottom_toolbar){ + scheduler.config.bottom_toolbar = [ + { view:"button",id:"today",label:scheduler.locale.labels.icon_today,inputWidth:scheduler.xy.icon_today, align:"left",width:scheduler.xy.icon_today+6}, + { view:"segmented", id:"buttons",selected:"list",align:"center",multiview:true, options:[ + {value:"list", label:scheduler.locale.labels.list_tab,width:scheduler.xy.list_tab}, + {value:"day", label:scheduler.locale.labels.day_tab,width:scheduler.xy.day_tab}, + {value:"month", label:scheduler.locale.labels.month_tab,width:scheduler.xy.month_tab} + ]}, + { view:"button",css:"add",id:"add", align:"right",label:"",inputWidth:42,width:50}, + { view:"label", label:"",inputWidth:42,width:50, batch:"readonly"} + ]; + } + if(!scheduler.config.day_toolbar){ + scheduler.config.day_toolbar = [ + {view:'label',id:"prev",align:"left",label:"
"}, + {view:'label',id:"date",align:"center",width:200}, + {view:'label',id:"next",align:"right",label:"
"} + ]; + } + if(!scheduler.config.selected_toolbar){ + scheduler.config.selected_toolbar = [ + {view:'button', inputWidth:scheduler.xy.icon_back, type:"prev", id:"back",align:"left",label:scheduler.locale.labels.icon_back}, + {view:'button', inputWidth:scheduler.xy.icon_edit, id:"edit",align:"right",label:scheduler.locale.labels.icon_edit} + ]; + } + if(!scheduler.config.form_toolbar){ + scheduler.config.form_toolbar = [ + {view:'button', inputWidth:scheduler.xy.icon_cancel, id:"cancel",css:"cancel",align:"left",label:scheduler.locale.labels.icon_cancel}, + {view:'button', inputWidth:scheduler.xy.icon_save, id:"save",align:"right",label:scheduler.locale.labels.icon_save} + ]; + } + + /*List types*/ + scheduler.types = { + event_list:{ + name:"EventsList", + css:"events", + cssNoEvents:"no_events", + padding:0, + height:scheduler.xy.list_height, + width:"auto", + dateStart:scheduler.templates.event_date, + timeStart:scheduler.templates.event_time, + color:scheduler.templates.event_color, + marker:scheduler.templates.event_marker, + template:scheduler.templates.event_title + }, + day_event_list:{ + name:"DayEventsList", + css:"day_events", + cssNoEvents:"no_events", + padding:0, + height:scheduler.xy.month_list_height, + width:"auto", + timeStart:scheduler.templates.event_time, + color:scheduler.templates.event_color, + marker:scheduler.templates.event_marker, + template:scheduler.templates.month_event_title + } + }; + + dhx.Type(dhx.ui.list, scheduler.types.event_list); + dhx.Type(dhx.ui.list, scheduler.types.day_event_list); + + dhx.DataDriver.scheduler = { + records:"/*/event" + }; + dhx.extend(dhx.DataDriver.scheduler,dhx.DataDriver.xml); + + /*the views of scheduler multiview*/ + var views = [ + { + id:"list", + view:"list", + type:"EventsList", + startDate:new Date() + }, + { + id:"day", + rows:[ + { + id:"dayBar", + view:"toolbar", + css:"dhx_topbar", + elements: scheduler.config.day_toolbar + }, + { + id:"dayList", + view:"dayevents" + } + ] + }, + { + id:"month", + rows:[ + { + id:"calendar", + view:"calendar", + dayWithEvents: scheduler.templates.calendar_event, + calendarHeader:scheduler.config.calendar_date + }, + { + id:"calendarDayEvents", + view:"list", + type:"DayEventsList" + } + ] + + }, + { + id:"event", + animate:{ + type:"slide", + subtype:"in", + direction:"top" + }, + rows:[ + { + id:"eventBar", + view:"toolbar", + type:"TopBar", + css:"single_event", + elements: scheduler.config.selected_toolbar + }, + { + id:"eventTemplate", + view:"template", + template:scheduler.templates.selected_event + } + + ] + }, + { + id:"form", + rows:[ + { + id:"editBar", + view:"toolbar", + type:"TopBar", + elements:scheduler.config.form_toolbar + }, + { + id:"editForm", + view:"form", + elements: scheduler.config.form, + rules: scheduler.config.form_rules + } + ] + } + ].concat(scheduler.config.views); + + dhx.protoUI({ + name:"scheduler", + defaults:{ + rows:[ + { + view:"multiview", + id:"views", + cells: views + }, + { + view:"toolbar", + id:"bottomBar", + type:"SchedulerBar", + visibleBatch:"default", + elements: scheduler.config.bottom_toolbar + } + ], + color:"#color#", + textColor:"#textColor#" + }, + $init: function() { + this.name = "Scheduler"; + this._viewobj.className += " dhx_scheduler"; + /*date format functions*/ + dhx.i18n.dateFormat = scheduler.config.item_date; + dhx.i18n.timeFormat = scheduler.config.hour_date; + dhx.i18n.fullDateFormat = scheduler.config.xml_date; + dhx.i18n.headerFormatStr = dhx.Date.dateToStr( scheduler.config.header_date); + dhx.i18n.setLocale(); + this.data.provideApi(this); + this.data.extraParser = dhx.bind(function(data){ + data.start_date = dhx.i18n.fullDateFormatDate(data.start_date); + data.end_date = dhx.i18n.fullDateFormatDate(data.end_date); + },this); + this.$ready.push(this._initStructure); + this.data.attachEvent("onStoreUpdated", dhx.bind(this._sortDates,this)); + }, + _initStructure:function(){ + this._initToolbars(); + this._initmonth(); + + //store current date + this.coreData = new dhx.DataValue(); + this.coreData.setValue(scheduler.config.init_date); + + this.$$("dayList").define("date",this.coreData); + + this.selectedEvent = new dhx.DataRecord(); + + if(this.config.readonly){ + this.define("readonly",this.config.readonly); + } + else if(scheduler.config.readonly) + this.define("readonly",true); + /*saving data*/ + if(this.config.save){ + var dp = new dhx.DataProcessor({ + master:this, + url:this.config.save + }); + dp.attachEvent("onBeforeDataSend",this._onSchedulerUpdate); + } + + if(this.$$("date")) + this.$$("date").bind(this.coreData, null, dhx.i18n.headerFormatStr); + + + this.$$("list").sync(this); + this.$$("list").bind(this.coreData, function(target, source){ + return source < target.end_date; + }); + + this.$$("dayList").sync(this, true); + this.$$("dayList").bind(this.coreData, function(target, source){ + var d = dhx.Date.datePart(source); + return d < target.end_date && dhx.Date.add(d,1,"day") > target.start_date; + }); + + this.$$("calendar").bind(this.coreData); + + this.$$("calendarDayEvents").sync(this, true); + this.$$("calendarDayEvents").bind(this.coreData, function(target, source){ + var d = dhx.Date.datePart(source); + return d < target.end_date && dhx.Date.add(d,1,"day") > target.start_date; + }); + + this.$$("eventTemplate").bind(this); + this.$$("editForm").bind(this); + + this.$$("list").attachEvent("onItemClick", dhx.bind(this._on_event_clicked, this)); + this.$$("dayList").attachEvent("onItemClick", dhx.bind(this._on_event_clicked, this)); + this.$$("calendarDayEvents").attachEvent("onItemClick", dhx.bind(this._on_event_clicked, this)); + }, + _on_event_clicked:function(id){ + this.setCursor(id); + this.$$('event').show(); + }, + /*Sorts dates asc, gets hash of dates with event*/ + _sortDates:function(){ + this.data.blockEvent(); + this.data.sort(function(a,b){ + return a.start_date < b.start_date?1:-1; + }); + this.data.unblockEvent(); + this._eventsByDate = {}; + var evs = this.data.getRange(); + for(var i = 0; i < evs.length;i++) + this._setDateEvents(evs[i]); + }, + /*Month Events view: gets dates of a certain event*/ + _setDateEvents:function(ev){ + var start = dhx.Date.datePart(ev.start_date); + var end = dhx.Date.datePart(ev.end_date); + if(ev.end_date.valueOf()!=end.valueOf()) + end = dhx.Date.add(end,1,"day"); + while(startscheduler._props[name].options.length){ + scheduler._props[name]._original_size = size; + size = 0; + } + scheduler._props[name].size = size; + scheduler._props[name].skip_incorrect = skip_incorrect||false; + scheduler.date[name+"_start"]= scheduler.date.day_start; scheduler.templates[name+"_date"] = function(date){ return scheduler.templates.day_date(date); - } + }; + scheduler.templates[name+"_scale_date"] = function(date){ + var list = scheduler._props[name].options; if (!list.length) return ""; var index = (scheduler._props[name].position||0)+Math.floor((scheduler._correct_shift(date.valueOf(),1)-scheduler._min_date.valueOf())/(60*60*24*1000)); if (list[index].css) return ""+list[index].label+""; else return list[index].label; - } - scheduler.date["add_"+name]=function(date,inc){ return scheduler.date.add(date,inc,"day"); } - scheduler.date["get_"+name+"_end"]=function(date){ return scheduler.date.add(date,size||list.length,"day"); } - - scheduler._props[name]={map_to:property, options:list, size:size, step:step, position:0 }; + }; + + scheduler.date["add_"+name]=function(date,inc){ return scheduler.date.add(date,inc,"day"); }; + scheduler.date["get_"+name+"_end"]=function(date){ + return scheduler.date.add(date,scheduler._props[name].size||scheduler._props[name].options.length,"day"); + }; scheduler.attachEvent("onOptionsLoad",function(){ - var order = scheduler._props[name].order = {}; + var pr = scheduler._props[name]; + var order = pr.order = {}; + var list = pr.options; for(var i=0; i list.length) { + pr._original_size = pr.size; + pr.size = 0; + } + else + pr.size = pr._original_size||pr.size; + if (scheduler._date && scheduler._mode == name) scheduler.setCurrentView(scheduler._date, scheduler._mode); }); scheduler.callEvent("onOptionsLoad",[]); @@ -40,8 +69,31 @@ scheduler.scrollUnit=function(step){ this.update_view(); } }; - (function(){ + var _removeIncorrectEvents = function(evs) { + var pr = scheduler._props[scheduler._mode]; + if(pr && pr.order && pr.skip_incorrect) { + var correct_events = []; + for(var i=0; i= pr.size+pr.position ) - return false; + var val = pr.order[e[pr.map_to]]; + if (val < pr.position || val >= pr.size+pr.position ) + return false; } } return res; - } - + }; scheduler._reset_scale = function(){ var pr = scheduler._props[this._mode]; var ret = t.apply(this,arguments); @@ -106,7 +157,7 @@ scheduler.scrollUnit=function(step){ } return ret; - } + }; var r = scheduler._get_event_sday; scheduler._get_event_sday=function(ev){ var pr = scheduler._props[this._mode]; @@ -115,7 +166,7 @@ scheduler.scrollUnit=function(step){ return pr.order[ev[pr.map_to]]-pr.position; } return r.call(this,ev); - } + }; var l = scheduler.locate_holder_day; scheduler.locate_holder_day=function(a,b,ev){ var pr = scheduler._props[this._mode]; @@ -124,23 +175,25 @@ scheduler.scrollUnit=function(step){ return pr.order[ev[pr.map_to]]*1+(b?1:0)-pr.position; } return l.apply(this,arguments); - } + }; var p = scheduler._mouse_coords; scheduler._mouse_coords=function(){ var pr = scheduler._props[this._mode]; var pos=p.apply(this,arguments); if (pr){ + if(!this._drag_event) this._drag_event = {}; var ev = this._drag_event; - if (this._drag_id){ + if (this._drag_id && this._drag_mode){ ev = this.getEvent(this._drag_id); this._drag_event._dhx_changed = true; } var unit_ind = Math.min(pos.x+pr.position,pr.options.length-1); ev[pr.map_to]=pr.options[unit_ind].key; - pos.x = unit_ind/10000000; + pos.x = 0; + pos.custom = true; } return pos; - } + }; var o = scheduler._time_order; scheduler._time_order = function(evs){ var pr = scheduler._props[this._mode]; @@ -150,8 +203,7 @@ scheduler.scrollUnit=function(step){ }); } else o.apply(this,arguments); - } - + }; scheduler.attachEvent("onEventAdded",function(id,ev){ if (this._loading) return true; for (var a in scheduler._props){ @@ -160,7 +212,7 @@ scheduler.scrollUnit=function(step){ ev[pr.map_to] = pr.options[0].key; } return true; - }) + }); scheduler.attachEvent("onEventCreated",function(id,n_ev){ var pr = scheduler._props[this._mode]; if (pr){ @@ -170,6 +222,20 @@ scheduler.scrollUnit=function(step){ this.event_updated(ev); } return true; - }) - -})(); \ No newline at end of file + }) +})(); + + +/* just in case, there shouldn't be any need for this + + scheduler.getUnitSection = function(event_id) { + var ev = scheduler.getEvent(event_id); + var options = scheduler._props['unit'].options; + var section; + for(var i=0; ifrom) - result.push(sev[i]); - } else if (!ev.event_pid || ev.event_pid==0){ + for (var i=0; i < sev.length; i++) { + // if event is in rec_markers then it will be checked by himself, here need to skip it + if (!sev[i].rec_pattern && sev[i].start_datefrom && !this._rec_markers[sev[i].id]) { + result.push(sev[i]); + } + } + } else if (ev.id.toString().indexOf("#")==-1){ // if it's virtual event we can skip it result.push(ev); } } @@ -585,7 +628,7 @@ scheduler.getEvents = function(from,to){ scheduler.config.repeat_date="%m.%d.%Y"; scheduler.config.lightbox.sections=[ {name:"description", height:130, map_to:"text", type:"textarea" , focus:true}, - {name:"recurring", height:115, type:"recurring", map_to:"rec_type", button:"recurring"}, + {name:"recurring", type:"recurring", map_to:"rec_type", button:"recurring"}, {name:"time", height:72, type:"time", map_to:"auto"} ]; //drop secondary attributes diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template.html index 3d351383fc9..078f4415777 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template.html @@ -49,7 +49,7 @@

occurrences
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_cn.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_cn.html index 222bb5f6e6c..c47f485b80f 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_cn.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_cn.html @@ -49,7 +49,7 @@

次结束
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_de.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_de.html index ae9dbb3cabf..bb70c5aac79 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_de.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_de.html @@ -52,7 +52,7 @@

Ereignissen
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_el.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_el.html new file mode 100644 index 00000000000..eddddee99aa --- /dev/null +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_el.html @@ -0,0 +1,57 @@ +
+
+
+
+
+
+ +
+
+
+ + +
+ ημέρα κάθεμήνα
+ κάθεμήνα
+
+ +
+
+
+
+ επαναλήψεις
+
+
+
+
+
+
\ No newline at end of file diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_es.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_es.html index bcfcf2e81ea..94549432bc8 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_es.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_es.html @@ -49,7 +49,7 @@

occurencias
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_fr.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_fr.html index 65313e6314b..281dbe7afc4 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_fr.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_fr.html @@ -49,7 +49,7 @@

occurrences
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_it.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_it.html index e55c7ebc2bc..1d92cb4d420 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_it.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_it.html @@ -49,7 +49,7 @@

occorenze
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_nl.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_nl.html index 14f32c7f2ef..d9e563191f6 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_nl.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_nl.html @@ -57,7 +57,7 @@

keren
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_ru.html b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_ru.html index 6b521212eb0..becab2809c7 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_ru.html +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/repeat_template_ru.html @@ -49,7 +49,7 @@

повторений
-
+
diff --git a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/scheduler.js b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/scheduler.js index b14592a050b..80018266f24 100644 --- a/addons/base_calendar/static/lib/dhtmlxScheduler/sources/scheduler.js +++ b/addons/base_calendar/static/lib/dhtmlxScheduler/sources/scheduler.js @@ -1,8 +1,14 @@ -window.dhtmlXScheduler=window.scheduler={version:2.2}; +/* +This software is allowed to use under GPL or you need to obtain Commercial or Enterise License +to use it in not GPL project. Please contact sales@dhtmlx.com for details +*/ +window.dhtmlXScheduler=window.scheduler={version:3.0}; dhtmlxEventable(scheduler); scheduler.init=function(id,date,mode){ date=date||(new Date()); mode=mode||"week"; + + scheduler.date.init(); this._obj=(typeof id == "string")?document.getElementById(id):id; this._els=[]; @@ -19,9 +25,9 @@ scheduler.init=function(id,date,mode){ if (scheduler.callEvent("onSchedulerResize",[])) scheduler.update_view(); }, 100); - }) - + }); this.set_sizes(); + scheduler.callEvent('onSchedulerReady', []); this.setCurrentView(date,mode); }; scheduler.xy={ @@ -57,7 +63,7 @@ scheduler.set_sizes=function(){ var data_y=this.xy.scale_height+this.xy.nav_height+(this._quirks?-2:0); this.set_xy(this._els["dhx_cal_data"][0],w,h-(data_y+2),0,data_y+2); -} +}; scheduler.set_xy=function(node,w,h,x,y){ node.style.width=Math.max(0,w)+"px"; node.style.height=Math.max(0,h)+"px"; @@ -65,7 +71,7 @@ scheduler.set_xy=function(node,w,h,x,y){ node.style.left=x+"px"; node.style.top=y+"px"; } -} +}; scheduler.get_elements=function(){ //get all child elements as named hash var els=this._obj.getElementsByTagName("DIV"); @@ -78,26 +84,26 @@ scheduler.get_elements=function(){ var t=scheduler.locale.labels[els[i].getAttribute("name")||name]; if (t) els[i].innerHTML=t; } -} +}; scheduler.set_actions=function(){ for (var a in this._els) if (this._click[a]) for (var i=0; i < this._els[a].length; i++) this._els[a][i].onclick=scheduler._click[a]; - this._obj.onselectstart=function(e){ return false; } + this._obj.onselectstart=function(e){ return false; }; this._obj.onmousemove=function(e){ scheduler._on_mouse_move(e||event); - } + }; this._obj.onmousedown=function(e){ scheduler._on_mouse_down(e||event); - } + }; this._obj.onmouseup=function(e){ scheduler._on_mouse_up(e||event); - } + }; this._obj.ondblclick=function(e){ scheduler._on_dbl_click(e||event); } -} +}; scheduler.select=function(id){ if (this._table_view || !this.getEvent(id)._timed) return; //temporary block if (this._select_id==id) return; @@ -105,13 +111,13 @@ scheduler.select=function(id){ this.unselect(); this._select_id = id; this.updateEvent(id); -} +}; scheduler.unselect=function(id){ if (id && id!=this._select_id) return; var t=this._select_id; this._select_id = null; if (t) this.updateEvent(t); -} +}; scheduler.getState=function(){ return { mode: this._mode, @@ -119,11 +125,13 @@ scheduler.getState=function(){ min_date: this._min_date, max_date: this._max_date, editor_id: this._edit_id, - lightbox_id: this._lightbox_id + lightbox_id: this._lightbox_id, + new_event: this._new_event }; -} +}; scheduler._click={ dhx_cal_data:function(e){ + //debugger; var trg = e?e.target:event.srcElement; var id = scheduler._locate_event(trg); @@ -149,7 +157,8 @@ scheduler._click={ scheduler.setCurrentView(new Date()); }, dhx_cal_tab:function(){ - var mode = this.getAttribute("name").split("_")[0]; + var name = this.getAttribute("name"); + var mode = name.substring(0, name.search("_tab")); scheduler.setCurrentView(scheduler._date,mode); }, buttons:{ @@ -159,11 +168,10 @@ scheduler._click={ details:function(id){ scheduler.showLightbox(id); }, cancel:function(id){ scheduler.editStop(false); } } -} - +}; scheduler.addEventNow=function(start,end,e){ var base = {}; - if (typeof start == "object"){ + if (start && start.constructor.toString().match(/object/i) !== null){ base = start; start = null; } @@ -179,14 +187,18 @@ scheduler.addEventNow=function(start,end,e){ } end = start+d; } - - + var end_date = new Date(end); + + // scheduler.addEventNow(new Date(), new Date()) + collision though get_visible events defect (such event was not retrieved) + if(start_date.valueOf() == end_date.valueOf()) + end_date.setTime(end_date.valueOf()+d); + base.start_date = base.start_date||start_date; - base.end_date = base.end_date||new Date(end); + base.end_date = base.end_date||end_date; base.text = base.text||this.locale.labels.new_event; base.id = this._drag_id = this.uid(); this._drag_mode="new-size"; - + this._loading=true; this.addEvent(base); this.callEvent("onEventCreated",[this._drag_id,e]); @@ -194,7 +206,7 @@ scheduler.addEventNow=function(start,end,e){ this._drag_event={}; //dummy , to trigger correct event updating logic this._on_mouse_up(e); -} +}; scheduler._on_dbl_click=function(e,src){ src = src||(e.target||e.srcElement); if (this.config.readonly) return; @@ -203,6 +215,7 @@ scheduler._on_dbl_click=function(e,src){ case "dhx_scale_holder": case "dhx_scale_holder_now": case "dhx_month_body": + case "dhx_wa_day_data": if (!scheduler.config.dblclick_create) break; var pos=this._mouse_coords(e); var start=this._min_date.valueOf()+(pos.y*this.config.time_step+(this._table_view?0:pos.x)*24*60)*60000; @@ -210,6 +223,7 @@ scheduler._on_dbl_click=function(e,src){ this.addEventNow(start,null,e); break; case "dhx_body": + case "dhx_wa_ev_body": case "dhx_cal_event_line": case "dhx_cal_event_clear": var id = this._locate_event(src); @@ -227,7 +241,7 @@ scheduler._on_dbl_click=function(e,src){ if (t) t.call(this,e); break; } -} +}; scheduler._mouse_coords=function(ev){ var pos; @@ -238,17 +252,17 @@ scheduler._mouse_coords=function(ev){ else pos={ x:ev.clientX + (b.scrollLeft||d.scrollLeft||0) - b.clientLeft, y:ev.clientY + (b.scrollTop||d.scrollTop||0) - b.clientTop - } + }; //apply layout pos.x-=getAbsoluteLeft(this._obj)+(this._table_view?0:this.xy.scale_width); pos.y-=getAbsoluteTop(this._obj)+this.xy.nav_height+(this._dy_shift||0)+this.xy.scale_height-this._els["dhx_cal_data"][0].scrollTop; pos.ev = ev; - + var handler = this["mouse_"+this._mode]; if (handler) return handler.call(this,pos); - + //transform to date if (!this._table_view){ pos.x=Math.max(0,Math.ceil(pos.x/this._cols[0])-1); @@ -258,7 +272,7 @@ scheduler._mouse_coords=function(ev){ for (dy=1; dy < this._colsS.heights.length; dy++) if (this._colsS.heights[dy]>pos.y) break; - pos.y=(Math.max(0,Math.ceil(pos.x/this._cols[0])-1)+Math.max(0,dy-1)*7)*24*60/this.config.time_step; + pos.y=(Math.max(0,Math.ceil(pos.x/this._cols[0])-1)+Math.max(0,dy-1)*7)*24*60/this.config.time_step; pos.x=0; } @@ -270,14 +284,14 @@ scheduler._close_not_saved=function(){ if (!c || confirm(c)) scheduler.editStop(scheduler.config.positive_closing); } -} +}; scheduler._correct_shift=function(start, back){ return start-=((new Date(scheduler._min_date)).getTimezoneOffset()-(new Date(start)).getTimezoneOffset())*60000*(back?-1:1); -} +}; scheduler._on_mouse_move=function(e){ if (this._drag_mode){ var pos=this._mouse_coords(e); - if (!this._drag_pos || this._drag_pos.x!=pos.x || this._drag_pos.y!=pos.y){ + if (!this._drag_pos || pos.custom || this._drag_pos.x!=pos.x || this._drag_pos.y!=pos.y){ if (this._edit_id!=this._drag_id) this._close_not_saved(); @@ -316,8 +330,11 @@ scheduler._on_mouse_move=function(e){ end = ev.end_date.valueOf()-(ev.start_date.valueOf()-start); } else { start = ev.start_date.valueOf(); - if (this._table_view) + if (this._table_view) { end = this._min_date.valueOf()+pos.y*this.config.time_step*60000 + (pos.custom?0:24*60*60000); + if (this._mode == "month") + end = this._correct_shift(end, false); + } else{ end = this.date.date_part(new Date(ev.end_date)).valueOf()+pos.y*this.config.time_step*60000; this._els["dhx_cal_data"][0].style.cursor="s-resize"; @@ -327,7 +344,7 @@ scheduler._on_mouse_move=function(e){ if (this._drag_mode == "new-size"){ if (end <= this._drag_start){ var shift = pos.shift||((this._table_view && !pos.custom)?24*60*60000:0); - start = end-shift; + start = end-(pos.shift?0:shift); end = this._drag_start+(shift||(this.config.time_step*60000)); } else { start = this._drag_start; @@ -339,7 +356,7 @@ scheduler._on_mouse_move=function(e){ var new_end = new Date(end-1); var new_start = new Date(start); //prevent out-of-borders situation for day|week view - if (this._table_view || (new_end.getDate()==new_start.getDate() && new_end.getHours() this._min_date && now.getHours() >= this.config.first_hour && now.getHours()
" + html+=">
"+this.templates.month_day(sd)+"
"; sd=this.date.add(sd,1,"day"); } html+=""; @@ -625,7 +683,7 @@ scheduler._reset_month_scale=function(b,dd,sd){ b.innerHTML=html; return sd; -} +}; scheduler.getLabel = function(property, key) { var sections = this.config.lightbox.sections; for (var i=0; i Date: Wed, 3 Aug 2011 16:42:44 +0200 Subject: [PATCH 215/230] [REN] client action member 'kwargs' to 'params' bzr revid: xmo@openerp.com-20110803144244-86s098uqcamwatde --- addons/base/static/src/js/views.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base/static/src/js/views.js b/addons/base/static/src/js/views.js index 94ae1325b83..e10add1c8c0 100644 --- a/addons/base/static/src/js/views.js +++ b/addons/base/static/src/js/views.js @@ -96,7 +96,7 @@ openerp.base.ActionManager = openerp.base.Controller.extend({ }, 'ir.actions.client': function (action) { var Handler = openerp.base.client_actions.get_object(action.tag); - new Handler(this, this.element_id, action['kwargs']).start(); + new Handler(this, this.element_id, action.params).start(); }, close_dialog: function () { if (this.current_dialog) { From be1a6596582c18f879fca9a5adcc0a86774b8363 Mon Sep 17 00:00:00 2001 From: Launchpad Translations on behalf of openerp <> Date: Thu, 4 Aug 2011 04:34:56 +0000 Subject: [PATCH 216/230] Launchpad automatic translations update. bzr revid: launchpad_translations_on_behalf_of_openerp-20110803043726-ofn4l3px2ooldl00 bzr revid: launchpad_translations_on_behalf_of_openerp-20110804043456-fnef8uwgur5od0en --- addons/account_cancel/i18n/sv.po | 13 +- addons/association/i18n/sv.po | 12 +- addons/base_action_rule/i18n/sv.po | 12 +- addons/base_calendar/i18n/sv.po | 38 ++-- addons/base_module_record/i18n/sv.po | 10 +- addons/base_synchro/i18n/sv.po | 10 +- addons/board/i18n/sv.po | 10 +- addons/caldav/i18n/sv.po | 24 +-- addons/crm/i18n/sv.po | 14 +- addons/email_template/i18n/sv.po | 10 +- addons/event/i18n/ru.po | 236 +++++++++++++------------ addons/mrp/i18n/sv.po | 24 +-- addons/mrp_operations/i18n/sv.po | 52 +++--- addons/mrp_repair/i18n/sv.po | 10 +- addons/multi_company/i18n/sv.po | 23 ++- addons/point_of_sale/i18n/sv.po | 10 +- addons/procurement/i18n/sv.po | 20 +-- addons/project_scrum/i18n/sv.po | 10 +- addons/purchase/i18n/sv.po | 10 +- addons/report_webkit_sample/i18n/fi.po | 143 +++++++++++++++ 20 files changed, 433 insertions(+), 258 deletions(-) create mode 100644 addons/report_webkit_sample/i18n/fi.po diff --git a/addons/account_cancel/i18n/sv.po b/addons/account_cancel/i18n/sv.po index 1352a70a600..bfcb0a95084 100644 --- a/addons/account_cancel/i18n/sv.po +++ b/addons/account_cancel/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-11-24 09:29+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-01 23:18+0000\n" +"Last-Translator: Magnus Brandt (mba), Aspirix AB \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-29 05:46+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: account_cancel #: model:ir.module.module,description:account_cancel.module_meta_information @@ -25,6 +25,11 @@ msgid "" "journal. If set to true it allows user to cancel entries & invoices.\n" " " msgstr "" +"\n" +" Modulen lägger till 'Tillåt ändrande poster' fält på fomulärvyn av " +"kontojournalen. Om satt till sant tillåter den att användaren\n" +" avbryter verifikat och fakturor.\n" +" " #. module: account_cancel #: model:ir.module.module,shortdesc:account_cancel.module_meta_information diff --git a/addons/association/i18n/sv.po b/addons/association/i18n/sv.po index fc7da345b3e..3077049bcaf 100644 --- a/addons/association/i18n/sv.po +++ b/addons/association/i18n/sv.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: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2011-01-24 22:40+0000\n" -"Last-Translator: Magnus Brandt (mba), Aspirix AB \n" +"PO-Revision-Date: 2011-08-01 23:35+0000\n" +"Last-Translator: Stefan Lind \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: 2011-04-29 05:51+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: association #: field:profile.association.config.install_modules_wizard,wiki:0 @@ -24,7 +24,7 @@ msgstr "Wiki" #. module: association #: view:profile.association.config.install_modules_wizard:0 msgid "Event Management" -msgstr "" +msgstr "Evenemangsledning" #. module: association #: field:profile.association.config.install_modules_wizard,project_gtd:0 @@ -93,7 +93,7 @@ msgstr "" #. module: association #: field:profile.association.config.install_modules_wizard,hr_expense:0 msgid "Expenses Tracking" -msgstr "" +msgstr "Kostnadsuppföljning" #. module: association #: model:ir.actions.act_window,name:association.action_config_install_module diff --git a/addons/base_action_rule/i18n/sv.po b/addons/base_action_rule/i18n/sv.po index 1470baadd91..cf6d5af0b2d 100644 --- a/addons/base_action_rule/i18n/sv.po +++ b/addons/base_action_rule/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-20 04:26+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:30+0000\n" +"Last-Translator: Stefan Lind \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-29 05:51+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: base_action_rule #: help:base.action.rule,act_mail_to_user:0 @@ -135,7 +135,7 @@ msgstr "%(object_subject) = Objekt ämnen" #. module: base_action_rule #: view:base.action.rule:0 msgid "Email Reminders" -msgstr "" +msgstr "Epost påminnelser" #. module: base_action_rule #: view:base.action.rule:0 @@ -258,7 +258,7 @@ msgstr "" #. module: base_action_rule #: field:base.action.rule,act_email_to:0 msgid "Email To" -msgstr "" +msgstr "Skicka mail till" #. module: base_action_rule #: help:base.action.rule,act_mail_to_watchers:0 diff --git a/addons/base_calendar/i18n/sv.po b/addons/base_calendar/i18n/sv.po index 08b19ffb938..3ac4e57751f 100644 --- a/addons/base_calendar/i18n/sv.po +++ b/addons/base_calendar/i18n/sv.po @@ -8,25 +8,25 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-11 12:17+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:11+0000\n" +"Last-Translator: Magnus Brandt (mba), Aspirix AB \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-29 05:50+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: base_calendar #: selection:calendar.alarm,trigger_related:0 #: selection:res.alarm,trigger_related:0 msgid "The event starts" -msgstr "" +msgstr "Evenemanget börjar" #. module: base_calendar #: selection:base.calendar.set.exrule,freq:0 msgid "Hourly" -msgstr "" +msgstr "Varje timme" #. module: base_calendar #: view:calendar.attendee:0 @@ -120,7 +120,7 @@ msgstr "Visa som" #: field:calendar.todo,day:0 #: selection:calendar.todo,select1:0 msgid "Date of month" -msgstr "" +msgstr "Månadens datum" #. module: base_calendar #: selection:calendar.event,class:0 @@ -141,6 +141,7 @@ msgid "March" msgstr "Mars" #. module: base_calendar +#: code:addons/base_calendar/base_calendar.py:414 #: code:addons/base_calendar/wizard/base_calendar_set_exrule.py:90 #, python-format msgid "Warning !" @@ -172,7 +173,7 @@ msgstr "Alternativ" #: selection:calendar.todo,show_as:0 #: selection:res.users,availability:0 msgid "Free" -msgstr "" +msgstr "Fri" #. module: base_calendar #: help:calendar.attendee,rsvp:0 @@ -258,7 +259,7 @@ msgid "Invitation Detail" msgstr "" #. module: base_calendar -#: code:addons/base_calendar/base_calendar.py:1356 +#: code:addons/base_calendar/base_calendar.py:1355 #: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:96 #: code:addons/base_calendar/wizard/base_calendar_invite_attendee.py:143 #: code:addons/base_calendar/wizard/base_calendar_set_exrule.py:128 @@ -281,7 +282,7 @@ msgstr "" #: selection:calendar.event,state:0 #: selection:calendar.todo,state:0 msgid "Cancelled" -msgstr "" +msgstr "Avbruten" #. module: base_calendar #: selection:calendar.alarm,trigger_interval:0 @@ -307,7 +308,7 @@ msgstr "" #. module: base_calendar #: selection:base.calendar.set.exrule,freq:0 msgid "Secondly" -msgstr "" +msgstr "För det andra" #. module: base_calendar #: field:calendar.alarm,event_date:0 @@ -352,7 +353,7 @@ msgstr "År" #: field:calendar.alarm,event_end_date:0 #: field:calendar.attendee,event_end_date:0 msgid "Event End Date" -msgstr "" +msgstr "Evenemangets slutdatum" #. module: base_calendar #: selection:calendar.attendee,role:0 @@ -367,8 +368,8 @@ msgstr "" #. module: base_calendar #: code:addons/base_calendar/base_calendar.py:385 +#: code:addons/base_calendar/base_calendar.py:1088 #: code:addons/base_calendar/base_calendar.py:1090 -#: code:addons/base_calendar/base_calendar.py:1092 #, python-format msgid "Warning!" msgstr "Varning!" @@ -418,7 +419,7 @@ msgstr "" #: selection:calendar.alarm,trigger_occurs:0 #: selection:res.alarm,trigger_occurs:0 msgid "Before" -msgstr "" +msgstr "Före" #. module: base_calendar #: view:calendar.event:0 @@ -481,7 +482,7 @@ msgstr "" #: selection:calendar.event,select1:0 #: selection:calendar.todo,select1:0 msgid "Day of month" -msgstr "" +msgstr "Dag i månaden" #. module: base_calendar #: view:calendar.event:0 @@ -589,7 +590,7 @@ msgstr "Tor" #. module: base_calendar #: field:calendar.attendee,child_ids:0 msgid "Delegrated To" -msgstr "" +msgstr "Delegerad till" #. module: base_calendar #: view:calendar.attendee:0 @@ -828,7 +829,7 @@ msgid "Hours" msgstr "Timmar" #. module: base_calendar -#: code:addons/base_calendar/base_calendar.py:1092 +#: code:addons/base_calendar/base_calendar.py:1090 #, python-format msgid "Count can not be Negative" msgstr "" @@ -878,7 +879,6 @@ msgstr "Påminnelse" #. module: base_calendar #: view:base.calendar.set.exrule:0 -#: model:ir.actions.act_window,name:base_calendar.action_base_calendar_set_exrule #: model:ir.model,name:base_calendar.model_base_calendar_set_exrule msgid "Set Exrule" msgstr "" @@ -1060,7 +1060,7 @@ msgid "Wednesday" msgstr "Onsdag" #. module: base_calendar -#: code:addons/base_calendar/base_calendar.py:1090 +#: code:addons/base_calendar/base_calendar.py:1088 #, python-format msgid "Interval can not be Negative" msgstr "" diff --git a/addons/base_module_record/i18n/sv.po b/addons/base_module_record/i18n/sv.po index 70c3ed4c513..82061d81f2d 100644 --- a/addons/base_module_record/i18n/sv.po +++ b/addons/base_module_record/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-02 09:02+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:19+0000\n" +"Last-Translator: Magnus Brandt (mba), Aspirix AB \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: 2011-04-29 05:01+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: base_module_record #: wizard_field:base_module_record.module_record_objects,info,category:0 @@ -73,7 +73,7 @@ msgstr "ir.module.record" #. module: base_module_record #: selection:base_module_record.module_record_objects,info,data_kind:0 msgid "Demo Data" -msgstr "" +msgstr "Testdata" #. module: base_module_record #: wizard_field:base_module_record.module_record_objects,save,module_filename:0 diff --git a/addons/base_synchro/i18n/sv.po b/addons/base_synchro/i18n/sv.po index 4918f90c413..9619c34e6cf 100644 --- a/addons/base_synchro/i18n/sv.po +++ b/addons/base_synchro/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-01 09:43+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:26+0000\n" +"Last-Translator: Stefan Lind \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-29 05:52+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: base_synchro #: model:ir.actions.act_window,name:base_synchro.action_view_base_synchro @@ -244,7 +244,7 @@ msgstr "Sekvens" msgid "" "The synchronisation has been started.You will receive a request when it's " "done." -msgstr "" +msgstr "Synkroniseringen har startat. Du kommer få ett svar när den är klar." #. module: base_synchro #: field:base.synchro.server,server_port:0 diff --git a/addons/board/i18n/sv.po b/addons/board/i18n/sv.po index c80366f6096..de7d5cbc422 100644 --- a/addons/board/i18n/sv.po +++ b/addons/board/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-15 01:56+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:18+0000\n" +"Last-Translator: Stefan Lind \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: 2011-04-29 05:29+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: board #: view:res.log.report:0 @@ -47,7 +47,7 @@ msgstr "Instrumentpanel huvudmodul" #. module: board #: view:res.users:0 msgid "Latest Connections" -msgstr "" +msgstr "Senaste anslutningarna" #. module: board #: code:addons/board/wizard/board_menu_create.py:45 diff --git a/addons/caldav/i18n/sv.po b/addons/caldav/i18n/sv.po index 2331013b642..29ae3796eb5 100644 --- a/addons/caldav/i18n/sv.po +++ b/addons/caldav/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:14+0000\n" -"PO-Revision-Date: 2010-12-03 07:37+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 22:58+0000\n" +"Last-Translator: Magnus Brandt (mba), Aspirix AB \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-29 05:52+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: caldav #: view:basic.calendar:0 @@ -64,8 +64,8 @@ msgid "Can not map a field more than once" msgstr "" #. module: caldav -#: code:addons/caldav/calendar.py:772 -#: code:addons/caldav/calendar.py:861 +#: code:addons/caldav/calendar.py:787 +#: code:addons/caldav/calendar.py:877 #: code:addons/caldav/wizard/calendar_event_import.py:63 #, python-format msgid "Warning !" @@ -108,7 +108,7 @@ msgid "Ok" msgstr "Ok" #. module: caldav -#: code:addons/caldav/calendar.py:861 +#: code:addons/caldav/calendar.py:877 #, python-format msgid "Please provide proper configuration of \"%s\" in Calendar Lines" msgstr "" @@ -218,7 +218,7 @@ msgid "Use the field" msgstr "Använd fältet" #. module: caldav -#: code:addons/caldav/calendar.py:772 +#: code:addons/caldav/calendar.py:787 #, python-format msgid "Can not create line \"%s\" more than once" msgstr "Kan inte skapa raden \"%s\" mer än en gång" @@ -290,7 +290,7 @@ msgid "Save in .ics format" msgstr "Spara i .ics format" #. module: caldav -#: code:addons/caldav/calendar.py:1275 +#: code:addons/caldav/calendar.py:1291 #, python-format msgid "Error !" msgstr "Fel !" @@ -456,7 +456,7 @@ msgstr "" #: view:basic.calendar:0 #: field:basic.calendar,has_webcal:0 msgid "WebCal" -msgstr "" +msgstr "WebCal" #. module: caldav #: view:document.directory:0 @@ -466,7 +466,7 @@ msgid "Calendar Collections" msgstr "" #. module: caldav -#: code:addons/caldav/calendar.py:798 +#: code:addons/caldav/calendar.py:813 #: sql_constraint:basic.calendar.alias:0 #, python-format msgid "The same filename cannot apply to two records!" @@ -740,7 +740,7 @@ msgid "basic.calendar.alarm" msgstr "" #. module: caldav -#: code:addons/caldav/calendar.py:1275 +#: code:addons/caldav/calendar.py:1291 #, python-format msgid "Attendee must have an Email Id" msgstr "" diff --git a/addons/crm/i18n/sv.po b/addons/crm/i18n/sv.po index 887c6ea83a8..dc928ea707b 100644 --- a/addons/crm/i18n/sv.po +++ b/addons/crm/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-06-03 13:57+0000\n" -"Last-Translator: Jan-Eric Lindh \n" +"PO-Revision-Date: 2011-08-03 22:39+0000\n" +"Last-Translator: Stefan Lind \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: 2011-06-04 04:53+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: crm #: view:crm.lead.report:0 @@ -92,7 +92,7 @@ msgstr " " #: view:crm.lead.report:0 #: field:crm.phonecall.report,delay_close:0 msgid "Delay to close" -msgstr "" +msgstr "Vänta med att stänga" #. module: crm #: view:crm.lead:0 @@ -127,7 +127,7 @@ msgstr "Koden för säljteamet måste vara unikt!" #: code:addons/crm/wizard/crm_lead_to_opportunity.py:95 #, python-format msgid "Lead '%s' has been converted to an opportunity." -msgstr "" +msgstr "Lead '%s' har konverterats till en affärsmöjlighet." #. module: crm #: code:addons/crm/crm_lead.py:228 @@ -1182,7 +1182,7 @@ msgstr "" #: model:crm.case.stage,name:crm.stage_opportunity5 #: view:crm.lead:0 msgid "Won" -msgstr "" +msgstr "Vunnit" #. module: crm #: field:crm.lead.report,delay_expected:0 diff --git a/addons/email_template/i18n/sv.po b/addons/email_template/i18n/sv.po index 2d628f0c74e..513bc37d603 100644 --- a/addons/email_template/i18n/sv.po +++ b/addons/email_template/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-06-03 14:08+0000\n" -"Last-Translator: Jan-Eric Lindh \n" +"PO-Revision-Date: 2011-08-01 23:20+0000\n" +"Last-Translator: Stefan Lind \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-06-04 04:53+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: email_template #: help:email_template.account,auto_delete:0 @@ -1070,7 +1070,7 @@ msgstr "" #. module: email_template #: field:email.template,null_value:0 msgid "Null Value" -msgstr "" +msgstr "Nollvärde" #. module: email_template #: field:email.template,template_language:0 diff --git a/addons/event/i18n/ru.po b/addons/event/i18n/ru.po index 092a0c3864c..1b16fc71207 100644 --- a/addons/event/i18n/ru.po +++ b/addons/event/i18n/ru.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: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-05-21 19:59+0000\n" +"PO-Revision-Date: 2011-08-02 10:44+0000\n" "Last-Translator: Stanislav Hanzhin \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: 2011-05-22 04:47+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: event #: view:event.event:0 @@ -77,12 +77,12 @@ msgstr "Дата регистрации" #. module: event #: help:event.event,main_speaker_id:0 msgid "Speaker who are giving speech on event." -msgstr "" +msgstr "Выступающие на мероприятии." #. module: event #: view:partner.event.registration:0 msgid "_Close" -msgstr "" +msgstr "_Закрыть" #. module: event #: model:event.event,name:event.event_0 @@ -96,11 +96,14 @@ msgid "" "event. Note that you can specify for each registration a specific amount if " "you want to" msgstr "" +"Укажите здесь стоимость регистрации по-умолчанию, которая будет " +"использоваться для выставления счетов за мероприятие. Для каждой регистрации " +"может быть указана своя стоимость." #. module: event #: selection:report.event.registration,month:0 msgid "March" -msgstr "" +msgstr "Март" #. module: event #: field:event.event,mail_confirm:0 @@ -111,7 +114,7 @@ msgstr "Подтверждение ел. почты" #: code:addons/event/wizard/event_make_invoice.py:63 #, python-format msgid "Registration doesn't have any partner to invoice." -msgstr "" +msgstr "Для выставления счёта регистрация должна быть связана с партнёром." #. module: event #: field:event.event,company_id:0 @@ -119,7 +122,7 @@ msgstr "" #: view:report.event.registration:0 #: field:report.event.registration,company_id:0 msgid "Company" -msgstr "" +msgstr "Организация" #. module: event #: field:event.make.invoice,invoice_date:0 @@ -139,7 +142,7 @@ msgstr "Регистрация события" #. module: event #: view:report.event.registration:0 msgid "Last 7 Days" -msgstr "" +msgstr "Последние 7 дней" #. module: event #: field:event.event,parent_id:0 @@ -154,7 +157,7 @@ msgstr "Сформировать счёт" #. module: event #: field:event.registration,price_subtotal:0 msgid "Subtotal" -msgstr "" +msgstr "Подитог" #. module: event #: view:report.event.registration:0 @@ -169,7 +172,7 @@ msgstr "Текущие мероприятия" #. module: event #: view:event.registration:0 msgid "Add Internal Note" -msgstr "" +msgstr "Добавить внутреннюю заметку" #. module: event #: model:ir.actions.act_window,name:event.action_report_event_registration @@ -182,7 +185,7 @@ msgstr "Анализ мероприятий" #. module: event #: field:event.registration,message_ids:0 msgid "Messages" -msgstr "" +msgstr "Сообщения" #. module: event #: field:event.event,mail_auto_confirm:0 @@ -206,12 +209,12 @@ msgstr "Подтвердить событие" #: selection:event.registration,state:0 #: selection:report.event.registration,state:0 msgid "Cancelled" -msgstr "" +msgstr "Отменено" #. module: event #: field:event.event,reply_to:0 msgid "Reply-To" -msgstr "" +msgstr "Ответить" #. module: event #: model:ir.actions.act_window,name:event.open_board_associations_manager @@ -221,12 +224,12 @@ msgstr "Инфо-панель мероприятий" #. module: event #: model:event.event,name:event.event_1 msgid "Opera of Verdi" -msgstr "" +msgstr "Опера Верди" #. module: event #: field:event.event,pricelist_id:0 msgid "Pricelist" -msgstr "" +msgstr "Прайс-лист" #. module: event #: field:event.registration,contact_id:0 @@ -241,7 +244,7 @@ msgstr "event.registration.badge" #. module: event #: field:event.registration,ref:0 msgid "Reference" -msgstr "" +msgstr "Ссылка" #. module: event #: help:event.event,date_end:0 @@ -252,7 +255,7 @@ msgstr "Дата завершения мероприятия" #. module: event #: view:event.registration:0 msgid "Emails" -msgstr "" +msgstr "Адреса эл.почты" #. module: event #: view:event.registration:0 @@ -263,7 +266,7 @@ msgstr "Доп. информация" #: code:addons/event/wizard/event_make_invoice.py:83 #, python-format msgid "Customer Invoices" -msgstr "" +msgstr "Счета заказчику" #. module: event #: selection:event.event,state:0 @@ -279,7 +282,7 @@ msgstr "Тип события" #. module: event #: model:ir.model,name:event.model_event_type msgid " Event Type " -msgstr "" +msgstr " Тип мероприятия " #. module: event #: view:event.event:0 @@ -330,13 +333,13 @@ msgstr "" #. module: event #: view:event.registration:0 msgid "Misc" -msgstr "" +msgstr "Разное" #. module: event #: view:event.event:0 #: field:event.event,speaker_ids:0 msgid "Other Speakers" -msgstr "" +msgstr "Другие выступающие" #. module: event #: model:ir.model,name:event.model_event_make_invoice @@ -355,22 +358,22 @@ msgstr "Число регистраций или билетов" #: code:addons/event/wizard/event_make_invoice.py:62 #, python-format msgid "Warning !" -msgstr "" +msgstr "Внимание !" #. module: event #: view:event.registration:0 msgid "Send New Email" -msgstr "" +msgstr "Отправить новое эл. письмо" #. module: event #: view:event.event:0 msgid "Location" -msgstr "" +msgstr "Местоположение" #. module: event #: view:event.registration:0 msgid "Reply" -msgstr "" +msgstr "Ответ" #. module: event #: field:event.event,register_current:0 @@ -392,7 +395,7 @@ msgstr "Тип" #. module: event #: field:event.registration,email_from:0 msgid "Email" -msgstr "" +msgstr "Эл. почта" #. module: event #: field:event.registration,tobe_invoiced:0 @@ -403,12 +406,12 @@ msgstr "Счета к выставлению" #: code:addons/event/event.py:394 #, python-format msgid "Error !" -msgstr "" +msgstr "Ошибка !" #. module: event #: field:event.registration,create_date:0 msgid "Creation Date" -msgstr "" +msgstr "Дата создания" #. module: event #: view:event.event:0 @@ -426,7 +429,7 @@ msgstr "Зарегистрированный контрагент не имее #. module: event #: field:event.registration,nb_register:0 msgid "Quantity" -msgstr "" +msgstr "Количество" #. module: event #: help:event.event,type:0 @@ -440,6 +443,9 @@ msgid "" "subscribes to a confirmed event. This is also the email sent to remind " "someone about the event." msgstr "" +"Это сообщение будет отправлено, когда мероприятие будет утверждено или кто-" +"то подпишется на утвержденное мероприятие. Оно так же отправляется для " +"напоминания о мероприятии." #. module: event #: help:event.event,register_prospect:0 @@ -449,7 +455,7 @@ msgstr "" #. module: event #: selection:report.event.registration,month:0 msgid "July" -msgstr "" +msgstr "Июль" #. module: event #: view:event.event:0 @@ -459,7 +465,7 @@ msgstr "Организация события" #. module: event #: view:event.registration:0 msgid "History Information" -msgstr "" +msgstr "История" #. module: event #: view:event.registration:0 @@ -508,12 +514,12 @@ msgstr "Отменить событие" #: view:event.event:0 #: view:event.registration:0 msgid "Contact" -msgstr "" +msgstr "Контакт" #. module: event #: view:report.event.registration:0 msgid "Last 30 Days" -msgstr "" +msgstr "Последние 30 дней" #. module: event #: view:event.event:0 @@ -521,7 +527,7 @@ msgstr "" #: field:event.registration,partner_id:0 #: model:ir.model,name:event.model_res_partner msgid "Partner" -msgstr "" +msgstr "Контрагент" #. module: event #: view:board.board:0 @@ -559,7 +565,7 @@ msgstr "Счёт выставлен контрагенту" #. module: event #: field:event.registration,log_ids:0 msgid "Logs" -msgstr "" +msgstr "Журналы" #. module: event #: view:event.event:0 @@ -569,33 +575,33 @@ msgstr "" #: view:report.event.registration:0 #: field:report.event.registration,state:0 msgid "State" -msgstr "" +msgstr "Состояние" #. module: event #: selection:report.event.registration,month:0 msgid "September" -msgstr "" +msgstr "Сентябрь" #. module: event #: selection:report.event.registration,month:0 msgid "December" -msgstr "" +msgstr "Декабрь" #. module: event #: field:event.registration,event_product:0 msgid "Invoice Name" -msgstr "" +msgstr "Название счёта" #. module: event #: field:report.event.registration,draft_state:0 msgid " # No of Draft Registrations" -msgstr "" +msgstr " Кол-во неподтверждённых регистраций" #. module: event #: view:report.event.registration:0 #: field:report.event.registration,month:0 msgid "Month" -msgstr "" +msgstr "Месяц" #. module: event #: view:event.event:0 @@ -641,7 +647,7 @@ msgstr "" #. module: event #: field:event.confirm.registration,msg:0 msgid "Message" -msgstr "" +msgstr "Сообщение" #. module: event #: constraint:event.event:0 @@ -651,30 +657,30 @@ msgstr "Ошибка! Невозможно создать рекурсивное #. module: event #: field:event.registration,ref2:0 msgid "Reference 2" -msgstr "" +msgstr "Ссылка 2" #. module: event #: code:addons/event/event.py:357 #: view:report.event.registration:0 #, python-format msgid "Invoiced" -msgstr "" +msgstr "Выставлен счет" #. module: event #: view:event.event:0 #: view:report.event.registration:0 msgid "My Events" -msgstr "" +msgstr "Мои события" #. module: event #: view:event.event:0 msgid "Speakers" -msgstr "" +msgstr "Выступающие" #. module: event #: view:event.make.invoice:0 msgid "Create invoices" -msgstr "" +msgstr "Создать счета" #. module: event #: help:event.registration,email_cc:0 @@ -683,26 +689,28 @@ msgid "" "outbound emails for this record before being sent. Separate multiple email " "addresses with a comma" msgstr "" +"Эти эл. адреса будут добавлены в поле \"Копия\" всей входящей и исходящей " +"почты для этой записи. Разделяйте эл. адреса запятыми." #. module: event #: constraint:res.partner:0 msgid "Error ! You can not create recursive associated members." -msgstr "" +msgstr "Ошибка! Вы не можете создать рекурсивно связанных участников." #. module: event #: view:event.make.invoice:0 msgid "Do you really want to create the invoice(s) ?" -msgstr "" +msgstr "Вы уверены, что хотите создать счет(а) ?" #. module: event #: view:event.event:0 msgid "Beginning Date" -msgstr "" +msgstr "Дата начала" #. module: event #: field:event.registration,date_closed:0 msgid "Closed" -msgstr "" +msgstr "Закрыто" #. module: event #: view:event.event:0 @@ -722,39 +730,40 @@ msgstr "Кол-во регистраций" #. module: event #: field:event.event,child_ids:0 msgid "Child Events" -msgstr "" +msgstr "Дочерние мероприятия" #. module: event #: selection:report.event.registration,month:0 msgid "August" -msgstr "" +msgstr "Август" #. module: event #: field:res.partner,event_ids:0 #: field:res.partner,event_registration_ids:0 msgid "unknown" -msgstr "" +msgstr "unknown" #. module: event #: selection:report.event.registration,month:0 msgid "June" -msgstr "" +msgstr "Июнь" #. module: event #: help:event.event,mail_auto_registr:0 msgid "" "Check this box if you want to use the automatic mailing for new registration" msgstr "" +"Отметьте, если хотите получать автоматические сообщения о новой регистрации." #. module: event #: field:event.registration,write_date:0 msgid "Write Date" -msgstr "" +msgstr "Дата записи" #. module: event #: view:event.registration:0 msgid "My Registrations" -msgstr "" +msgstr "Мои регистрации" #. module: event #: view:event.confirm:0 @@ -762,57 +771,60 @@ msgid "" "Warning: This Event has not reached its Minimum Registration Limit. Are you " "sure you want to confirm it?" msgstr "" +"Предупреждение: Данное мероприятие не получило минимального количества " +"необходимых регистраций. Вы действительно хотите утвердить его?" #. module: event #: field:event.registration,active:0 msgid "Active" -msgstr "" +msgstr "Активно" #. module: event #: selection:report.event.registration,month:0 msgid "November" -msgstr "" +msgstr "Ноябрь" #. module: event #: view:report.event.registration:0 msgid "Extended Filters..." -msgstr "" +msgstr "Расширенные фильтры..." #. module: event #: help:event.event,reply_to:0 msgid "The email address put in the 'Reply-To' of all emails sent by OpenERP" msgstr "" +"Данный адрес будет указан в поле 'От кого' в письмах, отправленных OpenERP" #. module: event #: selection:report.event.registration,month:0 msgid "October" -msgstr "" +msgstr "Октябрь" #. module: event #: help:event.event,register_current:0 msgid "Total of Open and Done Registrations" -msgstr "" +msgstr "Сумма открытых и закрытых регистраций" #. module: event #: field:event.event,language:0 msgid "Language" -msgstr "" +msgstr "Язык" #. module: event #: view:event.registration:0 #: field:event.registration,email_cc:0 msgid "CC" -msgstr "" +msgstr "Копия" #. module: event #: selection:report.event.registration,month:0 msgid "January" -msgstr "" +msgstr "Январь" #. module: event #: help:event.registration,email_from:0 msgid "These people will receive email." -msgstr "" +msgstr "Эти люди получат эл. письма." #. module: event #: view:event.event:0 @@ -833,17 +845,17 @@ msgstr "Подтвердить регистрацию" #: view:report.event.registration:0 #: view:res.partner:0 msgid "Date" -msgstr "" +msgstr "Дата" #. module: event #: model:ir.ui.menu,name:event.board_associations msgid "Dashboard" -msgstr "" +msgstr "Инфо-панель" #. module: event #: view:event.event:0 msgid "Confirmation Email Body" -msgstr "" +msgstr "Тело подтверждающего письма" #. module: event #: view:event.registration:0 @@ -854,7 +866,7 @@ msgstr "Журнал" #. module: event #: field:event.event,address_id:0 msgid "Location Address" -msgstr "" +msgstr "Адрес местоположения" #. module: event #: model:ir.ui.menu,name:event.menu_event_type @@ -865,7 +877,7 @@ msgstr "Типы событий" #. module: event #: view:event.registration:0 msgid "Attachments" -msgstr "" +msgstr "Прикрепленные файлы" #. module: event #: code:addons/event/wizard/event_make_invoice.py:59 @@ -876,17 +888,17 @@ msgstr "" #. module: event #: view:event.event:0 msgid "Auto Confirmation Email" -msgstr "" +msgstr "Письмо автоподтверждения" #. module: event #: view:report.event.registration:0 msgid "Last 365 Days" -msgstr "" +msgstr "Последние 365 дней" #. module: event #: constraint:event.event:0 msgid "Error ! Closing Date cannot be set before Beginning Date." -msgstr "" +msgstr "Ошибка! Дата завершения не может быть установлена до даты начала." #. module: event #: code:addons/event/event.py:442 @@ -913,7 +925,7 @@ msgstr "Счет" #: view:report.event.registration:0 #: field:report.event.registration,year:0 msgid "Year" -msgstr "" +msgstr "Год" #. module: event #: code:addons/event/event.py:517 @@ -926,12 +938,12 @@ msgstr "Отмена" #: view:event.confirm.registration:0 #: view:event.make.invoice:0 msgid "Close" -msgstr "" +msgstr "Закрыть" #. module: event #: view:event.event:0 msgid "Event by Registration" -msgstr "" +msgstr "Мероприятия по регистрации" #. module: event #: code:addons/event/event.py:432 @@ -942,14 +954,14 @@ msgstr "Открыть" #. module: event #: field:event.event,user_id:0 msgid "Responsible User" -msgstr "" +msgstr "Ответственный пользователь" #. module: event #: code:addons/event/event.py:538 #: code:addons/event/event.py:545 #, python-format msgid "Auto Confirmation: [%s] %s" -msgstr "" +msgstr "Автоподтверждение: [%s] %s" #. module: event #: view:event.event:0 @@ -958,20 +970,20 @@ msgstr "" #: view:report.event.registration:0 #: field:report.event.registration,user_id:0 msgid "Responsible" -msgstr "" +msgstr "Ответственный" #. module: event #: field:event.event,unit_price:0 #: view:event.registration:0 #: field:partner.event.registration,unit_price:0 msgid "Registration Cost" -msgstr "" +msgstr "Стоимость регистрации" #. module: event #: view:event.event:0 #: view:event.registration:0 msgid "Current" -msgstr "" +msgstr "Текущие" #. module: event #: field:event.registration,unit_price:0 @@ -983,17 +995,17 @@ msgstr "Цена за ед." #: field:report.event.registration,speaker_id:0 #: field:res.partner,speaker:0 msgid "Speaker" -msgstr "" +msgstr "Выступающий" #. module: event #: view:event.registration:0 msgid "Details" -msgstr "" +msgstr "Подробности" #. module: event #: model:event.event,name:event.event_2 msgid "Conference on ERP Buisness" -msgstr "" +msgstr "Конференция по ERP-бизнесу" #. module: event #: field:event.event,section_id:0 @@ -1001,18 +1013,18 @@ msgstr "" #: view:report.event.registration:0 #: field:report.event.registration,section_id:0 msgid "Sale Team" -msgstr "" +msgstr "Отдел продаж" #. module: event #: field:partner.event.registration,start_date:0 msgid "Start date" -msgstr "" +msgstr "Дата начала" #. module: event #: field:event.event,date_end:0 #: field:partner.event.registration,end_date:0 msgid "Closing date" -msgstr "" +msgstr "Дата закрытия" #. module: event #: field:event.event,product_id:0 @@ -1027,32 +1039,32 @@ msgstr "Продукция" #: view:event.registration:0 #: field:event.registration,description:0 msgid "Description" -msgstr "" +msgstr "Описание" #. module: event #: field:report.event.registration,confirm_state:0 msgid " # No of Confirmed Registrations" -msgstr "" +msgstr " Кол-во подтверждённых регистраций" #. module: event #: model:ir.actions.act_window,name:event.act_register_event_partner msgid "Subscribe" -msgstr "" +msgstr "Подписаться" #. module: event #: selection:report.event.registration,month:0 msgid "May" -msgstr "" +msgstr "Май" #. module: event #: view:res.partner:0 msgid "Events Registration" -msgstr "" +msgstr "Регистрация мероприятий" #. module: event #: help:event.event,mail_registr:0 msgid "This email will be sent when someone subscribes to the event." -msgstr "" +msgstr "Это письмо будет отправлено при подписке на мероприятие." #. module: event #: model:product.template,name:event.event_product_2_product_template @@ -1062,55 +1074,55 @@ msgstr "Билет на конференцию" #. module: event #: field:event.registration.badge,address_id:0 msgid "Address" -msgstr "" +msgstr "Адрес" #. module: event #: view:board.board:0 #: model:ir.actions.act_window,name:event.act_event_view msgid "Next Events" -msgstr "" +msgstr "Следующие события" #. module: event #: view:partner.event.registration:0 msgid "_Subcribe" -msgstr "" +msgstr "_Подписаться" #. module: event #: model:ir.model,name:event.model_partner_event_registration msgid " event Registration " -msgstr "" +msgstr " Регистрация на мероприятие " #. module: event #: help:event.event,date_begin:0 #: help:partner.event.registration,start_date:0 msgid "Beginning Date of Event" -msgstr "" +msgstr "Дата начала мероприятия" #. module: event #: selection:event.registration,state:0 msgid "Unconfirmed" -msgstr "" +msgstr "Неподтверждённый" #. module: event #: code:addons/event/event.py:542 #, python-format msgid "Auto Registration: [%s] %s" -msgstr "" +msgstr "Авто-регистрация: [%s] %s" #. module: event #: field:event.registration,date_deadline:0 msgid "End Date" -msgstr "" +msgstr "Дата окончания" #. module: event #: selection:report.event.registration,month:0 msgid "February" -msgstr "" +msgstr "Февраль" #. module: event #: view:board.board:0 msgid "Association Dashboard" -msgstr "" +msgstr "Панель ассоциаций" #. module: event #: view:event.event:0 @@ -1128,7 +1140,7 @@ msgstr "" #. module: event #: field:event.event,country_id:0 msgid "Country" -msgstr "" +msgstr "Страна" #. module: event #: code:addons/event/wizard/event_make_invoice.py:55 @@ -1143,18 +1155,18 @@ msgstr "" #: view:res.partner:0 #, python-format msgid "Close Registration" -msgstr "" +msgstr "Закрыть регистрацию" #. module: event #: selection:report.event.registration,month:0 msgid "April" -msgstr "" +msgstr "Апрель" #. module: event #: field:event.event,name:0 #: field:event.registration,name:0 msgid "Summary" -msgstr "" +msgstr "Описание" #. module: event #: view:event.event:0 @@ -1176,7 +1188,7 @@ msgstr "Регистрации" #. module: event #: field:event.registration,date:0 msgid "Start Date" -msgstr "" +msgstr "Дата начала" #. module: event #: field:event.event,register_max:0 @@ -1222,7 +1234,7 @@ msgstr "" #: view:report.event.registration:0 #: field:report.event.registration,total:0 msgid "Total" -msgstr "" +msgstr "Всего" #. module: event #: help:event.event,register_min:0 @@ -1232,7 +1244,7 @@ msgstr "" #. module: event #: field:event.event,speaker_confirmed:0 msgid "Speaker Confirmed" -msgstr "" +msgstr "Выступающий утвержден" #. module: event #: model:ir.actions.act_window,help:event.action_event_view diff --git a/addons/mrp/i18n/sv.po b/addons/mrp/i18n/sv.po index 99c9ee97a22..30687c7a183 100644 --- a/addons/mrp/i18n/sv.po +++ b/addons/mrp/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-01-27 22:20+0000\n" -"Last-Translator: Magnus Brandt (mba), Aspirix AB \n" +"PO-Revision-Date: 2011-08-03 23:21+0000\n" +"Last-Translator: Stefan Lind \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: 2011-04-29 04:50+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: mrp #: field:mrp.production,move_created_ids:0 @@ -122,7 +122,7 @@ msgstr "" #. module: mrp #: model:process.transition,name:mrp.process_transition_stockproduction0 msgid "To Produce" -msgstr "" +msgstr "Att tillverka" #. module: mrp #: help:mrp.routing.workcenter,cycle_nbr:0 @@ -720,7 +720,7 @@ msgid "Per month" msgstr "Per månad" #. module: mrp -#: code:addons/mrp/mrp.py:591 +#: code:addons/mrp/mrp.py:595 #: code:addons/mrp/wizard/change_production_qty.py:77 #: code:addons/mrp/wizard/change_production_qty.py:82 #, python-format @@ -733,7 +733,7 @@ msgid "Product Name" msgstr "Produktnamn" #. module: mrp -#: code:addons/mrp/mrp.py:491 +#: code:addons/mrp/mrp.py:495 #, python-format msgid "Invalid action !" msgstr "Invalid action !" @@ -1299,7 +1299,7 @@ msgid "Month -1" msgstr "" #. module: mrp -#: code:addons/mrp/mrp.py:914 +#: code:addons/mrp/mrp.py:924 #, python-format msgid "Manufacturing order '%s' is scheduled for the %s." msgstr "" @@ -1310,7 +1310,7 @@ msgid "Production Order N° :" msgstr "Production Order N° :" #. module: mrp -#: code:addons/mrp/mrp.py:630 +#: code:addons/mrp/mrp.py:640 #, python-format msgid "Manufacturing order '%s' is ready to produce." msgstr "" @@ -1539,7 +1539,7 @@ msgid "Manufacturing Orders To Start" msgstr "" #. module: mrp -#: code:addons/mrp/mrp.py:491 +#: code:addons/mrp/mrp.py:495 #, python-format msgid "Cannot delete Production Order(s) which are in %s State!" msgstr "" @@ -1629,7 +1629,7 @@ msgid "Production Analysis" msgstr "" #. module: mrp -#: code:addons/mrp/mrp.py:345 +#: code:addons/mrp/mrp.py:349 #, python-format msgid "Copy" msgstr "" @@ -2118,7 +2118,7 @@ msgid "Product type is Stockable or Consumable." msgstr "" #. module: mrp -#: code:addons/mrp/mrp.py:591 +#: code:addons/mrp/mrp.py:595 #: code:addons/mrp/wizard/change_production_qty.py:77 #: code:addons/mrp/wizard/change_production_qty.py:82 #, python-format diff --git a/addons/mrp_operations/i18n/sv.po b/addons/mrp_operations/i18n/sv.po index 6b9c9cb274b..77319bb130d 100644 --- a/addons/mrp_operations/i18n/sv.po +++ b/addons/mrp_operations/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-03 16:58+0000\n" -"PO-Revision-Date: 2010-11-23 09:29+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:14+0000\n" +"Last-Translator: Treecko \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: 2011-04-29 05:31+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: mrp_operations #: model:ir.actions.act_window,name:mrp_operations.mrp_production_wc_action_form @@ -78,7 +78,7 @@ msgstr "(" #. module: mrp_operations #: view:mrp.production.workcenter.line:0 msgid "Product to Produce" -msgstr "" +msgstr "Produkt att producera" #. module: mrp_operations #: view:mrp_operations.operation:0 @@ -117,7 +117,7 @@ msgid "Creation of the work order" msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:461 +#: code:addons/mrp_operations/mrp_operations.py:463 #, python-format msgid "You cannot Pause the Operation other then Start/Resume state !" msgstr "" @@ -136,10 +136,10 @@ msgstr "" #. module: mrp_operations #: code:addons/mrp_operations/mrp_operations.py:133 -#: code:addons/mrp_operations/mrp_operations.py:461 -#: code:addons/mrp_operations/mrp_operations.py:465 -#: code:addons/mrp_operations/mrp_operations.py:477 -#: code:addons/mrp_operations/mrp_operations.py:480 +#: code:addons/mrp_operations/mrp_operations.py:463 +#: code:addons/mrp_operations/mrp_operations.py:467 +#: code:addons/mrp_operations/mrp_operations.py:479 +#: code:addons/mrp_operations/mrp_operations.py:482 #, python-format msgid "Error!" msgstr "" @@ -224,7 +224,7 @@ msgid "" msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:470 +#: code:addons/mrp_operations/mrp_operations.py:472 #, python-format msgid "You cannot finish the operation without Starting/Resuming it !" msgstr "" @@ -235,7 +235,7 @@ msgid "Planned Date" msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:477 +#: code:addons/mrp_operations/mrp_operations.py:479 #, python-format msgid "There is no Operation to be cancelled !" msgstr "" @@ -274,7 +274,7 @@ msgstr "" #. module: mrp_operations #: field:mrp_operations.operation,order_date:0 msgid "Order Date" -msgstr "" +msgstr "Orderdatum" #. module: mrp_operations #: model:ir.actions.act_window,name:mrp_operations.mrp_production_wc_draft_action @@ -282,7 +282,7 @@ msgid "Future Work Orders" msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:457 +#: code:addons/mrp_operations/mrp_operations.py:459 #, python-format msgid "" "Operation has already started !You can either Pause /Finish/Cancel the " @@ -363,7 +363,7 @@ msgstr "" #: view:mrp.production.workcenter.line:0 #: selection:mrp_operations.operation.code,start_stop:0 msgid "Start" -msgstr "" +msgstr "Start" #. module: mrp_operations #: view:mrp_operations.operation:0 @@ -400,7 +400,7 @@ msgid "Production Operation Code" msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:465 +#: code:addons/mrp_operations/mrp_operations.py:467 #, python-format msgid " You cannot Resume the operation other then Pause state !" msgstr "" @@ -454,7 +454,7 @@ msgid "June" msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:480 +#: code:addons/mrp_operations/mrp_operations.py:482 #, python-format msgid "Operation is already finished !" msgstr "" @@ -511,7 +511,7 @@ msgid "Finish the operation." msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:450 +#: code:addons/mrp_operations/mrp_operations.py:452 #, python-format msgid "Operation is not started yet !" msgstr "" @@ -522,10 +522,10 @@ msgid "Information from the production order." msgstr "" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:450 -#: code:addons/mrp_operations/mrp_operations.py:457 -#: code:addons/mrp_operations/mrp_operations.py:470 -#: code:addons/mrp_operations/mrp_operations.py:473 +#: code:addons/mrp_operations/mrp_operations.py:452 +#: code:addons/mrp_operations/mrp_operations.py:459 +#: code:addons/mrp_operations/mrp_operations.py:472 +#: code:addons/mrp_operations/mrp_operations.py:475 #, python-format msgid "Sorry!" msgstr "" @@ -542,7 +542,7 @@ msgid "Code" msgstr "Kod" #. module: mrp_operations -#: code:addons/mrp_operations/mrp_operations.py:473 +#: code:addons/mrp_operations/mrp_operations.py:475 #, python-format msgid "Operation is Already Cancelled !" msgstr "" @@ -560,7 +560,7 @@ msgstr "" #. module: mrp_operations #: field:mrp.production.workcenter.line,qty:0 msgid "Qty" -msgstr "" +msgstr "Kvantitet" #. module: mrp_operations #: model:process.node,name:mrp_operations.process_node_doneoperation0 @@ -647,7 +647,7 @@ msgstr "" #. module: mrp_operations #: view:mrp.production.workcenter.line:0 msgid "Real" -msgstr "" +msgstr "Faktisk" #. module: mrp_operations #: field:mrp.production.workcenter.line,date_planned:0 @@ -775,7 +775,7 @@ msgstr "" #. module: mrp_operations #: view:mrp.production.workcenter.line:0 msgid "Duration" -msgstr "" +msgstr "Varaktighet" #. module: mrp_operations #: constraint:mrp.production:0 diff --git a/addons/mrp_repair/i18n/sv.po b/addons/mrp_repair/i18n/sv.po index 6f58b0cad9d..bac9167e5bd 100644 --- a/addons/mrp_repair/i18n/sv.po +++ b/addons/mrp_repair/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-06-03 14:18+0000\n" -"Last-Translator: Jan-Eric Lindh \n" +"PO-Revision-Date: 2011-08-01 23:11+0000\n" +"Last-Translator: Treecko \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: 2011-06-04 04:53+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: mrp_repair #: view:mrp.repair:0 @@ -760,7 +760,7 @@ msgstr "Totalt" #. module: mrp_repair #: selection:mrp.repair,state:0 msgid "Ready to Repair" -msgstr "" +msgstr "Redo att reparera" #. module: mrp_repair #: code:addons/mrp_repair/mrp_repair.py:365 diff --git a/addons/multi_company/i18n/sv.po b/addons/multi_company/i18n/sv.po index d438b0b13de..c79c85cbdc7 100644 --- a/addons/multi_company/i18n/sv.po +++ b/addons/multi_company/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2010-11-23 09:51+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-01 23:24+0000\n" +"Last-Translator: Stefan Lind \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: 2011-04-29 05:41+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: multi_company #: model:res.company,overdue_msg:multi_company.res_company_odoo @@ -39,6 +39,21 @@ msgid "" "%(company_name)s\n" " " msgstr "" +"\n" +"Datum: %(date)s\n" +"\n" +"Hej %(partner_name)s,\n" +"\n" +"Här kommer en påminnelse, bifogad, på era obetalda fakturor, med en total " +"förfallen summa på:\n" +"\n" +"%(followup_amount).2f %(company_currency)s\n" +"\n" +"Vänligen\n" +"--\n" +"%(user_signature)s\n" +"%(company_name)s\n" +" " #. module: multi_company #: model:product.category,name:multi_company.Odoo1 diff --git a/addons/point_of_sale/i18n/sv.po b/addons/point_of_sale/i18n/sv.po index c989a0a141b..83076eac862 100644 --- a/addons/point_of_sale/i18n/sv.po +++ b/addons/point_of_sale/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-03 16:58+0000\n" -"PO-Revision-Date: 2010-12-15 15:07+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 22:56+0000\n" +"Last-Translator: Stefan Lind \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: 2011-07-23 04:57+0000\n" -"X-Generator: Launchpad (build 13405)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: point_of_sale #: field:pos.discount,discount_notes:0 @@ -1962,7 +1962,7 @@ msgstr "Meddelande" #: model:ir.model,name:point_of_sale.model_pos_order #: model:ir.ui.menu,name:point_of_sale.menu_point_root msgid "Point of Sale" -msgstr "" +msgstr "Försäljningsställe" #. module: point_of_sale #: view:pos.order:0 diff --git a/addons/procurement/i18n/sv.po b/addons/procurement/i18n/sv.po index 9597e40a678..b958aebebdc 100644 --- a/addons/procurement/i18n/sv.po +++ b/addons/procurement/i18n/sv.po @@ -8,14 +8,14 @@ msgstr "" "Project-Id-Version: openobject-addons\n" "Report-Msgid-Bugs-To: FULL NAME \n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2010-12-15 05:17+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 22:59+0000\n" +"Last-Translator: Stefan Lind \n" "Language-Team: Swedish \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: 8bit\n" -"X-Launchpad-Export-Date: 2011-04-29 05:48+0000\n" -"X-Generator: Launchpad (build 12758)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: procurement #: view:make.procurement:0 @@ -67,7 +67,7 @@ msgid "Procurement Method" msgstr "" #. module: procurement -#: code:addons/procurement/procurement.py:298 +#: code:addons/procurement/procurement.py:304 #, python-format msgid "No address defined for the supplier" msgstr "" @@ -172,7 +172,7 @@ msgstr "" #. module: procurement #: selection:procurement.order,state:0 msgid "Ready" -msgstr "" +msgstr "Klar" #. module: procurement #: field:procurement.order.compute.all,automatic:0 @@ -306,7 +306,7 @@ msgid "Quantity" msgstr "" #. module: procurement -#: code:addons/procurement/procurement.py:370 +#: code:addons/procurement/procurement.py:377 #, python-format msgid "Not enough stock and no minimum orderpoint rule defined." msgstr "" @@ -437,7 +437,7 @@ msgid "plus" msgstr "" #. module: procurement -#: code:addons/procurement/procurement.py:319 +#: code:addons/procurement/procurement.py:325 #, python-format msgid "" "Please check the Quantity in Procurement Order(s), it should not be less " @@ -599,7 +599,7 @@ msgid "Cannot delete Procurement Order(s) which are in %s State!" msgstr "" #. module: procurement -#: code:addons/procurement/procurement.py:318 +#: code:addons/procurement/procurement.py:324 #, python-format msgid "Data Insufficient !" msgstr "" @@ -823,7 +823,7 @@ msgid "Product UoS" msgstr "" #. module: procurement -#: code:addons/procurement/procurement.py:347 +#: code:addons/procurement/procurement.py:353 #, python-format msgid "from stock: products assigned." msgstr "" diff --git a/addons/project_scrum/i18n/sv.po b/addons/project_scrum/i18n/sv.po index cba4c5bd8d9..1e5b3c31010 100644 --- a/addons/project_scrum/i18n/sv.po +++ b/addons/project_scrum/i18n/sv.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: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-06-03 14:17+0000\n" -"Last-Translator: Jan-Eric Lindh \n" +"PO-Revision-Date: 2011-08-01 23:16+0000\n" +"Last-Translator: Stefan Lind \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: 2011-06-04 04:53+0000\n" -"X-Generator: Launchpad (build 12959)\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: project_scrum #: help:project.scrum.email,scrum_master_email:0 @@ -111,7 +111,7 @@ msgstr "Förlopp" #: view:project.scrum.sprint:0 #: field:project.scrum.sprint,scrum_master_id:0 msgid "Scrum Master" -msgstr "" +msgstr "Scrum Master" #. module: project_scrum #: code:addons/project_scrum/project_scrum.py:83 diff --git a/addons/purchase/i18n/sv.po b/addons/purchase/i18n/sv.po index c2bf121f9b1..4ec8019c55c 100644 --- a/addons/purchase/i18n/sv.po +++ b/addons/purchase/i18n/sv.po @@ -7,14 +7,14 @@ msgstr "" "Project-Id-Version: OpenERP Server 5.0.14\n" "Report-Msgid-Bugs-To: support@openerp.com\n" "POT-Creation-Date: 2011-01-11 11:15+0000\n" -"PO-Revision-Date: 2011-01-12 17:11+0000\n" -"Last-Translator: OpenERP Administrators \n" +"PO-Revision-Date: 2011-08-03 23:22+0000\n" +"Last-Translator: Stefan Lind \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: 2011-07-23 04:56+0000\n" -"X-Generator: Launchpad (build 13405)\n" +"X-Launchpad-Export-Date: 2011-08-04 04:34+0000\n" +"X-Generator: Launchpad (build 13573)\n" #. module: purchase #: model:process.transition,note:purchase.process_transition_confirmingpurchaseorder0 @@ -27,7 +27,7 @@ msgstr "" #: code:addons/purchase/purchase.py:282 #, python-format msgid "You can not confirm purchase order without Purchase Order Lines." -msgstr "" +msgstr "Du kan inte bekräfta beställningen utan inköpsorder" #. module: purchase #: field:purchase.order,invoiced:0 diff --git a/addons/report_webkit_sample/i18n/fi.po b/addons/report_webkit_sample/i18n/fi.po new file mode 100644 index 00000000000..1d2690dd578 --- /dev/null +++ b/addons/report_webkit_sample/i18n/fi.po @@ -0,0 +1,143 @@ +# Finnish translation for openobject-addons +# Copyright (c) 2011 Rosetta Contributors and Canonical Ltd 2011 +# This file is distributed under the same license as the openobject-addons package. +# FIRST AUTHOR , 2011. +# +msgid "" +msgstr "" +"Project-Id-Version: openobject-addons\n" +"Report-Msgid-Bugs-To: FULL NAME \n" +"POT-Creation-Date: 2011-01-11 11:16+0000\n" +"PO-Revision-Date: 2011-08-01 06:15+0000\n" +"Last-Translator: FULL NAME \n" +"Language-Team: Finnish \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" +"X-Launchpad-Export-Date: 2011-08-03 04:37+0000\n" +"X-Generator: Launchpad (build 13573)\n" + +#. module: report_webkit_sample +#: model:ir.actions.report.xml,name:report_webkit_sample.report_webkit_html +msgid "WebKit invoice" +msgstr "Webkit lasku" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:35 +msgid "Supplier Invoice" +msgstr "Toimittajan lasku" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Unit Price" +msgstr "Yksikköhinta" + +#. module: report_webkit_sample +#: model:ir.module.module,description:report_webkit_sample.module_meta_information +msgid "" +"Samples for Webkit Report Engine (report_webkit module).\n" +"\n" +" A sample invoice report is included in this module, as well as a wizard " +"to\n" +" add Webkit Report entries on any Document in the system.\n" +" \n" +" You have to create the print buttons by calling the wizard. For more " +"details see:\n" +" http://files.me.com/nbessi/06n92k.mov \n" +" " +msgstr "" + +#. module: report_webkit_sample +#: model:ir.module.module,shortdesc:report_webkit_sample.module_meta_information +msgid "Webkit Report Samples" +msgstr "Webkit esimerkkiraportit" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Disc.(%)" +msgstr "Alennus (%)" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:22 +msgid "Fax" +msgstr "Faksi" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:44 +msgid "Document" +msgstr "Dokumentti" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Description" +msgstr "Kuvaus" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Price" +msgstr "Hinta" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:44 +msgid "Invoice Date" +msgstr "Laskun päivämäärä" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "QTY" +msgstr "Määrä" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:64 +msgid "Base" +msgstr "Pohja" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:44 +msgid "Partner Ref." +msgstr "Kumppanin viite" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:49 +msgid "Taxes" +msgstr "Verot" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:64 +msgid "Amount" +msgstr "Määrä" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:28 +msgid "VAT" +msgstr "ALV" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:37 +msgid "Refund" +msgstr "Palautus" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:19 +msgid "Tel" +msgstr "Puh" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:25 +msgid "E-mail" +msgstr "Sähköposti" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:33 +msgid "Invoice" +msgstr "Lasku" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:39 +msgid "Supplier Refund" +msgstr "Toimittajan hyvitys" + +#. module: report_webkit_sample +#: report:report.webkitaccount.invoice:76 +msgid "Total" +msgstr "Kokonaismäärä" From 01f32f9f3f6b59ad1d35037fb1c3b23beb8c12f5 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Aug 2011 10:54:55 +0200 Subject: [PATCH 217/230] [REN] client action member 'kwargs' to 'params' bzr revid: xmo@openerp.com-20110804085455-647wwp0g4454kj1g --- openerp/addons/base/ir/ir_actions.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/openerp/addons/base/ir/ir_actions.py b/openerp/addons/base/ir/ir_actions.py index d987e883732..de361d2c44b 100644 --- a/openerp/addons/base/ir/ir_actions.py +++ b/openerp/addons/base/ir/ir_actions.py @@ -918,15 +918,15 @@ class act_client(osv.osv): _sequence = 'ir_actions_id_seq' _order = 'name' - def _get_kwargs(self, cr, uid, ids, field_name, arg, context): + def _get_params(self, cr, uid, ids, field_name, arg, context): return dict([ - ((record.id, ast.literal_eval(record.kwargs_store)) - if record.kwargs_store else (record.id, False)) + ((record.id, ast.literal_eval(record.params_store)) + if record.params_store else (record.id, False)) for record in self.browse(cr, uid, ids, context=context) ]) - def _set_kwargs(self, cr, uid, ids, field_name, field_value, arg, context): - assert isinstance(field_value, dict), "kwargs can only be dictionaries" + def _set_params(self, cr, uid, ids, field_name, field_value, arg, context): + assert isinstance(field_value, dict), "params can only be dictionaries" for record in self.browse(cr, uid, ids, context=context): record.write({field_name: repr(field_value)}) @@ -935,12 +935,12 @@ class act_client(osv.osv): help="An arbitrary string, interpreted by the client" " according to its own needs and wishes. There " "is no central tag repository across clients."), - 'kwargs': fields.function(_get_kwargs, fnct_inv=_set_kwargs, + 'params': fields.function(_get_params, fnct_inv=_set_params, type='binary', method=True, string="Supplementary arguments", help="Arguments sent to the client along with" "the view tag"), - 'kwargs_store': fields.binary("Kwargs storage", readonly=True) + 'params_store': fields.binary("Params storage", readonly=True) } _defaults = { 'type': 'ir.actions.client', From e816c34b0a08c71bc46b518c6d2dbf1a22f5ce39 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Aug 2011 11:01:24 +0200 Subject: [PATCH 218/230] [IMP] use blockUI in static home installation, since we got it bzr revid: xmo@openerp.com-20110804090124-rteblcid3mx59599 --- addons/base_default_home/static/src/js/home.js | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/addons/base_default_home/static/src/js/home.js b/addons/base_default_home/static/src/js/home.js index 8cdec179999..e95b9681ceb 100644 --- a/addons/base_default_home/static/src/js/home.js +++ b/addons/base_default_home/static/src/js/home.js @@ -77,20 +77,16 @@ openerp.base_default_home = function (openerp) { [['name', '=', module_name], ['state', '=', 'uninstalled']]), Upgrade = new openerp.base.DataSet(this, 'base.module.upgrade'); - var $overlay = $('
') - .appendTo(document.body) - .css('z-index', 10001), - $wait = $overlay.add( - $('') - .appendTo(document.body) - .css({position: 'absolute', top: '50%', left: '50%'})); + $.blockUI({ + message: '' + }); Modules.read_slice(['id'], null, null, function (records) { if (!(records.length === 1)) { return; } Modules.call('state_update', [_.pluck(records, 'id'), 'to install', ['uninstalled']], function () { Upgrade.call('upgrade_module', [[]], function () { - $wait.remove(); + $.unblockUI(); // TODO: less brutal reloading window.location.reload(true); }); From 9bc6c66a2cfd8c4fa071a13aa8fbf5c301b77613 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Aug 2011 11:20:43 +0200 Subject: [PATCH 219/230] [IMP] don't recreate the home template from scratch every single time bzr revid: xmo@openerp.com-20110804092043-rkc4zhj35za0wskz --- addons/base/controllers/main.py | 68 ++++++++++++++++++--------------- 1 file changed, 37 insertions(+), 31 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 6f63e5c7e24..178a804d0da 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -1,19 +1,23 @@ # -*- coding: utf-8 -*- -import base64, glob, os, re +import base64 +import csv +import glob +import operator +import os +import re +import simplejson +import textwrap +import xmlrpclib from xml.etree import ElementTree from cStringIO import StringIO -import operator -import simplejson +import cherrypy import openerpweb import openerpweb.ast import openerpweb.nonliterals -import cherrypy -import xmlrpclib -import csv # Should move to openerpweb.Xml2Json class Xml2Json: @@ -86,6 +90,27 @@ def concat_files(file_list): files_concat = "".join(files_content) return files_concat +home_template = textwrap.dedent(""" + + + + OpenERP + %(javascript)s + + + %(css)s + + + + +""") class WebClient(openerpweb.Controller): _cp_path = "/base/webclient" @@ -115,40 +140,21 @@ class WebClient(openerpweb.Controller): @openerpweb.httprequest def home(self, req, s_action=None): - template =""" - - - - OpenERP - %s - - - %s - - - - - """.replace('\n'+' '*8,'\n') - # script tags jslist = ['/base/webclient/js'] if 1: # debug == 1 jslist = manifest_glob(['base'], 'js') - js = "\n ".join([''%i for i in jslist]) + js = "\n ".join([''%i for i in jslist]) # css tags csslist = ['/base/webclient/css'] if 1: # debug == 1 csslist = manifest_glob(['base'], 'css') - css = "\n ".join([''%i for i in csslist]) - r = template % (js, css) + css = "\n ".join([''%i for i in csslist]) + r = home_template % { + 'javascript': js, + 'css': css + } return r class Database(openerpweb.Controller): From 3ce3ce9cb6ded7a2d434c2e39730570337ec17e7 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Aug 2011 12:02:55 +0200 Subject: [PATCH 220/230] [FIX] handle error on XML-RPC method part of yet-to-merge server code bzr revid: xmo@openerp.com-20110804100255-y5n6troopyhf41wv --- addons/base_default_home/static/src/js/home.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/addons/base_default_home/static/src/js/home.js b/addons/base_default_home/static/src/js/home.js index e95b9681ceb..eef664a4700 100644 --- a/addons/base_default_home/static/src/js/home.js +++ b/addons/base_default_home/static/src/js/home.js @@ -69,6 +69,9 @@ openerp.base_default_home = function (openerp) { self.install_module($(this).val()); }) + }, function (err, event) { + event.preventDefault(); + return old_home.call(self); }); }, install_module: function (module_name) { From fd573bc0d965555245293adf78989fc431c2366c Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 4 Aug 2011 12:07:31 +0200 Subject: [PATCH 221/230] [FIX] Some fixes in calendar since dhtmlxSheduler upgrade bzr revid: fme@openerp.com-20110804100731-v032rcnxthqe0y7u --- .../base_calendar/static/src/js/calendar.js | 25 ++++++++----------- .../static/src/xml/base_calendar.xml | 14 +++++------ 2 files changed, 17 insertions(+), 22 deletions(-) diff --git a/addons/base_calendar/static/src/js/calendar.js b/addons/base_calendar/static/src/js/calendar.js index ed16ea998e3..2e5d0c6a2b2 100644 --- a/addons/base_calendar/static/src/js/calendar.js +++ b/addons/base_calendar/static/src/js/calendar.js @@ -70,35 +70,28 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ } this.init_scheduler(); - this.load_scheduler(); this.has_been_loaded.resolve(); }, init_scheduler: function() { var self = this; scheduler.clearAll(); - scheduler.config.api_date = "%Y-%m-%d %H:%M:%S"; - //scheduler.config.details_on_dblclick = true; - //scheduler.config.details_on_create = true; - scheduler.keys.edit_cancel = 27; - if (this.fields[this.date_start]['type'] == 'time') { scheduler.config.xml_date = "%H:%M:%S"; } else { - scheduler.config.xml_date = "%Y-%m-%d %H:%M:%S"; + scheduler.config.xml_date = "%Y-%m-%d %H:%i"; } - - this.mode = this.mode || 'month'; - + scheduler.config.api_date = "%Y-%m-%d %H:%i"; scheduler.config.multi_day = true; //Multi day events are not rendered in daily and weekly views // Initialize Sceduler + this.mode = this.mode || 'month'; scheduler.init('openerp_scheduler', null, this.mode); scheduler.attachEvent('onEventAdded', this.do_create_event); scheduler.attachEvent('onEventDeleted', this.do_delete_event); scheduler.attachEvent('onEventChanged', this.do_save_event); - scheduler.renderCalendar({ + this.mini_calendar = scheduler.renderCalendar({ container: this.sidebar.navigator.element_id, navigation: true, date: scheduler._date, @@ -109,6 +102,7 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ }, resize_scheduler: function() { scheduler.setCurrentView(scheduler._date); + scheduler.updateCalendar(this.mini_calendar); }, load_scheduler: function() { var self = this; @@ -163,7 +157,6 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ } res_events.push(this.convert_event(evt)); } - scheduler.parse(res_events, 'json'); this.resize_scheduler(); this.sidebar.responsible.on_events_loaded(sidebar_items); @@ -266,9 +259,11 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ this.dataset.write(event_id, data); }, do_delete_event: function(event_id, event_obj) { - var self = this; - this.dataset.unlink(event_id, function(r) { - }); + // dhtmlx sends this event even when it does not exist in openerp. + // Eg: use cancel in dhtmlx new event dialog + if (_.indexOf(this.dataset.ids, event_id) > -1) { + this.dataset.unlink(parseInt(event_id, 10)); + } }, get_event_data: function(event_obj) { var data = { diff --git a/addons/base_calendar/static/src/xml/base_calendar.xml b/addons/base_calendar/static/src/xml/base_calendar.xml index 757c4925cd1..f14fc6af450 100644 --- a/addons/base_calendar/static/src/xml/base_calendar.xml +++ b/addons/base_calendar/static/src/xml/base_calendar.xml @@ -3,13 +3,13 @@

-
-
-
-
-
-
-
+
&nbsp;
+
&nbsp;
+
+
+
+
+
From 0094e828b9ce2505f4e4bd4ed4833597276050b8 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Aug 2011 12:37:25 +0200 Subject: [PATCH 222/230] [FIX] creation of db with no demo data lp bug: https://launchpad.net/bugs/820812 fixed bzr revid: xmo@openerp.com-20110804103725-9o6uuvg5zb15rp6h --- addons/base/controllers/main.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/addons/base/controllers/main.py b/addons/base/controllers/main.py index 178a804d0da..aaf89853cad 100644 --- a/addons/base/controllers/main.py +++ b/addons/base/controllers/main.py @@ -178,9 +178,13 @@ class Database(openerpweb.Controller): def create(self, req, fields): params = dict(map(operator.itemgetter('name', 'value'), fields)) - create_attrs = operator.itemgetter( - 'super_admin_pwd', 'db_name', 'demo_data', 'db_lang', 'create_admin_pwd')( - params) + create_attrs = ( + params['super_admin_pwd'], + params['db_name'], + bool(params.get('demo_data')), + params['db_lang'], + params['create_admin_pwd'] + ) try: return req.session.proxy("db").create(*create_attrs) From e3b56ecec4ca2787468dd970591dab309c97f465 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 4 Aug 2011 14:23:00 +0200 Subject: [PATCH 223/230] [IMP] create new databases without demo data by default bzr revid: xmo@openerp.com-20110804122300-zr1aq3bl5oq7rpxt --- addons/base/static/src/xml/base.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/addons/base/static/src/xml/base.xml b/addons/base/static/src/xml/base.xml index db0fdad44fa..0854ab8712a 100644 --- a/addons/base/static/src/xml/base.xml +++ b/addons/base/static/src/xml/base.xml @@ -89,7 +89,7 @@ - + From b8304e55f827fca74fb8d8536212fa823c4590e4 Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 4 Aug 2011 16:53:42 +0200 Subject: [PATCH 224/230] [ADD] Added error_callback to Dataset#write bzr revid: fme@openerp.com-20110804145342-81mvfc4x4ydt0hnu --- addons/base/static/src/js/data.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/addons/base/static/src/js/data.js b/addons/base/static/src/js/data.js index 3b2c88acee1..fb926a2a592 100644 --- a/addons/base/static/src/js/data.js +++ b/addons/base/static/src/js/data.js @@ -318,13 +318,13 @@ openerp.base.DataSet = openerp.base.Widget.extend( /** @lends openerp.base.Data context: this.get_context() }, callback, error_callback); }, - write: function (id, data, callback) { + write: function (id, data, callback, error_callback) { return this.rpc('/base/dataset/save', { model: this.model, id: id, data: data, context: this.get_context() - }, callback); + }, callback, error_callback); }, unlink: function(ids, callback, error_callback) { var self = this; From 4b9a2bcf7b4b1b7b859ef9f8077d3d2e78c5a5fc Mon Sep 17 00:00:00 2001 From: Fabien Meghazi Date: Thu, 4 Aug 2011 16:54:53 +0200 Subject: [PATCH 225/230] [FIX] Many fixes for calendar view bzr revid: fme@openerp.com-20110804145453-imbj970742zqe8zs --- .../base_calendar/static/src/js/calendar.js | 43 +++++++++++++------ .../static/src/xml/base_calendar.xml | 2 +- 2 files changed, 30 insertions(+), 15 deletions(-) diff --git a/addons/base_calendar/static/src/js/calendar.js b/addons/base_calendar/static/src/js/calendar.js index 2e5d0c6a2b2..2d86009db7b 100644 --- a/addons/base_calendar/static/src/js/calendar.js +++ b/addons/base_calendar/static/src/js/calendar.js @@ -21,6 +21,9 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ start: function() { this.rpc("/base_calendar/calendarview/load", {"model": this.model, "view_id": this.view_id, 'toolbar': true}, this.on_loaded); }, + stop: function() { + scheduler.clearAll(); + }, on_loaded: function(data) { this.calendar_fields = {}; this.ids = this.dataset.ids; @@ -64,13 +67,16 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ this.sidebar.add_toolbar(data.fields_view.toolbar); this.set_common_sidebar_sections(this.sidebar); this.sidebar.do_unfold(); - this.sidebar.do_fold.add_last(this.resize_scheduler); - this.sidebar.do_unfold.add_last(this.resize_scheduler); - this.sidebar.do_toggle.add_last(this.resize_scheduler); + this.sidebar.do_fold.add_last(this.refresh_scheduler); + this.sidebar.do_unfold.add_last(this.refresh_scheduler); + this.sidebar.do_toggle.add_last(this.refresh_scheduler); } this.init_scheduler(); this.has_been_loaded.resolve(); + if (this.dataset.ids.length) { + this.dataset.read_ids(this.dataset.ids, _.keys(this.fields), this.on_events_loaded); + } }, init_scheduler: function() { var self = this; @@ -82,11 +88,15 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ } scheduler.config.api_date = "%Y-%m-%d %H:%i"; scheduler.config.multi_day = true; //Multi day events are not rendered in daily and weekly views + scheduler.config.start_on_monday = true; + scheduler.config.scroll_hour = 8; + scheduler.config.drag_resize = scheduler.config.drag_create = !!this.date_stop; // Initialize Sceduler this.mode = this.mode || 'month'; scheduler.init('openerp_scheduler', null, this.mode); + scheduler.detachAllEvents(); scheduler.attachEvent('onEventAdded', this.do_create_event); scheduler.attachEvent('onEventDeleted', this.do_delete_event); scheduler.attachEvent('onEventChanged', this.do_save_event); @@ -100,8 +110,10 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ } }); }, - resize_scheduler: function() { + refresh_scheduler: function() { scheduler.setCurrentView(scheduler._date); + }, + refresh_minical: function() { scheduler.updateCalendar(this.mini_calendar); }, load_scheduler: function() { @@ -113,14 +125,14 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ '/base_calendar/static/lib/dhtmlxScheduler/sources/locale_' + self.session.locale_code + '.js', '/base_calendar/static/lib/dhtmlxScheduler/sources/locale_recurring_' + self.session.locale_code + '.js' ]).wait(function() { - self.schedule_events(events); + self.on_events_loaded(events); }); } else { - self.schedule_events(events); + self.on_events_loaded(events); } }); }, - schedule_events: function(events) { + on_events_loaded: function(events) { var self = this; scheduler.clearAll(); @@ -158,7 +170,8 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ res_events.push(this.convert_event(evt)); } scheduler.parse(res_events, 'json'); - this.resize_scheduler(); + this.refresh_scheduler(); + this.refresh_minical(); this.sidebar.responsible.on_events_loaded(sidebar_items); }, convert_event: function(event) { @@ -247,22 +260,26 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ var id = parseInt(r.result, 10); self.dataset.ids.push(id); scheduler.changeEventId(event_id, id); + self.refresh_minical(); }, function(r, event) { // TODO: open form view self.notification.warn(self.name, "Could not create event"); - event.preventDefault(); }); }, do_save_event: function(event_id, event_obj) { var self = this, data = this.get_event_data(event_obj); - this.dataset.write(event_id, data); + this.dataset.write(parseInt(event_id, 10), data, function() { + self.refresh_minical(); + }); }, do_delete_event: function(event_id, event_obj) { // dhtmlx sends this event even when it does not exist in openerp. // Eg: use cancel in dhtmlx new event dialog if (_.indexOf(this.dataset.ids, event_id) > -1) { - this.dataset.unlink(parseInt(event_id, 10)); + this.dataset.unlink(parseInt(event_id, 10, function() { + self.refresh_minical(); + })); } }, get_event_data: function(event_obj) { @@ -297,9 +314,7 @@ openerp.base_calendar.CalendarView = openerp.base.View.extend({ // TODO: handle non-empty results.group_by with read_group self.dataset.context = self.context = results.context; self.dataset.domain = self.domain = results.domain; - self.dataset.read_slice(_.keys(self.fields), 0, self.limit, function(events) { - self.schedule_events(events); - }); + self.dataset.read_slice(_.keys(self.fields), 0, self.limit, self.on_events_loaded); }); }, do_show: function () { diff --git a/addons/base_calendar/static/src/xml/base_calendar.xml b/addons/base_calendar/static/src/xml/base_calendar.xml index f14fc6af450..d5350ec9046 100644 --- a/addons/base_calendar/static/src/xml/base_calendar.xml +++ b/addons/base_calendar/static/src/xml/base_calendar.xml @@ -1,7 +1,7 @@