Changes for search field
authorMartin Taal <martin.taal@openbravo.com>
Fri, 31 Dec 2010 13:25:30 +0100
changeset 9510 db0ac9854e2d
parent 9509 19e6880578da
child 9511 9854f7b4d987
Changes for search field
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-formitem-widgets.js
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-grid.js
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-standard-view.js
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-utilities.js
modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-view-form.js
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-formitem-widgets.js	Fri Dec 31 12:53:14 2010 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-formitem-widgets.js	Fri Dec 31 13:25:30 2010 +0100
@@ -38,13 +38,137 @@
 // Item used for Openbravo search fields.
 isc.ClassFactory.defineClass('OBSearchItem', StaticTextItem);
 
+function closeSearch(action, value, display, parameters, wait){
+  var length, i, hiddenInputName, targetFld = isc.OBSearchItem.openSearchItem;
+  if (action === 'SAVE') {
+    targetFld.setValue(value);
+    targetFld.form.setValue(targetFld.displayField, display);
+ 
+    if (parameters && parameters.length > 0) {
+      length = parameters.length;
+      for (i = 0; i < length; i++) {
+        hiddenInputName = ((parameters[i].esRef) ? targetFld.inpColumnName : "") + parameters[i].campo;
+        targetFld.form.hiddenInputs[hiddenInputName] = parameters[i].valor;
+      }
+    }
+    targetFld._doFICCall = true;
+    targetFld.form.handleItemChange(targetFld);
+  }
+  isc.OBSearchItem.openedWindow.close();
+  isc.OBSearchItem.openSearchItem = null;
+}
+
 isc.OBSearchItem.addProperties({
   showPickerIcon: true,
   pickerIconHeight: 21,
   pickerIconWidth: 21,
   pickerIconSrc: '[SKINIMG]../../org.openbravo.client.application/images/form/search_picker.png',
-  showPicker: function() {
-     this.openWindow();    
+      
+  changed: function(){
+    var ret = this.Super("changed", arguments);
+    if (this.form && this.form.handleItemChange) {
+      this.form.handleItemChange(this);
+    }
+    return ret;
+  },
+  
+  showPicker: function(){
+    var parameters = [], index = 0, i = 0, length, fld, inpName;
+    parameters[index++] = 'inpIDValue';
+    if (this.getValue()) {
+      parameters[index++] = this.getValue();
+    } else {
+      parameters[index++] = '';
+    }
+    parameters[index++] = 'WindowID';
+    parameters[index++] = this.form.view.standardWindow.windowId;
+    length = this.inFields.length;
+    for (i = 0; i < length; i++) {
+      inpName = this.inFields[i];
+      fld = this.form.getFieldFromInpColumnName(inpName);
+      if (fld && fld.getValue()) {
+        parameters[index++] = inpName;
+        parameters[index++] = fld.getValue();
+      }
+    }
+    this.openSearchWindow(this.searchUrl, parameters, this.getValue());
+  },
+  
+  openSearchWindow: function(url, parameters, strValueID){
+    var height, width, top, left;
+    var complementsNS4 = "";
+    var auxField = "";
+    var hidden;
+    
+    if (url.indexOf("Location") != -1) {
+      height = 300;
+      width = 600;
+    } else {
+      height = (screen.height - 100);
+      width = 900;
+    }
+    top = parseInt((screen.height - height) / 2, 10);
+    left = parseInt((screen.width - width) / 2, 10);
+    
+    if (isc.OBSearchItem.openedWindow) {
+      isc.OBSearchItem.openedWindow.close();
+      this.clearUnloadEventHandling();
+    }
+    isc.OBSearchItem.openedWindow = null;
+    
+    if (strValueID) {
+      auxField = "inpNameValue=" + encodeURIComponent(this.form.getValue(this.displayField));
+    }
+    if (parameters) {
+      var total = parameters.length;
+      for (var i = 0; i < total; i++) {
+        if (auxField !== "") {
+          auxField += "&";
+        }
+        // TODO: check this
+        //        if (parameters[i] === "isMultiLine" && parameters[i + 1] == "Y") {
+        //          gIsMultiLineSearch = true;
+        //        }
+        auxField += parameters[i] + "=" + ((parameters[i + 1] !== null) ? encodeURIComponent(parameters[i + 1]) : "");
+        if (parameters[i] === "Command") {
+          hidden = true;
+        }
+        i++;
+      }
+    }
+    
+    if (navigator.appName.indexOf("Netscape")) {
+      complementsNS4 = "alwaysRaised=1, dependent=1, directories=0, hotkeys=0, menubar=0, ";
+    }
+    var complements = complementsNS4 + "height=" + height + ", width=" + width + ", left=" + left + ", top=" + top + ", screenX=" + left + ", screenY=" + top + ", location=0, resizable=1, scrollbars=1, status=0, toolbar=0, titlebar=0, modal='yes'";
+    isc.OBSearchItem.openedWindow = window.open(OB.Application.contextUrl + url + ((auxField === "") ? "" : "?" + auxField), 'SELECTOR', complements);
+    if (isc.OBSearchItem.openedWindow) {
+      isc.OBSearchItem.openedWindow.focus();
+      this.setUnloadEventHandling();
+    }
+    isc.OBSearchItem.openSearchItem = this;
+  },
+  
+  setUnloadEventHandling: function(){
+    var me = this;
+    if (document.layers) {
+      document.captureEvents(Event.UNLOAD);
+    }
+    window.onunload = function(){
+      if (isc.OBSearchItem.openedWindow) {
+        isc.OBSearchItem.openedWindow.close();
+      }
+      isc.OBSearchItem.openedWindow = null;
+      me.clearUnloadEventHandling();
+    };
+  },
+  
+  clearUnloadEventHandling: function(){
+    if (document.layers) {
+      window.releaseEvents(Event.UNLOAD);
+    }
+    window.onunload = function(){
+    };
   }
 });
 
@@ -53,8 +177,7 @@
 isc.ClassFactory.defineClass('OBEncryptedItem', isc.PasswordItem);
 
 // add specific properties here
-isc.OBEncryptedItem.addProperties({
-});
+isc.OBEncryptedItem.addProperties({});
 
 // == OBFormButton ==
 // The default form button.
@@ -84,14 +207,14 @@
 
   itemData: null,
   
-  changed: function() {
+  changed: function(){
     var ret = this.Super("changed", arguments);
     if (this.form && this.form.handleItemChange) {
       this.form.handleItemChange(this);
     }
     return ret;
   },
-
+  
   getValueMap: function(){
     if (this.itemData) {
       return this.itemData;
@@ -119,15 +242,15 @@
   getDataSource: function(){
     return this.getOptionDataSource();
   },
-     
-  changed: function() {
+  
+  changed: function(){
     var ret = this.Super("changed", arguments);
     if (this.form && this.form.handleItemChange) {
       this.form.handleItemChange(this);
     }
     return ret;
   },
-
+  
   getOptionDataSource: function(){
     if (this.optionDataSource) {
       return this.optionDataSource;
@@ -867,17 +990,17 @@
   titleClick: function(form, item){
     item.focusInItem();
   },
-      
-  changed: function() {
+  
+  changed: function(){
     var ret = this.Super("changed", arguments);
     this._doFICCall = true;
     return ret;
   },
-
-  blur : function (form, item) {
+  
+  blur: function(form, item){
     if (form && form.handleItemChange) {
       form.handleItemChange(this);
     }
     this._hasChanged = false;
-  }  
+  }
 });
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-standard-view.js	Fri Dec 31 12:53:14 2010 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-standard-view.js	Fri Dec 31 13:25:30 2010 +0100
@@ -1,1238 +1,1283 @@
-/*
- *************************************************************************
- * The contents of this file are subject to the Openbravo  Public  License
- * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
- * Version 1.1  with a permitted attribution clause; you may not  use this
- * file except in compliance with the License. You  may  obtain  a copy of
- * the License at http://www.openbravo.com/legal/license.html
- * Software distributed under the License  is  distribfuted  on  an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific  language  governing  rights  and  limitations
- * under the License.
- * The Original Code is Openbravo ERP.
- * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2010 Openbravo SLU
- * All Rights Reserved.
- * Contributor(s):  ______________________________________.
- ************************************************************************
- */
-
-isc.ClassFactory.defineClass('OBStandardWindow', isc.VLayout);
-
-// The OBStandardWindow contains the toolbar and the root view.
-isc.OBStandardWindow.addProperties({
-  toolBar: null,
-  view: null,
-  
-  viewProperties: null,
-  
-  initWidget: function(){
-    var standardWindow = this;
-    this.toolBar = isc.OBToolbar.create({
-      height: this.toolBarHeight,
-      minHeight: this.toolBarHeight,
-      maxHeight: this.toolBarHeight,
-      leftMembers: [isc.OBToolbarIconButton.create({
-        action: 'alert(\'New Document\')',
-        buttonType: 'newDoc',
-        prompt: 'New Document'
-      }), isc.OBToolbarIconButton.create({
-        action: 'alert(\'New Row\')',
-        buttonType: 'newRow',
-        prompt: 'New Row'
-      })],
-      rightMembers: [isc.OBToolbarTextButton.create({
-        action: 'OB.Utilities.openActionButton(this, {viewId: "OBPopupClassicWindow", obManualURL: "TablesandColumns/Table_Edition.html", processId: "173", id: "173", command: "BUTTONImportTable173", tabTitle: "Testing"});',
-        title: 'Button A'
-      })]
-    });
-    
-    this.toolBar.addLeftMembers([isc.OBToolbarIconButton.create({
-      action: 'alert(\'Save\')',
-      buttonType: 'save',
-      prompt: 'Save'
-    }), isc.OBToolbarIconButton.create({
-      action: 'alert(\'Create Copy\')',
-      buttonType: 'createCopy',
-      prompt: 'Create Copy'
-    })]);
-    
-    this.toolBar.addRightMembers([isc.OBToolbarTextButton.create({
-      action: 'alert(\'Button B\')',
-      title: 'Button B'
-    })]);
-    
-    this.addMember(this.toolBar);
-    
-    this.viewProperties.standardWindow = this;
-    
-    this.view = isc.OBStandardView.create(this.viewProperties);
-    this.addMember(this.view);
-    this.Super('initWidget', arguments);
-    this.view.toolBar = this.toolBar;
-    
-    // is set later after creation
-    this.view.tabTitle = this.tabTitle;
-  },
-  
-  draw: function(){
-    var standardWindow = this;
-    var ret = this.Super('draw', arguments);
-    
-    if (this.targetRecordId) {
-      OB.RemoteCallManager.call('org.openbravo.client.application.window.ComputeSelectedRecordActionHandler', null, {
-        targetEntity: this.targetEntity,
-        targetRecordId: this.targetRecordId,
-        windowId: this.windowId
-      }, function(response, data, request){
-        standardWindow.directTabInfo = data.result;
-        standardWindow.view.openDirectTab();
-      });
-      delete this.targetRecordId;
-      delete this.targetTabId;
-      delete this.targetEntity;
-    }
-    
-    return ret;
-  },
-  
-  setViewTabId: function(viewTabId){
-    this.view.viewTabId = viewTabId;
-    this.viewTabId = viewTabId;
-  },
-  
-  doHandleClick: function(){
-    this.view.doHandleClick();
-  },
-  
-  doHandleDoubleClick: function(){
-    this.view.doHandleDoubleClick();
-  },
-  
-  getBookMarkParams: function(){
-    var result = {};
-    result.windowId = this.windowId;
-    result.viewId = this.getClassName();
-    result.tabTitle = this.tabTitle;
-    return result;
-  },
-  
-  isEqualParams: function(params){
-    var equalTab = params.windowId && params.windowId === this.windowId;
-    return equalTab;
-  },
-  
-  isSameTab: function(viewName, params){
-    return this.isEqualParams(params);
-  },
-  
-  // returns the view information for the help view.
-  getHelpView: function(){
-    return null;
-  }
-  
-});
-
-// Note: currently this class covers both the top-level view as well as child views
-// in child tabs. If there is a lot of separate code then maybe the 2 types of usages
-// have to be factored out in separate classes.
-isc.ClassFactory.defineClass('OBStandardView', isc.VLayout);
-
-isc.OBStandardView.addClassProperties({
-  STATE_TOP_MAX: 'TopMax', // the part in the top is maximized, meaning
-  // that the tabset in the bottom is minimized
-  STATE_BOTTOM_MAX: 'BottomMax', // the tabset part is maximized, the
-  // the top has height 0
-  STATE_MID: 'Mid', // the view is split in the middle, the top part has
-  // 50%, the tabset also
-  STATE_IN_MID: 'InMid', // state of the tabset which is shown in the middle,
-  // the parent of the tabset has state
-  // isc.OBStandardView.STATE_MID
-  STATE_MIN: 'Min' // minimized state, the parent has
-  // isc.OBStandardView.STATE_TOP_MAX or
-  // isc.OBStandardView.STATE_IN_MID
-});
-
-// = OBStandardView =
-// The OBStandardView is the composite canvas which contains a form/grid and
-// child tabs.
-
-isc.OBStandardView.addProperties({
-
-  // properties used by the ViewManager, only relevant in case this is the
-  // top
-  // view shown directly in the main tab
-  showsItself: false,
-  tabTitle: null,
-  
-  // ** {{{ windowId }}} **
-  // The id of the window shown here, only set for the top view in the
-  // hierarchy
-  // and if this is a window/tab view.
-  windowId: null,
-  
-  // ** {{{ tabId }}} **
-  // The id of the tab shown here, set in case of a window/tab view.
-  tabId: null,
-  
-  // ** {{{ processId }}} **
-  // The id of the process shown here, set in case of a process view.
-  processId: null,
-  
-  // ** {{{ formId }}} **
-  // The id of the form shown here, set in case of a form view.
-  formId: null,
-  
-  // ** {{{ parentView }}} **
-  // The parentView if this view is a child in a parent child structure.
-  parentView: null,
-  
-  // ** {{{ parentTabSet }}} **
-  // The tabSet which shows this view. If the parentView is null then this
-  // is the
-  // top tabSet.
-  parentTabSet: null,
-  tab: null,
-  
-  // ** {{{ toolbar }}} **
-  // The toolbar canvas.
-  toolBar: null,
-  
-  // ** {{{ formGridLayout }}} **
-  // The layout which holds the form and grid.
-  formGridLayout: null,
-  
-  // ** {{{ childTabSet }}} **
-  // The tabSet holding the child tabs with the OBView instances.
-  childTabSet: null,
-  
-  // ** {{{ hasChildTabs }}} **
-  // Is set to true if there are child tabs.
-  hasChildTabs: false,
-  
-  // ** {{{ dataSource }}} **
-  // The dataSource used to fill the data in the grid/form.
-  dataSource: null,
-  
-  // ** {{{ viewForm }}} **
-  // The viewForm used to display single records
-  viewForm: null,
-  
-  // ** {{{ viewGrid }}} **
-  // The viewGrid used to display multiple records
-  viewGrid: null,
-  
-  // ** {{{ parentProperty }}} **
-  // The name of the property refering to the parent record, if any
-  parentProperty: null,
-  
-  // ** {{{ targetRecordId }}} **
-  // The id of the record to initially show.
-  targetRecordId: null,
-  
-  // ** {{{ targetEntity }}} **
-  // The entity to show.
-  entity: null,
-  
-  width: '100%',
-  height: '100%',
-  margin: 0,
-  padding: 0,
-  overflow: 'hidden',
-  
-  // set if one record has been selected
-  lastRecordSelected: null,
-  
-  // ** {{{ refreshContents }}} **
-  // Should the contents listgrid/forms be refreshed when the tab
-  // gets selected and shown to the user.
-  refreshContents: true,
-  
-  state: isc.OBStandardView.STATE_MID,
-  previousState: isc.OBStandardView.STATE_TOP_MAX,
-  
-  initWidget: function(properties){
-    var isRootView = !this.parentProperty;
-    
-    if (isRootView) {
-      this.buildStructure();
-    }
-    
-    OB.TestRegistry.register('org.openbravo.client.application.ViewGrid_' + this.tabId, this.viewGrid);
-    OB.TestRegistry.register('org.openbravo.client.application.ViewForm_' + this.tabId, this.viewForm);
-    
-    this.Super('initWidget', arguments);
-  },
-  
-  buildStructure: function(){
-    var isRootView = !this.parentProperty;
-    // if (isRootView) {
-    // this.setOverflow('hidden');
-    // } else {
-    // this.setOverflow('auto');
-    // }
-    this.createMainParts();
-    this.createViewStructure();
-    this.dataSource = OB.Datasource.get(this.dataSourceId, this);
-    
-    if (isRootView) {
-      if (this.childTabSet) {
-        this.members[0].setHeight('50%');
-        this.members[1].setHeight('50%');
-        this.childTabSet.setState(isc.OBStandardView.STATE_IN_MID);
-        this.childTabSet.selectTab(this.childTabSet.tabs[0]);
-        
-        OB.TestRegistry.register('org.openbravo.client.application.ChildTabSet_' + this.tabId, this.viewForm);
-      } else {
-        this.members[0].setHeight('100%');
-      }
-    }
-  },
-  
-  setDataSource: function(ds){
-  //Wrap DataSource with OBDataSource which overrides methods to set tab info7
-    var obDsClassname = 'OBDataSource'+this.tabId;
-    isc.defineClass(obDsClassname, ds.getClass());
-    
-    var modifiedDs = isc.addProperties({},ds,{
-        updateData: function(updatedRecord, callback, requestProperties){
-        var newRequestProperties = OB.Utilities._getTabInfoRequestProperties(this.view, requestProperties);
-        //standard update is not sent with operationType
-        var additionalPara = {
-          _operationType: 'update'
-        };
-        isc.addProperties(requestProperties.params, additionalPara);
-        this.Super('updateData', [updatedRecord, callback, newRequestProperties]);
-      },
-      
-      addData : function(updatedRecord, callback, requestProperties){
-        var newRequestProperties = OB.Utilities._getTabInfoRequestProperties(this.view, requestProperties);
-        //standard update is not sent with operationType
-        var additionalPara = {
-          _operationType: 'add'
-        };
-        isc.addProperties(requestProperties.params, additionalPara);
-        this.Super('addData', [updatedRecord, callback, newRequestProperties]);
-      },
-      
-      removeData: function(updatedRecord, callback, requestProperties){
-        var newRequestProperties = OB.Utilities._getTabInfoRequestProperties(this.view, requestProperties);
-        //standard update is not sent with operationType
-        var additionalPara = {
-          _operationType: 'remove'
-        };
-        isc.addProperties(requestProperties.params, additionalPara);
-        this.Super('removeData', [updatedRecord, callback, newRequestProperties]);
-      },
-
-      transformResponse: function (dsResponse, dsRequest, jsonData) {
-        if (!jsonData.response || jsonData.response.status === 'undefined' || jsonData.response.status !== 0){ //0 is success
-          if (jsonData.response && jsonData.response.error) {
-            var error = jsonData.response.error;
-            if (error.type && error.type === 'user') {
-              OB.KernelUtilities.handleUserException(error.message, error.params);
-            }
-            else {
-              OB.KernelUtilities.handleSystemException(error.message);
-            }
-          } else {
-            OB.KernelUtilities.handleSystemException('Error occured');
-          }
-        }
-        return this.Super('transformResponse', arguments);  
-      },
-      
-      view: this
-    });
-    
-    var myDs = isc[obDsClassname].create(modifiedDs);
-  
-    this.dataSource = myDs;
-    
-    if (this.viewGrid) {
-      if (this.targetRecordId) {
-        this.viewGrid.targetRecordId = this.targetRecordId;
-      }
-      this.viewGrid.setDataSource(this.dataSource, this.viewGrid.completeFields || this.viewGrid.fields);
-      if (!this.parentProperty) {
-        this.viewGrid.fetchData();
-        this.refreshContents = false;
-      }
-    }
-    if (this.viewForm) {
-      this.viewForm.setDataSource(this.dataSource, this.viewForm.fields);
-    }
-  },
-  
-  draw: function(){
-    var result = this.Super('draw', arguments);
-    if (!this.viewGrid || !this.viewGrid.filterEditor) {
-      return result;
-    }
-    this.viewGrid.focusInFilterEditor();
-    return result;
-  },
-  
-  // ** {{{ createViewStructure }}} **
-  // Is to be overridden, is called in initWidget.
-  createViewStructure: function(){
-  },
-  
-  // ** {{{ createMainParts }}} **
-  // Creates the main layout components of this view.
-  createMainParts: function(){
-    var isRootView = !this.parentProperty;
-    var me = this;
-    if (this.tabId && this.tabId.length > 0) {
-      this.formGridLayout = isc.HLayout.create({
-        width: '100%',
-        height: '*',
-        overflow: 'auto',
-        view: this,
-        focusChanged: function(hasFocus){
-//          console.log("Tab " + this.view.tabTitle + ' --> ' + hasFocus + ' ' + this.view.containsFocus());
-        }
-      });
-      
-      if (this.viewGrid) {
-        this.viewGrid.setWidth('100%');
-        this.viewGrid.view = this;
-        this.formGridLayout.addMember(this.viewGrid);
-      }
-      
-      if (this.viewForm) {
-        this.viewForm.setWidth('100%');
-        this.formGridLayout.addMember(this.viewForm);
-        this.viewForm.view = this;
-      }
-      
-      this.statusBar = this.createStatusBar();
-      
-      this.statusBarFormLayout = isc.VLayout.create({
-        width: '100%',
-        height: '*',
-        visibility: 'hidden',
-        leaveScrollbarGap: true,
-        overflow: 'auto'
-      });
-      this.statusBarFormLayout.addMember(this.statusBar);
-      this.statusBarFormLayout.addMember(this.viewForm);
-      
-      this.formGridLayout.addMember(this.statusBarFormLayout);
-      this.addMember(this.formGridLayout);
-    }
-    if (this.hasChildTabs) {
-      this.childTabSet = isc.OBStandardViewTabSet.create({
-        parentContainer: this,
-        parentTabSet: this.parentTabSet
-      });
-      this.addMember(this.childTabSet);
-    }
-  },
-  
-  // ** {{{ addChildView }}} **
-  // The addChildView creates the child tab and sets the pointer back to
-  // this
-  // parent.
-  addChildView: function(childView){
-    childView.standardWindow = this.standardWindow;
-    
-    childView.parentView = this;
-    childView.parentTabSet = this.childTabSet;
-    
-    // build the structure of the children
-    childView.buildStructure();
-    
-    var childTabDef = {
-      title: childView.tabTitle,
-      pane: childView
-    };
-    
-    this.childTabSet.addTab(childTabDef);
-    
-    childView.tab = this.childTabSet.tabs[this.childTabSet.tabs.length - 1];
-    
-    OB.TestRegistry.register('org.openbravo.client.application.ChildTab_' + this.tabId + "_" + childView.tabId, childView.tab);
-    
-  },
-  
-  doRefreshContents: function(){
-    // refresh when shown
-    if (this.parentTabSet && this.parentTabSet.state === isc.OBStandardView.STATE_MIN) {
-      return;
-    }
-    if (!this.refreshContents) {
-      return;
-    }
-    var me = this;
-    this.viewForm.clearErrors();
-    this.viewForm.clearValues();
-    // open default edit view if there is no parent view or if there is at least
-    // one parent record selected
-    if (this.shouldOpenDefaultEditMode()) {
-      this.openDefaultEditView();
-    } else if (!this.viewGrid.isVisible()) {
-      this.switchFormGridVisibility();
-    }
-    this.viewGrid.refreshContents();
-    this.refreshContents = false;
-  },
-  
-  shouldOpenDefaultEditMode: function(){
-    // can open default edit mode if defaultEditMode is set
-    // and this is the root view or a child view with a selected parent.
-    return this.defaultEditMode && (!this.parentProperty || this.parentView.viewGrid.getSelectedRecords().length === 1);
-  },
-  
-  openDefaultEditView: function(record){
-    if (!this.shouldOpenDefaultEditMode()) {
-      return;
-    }
-    
-    // open form in insert mode
-    if (record) {
-      this.editRecord(record);
-    } else if (!this.viewGrid.data || this.viewGrid.data.getLength() === 0) {
-      // open in insert mode
-      this.viewGrid.hide();
-      this.statusBarFormLayout.show();
-      this.statusBarFormLayout.setHeight('100%');
-    } else {
-      // edit the first record
-      this.editRecord(this.viewGrid.getRecord(0));
-    }
-  },
-  
-  // ** {{{ switchFormGridVisibility }}} **
-  // Switch from form to grid view or the other way around
-  switchFormGridVisibility: function(){
-    if (this.viewGrid.isVisible()) {
-      this.viewGrid.hide();
-      this.statusBarFormLayout.show();
-      this.statusBarFormLayout.setHeight('100%');
-    } else {
-      this.statusBarFormLayout.hide();
-      this.viewGrid.show();
-      this.viewGrid.setHeight('100%');
-    }
-    this.updateTabTitle();
-  },
-  
-  doHandleClick: function(){
-    if (!this.childTabSet) {
-      return;
-    }
-    if (this.state !== isc.OBStandardView.STATE_BOTTOM_MAX) {
-      this.setHalfSplit();
-      this.previousState = isc.OBStandardView.STATE_TOP_MAX;
-      this.state = isc.OBStandardView.STATE_MID;
-    }
-  },
-  
-  doHandleDoubleClick: function(){
-    var tempState;
-    if (!this.childTabSet) {
-      return;
-    }
-    tempState = this.state;
-    this.state = this.previousState;
-    if (this.previousState === isc.OBStandardView.STATE_BOTTOM_MAX) {
-      this.setBottomMaximum();
-    } else if (this.previousState === isc.OBStandardView.STATE_MID) {
-      this.setHalfSplit();
-    } else if (this.previousState === isc.OBStandardView.STATE_TOP_MAX) {
-      this.setTopMaximum();
-    } else {
-      isc.warn(this.previousState + ' not supported ');
-    }
-    this.previousState = tempState;
-  },
-  
-  // ** {{{ editRecord }}} **
-  // Opens the edit form and selects the record in the grid, will refresh
-  // child views also
-  editRecord: function(record){
-  
-    // this.recordSelected(record);
-    this.viewForm.editRecord(record);
-    this.viewForm.clearErrors();
-    if (this.viewGrid.isVisible()) {
-      this.switchFormGridVisibility();
-    }
-    this.viewGrid.doSelectSingleRecord(record);
-  },
-  
-  // check if a child tab should be opened directly
-  openDirectChildTab: function(){
-    if (this.childTabSet) {
-      var i, tabs = this.childTabSet.tabs;
-      for (i = 0; i < tabs.length; i++) {
-        if (tabs[i].pane.openDirectTab()) {
-          return;
-        }
-      }
-    }
-    
-    // no child tabs to open anymore, show ourselves as the default view
-    // open this view
-    if (this.parentTabSet) {
-      this.parentTabSet.setState(isc.OBStandardView.STATE_MID);
-    } else {
-      this.doHandleClick();
-    }
-    var gridRecord = this.viewGrid.getSelectedRecord();
-    this.editRecord(gridRecord);
-    
-    // remove this info
-    delete this.standardWindow.directTabInfo;
-  },
-  
-  openDirectTab: function(){
-    if (!this.dataSource) {
-      // wait for the datasource to arrive
-      this.delayCall('openDirectTab', null, 200, this);
-      return;
-    }
-    var i, thisView = this, tabInfos = this.standardWindow.directTabInfo;
-    if (!tabInfos) {
-      return;
-    }
-    for (i = 0; i < tabInfos.length; i++) {
-      if (tabInfos[i].targetTabId === this.tabId) {
-        // found it...
-        this.viewGrid.targetRecordId = tabInfos[i].targetRecordId;
-        
-        if (this.parentTabSet && this.parentTabSet.getSelectedTab() !== this.tab) {
-          this.parentTabSet.selectTab(this.tab);
-        } else {
-          // make sure that the content gets refreshed
-          this.refreshContents = true;
-          // refresh and open a child view when all is done
-          this.doRefreshContents();
-        }
-        return true;
-      }
-    }
-    return false;
-  },
-  
-  // ** {{{ recordSelected }}} **
-  // Is called when a record get's selected. Will refresh direct child views
-  // which will again refresh their children.
-  recordSelected: function(){
-    this.fireOnPause("recordSelected", {
-      target: this,
-      methodName: "doRecordSelected",
-      args: []
-    }, this.fetchDelay);
-  },
-  
-  doRecordSelected: function(){
-    // no change go away
-    if (this.viewGrid.getSelectedRecords().length === 1 && this.viewGrid.getSelectedRecord() === this.lastRecordSelected) {
-      return;
-    }
-    
-    var tabViewPane = null;
-    
-    // refresh the tabs
-    if (this.childTabSet) {
-      for (var i = 0; i < this.childTabSet.tabs.length; i++) {
-        tabViewPane = this.childTabSet.tabs[i].pane;
-        tabViewPane.parentRecordSelected();
-      }
-    }
-    // and recompute the count:
-    this.updateChildCount();
-    this.updateTabTitle();
-    this.lastRecordSelected = this.viewGrid.getSelectedRecord();
-  },
-  
-  // ** {{{ parentRecordSelected }}} **
-  // Is called when a selection change occurs in the parent.
-  parentRecordSelected: function(){
-  
-    // clear all our selections..
-    this.viewGrid.deselectAllRecords();
-    
-    // switch back to the grid or form
-    if (this.shouldOpenDefaultEditMode()) {
-      if (this.viewGrid.isVisible()) {
-        this.switchFormGridVisibility();
-      }
-    } else if (!this.viewGrid.isVisible()) {
-      this.switchFormGridVisibility();
-    }
-    
-    // clear the count from the tabtitle, will be recomputed
-    this.updateTabTitle();
-    
-    // if not visible or the parent also needs to be refreshed
-    if (!this.isViewVisible() ||
-    (this.parentView && this.parentView.refreshContents)) {
-      isc.Log.logDebug('ParentRecordSelected: View not visible ' + this.tabTitle, 'OB');
-      // refresh when the view get's shown
-      this.refreshContents = true;
-    } else {
-      isc.Log.logDebug('ParentRecordSelected: View visible ' + this.tabTitle, 'OB');
-      var me = this;
-      if (this.viewGrid) {
-        this.viewGrid.refreshContents();
-      }
-      if (this.viewForm) {
-        this.viewForm.clearValues();
-        this.viewForm.clearErrors();
-      }
-    }
-    // enable the following code if we don't automatically select the first
-    // record
-    if (this.childTabSet) {
-      for (var i = 0; i < this.childTabSet.tabs.length; i++) {
-        tabViewPane = this.childTabSet.tabs[i].pane;
-        tabViewPane.parentRecordSelected();
-      }
-    }
-  },
-  
-  updateChildCount: function(){
-    if (!this.childTabSet) {
-      return;
-    }
-    if (this.viewGrid.getSelectedRecords().length !== 1) {
-      return;
-    }
-    
-    var infoByTab = [], tabInfo, childView, data = {}, me = this, callback;
-    
-    data.parentId = this.viewGrid.getSelectedRecords()[0][OB.Constants.ID];
-    
-    for (var i = 0; i < this.childTabSet.tabs.length; i++) {
-      tabInfo = {};
-      childView = this.childTabSet.tabs[i].pane;
-      tabInfo.parentProperty = childView.parentProperty;
-      tabInfo.tabId = childView.tabId;
-      tabInfo.entity = childView.entity;
-      if (childView.viewGrid.whereClause) {
-        tabInfo.whereClause = childView.viewGrid.whereClause;
-      }
-      infoByTab.push(tabInfo);
-    }
-    data.tabs = infoByTab;
-    
-    // walks through the tabs and sets the title
-    callback = function(resp, data, req){
-      var tab, tabPane;
-      var tabInfos = data.result;
-      if (!tabInfos || tabInfos.length !== me.childTabSet.tabs.length) {
-        // error, something has changed
-        return;
-      }
-      for (var i = 0; i < me.childTabSet.tabs.length; i++) {
-        childView = me.childTabSet.tabs[i].pane;
-        tab = me.childTabSet.getTab(i);
-        if (childView.tabId === tabInfos[i].tabId) {
-          tabPane = me.childTabSet.getTabPane(tab);
-          tabPane.recordCount = tabInfos[i].count;
-          tabPane.updateTabTitle();
-        }
-      }
-    };
-    
-    OB.RemoteCallManager.call('org.openbravo.client.application.ChildTabRecordCounterActionHandler', data, {}, callback, null);
-  },
-  
-  updateTabTitle: function(){
-  
-    // store the original tab title
-    if (!this.originalTabTitle) {
-      this.originalTabTitle = this.tabTitle;
-    }
-    
-    var identifier, tab;
-    // showing the form
-    if (!this.viewGrid.isVisible() && this.viewGrid.getSelectedRecord() && this.viewGrid.getSelectedRecord()[OB.Constants.IDENTIFIER]) {
-      identifier = this.viewGrid.getSelectedRecord()[OB.Constants.IDENTIFIER];
-      if (!this.parentTabSet && this.viewTabId) {
-        tab = OB.MainView.TabSet.getTab(this.viewTabId);
-        OB.MainView.TabSet.setTabTitle(tab, this.originalTabTitle + ' - ' + identifier);
-      } else if (this.parentTabSet && this.tab) {
-        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle + ' - ' + identifier);
-      }
-    } else if (!this.parentTabSet && this.viewTabId) {
-      // the root view
-      tab = OB.MainView.TabSet.getTab(this.viewTabId);
-      OB.MainView.TabSet.setTabTitle(tab, this.originalTabTitle);
-    } else if (this.parentTabSet && this.tab) {
-      // the check on this.tab is required for the initialization phase
-      // only show a count if there is one parent
-      if (this.parentView.viewGrid.getSelectedRecords().length !== 1) {
-        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle);
-      } else if (this.recordCount) {
-        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle + ' (' + this.recordCount + ')');
-      } else {
-        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle);
-      }
-    }
-  },
-  
-  isViewVisible: function(){
-    return this.parentTabSet.getSelectedTabNumber() ===
-    this.parentTabSet.getTabNumber(this.tab);
-  },
-  
-  /* ++++++++++++++++++++ Status Bar ++++++++++++++++++++++++++ */
-  
-  statusBarCloseIconButtonProperties: {
-    view: null,
-    imageType: 'center',
-    showRollOver: false,
-    src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/ico-x.png',
-    action: function(){
-      this.view.switchFormGridVisibility();
-    }
-  },
-  
-  statusBarPrevIconButtonProperties: {
-    view: null,
-    imageType: 'center',
-    showRollOver: false,
-    src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/sn-previous.gif',
-    action: function(){
-      var rowNum = this.view.viewGrid.data.indexOf(this.view.viewGrid.getSelectedRecord());
-      var newRowNum = rowNum - 1;
-      if (newRowNum > -1) {
-        var newRecord = this.view.viewGrid.getRecord(newRowNum);
-        this.view.viewGrid.scrollRecordToTop(newRowNum);
-        this.view.editRecord(newRecord);
-        this.view.updateTabTitle();
-      }
-    }
-  },
-  
-  statusBarNextIconButtonProperties: {
-    view: null,
-    imageType: 'center',
-    showRollOver: false,
-    src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/sn-next.gif',
-    action: function(){
-      var rowNum = this.view.viewGrid.data.indexOf(this.view.viewGrid.getSelectedRecord());
-      var newRowNum = rowNum + 1;
-      // if there is data move to it
-      if (this.view.viewGrid.data.get(newRowNum)) {
-        var newRecord = this.view.viewGrid.getRecord(newRowNum);
-        this.view.viewGrid.scrollRecordToTop(newRowNum);
-        this.view.editRecord(newRecord);
-        this.view.updateTabTitle();
-      }
-    }
-  },
-  
-  createStatusBar: function(){
-    var statusBar = isc.HLayout.create({
-      width: '100%',
-      height: '30',
-      overflow: 'auto'
-    });
-    var messageBar = isc.HLayout.create({
-      width: '*',
-      align: 'left',
-      overflow: 'visible'
-    });
-    messageBar.addMember(isc.Label.create({
-      contents: 'message'
-    }));
-    
-    var prevButton = isc.ImgButton.create(this.statusBarPrevIconButtonProperties);
-    var nextButton = isc.ImgButton.create(this.statusBarNextIconButtonProperties);
-    var closeButton = isc.ImgButton.create(this.statusBarCloseIconButtonProperties);
-    var buttonBar = isc.HLayout.create({
-      width: '100',
-      align: 'right',
-      overflow: 'visible'
-    });
-    
-    prevButton.view = this;
-    nextButton.view = this;
-    closeButton.view = this;
-    
-    buttonBar.addMembers([prevButton, nextButton, closeButton]);
-    statusBar.addMembers([messageBar, buttonBar]);
-    return statusBar;
-  },
-  
-  /*
-   * ++++++++++++++++++++ Parent-Child Tab Handling
-   * ++++++++++++++++++++++++++
-   */
-  convertToPercentageHeights: function(){
-    if (!this.members[1]) {
-      return;
-    }
-    var height = this.members[1].getHeight();
-    var percentage = ((height / this.getHeight()) * 100);
-    // this.members[0].setHeight((100 - percentage) + '%');
-    this.members[0].setHeight('*');
-    this.members[1].setHeight(percentage + '%');
-  },
-  
-  setTopMaximum: function(){
-    this.setHeight('100%');
-    if (this.members[1]) {
-      this.members[0].setHeight('*');
-      this.members[1].setState(isc.OBStandardView.STATE_MIN);
-      this.members[1].show();
-      this.members[0].show();
-      this.convertToPercentageHeights();
-    } else {
-      this.members[0].setHeight('100%');
-      this.members[0].show();
-    }
-  },
-  
-  setBottomMaximum: function(){
-    this.setHeight('100%');
-    if (this.members[1]) {
-      this.members[0].hide();
-      this.members[0].setHeight(0);
-      this.members[1].setHeight('100%');
-      this.members[1].show();
-    } else {
-      this.members[0].setHeight('100%');
-      this.members[0].show();
-    }
-  },
-  
-  setHalfSplit: function(){
-    this.setHeight('100%');
-    var i, tab, pane;
-    if (this.members[1]) {
-      // divide the space between the first and second level
-      if (this.members[1].draggedHeight) {
-        this.members[0].setHeight('*');
-        this.members[1].setHeight(this.members[1].draggedHeight);
-        this.members[0].show();
-        this.members[1].show();
-        this.convertToPercentageHeights();
-        this.members[1].setState(isc.OBStandardView.STATE_IN_MID);
-      } else {
-        // NOTE: noticed that when resizing multiple members in a layout, that it 
-        // makes a difference what the order of resizing is, first resize the 
-        // one which will be larger, then the one which will be smaller.
-        // also do the STATE_IN_MID before resizing
-        this.members[1].setHeight('50%');
-        this.members[0].setHeight('50%');
-        this.members[1].show();
-        this.members[0].show();
-        this.members[1].setState(isc.OBStandardView.STATE_IN_MID);
-      }
-    } else {
-      this.members[0].setHeight('100%');
-      this.members[0].show();
-    }
-  },
-  
-  getContextInfo: function(allProperties, sessionProperties){
-    // different modes:
-    // 1) showing grid with one record selected
-    // 2) showing form with aux inputs
-    var record;
-    if (this.viewGrid.isVisible()) {
-      record = this.viewGrid.getSelectedRecord();
-    } else {
-      record = this.viewForm.getValues();   
-    }
-    
-    var properties = this.propertyToColumns;
-
-    for (var i=0; i<properties.length; i++){
-      var value = record[properties[i].property];
-      if (typeof value !== 'undefined') {
-        allProperties[properties[i].column] = value;
-        if (properties[i].sessionProperty) {
-          sessionProperties[properties[i].column] = value;
-        }
-      }
-    }
-    
-    if (this.viewForm.isVisible()) {
-      isc.addProperties(allProperties, this.viewForm.auxInputs);
-      isc.addProperties(sessionProperties, this.viewForm.auxInputs);
-    }
-    
-    if (this.parentView) {
-      this.parentView.getContextInfo(allProperties, sessionProperties);
-    }
-  },
-
-  setContextInfo: function (sessionProperties, callbackFunction) {
-    var allProperties = {};
-    if (!sessionProperties) {
-      sessionProperties = {};
-      this.getContextInfo(allProperties, sessionProperties);
-    }
-    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', 
-    sessionProperties, {
-      MODE: 'SETSESSION',
-      TAB_ID: this.view.tabId
-    }, callbackFunction);
-  }  
-});
-
-// = OBStandardViewTabSet =
-// The OBStandardViewTabSet is the tabset used within the standard view to
-// display child tabs
-isc.ClassFactory.defineClass('OBStandardViewTabSet', isc.OBTabSetChild);
-
-isc.OBStandardViewTabSet.addClassProperties({
-
-  TABBARPROPERTIES: {
-    dblClickWaiting: false,
-    
-    canDrag: false,
-    dragAppearance: 'none',
-    dragStartDistance: 1,
-    overflow: 'hidden',
-    
-    itemClick: function(item, itemNum){
-      var me = this;
-      me.dblClickWaiting = true;
-      isc.Timer.setTimeout(function(){
-        // if no double click happened then do the single click
-        if (me.dblClickWaiting) {
-          me.dblClickWaiting = false;
-          me.tabSet.doHandleClick();
-        }
-      }, OB.Constants.DBL_CLICK_DELAY);
-      
-    },
-    
-    itemDoubleClick: function(item, itemNum){
-      this.dblClickWaiting = false;
-      this.tabSet.doHandleDoubleClick();
-    },
-    
-    dragStop: function(){
-      // change the height to percentage based to handle resizing of browser:
-      this.tabSet.parentContainer.convertToPercentageHeights();
-      return true;
-    },
-    
-    dragStart: function(){
-      // -2 to prevent scrollbar
-      this.tabSet.maxHeight = this.tabSet.parentContainer.getHeight() - 2;
-      this.tabSet.minHeight = (this.getHeight() * 2) + 15;
-      return true;
-    },
-    
-    dragMove: function(){
-      var offset = (0 - isc.EH.dragOffsetY);
-      this.resizeTarget(this.tabSet, true, true, offset, -1 * this.getHeight(), null, true);
-      this.tabSet.draggedHeight = this.tabSet.getHeight();
-      // if (this.tabSet.getHeight() === this.getHeight()) {
-      // // set the parent to top-max
-      // this.tabSet.parentTabSet.setState(isc.OBStandardView.STATE_TOP_MAX);
-      // this.tabSet.draggedHeight = null;
-      // }
-      return true;
-    }
-  }
-});
-
-isc.OBStandardViewTabSet.addProperties({
-  tabBarProperties: isc.addProperties({}, isc.OBStandardViewTabSet.TABBARPROPERTIES),
-  tabBarPosition: 'top',
-  width: '100%',
-  height: '*',
-  overflow: 'hidden',
-  
-  // get rid of the margin around the content of a pane
-  paneMargin: 0,
-  paneContainerMargin: 0,
-  paneContainerPadding: 0,
-  showPaneContainerEdges: false,
-  
-  state: null,
-  previousState: null,
-  
-  // keeps track of the previous dragged height, to restore it
-  draggedHeight: null,
-  
-  setDraggable: function(draggable){
-    if (draggable) {
-      this.tabBar.canDrag = true;
-      this.tabBar.cursor = isc.Canvas.HAND;
-    } else {
-      this.tabBar.canDrag = false;
-      this.tabBar.cursor = isc.Canvas.DEFAULT;
-    }
-  },
-  
-  doHandleClick: function(){
-    if (this.state === isc.OBStandardView.STATE_MIN) {
-      // we are minimized, there must be a parent then
-      if (this.parentTabSet) {
-        this.parentTabSet.setState(isc.OBStandardView.STATE_MID);
-      } else {
-        this.parentContainer.setHalfSplit();
-      }
-    } else if (this.state === isc.OBStandardView.STATE_BOTTOM_MAX) {
-      this.setState(isc.OBStandardView.STATE_MID);
-    }
-  },
-  
-  doHandleDoubleClick: function(){
-    if (this.state === isc.OBStandardView.STATE_TOP_MAX) {
-      // we are maximized go back to the previous state
-      if (this.previousState && this.previousState !== this.state) {
-        if (this.previousState === isc.OBStandardView.STATE_IN_MID) {
-          this.parentContainer.setHalfSplit();
-        } else if (this.previousState === isc.OBStandardView.STATE_MIN) {
-          if (this.parentTabSet) {
-            this.parentTabSet.setState(isc.OBStandardView.STATE_TOP_MAX);
-          } else {
-            this.parentContainer.setTopMaximum();
-          }
-        } else {
-          this.setState(this.previousState);
-        }
-      } else {
-        this.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
-      }
-    } else {
-      // first set to IN_MID, to prevent empty tab displays
-      this.setState(isc.OBStandardView.STATE_IN_MID);
-      this.setState(isc.OBStandardView.STATE_TOP_MAX);
-    }
-  },
-  
-  getState: function(){
-    return this.state;
-  },
-  
-  setState: function(newState){
-  
-    // disabled this as sometimes states have
-    // to be reset to recompute heights changed automatically
-    // if (this.state === newState) {
-    // return;
-    // }
-    
-    var tab, i, pane;
-    var tmpPreviousState = this.state;
-    
-    // is corrected below for one state
-    this.setDraggable(false);
-    
-    if (newState === isc.OBStandardView.STATE_TOP_MAX) {
-      this.state = newState;
-      
-      // minimize the ancestors
-      if (this.parentTabSet) {
-        this.parentTabSet.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
-      } else if (this.parentContainer) {
-        this.parentContainer.setBottomMaximum();
-      }
-      
-      // note this for loop must be done before the parent's are
-      // done otherwise the content is not drawn
-      // the top member in each tab is maximized
-      // the bottom member in each tab is set to the tabbar height
-      for (i = 0; i < this.tabs.length; i++) {
-        tab = this.tabs[i];
-        this.makeTabVisible(tab);
-        pane = this.getTabPane(tab);
-        pane.setTopMaximum();
-      }
-      
-    } else if (newState === isc.OBStandardView.STATE_MIN) {
-      // the height is set to the height of the tabbar
-      this.setHeight(this.tabBar.getHeight());
-      for (i = 0; i < this.tabs.length; i++) {
-        tab = this.tabs[i];
-        this.getTabPane(tab).hide();
-      }
-      this.state = newState;
-    } else if (newState === isc.OBStandardView.STATE_BOTTOM_MAX) {
-      // the top part in each layout is set to 0%, and the bottom to max
-      this.state = newState;
-      if (this.parentTabSet) {
-        this.parentTabSet.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
-      } else if (this.parentContainer) {
-        this.parentContainer.setBottomMaximum();
-      }
-      for (i = 0; i < this.tabs.length; i++) {
-        tab = this.tabs[i];
-        this.makeTabVisible(tab);
-        pane = this.getTabPane(tab);
-        pane.setBottomMaximum();
-      }
-    } else if (newState === isc.OBStandardView.STATE_IN_MID) {
-      this.state = newState;
-      this.setDraggable(true);
-      // minimize the third level
-      for (i = 0; i < this.tabs.length; i++) {
-        tab = this.tabs[i];
-        pane = this.getTabPane(tab);
-        this.makeTabVisible(tab);
-        pane.members[0].setHeight('*');
-        if (pane.members[1]) {
-          pane.members[1].setState(isc.OBStandardView.STATE_MIN);
-        }
-      }
-    } else if (newState === isc.OBStandardView.STATE_MID) {
-      if (this.parentTabSet) {
-        this.parentTabSet.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
-      } else if (this.parentContainer) {
-        this.parentContainer.setBottomMaximum();
-      }
-      // the content of the tabs is split in 2
-      this.state = newState;
-      for (i = 0; i < this.tabs.length; i++) {
-        tab = this.tabs[i];
-        pane = this.getTabPane(tab);
-        pane.setHalfSplit();
-        this.makeTabVisible(tab);
-      }
-    }
-    
-    this.previousState = tmpPreviousState;
-  },
-  
-  makeTabVisible: function(tab){
-    if (tab === this.getSelectedTab()) {
-      pane = this.getTabPane(tab);
-      pane.show();
-      if (pane.doRefreshContents) {
-        pane.doRefreshContents();
-      }
-      if (pane.members[0]) {
-        pane.members[0].show();
-      }
-      if (pane.members[1]) {
-        pane.members[1].show();
-      }
-      this.selectTab(tab);
-    }
-  },
-  
-  tabSelected: function(tabNum, tabPane, ID, tab){
-    if (tabPane.refreshContents) {
-      tabPane.doRefreshContents();
-    }
-  },
-  
-  initWidget: function(){
-    this.tabBarProperties.tabSet = this;
-    this.Super('initWidget', arguments);
-  }
-});
-
-// TODO: move this to a central location
-isc.Canvas.addProperties({
-  // let focuschanged go up to the parent
-  focusChanged: function(hasFocus){
-    if (this.parentElement && this.parentElement.focusChanged) {
-      this.parentElement.focusChanged(hasFocus);
-    }
-  }
-});
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distribfuted  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2010 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+isc.ClassFactory.defineClass('OBStandardWindow', isc.VLayout);
+
+// The OBStandardWindow contains the toolbar and the root view.
+isc.OBStandardWindow.addProperties({
+  toolBar: null,
+  view: null,
+  messageBar: null,
+  
+  viewProperties: null,
+  
+  initWidget: function(){
+    var standardWindow = this;
+    this.toolBar = isc.OBToolbar.create({
+      height: this.toolBarHeight,
+      minHeight: this.toolBarHeight,
+      maxHeight: this.toolBarHeight,
+      leftMembers: [isc.OBToolbarIconButton.create({
+        action: 'alert(\'New Document\')',
+        buttonType: 'newDoc',
+        prompt: 'New Document'
+      }), isc.OBToolbarIconButton.create({
+        action: 'alert(\'New Row\')',
+        buttonType: 'newRow',
+        prompt: 'New Row'
+      })],
+      rightMembers: [isc.OBToolbarTextButton.create({
+        action: 'OB.Utilities.openActionButton(this, {viewId: "OBPopupClassicWindow", obManualURL: "TablesandColumns/Table_Edition.html", processId: "173", id: "173", command: "BUTTONImportTable173", tabTitle: "Testing"});',
+        title: 'Button A'
+      })]
+    });
+    
+    this.toolBar.addLeftMembers([isc.OBToolbarIconButton.create({
+      action: 'alert(\'Save\')',
+      buttonType: 'save',
+      prompt: 'Save'
+    }), isc.OBToolbarIconButton.create({
+      action: 'alert(\'Create Copy\')',
+      buttonType: 'createCopy',
+      prompt: 'Create Copy'
+    })]);
+    
+    this.toolBar.addRightMembers([isc.OBToolbarTextButton.create({
+      action: 'alert(\'Button B\')',
+      title: 'Button B'
+    })]);
+    
+    this.messageBar = isc.OBMessagebar.create({});
+    
+    this.addMember(this.messageBar);
+    this.addMember(this.toolBar);
+    
+    this.viewProperties.standardWindow = this;
+    
+    this.view = isc.OBStandardView.create(this.viewProperties);
+    this.addMember(this.view);
+    this.Super('initWidget', arguments);
+    this.view.toolBar = this.toolBar;
+    
+    // is set later after creation
+    this.view.tabTitle = this.tabTitle;
+  },
+  
+  draw: function(){
+    var standardWindow = this;
+    var ret = this.Super('draw', arguments);
+    
+    if (this.targetRecordId) {
+      OB.RemoteCallManager.call('org.openbravo.client.application.window.ComputeSelectedRecordActionHandler', null, {
+        targetEntity: this.targetEntity,
+        targetRecordId: this.targetRecordId,
+        windowId: this.windowId
+      }, function(response, data, request){
+        standardWindow.directTabInfo = data.result;
+        standardWindow.view.openDirectTab();
+      });
+      delete this.targetRecordId;
+      delete this.targetTabId;
+      delete this.targetEntity;
+    }
+    
+    return ret;
+  },
+  
+  setViewTabId: function(viewTabId){
+    this.view.viewTabId = viewTabId;
+    this.viewTabId = viewTabId;
+  },
+  
+  doHandleClick: function(){
+    this.view.doHandleClick();
+  },
+  
+  doHandleDoubleClick: function(){
+    this.view.doHandleDoubleClick();
+  },
+  
+  getBookMarkParams: function(){
+    var result = {};
+    result.windowId = this.windowId;
+    result.viewId = this.getClassName();
+    result.tabTitle = this.tabTitle;
+    return result;
+  },
+  
+  isEqualParams: function(params){
+    var equalTab = params.windowId && params.windowId === this.windowId;
+    return equalTab;
+  },
+  
+  isSameTab: function(viewName, params){
+    return this.isEqualParams(params);
+  },
+  
+  // returns the view information for the help view.
+  getHelpView: function(){
+    return null;
+  }
+  
+});
+
+// Note: currently this class covers both the top-level view as well as child views
+// in child tabs. If there is a lot of separate code then maybe the 2 types of usages
+// have to be factored out in separate classes.
+isc.ClassFactory.defineClass('OBStandardView', isc.VLayout);
+
+isc.OBStandardView.addClassProperties({
+  STATE_TOP_MAX: 'TopMax', // the part in the top is maximized, meaning
+  // that the tabset in the bottom is minimized
+  STATE_BOTTOM_MAX: 'BottomMax', // the tabset part is maximized, the
+  // the top has height 0
+  STATE_MID: 'Mid', // the view is split in the middle, the top part has
+  // 50%, the tabset also
+  STATE_IN_MID: 'InMid', // state of the tabset which is shown in the middle,
+  // the parent of the tabset has state
+  // isc.OBStandardView.STATE_MID
+  STATE_MIN: 'Min' // minimized state, the parent has
+  // isc.OBStandardView.STATE_TOP_MAX or
+  // isc.OBStandardView.STATE_IN_MID
+});
+
+// = OBStandardView =
+// The OBStandardView is the composite canvas which contains a form/grid and
+// child tabs.
+
+isc.OBStandardView.addProperties({
+
+  // properties used by the ViewManager, only relevant in case this is the
+  // top
+  // view shown directly in the main tab
+  showsItself: false,
+  tabTitle: null,
+  
+  // ** {{{ windowId }}} **
+  // The id of the window shown here, only set for the top view in the
+  // hierarchy
+  // and if this is a window/tab view.
+  windowId: null,
+  
+  // ** {{{ tabId }}} **
+  // The id of the tab shown here, set in case of a window/tab view.
+  tabId: null,
+  
+  // ** {{{ processId }}} **
+  // The id of the process shown here, set in case of a process view.
+  processId: null,
+  
+  // ** {{{ formId }}} **
+  // The id of the form shown here, set in case of a form view.
+  formId: null,
+  
+  // ** {{{ parentView }}} **
+  // The parentView if this view is a child in a parent child structure.
+  parentView: null,
+  
+  // ** {{{ parentTabSet }}} **
+  // The tabSet which shows this view. If the parentView is null then this
+  // is the
+  // top tabSet.
+  parentTabSet: null,
+  tab: null,
+  
+  // ** {{{ toolbar }}} **
+  // The toolbar canvas.
+  toolBar: null,
+  
+  // ** {{{ formGridLayout }}} **
+  // The layout which holds the form and grid.
+  formGridLayout: null,
+  
+  // ** {{{ childTabSet }}} **
+  // The tabSet holding the child tabs with the OBView instances.
+  childTabSet: null,
+  
+  // ** {{{ hasChildTabs }}} **
+  // Is set to true if there are child tabs.
+  hasChildTabs: false,
+  
+  // ** {{{ dataSource }}} **
+  // The dataSource used to fill the data in the grid/form.
+  dataSource: null,
+  
+  // ** {{{ viewForm }}} **
+  // The viewForm used to display single records
+  viewForm: null,
+  
+  // ** {{{ viewGrid }}} **
+  // The viewGrid used to display multiple records
+  viewGrid: null,
+  
+  // ** {{{ parentProperty }}} **
+  // The name of the property refering to the parent record, if any
+  parentProperty: null,
+  
+  // ** {{{ targetRecordId }}} **
+  // The id of the record to initially show.
+  targetRecordId: null,
+  
+  // ** {{{ targetEntity }}} **
+  // The entity to show.
+  entity: null,
+  
+  width: '100%',
+  height: '100%',
+  margin: 0,
+  padding: 0,
+  overflow: 'hidden',
+  
+  // set if one record has been selected
+  lastRecordSelected: null,
+  
+  // ** {{{ refreshContents }}} **
+  // Should the contents listgrid/forms be refreshed when the tab
+  // gets selected and shown to the user.
+  refreshContents: true,
+  
+  state: isc.OBStandardView.STATE_MID,
+  previousState: isc.OBStandardView.STATE_TOP_MAX,
+  
+  initWidget: function(properties){
+    var isRootView = !this.parentProperty;
+    
+    if (isRootView) {
+      this.buildStructure();
+    }
+    
+    OB.TestRegistry.register('org.openbravo.client.application.ViewGrid_' + this.tabId, this.viewGrid);
+    OB.TestRegistry.register('org.openbravo.client.application.ViewForm_' + this.tabId, this.viewForm);
+    
+    this.Super('initWidget', arguments);
+  },
+  
+  buildStructure: function(){
+    var isRootView = !this.parentProperty;
+    // if (isRootView) {
+    // this.setOverflow('hidden');
+    // } else {
+    // this.setOverflow('auto');
+    // }
+    this.createMainParts();
+    this.createViewStructure();
+    this.dataSource = OB.Datasource.get(this.dataSourceId, this);
+    
+    if (isRootView) {
+      if (this.childTabSet) {
+        this.members[0].setHeight('50%');
+        this.members[1].setHeight('50%');
+        this.childTabSet.setState(isc.OBStandardView.STATE_IN_MID);
+        this.childTabSet.selectTab(this.childTabSet.tabs[0]);
+        
+        OB.TestRegistry.register('org.openbravo.client.application.ChildTabSet_' + this.tabId, this.viewForm);
+      } else {
+        this.members[0].setHeight('100%');
+      }
+    }
+  },
+  
+  setDataSource: function(ds){
+    //Wrap DataSource with OBDataSource which overrides methods to set tab info7
+    var obDsClassname = 'OBDataSource' + this.tabId;
+    isc.defineClass(obDsClassname, ds.getClass());
+    
+    var modifiedDs = isc.addProperties({}, ds, {
+      updateData: function(updatedRecord, callback, requestProperties){
+        var newRequestProperties = OB.Utilities._getTabInfoRequestProperties(this.view, requestProperties);
+        //standard update is not sent with operationType
+        var additionalPara = {
+          _operationType: 'update'
+        };
+        isc.addProperties(requestProperties.params, additionalPara);
+        this.Super('updateData', [updatedRecord, callback, newRequestProperties]);
+      },
+      
+      addData: function(updatedRecord, callback, requestProperties){
+        var newRequestProperties = OB.Utilities._getTabInfoRequestProperties(this.view, requestProperties);
+        //standard update is not sent with operationType
+        var additionalPara = {
+          _operationType: 'add'
+        };
+        isc.addProperties(requestProperties.params, additionalPara);
+        this.Super('addData', [updatedRecord, callback, newRequestProperties]);
+      },
+      
+      removeData: function(updatedRecord, callback, requestProperties){
+        var newRequestProperties = OB.Utilities._getTabInfoRequestProperties(this.view, requestProperties);
+        //standard update is not sent with operationType
+        var additionalPara = {
+          _operationType: 'remove'
+        };
+        isc.addProperties(requestProperties.params, additionalPara);
+        this.Super('removeData', [updatedRecord, callback, newRequestProperties]);
+      },
+      
+      transformResponse: function(dsResponse, dsRequest, jsonData){
+        if (!jsonData.response || jsonData.response.status === 'undefined' || jsonData.response.status !== 0) { //0 is success
+          if (jsonData.response && jsonData.response.error) {
+            var error = jsonData.response.error;
+            if (error.type && error.type === 'user') {
+              OB.KernelUtilities.handleUserException(error.message, error.params);
+            } else {
+              OB.KernelUtilities.handleSystemException(error.message);
+            }
+          } else {
+            OB.KernelUtilities.handleSystemException('Error occured');
+          }
+        }
+        return this.Super('transformResponse', arguments);
+      },
+      
+      view: this
+    });
+    
+    var myDs = isc[obDsClassname].create(modifiedDs);
+    
+    this.dataSource = myDs;
+    
+    if (this.viewGrid) {
+      if (this.targetRecordId) {
+        this.viewGrid.targetRecordId = this.targetRecordId;
+      }
+      this.viewGrid.setDataSource(this.dataSource, this.viewGrid.completeFields || this.viewGrid.fields);
+      if (!this.parentProperty) {
+        this.viewGrid.fetchData();
+        this.refreshContents = false;
+      }
+    }
+    if (this.viewForm) {
+      this.viewForm.setDataSource(this.dataSource, this.viewForm.fields);
+    }
+  },
+  
+  draw: function(){
+    var result = this.Super('draw', arguments);
+    if (!this.viewGrid || !this.viewGrid.filterEditor) {
+      return result;
+    }
+    this.viewGrid.focusInFilterEditor();
+    return result;
+  },
+  
+  // ** {{{ createViewStructure }}} **
+  // Is to be overridden, is called in initWidget.
+  createViewStructure: function(){
+  },
+  
+  // ** {{{ createMainParts }}} **
+  // Creates the main layout components of this view.
+  createMainParts: function(){
+    var isRootView = !this.parentProperty;
+    var me = this;
+    if (this.tabId && this.tabId.length > 0) {
+      this.formGridLayout = isc.HLayout.create({
+        width: '100%',
+        height: '*',
+        overflow: 'auto',
+        view: this,
+        focusChanged: function(hasFocus){
+          //          console.log("Tab " + this.view.tabTitle + ' --> ' + hasFocus + ' ' + this.view.containsFocus());
+        }
+      });
+      
+      if (this.viewGrid) {
+        this.viewGrid.setWidth('100%');
+        this.viewGrid.view = this;
+        this.formGridLayout.addMember(this.viewGrid);
+      }
+      
+      if (this.viewForm) {
+        this.viewForm.setWidth('100%');
+        this.formGridLayout.addMember(this.viewForm);
+        this.viewForm.view = this;
+      }
+      
+      this.statusBar = this.createStatusBar();
+      
+      this.statusBarFormLayout = isc.VLayout.create({
+        width: '100%',
+        height: '*',
+        visibility: 'hidden',
+        leaveScrollbarGap: true,
+        overflow: 'auto'
+      });
+      this.statusBarFormLayout.addMember(this.statusBar);
+      this.statusBarFormLayout.addMember(this.viewForm);
+      
+      this.formGridLayout.addMember(this.statusBarFormLayout);
+      this.addMember(this.formGridLayout);
+    }
+    if (this.hasChildTabs) {
+      this.childTabSet = isc.OBStandardViewTabSet.create({
+        parentContainer: this,
+        parentTabSet: this.parentTabSet
+      });
+      this.addMember(this.childTabSet);
+    }
+  },
+  
+  // ** {{{ addChildView }}} **
+  // The addChildView creates the child tab and sets the pointer back to
+  // this
+  // parent.
+  addChildView: function(childView){
+    childView.standardWindow = this.standardWindow;
+    
+    childView.parentView = this;
+    childView.parentTabSet = this.childTabSet;
+    
+    // build the structure of the children
+    childView.buildStructure();
+    
+    var childTabDef = {
+      title: childView.tabTitle,
+      pane: childView
+    };
+    
+    this.childTabSet.addTab(childTabDef);
+    
+    childView.tab = this.childTabSet.tabs[this.childTabSet.tabs.length - 1];
+    
+    OB.TestRegistry.register('org.openbravo.client.application.ChildTab_' + this.tabId + "_" + childView.tabId, childView.tab);
+    
+  },
+  
+  doRefreshContents: function(){
+    // refresh when shown
+    if (this.parentTabSet && this.parentTabSet.state === isc.OBStandardView.STATE_MIN) {
+      return;
+    }
+    if (!this.refreshContents) {
+      return;
+    }
+    var me = this;
+    this.viewForm.clearErrors();
+    this.viewForm.clearValues();
+    // open default edit view if there is no parent view or if there is at least
+    // one parent record selected
+    if (this.shouldOpenDefaultEditMode()) {
+      this.openDefaultEditView();
+    } else if (!this.viewGrid.isVisible()) {
+      this.switchFormGridVisibility();
+    }
+    this.viewGrid.refreshContents();
+    this.refreshContents = false;
+  },
+  
+  shouldOpenDefaultEditMode: function(){
+    // can open default edit mode if defaultEditMode is set
+    // and this is the root view or a child view with a selected parent.
+    return this.defaultEditMode && (!this.parentProperty || this.parentView.viewGrid.getSelectedRecords().length === 1);
+  },
+  
+  openDefaultEditView: function(record){
+    if (!this.shouldOpenDefaultEditMode()) {
+      return;
+    }
+    
+    // open form in insert mode
+    if (record) {
+      this.editRecord(record);
+    } else if (!this.viewGrid.data || this.viewGrid.data.getLength() === 0) {
+      // open in insert mode
+      this.viewGrid.hide();
+      this.statusBarFormLayout.show();
+      this.statusBarFormLayout.setHeight('100%');
+    } else {
+      // edit the first record
+      this.editRecord(this.viewGrid.getRecord(0));
+    }
+  },
+  
+  // ** {{{ switchFormGridVisibility }}} **
+  // Switch from form to grid view or the other way around
+  switchFormGridVisibility: function(){
+    if (this.viewGrid.isVisible()) {
+      this.viewGrid.hide();
+      this.statusBarFormLayout.show();
+      this.statusBarFormLayout.setHeight('100%');
+    } else {
+      this.statusBarFormLayout.hide();
+      this.viewGrid.show();
+      this.viewGrid.setHeight('100%');
+    }
+    this.updateTabTitle();
+  },
+  
+  doHandleClick: function(){
+    if (!this.childTabSet) {
+      return;
+    }
+    if (this.state !== isc.OBStandardView.STATE_BOTTOM_MAX) {
+      this.setHalfSplit();
+      this.previousState = isc.OBStandardView.STATE_TOP_MAX;
+      this.state = isc.OBStandardView.STATE_MID;
+    }
+  },
+  
+  doHandleDoubleClick: function(){
+    var tempState;
+    if (!this.childTabSet) {
+      return;
+    }
+    tempState = this.state;
+    this.state = this.previousState;
+    if (this.previousState === isc.OBStandardView.STATE_BOTTOM_MAX) {
+      this.setBottomMaximum();
+    } else if (this.previousState === isc.OBStandardView.STATE_MID) {
+      this.setHalfSplit();
+    } else if (this.previousState === isc.OBStandardView.STATE_TOP_MAX) {
+      this.setTopMaximum();
+    } else {
+      isc.warn(this.previousState + ' not supported ');
+    }
+    this.previousState = tempState;
+  },
+  
+  // ** {{{ editRecord }}} **
+  // Opens the edit form and selects the record in the grid, will refresh
+  // child views also
+  editRecord: function(record){
+  
+    // this.recordSelected(record);
+    this.viewForm.editRecord(record);
+    this.viewForm.clearErrors();
+    if (this.viewGrid.isVisible()) {
+      this.switchFormGridVisibility();
+    }
+    this.viewGrid.doSelectSingleRecord(record);
+  },
+  
+  // check if a child tab should be opened directly
+  openDirectChildTab: function(){
+    if (this.childTabSet) {
+      var i, tabs = this.childTabSet.tabs;
+      for (i = 0; i < tabs.length; i++) {
+        if (tabs[i].pane.openDirectTab()) {
+          return;
+        }
+      }
+    }
+    
+    // no child tabs to open anymore, show ourselves as the default view
+    // open this view
+    if (this.parentTabSet) {
+      this.parentTabSet.setState(isc.OBStandardView.STATE_MID);
+    } else {
+      this.doHandleClick();
+    }
+    var gridRecord = this.viewGrid.getSelectedRecord();
+    this.editRecord(gridRecord);
+    
+    // remove this info
+    delete this.standardWindow.directTabInfo;
+  },
+  
+  openDirectTab: function(){
+    if (!this.dataSource) {
+      // wait for the datasource to arrive
+      this.delayCall('openDirectTab', null, 200, this);
+      return;
+    }
+    var i, thisView = this, tabInfos = this.standardWindow.directTabInfo;
+    if (!tabInfos) {
+      return;
+    }
+    for (i = 0; i < tabInfos.length; i++) {
+      if (tabInfos[i].targetTabId === this.tabId) {
+        // found it...
+        this.viewGrid.targetRecordId = tabInfos[i].targetRecordId;
+        
+        if (this.parentTabSet && this.parentTabSet.getSelectedTab() !== this.tab) {
+          this.parentTabSet.selectTab(this.tab);
+        } else {
+          // make sure that the content gets refreshed
+          this.refreshContents = true;
+          // refresh and open a child view when all is done
+          this.doRefreshContents();
+        }
+        return true;
+      }
+    }
+    return false;
+  },
+  
+  // ** {{{ recordSelected }}} **
+  // Is called when a record get's selected. Will refresh direct child views
+  // which will again refresh their children.
+  recordSelected: function(){
+    this.fireOnPause("recordSelected", {
+      target: this,
+      methodName: "doRecordSelected",
+      args: []
+    }, this.fetchDelay);
+  },
+  
+  doRecordSelected: function(){
+    // no change go away
+    if (this.viewGrid.getSelectedRecords().length === 1 && this.viewGrid.getSelectedRecord() === this.lastRecordSelected) {
+      return;
+    }
+    
+    var tabViewPane = null;
+    
+    // refresh the tabs
+    if (this.childTabSet) {
+      for (var i = 0; i < this.childTabSet.tabs.length; i++) {
+        tabViewPane = this.childTabSet.tabs[i].pane;
+        tabViewPane.parentRecordSelected();
+      }
+    }
+    // and recompute the count:
+    this.updateChildCount();
+    this.updateTabTitle();
+    this.lastRecordSelected = this.viewGrid.getSelectedRecord();
+  },
+  
+  // ** {{{ parentRecordSelected }}} **
+  // Is called when a selection change occurs in the parent.
+  parentRecordSelected: function(){
+  
+    // clear all our selections..
+    this.viewGrid.deselectAllRecords();
+    
+    // switch back to the grid or form
+    if (this.shouldOpenDefaultEditMode()) {
+      if (this.viewGrid.isVisible()) {
+        this.switchFormGridVisibility();
+      }
+    } else if (!this.viewGrid.isVisible()) {
+      this.switchFormGridVisibility();
+    }
+    
+    // clear the count from the tabtitle, will be recomputed
+    this.updateTabTitle();
+    
+    // if not visible or the parent also needs to be refreshed
+    if (!this.isViewVisible() ||
+    (this.parentView && this.parentView.refreshContents)) {
+      isc.Log.logDebug('ParentRecordSelected: View not visible ' + this.tabTitle, 'OB');
+      // refresh when the view get's shown
+      this.refreshContents = true;
+    } else {
+      isc.Log.logDebug('ParentRecordSelected: View visible ' + this.tabTitle, 'OB');
+      var me = this;
+      if (this.viewGrid) {
+        this.viewGrid.refreshContents();
+      }
+      if (this.viewForm) {
+        this.viewForm.clearValues();
+        this.viewForm.clearErrors();
+      }
+    }
+    // enable the following code if we don't automatically select the first
+    // record
+    if (this.childTabSet) {
+      for (var i = 0; i < this.childTabSet.tabs.length; i++) {
+        tabViewPane = this.childTabSet.tabs[i].pane;
+        tabViewPane.parentRecordSelected();
+      }
+    }
+  },
+  
+  updateChildCount: function(){
+    if (!this.childTabSet) {
+      return;
+    }
+    if (this.viewGrid.getSelectedRecords().length !== 1) {
+      return;
+    }
+    
+    var infoByTab = [], tabInfo, childView, data = {}, me = this, callback;
+    
+    data.parentId = this.viewGrid.getSelectedRecords()[0][OB.Constants.ID];
+    
+    for (var i = 0; i < this.childTabSet.tabs.length; i++) {
+      tabInfo = {};
+      childView = this.childTabSet.tabs[i].pane;
+      tabInfo.parentProperty = childView.parentProperty;
+      tabInfo.tabId = childView.tabId;
+      tabInfo.entity = childView.entity;
+      if (childView.viewGrid.whereClause) {
+        tabInfo.whereClause = childView.viewGrid.whereClause;
+      }
+      infoByTab.push(tabInfo);
+    }
+    data.tabs = infoByTab;
+    
+    // walks through the tabs and sets the title
+    callback = function(resp, data, req){
+      var tab, tabPane;
+      var tabInfos = data.result;
+      if (!tabInfos || tabInfos.length !== me.childTabSet.tabs.length) {
+        // error, something has changed
+        return;
+      }
+      for (var i = 0; i < me.childTabSet.tabs.length; i++) {
+        childView = me.childTabSet.tabs[i].pane;
+        tab = me.childTabSet.getTab(i);
+        if (childView.tabId === tabInfos[i].tabId) {
+          tabPane = me.childTabSet.getTabPane(tab);
+          tabPane.recordCount = tabInfos[i].count;
+          tabPane.updateTabTitle();
+        }
+      }
+    };
+    
+    OB.RemoteCallManager.call('org.openbravo.client.application.ChildTabRecordCounterActionHandler', data, {}, callback, null);
+  },
+  
+  updateTabTitle: function(){
+  
+    // store the original tab title
+    if (!this.originalTabTitle) {
+      this.originalTabTitle = this.tabTitle;
+    }
+    
+    var identifier, tab;
+    // showing the form
+    if (!this.viewGrid.isVisible() && this.viewGrid.getSelectedRecord() && this.viewGrid.getSelectedRecord()[OB.Constants.IDENTIFIER]) {
+      identifier = this.viewGrid.getSelectedRecord()[OB.Constants.IDENTIFIER];
+      if (!this.parentTabSet && this.viewTabId) {
+        tab = OB.MainView.TabSet.getTab(this.viewTabId);
+        OB.MainView.TabSet.setTabTitle(tab, this.originalTabTitle + ' - ' + identifier);
+      } else if (this.parentTabSet && this.tab) {
+        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle + ' - ' + identifier);
+      }
+    } else if (!this.parentTabSet && this.viewTabId) {
+      // the root view
+      tab = OB.MainView.TabSet.getTab(this.viewTabId);
+      OB.MainView.TabSet.setTabTitle(tab, this.originalTabTitle);
+    } else if (this.parentTabSet && this.tab) {
+      // the check on this.tab is required for the initialization phase
+      // only show a count if there is one parent
+      if (this.parentView.viewGrid.getSelectedRecords().length !== 1) {
+        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle);
+      } else if (this.recordCount) {
+        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle + ' (' + this.recordCount + ')');
+      } else {
+        this.parentTabSet.setTabTitle(this.tab, this.originalTabTitle);
+      }
+    }
+  },
+  
+  isViewVisible: function(){
+    return this.parentTabSet.getSelectedTabNumber() ===
+    this.parentTabSet.getTabNumber(this.tab);
+  },
+  
+  /* ++++++++++++++++++++ Status Bar ++++++++++++++++++++++++++ */
+  
+  statusBarCloseIconButtonProperties: {
+    view: null,
+    imageType: 'center',
+    showRollOver: false,
+    src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/ico-x.png',
+    action: function(){
+      this.view.switchFormGridVisibility();
+    }
+  },
+  
+  statusBarPrevIconButtonProperties: {
+    view: null,
+    imageType: 'center',
+    showRollOver: false,
+    src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/sn-previous.gif',
+    action: function(){
+      var rowNum = this.view.viewGrid.data.indexOf(this.view.viewGrid.getSelectedRecord());
+      var newRowNum = rowNum - 1;
+      if (newRowNum > -1) {
+        var newRecord = this.view.viewGrid.getRecord(newRowNum);
+        this.view.viewGrid.scrollRecordToTop(newRowNum);
+        this.view.editRecord(newRecord);
+        this.view.updateTabTitle();
+      }
+    }
+  },
+  
+  statusBarNextIconButtonProperties: {
+    view: null,
+    imageType: 'center',
+    showRollOver: false,
+    src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/sn-next.gif',
+    action: function(){
+      var rowNum = this.view.viewGrid.data.indexOf(this.view.viewGrid.getSelectedRecord());
+      var newRowNum = rowNum + 1;
+      // if there is data move to it
+      if (this.view.viewGrid.data.get(newRowNum)) {
+        var newRecord = this.view.viewGrid.getRecord(newRowNum);
+        this.view.viewGrid.scrollRecordToTop(newRowNum);
+        this.view.editRecord(newRecord);
+        this.view.updateTabTitle();
+      }
+    }
+  },
+  
+  createStatusBar: function(){
+    var statusBar = isc.HLayout.create({
+      width: '100%',
+      height: '30',
+      overflow: 'auto'
+    });
+    var messageBar = isc.HLayout.create({
+      width: '*',
+      align: 'left',
+      overflow: 'visible'
+    });
+    messageBar.addMember(isc.Label.create({
+      contents: 'message'
+    }));
+    
+    var prevButton = isc.ImgButton.create(this.statusBarPrevIconButtonProperties);
+    var nextButton = isc.ImgButton.create(this.statusBarNextIconButtonProperties);
+    var closeButton = isc.ImgButton.create(this.statusBarCloseIconButtonProperties);
+    var buttonBar = isc.HLayout.create({
+      width: '100',
+      align: 'right',
+      overflow: 'visible'
+    });
+    
+    prevButton.view = this;
+    nextButton.view = this;
+    closeButton.view = this;
+    
+    buttonBar.addMembers([prevButton, nextButton, closeButton]);
+    statusBar.addMembers([messageBar, buttonBar]);
+    return statusBar;
+  },
+  
+  /*
+   * ++++++++++++++++++++ Parent-Child Tab Handling
+   * ++++++++++++++++++++++++++
+   */
+  convertToPercentageHeights: function(){
+    if (!this.members[1]) {
+      return;
+    }
+    var height = this.members[1].getHeight();
+    var percentage = ((height / this.getHeight()) * 100);
+    // this.members[0].setHeight((100 - percentage) + '%');
+    this.members[0].setHeight('*');
+    this.members[1].setHeight(percentage + '%');
+  },
+  
+  setTopMaximum: function(){
+    this.setHeight('100%');
+    if (this.members[1]) {
+      this.members[0].setHeight('*');
+      this.members[1].setState(isc.OBStandardView.STATE_MIN);
+      this.members[1].show();
+      this.members[0].show();
+      this.convertToPercentageHeights();
+    } else {
+      this.members[0].setHeight('100%');
+      this.members[0].show();
+    }
+  },
+  
+  setBottomMaximum: function(){
+    this.setHeight('100%');
+    if (this.members[1]) {
+      this.members[0].hide();
+      this.members[0].setHeight(0);
+      this.members[1].setHeight('100%');
+      this.members[1].show();
+    } else {
+      this.members[0].setHeight('100%');
+      this.members[0].show();
+    }
+  },
+  
+  setHalfSplit: function(){
+    this.setHeight('100%');
+    var i, tab, pane;
+    if (this.members[1]) {
+      // divide the space between the first and second level
+      if (this.members[1].draggedHeight) {
+        this.members[0].setHeight('*');
+        this.members[1].setHeight(this.members[1].draggedHeight);
+        this.members[0].show();
+        this.members[1].show();
+        this.convertToPercentageHeights();
+        this.members[1].setState(isc.OBStandardView.STATE_IN_MID);
+      } else {
+        // NOTE: noticed that when resizing multiple members in a layout, that it 
+        // makes a difference what the order of resizing is, first resize the 
+        // one which will be larger, then the one which will be smaller.
+        // also do the STATE_IN_MID before resizing
+        this.members[1].setHeight('50%');
+        this.members[0].setHeight('50%');
+        this.members[1].show();
+        this.members[0].show();
+        this.members[1].setState(isc.OBStandardView.STATE_IN_MID);
+      }
+    } else {
+      this.members[0].setHeight('100%');
+      this.members[0].show();
+    }
+  },
+  
+  getContextInfo: function(allProperties, sessionProperties){
+    // different modes:
+    // 1) showing grid with one record selected
+    // 2) showing form with aux inputs
+    var record;
+    if (this.viewGrid.isVisible()) {
+      record = this.viewGrid.getSelectedRecord();
+    } else {
+      record = this.viewForm.getValues();
+    }
+    
+    var properties = this.propertyToColumns;
+    
+    for (var i = 0; i < properties.length; i++) {
+      var value = record[properties[i].property];
+      if (typeof value !== 'undefined') {
+        allProperties[properties[i].column] = value;
+        if (properties[i].sessionProperty) {
+          sessionProperties[properties[i].column] = value;
+        }
+      }
+    }
+    
+    if (this.viewForm.isVisible()) {
+      isc.addProperties(allProperties, this.viewForm.auxInputs);
+      isc.addProperties(allProperties, this.viewForm.hiddenInputs);
+      isc.addProperties(sessionProperties, this.viewForm.auxInputs);
+      isc.addProperties(sessionProperties, this.viewForm.hiddenInputs);
+    }
+    
+    if (this.parentView) {
+      this.parentView.getContextInfo(allProperties, sessionProperties);
+    }
+  },
+  
+  setContextInfo: function(sessionProperties, callbackFunction){
+    var allProperties = {};
+    if (!sessionProperties) {
+      sessionProperties = {};
+      this.getContextInfo(allProperties, sessionProperties);
+    }
+    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', sessionProperties, {
+      MODE: 'SETSESSION',
+      TAB_ID: this.view.tabId
+    }, callbackFunction);
+  }
+});
+
+// = OBStandardViewTabSet =
+// The OBStandardViewTabSet is the tabset used within the standard view to
+// display child tabs
+isc.ClassFactory.defineClass('OBStandardViewTabSet', isc.OBTabSetChild);
+
+isc.OBStandardViewTabSet.addClassProperties({
+
+  TABBARPROPERTIES: {
+    dblClickWaiting: false,
+    
+    canDrag: false,
+    dragAppearance: 'none',
+    dragStartDistance: 1,
+    overflow: 'hidden',
+    
+    itemClick: function(item, itemNum){
+      var me = this;
+      me.dblClickWaiting = true;
+      isc.Timer.setTimeout(function(){
+        // if no double click happened then do the single click
+        if (me.dblClickWaiting) {
+          me.dblClickWaiting = false;
+          me.tabSet.doHandleClick();
+        }
+      }, OB.Constants.DBL_CLICK_DELAY);
+      
+    },
+    
+    itemDoubleClick: function(item, itemNum){
+      this.dblClickWaiting = false;
+      this.tabSet.doHandleDoubleClick();
+    },
+    
+    dragStop: function(){
+      // change the height to percentage based to handle resizing of browser:
+      this.tabSet.parentContainer.convertToPercentageHeights();
+      return true;
+    },
+    
+    dragStart: function(){
+      // -2 to prevent scrollbar
+      this.tabSet.maxHeight = this.tabSet.parentContainer.getHeight() - 2;
+      this.tabSet.minHeight = (this.getHeight() * 2) + 15;
+      return true;
+    },
+    
+    dragMove: function(){
+      var offset = (0 - isc.EH.dragOffsetY);
+      this.resizeTarget(this.tabSet, true, true, offset, -1 * this.getHeight(), null, true);
+      this.tabSet.draggedHeight = this.tabSet.getHeight();
+      // if (this.tabSet.getHeight() === this.getHeight()) {
+      // // set the parent to top-max
+      // this.tabSet.parentTabSet.setState(isc.OBStandardView.STATE_TOP_MAX);
+      // this.tabSet.draggedHeight = null;
+      // }
+      return true;
+    }
+  }
+});
+
+isc.OBStandardViewTabSet.addProperties({
+  tabBarProperties: isc.addProperties({}, isc.OBStandardViewTabSet.TABBARPROPERTIES),
+  tabBarPosition: 'top',
+  width: '100%',
+  height: '*',
+  overflow: 'hidden',
+  
+  // get rid of the margin around the content of a pane
+  paneMargin: 0,
+  paneContainerMargin: 0,
+  paneContainerPadding: 0,
+  showPaneContainerEdges: false,
+  
+  state: null,
+  previousState: null,
+  
+  // keeps track of the previous dragged height, to restore it
+  draggedHeight: null,
+  
+  setDraggable: function(draggable){
+    if (draggable) {
+      this.tabBar.canDrag = true;
+      this.tabBar.cursor = isc.Canvas.HAND;
+    } else {
+      this.tabBar.canDrag = false;
+      this.tabBar.cursor = isc.Canvas.DEFAULT;
+    }
+  },
+  
+  doHandleClick: function(){
+    if (this.state === isc.OBStandardView.STATE_MIN) {
+      // we are minimized, there must be a parent then
+      if (this.parentTabSet) {
+        this.parentTabSet.setState(isc.OBStandardView.STATE_MID);
+      } else {
+        this.parentContainer.setHalfSplit();
+      }
+    } else if (this.state === isc.OBStandardView.STATE_BOTTOM_MAX) {
+      this.setState(isc.OBStandardView.STATE_MID);
+    }
+  },
+  
+  doHandleDoubleClick: function(){
+    if (this.state === isc.OBStandardView.STATE_TOP_MAX) {
+      // we are maximized go back to the previous state
+      if (this.previousState && this.previousState !== this.state) {
+        if (this.previousState === isc.OBStandardView.STATE_IN_MID) {
+          this.parentContainer.setHalfSplit();
+        } else if (this.previousState === isc.OBStandardView.STATE_MIN) {
+          if (this.parentTabSet) {
+            this.parentTabSet.setState(isc.OBStandardView.STATE_TOP_MAX);
+          } else {
+            this.parentContainer.setTopMaximum();
+          }
+        } else {
+          this.setState(this.previousState);
+        }
+      } else {
+        this.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
+      }
+    } else {
+      // first set to IN_MID, to prevent empty tab displays
+      this.setState(isc.OBStandardView.STATE_IN_MID);
+      this.setState(isc.OBStandardView.STATE_TOP_MAX);
+    }
+  },
+  
+  getState: function(){
+    return this.state;
+  },
+  
+  setState: function(newState){
+  
+    // disabled this as sometimes states have
+    // to be reset to recompute heights changed automatically
+    // if (this.state === newState) {
+    // return;
+    // }
+    
+    var tab, i, pane;
+    var tmpPreviousState = this.state;
+    
+    // is corrected below for one state
+    this.setDraggable(false);
+    
+    if (newState === isc.OBStandardView.STATE_TOP_MAX) {
+      this.state = newState;
+      
+      // minimize the ancestors
+      if (this.parentTabSet) {
+        this.parentTabSet.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
+      } else if (this.parentContainer) {
+        this.parentContainer.setBottomMaximum();
+      }
+      
+      // note this for loop must be done before the parent's are
+      // done otherwise the content is not drawn
+      // the top member in each tab is maximized
+      // the bottom member in each tab is set to the tabbar height
+      for (i = 0; i < this.tabs.length; i++) {
+        tab = this.tabs[i];
+        this.makeTabVisible(tab);
+        pane = this.getTabPane(tab);
+        pane.setTopMaximum();
+      }
+      
+    } else if (newState === isc.OBStandardView.STATE_MIN) {
+      // the height is set to the height of the tabbar
+      this.setHeight(this.tabBar.getHeight());
+      for (i = 0; i < this.tabs.length; i++) {
+        tab = this.tabs[i];
+        this.getTabPane(tab).hide();
+      }
+      this.state = newState;
+    } else if (newState === isc.OBStandardView.STATE_BOTTOM_MAX) {
+      // the top part in each layout is set to 0%, and the bottom to max
+      this.state = newState;
+      if (this.parentTabSet) {
+        this.parentTabSet.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
+      } else if (this.parentContainer) {
+        this.parentContainer.setBottomMaximum();
+      }
+      for (i = 0; i < this.tabs.length; i++) {
+        tab = this.tabs[i];
+        this.makeTabVisible(tab);
+        pane = this.getTabPane(tab);
+        pane.setBottomMaximum();
+      }
+    } else if (newState === isc.OBStandardView.STATE_IN_MID) {
+      this.state = newState;
+      this.setDraggable(true);
+      // minimize the third level
+      for (i = 0; i < this.tabs.length; i++) {
+        tab = this.tabs[i];
+        pane = this.getTabPane(tab);
+        this.makeTabVisible(tab);
+        pane.members[0].setHeight('*');
+        if (pane.members[1]) {
+          pane.members[1].setState(isc.OBStandardView.STATE_MIN);
+        }
+      }
+    } else if (newState === isc.OBStandardView.STATE_MID) {
+      if (this.parentTabSet) {
+        this.parentTabSet.setState(isc.OBStandardView.STATE_BOTTOM_MAX);
+      } else if (this.parentContainer) {
+        this.parentContainer.setBottomMaximum();
+      }
+      // the content of the tabs is split in 2
+      this.state = newState;
+      for (i = 0; i < this.tabs.length; i++) {
+        tab = this.tabs[i];
+        pane = this.getTabPane(tab);
+        pane.setHalfSplit();
+        this.makeTabVisible(tab);
+      }
+    }
+    
+    this.previousState = tmpPreviousState;
+  },
+  
+  makeTabVisible: function(tab){
+    if (tab === this.getSelectedTab()) {
+      pane = this.getTabPane(tab);
+      pane.show();
+      if (pane.doRefreshContents) {
+        pane.doRefreshContents();
+      }
+      if (pane.members[0]) {
+        pane.members[0].show();
+      }
+      if (pane.members[1]) {
+        pane.members[1].show();
+      }
+      this.selectTab(tab);
+    }
+  },
+  
+  tabSelected: function(tabNum, tabPane, ID, tab){
+    if (tabPane.refreshContents) {
+      tabPane.doRefreshContents();
+    }
+  },
+  
+  initWidget: function(){
+    this.tabBarProperties.tabSet = this;
+    this.Super('initWidget', arguments);
+  }
+});
+
+isc.ClassFactory.defineClass('OBMessagebar', isc.HLayout);
+
+// = OBMessagebar =
+//
+// The OBMessagebar is the bar which shows messages, it is located above the toolbar.
+//
+isc.OBMessagebar.addProperties({
+  visibility: 'hidden',
+  msgLabel: null,
+  closeButton: null,
+  overflow: 'visible',
+  height: 40,
+  
+  initWidget: function(){
+    this.closeButton = isc.ImgButton.create({
+      messageBar: this,
+      imageType: 'center',
+      showRollOver: false,
+      src: '[SKINIMG]../../org.openbravo.client.application/images/statusbar/ico-x.png',
+      action: function(){
+        this.messageBar.hide();
+      }
+    });
+    
+    this.msgLabel = isc.Label.create({
+      overflow: 'visible',
+      xwidth: '100%',
+      height: '100%'
+    });
+    
+    this.addMember(this.msgLabel);
+    this.addMember(this.closeButton);
+    
+    return this.Super('initWidget', arguments);
+  },
+  
+  setMessage: function(msg){
+    this.msgLabel.setTitle(msg);
+    this.show();
+  }
+});
+
+// TODO: move this to a central location
+isc.Canvas.addProperties({
+  // let focuschanged go up to the parent
+  focusChanged: function(hasFocus){
+    if (this.parentElement && this.parentElement.focusChanged) {
+      this.parentElement.focusChanged(hasFocus);
+    }
+  }
+});
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-utilities.js	Fri Dec 31 12:53:14 2010 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-utilities.js	Fri Dec 31 13:25:30 2010 +0100
@@ -823,7 +823,7 @@
   });
   
   
-  //  OB.Layout.ViewManager.openView("OBPopupClassicWindow", o);
+  //	OB.Layout.ViewManager.openView("OBPopupClassicWindow", o);
   //OB.Layout.ViewManager.openView("OBClassicPopup", o);
 
 
--- a/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-view-form.js	Fri Dec 31 12:53:14 2010 +0100
+++ b/modules/org.openbravo.client.application/web/org.openbravo.client.application/js/ob-view-form.js	Fri Dec 31 13:25:30 2010 +0100
@@ -1,203 +1,203 @@
-/*
- *************************************************************************
- * The contents of this file are subject to the Openbravo  Public  License
- * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
- * Version 1.1  with a permitted attribution clause; you may not  use this
- * file except in compliance with the License. You  may  obtain  a copy of
- * the License at http://www.openbravo.com/legal/license.html
- * Software distributed under the License  is  distributed  on  an "AS IS"
- * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
- * License for the specific  language  governing  rights  and  limitations
- * under the License.
- * The Original Code is Openbravo ERP.
- * The Initial Developer of the Original Code is Openbravo SLU
- * All portions are Copyright (C) 2010 Openbravo SLU
- * All Rights Reserved.
- * Contributor(s):  ______________________________________.
- ************************************************************************
- */
-isc.ClassFactory.defineClass('OBViewForm', isc.DynamicForm);
-
-// = OBViewForm =
-// The OBViewForm is the Openbravo specific subclass of the Smartclient
-// DynamicForm.
-
-isc.OBViewForm.addProperties({
-
-  // ** {{{ view }}} **
-  // The view member contains the pointer to the composite canvas which
-  // handles this form
-  // and the grid and other related components.
-  view: null,
-  auxInputs: {},
-  dynamicCols: [],
-
-  // ** {{ Layout Settings }} **
-  numCols: 4,
-  colWidths: ['24%', '24%', '24%', '24%'],
-  //cellBorder: 1, // debug layout
-  
-  fieldsByInpColumnName: null,
-  fieldsByColumnName: null,
-  
-  initWidget: function(){
-    // iterate over the fields and set the datasource
-    //    var field, i, fieldsNum = this.fields.length;
-    //    for (i = 0; i < fieldsNum; i++) {
-    //      field = this.fields[i];
-    //      if (field.dataSourceId) {
-    // field.optionDataSource = OB.Datasource.get(field.dataSourceId, field, 'optionDataSource');
-    //      }
-    //    }
-    var ret = this.Super('initWidget', arguments);
-    return ret;
-  },
-  
-  editRecord: function(record){
-    var ret = this.Super("editRecord", arguments);
-    this.retrieveInitialValues();
-    return ret;
-  },
-  
-  getFieldFromInpColumnName: function(inpColumnName){
-    if (!this.fieldsByInpColumnName) {
-      var localResult = [], fields = this.getFields();
-      for (var i = 0; i < fields.length; i++) {
-        localResult[fields[i].inpColumnName] = fields[i];
-      }
-      this.fieldsByInpColumnName = localResult;
-    }
-    return this.fieldsByInpColumnName[inpColumnName.toLowerCase()];
-  },
-  
-  getFieldFromColumnName: function(columnName){
-    if (!this.fieldsByColumnName) {
-      var localResult = [], fields = this.getFields();
-      for (var i = 0; i < fields.length; i++) {
-        localResult[fields[i].columnName] = fields[i];
-      }
-      this.fieldsByColumnName = localResult;
-    }
-    return this.fieldsByColumnName[columnName.toLowerCase()];
-  },
-  
-  setFields: function(){
-    this.Super('setFields', arguments);
-    this.fieldsByInpColumnName = null;
-    this.fieldsByColumnName = null;
-  },
-  
-  retrieveInitialValues: function(){
-    var parentId = null, me = this;
-    if (this.view.parentProperty) {
-      parentId = this.getValue(this.view.parentProperty);
-    }
-    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', null, {
-      MODE: 'EDIT',
-      PARENT_ID: parentId,
-      TAB_ID: this.view.tabId,
-      ROW_ID: this.getValue(OB.Constants.ID)
-    }, function(response, data, request){
-      me.processFICReturn(response, data, request);
-    });
-  },
-  
-  processFICReturn: function(response, data, request){
-    // TODO: an error occured, handles this much better...
-    if (!data) {
-      return;
-    }
-    var columnValues = data.columnValues, calloutMessages = data.calloutMessages, auxInputs = data.auxiliaryInputValues, prop, value;
-    var dynamicCols = data.dynamicCols;
-    if (columnValues) {
-      for (prop in columnValues) {
-        if (columnValues.hasOwnProperty(prop)) {
-          this.processColumnValue(prop, columnValues[prop]);
-        }
-      }
-    }
-    if (calloutMessages) {
-      // show messages...
-      // code added to prevent jslint error
-      var __dummy = 0;  
-    }
-    if (auxInputs) {
-      this.auxInputs = {};
-      for (prop in auxInputs) {
-        if (auxInputs.hasOwnProperty(prop)) {
-          this.setValue(prop, auxInputs[prop].value);
-          auxInputs[prop] = auxInputs[prop].value;
-        }
-      }
-    }
-    if (dynamicCols) {
-      this.dynamicCols = dynamicCols;
-    }
-  },
-  
-  processColumnValue: function(columnName, columnValue){
-    var isDate, i, valueMap = {}, field = this.getFieldFromColumnName(columnName), entries = columnValue.entries;
-    if (!field) {
-      // ignore for now, the pk is also passed in
-      //isc.warn('No field found using column name: ' + columnName + ' for tab ' + this.view.tabId);
-      return;
-    }
-    if (entries && entries.length > 0) {
-      if (field.getDataSource()) {
-        field.getDataSource().setCacheData(entries, true);
-      } else {
-        for (i = 0; i < entries.length; i++) {
-          valueMap[entries[i][OB.Constants.ID]] = entries[i][OB.Constants.IDENTIFIER];
-        }
-        field.setValueMap(valueMap);
-      }
-    }
-    if (columnValue.value) {
-      isDate = field.type &&
-        (isc.SimpleType.getType(field.type).inheritsFrom === 'date' ||
-        isc.SimpleType.getType(field.type).inheritsFrom === 'datetime');
-      if (isDate) {
-        this.setValue(field.name, isc.Date.parseSchemaDate(columnValue.value));
-      } else {
-        this.setValue(field.name, columnValue.value);
-      }
-    } else {
-      this.clearValue(field.name);
-    }
-  },
-  
-  handleItemChange: function(item) {
-    if (item._doFICCall) {
-      var i;
-      for (i = 0; i < this.dynamicCols.length; i++) {
-        if (this.dynamicCols[i] === item.inpColumnName) {
-          item._doFICCall = false;
-          this.doChangeFICCall(item);
-          return;
-        }
-      }
-    }
-    item._doFICCall = false;
-  },
-  
-  doChangeFICCall: function(item) {
-    var parentId = null, me = this;
-    if (this.view.parentProperty) {
-      parentId = this.getValue(this.view.parentProperty);
-    }
-    
-    var allProperties = {}, sessionProperties = {};
-    this.view.getContextInfo(allProperties, sessionProperties);
-    
-    // collect the context information    
-    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', allProperties, {
-      MODE: 'CHANGE',
-      PARENT_ID: parentId,
-      TAB_ID: this.view.tabId,
-      ROW_ID: this.getValue(OB.Constants.ID),
-      CHANGED_COLUMN: item.inpColumnName
-    }, function(response, data, request){
-      me.processFICReturn(response, data, request);
-    });
-  }
-});
+/*
+ *************************************************************************
+ * The contents of this file are subject to the Openbravo  Public  License
+ * Version  1.1  (the  "License"),  being   the  Mozilla   Public  License
+ * Version 1.1  with a permitted attribution clause; you may not  use this
+ * file except in compliance with the License. You  may  obtain  a copy of
+ * the License at http://www.openbravo.com/legal/license.html
+ * Software distributed under the License  is  distributed  on  an "AS IS"
+ * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+ * License for the specific  language  governing  rights  and  limitations
+ * under the License.
+ * The Original Code is Openbravo ERP.
+ * The Initial Developer of the Original Code is Openbravo SLU
+ * All portions are Copyright (C) 2010 Openbravo SLU
+ * All Rights Reserved.
+ * Contributor(s):  ______________________________________.
+ ************************************************************************
+ */
+isc.ClassFactory.defineClass('OBViewForm', isc.DynamicForm);
+
+// = OBViewForm =
+// The OBViewForm is the Openbravo specific subclass of the Smartclient
+// DynamicForm.
+
+isc.OBViewForm.addProperties({
+
+  // ** {{{ view }}} **
+  // The view member contains the pointer to the composite canvas which
+  // handles this form
+  // and the grid and other related components.
+  view: null,
+  auxInputs: {},
+  hiddenInputs: {},
+  dynamicCols: [],
+
+  // ** {{ Layout Settings }} **
+  numCols: 4,
+  colWidths: ['24%', '24%', '24%', '24%'],
+  //cellBorder: 1, // debug layout
+  
+  fieldsByInpColumnName: null,
+  fieldsByColumnName: null,
+  
+  initWidget: function(){
+    // iterate over the fields and set the datasource
+    //    var field, i, fieldsNum = this.fields.length;
+    //    for (i = 0; i < fieldsNum; i++) {
+    //      field = this.fields[i];
+    //      if (field.dataSourceId) {
+    // field.optionDataSource = OB.Datasource.get(field.dataSourceId, field, 'optionDataSource');
+    //      }
+    //    }
+    var ret = this.Super('initWidget', arguments);
+    return ret;
+  },
+  
+  editRecord: function(record){
+    var ret = this.Super("editRecord", arguments);
+    this.retrieveInitialValues();
+    return ret;
+  },
+  
+  getFieldFromInpColumnName: function(inpColumnName){
+    if (!this.fieldsByInpColumnName) {
+      var localResult = [], fields = this.getFields();
+      for (var i = 0; i < fields.length; i++) {
+        localResult[fields[i].inpColumnName] = fields[i];
+      }
+      this.fieldsByInpColumnName = localResult;
+    }
+    return this.fieldsByInpColumnName[inpColumnName.toLowerCase()];
+  },
+  
+  getFieldFromColumnName: function(columnName){
+    if (!this.fieldsByColumnName) {
+      var localResult = [], fields = this.getFields();
+      for (var i = 0; i < fields.length; i++) {
+        localResult[fields[i].columnName] = fields[i];
+      }
+      this.fieldsByColumnName = localResult;
+    }
+    return this.fieldsByColumnName[columnName.toLowerCase()];
+  },
+  
+  setFields: function(){
+    this.Super('setFields', arguments);
+    this.fieldsByInpColumnName = null;
+    this.fieldsByColumnName = null;
+  },
+  
+  retrieveInitialValues: function(){
+    var parentId = null, me = this;
+    if (this.view.parentProperty) {
+      parentId = this.getValue(this.view.parentProperty);
+    }
+    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', null, {
+      MODE: 'EDIT',
+      PARENT_ID: parentId,
+      TAB_ID: this.view.tabId,
+      ROW_ID: this.getValue(OB.Constants.ID)
+    }, function(response, data, request){
+      me.processFICReturn(response, data, request);
+    });
+  },
+  
+  processFICReturn: function(response, data, request){
+    // TODO: an error occured, handles this much better...
+    if (!data) {
+      return;
+    }
+    var columnValues = data.columnValues, calloutMessages = data.calloutMessages, auxInputs = data.auxiliaryInputValues, prop, value;
+    var dynamicCols = data.dynamicCols;
+    if (columnValues) {
+      for (prop in columnValues) {
+        if (columnValues.hasOwnProperty(prop)) {
+          this.processColumnValue(prop, columnValues[prop]);
+        }
+      }
+    }
+    if (calloutMessages && calloutMessages.length > 0) {
+      // TODO: handle multiple messages
+      this.view.standardWindow.messageBar.setMessage(calloutMessages[0]);
+    }
+    if (auxInputs) {
+      this.auxInputs = {};
+      for (prop in auxInputs) {
+        if (auxInputs.hasOwnProperty(prop)) {
+          this.setValue(prop, auxInputs[prop].value);
+          auxInputs[prop] = auxInputs[prop].value;
+        }
+      }
+    }
+    if (dynamicCols) {
+      this.dynamicCols = dynamicCols;
+    }
+  },
+  
+  processColumnValue: function(columnName, columnValue){
+    var isDate, i, valueMap = {}, field = this.getFieldFromColumnName(columnName), entries = columnValue.entries;
+    if (!field) {
+      // ignore for now, the pk is also passed in
+      //isc.warn('No field found using column name: ' + columnName + ' for tab ' + this.view.tabId);
+      return;
+    }
+    if (entries) {
+      if (field.getDataSource()) {
+        field.getDataSource().setCacheData(entries, true);
+      } else {
+        for (i = 0; i < entries.length; i++) {
+          valueMap[entries[i][OB.Constants.ID]] = entries[i][OB.Constants.IDENTIFIER];
+        }
+        field.setValueMap(valueMap);
+      }
+    }
+    if (columnValue.value) {
+      isDate = field.type &&
+        (isc.SimpleType.getType(field.type).inheritsFrom === 'date' ||
+        isc.SimpleType.getType(field.type).inheritsFrom === 'datetime');
+      if (isDate) {
+        this.setValue(field.name, isc.Date.parseSchemaDate(columnValue.value));
+      } else {
+        this.setValue(field.name, columnValue.value);
+      }
+    } else {
+      this.clearValue(field.name);
+    }
+  },
+  
+  handleItemChange: function(item) {
+    if (item._doFICCall) {
+      var i;
+      for (i = 0; i < this.dynamicCols.length; i++) {
+        if (this.dynamicCols[i] === item.inpColumnName) {
+          item._doFICCall = false;
+          this.doChangeFICCall(item);
+          return;
+        }
+      }
+    }
+    item._doFICCall = false;
+  },
+  
+  doChangeFICCall: function(item) {
+    var parentId = null, me = this;
+    if (this.view.parentProperty) {
+      parentId = this.getValue(this.view.parentProperty);
+    }
+    
+    var allProperties = {}, sessionProperties = {};
+    this.view.getContextInfo(allProperties, sessionProperties);
+    
+    // collect the context information    
+    OB.RemoteCallManager.call('org.openbravo.client.application.window.FormInitializationComponent', allProperties, {
+      MODE: 'CHANGE',
+      PARENT_ID: parentId,
+      TAB_ID: this.view.tabId,
+      ROW_ID: this.getValue(OB.Constants.ID),
+      CHANGED_COLUMN: item.inpColumnName
+    }, function(response, data, request){
+      me.processFICReturn(response, data, request);
+    });
+  }
+});