diff --git a/Common/GmshSocket.h b/Common/GmshSocket.h
index 158f9e6f80cd40a68e5b9cbab138ff5f9d870eab..971b14933f8228698d9ce621a2ad6aab141c294a 100644
--- a/Common/GmshSocket.h
+++ b/Common/GmshSocket.h
@@ -85,6 +85,7 @@ class GmshSocket{
     GMSH_SPEED_TEST          = 30,
     GMSH_PARAMETER_CLEAR     = 31,
     GMSH_PARAMETER_UPDATE    = 32,
+    GMSH_OPEN_PROJECT        = 33,
     GMSH_OPTION_1            = 100,
     GMSH_OPTION_2            = 101,
     GMSH_OPTION_3            = 102,
@@ -193,6 +194,7 @@ class GmshSocket{
   void Error(const char *str){ SendString(GMSH_ERROR, str); }
   void Progress(const char *str){ SendString(GMSH_PROGRESS, str); }
   void MergeFile(const char *str){ SendString(GMSH_MERGE_FILE, str); }
+  void OpenProject(const char *str){ SendString(GMSH_OPEN_PROJECT, str); }
   void ParseString(const char *str){ SendString(GMSH_PARSE_STRING, str); }
   void SpeedTest(const char *str){ SendString(GMSH_SPEED_TEST, str); }
   void Option(int num, const char *str)
diff --git a/Common/onelab.h b/Common/onelab.h
index 9edf74072ab78685a5ae3f42d9e6966aa1be4d94..e8ef8cf22843df4226978139daf49ed9e2c946b2 100644
--- a/Common/onelab.h
+++ b/Common/onelab.h
@@ -849,6 +849,7 @@ namespace onelab{
     virtual void sendError(const std::string &msg){ std::cerr << msg << std::endl; }
     virtual void sendProgress(const std::string &msg){ std::cout << msg << std::endl; }
     virtual void sendMergeFileRequest(const std::string &msg){}
+    virtual void sendOpenProjectRequest(const std::string &msg){}
     virtual void sendParseStringRequest(const std::string &msg){}
     virtual void sendVertexArray(const std::string &msg){}
     virtual bool clear(const std::string &name) = 0;
@@ -1230,6 +1231,10 @@ namespace onelab{
     {
       if(_gmshClient) _gmshClient->MergeFile(msg.c_str());
     }
+    void sendOpenProjectRequest(const std::string &msg)
+    {
+      if(_gmshClient) _gmshClient->OpenProject(msg.c_str());
+    }
     void sendParseStringRequest(const std::string &msg)
     {
       if(_gmshClient) _gmshClient->ParseString(msg.c_str());
diff --git a/Fltk/onelabGroup.cpp b/Fltk/onelabGroup.cpp
index a0a1235fa9f3f0f72277ff2eeca8fda6e3313f06..14841184ea679a7187f96d150ec184be1378c740 100644
--- a/Fltk/onelabGroup.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -351,6 +351,10 @@ bool gmshLocalNetworkClient::receiveMessage(gmshLocalNetworkClient *master)
       }
     }
     break;
+  case GmshSocket::GMSH_OPEN_PROJECT:
+    OpenProject(message);
+    drawContext::global()->draw();
+    break;
   case GmshSocket::GMSH_PARSE_STRING:
     ParseString(message);
     drawContext::global()->draw();
diff --git a/contrib/onelab/python/onelab.py b/contrib/onelab/python/onelab.py
index 508b346b4aef2ceb23c0ce801d4055e90f11c703..21ce4b7af5f172c88e9d1119e03e4399f23eea79 100755
--- a/contrib/onelab/python/onelab.py
+++ b/contrib/onelab/python/onelab.py
@@ -139,6 +139,17 @@ class client :
   _GMSH_PARAMETER_NOT_FOUND = 29
   _GMSH_PARAMETER_CLEAR = 31
   _GMSH_PARAMETER_UPDATE = 32
+  _GMSH_OPEN_PROJECT = 33
+
+  def _createSocket(self) :
+    addr = self.addr
+    if '/' in addr or '\\' in addr or ':' not in addr :
+      self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
+      self.socket.connect(addr)
+    else :
+      self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
+      s = addr.split(':')
+      self.socket.connect((s[0], int(s[1])))
 
   def _receive(self) :
     def buffered_receive(l) :
@@ -180,6 +191,16 @@ class client :
       self._send(self._GMSH_PARAMETER, p.tochar())
       return p.value
         
+  def _getParameter(self, param, warn_if_not_found=True) :
+    if not self.socket :
+      return
+    self._send(self._GMSH_PARAMETER_QUERY, param.tochar())
+    (t, msg) = self._receive() 
+    if t == self._GMSH_PARAMETER :
+      param.fromchar(msg)
+    elif t == self._GMSH_PARAMETER_NOT_FOUND and warn_if_not_found :
+      print ('Unknown parameter %s' %(param.name))
+
   def defineNumber(self, name, **param):
     if 'labels' in param :
       param["choices"] = param["labels"].keys()
@@ -237,16 +258,6 @@ class client :
       print ('Unknown parameter %s' %(param.name))
     self._send(self._GMSH_PARAMETER, p.tochar())
 
-  def _getParameter(self, param, warn_if_not_found=True) :
-    if not self.socket :
-      return
-    self._send(self._GMSH_PARAMETER_QUERY, param.tochar())
-    (t, msg) = self._receive() 
-    if t == self._GMSH_PARAMETER :
-      param.fromchar(msg)
-    elif t == self._GMSH_PARAMETER_NOT_FOUND and warn_if_not_found :
-      print ('Unknown parameter %s' %(param.name))
-
   def getNumber(self, name, warn_if_not_found=True):
     param = _parameter('number', name=name)
     self._getParameter(param, warn_if_not_found)
@@ -288,6 +299,11 @@ class client :
       return
     self._send(self._GMSH_MERGE_FILE, filename)
 
+  def openProject(self, filename) :
+    if not self.socket or not filename :
+      return
+    self._send(self._GMSH_OPEN_PROJECT, filename)
+
   def reloadGeometry(self, filename) :
     if not self.socket or not filename :
       return
@@ -330,16 +346,6 @@ class client :
           return True
     return False
 
-  def _createSocket(self) :
-    addr = self.addr
-    if '/' in addr or '\\' in addr or ':' not in addr :
-      self.socket = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
-      self.socket.connect(addr)
-    else :
-      self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
-      s = addr.split(':')
-      self.socket.connect((s[0], int(s[1])))
-
   def waitOnSubClients(self):
     if not self.socket :
       return
@@ -349,7 +355,6 @@ class client :
         self._numSubClients -= 1
 
   def runNonBlockingSubClient(self, name, command, arguments=''):
-    # create command line
     if self.action == "check":
       cmd = command
     else:
@@ -440,7 +445,6 @@ class client :
       self._send(self._GMSH_INFO, 'upload: ' + ' '.join(argv))
     else :
       print(call.stderr.read())
-      ## self._send(self._GMSH_ERROR, 'upload failed !!\n' + call.stderr.read().encode('utf-8'))
 
   def download(self, here, there, remote='') :
     if not here or not there :
@@ -456,7 +460,6 @@ class client :
       self._send(self._GMSH_INFO, 'download: ' + ' '.join(argv))
     else :
       print(call.stderr.read())
-      ##self._send(self._GMSH_ERROR, 'download failed !!\n' + call.stderr.read().encode('utf-8'))
       
   def solutionFiles(self, list) :
     self.defineNumber('0Metamodel/9Use restored solution', value=0, choices=[0,1])