diff --git a/contrib/mobile/Android/src/org/geuz/onelab/AboutActivity.java b/contrib/mobile/Android/src/org/geuz/onelab/AboutActivity.java
index d289e685f3195ccec7f5a5210b2994345fa3efe3..55d564fdd81c6b9f9d5f15f04e1062e2f5fe7099 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/AboutActivity.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/AboutActivity.java
@@ -9,32 +9,32 @@ import android.webkit.WebView;
 
 public class AboutActivity extends Activity{
 
-	protected void onCreate(android.os.Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		getActionBar().setDisplayHomeAsUpEnabled(true);
-		WebView webview = new WebView(this);
-		String aboutGmsh = Gmsh.getAboutGmsh();
-		String aboutGetDP = Gmsh.getAboutGetDP();
-		String aboutOnelab = "<center><h3>Onelab/Mobile</h3>";
-		try {
-			aboutOnelab += "Version "+this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
-		}
-		catch (android.content.pm.PackageManager.NameNotFoundException e) {
-			aboutOnelab += "Version ?.?.?";
-		}
-		aboutOnelab += "<p>Copyright (C) 2014 Christophe Geuzaine and Maxime Graulich, University of Li&egrave;ge</p>";
-		aboutOnelab += "<p>Visit <a href=\"http://onelab.info/\">http://onelab.info/</a> for more information</p>";
-		aboutOnelab += "<p>This version of Onelab/Mobile contains:</p>";
-		webview.loadDataWithBaseURL("", aboutOnelab + aboutGmsh + aboutGetDP, "text/html", "UTF-8", "");
-		setContentView(webview);
-	}
-	@Override
+    protected void onCreate(android.os.Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        getActionBar().setDisplayHomeAsUpEnabled(true);
+        WebView webview = new WebView(this);
+        String aboutGmsh = Gmsh.getAboutGmsh();
+        String aboutGetDP = Gmsh.getAboutGetDP();
+        String aboutOnelab = "<p>&npsp;</p><center><h3>Onelab/Mobile</h3>";
+        try {
+            aboutOnelab += "Version "+this.getPackageManager().getPackageInfo(this.getPackageName(), 0).versionName;
+        }
+        catch (android.content.pm.PackageManager.NameNotFoundException e) {
+            aboutOnelab += "Version ?.?.?";
+        }
+        aboutOnelab += "<p>Copyright (C) 2014 Christophe Geuzaine and Maxime Graulich, University of Li&egrave;ge</p>";
+        aboutOnelab += "<p>Visit <a href=\"http://onelab.info/\">http://onelab.info/</a> for more information</p>";
+        aboutOnelab += "<p>&nbsp;</p><p>This version of Onelab/Mobile contains:</p>";
+        webview.loadDataWithBaseURL("", aboutOnelab + aboutGmsh + aboutGetDP, "text/html", "UTF-8", "");
+        setContentView(webview);
+    }
+    @Override
 	public boolean onMenuItemSelected(int featureId, MenuItem item) {
-		if(item.getItemId() == android.R.id.home) {
-			Intent returnIntent = new Intent();
-			this.setResult(RESULT_CANCELED, returnIntent);
-			this.finish();
-		}
-		return super.onMenuItemSelected(featureId, item);
-	}
+        if(item.getItemId() == android.R.id.home) {
+            Intent returnIntent = new Intent();
+            this.setResult(RESULT_CANCELED, returnIntent);
+            this.finish();
+        }
+        return super.onMenuItemSelected(featureId, item);
+    }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java b/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java
index 9790ee87440c3a8be95e0561c16c6a2a7acb2fd9..7016016a861e5e67936fc7ba744e069478079aaa 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/GLESRender.java
@@ -10,66 +10,51 @@ import android.opengl.GLSurfaceView.Renderer;
 
 public class GLESRender implements Renderer{
 
-	private Gmsh mGModel;
-	private int _width, _height;
-	private Bitmap _screenshot;
-	private boolean _needScreenshot;
+    private Gmsh mGModel;
+    private int _width, _height;
+    private Bitmap _screenshot;
+    private boolean _needScreenshot;
 
-	public GLESRender(Gmsh model) {
-		this.mGModel = model;
-		_needScreenshot = false;
-	}
-	
-	public void load(String filename){
-		mGModel.load(filename);
-	}
-	
-	public void startInteraction(float x, float y) {
-		mGModel.startEvent(x, y);
-	}
-	public void endInteraction(float x, float y) {
-		mGModel.endEvent(x, y);
-	}
-	public void rotateModel(float x, float y) {
-		mGModel.rotate(x, y);
-	}
-	public void scaleModel(float s) {
-		mGModel.scale(s);
-	}
-	public void translateModel(float x, float y) {
-		mGModel.translate(x, y);
-	}
-	public void resetModelPosition() {
-		mGModel.resetPosition();
-	}
-	public void viewX() { mGModel.viewX();}
-	public void viewY() { mGModel.viewY();}
-	public void viewZ() { mGModel.viewZ();}
-	
-	// OpenGL ES methods
-	public void onDrawFrame(GL10 gl) {
-		mGModel.viewDraw();
-		if(_needScreenshot) this.screenshot(gl);
-	}
+    public GLESRender(Gmsh model)
+    {
+        this.mGModel = model;
+        _needScreenshot = false;
+    }
+    public void load(String filename){ mGModel.load(filename); }
+    public void startInteraction(float x, float y) { mGModel.startEvent(x, y); }
+    public void endInteraction(float x, float y) { mGModel.endEvent(x, y); }
+    public void rotateModel(float x, float y) { mGModel.rotate(x, y); }
+    public void scaleModel(float s) { mGModel.scale(s); }
+    public void translateModel(float x, float y) { mGModel.translate(x, y); }
+    public void resetModelPosition() { mGModel.resetPosition(); }
+    public void viewX() { mGModel.viewX();}
+    public void viewY() { mGModel.viewY();}
+    public void viewZ() { mGModel.viewZ();}
 
-	public void onSurfaceChanged(GL10 gl, int width, int height) {
-		mGModel.viewInit(width, height);
-		_width = width;
-		_height = height;
-	}
+    // OpenGL ES methods
+    public void onDrawFrame(GL10 gl)
+    {
+        mGModel.viewDraw();
+        if(_needScreenshot) this.screenshot(gl);
+    }
+    public void onSurfaceChanged(GL10 gl, int width, int height)
+    {
+        mGModel.viewInit(width, height);
+        _width = width;
+        _height = height;
+    }
+    public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
+    public void needScreenshot() {_screenshot = null; _needScreenshot = true;}
+    public Bitmap getScreenshot(){return _screenshot;}
+    private void screenshot(GL10 gl)
+    {
+        _needScreenshot = false;
+        int bitmapBuffer[] = new int[_width * _height];
+        int bitmapSource[] = new int[_width * _height];
+        IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
+        intBuffer.position(0);
 
-	public void onSurfaceCreated(GL10 gl, EGLConfig config) { }
-	public void needScreenshot() {_screenshot = null; _needScreenshot = true;}
-	public Bitmap getScreenshot(){return _screenshot;}
-	private void screenshot(GL10 gl)
-	{
-		_needScreenshot = false;
-		int bitmapBuffer[] = new int[_width * _height];
-	    int bitmapSource[] = new int[_width * _height];
-	    IntBuffer intBuffer = IntBuffer.wrap(bitmapBuffer);
-	    intBuffer.position(0);
-
-	    gl.glReadPixels(0, 0, _width, _height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
+        gl.glReadPixels(0, 0, _width, _height, GL10.GL_RGBA, GL10.GL_UNSIGNED_BYTE, intBuffer);
         int offset1, offset2;
         for (int i = 0; i < _height; i++) {
             offset1 = i * _width;
@@ -80,5 +65,5 @@ public class GLESRender implements Renderer{
             }
         }
         _screenshot = Bitmap.createBitmap(bitmapSource, _width, _height, Bitmap.Config.ARGB_8888);
-	}
+    }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java b/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java
index 1436341aa344211f8d9e95c6d7c95c0257831cab..cf7dc24ee21fb31bc7917737a6264022e6118416 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/Gmsh.java
@@ -5,121 +5,125 @@ import android.os.Parcel;
 import android.os.Parcelable;
 
 public class Gmsh implements Parcelable {
-	/** From C / C++ code **/
-	static {
-		System.loadLibrary("f2cblas");
-		System.loadLibrary("f2clapack");
-		System.loadLibrary("petsc");
-		System.loadLibrary("Gmsh");
-		System.loadLibrary("GetDP");
-		System.loadLibrary("Onelab");
-    }
-	private native long init(float fontFactor); // Init Gmsh
-	private native void loadFile(long ptr, String name); // load a file(OpenProjet)
-	private native void initView(long ptr, int w, int h); // Called each time the GLView change
-	private native void drawView(long ptr); // Called each time the GLView request a render
-	private native void eventHandler(long ptr, int event, float x, float y);
-	public native String[] getParams(); // return the parameters for onelab
-	public native int setParam(String type, String name, String value); // change a parameters
-	public native int setStringOption(String category, String name, String value);
-	public native int setDoubleOption(String category, String name, double value);
-	public native int setIntegerOption(String category, String name, int value);
-	public native String getStringOption(String category, String name);
-	public native double getDoubleOption(String category, String name);
-	public native int getIntegerOption(String category, String name);
-	public native String[] getPView(); // get a list of PViews
-	public native void setPView(int position, int intervalsType,int visible,int nbIso, float raisez); // Change options for a PView
-	public native int onelabCB(String action); // Call onelab
-
-	public boolean haveAnimation() {return numberOfAnimation() > 1;}
-	public native int numberOfAnimation();
-	public native int animationNext();
-	public native int animationPrev();
-	public native void setAnimation(int animation);
-
-	public static native String getAboutGmsh();
-	public static native String getAboutGetDP();
-
-	/** Java CLASS **/
-	private long ptr;
-	private Handler handler;
-
-	public Gmsh(Handler handler, float fontFactor) {
-		ptr = this.init(fontFactor);
-		this.handler = handler;
-	}
-
-	public void viewInit(int w, int h) {
-		this.initView(ptr, w, h);
-	}
-
-	public void viewDraw() {
-		this.drawView(ptr);
-	}
-
-	public void load(String filename){
-		this.loadFile(ptr, filename);
-	}
+    /** From C / C++ code **/
+    static {
+        System.loadLibrary("f2cblas");
+        System.loadLibrary("f2clapack");
+        System.loadLibrary("petsc");
+        System.loadLibrary("Gmsh");
+        System.loadLibrary("GetDP");
+        System.loadLibrary("Onelab");
+    }
+    private native long init(float fontFactor); // Init Gmsh
+    private native void loadFile(long ptr, String name); // load a file(OpenProjet)
+    private native void initView(long ptr, int w, int h); // Called each time the GLView change
+    private native void drawView(long ptr); // Called each time the GLView request a render
+    private native void eventHandler(long ptr, int event, float x, float y);
+    public native String[] getParams(); // return the parameters for onelab
+    public native int setParam(String type, String name, String value); // change a parameters
+    public native int setStringOption(String category, String name, String value);
+    public native int setDoubleOption(String category, String name, double value);
+    public native int setIntegerOption(String category, String name, int value);
+    public native String getStringOption(String category, String name);
+    public native double getDoubleOption(String category, String name);
+    public native int getIntegerOption(String category, String name);
+    public native String[] getPView(); // get a list of PViews
+    public native void setPView(int position, int intervalsType,int visible,int nbIso, float raisez); // Change options for a PView
+    public native int onelabCB(String action); // Call onelab
 
-	public void startEvent(float x, float y)
-	{
-		this.eventHandler(ptr, 0, x, y);
-	}
-	public void translate(float x, float y)
-	{
-		this.eventHandler(ptr, 1, x, y);
-	}
-	public void scale(float s)
-	{
-		this.eventHandler(ptr, 2, s, 0);
-	}
-	public void rotate(float x, float y)
-	{
-		this.eventHandler(ptr, 3, x, y);
-	}
-	public void viewX() { this.eventHandler(ptr, 5, 0, 0);}
-	public void viewY() { this.eventHandler(ptr, 6, 0, 0);}
-	public void viewZ() { this.eventHandler(ptr, 7, 0, 0);}
-	public void endEvent(float x, float y)
-	{
-		this.eventHandler(ptr, 4, x, y);
-	}
-	public void resetPosition()
-	{
-		this.eventHandler(ptr, 10, 0, 0);
-	}
-	public void ShowPopup(String message) {
-		if(handler != null)
-			handler.obtainMessage(0, message).sendToTarget();
-	}
-	public void RequestRender() {
-		if(handler != null)
-			handler.obtainMessage(1).sendToTarget();
-	}
-	public void SetLoading(String message) {
-		if(handler != null)
-			handler.obtainMessage(2, message).sendToTarget();
-	}
-	public void SetLoading(int percent) {
-		if(handler != null)
-			handler.obtainMessage(3, percent, 100).sendToTarget();
-	}
-	// Parcelable methods/constructors
-	private Gmsh(Parcel in) {
-		this.ptr = in.readLong();
-	}
-	public int describeContents() {return 0;}
-	public void writeToParcel(Parcel out, int flags) {
-		out.writeLong(this.ptr);
-	}
-	public static Parcelable.Creator<Gmsh> CREATOR = new Parcelable.Creator<Gmsh>() {
+    public boolean haveAnimation() {return numberOfAnimation() > 1;}
+    public native int numberOfAnimation();
+    public native int animationNext();
+    public native int animationPrev();
+    public native void setAnimation(int animation);
 
-		public Gmsh createFromParcel(Parcel source) {
-			return new Gmsh(source);
-		}
+    public static native String getAboutGmsh();
+    public static native String getAboutGetDP();
 
-		public Gmsh[] newArray(int size) {
-			return new Gmsh[size];
-		}
-	};
+    /** Java CLASS **/
+    private long ptr;
+    private Handler handler;
+    public Gmsh(Handler handler, float fontFactor)
+    {
+        ptr = this.init(fontFactor);
+        this.handler = handler;
+    }
+    public void viewInit(int w, int h)
+    {
+        this.initView(ptr, w, h);
+    }
+    public void viewDraw()
+    {
+        this.drawView(ptr);
+    }
+    public void load(String filename)
+    {
+        this.loadFile(ptr, filename);
+    }
+    public void startEvent(float x, float y)
+    {
+        this.eventHandler(ptr, 0, x, y);
+    }
+    public void translate(float x, float y)
+    {
+        this.eventHandler(ptr, 1, x, y);
+    }
+    public void scale(float s)
+    {
+        this.eventHandler(ptr, 2, s, 0);
+    }
+    public void rotate(float x, float y)
+    {
+        this.eventHandler(ptr, 3, x, y);
+    }
+    public void viewX() { this.eventHandler(ptr, 5, 0, 0);}
+    public void viewY() { this.eventHandler(ptr, 6, 0, 0);}
+    public void viewZ() { this.eventHandler(ptr, 7, 0, 0);}
+    public void endEvent(float x, float y)
+    {
+        this.eventHandler(ptr, 4, x, y);
+    }
+    public void resetPosition()
+    {
+        this.eventHandler(ptr, 10, 0, 0);
+    }
+    public void ShowPopup(String message) {
+        if(handler != null)
+            handler.obtainMessage(0, message).sendToTarget();
+    }
+    public void RequestRender() {
+        if(handler != null)
+            handler.obtainMessage(1).sendToTarget();
+    }
+    public void SetLoading(String message)
+    {
+        if(handler != null)
+            handler.obtainMessage(2, message).sendToTarget();
+    }
+    public void SetLoading(int percent)
+    {
+        if(handler != null)
+            handler.obtainMessage(3, percent, 100).sendToTarget();
+    }
+    // Parcelable methods/constructors
+    private Gmsh(Parcel in)
+    {
+        this.ptr = in.readLong();
+    }
+    public int describeContents() {return 0;}
+    public void writeToParcel(Parcel out, int flags)
+    {
+        out.writeLong(this.ptr);
+    }
+    public static Parcelable.Creator<Gmsh> CREATOR = new Parcelable.Creator<Gmsh>()
+    {
+        public Gmsh createFromParcel(Parcel source)
+        {
+            return new Gmsh(source);
+        }
+        public Gmsh[] newArray(int size)
+        {
+            return new Gmsh[size];
+        }
+    };
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java b/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java
index 96d67c0b64ca56f7ead0513cee0dd02d5db16780..43e8e06467ce27c01518d420c6599caf915b50df 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/MainActivity.java
@@ -33,70 +33,69 @@ import android.widget.Toast;
 
 public class MainActivity extends Activity{
 
-	private Gmsh _gmsh;
-	private boolean _compute, _twoPane, _notify;
-	private MenuItem _runStopMenuItem, _switchFragmentMenuItem;
-	private ModelFragment _modelFragment;
-	private OptionsFragment _optionsFragment;
-	private ArrayList<String> _errors = new ArrayList<String>();
-	private Dialog _errorDialog;
+    private Gmsh _gmsh;
+    private boolean _compute, _twoPane, _notify;
+    private MenuItem _runStopMenuItem, _switchFragmentMenuItem;
+    private ModelFragment _modelFragment;
+    private OptionsFragment _optionsFragment;
+    private ArrayList<String> _errors = new ArrayList<String>();
+    private Dialog _errorDialog;
 
-	public MainActivity() {
-	}
+    public MainActivity() { }
 
-	@Override
+    @Override
 	protected void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
-		getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
-		setContentView(R.layout.main_activity_layout);
-		_gmsh = new Gmsh(mainHandler, getResources().getDisplayMetrics().density);
-		_notify = false;
-		ActionBar actionBar = getActionBar();
-		actionBar.setDisplayHomeAsUpEnabled(true);
-		actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#64000000")));
-		Intent intent = getIntent();
+        super.onCreate(savedInstanceState);
+        getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN, WindowManager.LayoutParams.FLAG_FULLSCREEN);
+        getWindow().requestFeature(Window.FEATURE_ACTION_BAR_OVERLAY);
+        setContentView(R.layout.main_activity_layout);
+        _gmsh = new Gmsh(mainHandler, getResources().getDisplayMetrics().density);
+        _notify = false;
+        ActionBar actionBar = getActionBar();
+        actionBar.setDisplayHomeAsUpEnabled(true);
+        actionBar.setBackgroundDrawable(new ColorDrawable(Color.parseColor("#64000000")));
+        Intent intent = getIntent();
     	Bundle extras = intent.getExtras();
     	if(savedInstanceState != null);
     	else if(intent.getAction() != null && intent.getAction().equals(Intent.ACTION_VIEW)) {
-    		String tmp = intent.getData().getPath();
-    		_gmsh.load(tmp);
+            String tmp = intent.getData().getPath();
+            _gmsh.load(tmp);
     	}
     	else if(extras != null) {
-    		String name = extras.getString("name");
-    		this.getActionBar().setTitle(name);
-    		String tmp = extras.getString("file");
-    		_gmsh.load(tmp);
+            String name = extras.getString("name");
+            this.getActionBar().setTitle(name);
+            String tmp = extras.getString("file");
+            _gmsh.load(tmp);
     	}
     	else
-    		this.finish();
+            this.finish();
     	_twoPane = (findViewById(R.id.parameter_fragment) != null);
     	_modelFragment = ModelFragment.newInstance(_gmsh);
-		getFragmentManager().beginTransaction().replace(R.id.model_fragment, _modelFragment).commit();
+        getFragmentManager().beginTransaction().replace(R.id.model_fragment, _modelFragment).commit();
     	if(_twoPane) {
-    		_optionsFragment = OptionsFragment.newInstance(_gmsh);
-    		getFragmentManager().beginTransaction().replace(R.id.parameter_fragment, _optionsFragment).commit();
-    		_optionsFragment.setOnOptionsChangedListener(new OptionsFragment.OnOptionsChangedListener() {
+            _optionsFragment = OptionsFragment.newInstance(_gmsh);
+            getFragmentManager().beginTransaction().replace(R.id.parameter_fragment, _optionsFragment).commit();
+            _optionsFragment.setOnOptionsChangedListener(new OptionsFragment.OnOptionsChangedListener() {
 
-    			public void OnOptionsChanged() {
-    				_modelFragment.requestRender();
-    			}
+                    public void OnOptionsChanged() {
+                        _modelFragment.requestRender();
+                    }
     		});
     	}
-	}
+    }
 
-	@Override
+    @Override
 	protected void onSaveInstanceState(Bundle outState) {
-		outState.putBoolean("Compute", _compute);
-		super.onSaveInstanceState(outState);
-	}
+        outState.putBoolean("Compute", _compute);
+        super.onSaveInstanceState(outState);
+    }
 
-	@Override
-    public boolean onCreateOptionsMenu(Menu menu) {
+    @Override
+        public boolean onCreateOptionsMenu(Menu menu) {
     	super.onCreateOptionsMenu(menu);
     	if(!_twoPane) {
-    		_switchFragmentMenuItem = menu.add(R.string.menu_parameters);
-    		_switchFragmentMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
+            _switchFragmentMenuItem = menu.add(R.string.menu_parameters);
+            _switchFragmentMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_IF_ROOM);
     	}
     	_runStopMenuItem = menu.add((_compute)?R.string.menu_stop:R.string.menu_run);
     	_runStopMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
@@ -104,84 +103,84 @@ public class MainActivity extends Activity{
     	shareMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_NEVER);
         return true;
     }
-	@Override
+    @Override
 	public boolean onMenuOpened(int featureId, Menu menu) {
-		_modelFragment.postDelay();
-		return super.onMenuOpened(featureId, menu);
-	}
-	@Override
-    public boolean onMenuItemSelected(int featureId, MenuItem item) {
+        _modelFragment.postDelay();
+        return super.onMenuOpened(featureId, menu);
+    }
+    @Override
+        public boolean onMenuItemSelected(int featureId, MenuItem item) {
     	if (item.getTitle().equals(getString(R.string.menu_parameters))) {
-    		Intent intent = new Intent(this, OptionsActivity.class);
-		    intent.putExtra("Gmsh", (Parcelable)_gmsh);
-		    intent.putExtra("Compute", _compute);
-			startActivityForResult(intent, 1);
-			_modelFragment.requestRender();
+            Intent intent = new Intent(this, OptionsActivity.class);
+            intent.putExtra("Gmsh", (Parcelable)_gmsh);
+            intent.putExtra("Compute", _compute);
+            startActivityForResult(intent, 1);
+            _modelFragment.requestRender();
     	}
     	else if(item.getTitle().equals(getString(R.string.menu_run))){
-    		if(_modelFragment != null) _modelFragment.hideControlBar();
-    		new Run().execute();
+            if(_modelFragment != null) _modelFragment.hideControlBar();
+            new Run().execute();
     	}
     	else if(item.getTitle().equals(getString(R.string.menu_stop))){
-    		_runStopMenuItem.setEnabled(false);
-    		_gmsh.onelabCB("stop");
+            _runStopMenuItem.setEnabled(false);
+            _gmsh.onelabCB("stop");
     	}
     	else if(item.getTitle().equals(getString(R.string.menu_share))) {
-    		if(this._compute) {
-				AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
-    			_errorDialog = dialogBuilder.setTitle("Can't show the model list")
-    			.setMessage("The computation has to complete before you can take a screenshot")
-    			.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+            if(this._compute) {
+                AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
+                _errorDialog = dialogBuilder.setTitle("Can't show the model list")
+                    .setMessage("The computation has to complete before you can take a screenshot")
+                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
 
-					public void onClick(DialogInterface dialog, int which) {
-						dialog.dismiss();
-					}
-				})
-    			.show();
-    		}
-    		else {
-    			SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss");
-    			File file = new File(this.getExternalFilesDir(null), "onelab-screenshot-"+dateFormat.format(new Date())+".png");
-    			file.setReadable(true, false);
-    			_modelFragment.takeScreenshot(file);
-    			Intent shareIntent = new Intent();
-    			shareIntent.setAction(Intent.ACTION_SEND);
-    			shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
-    			shareIntent.setType("image/jpeg");
-    			startActivity(Intent.createChooser(shareIntent, getString(R.string.title_share)));
-    		}
+                            public void onClick(DialogInterface dialog, int which) {
+                                dialog.dismiss();
+                            }
+                        })
+                    .show();
+            }
+            else {
+                SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy_MM_dd-HH_mm_ss");
+                File file = new File(this.getExternalFilesDir(null), "onelab-screenshot-"+dateFormat.format(new Date())+".png");
+                file.setReadable(true, false);
+                _modelFragment.takeScreenshot(file);
+                Intent shareIntent = new Intent();
+                shareIntent.setAction(Intent.ACTION_SEND);
+                shareIntent.putExtra(Intent.EXTRA_STREAM, Uri.fromFile(file));
+                shareIntent.setType("image/jpeg");
+                startActivity(Intent.createChooser(shareIntent, getString(R.string.title_share)));
+            }
     	}
-		else if(item.getItemId() == android.R.id.home) {
-			if(this._compute) {
-				AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
-    			_errorDialog = dialogBuilder.setTitle("Can't show the model list")
-    			.setMessage("The computation has to complete before you can select another model")
-    			.setPositiveButton("OK", new DialogInterface.OnClickListener() {
+        else if(item.getItemId() == android.R.id.home) {
+            if(this._compute) {
+                AlertDialog.Builder dialogBuilder = new AlertDialog.Builder(this);
+                _errorDialog = dialogBuilder.setTitle("Can't show the model list")
+                    .setMessage("The computation has to complete before you can select another model")
+                    .setPositiveButton("OK", new DialogInterface.OnClickListener() {
 
-					public void onClick(DialogInterface dialog, int which) {
-						dialog.dismiss();
-					}
-				})
-    			.show();
-    		}
-    		else
-    			this.finish();
-		}
+                            public void onClick(DialogInterface dialog, int which) {
+                                dialog.dismiss();
+                            }
+                        })
+                    .show();
+            }
+            else
+                this.finish();
+        }
     	return super.onMenuItemSelected(featureId, item);
     }
 
-	@Override
+    @Override
 	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
-		super.onActivityResult(requestCode, resultCode, data);
-		switch (requestCode) {
-		case 1:
-			if(resultCode == RESULT_OK)
-				if(!_compute && data.getBooleanExtra("Compute", false)) new Run().execute();
-			break;
-		}
-	}
+        super.onActivityResult(requestCode, resultCode, data);
+        switch (requestCode) {
+        case 1:
+            if(resultCode == RESULT_OK)
+                if(!_compute && data.getBooleanExtra("Compute", false)) new Run().execute();
+            break;
+        }
+    }
 
-	public String getRealPathFromURI(Uri contentUri) {
+    public String getRealPathFromURI(Uri contentUri) {
         String[] proj = { MediaStore.Images.Media.DATA };
         Cursor cursor = managedQuery(contentUri, proj, null, null, null);
         int column_index = cursor.getColumnIndexOrThrow(MediaStore.Images.Media.DATA);
@@ -189,11 +188,11 @@ public class MainActivity extends Activity{
         return cursor.getString(column_index);
     }
 
-	private class Run extends AsyncTask<Void, Void, Integer[]> {
+    private class Run extends AsyncTask<Void, Void, Integer[]> {
 
     	@Override
-    	protected void onPreExecute() {
-    		_compute = true;
+            protected void onPreExecute() {
+            _compute = true;
     		_runStopMenuItem.setTitle(R.string.menu_stop);
     		super.onPreExecute();
     	}
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Model.java b/contrib/mobile/Android/src/org/geuz/onelab/Model.java
index a25da783b58922211ae3170efb6374b4fa712982..42419e35ac680d6fb0f43920af520c2d19d82911 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/Model.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/Model.java
@@ -6,42 +6,41 @@ import android.net.Uri;
 import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 
-
 class Model {
-	private String _name, _summary;
-	private File _file;
-	private Bitmap _bitmap;
-	private Uri _url;
-	
-	public Model(String name, String summary, File file){
-		_name = name;
-		_summary = summary;
-		_file = file;
-	}
-	public String getName() {
-		return _name;
-	}
-	public String getSummary() {
-		return _summary;
-	}
-	public File getFile() {
-		return _file;
-	}
-	public Bitmap getBitmap() {
-		return _bitmap;
-	}
-	public Uri getUrl() {
-		return _url;
-	}
-	public void setBitmap(File f) {
-		BitmapFactory.Options options = new BitmapFactory.Options();
-		options.inSampleSize = 8;
-		options.inJustDecodeBounds = false;
-		options.inPreferredConfig = Bitmap.Config.RGB_565;
-		options.inDither = true;
-		_bitmap = BitmapFactory.decodeFile(f.toString(), options);
-	}
-	public void setUrl(Uri url) {
-		_url = url;
-	}
+    private String _name, _summary;
+    private File _file;
+    private Bitmap _bitmap;
+    private Uri _url;
+
+    public Model(String name, String summary, File file){
+        _name = name;
+        _summary = summary;
+        _file = file;
+    }
+    public String getName() {
+        return _name;
+    }
+    public String getSummary() {
+        return _summary;
+    }
+    public File getFile() {
+        return _file;
+    }
+    public Bitmap getBitmap() {
+        return _bitmap;
+    }
+    public Uri getUrl() {
+        return _url;
+    }
+    public void setBitmap(File f) {
+        BitmapFactory.Options options = new BitmapFactory.Options();
+        options.inSampleSize = 8;
+        options.inJustDecodeBounds = false;
+        options.inPreferredConfig = Bitmap.Config.RGB_565;
+        options.inDither = true;
+        _bitmap = BitmapFactory.decodeFile(f.toString(), options);
+    }
+    public void setUrl(Uri url) {
+        _url = url;
+    }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java b/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java
index 707bc2421f1fe9525e58d375ac5af9b50c5effa2..e3112a3235d4cabd0437161837d95d6d551ee3c1 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/ModelFragment.java
@@ -29,219 +29,220 @@ import android.widget.TextView;
 
 public class ModelFragment extends Fragment{
 
-	private Gmsh _gmsh;
-	private mGLSurfaceView _glView;
-	private TextView _progress;
-	private LinearLayout _progressLayout;
-	private LinearLayout _controlBarLayout;
-	private GestureDetector _gestureDetector;
-	private Timer _animation;
-	private Handler _hideDelay;
-	private SeekBar _animationStepper;
+    private Gmsh _gmsh;
+    private mGLSurfaceView _glView;
+    private TextView _progress;
+    private LinearLayout _progressLayout;
+    private LinearLayout _controlBarLayout;
+    private GestureDetector _gestureDetector;
+    private Timer _animation;
+    private Handler _hideDelay;
+    private SeekBar _animationStepper;
 
-	final Runnable hideControlsRunnable = new Runnable() {public void run() {hideControlBar();}};
+    final Runnable hideControlsRunnable = new Runnable() {
+            public void run() {hideControlBar();}
+        };
 
-	public static ModelFragment newInstance(Gmsh g) {
-		ModelFragment fragment = new ModelFragment();
-		Bundle bundle = new Bundle();
-		bundle.putParcelable("Gmsh", g);
-		fragment.setArguments(bundle);
-		return fragment;
-	}
-	
-	public ModelFragment() {
-	}
+    public static ModelFragment newInstance(Gmsh g) {
+        ModelFragment fragment = new ModelFragment();
+        Bundle bundle = new Bundle();
+        bundle.putParcelable("Gmsh", g);
+        fragment.setArguments(bundle);
+        return fragment;
+    }
 
-	@Override
+    public ModelFragment() {
+    }
+
+    @Override
 	public void onCreate(Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		_gmsh = getArguments().getParcelable("Gmsh");
-	}
+        super.onCreate(savedInstanceState);
+        _gmsh = getArguments().getParcelable("Gmsh");
+    }
 
-	@Override
+    @Override
 	public View onCreateView(LayoutInflater inflater, ViewGroup container,
-			Bundle savedInstanceState) {
-		View rootView = inflater.inflate(R.layout.fragment_model, container, false);
-		RelativeLayout glViewLayout = (RelativeLayout)rootView.findViewById(R.id.glViewLayout);
-		GLESRender renderer = new GLESRender(_gmsh);
-		_glView = new mGLSurfaceView(glViewLayout.getContext(), renderer);
-		_glView.setEGLContextClientVersion(1);
-		_glView.setRenderer(renderer);
-		_glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
-		_glView.requestRender();
-		_hideDelay = new Handler();
-		_gestureDetector = new GestureDetector(getActivity(), new OnGestureListener() {
-			public boolean onSingleTapUp(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
-			public void onShowPress(MotionEvent e) {} // UNUSED Auto-generated method stub
-			public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } // UNUSED Auto-generated method stub
-			public void onLongPress(MotionEvent e) {} // UNUSED Auto-generated method stub
-			public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } // UNUSED Auto-generated method stub
-			public boolean onDown(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
-		});
-		_gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
-			public boolean onSingleTapConfirmed(MotionEvent e) {
-				if(View.VISIBLE == _controlBarLayout.getVisibility())
-					hideControlBar();
-				else
-					showControlBar();
-				return true;
-			}
-			public boolean onDoubleTapEvent(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
-			public boolean onDoubleTap(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
-		});
-		_glView.setOnTouchListener(new View.OnTouchListener() {
-			
-			public boolean onTouch(View v, MotionEvent event) {
-				return _gestureDetector.onTouchEvent(event);
-			}
-		});
-		glViewLayout.addView(_glView);
-		RelativeLayout topRightLayout = new RelativeLayout(container.getContext());
-		ImageButton rotationButton = new ImageButton(container.getContext());
-		rotationButton.setBackgroundResource(R.drawable.icon_rotate);
-		rotationButton.setLayoutParams(new LinearLayout.LayoutParams(50, 50));
-		rotationButton.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				boolean rotate = !_glView.getRotate();
-				((ImageButton)v).setBackgroundResource((rotate)?R.drawable.icon_translate:R.drawable.icon_rotate);
-				_glView.setRotate(rotate);
-			}
-		});
-		topRightLayout.addView(rotationButton);
-		RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams(
-			    RelativeLayout.LayoutParams.WRAP_CONTENT, 
-			    RelativeLayout.LayoutParams.WRAP_CONTENT);
-		layoutParams.setMargins(0, 100, 10, 0);
-		layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
-		layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
-		glViewLayout.addView(topRightLayout, layoutParams);
-		_progressLayout = new LinearLayout(container.getContext());
-		ProgressBar bar = new ProgressBar(container.getContext());
-		bar.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				_progress.setAlpha((_progress.getAlpha() > 0)? 0 : 1);
-			}
-		});
-		_progressLayout.addView(bar);
-		_progress = new TextView(container.getContext());
-		_progressLayout.setAlpha(0);
-		_progressLayout.setGravity(Gravity.CENTER);
-		_progressLayout.addView(_progress);
-		layoutParams = new RelativeLayout.LayoutParams(
-			    RelativeLayout.LayoutParams.WRAP_CONTENT, 
-			    RelativeLayout.LayoutParams.WRAP_CONTENT);
-		layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-		glViewLayout.addView(_progressLayout, layoutParams);
-		_controlBarLayout = (LinearLayout) getActivity().getLayoutInflater().inflate(R.layout.control_bar, null);
-		final ImageButton prevButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPrev);
-		final ImageButton playPauseButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPlay);
-		final ImageButton nextButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlNext);
-		_animationStepper = (SeekBar)_controlBarLayout.findViewById(R.id.controlStepper);
-		_animationStepper.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-			
-			public void onStopTrackingTouch(SeekBar seekBar) {} // UNUSED Auto-generated method stub
-			public void onStartTrackingTouch(SeekBar seekBar) {} // UNUSED Auto-generated method stub
-			public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
-				if(fromUser) {
-					postDelay();
-					_gmsh.setAnimation(progress);
-					requestRender();
-				}
-			}
-		});
-		_controlBarLayout.setEnabled(false);
-		playPauseButton.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				postDelay();
-				if(((ImageButton)v).getContentDescription().equals("play")) {
-					((ImageButton)v).setContentDescription("pause");
-					((ImageButton)v).setImageResource(android.R.drawable.ic_media_pause);
-					_animationStepper.setMax(_gmsh.numberOfAnimation()-1);
-		    		_animation = new Timer();
-		    		_animation.schedule(new TimerTask() {
-		    			public void run()  {
-		    				_animationStepper.setProgress(_gmsh.animationNext());
-		    				requestRender();
-		    			} }, 0, 500);
-		    		prevButton.setEnabled(false);
-		    		nextButton.setEnabled(false);
-				}
-				else {
-					((ImageButton)v).setContentDescription("play");
-					((ImageButton)v).setImageResource(android.R.drawable.ic_media_play);
-					_animation.cancel();
-					prevButton.setEnabled(true);
-					nextButton.setEnabled(true);
-				}
-			}
-		});
-		nextButton.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				postDelay();
-				_animationStepper.setProgress(_gmsh.animationNext());
-		    	requestRender();
-			}
-		});
-		prevButton.setOnClickListener(new View.OnClickListener() {
-			public void onClick(View v) {
-				postDelay();
-				_animationStepper.setProgress(_gmsh.animationPrev());
-		    	requestRender();
-			}
-		});
-		layoutParams = new RelativeLayout.LayoutParams(
-			    RelativeLayout.LayoutParams.MATCH_PARENT, 
-			    RelativeLayout.LayoutParams.WRAP_CONTENT);
-		layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
-		glViewLayout.addView(_controlBarLayout, layoutParams);
-		this._controlBarLayout.setVisibility(View.INVISIBLE);
-		return rootView;
-	}
-	public void postDelay(int delay) {
-		_hideDelay.removeCallbacks(hideControlsRunnable);
-		_hideDelay.postDelayed(hideControlsRunnable, delay);
-	}
-	public void postDelay() {
-		this.postDelay(6000);
-	}
-	public void showControlBar() {
-		if(getActivity() == null || ((MainActivity)getActivity()).isComputing() || !_gmsh.haveAnimation()) return;
-		_controlBarLayout.setEnabled(true);
-		_animationStepper.setMax(_gmsh.numberOfAnimation()-1);
-		this.postDelay();
-		Animation bottomUp = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
-		_controlBarLayout.setVisibility(View.VISIBLE);
-		_controlBarLayout.startAnimation(bottomUp);
-	}
-	public void hideControlBar() {
-		if(getActivity() == null || View.INVISIBLE == _controlBarLayout.getVisibility()) return;
-		_hideDelay.removeCallbacks(hideControlsRunnable);
-		Animation bottomDown = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
-		_controlBarLayout.startAnimation(bottomDown);
-		_controlBarLayout.setVisibility(View.INVISIBLE);
-		
-	}
-	public void showProgress(String progress) {
-		_progressLayout.setAlpha(1);
-		_progress.setText(progress);
-	}
-	public void hideProgress() {
-		_progressLayout.setAlpha(0);
-		_progress.setText("");
-	}
-	public void requestRender() {
-		_glView.requestRender();
-	}
-	public void takeScreenshot(File out) {
-		Bitmap screenshot = _glView.getScreenshot();
-		try {
-			FileOutputStream f = new FileOutputStream(out);
-			screenshot.compress(Bitmap.CompressFormat.PNG, 85, f);
-		} catch (FileNotFoundException e) {
-			e.printStackTrace();
-		}
-		finally {
-			_glView.setDrawingCacheEnabled(false);
-		}
-	}
+                                 Bundle savedInstanceState) {
+        View rootView = inflater.inflate(R.layout.fragment_model, container, false);
+        RelativeLayout glViewLayout = (RelativeLayout)rootView.findViewById(R.id.glViewLayout);
+        GLESRender renderer = new GLESRender(_gmsh);
+        _glView = new mGLSurfaceView(glViewLayout.getContext(), renderer);
+        _glView.setEGLContextClientVersion(1);
+        _glView.setRenderer(renderer);
+        _glView.setRenderMode(GLSurfaceView.RENDERMODE_WHEN_DIRTY);
+        _glView.requestRender();
+        _hideDelay = new Handler();
+        _gestureDetector = new GestureDetector(getActivity(), new OnGestureListener() {
+                public boolean onSingleTapUp(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
+                public void onShowPress(MotionEvent e) {} // UNUSED Auto-generated method stub
+                public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY) { return false; } // UNUSED Auto-generated method stub
+                public void onLongPress(MotionEvent e) {} // UNUSED Auto-generated method stub
+                public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY) { return false; } // UNUSED Auto-generated method stub
+                public boolean onDown(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
+            });
+        _gestureDetector.setOnDoubleTapListener(new GestureDetector.OnDoubleTapListener() {
+                public boolean onSingleTapConfirmed(MotionEvent e) {
+                    if(View.VISIBLE == _controlBarLayout.getVisibility())
+                        hideControlBar();
+                    else
+                        showControlBar();
+                    return true;
+                }
+                public boolean onDoubleTapEvent(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
+                public boolean onDoubleTap(MotionEvent e) { return false; } // UNUSED Auto-generated method stub
+            });
+        _glView.setOnTouchListener(new View.OnTouchListener() {
+
+                public boolean onTouch(View v, MotionEvent event) {
+                    return _gestureDetector.onTouchEvent(event);
+                }
+            });
+        glViewLayout.addView(_glView);
+        RelativeLayout topRightLayout = new RelativeLayout(container.getContext());
+        ImageButton rotationButton = new ImageButton(container.getContext());
+        rotationButton.setBackgroundResource(R.drawable.icon_rotate);
+        rotationButton.setLayoutParams(new LinearLayout.LayoutParams(65, 65));
+        rotationButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    boolean rotate = !_glView.getRotate();
+                    ((ImageButton)v).setBackgroundResource((rotate)?R.drawable.icon_translate:R.drawable.icon_rotate);
+                    _glView.setRotate(rotate);
+                }
+            });
+        topRightLayout.addView(rotationButton);
+        RelativeLayout.LayoutParams layoutParams = new RelativeLayout.LayoutParams
+            (RelativeLayout.LayoutParams.WRAP_CONTENT, RelativeLayout.LayoutParams.WRAP_CONTENT);
+        layoutParams.setMargins(20, 140, 20, 0);
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_TOP);
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_RIGHT);
+        glViewLayout.addView(topRightLayout, layoutParams);
+        _progressLayout = new LinearLayout(container.getContext());
+        ProgressBar bar = new ProgressBar(container.getContext());
+        bar.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    _progress.setAlpha((_progress.getAlpha() > 0) ? 0 : 1);
+                }
+            });
+        _progressLayout.addView(bar);
+        _progress = new TextView(container.getContext());
+        _progressLayout.setAlpha(0);
+        _progressLayout.setGravity(Gravity.CENTER);
+        _progressLayout.addView(_progress);
+        layoutParams = new RelativeLayout.LayoutParams
+            (RelativeLayout.LayoutParams.WRAP_CONTENT,
+             RelativeLayout.LayoutParams.WRAP_CONTENT);
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+        glViewLayout.addView(_progressLayout, layoutParams);
+        _controlBarLayout = (LinearLayout) getActivity().getLayoutInflater().inflate(R.layout.control_bar, null);
+        final ImageButton prevButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPrev);
+        final ImageButton playPauseButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlPlay);
+        final ImageButton nextButton = (ImageButton)_controlBarLayout.findViewById(R.id.controlNext);
+        _animationStepper = (SeekBar)_controlBarLayout.findViewById(R.id.controlStepper);
+        _animationStepper.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+
+                public void onStopTrackingTouch(SeekBar seekBar) {} // UNUSED Auto-generated method stub
+                public void onStartTrackingTouch(SeekBar seekBar) {} // UNUSED Auto-generated method stub
+                public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {
+                    if(fromUser) {
+                        postDelay();
+                        _gmsh.setAnimation(progress);
+                        requestRender();
+                    }
+                }
+            });
+        _controlBarLayout.setEnabled(false);
+        playPauseButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    postDelay();
+                    if(((ImageButton)v).getContentDescription().equals("play")) {
+                        ((ImageButton)v).setContentDescription("pause");
+                        ((ImageButton)v).setImageResource(android.R.drawable.ic_media_pause);
+                        _animationStepper.setMax(_gmsh.numberOfAnimation()-1);
+                        _animation = new Timer();
+                        _animation.schedule(new TimerTask() {
+                                public void run()  {
+                                    _animationStepper.setProgress(_gmsh.animationNext());
+                                    requestRender();
+                                } }, 0, 500);
+                        prevButton.setEnabled(false);
+                        nextButton.setEnabled(false);
+                    }
+                    else {
+                        ((ImageButton)v).setContentDescription("play");
+                        ((ImageButton)v).setImageResource(android.R.drawable.ic_media_play);
+                        _animation.cancel();
+                        prevButton.setEnabled(true);
+                        nextButton.setEnabled(true);
+                    }
+                }
+            });
+        nextButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    postDelay();
+                    _animationStepper.setProgress(_gmsh.animationNext());
+                    requestRender();
+                }
+            });
+        prevButton.setOnClickListener(new View.OnClickListener() {
+                public void onClick(View v) {
+                    postDelay();
+                    _animationStepper.setProgress(_gmsh.animationPrev());
+                    requestRender();
+                }
+            });
+        layoutParams = new RelativeLayout.LayoutParams(
+                                                       RelativeLayout.LayoutParams.MATCH_PARENT,
+                                                       RelativeLayout.LayoutParams.WRAP_CONTENT);
+        layoutParams.addRule(RelativeLayout.ALIGN_PARENT_BOTTOM);
+        glViewLayout.addView(_controlBarLayout, layoutParams);
+        this._controlBarLayout.setVisibility(View.INVISIBLE);
+        return rootView;
+    }
+    public void postDelay(int delay) {
+        _hideDelay.removeCallbacks(hideControlsRunnable);
+        _hideDelay.postDelayed(hideControlsRunnable, delay);
+    }
+    public void postDelay() {
+        this.postDelay(6000);
+    }
+    public void showControlBar() {
+        if(getActivity() == null || ((MainActivity)getActivity()).isComputing() || !_gmsh.haveAnimation()) return;
+        _controlBarLayout.setEnabled(true);
+        _animationStepper.setMax(_gmsh.numberOfAnimation()-1);
+        this.postDelay();
+        Animation bottomUp = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_in);
+        _controlBarLayout.setVisibility(View.VISIBLE);
+        _controlBarLayout.startAnimation(bottomUp);
+    }
+    public void hideControlBar() {
+        if(getActivity() == null || View.INVISIBLE == _controlBarLayout.getVisibility()) return;
+        _hideDelay.removeCallbacks(hideControlsRunnable);
+        Animation bottomDown = AnimationUtils.loadAnimation(getActivity(), android.R.anim.fade_out);
+        _controlBarLayout.startAnimation(bottomDown);
+        _controlBarLayout.setVisibility(View.INVISIBLE);
+
+    }
+    public void showProgress(String progress) {
+        _progressLayout.setAlpha(1);
+        _progress.setText(progress);
+    }
+    public void hideProgress() {
+        _progressLayout.setAlpha(0);
+        _progress.setText("");
+    }
+    public void requestRender() {
+        _glView.requestRender();
+    }
+    public void takeScreenshot(File out) {
+        Bitmap screenshot = _glView.getScreenshot();
+        try {
+            FileOutputStream f = new FileOutputStream(out);
+            screenshot.compress(Bitmap.CompressFormat.PNG, 85, f);
+        } catch (FileNotFoundException e) {
+            e.printStackTrace();
+        }
+        finally {
+            _glView.setDrawingCacheEnabled(false);
+        }
+    }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/OptionsActivity.java b/contrib/mobile/Android/src/org/geuz/onelab/OptionsActivity.java
index 73e3f349d8af946c9d2d6607a7baf388ecd41139..ecac78244098a2e2dc566b7c061684fb23ba45a3 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/OptionsActivity.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/OptionsActivity.java
@@ -9,7 +9,7 @@ import android.view.WindowManager;
 
 public class OptionsActivity extends Activity {
 
-	boolean _compute;
+    boolean _compute;
 
 	@Override
 	protected void onCreate(Bundle savedInstanceState) {
@@ -24,28 +24,28 @@ public class OptionsActivity extends Activity {
 		OptionsFragment optionsFragment = OptionsFragment.newInstance(gmsh);
 		getFragmentManager().beginTransaction().replace(R.id.model_fragment, optionsFragment).commit();
 	}
-	
+
 	@Override
 	public boolean onCreateOptionsMenu(Menu menu) {
 		if(_compute) return super.onCreateOptionsMenu(menu);
 		MenuItem runStopMenuItem = menu.add(R.string.menu_run);
-    	runStopMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
+                runStopMenuItem.setShowAsAction(MenuItem.SHOW_AS_ACTION_ALWAYS);
 		return super.onCreateOptionsMenu(menu);
 	}
 
 	@Override
 	public boolean onMenuItemSelected(int featureId, MenuItem item) {
-		if(item.getTitle().equals(getString(R.string.menu_run))) {
-			Intent returnIntent = new Intent();
-			returnIntent.putExtra("Compute", true);
-			this.setResult(RESULT_OK, returnIntent);     
-			this.finish();
-		}
-		else if(item.getItemId() == android.R.id.home) {
-			Intent returnIntent = new Intent();
-			this.setResult(RESULT_CANCELED, returnIntent);
-			this.finish();
-		}
-		return super.onMenuItemSelected(featureId, item);
+            if(item.getTitle().equals(getString(R.string.menu_run))) {
+                Intent returnIntent = new Intent();
+                returnIntent.putExtra("Compute", true);
+                this.setResult(RESULT_OK, returnIntent);
+                this.finish();
+            }
+            else if(item.getItemId() == android.R.id.home) {
+                Intent returnIntent = new Intent();
+                this.setResult(RESULT_CANCELED, returnIntent);
+                this.finish();
+            }
+            return super.onMenuItemSelected(featureId, item);
 	}
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java b/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java
index ebe59cc058c8d5293ee1f641dc550ea47bb6fa49..dae90a439ec5d32d0b4537e0550caa4c3c90fb12 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/Parameter.java
@@ -7,81 +7,81 @@ import android.widget.TextView;
 
 
 public class Parameter {
-	protected Context _context;
-	protected Gmsh _gmsh;
-	protected String _name;
-	protected String _label;
-	protected boolean _readOnly;
-	protected boolean _changed;
-	protected TextView _title;
+    protected Context _context;
+    protected Gmsh _gmsh;
+    protected String _name;
+    protected String _label;
+    protected boolean _readOnly;
+    protected boolean _changed;
+    protected TextView _title;
 
-	public Parameter(Context context, Gmsh gmsh, String name){
-		_context = context;
-		_gmsh = gmsh;
-		_readOnly = false;
-		_name = name;
-		_title = new TextView(context);
-		_title.setText(name);
-		_title.setTextAppearance(context, android.R.style.TextAppearance_DeviceDefault_Medium);
-		_title.setTextColor(Color.DKGRAY);
-	}
-	public Parameter(Context context, Gmsh gmsh, String name, boolean readOnly){
-		this(context, gmsh, name);
-		_readOnly = readOnly;
-		_changed = false;
-	}
+    public Parameter(Context context, Gmsh gmsh, String name){
+        _context = context;
+        _gmsh = gmsh;
+        _readOnly = false;
+        _name = name;
+        _title = new TextView(context);
+        _title.setText(name);
+        _title.setTextAppearance(context, android.R.style.TextAppearance_DeviceDefault_Medium);
+        _title.setTextColor(Color.DKGRAY);
+    }
+    public Parameter(Context context, Gmsh gmsh, String name, boolean readOnly){
+        this(context, gmsh, name);
+        _readOnly = readOnly;
+        _changed = false;
+    }
 
-	protected void update(){
-		if(_label != null && !_label.equals(""))
-			_title.setText(_label);
-		else
-			_title.setText(getShortName());
-		if(isReadOnly()) _title.setAlpha(0.423f);
-	}
+    protected void update(){
+        if(_label != null && !_label.equals(""))
+            _title.setText(_label);
+        else
+            _title.setText(getShortName());
+        if(isReadOnly()) _title.setAlpha(0.423f);
+    }
 
-	public void setName(String name) {_name = name;this.update();}
-	public void setReadOnly(boolean readOnly) {_readOnly = readOnly;this.update();}
-	public void setLabel(String label) {
-		_label = label;
-		this.update();
-	}
-	public String getName() { return _name;}
-	public String getShortName() {
-		if(_label != null && _label.length() > 0) return _label;
-		String[] splited = _name.split("/");
-		String name = splited[splited.length-1];
-		while(name.length() > 0 && name.charAt(0) >= '0' && name.charAt(0) <= '9')
-			name = name.substring(1);
-		return name;
-	}
-	public boolean isReadOnly() {return _readOnly;}
-	public String getLabel() {return _label;}
-	public int fromString(String s){
-		String[] infos = s.split(Character.toString((char)0x03));
-		int pos=0;
-		pos++;// version
-		pos++;// type
-		setName(infos[pos++]);// name
-		setLabel(infos[pos++]);// label
-		pos++;// help
-		pos++;// never change
-		if(Integer.parseInt(infos[pos++]) != 1)return -1;// visible
-		this.setReadOnly((infos[pos++].equals("1")));// read only
-		int nAttributes = Integer.parseInt(infos[pos++]);// number of attributes
-		pos+=(nAttributes*2);// key+value
-		int nClients = Integer.parseInt(infos[pos++]);// number of client
-		pos+=(nClients*2);// client+changed
-		this.update();
-		return pos;
-	}
-	public boolean changed() { if(_changed){_changed=false; return true;}return _changed;}
-	public String getType(){return "Parameter";}
+    public void setName(String name) {_name = name;this.update();}
+    public void setReadOnly(boolean readOnly) {_readOnly = readOnly;this.update();}
+    public void setLabel(String label) {
+        _label = label;
+        this.update();
+    }
+    public String getName() { return _name;}
+    public String getShortName() {
+        if(_label != null && _label.length() > 0) return _label;
+        String[] splited = _name.split("/");
+        String name = splited[splited.length-1];
+        while(name.length() > 0 && name.charAt(0) >= '0' && name.charAt(0) <= '9')
+            name = name.substring(1);
+        return name;
+    }
+    public boolean isReadOnly() {return _readOnly;}
+    public String getLabel() {return _label;}
+    public int fromString(String s){
+        String[] infos = s.split(Character.toString((char)0x03));
+        int pos=0;
+        pos++;// version
+        pos++;// type
+        setName(infos[pos++]);// name
+        setLabel(infos[pos++]);// label
+        pos++;// help
+        pos++;// never change
+        if(Integer.parseInt(infos[pos++]) != 1)return -1;// visible
+        this.setReadOnly((infos[pos++].equals("1")));// read only
+        int nAttributes = Integer.parseInt(infos[pos++]);// number of attributes
+        pos+=(nAttributes*2);// key+value
+        int nClients = Integer.parseInt(infos[pos++]);// number of client
+        pos+=(nClients*2);// client+changed
+        this.update();
+        return pos;
+    }
+    public boolean changed() { if(_changed){_changed=false; return true;}return _changed;}
+    public String getType(){return "Parameter";}
 
-	public LinearLayout getView() {
-		LinearLayout paramLayout = new LinearLayout(_context);
-		paramLayout.setOrientation(LinearLayout.VERTICAL);
-		paramLayout.addView(_title);
-		return paramLayout;
-	}
+    public LinearLayout getView() {
+        LinearLayout paramLayout = new LinearLayout(_context);
+        paramLayout.setOrientation(LinearLayout.VERTICAL);
+        paramLayout.addView(_title);
+        return paramLayout;
+    }
 }
 
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java b/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java
index 379f2b1835ca76ac4d8b4f817a435e4fcba38c6b..2d1fc9f2dc190ddbe55ad5e23dce3f913b4a5b9c 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/ParameterNumber.java
@@ -19,245 +19,248 @@ import android.widget.SeekBar;
 import android.widget.Spinner;
 
 public class ParameterNumber extends Parameter{
-	private double _value, _min, _max, _step;
-	private SeekBar _bar;
-	private ArrayList<Double> _values;
-	private ArrayList<String> _choices;
-	private ArrayAdapter<String> _adapter;
-	private Spinner _spinner;
-	private CheckBox _checkbox;
-	private EditText _edittext;
-	private Stepper _stepper;
-	
-	public ParameterNumber(Context context, Gmsh gmsh, String name){
-		super(context, gmsh, name);
-	}
-	public ParameterNumber(Context context, Gmsh gmsh, String name,  double value, double min, double max, double step)
-	{
-		this(context, gmsh, name);
-		_value = value;
-		_min = min;
-		_max = max;
-		_step = step;
-	}
-	public ParameterNumber(Context context, Gmsh gmsh, String name, boolean readOnly, double value, double min, double max, double step)
-	{
-		this(context, gmsh, name, value, min, max, step);
-		_readOnly = readOnly;
-	}
-	
-	protected void update(){
-		super.update();
-		int nDecimal = String.valueOf(_min).length() - String.valueOf(_min).lastIndexOf('.') - 1; // hack for double round
-		if(_bar != null) {
-			DecimalFormat df = new DecimalFormat ( ) ;
-			df.setMaximumFractionDigits(nDecimal) ;
-			_title.setText(getShortName() + " (" + df.format(_value)+ ")");
-			_bar.setMax(100);
-			_bar.setProgress((int)(100*(_value-_min)/(_max-_min)));
-			_bar.setEnabled(!this.isReadOnly());
-		}
-		else if(_spinner != null)
-		{
-			for(int i=0;i<_choices.size();i++)
-				if(_values.get(i) == _value)
-					_spinner.setSelection(i, true);
-		}
-		else if(_checkbox != null)
-		{
-			_checkbox.setText(getShortName());
-			_checkbox.setChecked((_value == 0)? false : true);
-		}
-		else if(_edittext != null)
-		{
-			_edittext.setText(""+Math.round(_value*Math.pow(10, nDecimal))/Math.pow(10, nDecimal));
-		}
-		else if(_stepper != null)
-		{
-			_stepper.setMaximum((int)Math.round(_max));
-			_stepper.setMinimum((int)Math.round(_min));
-			_stepper.setValue((int)Math.round(_value));
-		}
-	}
-	
-	public void setValue(double value) {
-		if(value < _min || value > _max) {
-			//Log.w("ParameterNumber", "Incorect value "+value+" (max="+_max+" min="+_min+")");
-			return;
-		}
-		if(value == _value) return;
-		_value = value;
-		_changed = true;
-		_gmsh.setParam(getType(), getName(), String.valueOf(value));
-		if(mListener != null) mListener.OnParameterChanged();
-	}
-	public void setMin(double min) {_min = min;this.update();}
-	public void setMax(double max) {_max = max;this.update();}
-	public void setStep(double step) {_step = step;this.update();}
-	public void addChoice(double choice, String value) {
-		if(_values == null) {
-			_values = new ArrayList<Double>();
-			_choices = new ArrayList<String>();
-			_values.add(choice);
-			_choices.add(value);
-			if(_spinner == null) {
-				_spinner = new Spinner(_context);
-				_adapter = new ArrayAdapter<String>(_context, android.R.layout.simple_spinner_dropdown_item, _choices);
-				_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-				_spinner.setAdapter(_adapter);
-			}
-		}
-		else
-		{
-			for(int i=0;i<_values.size();i++) {
-				if(_values.get(i).equals(choice) && _choices.size() > i) {
-					_choices.set(i, value);
-					return;
-				}
-				else if(_values.get(i).equals(choice))
-				{
-					_choices.add(value);
-					return;
-				}
-			}
-			_values.add(choice);
-			_choices.add(value);
-		}
-	}
-	public double getValue() {return _value;}
-	public double getMax() {return _max;}
-	public double getMin() {return _min;}
-	public double getStep() {return _step;}
-	public int fromString(String s){
-		int pos = super.fromString(s);
-		if(pos <= 0) return -1; // error
-		String[] infos = s.split(Character.toString((char)0x03));
-		String tmpVal = infos[pos++];
-		if(tmpVal.equals("Inf")) // TODO set value to max ???
-			_value = 1;
-		else
-			_value = Double.parseDouble(tmpVal);
-		this.setMin(Double.parseDouble(infos[pos++]));
-		this.setMax(Double.parseDouble(infos[pos++]));
-		this.setStep(Double.parseDouble(infos[pos++]));
-		pos++;// index
-		int nChoix = Integer.parseInt(infos[pos++]); // choices' size
-		double choices[] = new double[nChoix];
-		for(int i=0; i<nChoix; i++)
-				choices[i] = Double.parseDouble(infos[pos++]); // choice
-		int nLabels = Integer.parseInt(infos[pos++]); // labels' size
-		if(nChoix == 2 && choices[0] == 0 && choices[1] == 1 && nLabels == 0) {
-			_checkbox = new CheckBox(_context);
-			this.update();
-			return pos;
-		}
-		if(_choices != null)_choices.clear();
-		if(_values != null) _values.clear();
-		for(int i=0; i<nLabels && nChoix == nLabels; i++)
-		{
-			double val = Double.parseDouble(infos[pos++]); // choice
-			this.addChoice(val, infos[pos++]); // label
-		}
-		// ...
-		if(nLabels < 1 && _step == 0)
-			_edittext = new EditText(_context);
-		else if(_step == 1)
-			_stepper = new Stepper(_context);
-		else if(nLabels < 1)
-			_bar = new SeekBar(_context);
-		this.update();
-		return pos;
-	}
-	public String getType(){return "ParameterNumber";}
-	public LinearLayout getView(){
-		LinearLayout paramLayout = new LinearLayout(_context);
-		paramLayout.setOrientation(LinearLayout.VERTICAL);
-		paramLayout.addView(_title);
-		if(_spinner != null) {
-			paramLayout.addView(_spinner);
-			_spinner.setEnabled(!_readOnly);
-			_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-				public void onNothingSelected(AdapterView<?> arg0) {}
-				public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
-					setValue(_values.get(pos));
-				}
-			});
-		}
-		else if(_bar != null) {
-			paramLayout.addView(_bar);
-			_bar.setEnabled(!_readOnly);
-			_bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
-				public void onStopTrackingTouch(SeekBar seekBar) {
-					setValue(getMin() + (getMax() - getMin())*seekBar.getProgress()/100);
-				}
-				
-				public void onStartTrackingTouch(SeekBar seekBar) {}
-				
-				public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
-			});
-		}
-		else if(_checkbox != null) {
-			paramLayout.removeView(_title);
-			paramLayout.addView(_checkbox);
-			_checkbox.setEnabled(!_readOnly);
-			_checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
-				
-				public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
-					setValue((isChecked)? 1 : 0);
-				}
-			});
-		}
-		else if(_edittext != null){
-			paramLayout.addView(_edittext);
-			_edittext.setEnabled(!_readOnly);
-			
-			_edittext.setOnKeyListener(new View.OnKeyListener() {
-				public boolean onKey(View v, int keyCode, KeyEvent event) {
-					if(keyCode == KeyEvent.KEYCODE_ENTER){ // hide the keyboard
-						InputMethodManager imm = (InputMethodManager)_context.getSystemService(
-							      Context.INPUT_METHOD_SERVICE);
-						imm.hideSoftInputFromWindow(_edittext.getWindowToken(), 0);
-						setValue(_value);
-						_edittext.clearFocus();
-						return true;
-					}
-					if(keyCode > KeyEvent.KEYCODE_9 && keyCode != KeyEvent.KEYCODE_NUMPAD_DOT && (keyCode <KeyEvent.KEYCODE_NUMPAD_0 || keyCode >KeyEvent.KEYCODE_NUMPAD_9) && keyCode != KeyEvent.KEYCODE_DEL)
-							return true;
-					return false;
-				}
-			});
-			_edittext.addTextChangedListener(new TextWatcher() {
-				
-				public void onTextChanged(CharSequence s, int start, int before, int count) {
-					try {
-						if(s.length() < 1) _value = 1;
-						else _value = Double.parseDouble(s.toString());
-					}
-					catch(NumberFormatException e)
-					{
-						_value = 1;
-						//_edittext.setText("");
-					}
-				}
-				
-				public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // UNUSED Auto-generated method stub
-				public void afterTextChanged(Editable s) {} // UNUSED Auto-generated method stub
+    private double _value, _min, _max, _step;
+    private SeekBar _bar;
+    private ArrayList<Double> _values;
+    private ArrayList<String> _choices;
+    private ArrayAdapter<String> _adapter;
+    private Spinner _spinner;
+    private CheckBox _checkbox;
+    private EditText _edittext;
+    private Stepper _stepper;
 
-			});
-		}
-		else if(_stepper != null) {
-			paramLayout.addView(_stepper);
-			_stepper.setOnValueChangedListener(new Stepper.OnValueChangedListener() {
-				public void onValueChanged() {
-					setValue(_stepper.getValue());
-				}
-			});
-		}
-		return paramLayout;
-	}
-	private OnParameterChangedListener mListener;
-	public void setOnParameterChangedListener(OnParameterChangedListener listener) { mListener = listener;}
-	public interface OnParameterChangedListener {
-		void OnParameterChanged();
-	}
+    public ParameterNumber(Context context, Gmsh gmsh, String name){
+        super(context, gmsh, name);
+    }
+    public ParameterNumber(Context context, Gmsh gmsh, String name,  double value, double min, double max, double step)
+    {
+        this(context, gmsh, name);
+        _value = value;
+        _min = min;
+        _max = max;
+        _step = step;
+    }
+    public ParameterNumber(Context context, Gmsh gmsh, String name, boolean readOnly, double value, double min, double max, double step)
+    {
+        this(context, gmsh, name, value, min, max, step);
+        _readOnly = readOnly;
+    }
+
+    protected void update()
+    {
+        super.update();
+        int nDecimal = String.valueOf(_min).length() - String.valueOf(_min).lastIndexOf('.') - 1; // hack for double round
+        if(_bar != null) {
+            DecimalFormat df = new DecimalFormat ( ) ;
+            df.setMaximumFractionDigits(nDecimal) ;
+            _title.setText(getShortName() + " (" + df.format(_value)+ ")");
+            _bar.setMax(100);
+            _bar.setProgress((int)(100*(_value-_min)/(_max-_min)));
+            _bar.setEnabled(!this.isReadOnly());
+        }
+        else if(_spinner != null)
+            {
+                for(int i=0;i<_choices.size();i++)
+                    if(_values.get(i) == _value)
+                        _spinner.setSelection(i, true);
+            }
+        else if(_checkbox != null)
+            {
+                _checkbox.setText(getShortName());
+                _checkbox.setChecked((_value == 0)? false : true);
+            }
+        else if(_edittext != null)
+            {
+                _edittext.setText(""+Math.round(_value*Math.pow(10, nDecimal))/Math.pow(10, nDecimal));
+            }
+        else if(_stepper != null)
+            {
+                _stepper.setMaximum((int)Math.round(_max));
+                _stepper.setMinimum((int)Math.round(_min));
+                _stepper.setValue((int)Math.round(_value));
+            }
+    }
+
+    public void setValue(double value) {
+        if(value < _min || value > _max) {
+            //Log.w("ParameterNumber", "Incorect value "+value+" (max="+_max+" min="+_min+")");
+            return;
+        }
+        if(value == _value) return;
+        _value = value;
+        _changed = true;
+        _gmsh.setParam(getType(), getName(), String.valueOf(value));
+        if(mListener != null) mListener.OnParameterChanged();
+    }
+    public void setMin(double min) {_min = min;this.update();}
+    public void setMax(double max) {_max = max;this.update();}
+    public void setStep(double step) {_step = step;this.update();}
+    public void addChoice(double choice, String value)
+    {
+        if(_values == null) {
+            _values = new ArrayList<Double>();
+            _choices = new ArrayList<String>();
+            _values.add(choice);
+            _choices.add(value);
+            if(_spinner == null) {
+                _spinner = new Spinner(_context);
+                _adapter = new ArrayAdapter<String>(_context, android.R.layout.simple_spinner_dropdown_item, _choices);
+                _adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+                _spinner.setAdapter(_adapter);
+            }
+        }
+        else{
+            for(int i=0;i<_values.size();i++) {
+                if(_values.get(i).equals(choice) && _choices.size() > i) {
+                    _choices.set(i, value);
+                    return;
+                }
+                else if(_values.get(i).equals(choice))
+                    {
+                        _choices.add(value);
+                        return;
+                    }
+            }
+            _values.add(choice);
+            _choices.add(value);
+        }
+    }
+    public double getValue() {return _value;}
+    public double getMax() {return _max;}
+    public double getMin() {return _min;}
+    public double getStep() {return _step;}
+    public int fromString(String s)
+    {
+        int pos = super.fromString(s);
+        if(pos <= 0) return -1; // error
+        String[] infos = s.split(Character.toString((char)0x03));
+        String tmpVal = infos[pos++];
+        if(tmpVal.equals("Inf")) // TODO set value to max ???
+            _value = 1;
+        else
+            _value = Double.parseDouble(tmpVal);
+        this.setMin(Double.parseDouble(infos[pos++]));
+        this.setMax(Double.parseDouble(infos[pos++]));
+        this.setStep(Double.parseDouble(infos[pos++]));
+        pos++;// index
+        int nChoix = Integer.parseInt(infos[pos++]); // choices' size
+        double choices[] = new double[nChoix];
+        for(int i=0; i<nChoix; i++)
+            choices[i] = Double.parseDouble(infos[pos++]); // choice
+        int nLabels = Integer.parseInt(infos[pos++]); // labels' size
+        if(nChoix == 2 && choices[0] == 0 && choices[1] == 1 && nLabels == 0) {
+            _checkbox = new CheckBox(_context);
+            this.update();
+            return pos;
+        }
+        if(_choices != null)_choices.clear();
+        if(_values != null) _values.clear();
+        for(int i=0; i<nLabels && nChoix == nLabels; i++){
+            double val = Double.parseDouble(infos[pos++]); // choice
+            this.addChoice(val, infos[pos++]); // label
+        }
+        // ...
+        if(nLabels < 1 && _step == 0)
+            _edittext = new EditText(_context);
+        else if(_step == 1)
+            _stepper = new Stepper(_context);
+        else if(nLabels < 1)
+            _bar = new SeekBar(_context);
+        this.update();
+        return pos;
+    }
+    public String getType(){return "ParameterNumber";}
+    public LinearLayout getView()
+    {
+        LinearLayout paramLayout = new LinearLayout(_context);
+        paramLayout.setOrientation(LinearLayout.VERTICAL);
+        paramLayout.addView(_title);
+        if(_spinner != null) {
+            paramLayout.addView(_spinner);
+            _spinner.setEnabled(!_readOnly);
+            _spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+                    public void onNothingSelected(AdapterView<?> arg0) {}
+                    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+                        setValue(_values.get(pos));
+                    }
+                });
+        }
+        else if(_bar != null) {
+            paramLayout.addView(_bar);
+            _bar.setEnabled(!_readOnly);
+            _bar.setOnSeekBarChangeListener(new SeekBar.OnSeekBarChangeListener() {
+                    public void onStopTrackingTouch(SeekBar seekBar) {
+                        setValue(getMin() + (getMax() - getMin())*seekBar.getProgress()/100);
+                    }
+
+                    public void onStartTrackingTouch(SeekBar seekBar) {}
+
+                    public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser) {}
+                });
+        }
+        else if(_checkbox != null) {
+            paramLayout.removeView(_title);
+            paramLayout.addView(_checkbox);
+            _checkbox.setEnabled(!_readOnly);
+            _checkbox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
+
+                    public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
+                        setValue((isChecked)? 1 : 0);
+                    }
+                });
+        }
+        else if(_edittext != null){
+            paramLayout.addView(_edittext);
+            _edittext.setEnabled(!_readOnly);
+
+            _edittext.setOnKeyListener(new View.OnKeyListener() {
+                    public boolean onKey(View v, int keyCode, KeyEvent event) {
+                        if(keyCode == KeyEvent.KEYCODE_ENTER){ // hide the keyboard
+                            InputMethodManager imm = (InputMethodManager)_context.getSystemService(
+                                                                                                   Context.INPUT_METHOD_SERVICE);
+                            imm.hideSoftInputFromWindow(_edittext.getWindowToken(), 0);
+                            setValue(_value);
+                            _edittext.clearFocus();
+                            return true;
+                        }
+                        if(keyCode > KeyEvent.KEYCODE_9 && keyCode != KeyEvent.KEYCODE_NUMPAD_DOT && (keyCode <KeyEvent.KEYCODE_NUMPAD_0 || keyCode >KeyEvent.KEYCODE_NUMPAD_9) && keyCode != KeyEvent.KEYCODE_DEL)
+                            return true;
+                        return false;
+                    }
+                });
+            _edittext.addTextChangedListener(new TextWatcher() {
+
+                    public void onTextChanged(CharSequence s, int start, int before, int count) {
+                        try {
+                            if(s.length() < 1) _value = 1;
+                            else _value = Double.parseDouble(s.toString());
+                        }
+                        catch(NumberFormatException e)
+                            {
+                                _value = 1;
+                                //_edittext.setText("");
+                            }
+                    }
+
+                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // UNUSED Auto-generated method stub
+                    public void afterTextChanged(Editable s) {} // UNUSED Auto-generated method stub
+
+                });
+        }
+        else if(_stepper != null) {
+            paramLayout.addView(_stepper);
+            _stepper.setOnValueChangedListener(new Stepper.OnValueChangedListener() {
+                    public void onValueChanged() {
+                        setValue(_stepper.getValue());
+                    }
+                });
+        }
+        return paramLayout;
+    }
+    private OnParameterChangedListener mListener;
+    public void setOnParameterChangedListener(OnParameterChangedListener listener) { mListener = listener;}
+    public interface OnParameterChangedListener
+    {
+        void OnParameterChanged();
+    }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java b/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java
index 491b89a39c295088622ca4d05eeda06c72e70200..0847f0c44bb3a5bbf9ecb582203273de72b9993a 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/ParameterString.java
@@ -15,141 +15,141 @@ import android.widget.LinearLayout;
 import android.widget.Spinner;
 
 public class ParameterString extends Parameter{
-	
-	private  String _kind;
-	private int _index;
-	private ArrayList<String> _choices;
-	private ArrayAdapter<String> _adapter;
-	private Spinner _spinner;
-	private EditText _edittext;
-	
-	public ParameterString(Context context, Gmsh gmsh, String name) {
-		super(context, gmsh, name);
-		_choices = new ArrayList<String>();
-		_choices.add("-"); // Default choice
-	}
-
-	private void createSpinner()
-	{
-		if(_spinner != null) return;
-		_spinner = new Spinner(_context);
-		_adapter = new ArrayAdapter<String>(_context, android.R.layout.simple_spinner_dropdown_item, _choices);
-		_adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
-		_spinner.setAdapter(_adapter);
-	}
-	
-	protected void update(){
-		super.update();
-		if(_spinner != null)
-			_spinner.setSelection(_index);
-		else if(_edittext != null && _choices.size() > 0)
-			_edittext.setText(_choices.get(0));
-	}
-	
-	public void setValue(int index) {
-		if(index == _index) return;
-		_changed = true;
-		_index = index;
-		_gmsh.setParam(getType(), getName(), _choices.get(_index));
-		if(mListener != null) mListener.OnParameterChanged();
-	}
-	public void setValue(String value) {
-		int index = _choices.indexOf(value);
-		if(index < 0) { // the value is not in the list, add it
-			this.addChoices(value);
-			index = _choices.indexOf(value);
-		}
-		if(index == _index) return;
-		_changed = true;
-		_index = index;
-		_gmsh.setParam(getType(), getName(), value);
-		if(mListener != null) mListener.OnParameterChanged();
-	}
-	public void setKind(String kind) {_kind = kind;}
-	public void addChoices(String choice) {
-		if(_edittext == null && _spinner == null) createSpinner();
-		for(String c : _choices) // do not add a duplicate value
-			if(c.equals(choice))return;
-		if(_choices.get(0).equals("-")) // remove the default choice with the first added choice
-			_choices.remove(0);
-		_choices.add(choice);
-		this.update();
-	}
-	public String getValue() {if( _index < 0) return "";return _choices.get(_index);}
-	public String getKind() {return _kind;}
-	public int getIndex() {return _index;}
-	public ArrayList<String> getChoices() {return _choices;}
-	public int fromString(String s){
-		int pos = super.fromString(s);
-		if(pos <= 0) return -1; // error
-		String[] infos = s.split(Character.toString((char)0x03));
-		String value = infos[pos++];
-		setKind(infos[pos++]); // generic file 
-		if(_kind.equals("file"))
-			return -1;
-		int nChoices = Integer.parseInt(infos[pos++]);
-		if(nChoices < 1 && _kind.equals("generic"))
-			_edittext = new EditText(_context);
-		if(_choices != null)_choices.clear();
-		for(int i=0;i<nChoices;i++) this.addChoices(infos[pos++]);
-		// ...
-		setValue(value);
-		this.update();
-		return pos;
-	}
-	public String getType(){return "ParameterString";}
-	public LinearLayout getView() {
-		LinearLayout paramLayout = new LinearLayout(_context);
-		paramLayout.setOrientation(LinearLayout.VERTICAL);
-		paramLayout.addView(_title);
-		if(_spinner != null){
-			paramLayout.addView(_spinner);
-			_spinner.setEnabled(!_readOnly);
-			_spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
-
-				public void onNothingSelected(AdapterView<?> arg0) {}
-
-				public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
-					setValue(pos);
-				}
-
-			});
-		}
-		else if(_edittext != null){
-			paramLayout.addView(_edittext);
-			_edittext.setEnabled(!_readOnly);
-			_edittext.setOnKeyListener(new View.OnKeyListener() {
-				
-				public boolean onKey(View v, int keyCode, KeyEvent event) {
-					if(keyCode == KeyEvent.KEYCODE_ENTER){ // hide the keyboard
-						InputMethodManager imm = (InputMethodManager)_context.getSystemService(
-							      Context.INPUT_METHOD_SERVICE);
-							imm.hideSoftInputFromWindow(_edittext.getWindowToken(), 0);
-							_edittext.clearFocus();
-						return true;
-					}
-					return false;
-				}
-			});
-			_edittext.addTextChangedListener(new TextWatcher() {
-				
-				public void onTextChanged(CharSequence s, int start, int before, int count) {
-					_choices.clear(); _choices.add(s.toString());
-				}
-				
-				public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // UNUSED Auto-generated method stub
-				
-				public void afterTextChanged(Editable s) {
-					_gmsh.setParam(getType(), getName(), _choices.get(0));
-				}
-			});
-		}
-		return paramLayout;
-	}
-	private OnParameterChangedListener mListener;
-	public void setOnParameterChangedListener(OnParameterChangedListener listener) { mListener = listener;}
-	public interface OnParameterChangedListener {
-		void OnParameterChanged();
-	}
-	
+
+    private  String _kind;
+    private int _index;
+    private ArrayList<String> _choices;
+    private ArrayAdapter<String> _adapter;
+    private Spinner _spinner;
+    private EditText _edittext;
+
+    public ParameterString(Context context, Gmsh gmsh, String name) {
+        super(context, gmsh, name);
+        _choices = new ArrayList<String>();
+        _choices.add("-"); // Default choice
+    }
+
+    private void createSpinner()
+    {
+        if(_spinner != null) return;
+        _spinner = new Spinner(_context);
+        _adapter = new ArrayAdapter<String>(_context, android.R.layout.simple_spinner_dropdown_item, _choices);
+        _adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item);
+        _spinner.setAdapter(_adapter);
+    }
+
+    protected void update(){
+        super.update();
+        if(_spinner != null)
+            _spinner.setSelection(_index);
+        else if(_edittext != null && _choices.size() > 0)
+            _edittext.setText(_choices.get(0));
+    }
+
+    public void setValue(int index) {
+        if(index == _index) return;
+        _changed = true;
+        _index = index;
+        _gmsh.setParam(getType(), getName(), _choices.get(_index));
+        if(mListener != null) mListener.OnParameterChanged();
+    }
+    public void setValue(String value) {
+        int index = _choices.indexOf(value);
+        if(index < 0) { // the value is not in the list, add it
+            this.addChoices(value);
+            index = _choices.indexOf(value);
+        }
+        if(index == _index) return;
+        _changed = true;
+        _index = index;
+        _gmsh.setParam(getType(), getName(), value);
+        if(mListener != null) mListener.OnParameterChanged();
+    }
+    public void setKind(String kind) {_kind = kind;}
+    public void addChoices(String choice) {
+        if(_edittext == null && _spinner == null) createSpinner();
+        for(String c : _choices) // do not add a duplicate value
+            if(c.equals(choice))return;
+        if(_choices.get(0).equals("-")) // remove the default choice with the first added choice
+            _choices.remove(0);
+        _choices.add(choice);
+        this.update();
+    }
+    public String getValue() {if( _index < 0) return "";return _choices.get(_index);}
+    public String getKind() {return _kind;}
+    public int getIndex() {return _index;}
+    public ArrayList<String> getChoices() {return _choices;}
+    public int fromString(String s){
+        int pos = super.fromString(s);
+        if(pos <= 0) return -1; // error
+        String[] infos = s.split(Character.toString((char)0x03));
+        String value = infos[pos++];
+        setKind(infos[pos++]); // generic file
+        if(_kind.equals("file"))
+            return -1;
+        int nChoices = Integer.parseInt(infos[pos++]);
+        if(nChoices < 1 && _kind.equals("generic"))
+            _edittext = new EditText(_context);
+        if(_choices != null)_choices.clear();
+        for(int i=0;i<nChoices;i++) this.addChoices(infos[pos++]);
+        // ...
+        setValue(value);
+        this.update();
+        return pos;
+    }
+    public String getType(){return "ParameterString";}
+    public LinearLayout getView() {
+        LinearLayout paramLayout = new LinearLayout(_context);
+        paramLayout.setOrientation(LinearLayout.VERTICAL);
+        paramLayout.addView(_title);
+        if(_spinner != null){
+            paramLayout.addView(_spinner);
+            _spinner.setEnabled(!_readOnly);
+            _spinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() {
+
+                    public void onNothingSelected(AdapterView<?> arg0) {}
+
+                    public void onItemSelected(AdapterView<?> parent, View view, int pos, long id) {
+                        setValue(pos);
+                    }
+
+                });
+        }
+        else if(_edittext != null){
+            paramLayout.addView(_edittext);
+            _edittext.setEnabled(!_readOnly);
+            _edittext.setOnKeyListener(new View.OnKeyListener() {
+
+                    public boolean onKey(View v, int keyCode, KeyEvent event) {
+                        if(keyCode == KeyEvent.KEYCODE_ENTER){ // hide the keyboard
+                            InputMethodManager imm = (InputMethodManager)_context.getSystemService(
+                                                                                                   Context.INPUT_METHOD_SERVICE);
+                            imm.hideSoftInputFromWindow(_edittext.getWindowToken(), 0);
+                            _edittext.clearFocus();
+                            return true;
+                        }
+                        return false;
+                    }
+                });
+            _edittext.addTextChangedListener(new TextWatcher() {
+
+                    public void onTextChanged(CharSequence s, int start, int before, int count) {
+                        _choices.clear(); _choices.add(s.toString());
+                    }
+
+                    public void beforeTextChanged(CharSequence s, int start, int count, int after) {} // UNUSED Auto-generated method stub
+
+                    public void afterTextChanged(Editable s) {
+                        _gmsh.setParam(getType(), getName(), _choices.get(0));
+                    }
+                });
+        }
+        return paramLayout;
+    }
+    private OnParameterChangedListener mListener;
+    public void setOnParameterChangedListener(OnParameterChangedListener listener) { mListener = listener;}
+    public interface OnParameterChangedListener {
+        void OnParameterChanged();
+    }
+
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/SeparatedListView.java b/contrib/mobile/Android/src/org/geuz/onelab/SeparatedListView.java
index e9a175552a474142310f175dac93160c841e5c12..4a20677fc8c9483c4b89f1c5697038f77f4a63ec 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/SeparatedListView.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/SeparatedListView.java
@@ -15,153 +15,153 @@ import android.widget.TextView;
 
 public class SeparatedListView extends ListView{
 
-	private SeparatedListAdaptater adapter;
-	private Context _context;
-	
-	public SeparatedListView(Context context) {
-		super(context);
-		_context = context;
-		adapter = new SeparatedListAdaptater();
-		this.setAdapter(adapter);
-	}
-	public SeparatedListView(Context context, AttributeSet attrs) {
-		this(context);
-	}
-	public SeparatedListView(Context context, View[] footer) {
-		super(context);
-		_context = context;
-		for(View v : footer)
-			this.addFooterView(v);
-		adapter = new SeparatedListAdaptater();
-		this.setAdapter(adapter);
-	}
-	
-	public void addItem(String header, View item) {
-		TextView title = (TextView)((LayoutInflater) _context.getSystemService( Context.LAYOUT_INFLATER_SERVICE )).inflate(R.layout.list_header, null);
-		title.setText(header);
-		adapter.addItem(header, title, item);
-		adapter.notifyDataSetChanged();
-		this.invalidateViews();
-	}
-	public int itemsCountInSection(String header) {
-		return adapter.getCountForSection(header);
-	}
-	public void refresh()
-	{
-		adapter.notifyDataSetChanged();
-		this.invalidateViews();
-	}
-	
-	public void clear()
-	{
-		adapter.clear();
-		adapter.notifyDataSetChanged();
-	}
-	
-	private class Section{
-		private String _name;
-		private List<View> _items;
-		public Section(String name){
-			_name = name;
-			_items = new ArrayList<View>();
-		}
-		public void addItem(View v){
-			_items.add(v);
-		}
-		public String getName(){
-			return _name;
-		}
-		public int getItemsCount(){
-			return _items.size();
-		}
-		public View getItem(int pos){
-			return _items.get(pos);
-		}
-	}
-	
-	private class SeparatedListAdaptater extends BaseAdapter{
-
-		List<Section> sections;
-		List<View> titles;
-		
-		public SeparatedListAdaptater() {
-			sections = new ArrayList<SeparatedListView.Section>();
-			titles = new ArrayList<View>();
-		}
-		
-		public void addItem(String header, View title, View item) {
-			for(Section s : sections){
-				if(s.getName().equals(header)){
-					s.addItem(item);
-					return;
-				}
-			}
-			Section s = new Section(header);
-			s.addItem(item);
-			sections.add(s);
-			titles.add(title);
-		}
-		
-		//@Override
-		public int getCount() {
-			int count = 0;
-			for(Section s : sections) count += s.getItemsCount() + 1;
-			return count;
-		}
-		public int getCountForSection(String header) {
-			for(Section s : sections)
-				if(s.getName().equals(header))
-					return s.getItemsCount();
-			return 0;
-		}
-		//@Override
-		public Object getItem(int position) {
-			int section = -1,
-					lastPosition = -1;
-			while(lastPosition<position){
-				int itemsCount = sections.get(section+1).getItemsCount();
-				if(lastPosition+1 == position)// this is a section
-					return titles.get(section+1);
-				else if(lastPosition+1+itemsCount >= position){ // the view is in this section
-					if(section<0) return sections.get(section+1).getItem(position-1);
-					return sections.get(section+1).getItem(position-lastPosition-2);
-				}
-				lastPosition+= 1 + itemsCount;
-				section++;
-			}
-			return null;
-		}
-
-		//@Override
-		public long getItemId(int position) {
-			// UNUSED Auto-generated method stub
-			return 0;
-		}
-
-		//@Override
-		public View getView(int position, View convertView, ViewGroup parent) {
-			int section = -1,
-					lastPosition = -1;
-			while(lastPosition<position){
-				int itemsCount = sections.get(section+1).getItemsCount();
-				if(lastPosition+1 == position)// this is a section
-					return titles.get(section+1);
-				else if(lastPosition+1+itemsCount >= position){ // the view is in this section
-					if(section<0) return sections.get(section+1).getItem(position-1);
-					return sections.get(section+1).getItem(position-lastPosition-2);
-				}
-				lastPosition+= 1 + itemsCount;
-				section++;
-			}
-			return null;
-		}
-		public void clear()
-		{
-			sections.clear();
-			titles.clear();
-		}
-		
-	}
+    private SeparatedListAdaptater adapter;
+    private Context _context;
+
+    public SeparatedListView(Context context) {
+        super(context);
+        _context = context;
+        adapter = new SeparatedListAdaptater();
+        this.setAdapter(adapter);
+    }
+    public SeparatedListView(Context context, AttributeSet attrs) {
+        this(context);
+    }
+    public SeparatedListView(Context context, View[] footer) {
+        super(context);
+        _context = context;
+        for(View v : footer)
+            this.addFooterView(v);
+        adapter = new SeparatedListAdaptater();
+        this.setAdapter(adapter);
+    }
+
+    public void addItem(String header, View item) {
+        TextView title = (TextView)((LayoutInflater) _context.getSystemService( Context.LAYOUT_INFLATER_SERVICE )).inflate(R.layout.list_header, null);
+        title.setText(header);
+        adapter.addItem(header, title, item);
+        adapter.notifyDataSetChanged();
+        this.invalidateViews();
+    }
+    public int itemsCountInSection(String header) {
+        return adapter.getCountForSection(header);
+    }
+    public void refresh()
+    {
+        adapter.notifyDataSetChanged();
+        this.invalidateViews();
+    }
+
+    public void clear()
+    {
+        adapter.clear();
+        adapter.notifyDataSetChanged();
+    }
+
+    private class Section{
+        private String _name;
+        private List<View> _items;
+        public Section(String name){
+            _name = name;
+            _items = new ArrayList<View>();
+        }
+        public void addItem(View v){
+            _items.add(v);
+        }
+        public String getName(){
+            return _name;
+        }
+        public int getItemsCount(){
+            return _items.size();
+        }
+        public View getItem(int pos){
+            return _items.get(pos);
+        }
+    }
+
+    private class SeparatedListAdaptater extends BaseAdapter{
+
+        List<Section> sections;
+        List<View> titles;
+
+        public SeparatedListAdaptater() {
+            sections = new ArrayList<SeparatedListView.Section>();
+            titles = new ArrayList<View>();
+        }
+
+        public void addItem(String header, View title, View item) {
+            for(Section s : sections){
+                if(s.getName().equals(header)){
+                    s.addItem(item);
+                    return;
+                }
+            }
+            Section s = new Section(header);
+            s.addItem(item);
+            sections.add(s);
+            titles.add(title);
+        }
+
+        //@Override
+        public int getCount() {
+            int count = 0;
+            for(Section s : sections) count += s.getItemsCount() + 1;
+            return count;
+        }
+        public int getCountForSection(String header) {
+            for(Section s : sections)
+                if(s.getName().equals(header))
+                    return s.getItemsCount();
+            return 0;
+        }
+        //@Override
+        public Object getItem(int position) {
+            int section = -1,
+                lastPosition = -1;
+            while(lastPosition<position){
+                int itemsCount = sections.get(section+1).getItemsCount();
+                if(lastPosition+1 == position)// this is a section
+                    return titles.get(section+1);
+                else if(lastPosition+1+itemsCount >= position){ // the view is in this section
+                    if(section<0) return sections.get(section+1).getItem(position-1);
+                    return sections.get(section+1).getItem(position-lastPosition-2);
+                }
+                lastPosition+= 1 + itemsCount;
+                section++;
+            }
+            return null;
+        }
+
+        //@Override
+        public long getItemId(int position) {
+            // UNUSED Auto-generated method stub
+            return 0;
+        }
+
+        //@Override
+        public View getView(int position, View convertView, ViewGroup parent) {
+            int section = -1,
+                lastPosition = -1;
+            while(lastPosition<position){
+                int itemsCount = sections.get(section+1).getItemsCount();
+                if(lastPosition+1 == position)// this is a section
+                    return titles.get(section+1);
+                else if(lastPosition+1+itemsCount >= position){ // the view is in this section
+                    if(section<0) return sections.get(section+1).getItem(position-1);
+                    return sections.get(section+1).getItem(position-lastPosition-2);
+                }
+                lastPosition+= 1 + itemsCount;
+                section++;
+            }
+            return null;
+        }
+        public void clear()
+        {
+            sections.clear();
+            titles.clear();
+        }
+
+    }
 
 }
 
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java b/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java
index ec5aa7e82a9e56c1a38b3302b5922de54883b236..92fe06f46653b91dcd88a2905709741b0c9b15ac 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/SplashScreen.java
@@ -14,78 +14,78 @@ import android.os.Handler;
 import android.os.Message;
 
 public class SplashScreen extends Activity{
-	private static final int SPLASHTIME = 1000; // duration for the splash screen in milliseconds
-	
-	private static final int STOPSPLASH = 0;
-	private static final int EXITAPP = 1;
-	
-	private Intent newIntent;
-	
-	private final Handler handler = new Handler()
+    private static final int SPLASHTIME = 500; // duration for the splash screen in milliseconds
+
+    private static final int STOPSPLASH = 0;
+    private static final int EXITAPP = 1;
+
+    private Intent newIntent;
+
+    private final Handler handler = new Handler()
 	{
-		public void handleMessage(Message msg) {
-			switch (msg.what) {
-			case STOPSPLASH:
-				startActivity(newIntent);
-				finish();
-				break;
-			case EXITAPP:
-				finish();
-				break;
-			default:
-				break;
-			}
-		};
+            public void handleMessage(Message msg) {
+                switch (msg.what) {
+                case STOPSPLASH:
+                    startActivity(newIntent);
+                    finish();
+                    break;
+                case EXITAPP:
+                    finish();
+                    break;
+                default:
+                    break;
+                }
+            };
 	};
-	
-	protected void onCreate(android.os.Bundle savedInstanceState) {
-		super.onCreate(savedInstanceState);
-		setContentView(R.layout.splash);
-		Intent oldIntent = this.getIntent();
-		if(oldIntent != null && oldIntent.getAction() != null && oldIntent.getAction().equals(Intent.ACTION_VIEW)){
-			newIntent = new Intent(SplashScreen.this, MainActivity.class);
-			newIntent.setAction(oldIntent.getAction());
-			newIntent.setData(oldIntent.getData());
-		}
-		else
-			newIntent = new Intent(SplashScreen.this, ModelList.class);
-		loadNative();
-		final Message msg = new Message();
+
+    protected void onCreate(android.os.Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.splash);
+        Intent oldIntent = this.getIntent();
+        if(oldIntent != null && oldIntent.getAction() != null && oldIntent.getAction().equals(Intent.ACTION_VIEW)){
+            newIntent = new Intent(SplashScreen.this, MainActivity.class);
+            newIntent.setAction(oldIntent.getAction());
+            newIntent.setData(oldIntent.getData());
+        }
+        else
+            newIntent = new Intent(SplashScreen.this, ModelList.class);
+        loadNative();
+        final Message msg = new Message();
         msg.what = STOPSPLASH;
         handler.sendMessageDelayed(msg, SPLASHTIME);
-	}
+    }
 
-	/**
+    /**
      * Load file from res/raw/ directory to the files directory of the application.
      */
     private void loadNative()
     {
     	try {
-    		ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(getResources().openRawResource(R.raw.models)));
-			ZipEntry entry;
-		     while ((entry = zipStream.getNextEntry()) != null) {
-		    	 String name = entry.getName();
-		    	 FileOutputStream outputStream;
-		    	 if(name.charAt(name.length()-1) == '/') {
-		    		 continue;
-		    	 }
-		    	 else if(name.lastIndexOf("/") > 0) {
-		    		 File document = this.getFilesDir();
-		    		 File currentDirectory = new File(document,name.substring(0, name.lastIndexOf("/")));
-		    		 currentDirectory.mkdir();
-		    		 File currentFile = new File(currentDirectory, name.substring(name.lastIndexOf("/")+1));
-		    		 outputStream = new FileOutputStream(currentFile);
-		    	 }
-		    	 else {
-		    		outputStream = openFileOutput(name, Context.MODE_PRIVATE);
-		    	 }
-				byte[] buffer = new byte[2048];
-				for (int i = zipStream.read(buffer, 0, buffer.length); i > 0;i = zipStream.read(buffer, 0, buffer.length)) 
-					outputStream.write(buffer,0,i);
-		     }
-		     zipStream.close();
-		} catch (IOException e1) {
-			e1.printStackTrace();
-		}
+            ZipInputStream zipStream = new ZipInputStream(new BufferedInputStream(getResources().openRawResource(R.raw.models)));
+            ZipEntry entry;
+            while ((entry = zipStream.getNextEntry()) != null) {
+                String name = entry.getName();
+                FileOutputStream outputStream;
+                if(name.charAt(name.length()-1) == '/') {
+                    continue;
+                }
+                else if(name.lastIndexOf("/") > 0) {
+                    File document = this.getFilesDir();
+                    File currentDirectory = new File(document,name.substring(0, name.lastIndexOf("/")));
+                    currentDirectory.mkdir();
+                    File currentFile = new File(currentDirectory, name.substring(name.lastIndexOf("/")+1));
+                    outputStream = new FileOutputStream(currentFile);
+                }
+                else {
+                    outputStream = openFileOutput(name, Context.MODE_PRIVATE);
+                }
+                byte[] buffer = new byte[2048];
+                for (int i = zipStream.read(buffer, 0, buffer.length); i > 0;i = zipStream.read(buffer, 0, buffer.length))
+                    outputStream.write(buffer,0,i);
+            }
+            zipStream.close();
+        } catch (IOException e1) {
+            e1.printStackTrace();
+        }
     }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/Stepper.java b/contrib/mobile/Android/src/org/geuz/onelab/Stepper.java
index fe0922828b8a68351fbbd58e611dc8ae4b6d4168..53922184a53bb50b975b714d045b913ad43ffbf8 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/Stepper.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/Stepper.java
@@ -11,70 +11,70 @@ import android.text.Editable;
 
 class Stepper extends LinearLayout{
 
-	private int _min, _max, _val;
-	private Button _incBtn, _decBtn;
-	private EditText _valTxt;
-	private OnValueChangedListener _listener;
+    private int _min, _max, _val;
+    private Button _incBtn, _decBtn;
+    private EditText _valTxt;
+    private OnValueChangedListener _listener;
 
-	public Stepper(Context context){
-		super(context);
-		_max = _min = _val = 0;
-		_incBtn = new Button(context);
-		_decBtn = new Button(context);
-		_valTxt = new EditText(context);
-		_incBtn.setText("+");
-		_decBtn.setText("-");
-		_valTxt.setText(Integer.toString(_val));
-		this.addView(_decBtn);
-		this.addView(_valTxt);
-		this.addView(_incBtn);
-		_incBtn.setOnClickListener(new OnClickListener() {
-			public void onClick(View v) {
-				inc();
-			}
-		});
-		_decBtn.setOnClickListener(new OnClickListener() {
-			public void onClick(View v) {
-				dec();
-			}
-		});
-		_valTxt.addTextChangedListener(new TextWatcher() {
-			public void afterTextChanged(Editable s){}
-			public void beforeTextChanged(CharSequence s, int start, int count, int after){}
-			public void onTextChanged(CharSequence s, int start, int before, int count) {
-				try {
-					setValueButText(Integer.parseInt(s.toString()));
-				}
-				catch (NumberFormatException e) {}
-			}
-		});
-	}
+    public Stepper(Context context){
+        super(context);
+        _max = _min = _val = 0;
+        _incBtn = new Button(context);
+        _decBtn = new Button(context);
+        _valTxt = new EditText(context);
+        _incBtn.setText("+");
+        _decBtn.setText("-");
+        _valTxt.setText(Integer.toString(_val));
+        this.addView(_decBtn);
+        this.addView(_valTxt);
+        this.addView(_incBtn);
+        _incBtn.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    inc();
+                }
+            });
+        _decBtn.setOnClickListener(new OnClickListener() {
+                public void onClick(View v) {
+                    dec();
+                }
+            });
+        _valTxt.addTextChangedListener(new TextWatcher() {
+                public void afterTextChanged(Editable s){}
+                public void beforeTextChanged(CharSequence s, int start, int count, int after){}
+                public void onTextChanged(CharSequence s, int start, int before, int count) {
+                    try {
+                        setValueButText(Integer.parseInt(s.toString()));
+                    }
+                    catch (NumberFormatException e) {}
+                }
+            });
+    }
 
-	public interface OnValueChangedListener {
-		public void onValueChanged();
-	}
+    public interface OnValueChangedListener {
+        public void onValueChanged();
+    }
 
 
-	public void inc(){setValue(_val+1);}
-	public void dec(){setValue(_val-1);}
+    public void inc(){setValue(_val+1);}
+    public void dec(){setValue(_val-1);}
 
-	public void setOnValueChangedListener(OnValueChangedListener listener) {_listener = listener;}
-	public void setMaximum(int max){_max = max;}
-	public void setMinimum(int min){_min = min;}
-	public void setValue(int val){
-		setValueButText(val);
-		_valTxt.setText(Integer.toString(_val));
-	}
-	public void setValueButText(int val){
-		if(_max > _min) {
-			if(val == _max) _incBtn.setEnabled(false);
-			else if(val == _min) _decBtn.setEnabled(false);
-			else {_incBtn.setEnabled(true); _decBtn.setEnabled(true);} 
-		}
-		_val = val;
-		if(_listener != null) _listener.onValueChanged();
-	}
-	public int getMaximum(){return _max;}
-	public int getMinimum(){return _min;}
-	public int getValue(){return _val;}
+    public void setOnValueChangedListener(OnValueChangedListener listener) {_listener = listener;}
+    public void setMaximum(int max){_max = max;}
+    public void setMinimum(int min){_min = min;}
+    public void setValue(int val){
+        setValueButText(val);
+        _valTxt.setText(Integer.toString(_val));
+    }
+    public void setValueButText(int val){
+        if(_max > _min) {
+            if(val == _max) _incBtn.setEnabled(false);
+            else if(val == _min) _decBtn.setEnabled(false);
+            else {_incBtn.setEnabled(true); _decBtn.setEnabled(true);}
+        }
+        _val = val;
+        if(_listener != null) _listener.onValueChanged();
+    }
+    public int getMaximum(){return _max;}
+    public int getMinimum(){return _min;}
+    public int getValue(){return _val;}
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java b/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java
index 3faa40d28370dc246e11841bd6677610847386d0..c53de7209922d8616b8f8f5f3d6a470c5f06ee27 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/StringTexture.java
@@ -17,156 +17,156 @@ import android.opengl.GLUtils;
 import android.os.Environment;
 
 public class StringTexture {
-	private String _text;
-	private Bitmap _bitmap;
-	private int[] _textures = new int[1]; // Texture pointer
-	
-	public StringTexture(String s) {
-		_text = s;
-		getBitmapFromText(12.0f, Color.BLACK);
-	}
-	
-	private void getBitmapFromText(float textSize, int textColor) {
-	    Paint paint = new Paint();
-	    paint.setTextSize(textSize);
-	    paint.setColor(textColor);
-	    paint.setTextAlign(Paint.Align.LEFT);
-	    int width = (int) (paint.measureText(_text) + 2.5f); // round
-	    int baseline = (int) (textSize + 2.5f);
-	    int height = (int) (baseline + paint.descent() + 2.5f);
-	    _bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
-	    _bitmap.eraseColor(Color.TRANSPARENT);
-	    Canvas canvas = new Canvas(_bitmap);
-	    canvas.setBitmap(_bitmap);
-	    canvas.drawText(_text, 0, baseline, paint);
-	}
-	
-	private void loadGLTexture(GL10 gl) {
-		if(_bitmap == null) return;
-		gl.glGenTextures(1, _textures, 0);
-
-		gl.glBindTexture(GL10.GL_TEXTURE_2D, _textures[0]);
-		
-		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
-		gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
- 
-		GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, _bitmap, 0);
-		
-		_bitmap.recycle();
-	}
-	
-	public void draw(GL10 gl, int x, int y) {
-		gl.glEnable(GL10.GL_TEXTURE_2D);
-		// VERTEX
-		float vertex[] = {
-				-1.0f, -1.0f,  0.0f,		// bottom left
-				-1.0f,  1.0f,  0.0f,		// top left
-				 1.0f, -1.0f,  0.0f,		// bottom right
-				 1.0f,  1.0f,  0.0f			// top right
-		};
-		FloatBuffer vertexBuffer;
-		ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertex.length * 4);
-		vertexByteBuffer.order(ByteOrder.nativeOrder());
-		vertexBuffer = vertexByteBuffer.asFloatBuffer();
-		vertexBuffer.put(vertex);
-		vertexBuffer.position(0);
-		
-		// TEXTURE
-		FloatBuffer textureBuffer;	// buffer holding the texture coordinates
-		float texture[] = {
-				0.0f, 1.0f,		// top left
-				0.0f, 0.0f,		// bottom left
-				1.0f, 1.0f,		// top right
-				1.0f, 0.0f		// bottom right
-		};
-		ByteBuffer textureByteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
-		textureByteBuffer.order(ByteOrder.nativeOrder());
-		textureBuffer = textureByteBuffer.asFloatBuffer();
-		textureBuffer.put(texture);
-		textureBuffer.position(0);
-		loadGLTexture(gl);
-		gl.glBindTexture(GL10.GL_TEXTURE_2D, _textures[0]);
-		
-		
-		// DRAW
-		gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
-		gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-		gl.glColor4f(1,1,1,1);
-		gl.glEnable(GL10.GL_BLEND);
-		gl.glBlendFunc(GL10.GL_SRC_COLOR, GL10.GL_ONE_MINUS_SRC_ALPHA);
-		gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
-		gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
-		gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertex.length / 3);
-		gl.glDisable(GL10.GL_BLEND);
-		gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
-		gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
-		gl.glDisable(GL10.GL_TEXTURE_2D);
-	}
-	
-	public static byte[] getBytesFromString(String s, int textSize)
-	{
-		// Generate the bitmap
-		int textColor = Color.BLACK;
-		Paint paint = new Paint();
-	    paint.setTextSize(textSize);
-	    paint.setColor(textColor);
-	    paint.setTextAlign(Paint.Align.LEFT);
-	    int width = (int) (paint.measureText(s) + 0.5f); // round
-	    int i;
-	    for(i=2;i<=width;i*=2); width = i;
-	    int baseline = (int) (textSize + 0.5f);
-	    int height = (int) (baseline + paint.descent() + 0.5f);
-	    for(i=2;i<=height;i*=2); height = i;
-	    Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
-	    bitmap.eraseColor(Color.WHITE);
-	    Canvas canvas = new Canvas(bitmap);
-	    canvas.setBitmap(bitmap);
-	    canvas.drawText(s, 0, baseline, paint);
-	    // TMP
-		try {
-			FileOutputStream stream = new FileOutputStream(Environment.getExternalStorageDirectory()+"/test.jpg");
-			bitmap.compress(CompressFormat.JPEG, 80, stream);
-		} catch (FileNotFoundException e) {
-			// TODO Auto-generated catch block
-			e.printStackTrace();
-		}
-	    // Get the pixel in a map
-	    ByteBuffer buffer = ByteBuffer.allocateDirect(width*height);
-	    buffer.order(ByteOrder.nativeOrder());
-	    buffer.position(0);
-	    for(int y = 0; y<height;y++)
-			for(int x = 0; x<width;x++)
-				buffer.put((byte) ((bitmap.getPixel(x, y) == Color.BLACK)? 0xFF : 0x00));
-	    buffer.position(0);
-	    byte[] b = new byte[buffer.capacity()];
-	    buffer.get(b);
-	    return b;
-	}
-	public static int getWidthFromString(String s, int textSize)
-	{
-		Paint paint = new Paint();
-	    paint.setTextSize(textSize);
-	    paint.setTextAlign(Paint.Align.LEFT);
-	    int ret = (int) (paint.measureText(s) + 0.5f);
-	    int i;
-	    for(i=2;i<=ret;i*=2); ret = i;
-	    return ret;
-	}
-	public static int getRealWidthFromString(String s, int textSize)
-	{
-		Paint paint = new Paint();
-	    paint.setTextSize(textSize);
-	    paint.setTextAlign(Paint.Align.LEFT);
-	    return (int) (paint.measureText(s) + 0.5f);
-	}
-	public static int getHeightFromString(String s, int textSize)
-	{
-		Paint paint = new Paint();
-	    paint.setTextSize(textSize);
-	    paint.setTextAlign(Paint.Align.LEFT);
-	    int ret = (int) (textSize + 0.5f + paint.descent() + 0.5f);
-	    int i;
-	    for(i=2;i<=ret;i*=2); ret = i;
-	    return ret;
-	}
+    private String _text;
+    private Bitmap _bitmap;
+    private int[] _textures = new int[1]; // Texture pointer
+
+    public StringTexture(String s) {
+        _text = s;
+        getBitmapFromText(12.0f, Color.BLACK);
+    }
+
+    private void getBitmapFromText(float textSize, int textColor) {
+        Paint paint = new Paint();
+        paint.setTextSize(textSize);
+        paint.setColor(textColor);
+        paint.setTextAlign(Paint.Align.LEFT);
+        int width = (int) (paint.measureText(_text) + 2.5f); // round
+        int baseline = (int) (textSize + 2.5f);
+        int height = (int) (baseline + paint.descent() + 2.5f);
+        _bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
+        _bitmap.eraseColor(Color.TRANSPARENT);
+        Canvas canvas = new Canvas(_bitmap);
+        canvas.setBitmap(_bitmap);
+        canvas.drawText(_text, 0, baseline, paint);
+    }
+
+    private void loadGLTexture(GL10 gl) {
+        if(_bitmap == null) return;
+        gl.glGenTextures(1, _textures, 0);
+
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, _textures[0]);
+
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
+        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
+
+        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, _bitmap, 0);
+
+        _bitmap.recycle();
+    }
+
+    public void draw(GL10 gl, int x, int y) {
+        gl.glEnable(GL10.GL_TEXTURE_2D);
+        // VERTEX
+        float vertex[] = {
+            -1.0f, -1.0f,  0.0f,		// bottom left
+            -1.0f,  1.0f,  0.0f,		// top left
+            1.0f, -1.0f,  0.0f,		// bottom right
+            1.0f,  1.0f,  0.0f			// top right
+        };
+        FloatBuffer vertexBuffer;
+        ByteBuffer vertexByteBuffer = ByteBuffer.allocateDirect(vertex.length * 4);
+        vertexByteBuffer.order(ByteOrder.nativeOrder());
+        vertexBuffer = vertexByteBuffer.asFloatBuffer();
+        vertexBuffer.put(vertex);
+        vertexBuffer.position(0);
+
+        // TEXTURE
+        FloatBuffer textureBuffer;	// buffer holding the texture coordinates
+        float texture[] = {
+            0.0f, 1.0f,		// top left
+            0.0f, 0.0f,		// bottom left
+            1.0f, 1.0f,		// top right
+            1.0f, 0.0f		// bottom right
+        };
+        ByteBuffer textureByteBuffer = ByteBuffer.allocateDirect(texture.length * 4);
+        textureByteBuffer.order(ByteOrder.nativeOrder());
+        textureBuffer = textureByteBuffer.asFloatBuffer();
+        textureBuffer.put(texture);
+        textureBuffer.position(0);
+        loadGLTexture(gl);
+        gl.glBindTexture(GL10.GL_TEXTURE_2D, _textures[0]);
+
+
+        // DRAW
+        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+        gl.glColor4f(1,1,1,1);
+        gl.glEnable(GL10.GL_BLEND);
+        gl.glBlendFunc(GL10.GL_SRC_COLOR, GL10.GL_ONE_MINUS_SRC_ALPHA);
+        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
+        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
+        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, vertex.length / 3);
+        gl.glDisable(GL10.GL_BLEND);
+        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
+        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
+        gl.glDisable(GL10.GL_TEXTURE_2D);
+    }
+
+    public static byte[] getBytesFromString(String s, int textSize)
+    {
+        // Generate the bitmap
+        int textColor = Color.BLACK;
+        Paint paint = new Paint();
+        paint.setTextSize(textSize);
+        paint.setColor(textColor);
+        paint.setTextAlign(Paint.Align.LEFT);
+        int width = (int) (paint.measureText(s) + 0.5f); // round
+        int i;
+        for(i=2;i<=width;i*=2); width = i;
+        int baseline = (int) (textSize + 0.5f);
+        int height = (int) (baseline + paint.descent() + 0.5f);
+        for(i=2;i<=height;i*=2); height = i;
+        Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.RGB_565);
+        bitmap.eraseColor(Color.WHITE);
+        Canvas canvas = new Canvas(bitmap);
+        canvas.setBitmap(bitmap);
+        canvas.drawText(s, 0, baseline, paint);
+        // TMP
+        try {
+            FileOutputStream stream = new FileOutputStream(Environment.getExternalStorageDirectory()+"/test.jpg");
+            bitmap.compress(CompressFormat.JPEG, 80, stream);
+        } catch (FileNotFoundException e) {
+            // TODO Auto-generated catch block
+            e.printStackTrace();
+        }
+        // Get the pixel in a map
+        ByteBuffer buffer = ByteBuffer.allocateDirect(width*height);
+        buffer.order(ByteOrder.nativeOrder());
+        buffer.position(0);
+        for(int y = 0; y<height;y++)
+            for(int x = 0; x<width;x++)
+                buffer.put((byte) ((bitmap.getPixel(x, y) == Color.BLACK)? 0xFF : 0x00));
+        buffer.position(0);
+        byte[] b = new byte[buffer.capacity()];
+        buffer.get(b);
+        return b;
+    }
+    public static int getWidthFromString(String s, int textSize)
+    {
+        Paint paint = new Paint();
+        paint.setTextSize(textSize);
+        paint.setTextAlign(Paint.Align.LEFT);
+        int ret = (int) (paint.measureText(s) + 0.5f);
+        int i;
+        for(i=2;i<=ret;i*=2); ret = i;
+        return ret;
+    }
+    public static int getRealWidthFromString(String s, int textSize)
+    {
+        Paint paint = new Paint();
+        paint.setTextSize(textSize);
+        paint.setTextAlign(Paint.Align.LEFT);
+        return (int) (paint.measureText(s) + 0.5f);
+    }
+    public static int getHeightFromString(String s, int textSize)
+    {
+        Paint paint = new Paint();
+        paint.setTextSize(textSize);
+        paint.setTextAlign(Paint.Align.LEFT);
+        int ret = (int) (textSize + 0.5f + paint.descent() + 0.5f);
+        int i;
+        for(i=2;i<=ret;i*=2); ret = i;
+        return ret;
+    }
 }
diff --git a/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java b/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java
index f22f26b09c19dbe6b065e0107610be20e2aae5a7..c69bbbca5a9d2ebb2326da82529d11713bafb5b9 100644
--- a/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java
+++ b/contrib/mobile/Android/src/org/geuz/onelab/mGLSurfaceView.java
@@ -11,107 +11,107 @@ import android.view.GestureDetector.OnGestureListener;
 import android.view.ScaleGestureDetector.OnScaleGestureListener;
 
 class mGLSurfaceView extends GLSurfaceView {
-	private float scaleFactor = 1f;
-	private GestureDetector gesture;
-	private ScaleGestureDetector scaleGesture;
-	private GLESRender _renderer;
-	private boolean _rotate;
-
-	public mGLSurfaceView(Context context, GLESRender renderer) {
-		super(context);
-		_renderer = renderer;
-		gesture = new GestureDetector(context, new GestureListener());
-		scaleGesture = new ScaleGestureDetector(context, new OnScaleGestureListener() {
-			
-			public void onScaleEnd(ScaleGestureDetector detector) {
-				_renderer.endInteraction(detector.getFocusX(), detector.getFocusY());
-			}
-			
-			public boolean onScaleBegin(ScaleGestureDetector detector) {
-				_renderer.startInteraction(detector.getFocusX(), detector.getFocusY());
-				return true;
-			}
-			
-			public boolean onScale(ScaleGestureDetector detector) {
-				scaleFactor *= detector.getScaleFactor();
-				scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 50.0f)); // limit the scale factor
-				_renderer.scaleModel(scaleFactor);
-				requestRender();
-				return true;
-				
-			}
-		});
-	}
-		
-	@Override
+    private float scaleFactor = 1f;
+    private GestureDetector gesture;
+    private ScaleGestureDetector scaleGesture;
+    private GLESRender _renderer;
+    private boolean _rotate;
+
+    public mGLSurfaceView(Context context, GLESRender renderer) {
+        super(context);
+        _renderer = renderer;
+        gesture = new GestureDetector(context, new GestureListener());
+        scaleGesture = new ScaleGestureDetector(context, new OnScaleGestureListener() {
+
+                public void onScaleEnd(ScaleGestureDetector detector) {
+                    _renderer.endInteraction(detector.getFocusX(), detector.getFocusY());
+                }
+
+                public boolean onScaleBegin(ScaleGestureDetector detector) {
+                    _renderer.startInteraction(detector.getFocusX(), detector.getFocusY());
+                    return true;
+                }
+
+                public boolean onScale(ScaleGestureDetector detector) {
+                    scaleFactor *= detector.getScaleFactor();
+                    scaleFactor = Math.max(0.1f, Math.min(scaleFactor, 50.0f)); // limit the scale factor
+                    _renderer.scaleModel(scaleFactor);
+                    requestRender();
+                    return true;
+
+                }
+            });
+    }
+
+    @Override
 	public boolean onTouchEvent(MotionEvent event) {
-		scaleGesture.onTouchEvent(event);
-		return gesture.onTouchEvent(event);
-	}
-	
-	private class GestureListener implements OnGestureListener, OnDoubleTapListener{
-		public boolean onDown(MotionEvent e) {
-			_renderer.startInteraction(e.getX(),e.getY());
-			return true;
-		}
-
-		public boolean onFling(MotionEvent e1, MotionEvent e2,
-				float velocityX, float velocityY) {
-			// UNUSED Auto-generated method stub
-			return false;
-		}
-
-		public void onLongPress(MotionEvent e) {
-			// UNUSED Auto-generated method stub
-			
-		}
-
-		public boolean onScroll(MotionEvent e1, MotionEvent e2,
+        scaleGesture.onTouchEvent(event);
+        return gesture.onTouchEvent(event);
+    }
+
+    private class GestureListener implements OnGestureListener, OnDoubleTapListener{
+        public boolean onDown(MotionEvent e) {
+            _renderer.startInteraction(e.getX(),e.getY());
+            return true;
+        }
+
+        public boolean onFling(MotionEvent e1, MotionEvent e2,
+                               float velocityX, float velocityY) {
+            // UNUSED Auto-generated method stub
+            return false;
+        }
+
+        public void onLongPress(MotionEvent e) {
+            // UNUSED Auto-generated method stub
+
+        }
+
+        public boolean onScroll(MotionEvent e1, MotionEvent e2,
 				float distanceX, float distanceY) {
-			if(e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return false;
-			if(_rotate)
-				_renderer.rotateModel(e2.getX(), e2.getY());
-			else
-				_renderer.translateModel(e2.getX(), e2.getY());
-			requestRender();
-			return true;
-		}
-
-		public void onShowPress(MotionEvent e) {
-			// UNUSED Auto-generated method stub
-			
-		}
-
-		public boolean onSingleTapUp(MotionEvent e) {
-			// UNUSED Auto-generated method stub
-			return false;
-		}
-		public boolean onDoubleTap(MotionEvent e) {
-			// UNUSED Auto-generated method stub
-			return false;
-		}
-		public boolean onDoubleTapEvent(MotionEvent e) {
-			scaleFactor = 1f;
-			_renderer.resetModelPosition();
-			requestRender();
-			return true;
-		}
-		public boolean onSingleTapConfirmed(MotionEvent e) {
-			// UNUSED Auto-generated method stub
-			return false;
-		}
-		
-	}
-	public boolean getRotate() {return _rotate;}
-	public void setRotate(boolean r) {_rotate = r;}
-	public void resetScale(){
-		scaleFactor = 1f;
-		_renderer.scaleModel(scaleFactor);
-	}
-	public Bitmap getScreenshot() {
-		_renderer.needScreenshot();
-		this.requestRender();
-		while(_renderer.getScreenshot() == null);
-		return _renderer.getScreenshot();
-	}
+            if(e1.getPointerCount() > 1 || e2.getPointerCount() > 1) return false;
+            if(_rotate)
+                _renderer.rotateModel(e2.getX(), e2.getY());
+            else
+                _renderer.translateModel(e2.getX(), e2.getY());
+            requestRender();
+            return true;
+        }
+
+        public void onShowPress(MotionEvent e) {
+            // UNUSED Auto-generated method stub
+
+        }
+
+        public boolean onSingleTapUp(MotionEvent e) {
+            // UNUSED Auto-generated method stub
+            return false;
+        }
+        public boolean onDoubleTap(MotionEvent e) {
+            // UNUSED Auto-generated method stub
+            return false;
+        }
+        public boolean onDoubleTapEvent(MotionEvent e) {
+            scaleFactor = 1f;
+            _renderer.resetModelPosition();
+            requestRender();
+            return true;
+        }
+        public boolean onSingleTapConfirmed(MotionEvent e) {
+            // UNUSED Auto-generated method stub
+            return false;
+        }
+
+    }
+    public boolean getRotate() {return _rotate;}
+    public void setRotate(boolean r) {_rotate = r;}
+    public void resetScale(){
+        scaleFactor = 1f;
+        _renderer.scaleModel(scaleFactor);
+    }
+    public Bitmap getScreenshot() {
+        _renderer.needScreenshot();
+        this.requestRender();
+        while(_renderer.getScreenshot() == null);
+        return _renderer.getScreenshot();
+    }
 }
diff --git a/contrib/mobile/utils/onelab_android_build.sh b/contrib/mobile/utils/onelab_android_build.sh
index c36ba956d81db286b9450eedc1a5cdbcb990b4ff..6a2fb3d19f886999a51671719fd8bb862f0a2b6d 100755
--- a/contrib/mobile/utils/onelab_android_build.sh
+++ b/contrib/mobile/utils/onelab_android_build.sh
@@ -11,17 +11,17 @@ cmake_default="-DDEFAULT=0 -DCMAKE_TOOLCHAIN_FILE=$gmsh_svn/contrib/mobile/utils
 cmake_thread=6
 
 function check {
-	return_code=$?
-	if [ $return_code != 0 ]; then
-		echo "last command failed (return $return_code)"
-		exit $return_cod
-	fi
+  return_code=$?
+  if [ $return_code != 0 ]; then
+    echo "last command failed (return $return_code)"
+    exit $return_cod
+  fi
 }
 
 # PETSc and BLAS/LAPACK
 if [ ! -f "$petsc_lib/libpetsc.so" ] || [ ! -f "$petsc_lib/libf2clapack.so" ] || [ ! -f "$petsc_lib/libf2cblas.so" ] || [ ! -d "$petsc_lib/Headers/" ]; then 
-	echo "ERROR: Need BLAS (f2c), LAPACK (f2c) and PETSc\n check android_petsc_reconfigure-armv7-android-linux.py for compile options\n"
-	exit 1
+  echo "ERROR: Need BLAS (f2c), LAPACK (f2c) and PETSc\n check android_petsc_reconfigure-armv7-android-linux.py for compile options\n"
+  exit 1
 fi
 
 export ANDROID_NDK=$android_ndk 
@@ -81,21 +81,27 @@ cd Onelab
 if [ ! -d "libs/armeabi-v7a/" ]; then mkdir -p libs/armeabi-v7a/; fi
 target=1
 while read line; do
-        read line # Name
-        target_name=$(echo $line | awk '{print $2}')
-        target_version=$(echo $line | awk '{print $3}')
-        read line # Type
-        read line # API level
-        target_api=$(echo $line | awk '{print $3}')
-        read line # Revision
-        read line # Skins
-        if [ $target_api -ge 14 ]; then
-                $android_sdk/tools/android update project --name Onelab --path . --target $target
-		check
-                ant release
-		check
-		break
-        fi
-        read line # HACK
-        target=$(($target+1))
+  read line # Name
+  target_name=$(echo $line | awk '{print $2}')
+  target_version=$(echo $line | awk '{print $3}')
+  read line # Type
+  read line # API level
+  target_api=$(echo $line | awk '{print $3}')
+  read line # Revision
+  read line # Skins
+  if [ $target_api -ge 14 ]; then
+    $android_sdk/tools/android update project --name Onelab --path . --target $target
+    check
+    ant release
+    check
+    break
+  fi
+  read line # HACK
+  target=$(($target+1))
 done < <($android_sdk/tools/android list target | grep -A 5 "id:")
+
+# to re-install on the device:
+# $android_sdk/platform-tools/adb install -r $gmsh_svn/contrib/mobile/build_android/Onelab/bin/Onelab-release.apk
+
+# to debug and check the log:
+# $android_sdk/tools/ddms
diff --git a/contrib/mobile/utils/onelab_ios_build.sh b/contrib/mobile/utils/onelab_ios_build.sh
index 04e38dfabccdd88fd91e71827f5859fb1983c441..22f03e0ad9fee565038fbc36513c02ba27d63497 100755
--- a/contrib/mobile/utils/onelab_ios_build.sh
+++ b/contrib/mobile/utils/onelab_ios_build.sh
@@ -13,46 +13,46 @@ build_cmd="xcodebuild -verbose -target lib -configuration Release"
 header_cmd="xcodebuild -verbose -target getHeaders -configuration Release"
 
 function check {
-	return_code=$?
-	if [ $return_code != 0 ]; then
-		echo "last command failed (return $return_code)"
-		exit $return_code
-	fi
+    return_code=$?
+    if [ $return_code != 0 ]; then
+	echo "last command failed (return $return_code)"
+	exit $return_code
+    fi
 }
 
 function build_gmsh {
-  if [ $# -ne 1 ]; then
-    echo "You must specify an architecture (e.g. armv7, armv7s, arm64, ...)"
-    return
-  fi
-  if [ ! -d "$gmsh_svn/build_ios_$1" ]; then
-    mkdir $gmsh_svn/build_ios_$1
-  fi
-  cd $gmsh_svn/build_ios_$1
-  cmake $cmake_default -DENABLE_BLAS_LAPACK=1 -DENABLE_BUILD_LIB=1 -DENABLE_MATHEX=1 -DENABLE_MESH=1 -DENABLE_ONELAB=1 -DENABLE_PARSER=1 -DENABLE_POST=1 -DENABLE_TETGEN=1 -DCMAKE_OSX_ARCHITECTURES="$1" ..
-  check
-  $build_cmd
-  check
-  $header_cmd
-  cd -
+    if [ $# -ne 1 ]; then
+        echo "You must specify an architecture (e.g. armv7, armv7s, arm64, ...)"
+        return
+    fi
+    if [ ! -d "$gmsh_svn/build_ios_$1" ]; then
+        mkdir $gmsh_svn/build_ios_$1
+    fi
+    cd $gmsh_svn/build_ios_$1
+    cmake $cmake_default -DENABLE_BLAS_LAPACK=1 -DENABLE_BUILD_LIB=1 -DENABLE_MATHEX=1 -DENABLE_MESH=1 -DENABLE_ONELAB=1 -DENABLE_PARSER=1 -DENABLE_POST=1 -DENABLE_TETGEN=1 -DCMAKE_OSX_ARCHITECTURES="$1" ..
+    check
+    $build_cmd
+    check
+    $header_cmd
+    cd -
 }
 function build_getdp {
-  if [ $# -ne 1 ]; then
-    echo "You must specify an architecture (e.g. armv7, armv7s, arm64, ...)"
-    return
-  fi
-  if [ ! -d "$getdp_svn/build_ios_$1" ]; then
-    mkdir $getdp_svn/build_ios_$1
-  fi
-  cd $getdp_svn/build_ios_$1
-  export PETSC_DIR=
-  export PETSC_ARCH=
-  cmake $cmake_default -DENABLE_BLAS_LAPACK=1 -DENABLE_BUILD_LIB=1 -DENABLE_GMSH=1 -DENABLE_LEGACY=1 -DENABLE_PETSC=1 -DPETSC_INC="$petsc_framework/Headers/" -DPETSC_LIBS="$petsc_framework/petsc" -DENABLE_SLEPC=1 -DSLEPC_INC="$slepc_framework/Headers/" -DSLEPC_LIB="$slepc_framework/slepc" -DGMSH_INC="$frameworks_dir/Gmsh.framework/Headers/" -DGMSH_LIB="$frameworks_dir/Gmsh.framework/Gmsh" -DCMAKE_OSX_ARCHITECTURES="$1" ..
-  check
-  $build_cmd
-  check
-  $header_cmd
-  cd -
+    if [ $# -ne 1 ]; then
+        echo "You must specify an architecture (e.g. armv7, armv7s, arm64, ...)"
+        return
+    fi
+    if [ ! -d "$getdp_svn/build_ios_$1" ]; then
+        mkdir $getdp_svn/build_ios_$1
+    fi
+    cd $getdp_svn/build_ios_$1
+    export PETSC_DIR=
+    export PETSC_ARCH=
+    cmake $cmake_default -DENABLE_BLAS_LAPACK=1 -DENABLE_BUILD_LIB=1 -DENABLE_GMSH=1 -DENABLE_LEGACY=1 -DENABLE_PETSC=1 -DPETSC_INC="$petsc_framework/Headers/" -DPETSC_LIBS="$petsc_framework/petsc" -DENABLE_SLEPC=1 -DSLEPC_INC="$slepc_framework/Headers/" -DSLEPC_LIB="$slepc_framework/slepc" -DGMSH_INC="$frameworks_dir/Gmsh.framework/Headers/" -DGMSH_LIB="$frameworks_dir/Gmsh.framework/Gmsh" -DCMAKE_OSX_ARCHITECTURES="$1" ..
+    check
+    $build_cmd
+    check
+    $header_cmd
+    cd -
 }
 
 # build gmsh framework