Reviewers: ,


Please review this at http://codereview.tryton.org/777004/

Affected files:
  M Gruntfile.js
  M src/common.js
  M src/model.js
  M src/screen.js
  M src/view.js
  A src/window.js


Index: Gruntfile.js
===================================================================

--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -15,7 +15,8 @@
                 'src/screen.js',
                 'src/view.js',
                 'src/action.js',
-                'src/common.js'
+                'src/common.js',
+                'src/window.js'
             ],
             dest: 'dist/<%= pkg.name %>.js'
         }

Index: src/common.js
===================================================================

--- a/src/common.js
+++ b/src/common.js
@@ -1,5 +1,15 @@
 /* This file is part of Tryton.  The COPYRIGHT file at the top level of
    this repository contains the full copyright notices and license terms. */
+
+var FLOAT_TIME_CONV = {
+    'Y': 8760,
+    'M': 672,
+    'w': 168,
+    'd': 24,
+    'h': 1,
+    'm': 1.0 / 60
+};
+
 (function() {
     'use strict';
 
@@ -53,6 +63,50 @@
         return text;
     };
 
+    Sao.common.float_time_to_text = function(val, conv) {
+        var value = "";
+        if (val === null) return value;
+
+        if (conv) {
+            var tmp_conv = jQuery.extend({}, FLOAT_TIME_CONV);
+            jQuery.extend(tmp_conv, conv);
+            conv = tmp_conv;
+        } else {
+            conv = FLOAT_TIME_CONV;
+        }
+
+        if (val < 0) value += "-";
+        val = Math.abs(val);
+        var years = Math.floor(val / conv.Y);
+        val -= years * conv.Y;
+        var months = Math.floor(val / conv.M);
+        val -= months * conv.M;
+        var weeks = Math.floor(val / conv.w);
+        val -= weeks * conv.w;
+        var days = Math.floor(val / conv.d);
+        val -= days * conv.d;
+        var hours = Math.floor(val);
+        val -= hours;
+        var mins = Math.floor((val % 1 + 0.01) / conv.m);
+        //TODO Localization
+        if (years)
+            value += " " + years + "Y";
+        if (months)
+            value += " " + months + "M";
+        if (weeks)
+            value += " " + weeks + "w";
+        if (days)
+            value += " " + days + "d";
+        if (hours || mins || !value) {
+            mins = mins.toFixed();
+            value += (" " +
+                    hours.toString().length < 2 ? "0" + hours.toString() : 
hours.toString() +
+                    ":" +
+                    mins.toString().length < 2 ? "0" + mins.toString() : 
mins.toString());
+        }
+        return jQuery.trim(value);
+    };
+
     Sao.common.EvalEnvironment = function(parent_, eval_type) {
         if (eval_type === undefined)
             eval_type = 'eval';

Index: src/model.js
===================================================================

--- a/src/model.js
+++ b/src/model.js
@@ -875,7 +875,7 @@
         },
         get_client: function(record) {
             var rec_name = record._values[this.name + '.rec_name'];
-            if (rec_name === undefined) {
+            if (!rec_name) {
                 this.set(record, this.get(record));
                 rec_name = record._values[this.name + '.rec_name'] || '';
             }
@@ -886,20 +886,24 @@
             // TODO force parent
             var store_rec_name = function(rec_name) {
                 record._values[this.name + '.rec_name'] = rec_name[0].rec_name;
+                return rec_name[0].rec_name;
             };
+            var prm;
             if (!rec_name && (value >= 0) && (value !== null)) {
                 var model_name = record.model.fields[this.name].description
                     .relation;
-                var prm = Sao.rpc({
+                prm = Sao.rpc({
                     'method': 'model.' + model_name + '.' + 'read',
                     'params': [[value], ['rec_name'], record.get_context()]
                 }, record.model.session);
                 prm.done(store_rec_name.bind(this));
             } else {
                 store_rec_name.call(this, [{'rec_name': rec_name}]);
+                prm = jQuery.when(rec_name);
             }
             record._values[this.name] = value;
             // TODO force parent
+            return prm;
         },
         set_client: function(record, value) {
             var rec_name;

Index: src/screen.js
===================================================================

--- a/src/screen.js
+++ b/src/screen.js
@@ -66,10 +66,6 @@
             this.content_box.append(widget);
         }
     });
-}());
-
-(function() {
-    'use strict';
 
     Sao.Screen = Sao.class_(Object, {
         init: function(model_name, attributes) {
@@ -95,6 +91,10 @@
             } else {
                 this.row_activate = attributes.row_activate;
             }
+            //if (!jQuery.isEmptyObject(this.view_ids) ||
+                    //!jQuery.isEmptyObject(this.view_to_load)) {
+                //this.switch_view();
+            //}
         },
         load_next_view: function() {
             if (this.view_to_load) {
@@ -200,9 +200,18 @@
             }
             group.screens.push(this);
             this.group = group;
+            if (jQuery.isEmptyObject(group)) {
+                this.current_record = null;
+            } else {
+                this.current_record = group[0];
+            }
         },
-        new_group: function() {
-            this.set_group(new Sao.Group(this.model, this.context, []));
+        new_group: function(ids) {
+            var group = new Sao.Group(this.model, this.context, []);
+            if (ids) {
+                group.load(ids);
+            }
+            this.set_group(group);
         },
         display: function() {
             if (this.views) {

Index: src/view.js
===================================================================

--- a/src/view.js
+++ b/src/view.js
@@ -850,6 +850,8 @@
                 return Sao.View.Form.Boolean;
             case 'text':
                 return Sao.View.Form.Text;
+            case 'many2one':
+                return Sao.View.Form.Many2One;
         }
     };
 
@@ -1097,4 +1099,122 @@
         }
     });
 
+    Sao.View.Form.Many2One = Sao.class_(Sao.View.Form.Widget, {
+        class_: 'form-many2one',
+        init: function(field_name, model, attributes) {
+            Sao.View.Form.Many2One._super.init.call(this, field_name, model,
+                attributes);
+            this.el = jQuery('<div/>', {
+                'class': this.class_
+            });
+            this.entry = jQuery('<input/>', {
+                'type': 'input'
+            });
+            this.el.append(this.entry);
+            this.but_open = jQuery('<button/>').button({
+                'icons': {
+                    'primary': "ui-icon-search"
+                },
+                'text': false
+            });
+            this.but_open.click(this.sig_edit.bind(this));
+            this.el.append(this.but_open);
+            this.but_new = jQuery('<button/>').button({
+                'icons': {
+                    'primary': "ui-icon-document"
+                },
+                'text': false
+            });
+            this.but_new.click(this.sig_new.bind(this));
+            this.el.append(this.but_new);
+            this.model = attributes.relation;
+            // TODO autocompletion
+        },
+        get_screen: function() {
+            var domain = this.field().get_domain(this.record());
+            var context = this.field().get_context(this.record());
+            return new Sao.Screen(this.model, {
+                'context': context,
+                'domain': domain,
+                'mode': ['form'],
+                'view_ids': (this.attributes.view_ids || "").split(','),
+                'views_preload': this.attributes.views
+            });
+        },
+        display: function(record, field) {
+            // TODO set_button_sensitive
+            var text_value, value;
+            Sao.View.Form.Many2One._super.display.call(this, record, field);
+            if (record) {
+                text_value = record.field_get_client(this.field_name);
+                value = record.field_get(this.field_name);
+            } else {
+                text_value = "";
+                value = null;
+            }
+            this.entry.val(text_value || '');
+            if ((value !== undefined) && (value !== null)) {
+                this.but_open.button({
+                    'icons': {
+                        'primary': "ui-icon-folder-open"
+                    }});
+            } else {
+                this.but_open.button({
+                    'icons': {
+                        'primary': "ui-icon-search"
+                    }});
+            }
+        },
+        id_from_value: function (value) {
+            return value;
+        },
+        get_model: function (value) {
+            return this.attributes.relation;
+        },
+        sig_edit: function(evt) {
+            // TODO Model Access
+            var win;
+            var value = this.record().field_get(this.field_name);
+            if (this.get_model() && (value !== undefined) && (value !== null)) 
{
+                var screen = this.get_screen();
+                var m2o_id = 
this.id_from_value(this.record().field_get(this.field_name));
+                screen.new_group([m2o_id]);
+                var callback = function (evt, ui) {
+                    this.record().field_set_client(this.field_name, value);
+                }.bind(this);
+                win = new Sao.WinForm(callback, screen); // TODO add 
save_current
+            } else if (this.get_model()) {
+                var dom;
+                var domain = this.field().get_domain(this.record());
+                var context = this.field().get_context(this.record());
+                var text = this.entry.val();
+                if (text) {
+                    dom = [["rec_name", "ilike", "%" + text + "%"]];
+                } else {
+                    dom = domain;
+                }
+                var model = new Sao.Model(this.get_model());
+                var ids_prm = model.execute('search',
+                        [dom, 0, Sao.config.limit, null], context);
+                ids_prm.done(function (ids) {
+                    if (ids.length == 1) {
+                        this.record().field_set_client(this.field_name,
+                            this.id_from_value(ids[0]));
+                        return;
+                    }
+                    var callback = function (evt, ui) {
+                        this.record().field_set_client(this.field_name, value);
+                    }.bind(this);
+                    win = new Sao.WinSearch(callback, this.model, false, ids, 
context,
+                        domain, (this.attributes.view_ids || "").split(','),
+                        (this.attributes.views || {}),
+                        false); // TODO compute from but_new status
+                }.bind(this));
+            }
+        },
+        sig_new: function(evt) {
+            console.log('sig_new');
+        }
+    });
+
 }());

Index: src/window.js
===================================================================
new file mode 100644

--- /dev/null
+++ b/src/window.js
@@ -0,0 +1,80 @@
+/* This file is part of Tryton.  The COPYRIGHT file at the top level of
+   this repository contains the full copyright notices and license terms. */
+(function() {
+    'use strict';
+
+    Sao.WinForm = Sao.class_(Object, {
+        init: function(callback, screen, view_type, new_obj, many, domain,
+                  context, save_current) {
+            this.screen = screen;
+            if (!view_type) {
+                view_type = 'form';
+            }
+            var screen_views = [];
+            for (var i=0,len=this.screen.views; i<len; i++) {
+                screen_views.push(this.screen.views[i].view_type);
+            }
+            if (screen_views.indexOf(view_type) == -1 &&
+                this.screen.view_to_load.indexOf(view_type) == -1) {
+                this.screen.add_view_id(null, view_type);
+            }
+            var switch_prm = this.screen.switch_view(view_type);
+            this.many = many || 0;
+            this.domain = domain || null;
+            this.context = context || null;
+            this.save_current = save_current;
+            this.prev_view = screen.current_view;
+            this.el = jQuery('<div/>');
+
+            if (view_type == "tree") {
+                // TODO
+            }
+
+            switch_prm.done(function () {
+                this.el.dialog({
+                    autoOpen: false,
+                    buttons: [],
+                    title: '' // this.screen.current_view
+                });
+                this.el.bind('dialogclose', callback);
+                this.el.append(this.screen.screen_container.content_box);
+                this.el.dialog('open');
+                this.screen.display();
+            }.bind(this));
+
+        }
+    });
+
+    Sao.WinSearch = Sao.class_(Object, {
+        init: function(callback, model, sel_multi, ids, context, domain, 
view_ids,
+                  views_preload, new_) {
+            views_preload = views_preload || {};
+            this.domain = domain || [];
+            this.context = context || {};
+            this.sel_multi = sel_multi;
+
+            this.el = jQuery('<div/>');
+            this.el.dialog({
+                autoOpen: false,
+                buttons: []
+            });
+            this.screen = new Sao.Screen(model, {
+                mode: ['tree'],
+                context: context,
+                view_ids: view_ids
+            });
+            this.el.bind('dialogclose', callback);
+            if (!jQuery.isEmptyObject(ids)) {
+                this.screen.new_group(ids);
+            }
+            this.screen.load_next_view().done(function() {
+                this.screen.switch_view().done(function () {
+                    this.el.append(this.screen.screen_container.el);
+                    this.el.dialog('open');
+                    this.screen.display();
+                }.bind(this));
+            }.bind(this));
+        }
+    });
+
+}());

Reply via email to