[IMP] restrict drag&drop of list elements to the list itself
authorXavier Morel <xmo@openerp.com>
Thu, 8 Dec 2011 15:09:50 +0000 (16:09 +0100)
committerXavier Morel <xmo@openerp.com>
Thu, 8 Dec 2011 15:09:50 +0000 (16:09 +0100)
bzr revid: xmo@openerp.com-20111208150950-b1eip9apksztlrda

addons/web/static/src/js/view_form.js
addons/web/static/src/js/view_list_editable.js
addons/web/static/src/js/views.js
addons/web_calendar/static/src/js/calendar.js
addons/web_calendar/static/src/xml/web_calendar.xml
openerp/addons/base/base.sql
openerp/addons/base/module/module.py
openerp/addons/base/module/module_view.xml
openerp/modules/db.py
openerp/modules/module.py

index 15a402e..2f89eac 100644 (file)
@@ -1582,7 +1582,7 @@ openerp.web.form.FieldSelection = openerp.web.form.Field.extend({
             .change(function () { ischanging = true; })
             .click(function () { ischanging = false; })
             .keyup(function (e) {
-                if (e.which !== 13 || !ischanging) { return; }
+                if (!_([13, 38, 40]).contains(e.which) || !ischanging) { return; }
                 e.stopPropagation();
                 ischanging = false;
             });
@@ -1790,13 +1790,16 @@ openerp.web.form.FieldMany2One = openerp.web.form.Field.extend({
             minLength: 0,
             delay: 0
         });
-        // used to correct a bug when selecting an element by pushing 'enter' in an editable list
+        // Don't propagate KEY_UP and KEY_DOWN event to parent (for editable
+        // list), don't propagate KEY_RETURN either when the autocomplete
+        // control is currently open
         this.$input.keyup(function(e) {
-            if (e.which === 13) {
-                if (isSelecting)
-                    e.stopPropagation();
+            if (e.which === 38 || e.which === 40) {
+                e.stopPropagation();
+            } else if (isSelecting && e.which === 13) {
+                e.stopPropagation();
+                isSelecting = false;
             }
-            isSelecting = false;
         });
     },
     // autocomplete component content handling
index b2edf55..805ce0d 100644 (file)
@@ -3,8 +3,11 @@
  * @namespace
  */
 openerp.web.list_editable = function (openerp) {
+    // https://developer.mozilla.org/en/DOM/KeyboardEvent#Virtual_key_codes
     var KEY_RETURN = 13,
-        KEY_ESCAPE = 27;
+        KEY_ESCAPE = 27,
+        KEY_UP = 38,
+        KEY_DOWN = 40;
     var QWeb = openerp.web.qweb;
 
     // editability status of list rows
@@ -178,7 +181,7 @@ openerp.web.list_editable = function (openerp) {
 
                     var next_record_id,
                         next_record = self.records.at(
-                                self.records.indexOf(result.edited_record) + 1);
+                            self.records.indexOf(result.edited_record) + 1);
                     if (next_record) {
                         next_record_id = next_record.get('id');
                         self.dataset.index = _(self.dataset.ids)
@@ -190,6 +193,39 @@ openerp.web.list_editable = function (openerp) {
                     self.edit_record(next_record_id);
                 });
                 break;
+            case KEY_DOWN:
+                this.save_row().then(function (result) {
+                    var next_record_id,
+                        next_record = self.records.at(
+                            self.records.indexOf(result.edited_record) + 1);
+                    if (next_record) {
+                        next_record_id = next_record.get('id');
+                        self.dataset.index = _(self.dataset.ids)
+                                .indexOf(next_record_id);
+                    } else {
+                        self.dataset.index = 0;
+                        next_record_id = self.records.at(0).get('id');
+                    }
+                    self.edit_record(next_record_id);
+                });
+                break;
+            case KEY_UP:
+                this.save_row().then(function (result) {
+                    var previous_record_id,
+                        previous_record = self.records.at(
+                            self.records.indexOf(result.edited_record) - 1);
+                    if (previous_record) {
+                        previous_record_id = previous_record.get('id');
+                        self.dataset.index = _(self.dataset.ids)
+                                .indexOf(previous_record_id);
+                    } else {
+                        var last = self.records.length - 1;
+                        self.dataset.index = last;
+                        previous_record_id = self.records.at(last).get('id');
+                    }
+                    self.edit_record(previous_record_id);
+                });
+                break;
             case KEY_ESCAPE:
                 this.cancel_edition();
                 break;
index f583dd2..bdc1eeb 100644 (file)
@@ -1069,7 +1069,9 @@ session.web.View = session.web.Widget.extend(/** @lends session.web.View# */{
             view_type : 'form',
             view_mode : 'form',
             target : 'new',
-            flags : {}
+            flags : {
+                action_buttons : true
+            }
         }
         if (id) {
             action.res_id = id,
index 75b168c..9f2c860 100644 (file)
@@ -25,6 +25,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
              '#ff8e00', '#ff0000', '#b0008c', '#9000ff', '#0078ff', '#00ff00', '#e6ff00', '#ffff00',
              '#905000', '#9b0000', '#840067', '#510090', '#0000c9', '#009b00', '#9abe00', '#ffc900' ];
         this.color_map = {};
+        this.last_search = [];
     },
     start: function() {
         this._super();
@@ -106,9 +107,12 @@ openerp.web_calendar.CalendarView = openerp.web.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.time_step = 15;
         scheduler.config.scroll_hour = 8;
         scheduler.config.drag_resize = true;
         scheduler.config.drag_create = true;
+        scheduler.config.mark_now = true;
+        scheduler.config.day_date = '%l %j';
 
         scheduler.init('openerp_scheduler', null, this.mode || 'month');
 
@@ -120,6 +124,7 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
         scheduler.attachEvent('onEventDeleted', this.do_delete_event);
         scheduler.attachEvent('onEventChanged', this.do_save_event);
         scheduler.attachEvent('onDblClick', this.do_edit_event);
+        scheduler.attachEvent('onClick', this.do_edit_event);
         scheduler.attachEvent('onBeforeLightbox', this.do_edit_event);
 
         if (this.options.sidebar) {
@@ -162,9 +167,6 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
         for (var e = 0; e < events.length; e++) {
             var evt = events[e];
             if (!evt[this.date_start]) {
-                if (this.session.debug) {
-                    this.do_warn("Start date is not defined for event :", evt['id']);
-                }
                 break;
             }
 
@@ -333,10 +335,14 @@ openerp.web_calendar.CalendarView = openerp.web.View.extend({
         return data;
     },
     do_search: function(domain, context, group_by) {
-        var self = this;
+        var self = this
+        if (!domain) {
+            this.do_search.apply(this, this.last_search);
+        } else {
+            this.last_search = [domain, context, group_by];
+        }
         scheduler.clearAll();
         $.when(this.has_been_loaded).then(function() {
-            // TODO: handle non-empty results.group_by with read_group
             self.dataset.read_slice(_.keys(self.fields), {
                 offset: 0,
                 limit: self.limit
index c9e5f62..53bb710 100644 (file)
@@ -1,6 +1,5 @@
 <template>
  <t t-name="CalendarView">
-    <h3 class="title"><t t-esc="fields_view.arch.attrs.string"/></h3>
     <div id="openerp_scheduler" class="dhx_cal_container" style="height: 600px;">
         <div class="dhx_cal_navline">
             <div class="dhx_cal_prev_button">&amp;nbsp;</div>
index 6f3a8ed..a93ea4e 100644 (file)
@@ -295,7 +295,7 @@ CREATE TABLE ir_module_module (
     category_id integer REFERENCES ir_module_category ON DELETE SET NULL,
     certificate character varying(64),
     description text,
-    core boolean default False,
+    is_application boolean default False,
     demo boolean default False,
     web boolean DEFAULT FALSE,
     license character varying(32),
index fd69c07..68df983 100644 (file)
@@ -215,7 +215,7 @@ class module(osv.osv):
         'views_by_module': fields.function(_get_views, method=True, string='Views', type='text', multi="meta", store=True),
         'certificate' : fields.char('Quality Certificate', size=64, readonly=True),
         'web': fields.boolean('Has a web component', readonly=True),
-        'core': fields.boolean('Is a Core Application', readonly=True),
+        'is_application': fields.boolean('Is a Core Application', readonly=True),
         'icon': fields.char('Icon URL', size=128),
         'complexity': fields.selection([('easy','Easy'), ('normal','Normal'), ('expert','Expert')],
             string='Complexity', readonly=True,
index ff4dee3..2c9f384 100644 (file)
@@ -39,8 +39,8 @@
             <field name="arch" type="xml">
                 <search string="Search modules">
                     <group col='10' colspan='4'>
-                        <filter icon="terp-check" string="Main Apps" domain="[('core', '=', 1)]"/>
-                        <filter icon="terp-check" string="Extra" domain="[('core', '=', 0)]"/>
+                        <filter icon="terp-check" string="Main Apps" domain="[('is_application', '=', 1)]"/>
+                        <filter icon="terp-check" string="Extra" domain="[('is_application', '=', 0)]"/>
 
                         <separator orientation="vertical"/>
                         <filter icon="terp-check" string="Installed" domain="[('state', 'in', ['installed', 'to upgrade', 'to remove'])]"/>
                         <field name="complexity"/>
                         <field name="demo"/>
                         <field name="icon"/>
-                        <field name="core"/>
+                        <field name="is_application"/>
                     </group>
                     <notebook colspan="4">
                         <page string="Module">
index 4f80327..c3118e4 100644 (file)
@@ -75,14 +75,14 @@ def initialize(cr):
 
         cr.execute('INSERT INTO ir_module_module \
                 (author, website, name, shortdesc, description, \
-                    category_id, state, certificate, web, license, complexity, core, icon) \
+                    category_id, state, certificate, web, license, complexity, is_application, icon) \
                 VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s) RETURNING id', (
             info['author'],
             info['website'], i, info['name'],
             info['description'], category_id, state, info['certificate'],
             info['web'],
             info['license'],
-            info['complexity'], info['core'], info['icon']))
+            info['complexity'], info['is_application'], info['icon']))
         id = cr.fetchone()[0]
         cr.execute('INSERT INTO ir_model_data \
             (name,model,module, res_id, noupdate) VALUES (%s,%s,%s,%s,%s)', (
index 09fcb2e..711d05a 100644 (file)
@@ -250,7 +250,7 @@ def load_information_from_description_file(module):
             info.setdefault('name', False)
             info.setdefault('description', '')
             info.setdefault('complexity', 'normal')
-            info.setdefault('core', False)
+            info.setdefault('is_application', False)
             info.setdefault('icon', '')
             info['certificate'] = info.get('certificate') or None
             info['web'] = info.get('web') or False