diff --git a/CMakeLists.txt b/CMakeLists.txt
index c0bfad1385208a358d63925b0e45d412e098047e..bd8fe3846246e11fc18d6cfac1a3343f02ffcb9a 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -35,7 +35,6 @@ option(ENABLE_CGNS "Enable CGNS mesh export" OFF)
 option(ENABLE_CHACO "Enable Chaco mesh partitioner" ${DEFAULT})
 option(ENABLE_DINTEGRATION "Enable discrete integration and levelsets" ${DEFAULT})
 option(ENABLE_FLTK "Build FLTK GUI" ${DEFAULT})
-option(ENABLE_FL_TREE "Enable FLTK tree browser widget" ${DEFAULT})
 option(ENABLE_FOURIER_MODEL "Enable Fourier geometrical models" OFF)
 option(ENABLE_GMM "Enable GMM linear algebra solvers" ${DEFAULT})
 option(ENABLE_GRAPHICS "Compile-in OpenGL graphics even if there is no GUI" OFF)
@@ -399,23 +398,6 @@ if(ENABLE_FLTK)
       endif(FLTK_PNG)   
     endif(FLTK_FOUND)
   endif(NOT HAVE_FLTK)
-  if(HAVE_FLTK)
-    if(ENABLE_NATIVE_FILE_CHOOSER)
-      if(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1)
-        add_subdirectory(contrib/NativeFileChooser)
-        include_directories(contrib/NativeFileChooser)
-        add_definitions(-DFLTK1)
-      endif(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1)
-      set_config_option(HAVE_NATIVE_FILE_CHOOSER "NativeFileChooser")
-    endif(ENABLE_NATIVE_FILE_CHOOSER)
-    if(ENABLE_FL_TREE)
-      if(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1)
-        add_subdirectory(contrib/Fl_Tree)
-        include_directories(contrib/Fl_Tree)
-      endif(NOT FLTK_VERSION OR FLTK_VERSION EQUAL 1.1)
-      set_config_option(HAVE_FL_TREE "FlTree")
-    endif(ENABLE_FL_TREE)
-  endif(HAVE_FLTK)
 elseif(ENABLE_QT)
   find_package(Qt4)
   set(QT_USE_QTOPENGL TRUE)
@@ -427,10 +409,23 @@ elseif(ENABLE_QT)
   endif(QT_FOUND)
 endif(ENABLE_FLTK)
 
+if(ENABLE_NATIVE_FILE_CHOOSER)
+  set_config_option(HAVE_NATIVE_FILE_CHOOSER "NativeFileChooser")
+endif(ENABLE_NATIVE_FILE_CHOOSER)
+
+if(ENABLE_ONELAB)
+  set_config_option(HAVE_ONELAB "OneLab")
+  if(ENABLE_ONELAB_METAMODEL)
+    add_subdirectory(contrib/onelab)
+    include_directories(contrib/onelab)
+    set_config_option(HAVE_ONELAB_METAMODEL "OneLabMetamodel")
+  endif(ENABLE_ONELAB_METAMODEL)
+endif(ENABLE_ONELAB)
+
 if(HAVE_FLTK OR HAVE_QT OR ENABLE_GRAPHICS)
-  if(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS)
-    message(SEND_ERROR "Cannot compile GUI without Mesh, Post or Plugin modules")
-  endif(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS)
+  if(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS OR NOT HAVE_ONELAB)
+    message(SEND_ERROR "Cannot compile GUI without Mesh, Post, Plugin or OneLab")
+  endif(NOT HAVE_MESH OR NOT HAVE_POST OR NOT HAVE_PLUGINS OR NOT HAVE_ONELAB)
 
   if(FLTK_JPEG)
     set_config_option(HAVE_LIBJPEG "Jpeg(Fltk)")
@@ -909,15 +904,6 @@ if(ENABLE_ACIS)
   endif(ACIS_LIB)
 endif(ENABLE_ACIS)
 
-if(ENABLE_ONELAB)
-  set_config_option(HAVE_ONELAB "OneLab")
-  if(ENABLE_ONELAB_METAMODEL)
-    add_subdirectory(contrib/onelab)
-    include_directories(contrib/onelab)
-    set_config_option(HAVE_ONELAB_METAMODEL "OneLabMetamodel")
-  endif(ENABLE_ONELAB_METAMODEL)
-endif(ENABLE_ONELAB)
-
 check_function_exists(vsnprintf HAVE_VSNPRINTF)
 if(NOT HAVE_VSNPRINTF)
   set_config_option(HAVE_NO_VSNPRINTF "NoVsnprintf")
diff --git a/Common/CommandLine.cpp b/Common/CommandLine.cpp
index ec867de016c47eeca4a478a17af358cd1fb20676..a87f4170658e0a08731bd86c414423051d36db61 100644
--- a/Common/CommandLine.cpp
+++ b/Common/CommandLine.cpp
@@ -20,12 +20,10 @@
 
 #if defined(HAVE_FLTK)
 #include <FL/Fl.H>
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1) && (FL_PATCH_VERSION > 6)
+#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION >= 3)
 // OK
-#elif (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-// also OK
 #else
-#error "Gmsh requires FLTK >= 1.1.7 or FLTK 1.3.x"
+#error "Gmsh requires FLTK >= 1.3"
 #endif
 #endif
 
diff --git a/Common/Context.cpp b/Common/Context.cpp
index 43cd9ece96bf093e1c8d2261e7e16a563e4af135..0d687f912f2e466203ba505d06ecd8461274ea3c 100644
--- a/Common/Context.cpp
+++ b/Common/Context.cpp
@@ -39,7 +39,7 @@ CTX::CTX()
   outputFileName = "";
   bgmFileName = "";
   createAppendMeshStatReport = 0;
-  launchOnelabAtStartup = -2;
+  launchSolverAtStartup = -1;
   lc = 1.;
   min[0] = min[1] = min[2] = max[2] = 0.;
   max[0] = max[1] = 1.; // for nice view when adding point in new model
diff --git a/Common/Context.h b/Common/Context.h
index efe936dc481d3c5c7ddf26409cd0aeca1517a65d..f0bc9a6a99f3fb34ae201ecb251132f4a8fb7830 100644
--- a/Common/Context.h
+++ b/Common/Context.h
@@ -82,8 +82,8 @@ class CTX {
   std::vector<std::string> recentFiles;
   // create mesh statistics report (0: do nothing, 1: create, 2: append)
   int createAppendMeshStatReport;
-  // should we launch the onelab interface at startup?
-  int launchOnelabAtStartup ;
+  // should we launch a solver at startup?
+  int launchSolverAtStartup ;
   // save session/option file on exit?
   int sessionSave, optionsSave;
   // ask confirmation when overwriting files?
@@ -103,9 +103,9 @@ class CTX {
   // show tootips in the GUI?
   int tooltips;
   // position and size of various windows in the GUI
-  int menuPosition[2], glPosition[2], glSize[2], msgSize;
+  int glPosition[2], glSize[2], msgSize;
   int optPosition[2], visPosition[2], hotPosition[2], clipPosition[2], manipPosition[2];
-  int statPosition[2], ctxPosition[2], solverPosition[2], solverSize[2];
+  int statPosition[2], ctxPosition[2];
   int pluginPosition[2], pluginSize[2], fieldPosition[2], fieldSize[2];
   int fileChooserPosition[2], extraPosition[2], extraSize[2];
   // use the system menu bar on Mac OS X?
diff --git a/Common/CreateFile.cpp b/Common/CreateFile.cpp
index 2a04beffb9005fdaaf07da73932b34fbc809c11b..56f685cdc752b44f1fdc18c0156b8bc583ae071b 100644
--- a/Common/CreateFile.cpp
+++ b/Common/CreateFile.cpp
@@ -174,7 +174,7 @@ void CreateOutputFile(const std::string &fileName, int format, bool redraw)
   bool error = false;
 
   if(redraw)
-    Msg::StatusBar(2, true, "Writing '%s'...", name.c_str());
+    Msg::StatusBar(true, "Writing '%s'...", name.c_str());
 
   switch (format) {
 
@@ -531,7 +531,7 @@ void CreateOutputFile(const std::string &fileName, int format, bool redraw)
   CTX::instance()->printing = 0;
 
   if(redraw && !error)
-    Msg::StatusBar(2, true, "Done writing '%s'", name.c_str());
+    Msg::StatusBar(true, "Done writing '%s'", name.c_str());
 
 #if defined(HAVE_OPENGL)
   if(redraw) drawContext::global()->draw();
diff --git a/Common/DefaultOptions.h b/Common/DefaultOptions.h
index ae36bcf15bb51a25744c76f9ba6a28a56732e9e5..7a1447cd92d476e56279584fc22531f6346dcfc5 100644
--- a/Common/DefaultOptions.h
+++ b/Common/DefaultOptions.h
@@ -505,10 +505,6 @@ StringXNumber GeneralOptions_Number[] = {
     "Maximum model coordinate along the Y-axis (read-only)" },
   { F,   "MaxZ" , opt_general_zmax , 0. ,
     "Maximum model coordinate along the Z-axis (read-only)" },
-  { F|S, "MenuPositionX" , opt_general_menu_position0 , 800. ,
-    "Horizontal position (in pixels) of the upper left corner of the menu window" },
-  { F|S, "MenuPositionY" , opt_general_menu_position1 , 50. ,
-    "Vertical position (in pixels) of the upper left corner of the menu window" },
   { F|S, "MessageHeight" , opt_general_message_size , 300. ,
     "Height (in pixels) of the message console" },
   { F,   "MinX" , opt_general_xmin , 0. ,
@@ -607,15 +603,6 @@ StringXNumber GeneralOptions_Number[] = {
     " centered)" },
   { F|O, "SmallAxesSize" , opt_general_small_axes_size , 30. ,
     "Size (in pixels) of small axes" },
-  { F|S, "SolverPositionX" , opt_general_solver_position0 , 650. ,
-    "Horizontal position (in pixels) of the upper left corner of the solver "
-    "window" },
-  { F|S, "SolverPositionY" , opt_general_solver_position1 , 150. ,
-    "Vertical position (in pixels) of the upper left corner of the solver window" },
-  { F|S, "SolverHeight" , opt_general_solver_size1 , 400. ,
-    "Height (in pixels) of the solver window" },
-  { F|S, "SolverWidth" , opt_general_solver_size0 , 300. ,
-    "Width (in pixels) of the solver window" },
   { F|S, "StatisticsPositionX" , opt_general_statistics_position0 , 650. ,
     "Horizontal position (in pixels) of the upper left corner of the statistic "
     "window" },
diff --git a/Common/Gmsh.cpp b/Common/Gmsh.cpp
index 573931a542dddc7d04b618d15c21d7b5d23f9d36..41a5d9a6cfb516521729ba9709b7916fffef58fc 100644
--- a/Common/Gmsh.cpp
+++ b/Common/Gmsh.cpp
@@ -38,9 +38,9 @@
 
 #if defined(HAVE_FLTK)
 #include "FlGui.h"
-#include "menuWindow.h"
+#include "graphicWindow.h"
 #include "drawContext.h"
-#include "onelabWindow.h"
+#include "onelabGroup.h"
 #endif
 
 int GmshInitialize(int argc, char **argv)
@@ -235,15 +235,12 @@ int GmshFLTK(int argc, char **argv)
 
   // init first context
   switch (CTX::instance()->initialContext) {
-  case 1: FlGui::instance()->menu->setContext(menu_geometry, 0); break;
-  case 2: FlGui::instance()->menu->setContext(menu_mesh, 0); break;
-  case 3: FlGui::instance()->menu->setContext(menu_solver, 0); break;
-  case 4: FlGui::instance()->menu->setContext(menu_post, 0); break;
+  case 1: FlGui::instance()->openModule("Geometry"); break;
+  case 2: FlGui::instance()->openModule("Mesh"); break;
+  case 3: FlGui::instance()->openModule("Solver"); break;
+  case 4: FlGui::instance()->openModule("Post-processing"); break;
   default: // automatic
-    if(PView::list.size())
-      FlGui::instance()->menu->setContext(menu_post, 0);
-    else
-      FlGui::instance()->menu->setContext(menu_geometry, 0);
+    if(PView::list.size()) FlGui::instance()->openModule("Post-processing");
     break;
   }
 
@@ -256,16 +253,14 @@ int GmshFLTK(int argc, char **argv)
       Msg::Error("Invalid background mesh (no view)");
   }
 
-#if defined(HAVE_ONELAB)
   // listen to external solvers
   if(CTX::instance()->solver.listen){
     onelab::localNetworkClient *c = new onelab::localNetworkClient("Listen", "");
     c->run();
   }
-  if(CTX::instance()->launchOnelabAtStartup != -2){
-    solver_cb(0, (void*)CTX::instance()->launchOnelabAtStartup);
-  }
-#endif
+
+  // launch solver (if requested) and fill onelab tree
+  solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup);
 
   // loop
   return FlGui::instance()->run();
diff --git a/Common/GmshConfig.h.in b/Common/GmshConfig.h.in
index 4d917e3e9632b818b564e6d6add9bd88a24cd264..79b05ce051379ff6ea23c028cb55aa13c4fac558 100644
--- a/Common/GmshConfig.h.in
+++ b/Common/GmshConfig.h.in
@@ -18,7 +18,6 @@
 #cmakedefine HAVE_DLOPEN
 #cmakedefine HAVE_DINTEGRATION
 #cmakedefine HAVE_FLTK
-#cmakedefine HAVE_FL_TREE
 #cmakedefine HAVE_FOURIER_MODEL
 #cmakedefine HAVE_GMM
 #cmakedefine HAVE_GMP
diff --git a/Common/GmshMessage.cpp b/Common/GmshMessage.cpp
index 806bafc44a2ffe99dca9bfd2d6613be3765f1aec..0a8ae573f187562d694816ef2f7d1eaf0e77b060 100644
--- a/Common/GmshMessage.cpp
+++ b/Common/GmshMessage.cpp
@@ -387,10 +387,9 @@ void Msg::Direct(int level, const char *fmt, ...)
   }
 }
 
-void Msg::StatusBar(int num, bool log, const char *fmt, ...)
+void Msg::StatusBar(bool log, const char *fmt, ...)
 {
   if(_commRank || _verbosity < 4) return;
-  if(num < 1 || num > 3) return;
 
   char str[5000];
   va_list args;
@@ -404,8 +403,8 @@ void Msg::StatusBar(int num, bool log, const char *fmt, ...)
 #if defined(HAVE_FLTK)
   if(FlGui::available()){
     if(log) FlGui::instance()->check();
-    if(!log || num != 2 || _verbosity > 4)
-      FlGui::instance()->setStatus(str, num - 1);
+    if(!log || _verbosity > 4)
+      FlGui::instance()->setStatus(str);
     if(log){
       std::string tmp = std::string("Info    : ") + str;
       FlGui::instance()->addMessage(tmp.c_str());
@@ -419,6 +418,20 @@ void Msg::StatusBar(int num, bool log, const char *fmt, ...)
   }
 }
 
+void Msg::StatusGl(const char *fmt, ...)
+{
+#if defined(HAVE_FLTK)
+  if(_commRank) return;
+  char str[5000];
+  va_list args;
+  va_start(args, fmt);
+  vsnprintf(str, sizeof(str), fmt, args);
+  va_end(args);
+  if(FlGui::available())
+    FlGui::instance()->setStatus(str, true);
+#endif
+}
+
 void Msg::Debug(const char *fmt, ...)
 {
   if(_verbosity < 99) return;
@@ -791,7 +804,6 @@ void Msg::ExchangeOnelabParameter(const std::string &key,
 {
 #if defined(HAVE_ONELAB)
   if(!_onelabClient || val.empty()) return;
-  CTX::instance()->launchOnelabAtStartup = -1;
 
   std::string name = _getParameterName(key, copt);
 
@@ -873,7 +885,6 @@ void Msg::ExchangeOnelabParameter(const std::string &key,
 {
 #if defined(HAVE_ONELAB)
   if(!_onelabClient || val.empty()) return;
-  CTX::instance()->launchOnelabAtStartup = -1;
 
   std::string name = _getParameterName(key, copt);
 
@@ -919,10 +930,11 @@ void Msg::ImportPhysicalsAsOnelabRegions()
           name = std::string("Physical") +
             ((dim == 3) ? "Volume" : (dim == 2) ? "Surface" :
              (dim == 1) ? "Line" : "Point") + num.str();
-        name.insert(0, "Gmsh/Physical groups/");
+        name.insert(0, "Gmsh parameters/Physical groups/");
         onelab::region p(name, num.str());
         p.setDimension(dim);
         p.setReadOnly(true);
+        p.setVisible(false);
         p.setAttribute("Closed", "1");
         _onelabClient->set(p);
       }
diff --git a/Common/GmshMessage.h b/Common/GmshMessage.h
index 27431e42aeb453e7e525b455988dc1ab1dd52152..38b18916e20cfd5ccf4cd2a5bc8d8feb7b98a1ec 100644
--- a/Common/GmshMessage.h
+++ b/Common/GmshMessage.h
@@ -69,7 +69,8 @@ class Msg {
   static void Info(const char *fmt, ...);
   static void Direct(const char *fmt, ...);
   static void Direct(int level, const char *fmt, ...);
-  static void StatusBar(int num, bool log, const char *fmt, ...);
+  static void StatusBar(bool log, const char *fmt, ...);
+  static void StatusGl(const char *fmt, ...);
   static void Debug(const char *fmt, ...);
   static void ProgressMeter(int n, int N, bool log, const char *fmt, ...);
   static void SetProgressMeterStep(int step){ _progressMeterStep = step; }
diff --git a/Common/OpenFile.cpp b/Common/OpenFile.cpp
index 9b1bb7a938b999c41edbb1b38bdb8a2becf76af4..72098a2af4414f1f220d1965e3032b703b720b62 100644
--- a/Common/OpenFile.cpp
+++ b/Common/OpenFile.cpp
@@ -37,8 +37,8 @@
 #if defined(HAVE_FLTK)
 #include <FL/fl_ask.H>
 #include "FlGui.h"
-#include "onelabWindow.h"
-#include "menuWindow.h"
+#include "onelabGroup.h"
+#include "graphicWindow.h"
 #include "drawContext.h"
 #endif
 
@@ -257,7 +257,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing)
   if(!fgets(header, sizeof(header), fp)) return 0;
   fclose(fp);
 
-  Msg::StatusBar(2, true, "Reading '%s'...", fileName.c_str());
+  Msg::StatusBar(true, "Reading '%s'...", fileName.c_str());
 
   std::vector<std::string> split = SplitFileName(fileName);
   std::string noExt = split[0] + split[1], ext = split[2];
@@ -379,7 +379,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing)
     std::vector<std::string> split = SplitFileName(fileName);
     GModel::current()->setName("");
     status = MergeFile(split[0] + split[1] + ".geo");
-    CTX::instance()->launchOnelabAtStartup = 0;
+    CTX::instance()->launchSolverAtStartup = 0;
     return status;
   }
 #endif
@@ -445,7 +445,7 @@ int MergeFile(const std::string &fileName, bool warnIfMissing)
   Msg::ImportPhysicalsAsOnelabRegions();
 
   if(!status) Msg::Error("Error loading '%s'", fileName.c_str());
-  Msg::StatusBar(2, true, "Done reading '%s'", fileName.c_str());
+  Msg::StatusBar(true, "Done reading '%s'", fileName.c_str());
 
    // merge the associated option file if there is one
   if(!StatFile(fileName + ".opt"))
@@ -606,7 +606,7 @@ void OpenProject(const std::string &fileName)
       CTX::instance()->recentFiles.resize(5);
 #if defined(HAVE_FLTK)
     if(FlGui::available())
-      FlGui::instance()->menu->fillRecentHistoryMenu();
+      FlGui::instance()->graph[0]->fillRecentHistoryMenu();
 #endif
   }
 
diff --git a/Common/Options.cpp b/Common/Options.cpp
index 78013e28c1e1106f946d6e5dc65e109bd68a2e2a..a47fb543aa5b981a1a8bd45be7a25158ca003d70 100644
--- a/Common/Options.cpp
+++ b/Common/Options.cpp
@@ -41,12 +41,13 @@
 #if defined(HAVE_FLTK)
 #include <FL/Fl_Tooltip.H>
 #include "FlGui.h"
-#include "menuWindow.h"
 #include "graphicWindow.h"
 #include "optionWindow.h"
 #include "manipWindow.h"
 #include "contextWindow.h"
 #include "clippingWindow.h"
+#include "onelabGroup.h"
+#include "viewButton.h"
 #endif
 
 // General routines for string options
@@ -1279,9 +1280,9 @@ std::string opt_view_name(OPT_ARGS_STR)
         if((i == num ||
             PView::list[i]->getAliasOf() == view->getNum() ||
             PView::list[i]->getNum() == view->getAliasOf()) &&
-           i < (int)FlGui::instance()->menu->toggle.size()) {
-          FlGui::instance()->menu->toggle[i]->copy_label(data->getName().c_str());
-          FlGui::instance()->menu->toggle[i]->redraw();
+           FlGui::instance()->onelab->getViewButton(i)) {
+          FlGui::instance()->onelab->getViewButton(i)->copy_label(data->getName());
+          FlGui::instance()->onelab->getViewButton(i)->redraw();
         }
       }
     }
@@ -1802,48 +1803,6 @@ double opt_general_graphics_size1(OPT_ARGS_NUM)
   return CTX::instance()->glSize[1];
 }
 
-double opt_general_menu_position0(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX::instance()->menuPosition[0] = (int)val;
-  return CTX::instance()->menuPosition[0];
-}
-
-double opt_general_menu_position1(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX::instance()->menuPosition[1] = (int)val;
-  return CTX::instance()->menuPosition[1];
-}
-
-double opt_general_solver_position0(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX::instance()->solverPosition[0] = (int)val;
-  return CTX::instance()->solverPosition[0];
-}
-
-double opt_general_solver_position1(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX::instance()->solverPosition[1] = (int)val;
-  return CTX::instance()->solverPosition[1];
-}
-
-double opt_general_solver_size0(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX::instance()->solverSize[0] = (int)val;
-  return CTX::instance()->solverSize[0];
-}
-
-double opt_general_solver_size1(OPT_ARGS_NUM)
-{
-  if(action & GMSH_SET)
-    CTX::instance()->solverSize[1] = (int)val;
-  return CTX::instance()->solverSize[1];
-}
-
 double opt_general_context_position0(OPT_ARGS_NUM)
 {
   if(action & GMSH_SET)
@@ -2463,12 +2422,12 @@ double opt_general_orthographic(OPT_ARGS_NUM)
     if(CTX::instance()->ortho){
       FlGui::instance()->options->general.choice[2]->value(0);
       if(FlGui::available())
-        Msg::StatusBar(2, false, "Orthographic projection");
+        Msg::StatusBar(false, "Orthographic projection");
     }
     else{
       FlGui::instance()->options->general.choice[2]->value(1);
       if(FlGui::available())
-        Msg::StatusBar(2, false, "Perspective projection");
+        Msg::StatusBar(false, "Perspective projection");
     }
   }
 #endif
@@ -2483,13 +2442,13 @@ double opt_general_mouse_selection(OPT_ARGS_NUM)
   if(FlGui::available() && (action & GMSH_GUI)) {
     if(CTX::instance()->mouseSelection){
       if(FlGui::available())
-        Msg::StatusBar(2, false, "Mouse selection ON");
+        Msg::StatusBar(false, "Mouse selection ON");
       for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
         FlGui::instance()->graph[i]->butt[9]->color(FL_BACKGROUND_COLOR);
     }
     else{
       if(FlGui::available())
-        Msg::StatusBar(2, false, "Mouse selection OFF");
+        Msg::StatusBar(false, "Mouse selection OFF");
       for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
         FlGui::instance()->graph[i]->butt[9]->color(FL_RED);
     }
@@ -6555,8 +6514,8 @@ double opt_view_visible(OPT_ARGS_NUM)
   }
 #if defined(HAVE_FLTK)
   if(FlGui::available() && (action & GMSH_GUI) && num >= 0 &&
-     num < (int)FlGui::instance()->menu->toggle.size())
-    FlGui::instance()->menu->toggle[num]->value(opt->visible);
+     FlGui::instance()->onelab->getViewButton(num))
+    FlGui::instance()->onelab->getViewButton(num)->value(opt->visible);
 #endif
   return opt->visible;
 #else
diff --git a/Common/Options.h b/Common/Options.h
index 2d16e401e8e152c2d7ac126de8387f120d7edaf0..af3918cdd230dec1a88aa774890843b0c8c9af45 100644
--- a/Common/Options.h
+++ b/Common/Options.h
@@ -103,10 +103,6 @@ double opt_general_graphics_position0(OPT_ARGS_NUM);
 double opt_general_graphics_position1(OPT_ARGS_NUM);
 double opt_general_graphics_size0(OPT_ARGS_NUM);
 double opt_general_graphics_size1(OPT_ARGS_NUM);
-double opt_general_solver_position0(OPT_ARGS_NUM);
-double opt_general_solver_position1(OPT_ARGS_NUM);
-double opt_general_solver_size0(OPT_ARGS_NUM);
-double opt_general_solver_size1(OPT_ARGS_NUM);
 double opt_general_context_position0(OPT_ARGS_NUM);
 double opt_general_context_position1(OPT_ARGS_NUM);
 double opt_general_file_chooser_position0(OPT_ARGS_NUM);
@@ -114,8 +110,6 @@ double opt_general_file_chooser_position1(OPT_ARGS_NUM);
 double opt_general_polygon_offset_always(OPT_ARGS_NUM);
 double opt_general_polygon_offset_factor(OPT_ARGS_NUM);
 double opt_general_polygon_offset_units(OPT_ARGS_NUM);
-double opt_general_menu_position0(OPT_ARGS_NUM);
-double opt_general_menu_position1(OPT_ARGS_NUM);
 double opt_general_system_menu_bar(OPT_ARGS_NUM);
 double opt_general_message_size(OPT_ARGS_NUM);
 double opt_general_option_position0(OPT_ARGS_NUM);
diff --git a/Common/onelabUtils.cpp b/Common/onelabUtils.cpp
index 2c891e2aebbacb882302ca57b1bd406efaeb7f33..258bf1107cc62911171a986a11fbc563f94e7f75 100644
--- a/Common/onelabUtils.cpp
+++ b/Common/onelabUtils.cpp
@@ -140,8 +140,8 @@ namespace onelabUtils {
       }
     }
 
-    // force this to make sure that we remesh, even if a mesh exists and
-    // we did not actually change a Gmsh parameter
+    // force this to make sure that we remesh, even if a mesh exists and we did
+    // not actually change a Gmsh parameter
     if(changed)
       onelab::server::instance()->setChanged(true, "Gmsh");
   }
diff --git a/Fltk/CMakeLists.txt b/Fltk/CMakeLists.txt
index 7814c45c19d449c8a7eb9f65464a20a5c55b1aea..11d813af2b320e9696c935da2acbb57ddff9b1a7 100644
--- a/Fltk/CMakeLists.txt
+++ b/Fltk/CMakeLists.txt
@@ -7,7 +7,6 @@ set(SRC
   FlGui.cpp
     graphicWindow.cpp
       openglWindow.cpp
-    menuWindow.cpp
     optionWindow.cpp
       colorbarWindow.cpp
     fieldWindow.cpp
@@ -24,8 +23,9 @@ set(SRC
     projectionEditor.cpp
     classificationEditor.cpp
     partitionDialog.cpp
-    onelabWindow.cpp
+    onelabGroup.cpp
     inputRegion.cpp
+    viewButton.cpp
 )
 
 file(GLOB HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.h) 
diff --git a/Fltk/FlGui.cpp b/Fltk/FlGui.cpp
index 755e0f8327359f7efeb380515409927b03715671..9bf64ee85f8cdd4adcf5f7e8b422b85ff17838ce 100644
--- a/Fltk/FlGui.cpp
+++ b/Fltk/FlGui.cpp
@@ -19,7 +19,6 @@ typedef unsigned long intptr_t;
 #include <FL/gl.h>
 #include "FlGui.h"
 #include "graphicWindow.h"
-#include "menuWindow.h"
 #include "optionWindow.h"
 #include "fieldWindow.h"
 #include "pluginWindow.h"
@@ -29,7 +28,7 @@ typedef unsigned long intptr_t;
 #include "clippingWindow.h"
 #include "manipWindow.h"
 #include "contextWindow.h"
-#include "onelabWindow.h"
+#include "onelabGroup.h"
 #include "aboutWindow.h"
 #include "colorbarWindow.h"
 #include "fileDialogs.h"
@@ -186,7 +185,7 @@ class drawContextFltk : public drawContextGlobal{
   }
   void resetFontTextures()
   {
-#if defined(__APPLE__) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
+#if defined(__APPLE__)
     gl_texture_pile_height(1); // force font texture recomputation
 #endif
   }
@@ -233,17 +232,17 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false)
   // add callback to respond to Mac Finder
 #if defined(__APPLE__)
   fl_open_callback(OpenProjectMacFinder);
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
   fl_mac_set_about(help_about_cb, 0);
-#endif
 #endif
 
-  // all the windows are contructed (even if some are not displayed)
-  // since the shortcuts should be valid even for hidden windows, and
-  // we don't want to test for widget existence every time
-  menu = new menuWindow();
+  // all the windows are contructed (even if some are not displayed) since the
+  // shortcuts should be valid even for hidden windows, and we don't want to
+  // test for widget existence every time
   graph.push_back(new graphicWindow(true, CTX::instance()->numTiles));
 
+  // FIXME: make this cleaner ;-)
+  onelab = graph.back()->onelab;
+
 #if defined(WIN32)
   graph[0]->win->icon
     ((const char*)LoadImage(fl_display, MAKEINTRESOURCE(IDI_ICON),
@@ -267,18 +266,12 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false)
   graph[0]->win->icon
     ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
                                         gmsh32x32, 32, 32));
-  menu->win->icon
-    ((const char*)XCreateBitmapFromData(fl_display, DefaultRootWindow(fl_display),
-                                        gmsh32x32, 32, 32));
 #endif
 
-  // open graphic window first for correct non-modal behaviour on
-  // Win32
   graph[0]->win->show(1, argv);
-  menu->win->show();
 
-  // graphic window should have the initial focus (so we can
-  // e.g. directly loop through time steps with the keyboard)
+  // graphic window should have the initial focus (so we can e.g. directly loop
+  // through time steps with the keyboard)
   //graph[0]->gl[0]->take_focus();
   Fl::focus(graph[0]->gl[0]);
 
@@ -302,9 +295,6 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false)
   geoContext = new geometryContextWindow(CTX::instance()->deltaFontSize);
   meshContext = new meshContextWindow(CTX::instance()->deltaFontSize);
   about = new aboutWindow();
-#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-  onelab = new onelabWindow(CTX::instance()->deltaFontSize);
-#endif
 
   // init solver plugin stuff
   callForSolverPlugin(-1);
@@ -313,8 +303,6 @@ FlGui::FlGui(int argc, char **argv) : _openedThroughMacFinder(false)
   for(unsigned int i = 0; i < graph.size(); i++)
     for(unsigned int j = 0; j < graph[i]->gl.size(); j++)
       graph[i]->gl[j]->redraw();
-
-  menu->setContext(menu_geometry, 0);
 }
 
 FlGui *FlGui::_instance = 0;
@@ -326,8 +314,7 @@ FlGui *FlGui::instance(int argc, char **argv)
     // set all options in the new GUI
     InitOptionsGUI(0);
     // say welcome!
-    Msg::StatusBar(1, false, "Geometry");
-    Msg::StatusBar(2, false, "Gmsh %s", GetGmshVersion());
+    Msg::StatusBar(false, "Gmsh %s", GetGmshVersion());
     // log the following for bug reports
     Msg::Info("-------------------------------------------------------");
     Msg::Info("Gmsh version   : %s", GetGmshVersion());
@@ -346,9 +333,9 @@ FlGui *FlGui::instance(int argc, char **argv)
 
 int FlGui::run()
 {
-  // bounding box computation necessary if we run the gui without
-  // merging any files (e.g. if we build the geometry with python and
-  // create the gui from the python script)
+  // bounding box computation necessary if we run the gui without merging any
+  // files (e.g. if we build the geometry with python and create the gui from
+  // the python script)
   SetBoundingBox();
 
   // draw the scene
@@ -365,63 +352,40 @@ int FlGui::testGlobalShortcuts(int event)
   int status = 0;
 
   if(Fl::test_shortcut('0')) {
-    // FIXME: here we should also reset all onelab variables that depend on Gmsh
     geometry_reload_cb(0, 0);
-    mod_geometry_cb(0, 0);
     status = 1;
   }
   else if(Fl::test_shortcut('1') || Fl::test_shortcut(FL_F + 1)) {
     mesh_1d_cb(0, 0);
-    mod_mesh_cb(0, 0);
     status = 1;
   }
   else if(Fl::test_shortcut('2') || Fl::test_shortcut(FL_F + 2)) {
     mesh_2d_cb(0, 0);
-    mod_mesh_cb(0, 0);
     status = 1;
   }
   else if(Fl::test_shortcut('3') || Fl::test_shortcut(FL_F + 3)) {
     mesh_3d_cb(0, 0);
-    mod_mesh_cb(0, 0);
     status = 1;
   }
-  // FIXME TEST
-  //else if(Fl::test_shortcut('4') || Fl::test_shortcut(FL_F + 4)) {
-  //  RecombineMesh(GModel::current());
-  //  status = 2;
-  //}
   else if(Fl::test_shortcut(FL_CTRL + 'q') || Fl::test_shortcut(FL_META + 'q')){
-    // only necessary when using the system menu bar, but hey, it
-    // cannot hurt...
+    // only necessary when using the system menu bar, but hey, it cannot hurt...
     file_quit_cb(0, 0);
     status = 1;
   }
   else if(Fl::test_shortcut('g')) {
-    mod_geometry_cb(0, 0);
-    Fl::focus(menu->scroll);
+    FlGui::instance()->openModule("Geometry");
     status = 1;
   }
   else if(Fl::test_shortcut('m')) {
-    mod_mesh_cb(0, 0);
-    Fl::focus(menu->scroll);
+    FlGui::instance()->openModule("Mesh");
     status = 1;
   }
   else if(Fl::test_shortcut('s')) {
-    mod_solver_cb(0, 0);
-    Fl::focus(menu->scroll);
+    FlGui::instance()->openModule("Solver");
     status = 1;
   }
   else if(Fl::test_shortcut('p')) {
-    mod_post_cb(0, 0);
-    Fl::focus(menu->scroll);
-    status = 1;
-  }
-  else if(Fl::test_shortcut('<')) {
-    mod_back_cb(0, 0);
-    status = 1;
-  }
-  else if(Fl::test_shortcut('>')) {
-    mod_forward_cb(0, 0);
+    FlGui::instance()->openModule("Post-processing");
     status = 1;
   }
   else if(Fl::test_shortcut('w')) {
@@ -723,14 +687,12 @@ int FlGui::testArrowShortcuts()
 void FlGui::setGraphicTitle(std::string title)
 {
   for(unsigned int i = 0; i < graph.size(); i++){
-    if(!i){
-      graph[i]->setTitle(title);
-    }
-    else{
-      std::ostringstream sstream;
-      sstream << title << " [" << i << "]";
-      graph[i]->setTitle(sstream.str());
-    }
+    std::ostringstream sstream;
+    if(!i)
+      sstream << "Gmsh - " << title;
+    else
+      sstream << "Gmsh - " << title << " [" << i << "]";
+    graph[i]->setTitle(sstream.str());
   }
 }
 
@@ -739,8 +701,7 @@ void FlGui::updateViews(bool numberOfViewsHasChanged)
   for(unsigned int i = 0; i < graph.size(); i++)
     graph[i]->checkAnimButtons();
   if(numberOfViewsHasChanged){
-    if(menu->module->value() == 3)
-      menu->setContext(menu_post, 0);
+    onelab->rebuildTree();
     options->resetBrowser();
     options->resetExternalViewList();
     fields->loadFieldViewList();
@@ -786,18 +747,18 @@ char FlGui::selectEntity(int type)
      selectedElements);
 }
 
-void FlGui::setStatus(const char *msg, int num)
+void FlGui::setStatus(const char *msg, bool opengl)
 {
-  if(num == 0 || num == 1){
-    static char buff[2][1024];
-    strncpy(buff[num], msg, sizeof(buff[num]) - 1);
-    buff[num][sizeof(buff[num]) - 1] = '\0';
+  if(!opengl){
+    static char buff[1024];
+    strncpy(buff, msg, sizeof(buff) - 1);
+    buff[sizeof(buff) - 1] = '\0';
     for(unsigned int i = 0; i < graph.size(); i++){
-      graph[i]->label[num]->label(buff[num]);
-      graph[i]->label[num]->redraw();
+      graph[i]->label->label(buff);
+      graph[i]->label->redraw();
     }
   }
-  else if(num == 2){
+  else{
     openglWindow *gl = getCurrentOpenglWindow();
     int n = strlen(msg);
     int i = 0;
@@ -816,20 +777,18 @@ void FlGui::setStatus(const char *msg, int num)
 void FlGui::setProgress(const char *msg, double val, double min, double max)
 {
   for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++){
-    if(FlGui::instance()->graph[i]->label[1]->value() != val)
-      FlGui::instance()->graph[i]->label[1]->value(val);
-    if(FlGui::instance()->graph[i]->label[1]->minimum() != min)
-      FlGui::instance()->graph[i]->label[1]->minimum(min);
-    if(FlGui::instance()->graph[i]->label[1]->maximum() != max)
-      FlGui::instance()->graph[i]->label[1]->maximum(max);
-  }
-  setStatus(msg, 1);
+    if(FlGui::instance()->graph[i]->label->value() != val)
+      FlGui::instance()->graph[i]->label->value(val);
+    if(FlGui::instance()->graph[i]->label->minimum() != min)
+      FlGui::instance()->graph[i]->label->minimum(min);
+    if(FlGui::instance()->graph[i]->label->maximum() != max)
+      FlGui::instance()->graph[i]->label->maximum(max);
+  }
+  setStatus(msg);
 }
 
 void FlGui::storeCurrentWindowsInfo()
 {
-  CTX::instance()->menuPosition[0] = menu->win->x();
-  CTX::instance()->menuPosition[1] = menu->win->y();
   CTX::instance()->glPosition[0] = graph[0]->win->x();
   CTX::instance()->glPosition[1] = graph[0]->win->y();
   CTX::instance()->glSize[0] = graph[0]->win->w();
@@ -857,12 +816,6 @@ void FlGui::storeCurrentWindowsInfo()
   CTX::instance()->manipPosition[1] = manip->win->y();
   CTX::instance()->ctxPosition[0] = geoContext->win->x();
   CTX::instance()->ctxPosition[1] = meshContext->win->y();
-#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-  CTX::instance()->solverPosition[0] = onelab->x();
-  CTX::instance()->solverPosition[1] = onelab->y();
-  CTX::instance()->solverSize[0] = onelab->w();
-  CTX::instance()->solverSize[1] = onelab->h();
-#endif
 #if defined(HAVE_3M)
   storeWindowPosition3M();
 #endif
@@ -909,8 +862,6 @@ void window_cb(Fl_Widget *w, void *data)
       FlGui::instance()->manip->win->iconize();
     if(FlGui::instance()->stats->win->shown())
       FlGui::instance()->stats->win->iconize();
-    if(FlGui::instance()->menu->win->shown())
-      FlGui::instance()->menu->win->iconize();
   }
   else if(str == "zoom"){
     if(zoom){
@@ -936,7 +887,6 @@ void window_cb(Fl_Widget *w, void *data)
 #endif
       zoom = 1;
     }
-    FlGui::instance()->menu->win->show();
   }
   else if(str == "front"){
     // the order is important!
@@ -952,10 +902,6 @@ void window_cb(Fl_Widget *w, void *data)
       FlGui::instance()->geoContext->win->show();
     if(FlGui::instance()->meshContext->win->shown())
       FlGui::instance()->meshContext->win->show();
-#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-    if(FlGui::instance()->onelab->shown())
-      FlGui::instance()->onelab->show();
-#endif
     if(FlGui::instance()->visibility->win->shown())
       FlGui::instance()->visibility->win->show();
     if(FlGui::instance()->highordertools->win->shown())
@@ -966,7 +912,6 @@ void window_cb(Fl_Widget *w, void *data)
       FlGui::instance()->manip->win->show();
     if(FlGui::instance()->stats->win->shown())
       FlGui::instance()->stats->win->show();
-    FlGui::instance()->menu->win->show();
   }
 }
 
@@ -986,3 +931,13 @@ void FlGui::saveMessages(const char *fileName)
 {
   FlGui::instance()->graph[0]->saveMessages(fileName);
 }
+
+void FlGui::rebuildTree()
+{
+  onelab->rebuildTree();
+}
+
+void FlGui::openModule(const std::string &name)
+{
+  onelab->openTreeItem("0Gmsh modules/" + name);
+}
diff --git a/Fltk/FlGui.h b/Fltk/FlGui.h
index 5afbdb5873e79cd29a2805e145501396cd0c72de..d58b2135aec4d4f90711398f7e15cdbc255bdd9f 100644
--- a/Fltk/FlGui.h
+++ b/Fltk/FlGui.h
@@ -20,7 +20,6 @@
 
 class graphicWindow;
 class openglWindow;
-class menuWindow;
 class optionWindow;
 class fieldWindow;
 class pluginWindow;
@@ -32,7 +31,7 @@ class manipWindow;
 class geometryContextWindow;
 class meshContextWindow;
 class aboutWindow;
-class onelabWindow;
+class onelabGroup;
 class Fl_Widget;
 
 class GVertex;
@@ -53,7 +52,6 @@ class FlGui{
   std::vector<MElement*> selectedElements;
  public:
   std::vector<graphicWindow*> graph;
-  menuWindow *menu;
   optionWindow *options;
   fieldWindow *fields;
   pluginWindow *plugins;
@@ -65,7 +63,7 @@ class FlGui{
   geometryContextWindow *geoContext;
   meshContextWindow *meshContext;
   aboutWindow *about;
-  onelabWindow *onelab;
+  onelabGroup *onelab;
  public:
   FlGui(int argc, char **argv);
   ~FlGui(){}
@@ -107,7 +105,7 @@ class FlGui{
   // select an entity in the most recent graphic window
   char selectEntity(int type);
   // display status message
-  void setStatus(const char *msg, int num);
+  void setStatus(const char *msg, bool opengl=false);
   // display status message and update progress bar
   void setProgress(const char *msg, double val, double min, double max);
   // create the window for physical context dependant definitions
@@ -118,6 +116,10 @@ class FlGui{
   void showMessages();
   // add line in message console(s)
   void saveMessages(const char *fileName);
+  // rebuild the tree
+  void rebuildTree();
+  // open module in tree
+  void openModule(const std::string &name);
 };
 
 void redraw_cb(Fl_Widget *w, void *data);
diff --git a/Fltk/classificationEditor.cpp b/Fltk/classificationEditor.cpp
index f7607a3bd9adf0007edb9cbd4dab69f24d4b2070..c869db84d06c71287e3fe2b485249d2532556edb 100644
--- a/Fltk/classificationEditor.cpp
+++ b/Fltk/classificationEditor.cpp
@@ -20,7 +20,7 @@
 #include "discreteEdge.h"
 #include "discreteFace.h"
 
-extern GEdge *getNewModelEdge(GFace *gf1, GFace *gf2, 
+extern GEdge *getNewModelEdge(GFace *gf1, GFace *gf2,
                               std::map<std::pair<int, int>, GEdge*> &newEdges);
 
 extern void recurClassifyEdges(MTri3 *t, std::map<MTriangle*, GFace*> &reverse,
@@ -34,8 +34,8 @@ extern void recurClassify(MTri3 *t, GFace *gf,
 
 static void NoElementsSelectedMode(classificationEditor *e)
 {
-  e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->activate(); 
-  e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->activate(); 
+  e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->activate();
+  e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->activate();
 
   e->buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->deactivate();
   e->buttons[CLASS_BUTTON_RESET_SELECTION]->deactivate();
@@ -45,8 +45,8 @@ static void NoElementsSelectedMode(classificationEditor *e)
 
   CTX::instance()->mesh.changed = ENT_ALL;
   CTX::instance()->pickElements = 0;
-  drawContext::global()->draw();  
-  Msg::StatusBar(3, false, "");
+  drawContext::global()->draw();
+  Msg::StatusGl("");
 }
 
 static void ElementsSelectedMode(classificationEditor *e)
@@ -56,14 +56,14 @@ static void ElementsSelectedMode(classificationEditor *e)
   e->toggles[CLASS_TOGGLE_BOUNDARY]->activate();
   e->inputs[CLASS_VALUE_ANGLE]->activate();
 
-  e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->deactivate(); 
-  e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->deactivate(); 
+  e->buttons[CLASS_BUTTON_SELECT_ELEMENTS]->deactivate();
+  e->buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->deactivate();
 }
 
 static void update_edges_cb(Fl_Widget *w, void *data)
 {
   classificationEditor *e = (classificationEditor*)data;
- 
+
   if(!e->selected) return;
 
   for(unsigned int i = 0; i < e->selected->lines.size(); i++)
@@ -75,20 +75,20 @@ static void update_edges_cb(Fl_Widget *w, void *data)
     edge_angle ea = e->edges_detected[i];
     if(ea.angle <= threshold) break;
     e->selected->lines.push_back(new MLine(ea.v1, ea.v2));
-  } 
+  }
 
   if(e->toggles[CLASS_TOGGLE_BOUNDARY]->value()){
     for(unsigned int i = 0 ; i < e->edges_lonly.size(); i++){
       edge_angle ea = e->edges_lonly[i];
       e->selected->lines.push_back(new MLine(ea.v1, ea.v2));
-    } 
+    }
   }
 
   Msg::Info("Edges: %d inside, %d boundary, %d selected", (int)e->edges_detected.size(),
             (int)e->edges_lonly.size(), (int)e->selected->lines.size());
-  
+
   CTX::instance()->mesh.changed = ENT_ALL;
-  drawContext::global()->draw();   
+  drawContext::global()->draw();
 }
 
 static void select_elements_cb(Fl_Widget *w, void *data)
@@ -104,11 +104,11 @@ static void select_elements_cb(Fl_Widget *w, void *data)
   }
 
   if(all){
-    for(GModel::fiter it = GModel::current()->firstFace(); 
+    for(GModel::fiter it = GModel::current()->firstFace();
         it != GModel::current()->lastFace(); ++it){
-      e->elements.insert(e->elements.end(), (*it)->triangles.begin(), 
+      e->elements.insert(e->elements.end(), (*it)->triangles.begin(),
                          (*it)->triangles.end());
-      e->elements.insert(e->elements.end(), (*it)->quadrangles.begin(), 
+      e->elements.insert(e->elements.end(), (*it)->quadrangles.begin(),
                          (*it)->quadrangles.end());
     }
   }
@@ -117,15 +117,15 @@ static void select_elements_cb(Fl_Widget *w, void *data)
     while(1) {
       CTX::instance()->mesh.changed = ENT_ALL;
       drawContext::global()->draw();
-      Msg::StatusBar(3, false, "Select elements\n"
-                     "[Press 'e' to end selection or 'q' to abort]");
-      
+      Msg::StatusGl("Select elements\n"
+                    "[Press 'e' to end selection or 'q' to abort]");
+
       char ib = FlGui::instance()->selectEntity(ENT_ALL);
       if(ib == 'l') {
         for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
           MElement *me = FlGui::instance()->selectedElements[i];
           if(me->getDim() == 2 && me->getVisibility() != 2){
-            me->setVisibility(2); 
+            me->setVisibility(2);
             e->elements.push_back(me);
           }
         }
@@ -156,7 +156,7 @@ static void select_elements_cb(Fl_Widget *w, void *data)
   buildListOfEdgeAngle(adj, e->edges_detected, e->edges_lonly);
   ElementsSelectedMode(e);
   update_edges_cb(0, data);
-  Msg::StatusBar(3, false, "");
+  Msg::StatusGl("");
 }
 
 static void hide_cb(Fl_Widget *w, void *data)
@@ -193,20 +193,20 @@ static void delete_edge_cb(Fl_Widget *w, void *data)
 
   CTX::instance()->pickElements = 1;
   std::vector<MLine*> ele;
-  
+
   while(1) {
     CTX::instance()->mesh.changed = ENT_ALL;
     drawContext::global()->draw();
 
-    Msg::StatusBar(3, false, "Select elements\n"
-                   "[Press 'e' to end selection or 'q' to abort]");
-    
+    Msg::StatusGl("Select elements\n"
+                  "[Press 'e' to end selection or 'q' to abort]");
+
     char ib = FlGui::instance()->selectEntity(ENT_ALL);
     if(ib == 'l') {
       for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
         MElement *me = FlGui::instance()->selectedElements[i];
         if(me->getType() == TYPE_LIN && me->getVisibility() != 2){
-          me->setVisibility(2); 
+          me->setVisibility(2);
           ele.push_back((MLine*)me);
         }
       }
@@ -235,18 +235,18 @@ static void delete_edge_cb(Fl_Widget *w, void *data)
   // look in all selected edges if a deleted one is present and delete it
   std::vector<MLine*> temp = e->selected->lines;
   e->selected->lines.clear();
-  for(unsigned int i = 0; i < temp.size(); i++){      
+  for(unsigned int i = 0; i < temp.size(); i++){
     std::vector<MLine*>::iterator it = std::find(ele.begin(), ele.end(), temp[i]);
-    if(it != ele.end()) 
+    if(it != ele.end())
       delete temp[i];
     else
       e->selected->lines.push_back(temp[i]);
   }
-  
+
   CTX::instance()->mesh.changed = ENT_ALL;
   CTX::instance()->pickElements = 0;
-  drawContext::global()->draw();  
-  Msg::StatusBar(3, false, "");
+  drawContext::global()->draw();
+  Msg::StatusGl("");
 
   e->elements.clear();
   e->edges_detected.clear();
@@ -272,7 +272,7 @@ static void select_surfaces_cb(Fl_Widget *w, void *data)
   bool all = (w == e->buttons[CLASS_BUTTON_SELECT_ALL_SURFACES]);
 
   if(all){
-    for(GModel::fiter it = GModel::current()->firstFace(); 
+    for(GModel::fiter it = GModel::current()->firstFace();
         it != GModel::current()->lastFace(); ++it)
       e->faces.insert(*it);
   }
@@ -282,8 +282,8 @@ static void select_surfaces_cb(Fl_Widget *w, void *data)
     while(1) {
       CTX::instance()->mesh.changed = ENT_ALL;
       drawContext::global()->draw();
-      Msg::StatusBar(3, false, "Select Surface\n"
-                     "[Press 'e' to end selection or 'q' to abort]");
+      Msg::StatusGl("Select Surface\n"
+                    "[Press 'e' to end selection or 'q' to abort]");
       char ib = FlGui::instance()->selectEntity(ENT_SURFACE);
       if(ib == 'l') {
         for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
@@ -308,17 +308,17 @@ static void select_surfaces_cb(Fl_Widget *w, void *data)
     e->buttons[CLASS_BUTTON_CLASSIFY]->activate();
 
   CTX::instance()->mesh.changed = ENT_ALL;
-  drawContext::global()->draw();  
-  Msg::StatusBar(3, false, "");
+  drawContext::global()->draw();
+  Msg::StatusGl("");
 }
 
 static void classify_cb(Fl_Widget *w, void *data)
 {
   classificationEditor *e = (classificationEditor*)data;
   std::map<MLine*, GEdge*, compareMLinePtr> lines;
-  for(GModel::eiter it = GModel::current()->firstEdge(); 
+  for(GModel::eiter it = GModel::current()->firstEdge();
       it != GModel::current()->lastEdge(); ++it){
-    for(unsigned int i = 0; i < (*it)->lines.size();i++) 
+    for(unsigned int i = 0; i < (*it)->lines.size();i++)
       lines[(*it)->lines[i]] = *it;
   }
 
@@ -349,23 +349,23 @@ static void classify_cb(Fl_Widget *w, void *data)
     }
     ++it;
   }
-  
+
   // color some lines
   it = tris.begin();
   while(it != tris.end()){
     (*it)->setDeleted(false);
     ++it;
   }
-  
+
   it = tris.begin();
-  
+
   // classify edges that are bound by different GFaces
   std::map<std::pair<int, int>, GEdge*> newEdges;
   std::set<MLine*> touched;
   std::set<MTri3*> tritouched;
   recurClassifyEdges(*it, reverse, lines, touched, tritouched, newEdges);
-  
-  // check if new edges should not be splitted 
+
+  // check if new edges should not be splitted
   // splitted if composed of several open or closed edges
   for (std::map<std::pair<int, int>, GEdge*>::iterator it = newEdges.begin();
        it != newEdges.end() ; ++it){
@@ -382,7 +382,7 @@ static void classify_cb(Fl_Widget *w, void *data)
       it++;
       for (int i = 0; i < 2; i++) {
         for (std::list<MLine*>::iterator it = segments.begin();
-             it != segments.end(); ++it){ 
+             it != segments.end(); ++it){
           MVertex *v1 = (*it)->getVertex(0);
           MVertex *v2 = (*it)->getVertex(1);
           std::list<MLine*>::iterator itp;
@@ -422,7 +422,7 @@ static void classify_cb(Fl_Widget *w, void *data)
     GEdge *ge = it->second;
     GModel::current()->remove(ge);
   }
-  
+
   while(it != tris.end()){
     delete *it;
     ++it;
@@ -452,13 +452,13 @@ classificationEditor::classificationEditor() : selected(0)
   window = new paletteWindow
     (width, height, CTX::instance()->nonModalWindows ? true : false, "Reclassify 2D");
   window->box(GMSH_WINDOW_BOX);
-  
+
   int x = WB, y = WB;
   {
     Fl_Box *b = new Fl_Box
       (x, y, width, BH, "1. Select mesh elements on which to perform edge detection");
     b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
-    
+
     x += WB;
     y += BH;
     buttons[CLASS_BUTTON_SELECT_ELEMENTS] = new Fl_Button
@@ -468,13 +468,13 @@ classificationEditor::classificationEditor() : selected(0)
     buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS] = new Fl_Button
       (x + BBB + WB, y, (int)(0.5 * BBB) - WB, BH, "All");
     buttons[CLASS_BUTTON_SELECT_ALL_ELEMENTS]->callback(select_elements_cb, this);
-    
+
     toggles[CLASS_TOGGLE_HIDE] = new Fl_Check_Button
-      ((int)(x + 1.5 * BBB + WB), y, (int)(width - 1.5 * BBB - x - 2 * WB), BH, 
+      ((int)(x + 1.5 * BBB + WB), y, (int)(width - 1.5 * BBB - x - 2 * WB), BH,
        "Hide unselected elements");
     toggles[CLASS_TOGGLE_HIDE]->type(FL_TOGGLE_BUTTON);
     toggles[CLASS_TOGGLE_HIDE]->callback(hide_cb, this);
-    
+
     x -= WB;
   }
   {
@@ -488,7 +488,7 @@ classificationEditor::classificationEditor() : selected(0)
     Fl_Box *b = new Fl_Box
       (x, y, width, BH, "2. Fine-tune edge selection");
     b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
-    
+
     x += WB;
     y += BH;
     inputs[CLASS_VALUE_ANGLE] = new Fl_Value_Input
@@ -498,7 +498,7 @@ classificationEditor::classificationEditor() : selected(0)
     inputs[CLASS_VALUE_ANGLE]->minimum(0);
     inputs[CLASS_VALUE_ANGLE]->align(FL_ALIGN_RIGHT);
     inputs[CLASS_VALUE_ANGLE]->step(1);
-    inputs[CLASS_VALUE_ANGLE]->when(FL_WHEN_RELEASE);  
+    inputs[CLASS_VALUE_ANGLE]->when(FL_WHEN_RELEASE);
     inputs[CLASS_VALUE_ANGLE]->callback(update_edges_cb, this);
 
     toggles[CLASS_TOGGLE_SHOW_ONLY_EDGES] = new Fl_Check_Button
@@ -506,24 +506,24 @@ classificationEditor::classificationEditor() : selected(0)
        "Show only edges");
     toggles[CLASS_TOGGLE_SHOW_ONLY_EDGES]->type(FL_TOGGLE_BUTTON);
     toggles[CLASS_TOGGLE_SHOW_ONLY_EDGES]->callback(show_only_edges_cb, this);
-    
+
     y += BH;
     toggles[CLASS_TOGGLE_BOUNDARY] = new Fl_Check_Button
       (x, y, width - x - 2 * WB, BH, "Include edges on boundary (closure)");
     toggles[CLASS_TOGGLE_BOUNDARY]->type(FL_TOGGLE_BUTTON);
     toggles[CLASS_TOGGLE_BOUNDARY]->callback(update_edges_cb, this);
-    
+
     y += BH;
-    buttons[CLASS_BUTTON_DELETE_FROM_SELECTION] = new Fl_Button 
+    buttons[CLASS_BUTTON_DELETE_FROM_SELECTION] = new Fl_Button
       (x, y, (int)(1.5 * BBB), BH, "Delete edges from selection");
-    buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->callback(delete_edge_cb, this);    
+    buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->callback(delete_edge_cb, this);
     buttons[CLASS_BUTTON_DELETE_FROM_SELECTION]->deactivate();
-    
-    buttons[CLASS_BUTTON_RESET_SELECTION] = new Fl_Button 
+
+    buttons[CLASS_BUTTON_RESET_SELECTION] = new Fl_Button
       (x + (int)(1.5 * BBB + WB), y, BBB, BH, "Reset selection");
-    buttons[CLASS_BUTTON_RESET_SELECTION]->callback(reset_selection_cb, this);    
+    buttons[CLASS_BUTTON_RESET_SELECTION]->callback(reset_selection_cb, this);
     buttons[CLASS_BUTTON_RESET_SELECTION]->deactivate();
-    
+
     x -= WB;
   }
   {
@@ -537,7 +537,7 @@ classificationEditor::classificationEditor() : selected(0)
     Fl_Box *b = new Fl_Box
       (x, y, width, BH, "3. Reclassify surfaces using selected edges");
     b->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
-    
+
     x += WB;
     y += BH;
 
@@ -549,7 +549,7 @@ classificationEditor::classificationEditor() : selected(0)
       (x + BBB + WB, y, (int)(0.5 * BBB) - WB, BH, "All");
     buttons[CLASS_BUTTON_SELECT_ALL_SURFACES]->callback(select_surfaces_cb, this);
 
-    buttons[CLASS_BUTTON_CLASSIFY] = new Fl_Return_Button 
+    buttons[CLASS_BUTTON_CLASSIFY] = new Fl_Return_Button
       ((int)(x + 1.5 * BBB + WB), y, BBB, BH, "Reclassify");
     buttons[CLASS_BUTTON_CLASSIFY]->callback(classify_cb, this);
     buttons[CLASS_BUTTON_CLASSIFY]->deactivate();
diff --git a/Fltk/fileDialogs.cpp b/Fltk/fileDialogs.cpp
index f41eb646171200d9be930cab587e5d5056c6782c..c5a51abbbb1fcd6972a7c9aaeee10ad617d3e800 100644
--- a/Fltk/fileDialogs.cpp
+++ b/Fltk/fileDialogs.cpp
@@ -701,9 +701,9 @@ int optionsFileDialog(const char *name)
       Fl_Widget* o = Fl::readqueue();
       if (!o) break;
       if (o == dialog->ok) {
-        Msg::StatusBar(2, true, "Writing '%s'...", name);
+        Msg::StatusBar(true, "Writing '%s'...", name);
         PrintOptions(0, GMSH_FULLRC, dialog->b[0]->value(), dialog->b[1]->value(), name);
-        Msg::StatusBar(2, true, "Done writing '%s'", name);
+        Msg::StatusBar(true, "Done writing '%s'", name);
         dialog->window->hide();
         return 1;
       }
diff --git a/Fltk/graphicWindow.cpp b/Fltk/graphicWindow.cpp
index 311a3721e63fdc0a3bc16a1733c786239de13360..9cc68a765d9fd7d9f1cd1f2321e6719b8e4c3b2b 100644
--- a/Fltk/graphicWindow.cpp
+++ b/Fltk/graphicWindow.cpp
@@ -3,23 +3,2164 @@
 // See the LICENSE.txt file for license information. Please report all
 // bugs and problems to <gmsh@geuz.org>.
 
+#include "GmshConfig.h"
+#include "GmshDefines.h"
+#if !defined(HAVE_NO_STDINT_H)
+#include <stdint.h>
+#elif defined(HAVE_NO_INTPTR_T)
+typedef unsigned long intptr_t;
+#endif
 #include <string.h>
-#include <FL/fl_draw.H>
+#include <stdlib.h>
+#include <stdio.h>
+#include <time.h>
+#include <FL/Fl_Box.H>
 #include <FL/fl_ask.H>
+#include <FL/filename.H>
+#include <FL/fl_draw.H>
+#include <FL/Fl_Tree.H>
 #include "FlGui.h"
-#include "graphicWindow.h"
-#include "paletteWindow.h"
 #include "mainWindow.h"
-#include "menuWindow.h"
+#include "paletteWindow.h"
+#include "graphicWindow.h"
+#include "optionWindow.h"
+#include "statisticsWindow.h"
+#include "contextWindow.h"
+#include "visibilityWindow.h"
+#include "highOrderToolsWindow.h"
+#include "clippingWindow.h"
 #include "manipWindow.h"
-#include "extraDialogs.h"
+#include "fieldWindow.h"
+#include "pluginWindow.h"
+#include "aboutWindow.h"
+#include "onelabGroup.h"
 #include "fileDialogs.h"
+#include "extraDialogs.h"
+#include "partitionDialog.h"
+#include "projectionEditor.h"
+#include "classificationEditor.h"
+#include "GModel.h"
 #include "PView.h"
 #include "PViewData.h"
-#include "OS.h"
+#include "PViewOptions.h"
 #include "OpenFile.h"
+#include "CreateFile.h"
+#include "findLinks.h"
+#include "GeoStringInterface.h"
+#include "CommandLine.h"
 #include "Options.h"
 #include "Context.h"
+#include "StringUtils.h"
+#include "Generator.h"
+#include "HighOrder.h"
+#include "OS.h"
+#if defined(HAVE_3M)
+#include "3M.h"
+#endif
+
+static void file_new_cb(Fl_Widget *w, void *data)
+{
+ test:
+  if(fileChooser(FILE_CHOOSER_CREATE, "New", "",
+                 GModel::current()->getFileName().c_str())) {
+    std::string name = fileChooserGetName(1);
+    if(!StatFile(name)){
+      if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?",
+                   "Cancel", "Erase", 0, name.c_str()))
+        UnlinkFile(name);
+      else
+        goto test;
+    }
+    FILE *fp = fopen(name.c_str(), "w");
+    if(!fp){
+      Msg::Error("Unable to open file '%s'", name.c_str());
+      return;
+    }
+    time_t now;
+    time(&now);
+    fprintf(fp, "// Gmsh project created on %s", ctime(&now));
+    fclose(fp);
+    OpenProject(name);
+    drawContext::global()->draw();
+  }
+}
+
+#if defined(HAVE_NATIVE_FILE_CHOOSER)
+#  define TT "\t"
+#  define NN "\n"
+#else
+#  define TT " ("
+#  define NN ")\t"
+#endif
+
+static const char *input_formats =
+  "All Files" TT "*.*" NN
+  "Geometry - Gmsh GEO" TT "*.geo" NN
+#if defined(HAVE_ACIS)
+  "Geometry - ACIS" TT "*.sat" NN
+#endif
+#if defined(HAVE_OCC)
+  "Geometry - OpenCASCADE BRep" TT "*.brep" NN
+  "Geometry - OpenCASCADE IGES" TT "*.{igs,iges}" NN
+  "Geometry - OpenCASCADE STEP" TT "*.{stp,step}" NN
+#endif
+  "Mesh - Gmsh MSH" TT "*.msh" NN
+  "Mesh - Diffpack 3D" TT "*.diff" NN
+  "Mesh - I-deas Universal" TT "*.unv" NN
+#if defined(HAVE_MED)
+  "Mesh - MED" TT "*.{med,mmed}" NN
+#endif
+  "Mesh - INRIA Medit" TT "*.mesh" NN
+  "Mesh - Nastran Bulk Data File" TT "*.{bdf,nas}" NN
+  "Mesh - Plot3D Structured Mesh" TT "*.p3d" NN
+  "Mesh - STL Surface" TT "*.stl" NN
+  "Mesh - VTK" TT "*.vtk" NN
+  "Mesh - VRML Surface" TT "*.{wrl,vrml}" NN
+  "Mesh - PLY2 Surface" TT "*.ply2" NN
+  "Post-processing - Gmsh POS" TT "*.pos" NN
+#if defined(HAVE_MED)
+  "Post-processing - MED" TT "*.{rmed}" NN
+#endif
+  "Image - BMP" TT "*.bmp" NN
+#if defined(HAVE_LIBJPEG)
+  "Image - JPEG" TT "*.{jpg,jpeg}" NN
+#endif
+  "Image - PBM" TT "*.pbm" NN
+  "Image - PGM" TT "*.pgm" NN
+#if defined(HAVE_LIBPNG)
+  "Image - PNG" TT "*.png" NN
+#endif
+  "Image - PNM" TT "*.pnm" NN
+  "Image - PPM" TT "*.ppm" NN;
+
+static void file_open_cb(Fl_Widget *w, void *data)
+{
+  int n = PView::list.size();
+  if(fileChooser(FILE_CHOOSER_SINGLE, "Open", input_formats,
+                 GModel::current()->getFileName().c_str())) {
+    OpenProject(fileChooserGetName(1));
+    drawContext::global()->draw();
+  }
+  if(n != (int)PView::list.size())
+    FlGui::instance()->openModule("Post-processing");
+  if(CTX::instance()->launchSolverAtStartup >= 0)
+    solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup);
+}
+
+static void file_merge_cb(Fl_Widget *w, void *data)
+{
+  int n = PView::list.size();
+  int f = fileChooser(FILE_CHOOSER_MULTI, "Merge", input_formats,
+                      GModel::current()->getFileName().c_str());
+  if(f) {
+    for(int i = 1; i <= f; i++)
+      MergeFile(fileChooserGetName(i));
+    drawContext::global()->draw();
+  }
+  if(n != (int)PView::list.size())
+    FlGui::instance()->openModule("Post-processing");
+  if(CTX::instance()->launchSolverAtStartup >= 0)
+    solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup);
+}
+
+static void file_open_recent_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  std::string str((const char*)data);
+  int n = PView::list.size();
+  OpenProject(str);
+  drawContext::global()->draw();
+  if(n != (int)PView::list.size())
+    FlGui::instance()->openModule("Post-processing");
+  if(CTX::instance()->launchSolverAtStartup >= 0)
+    solver_cb(0, (void*)CTX::instance()->launchSolverAtStartup);
+}
+
+static void file_clear_cb(Fl_Widget *w, void *data)
+{
+  ClearProject();
+  drawContext::global()->draw();
+}
+
+static void file_remote_cb(Fl_Widget *w, void *data)
+{
+  onelab::localNetworkClient *c;
+  onelab::server::citer it = onelab::server::instance()->findClient("GmshRemote");
+  if(it == onelab::server::instance()->lastClient()){
+    c = new onelab::localNetworkClient("GmshRemote", "");
+    c->setSocketSwitch("-socket");
+  }
+  else
+    c = (onelab::localNetworkClient*)it->second;
+  GmshServer *server = c->getGmshServer();
+
+  std::string str((const char*)data);
+
+  if(str == "start"){
+    if(server){
+      Msg::Error("Cannot start: remote Gmsh is already running");
+      return;
+    }
+    c->setExecutable(connectionChooser());
+    if(c->getExecutable().size()) c->run();
+  }
+  else{
+    if(!server){
+      Msg::Error("Cannot %s: remote Gmsh not running", str.c_str());
+      return;
+    }
+    if(str == "stop"){
+      server->SendString(GmshSocket::GMSH_STOP, "Disconnect!");
+    }
+    else if(str == "merge"){
+      const char *file = fl_input("Merge", "/tmp/data.pos");
+      if(file) server->SendString(GmshSocket::GMSH_MERGE_FILE, file);
+    }
+    else if(str == "clear"){
+      server->SendString(GmshSocket::GMSH_PARSE_STRING, "Delete All;");
+      for(int i = PView::list.size() - 1; i >= 0; i--)
+        if(PView::list[i]->getData()->isRemote()) delete PView::list[i];
+      FlGui::instance()->updateViews();
+      drawContext::global()->draw();
+    }
+    else if(str == "test"){
+      server->SendString(GmshSocket::GMSH_SPEED_TEST, "Speed test");
+    }
+  }
+}
+
+static void file_window_cb(Fl_Widget *w, void *data)
+{
+  std::string str((const char*)data);
+  if(str == "new"){
+    graphicWindow *g1 = FlGui::instance()->graph.back();
+    graphicWindow *g2 = new graphicWindow(false, CTX::instance()->numTiles);
+    FlGui::instance()->graph.push_back(g2);
+    FlGui::instance()->setGraphicTitle(GModel::current()->getFileName());
+    g2->win->resize(g1->win->x() + 10, g1->win->y() + 10,
+                    g1->win->w(), g1->win->h());
+    g2->win->show();
+  }
+  else if(str == "split_h"){
+    FlGui::instance()->splitCurrentOpenglWindow('h');
+  }
+  else if(str == "split_v"){
+    FlGui::instance()->splitCurrentOpenglWindow('v');
+  }
+  else if(str == "split_u"){
+    FlGui::instance()->splitCurrentOpenglWindow('u');
+  }
+  drawContext::global()->draw();
+}
+
+static int _save_msh(const char *name){ return mshFileDialog(name); }
+static int _save_mesh_stat(const char *name){ return meshStatFileDialog(name); }
+static int _save_options(const char *name){ return optionsFileDialog(name); }
+static int _save_geo(const char *name){ return geoFileDialog(name); }
+static int _save_brep(const char *name){ CreateOutputFile(name, FORMAT_BREP); return 1; }
+static int _save_step(const char *name){ CreateOutputFile(name, FORMAT_STEP); return 1; }
+static int _save_cgns(const char *name){ return cgnsFileDialog(name); }
+static int _save_unv(const char *name){ return unvFileDialog(name); }
+static int _save_vtk(const char *name){ return genericMeshFileDialog
+    (name, "VTK Options", FORMAT_VTK, true, false); }
+static int _save_diff(const char *name){ return genericMeshFileDialog
+    (name, "Diffpack Options", FORMAT_DIFF, true, false); }
+static int _save_inp(const char *name){ return genericMeshFileDialog
+    (name, "Abaqus INP Options", FORMAT_INP, false, false); }
+static int _save_med(const char *name){ return genericMeshFileDialog
+    (name, "MED Options", FORMAT_MED, false, false); }
+static int _save_mesh(const char *name){ return genericMeshFileDialog
+    (name, "MESH Options", FORMAT_MESH, false, true); }
+static int _save_mail(const char *name){ return genericMeshFileDialog
+    (name, "MAIL Options", FORMAT_MAIL, false, false); }
+static int _save_bdf(const char *name){ return bdfFileDialog(name); }
+static int _save_p3d(const char *name){ return genericMeshFileDialog
+    (name, "P3D Options", FORMAT_P3D, false, false); }
+static int _save_ir3(const char *name){ return genericMeshFileDialog
+    (name, "Iridium Options", FORMAT_IR3, false, true); }
+static int _save_stl(const char *name){ return genericMeshFileDialog
+    (name, "STL Options", FORMAT_STL, true, false); }
+static int _save_vrml(const char *name){ return genericMeshFileDialog
+    (name, "VRML Options", FORMAT_VRML, false, false); }
+static int _save_ply2(const char *name){ return genericMeshFileDialog
+    (name, "PLY2 Options", FORMAT_PLY2, false, false); }
+static int _save_eps(const char *name){ return gl2psFileDialog
+    (name, "EPS Options", FORMAT_EPS); }
+static int _save_gif(const char *name){ return gifFileDialog(name); }
+static int _save_jpeg(const char *name){ return jpegFileDialog(name); }
+static int _save_mpeg(const char *name){ return mpegFileDialog(name); }
+static int _save_tex(const char *name){ return latexFileDialog(name); }
+static int _save_pdf(const char *name){ return gl2psFileDialog
+    (name, "PDF Options", FORMAT_PDF); }
+static int _save_png(const char *name){ return genericBitmapFileDialog
+    (name, "PNG Options", FORMAT_PNG); }
+static int _save_ps(const char *name){ return gl2psFileDialog
+    (name, "PS Options", FORMAT_PS); }
+static int _save_ppm(const char *name){ return genericBitmapFileDialog
+    (name, "PPM Options", FORMAT_PPM); }
+static int _save_svg(const char *name){ return gl2psFileDialog
+    (name, "SVG Options", FORMAT_SVG); }
+static int _save_yuv(const char *name){ return genericBitmapFileDialog
+    (name, "YUV Options", FORMAT_YUV); }
+static int _save_view_pos(const char *name){ return posFileDialog(name); }
+static int _save_view_med(const char *name){ return genericViewFileDialog
+    (name, "MED Options", 6); }
+static int _save_view_txt(const char *name){ return genericViewFileDialog
+    (name, "TXT Options", 4); }
+
+static int _save_auto(const char *name)
+{
+  switch(GuessFileFormatFromFileName(name)){
+  case FORMAT_MSH  : return _save_msh(name);
+  case FORMAT_POS  : return _save_view_pos(name);
+  case FORMAT_TXT  : return _save_view_txt(name);
+  case FORMAT_OPT  : return _save_options(name);
+  case FORMAT_GEO  : return _save_geo(name);
+  case FORMAT_BREP : return _save_brep(name);
+  case FORMAT_STEP : return _save_step(name);
+  case FORMAT_CGNS : return _save_cgns(name);
+  case FORMAT_UNV  : return _save_unv(name);
+  case FORMAT_VTK  : return _save_vtk(name);
+  case FORMAT_MED  : return _save_med(name);
+  case FORMAT_RMED : return _save_view_med(name);
+  case FORMAT_MESH : return _save_mesh(name);
+  case FORMAT_MAIL : return _save_mail(name);
+  case FORMAT_BDF  : return _save_bdf(name);
+  case FORMAT_DIFF : return _save_diff(name);
+  case FORMAT_INP  : return _save_inp(name);
+  case FORMAT_P3D  : return _save_p3d(name);
+  case FORMAT_IR3  : return _save_ir3(name);
+  case FORMAT_STL  : return _save_stl(name);
+  case FORMAT_VRML : return _save_vrml(name);
+  case FORMAT_PLY2 : return _save_ply2(name);
+  case FORMAT_EPS  : return _save_eps(name);
+  case FORMAT_GIF  : return _save_gif(name);
+  case FORMAT_JPEG : return _save_jpeg(name);
+  case FORMAT_MPEG : return _save_mpeg(name);
+  case FORMAT_TEX  : return _save_tex(name);
+  case FORMAT_PDF  : return _save_pdf(name);
+  case FORMAT_PNG  : return _save_png(name);
+  case FORMAT_PS   : return _save_ps(name);
+  case FORMAT_PPM  : return _save_ppm(name);
+  case FORMAT_SVG  : return _save_svg(name);
+  case FORMAT_YUV  : return _save_yuv(name);
+  default :
+    CreateOutputFile(name, FORMAT_AUTO);
+    return 1;
+  }
+}
+
+typedef struct{
+  const char *pat;
+  int (*func) (const char *name);
+} patXfunc;
+
+static void file_save_as_cb(Fl_Widget *w, void *data)
+{
+  static patXfunc formats[] = {
+    {"Guess From Extension" TT "*.*", _save_auto},
+    {"Geometry - Gmsh Options" TT "*.opt", _save_options},
+    {"Geometry - Gmsh Unrolled GEO" TT "*.geo", _save_geo},
+#if defined(HAVE_OCC)
+    {"Geometry - OpenCASCADE STEP" TT "*.step", _save_step},
+    {"Geometry - OpenCASCADE BRep" TT "*.brep", _save_brep},
+#endif
+    {"Mesh - Gmsh MSH" TT "*.msh", _save_msh},
+    {"Mesh - Abaqus INP" TT "*.inp", _save_inp},
+#if defined(HAVE_LIBCGNS)
+    {"Mesh - CGNS (Experimental)" TT "*.cgns", _save_cgns},
+#endif
+    {"Mesh - Diffpack 3D" TT "*.diff", _save_diff},
+    {"Mesh - I-deas Universal" TT "*.unv", _save_unv},
+    {"Mesh - Iridum" TT "*.ir3", _save_ir3},
+#if defined(HAVE_MED)
+    {"Mesh - MED" TT "*.med", _save_med},
+#endif
+    {"Mesh - INRIA Medit" TT "*.mesh", _save_mesh},
+    {"Mesh - CEA Triangulation" TT "*.mail", _save_mail},
+    {"Mesh - Nastran Bulk Data File" TT "*.bdf", _save_bdf},
+    {"Mesh - Plot3D Structured Mesh" TT "*.p3d", _save_p3d},
+    {"Mesh - STL Surface" TT "*.stl", _save_stl},
+    {"Mesh - VRML Surface" TT "*.wrl", _save_vrml},
+    {"Mesh - VTK" TT "*.vtk", _save_vtk},
+    {"Mesh - PLY2 Surface" TT "*.ply2", _save_ply2},
+    {"Post-processing - Gmsh POS" TT "*.pos", _save_view_pos},
+#if defined(HAVE_MED)
+    {"Post-processing - MED" TT "*.rmed", _save_view_med},
+#endif
+    {"Post-processing - Generic TXT" TT "*.txt", _save_view_txt},
+    {"Post-processing - Mesh Statistics" TT "*.pos", _save_mesh_stat},
+    {"Image - Encapsulated PostScript" TT "*.eps", _save_eps},
+    {"Image - GIF" TT "*.gif", _save_gif},
+#if defined(HAVE_LIBJPEG)
+    {"Image - JPEG" TT "*.jpg", _save_jpeg},
+#endif
+    {"Image - LaTeX" TT "*.tex", _save_tex},
+    {"Image - PDF" TT "*.pdf", _save_pdf},
+#if defined(HAVE_LIBPNG)
+    {"Image - PNG" TT "*.png", _save_png},
+#endif
+    {"Image - PostScript" TT "*.ps", _save_ps},
+    {"Image - PPM" TT "*.ppm", _save_ppm},
+    {"Image - SVG" TT "*.svg", _save_svg},
+    {"Image - YUV" TT "*.yuv", _save_yuv},
+#if defined(HAVE_MPEG_ENCODE)
+    {"Movie - MPEG" TT "*.mpg", _save_mpeg},
+#endif
+  };
+  int nbformats = sizeof(formats) / sizeof(formats[0]);
+  static char *pat = 0;
+  if(!pat) {
+    pat = new char[nbformats * 256];
+    strcpy(pat, formats[0].pat);
+    for(int i = 1; i < nbformats; i++) {
+      strcat(pat, NN);
+      strcat(pat, formats[i].pat);
+    }
+  }
+
+ test:
+  if(fileChooser(FILE_CHOOSER_CREATE, "Save As", pat,
+                 GModel::current()->getFileName().c_str())) {
+    std::string name = fileChooserGetName(1);
+    if(CTX::instance()->confirmOverwrite) {
+      if(!StatFile(name))
+        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
+                      "Cancel", "Replace", 0, name.c_str()))
+          goto test;
+    }
+    int i = fileChooserGetFilter();
+    if(i >= 0 && i < nbformats){
+      if(!formats[i].func(name.c_str())) goto test;
+    }
+    else{ // handle any additional automatic fltk filter
+      if(!_save_auto(name.c_str())) goto test;
+    }
+  }
+}
+
+#undef TT
+#undef NN
+
+static void file_options_save_cb(Fl_Widget *w, void *data)
+{
+  std::string str((const char*)data), fileName;
+  if(str == "file")
+    fileName = GModel::current()->getFileName() + ".opt";
+  else
+    fileName = CTX::instance()->homeDir + CTX::instance()->optionsFileName;
+  Msg::StatusBar(true, "Writing '%s'...", fileName.c_str());
+  if(str == "file")
+    PrintOptions(0, GMSH_FULLRC, 1, 0, fileName.c_str());
+  else
+    PrintOptions(0, GMSH_OPTIONSRC, 1, 1, fileName.c_str());
+  Msg::StatusBar(true, "Done writing '%s'", fileName.c_str());
+}
+
+static void file_rename_cb(Fl_Widget *w, void *data)
+{
+ test:
+  if(fileChooser(FILE_CHOOSER_CREATE, "Rename", "",
+                 GModel::current()->getFileName().c_str())) {
+    std::string name = fileChooserGetName(1);
+    if(CTX::instance()->confirmOverwrite) {
+      if(!StatFile(name))
+        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
+                      "Cancel", "Replace", 0, name.c_str()))
+          goto test;
+    }
+    rename(GModel::current()->getFileName().c_str(), name.c_str());
+    GModel::current()->setFileName(name);
+    GModel::current()->setName(SplitFileName(name)[1]);
+    FlGui::instance()->setGraphicTitle(GModel::current()->getFileName());
+    drawContext::global()->draw();
+  }
+}
+
+void file_quit_cb(Fl_Widget *w, void *data)
+{
+  Msg::Exit(0);
+}
+
+void file_watch_cb(Fl_Widget *w, void *data)
+{
+  if(w) CTX::instance()->watchFilePattern = patternChooser();
+
+  if(CTX::instance()->watchFilePattern.empty()) return;
+
+  std::string pattern = FixRelativePath
+    (GModel::current()->getFileName(), CTX::instance()->watchFilePattern);
+  std::string directory = SplitFileName(pattern)[0];
+  if(directory.empty()) directory = "./";
+
+  dirent **files = 0;
+  int num = fl_filename_list(directory.c_str(), &files, fl_numericsort);
+  if(num <= 0) return;
+  std::vector<std::string> matches;
+  for (int i = 0; i < num; i++) {
+    std::string name = directory + files[i]->d_name;
+    if(fl_filename_match(name.c_str(), pattern.c_str()))
+      matches.push_back(name);
+    free((void*)files[i]);
+  }
+  if(files) free((void*)files);
+
+  Msg::Info("%d match%s for pattern '%s'", (int)matches.size(),
+            (matches.size() > 1) ? "es" : "", pattern.c_str());
+
+  std::set<std::string> allFiles;
+  for(unsigned int i = 0; i < GModel::list.size(); i++)
+    allFiles.insert(GetFileNameWithoutPath(GModel::list[i]->getFileName()));
+  for(unsigned int i = 0; i < PView::list.size(); i++)
+    for(int j = 0; j < PView::list[i]->getData()->getNumTimeSteps(); j++)
+      allFiles.insert(GetFileNameWithoutPath(PView::list[i]->getData()->getFileName(j)));
+
+  for(unsigned int i = 0; i < matches.size(); i++)
+    if(allFiles.find(GetFileNameWithoutPath(matches[i])) == allFiles.end())
+      MergeFile(matches[i]);
+  drawContext::global()->draw();
+}
+
+#if defined(__APPLE__)
+#  define CC(str) "Cmd+" str " "
+#else
+#  define CC(str) "Ctrl+" str
+#endif
+
+static void help_short_cb(Fl_Widget *w, void *data)
+{
+  Msg::Direct(" ");
+  Msg::Direct("Keyboard shortcuts:");
+  Msg::Direct(" ");
+  Msg::Direct("  Left arrow    Go to previous time step");
+  Msg::Direct("  Right arrow   Go to next time step");
+  Msg::Direct("  Up arrow      Make previous view visible");
+  Msg::Direct("  Down arrow    Make next view visible");
+  Msg::Direct(" ");
+  Msg::Direct("  <             Go back to previous context");
+  Msg::Direct("  >             Go forward to next context");
+  Msg::Direct("  0             Reload project file");
+  Msg::Direct("  1 or F1       Mesh lines");
+  Msg::Direct("  2 or F2       Mesh surfaces");
+  Msg::Direct("  3 or F3       Mesh volumes");
+  Msg::Direct("  Escape        Cancel lasso zoom/selection, toggle mouse selection ON/OFF");
+  Msg::Direct(" ");
+  Msg::Direct("  g             Go to geometry module");
+  Msg::Direct("  m             Go to mesh module");
+  Msg::Direct("  p             Go to post-processing module");
+  Msg::Direct("  s             Go to solver module");
+  Msg::Direct(" ");
+  Msg::Direct("  Shift+a       Bring all windows to front");
+  Msg::Direct("  Shift+g       Show geometry options");
+  Msg::Direct("  Shift+m       Show mesh options");
+  Msg::Direct("  Shift+o       Show general options");
+  Msg::Direct("  Shift+p       Show post-processing options");
+  Msg::Direct("  Shift+s       Show solver options");
+  Msg::Direct("  Shift+u       Show post-processing view plugins");
+  Msg::Direct("  Shift+w       Show post-processing view options");
+  Msg::Direct("  Shift+Escape  Enable full mouse selection");
+  Msg::Direct(" ");
+  Msg::Direct("  " CC("i") "        Show statistics window");
+  Msg::Direct("  " CC("l") "        Show message console");
+#if defined(__APPLE__)
+  Msg::Direct("  " CC("m") "        Minimize window");
+#endif
+  Msg::Direct("  " CC("n") "        Create new project file");
+  Msg::Direct("  " CC("o") "        Open project file");
+  Msg::Direct("  " CC("q") "        Quit");
+  Msg::Direct("  " CC("r") "        Rename project file");
+  Msg::Direct("  " CC("s") "        Save file as");
+  Msg::Direct(" ");
+  Msg::Direct("  Shift+" CC("c") "  Show clipping plane window");
+  Msg::Direct("  Shift+" CC("m") "  Show manipulator window");
+  Msg::Direct("  Shift+" CC("n") "  Show option window");
+  Msg::Direct("  Shift+" CC("o") "  Merge file(s)");
+  Msg::Direct("  Shift+" CC("s") "  Save mesh in default format");
+  Msg::Direct("  Shift+" CC("u") "  Show plugin window");
+  Msg::Direct("  Shift+" CC("v") "  Show visibility window");
+  Msg::Direct(" ");
+  Msg::Direct("  Alt+a         Loop through axes modes");
+  Msg::Direct("  Alt+b         Hide/show bounding boxes");
+  Msg::Direct("  Alt+c         Loop through predefined color schemes");
+  Msg::Direct("  Alt+e         Hide/Show element outlines for visible post-pro views");
+  Msg::Direct("  Alt+f         Change redraw mode (fast/full)");
+  Msg::Direct("  Alt+h         Hide/show all post-processing views");
+  Msg::Direct("  Alt+i         Hide/show all post-processing view scales");
+  Msg::Direct("  Alt+l         Hide/show geometry lines");
+  Msg::Direct("  Alt+m         Toggle visibility of all mesh entities");
+  Msg::Direct("  Alt+n         Hide/show all post-processing view annotations");
+  Msg::Direct("  Alt+o         Change projection mode (orthographic/perspective)");
+  Msg::Direct("  Alt+p         Hide/show geometry points");
+  Msg::Direct("  Alt+r         Loop through range modes for visible post-pro views");
+  Msg::Direct("  Alt+s         Hide/show geometry surfaces");
+  Msg::Direct("  Alt+t         Loop through interval modes for visible post-pro views");
+  Msg::Direct("  Alt+v         Hide/show geometry volumes");
+  Msg::Direct("  Alt+w         Enable/disable all lighting");
+  Msg::Direct("  Alt+x         Set X view");
+  Msg::Direct("  Alt+y         Set Y view");
+  Msg::Direct("  Alt+z         Set Z view");
+  Msg::Direct(" ");
+  Msg::Direct("  Alt+Shift+a   Hide/show small axes");
+  Msg::Direct("  Alt+Shift+b   Hide/show mesh volume faces");
+  Msg::Direct("  Alt+Shift+d   Hide/show mesh surface faces");
+  Msg::Direct("  Alt+Shift+l   Hide/show mesh lines");
+  Msg::Direct("  Alt+Shift+o   Adjust projection parameters");
+  Msg::Direct("  Alt+Shift+p   Hide/show mesh points");
+  Msg::Direct("  Alt+Shift+s   Hide/show mesh surface edges");
+  Msg::Direct("  Alt+Shift+v   Hide/show mesh volume edges");
+  Msg::Direct("  Alt+Shift+w   Reverse all mesh normals");
+  Msg::Direct("  Alt+Shift+x   Set -X view");
+  Msg::Direct("  Alt+Shift+y   Set -Y view");
+  Msg::Direct("  Alt+Shift+z   Set -Z view");
+  Msg::Direct(" ");
+  FlGui::instance()->showMessages();
+}
+
+#undef CC
+
+static void help_mouse_cb(Fl_Widget *w, void *data)
+{
+  Msg::Direct(" ");
+  Msg::Direct("Mouse actions:");
+  Msg::Direct(" ");
+  Msg::Direct("  Move                - Highlight the entity under the mouse pointer");
+  Msg::Direct("                        and display its properties in the status bar");
+  Msg::Direct("                      - Resize a lasso zoom or a lasso (un)selection");
+  Msg::Direct("  Left button         - Rotate");
+  Msg::Direct("                      - Select an entity");
+  Msg::Direct("                      - Accept a lasso zoom or a lasso selection");
+  Msg::Direct("  Ctrl+Left button    Start a lasso zoom or a lasso (un)selection");
+  Msg::Direct("  Middle button       - Zoom");
+  Msg::Direct("                      - Unselect an entity");
+  Msg::Direct("                      - Accept a lasso zoom or a lasso unselection");
+  Msg::Direct("  Ctrl+Middle button  Orthogonalize display");
+  Msg::Direct("  Right button        - Pan");
+  Msg::Direct("                      - Cancel a lasso zoom or a lasso (un)selection");
+  Msg::Direct("                      - Pop-up menu on post-processing view button");
+  Msg::Direct("  Ctrl+Right button   Reset to default viewpoint");
+  Msg::Direct(" ");
+  Msg::Direct("  For a 2 button mouse, Middle button = Shift+Left button");
+  Msg::Direct("  For a 1 button mouse, Middle button = Shift+Left button, "
+              "Right button = Alt+Left button");
+  Msg::Direct(" ");
+  FlGui::instance()->showMessages();
+}
+
+static void help_command_line_cb(Fl_Widget *w, void *data)
+{
+  Msg::Direct(" ");
+  PrintUsage("gmsh");
+  FlGui::instance()->showMessages();
+}
+
+static void help_online_cb(Fl_Widget *w, void *data)
+{
+  std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
+  SystemCall(ReplaceSubString("%s", "http://geuz.org/gmsh/doc/texinfo/", prog));
+}
+
+void help_about_cb(Fl_Widget *w, void *data)
+{
+  FlGui::instance()->about->win->show();
+}
+
+static void geometry_edit_cb(Fl_Widget *w, void *data)
+{
+  std::string prog = FixWindowsPath(CTX::instance()->editor);
+  std::string file = FixWindowsPath(GModel::current()->getFileName());
+  SystemCall(ReplaceSubString("%s", file, prog));
+}
+
+void geometry_reload_cb(Fl_Widget *w, void *data)
+{
+  std::string fileName = GModel::current()->getFileName();
+  OpenProject(fileName);
+  drawContext::global()->draw();
+}
+
+static void add_new_point()
+{
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+
+  FlGui::instance()->geoContext->show(1);
+
+  while(1) {
+    for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
+      for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
+        FlGui::instance()->graph[i]->gl[j]->addPointMode = true;
+    Msg::StatusGl("Move mouse and/or enter coordinates\n"
+                  "[Press 'Shift' to hold position, 'e' to add point "
+                  "or 'q' to abort]");
+    char ib = FlGui::instance()->selectEntity(ENT_NONE);
+    if(ib == 'e'){
+      add_point(GModel::current()->getFileName(),
+                FlGui::instance()->geoContext->input[2]->value(),
+                FlGui::instance()->geoContext->input[3]->value(),
+                FlGui::instance()->geoContext->input[4]->value(),
+                FlGui::instance()->geoContext->input[5]->value());
+      FlGui::instance()->resetVisibility();
+      drawContext::global()->draw();
+    }
+    if(ib == 'q'){
+      for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
+        for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
+          FlGui::instance()->graph[i]->gl[j]->addPointMode = false;
+      break;
+    }
+  }
+
+  // at the end, not during creation to avoid having things jumping around
+  SetBoundingBox();
+  Msg::StatusGl("");
+}
+
+static void add_new_multiline(std::string type)
+{
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+
+  std::vector<int> p;
+  while(1) {
+    if(p.empty())
+      Msg::StatusGl("Select control points\n"
+                    "[Press 'e' to end selection or 'q' to abort]");
+    else
+      Msg::StatusGl("Select control points\n"
+                    "[Press 'e' to end selection, 'u' to undo last selection "
+                    "or 'q' to abort]");
+    char ib = FlGui::instance()->selectEntity(ENT_POINT);
+    if(ib == 'l') {
+      for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+        FlGui::instance()->selectedVertices[i]->setSelection(1);
+        p.push_back(FlGui::instance()->selectedVertices[i]->tag());
+      }
+      drawContext::global()->draw();
+    }
+    if(ib == 'r') {
+      Msg::Warning("Entity de-selection not supported yet during multi-line creation");
+    }
+    if(ib == 'e') {
+      if(p.size() >= 2)
+        add_multline(type, p, GModel::current()->getFileName());
+      FlGui::instance()->resetVisibility();
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      p.clear();
+    }
+    if(ib == 'u') {
+      if(p.size()){
+        GVertex *gv = GModel::current()->getVertexByTag(p.back());
+        if(gv) gv->setSelection(0);
+        drawContext::global()->draw();
+        p.pop_back();
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      break;
+    }
+  }
+
+  Msg::StatusGl("");
+}
+
+static void add_new_line()
+{
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+
+  std::vector<int> p;
+  while(1) {
+    if(p.empty())
+      Msg::StatusGl("Select start point\n"
+                    "[Press 'q' to abort]");
+    if(p.size() == 1)
+      Msg::StatusGl("Select end point\n"
+                    "[Press 'u' to undo last selection or 'q' to abort]");
+    char ib = FlGui::instance()->selectEntity(ENT_POINT);
+    if(ib == 'l') {
+      FlGui::instance()->selectedVertices[0]->setSelection(1);
+      drawContext::global()->draw();
+      p.push_back(FlGui::instance()->selectedVertices[0]->tag());
+    }
+    if(ib == 'r') {
+      Msg::Warning("Entity de-selection not supported yet during line creation");
+    }
+    if(ib == 'u') {
+      if(p.size()){
+        GVertex *gv = GModel::current()->getVertexByTag(p.back());
+        if(gv) gv->setSelection(0);
+        drawContext::global()->draw();
+        p.pop_back();
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      break;
+    }
+    if(p.size() == 2) {
+      add_multline("Line", p, GModel::current()->getFileName());
+      FlGui::instance()->resetVisibility();
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      p.clear();
+    }
+  }
+
+  Msg::StatusGl("");
+}
+
+static void add_new_circle()
+{
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+
+  std::vector<int> p;
+  while(1) {
+    if(p.empty())
+      Msg::StatusGl("Select start point\n"
+                    "[Press 'q' to abort]");
+    if(p.size() == 1)
+      Msg::StatusGl("Select center point\n"
+                    "[Press 'u' to undo last selection or 'q' to abort]");
+    if(p.size() == 2)
+      Msg::StatusGl("Select end point\n"
+                    "[Press 'u' to undo last selection or 'q' to abort]");
+    char ib = FlGui::instance()->selectEntity(ENT_POINT);
+    if(ib == 'l') {
+      FlGui::instance()->selectedVertices[0]->setSelection(1);
+      drawContext::global()->draw();
+      p.push_back(FlGui::instance()->selectedVertices[0]->tag());
+    }
+    if(ib == 'r') {
+      Msg::Warning("Entity de-selection not supported yet during circle creation");
+    }
+    if(ib == 'u') {
+      if(p.size()){
+        GVertex *gv = GModel::current()->getVertexByTag(p.back());
+        if(gv) gv->setSelection(0);
+        drawContext::global()->draw();
+        p.pop_back();
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      break;
+    }
+    if(p.size() == 3) {
+      add_circ(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end
+      FlGui::instance()->resetVisibility();
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      p.clear();
+    }
+  }
+
+  Msg::StatusGl("");
+}
+
+static void add_new_ellipse()
+{
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+
+  std::vector<int> p;
+  while(1) {
+    if(p.empty())
+      Msg::StatusGl("Select start point\n"
+                    "[Press 'q' to abort]");
+    if(p.size() == 1)
+      Msg::StatusGl("Select center point\n"
+                    "[Press 'u' to undo last selection or 'q' to abort]");
+    if(p.size() == 2)
+      Msg::StatusGl("Select major axis point\n"
+                    "[Press 'u' to undo last selection or 'q' to abort]");
+    if(p.size() == 3)
+      Msg::StatusGl("Select end point\n"
+                    "[Press 'u' to undo last selection or 'q' to abort]");
+    char ib = FlGui::instance()->selectEntity(ENT_POINT);
+    if(ib == 'l') {
+      FlGui::instance()->selectedVertices[0]->setSelection(1);
+      drawContext::global()->draw();
+      p.push_back(FlGui::instance()->selectedVertices[0]->tag());
+    }
+    if(ib == 'r') {
+      Msg::Warning("Entity de-selection not supported yet during ellipse creation");
+    }
+    if(ib == 'u') {
+      if(p.size()){
+        GVertex *gv = GModel::current()->getVertexByTag(p.back());
+        if(gv) gv->setSelection(0);
+        drawContext::global()->draw();
+        p.pop_back();
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      break;
+    }
+    if(p.size() == 4) {
+      add_ell(p[0], p[1], p[2], p[3], GModel::current()->getFileName());
+      FlGui::instance()->resetVisibility();
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      p.clear();
+    }
+  }
+
+  Msg::StatusGl("");
+}
+
+static int select_contour(int type, int num, List_T * List)
+{
+  int k = 0;
+
+  switch (type) {
+  case ENT_LINE:
+    k = allEdgesLinked(num, List);
+    for(int i = 0; i < List_Nbr(List); i++) {
+      int ip;
+      List_Read(List, i, &ip);
+      GEdge *ge = GModel::current()->getEdgeByTag(abs(ip));
+      if(ge) ge->setSelection(1);
+    }
+    break;
+  case ENT_SURFACE:
+    k = allFacesLinked(num, List);
+    for(int i = 0; i < List_Nbr(List); i++) {
+      int ip;
+      List_Read(List, i, &ip);
+      GFace *gf = GModel::current()->getFaceByTag(abs(ip));
+      if(gf) gf->setSelection(1);
+    }
+    break;
+  }
+
+  drawContext::global()->draw();
+  return k;
+}
+
+static void add_new_surface_volume(int mode)
+{
+  List_T *List1 = List_Create(10, 10, sizeof(int));
+  List_T *List2 = List_Create(10, 10, sizeof(int));
+  int type;
+  if(mode == 2) {
+    type = ENT_SURFACE;
+    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else {
+    type = ENT_LINE;
+    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  drawContext::global()->draw();
+
+  while(1) {
+    List_Reset(List1);
+    List_Reset(List2);
+
+    while(1) {
+      if(type == ENT_LINE){
+        if(!List_Nbr(List1))
+          Msg::StatusGl("Select surface boundary\n"
+                        "[Press 'q' to abort]");
+        else
+          Msg::StatusGl("Select surface boundary\n"
+                        "[Press 'u' to undo last selection or 'q' to abort]");
+      }
+      else{
+        if(!List_Nbr(List1))
+          Msg::StatusGl("Select volume boundary\n"
+                        "[Press 'q' to abort]");
+        else
+          Msg::StatusGl("Select volume boundary\n"
+                        "[Press 'u' to undo last selection or 'q' to abort]");
+      }
+
+      char ib = FlGui::instance()->selectEntity(type);
+      if(ib == 'q') {
+        GModel::current()->setSelection(0);
+        drawContext::global()->draw();
+        goto stopall;
+      }
+      if(ib == 'u') {
+        if(List_Nbr(List1) > 0){
+          int num;
+          List_Read(List1, List_Nbr(List1)-1, &num);
+          if(type == ENT_LINE){
+            GEdge *ge = GModel::current()->getEdgeByTag(abs(num));
+            if(ge) ge->setSelection(0);
+          }
+          else{
+            GFace *gf = GModel::current()->getFaceByTag(abs(num));
+            if(gf) gf->setSelection(0);
+          }
+          List_Pop(List1);
+          drawContext::global()->draw();
+        }
+      }
+      if(ib == 'r') {
+        Msg::Warning("Entity de-selection not supported yet during "
+                     "surface/volume creation");
+      }
+      if(ib == 'l') {
+        int num = (type == ENT_LINE) ?
+          FlGui::instance()->selectedEdges[0]->tag() :
+          FlGui::instance()->selectedFaces[0]->tag();
+        if(select_contour(type, num, List1)) {
+          if(type == ENT_LINE)
+            add_lineloop(List1, GModel::current()->getFileName(), &num);
+          else
+            add_surfloop(List1, GModel::current()->getFileName(), &num);
+          List_Reset(List1);
+          List_Add(List2, &num);
+          while(1) {
+            if(!List_Nbr(List1))
+              Msg::StatusGl("Select hole boundaries (if none, press 'e')\n"
+                            "[Press 'e' to end selection or 'q' to abort]");
+            else
+              Msg::StatusGl("Select hole boundaries\n"
+                            "[Press 'e' to end selection, 'u' to undo last selection "
+                            "or 'q' to abort]");
+            ib = FlGui::instance()->selectEntity(type);
+            if(ib == 'q') {
+              GModel::current()->setSelection(0);
+              drawContext::global()->draw();
+              goto stopall;
+            }
+            if(ib == 'e') {
+              GModel::current()->setSelection(0);
+              drawContext::global()->draw();
+              List_Reset(List1);
+              break;
+            }
+            if(ib == 'u') {
+              if(List_Nbr(List1) > 0){
+                int num;
+                List_Read(List1, List_Nbr(List1)-1, &num);
+                if(type == ENT_LINE){
+                  GEdge *ge = GModel::current()->getEdgeByTag(abs(num));
+                  if(ge) ge->setSelection(0);
+                }
+                else{
+                  GFace *gf = GModel::current()->getFaceByTag(abs(num));
+                  if(gf) gf->setSelection(0);
+                }
+                List_Pop(List1);
+                drawContext::global()->draw();
+              }
+            }
+            if(ib == 'l') {
+              int size = (type == ENT_LINE) ?
+                FlGui::instance()->selectedEdges.size() :
+                FlGui::instance()->selectedFaces.size();
+              for(int i=0;i<size;i++){
+                int num = (type == ENT_LINE) ?
+                  FlGui::instance()->selectedEdges[i]->tag() :
+                  FlGui::instance()->selectedFaces[i]->tag();
+                if(select_contour(type, num, List1)) {
+                  if(type == ENT_LINE)
+                    add_lineloop(List1, GModel::current()->getFileName(), &num);
+                  else
+                    add_surfloop(List1, GModel::current()->getFileName(), &num);
+                  List_Reset(List1);
+                  List_Add(List2, &num);
+                }
+              }
+            }
+            if(ib == 'r') {
+              Msg::Warning("Entity de-selection not supported yet during "
+                           "surface/volume creation");
+            }
+          }
+          List_Unique(List2,fcmp_absint);
+          if(List_Nbr(List2)) {
+            switch (mode) {
+            case 0: add_surf("Plane Surface", List2,
+                             GModel::current()->getFileName()); break;
+            case 1: add_surf("Ruled Surface", List2,
+                             GModel::current()->getFileName()); break;
+            case 2: add_vol(List2, GModel::current()->getFileName()); break;
+            }
+            FlGui::instance()->resetVisibility();
+            GModel::current()->setSelection(0);
+            drawContext::global()->draw();
+            break;
+          }
+        } // if select_contour
+      }
+    }
+  }
+
+ stopall:
+  List_Delete(List1);
+  List_Delete(List2);
+
+  Msg::StatusGl("");
+}
+
+static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+
+  std::string str((const char*)data);
+  if(str == "Parameter")
+    FlGui::instance()->geoContext->show(0);
+  else if(str == "Point")
+    add_new_point();
+  else if(str == "Line")
+    add_new_line();
+  else if(str == "Spline")
+    add_new_multiline(str);
+  else if(str == "BSpline")
+    add_new_multiline(str);
+  else if(str == "Circle")
+    add_new_circle();
+  else if(str == "Ellipse")
+    add_new_ellipse();
+  else if(str == "Plane Surface")
+    add_new_surface_volume(0);
+  else if(str == "Ruled Surface")
+    add_new_surface_volume(1);
+  else if(str == "Volume")
+    add_new_surface_volume(2);
+  else
+    Msg::Error("Unknown entity to create: %s", str.c_str());
+}
+
+static void split_selection()
+{
+  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+  Msg::StatusGl("Select a line to split\n"
+                "[Press 'q' to abort]");
+  GEdge* edge_to_split = 0;
+  while(1){
+    char ib = FlGui::instance()->selectEntity(ENT_LINE);
+    if(ib == 'q')
+      break;
+    if(!FlGui::instance()->selectedEdges.empty()){
+      edge_to_split = FlGui::instance()->selectedEdges[0];
+      edge_to_split->setSelection(1);
+      break;
+    }
+  }
+  Msg::StatusGl("");
+  if(FlGui::instance()->selectedEdges.empty()) return;
+  List_T *List1 = List_Create(5, 5, sizeof(int));
+  Msg::StatusGl("Select break points\n"
+                "[Press 'e' to end selection or 'q' to abort]");
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  drawContext::global()->draw();
+  while(1){
+    char ib = FlGui::instance()->selectEntity(ENT_POINT);
+    if(ib == 'q')
+      break;
+    if(ib == 'e'){
+      split_edge(edge_to_split->tag(), List1, GModel::current()->getFileName());
+      break;
+    }
+    for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+      int tag = FlGui::instance()->selectedVertices[i]->tag();
+      int index = List_ISearchSeq(List1, &tag, fcmp_int);
+      if(index < 0) List_Add(List1, &tag);
+      FlGui::instance()->selectedVertices[i]->setSelection(1);
+    }
+  }
+  Msg::StatusGl("");
+  FlGui::instance()->resetVisibility();
+  GModel::current()->setSelection(0);
+  drawContext::global()->draw();
+}
+
+static void action_point_line_surface_volume(int action, int mode, const char *what)
+{
+  int type;
+  const char *str;
+
+  if(!strcmp(what, "Point")) {
+    type = ENT_POINT;
+    str = "points";
+    opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else if(!strcmp(what, "Line")) {
+    type = ENT_LINE;
+    str = "lines";
+    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else if(!strcmp(what, "Surface")) {
+    type = ENT_SURFACE;
+    str = "surfaces";
+    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else if(!strcmp(what, "Volume")) {
+    type = ENT_VOLUME;
+    str = "volumes";
+    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
+  }
+  else{
+    Msg::Error("Unknown entity to select");
+    return;
+  }
+
+  if(action == 8){
+    FlGui::instance()->meshContext->show(0);
+  }
+
+  drawContext::global()->draw();
+
+  List_T *List1 = List_Create(5, 5, sizeof(int));
+  while(1) {
+    if(!List_Nbr(List1))
+      Msg::StatusGl("Select %s\n"
+                    "[Press 'e' to end selection or 'q' to abort]", str);
+    else
+      Msg::StatusGl("Select %s\n"
+                    "[Press 'e' to end selection, 'u' to undo last selection "
+                    "or 'q' to abort]", str);
+
+    char ib = FlGui::instance()->selectEntity(type);
+    if(ib == 'l') {
+      // we don't use List_Insert in order to keep the original
+      // ordering (this is slower, but this way undo works as
+      // expected)
+      int tag;
+      switch (type) {
+      case ENT_POINT:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+          FlGui::instance()->selectedVertices[i]->setSelection(1);
+          tag = FlGui::instance()->selectedVertices[i]->tag();
+          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+            List_Add(List1, &tag);
+        }
+        break;
+      case ENT_LINE:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
+          FlGui::instance()->selectedEdges[i]->setSelection(1);
+          tag = FlGui::instance()->selectedEdges[i]->tag();
+          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+            List_Add(List1, &tag);
+        }
+        break;
+      case ENT_SURFACE:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
+          FlGui::instance()->selectedFaces[i]->setSelection(1);
+          tag = FlGui::instance()->selectedFaces[i]->tag();
+          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+            List_Add(List1, &tag);
+        }
+        break;
+      case ENT_VOLUME:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
+          FlGui::instance()->selectedRegions[i]->setSelection(1);
+          tag = FlGui::instance()->selectedRegions[i]->tag();
+          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
+            List_Add(List1, &tag);
+        }
+        break;
+      }
+      drawContext::global()->draw();
+    }
+    if(ib == 'r') {
+      // we don't use List_Suppress in order to keep the original
+      // ordering (this is slower, but this way undo works as
+      // expected)
+      int index, tag;
+      switch (type) {
+      case ENT_POINT:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+          tag = FlGui::instance()->selectedVertices[i]->tag();
+          index = List_ISearchSeq(List1, &tag, fcmp_int);
+          if(index >= 0) List_PSuppress(List1, index);
+          FlGui::instance()->selectedVertices[i]->setSelection(0);
+        }
+        break;
+      case ENT_LINE:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
+          tag = FlGui::instance()->selectedEdges[i]->tag();
+          index = List_ISearchSeq(List1, &tag, fcmp_int);
+          if(index >= 0) List_PSuppress(List1, index);
+          FlGui::instance()->selectedEdges[i]->setSelection(0);
+        }
+        break;
+      case ENT_SURFACE:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
+          tag = FlGui::instance()->selectedFaces[i]->tag();
+          index = List_ISearchSeq(List1, &tag, fcmp_int);
+          if(index >= 0) List_PSuppress(List1, index);
+          FlGui::instance()->selectedFaces[i]->setSelection(0);
+        }
+        break;
+      case ENT_VOLUME:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
+          tag = FlGui::instance()->selectedRegions[i]->tag();
+          index = List_ISearchSeq(List1, &tag, fcmp_int);
+          if(index >= 0) List_PSuppress(List1, index);
+          FlGui::instance()->selectedRegions[i]->setSelection(0);
+        }
+        break;
+      }
+      drawContext::global()->draw();
+    }
+    if(ib == 'u') {
+      if(List_Nbr(List1)) {
+        int num;
+        List_Read(List1, List_Nbr(List1) - 1, &num);
+        if(type == ENT_POINT){
+          GVertex *gv = GModel::current()->getVertexByTag(num);
+          if(gv) gv->setSelection(0);
+        }
+        else if(type == ENT_LINE){
+          GEdge *ge = GModel::current()->getEdgeByTag(num);
+          if(ge) ge->setSelection(0);
+        }
+        else if(type == ENT_SURFACE){
+          GFace *gf = GModel::current()->getFaceByTag(num);
+          if(gf) gf->setSelection(0);
+        }
+        else if(type == ENT_VOLUME){
+          GRegion *gr = GModel::current()->getRegionByTag(num);
+          if(gr) gr->setSelection(0);
+        }
+        drawContext::global()->draw();
+        List_Pop(List1);
+      }
+    }
+    if(ib == 'i') {
+      Msg::Error("Inverting selection!");
+    }
+    if(ib == 'e') {
+      if(List_Nbr(List1)){
+        switch (action) {
+        case 0:
+          translate(mode, List1, GModel::current()->getFileName(), what,
+                    FlGui::instance()->geoContext->input[6]->value(),
+                    FlGui::instance()->geoContext->input[7]->value(),
+                    FlGui::instance()->geoContext->input[8]->value());
+          break;
+        case 1:
+          rotate(mode, List1, GModel::current()->getFileName(), what,
+                 FlGui::instance()->geoContext->input[12]->value(),
+                 FlGui::instance()->geoContext->input[13]->value(),
+                 FlGui::instance()->geoContext->input[14]->value(),
+                 FlGui::instance()->geoContext->input[9]->value(),
+                 FlGui::instance()->geoContext->input[10]->value(),
+                 FlGui::instance()->geoContext->input[11]->value(),
+                 FlGui::instance()->geoContext->input[15]->value());
+          break;
+        case 2:
+          dilate(mode, List1, GModel::current()->getFileName(), what,
+                 FlGui::instance()->geoContext->input[16]->value(),
+                 FlGui::instance()->geoContext->input[17]->value(),
+                 FlGui::instance()->geoContext->input[18]->value(),
+                 FlGui::instance()->geoContext->input[19]->value());
+          break;
+        case 3:
+          symmetry(mode, List1, GModel::current()->getFileName(), what,
+                   FlGui::instance()->geoContext->input[20]->value(),
+                   FlGui::instance()->geoContext->input[21]->value(),
+                   FlGui::instance()->geoContext->input[22]->value(),
+                   FlGui::instance()->geoContext->input[23]->value());
+          break;
+        case 4:
+          extrude(List1, GModel::current()->getFileName(), what,
+                  FlGui::instance()->geoContext->input[6]->value(),
+                  FlGui::instance()->geoContext->input[7]->value(),
+                  FlGui::instance()->geoContext->input[8]->value());
+          break;
+        case 5:
+          protude(List1, GModel::current()->getFileName(), what,
+                  FlGui::instance()->geoContext->input[12]->value(),
+                  FlGui::instance()->geoContext->input[13]->value(),
+                  FlGui::instance()->geoContext->input[14]->value(),
+                  FlGui::instance()->geoContext->input[9]->value(),
+                  FlGui::instance()->geoContext->input[10]->value(),
+                  FlGui::instance()->geoContext->input[11]->value(),
+                  FlGui::instance()->geoContext->input[15]->value());
+          break;
+        case 6:
+          delet(List1, GModel::current()->getFileName(), what);
+          break;
+        case 7:
+          add_physical(what, List1, GModel::current()->getFileName());
+          break;
+        case 8:
+          add_charlength(List1, GModel::current()->getFileName(),
+                         FlGui::instance()->meshContext->input[0]->value());
+          break;
+        case 9:
+          add_recosurf(List1, GModel::current()->getFileName());
+          break;
+        case 10:
+          add_compound(what, List1, GModel::current()->getFileName());
+          break;
+        default:
+          Msg::Error("Unknown action on selected entities");
+          break;
+        }
+        List_Reset(List1);
+        FlGui::instance()->resetVisibility();
+        GModel::current()->setSelection(0);
+        if(action <= 6) SetBoundingBox();
+        drawContext::global()->draw();
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      break;
+    }
+  }
+  List_Delete(List1);
+
+  Msg::StatusGl("");
+}
+
+static void geometry_elementary_add_translate_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(2);
+  action_point_line_surface_volume(0, 1, (const char*)data);
+}
+
+static void geometry_elementary_add_rotate_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(3);
+  action_point_line_surface_volume(1, 1, (const char*)data);
+}
+
+static void geometry_elementary_add_scale_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(4);
+  action_point_line_surface_volume(2, 1, (const char*)data);
+}
+
+static void geometry_elementary_add_symmetry_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(5);
+  action_point_line_surface_volume(3, 1, (const char*)data);
+}
+
+static void geometry_elementary_translate_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(2);
+  action_point_line_surface_volume(0, 0, (const char*)data);
+}
+
+static void geometry_elementary_rotate_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(3);
+  action_point_line_surface_volume(1, 0, (const char*)data);
+}
+
+static void geometry_elementary_scale_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(4);
+  action_point_line_surface_volume(2, 0, (const char*)data);
+}
+
+static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(5);
+  action_point_line_surface_volume(3, 0, (const char*)data);
+}
+
+static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(2);
+  action_point_line_surface_volume(4, 0, (const char*)data);
+}
+
+static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  FlGui::instance()->geoContext->show(3);
+  action_point_line_surface_volume(5, 0, (const char*)data);
+}
+
+static void geometry_elementary_delete_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  action_point_line_surface_volume(6, 0, (const char*)data);
+}
+
+static void geometry_elementary_split_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  split_selection();
+}
+
+static void geometry_elementary_coherence_cb(Fl_Widget *w, void *data)
+{
+  coherence(GModel::current()->getFileName());
+}
+
+static void geometry_physical_add_cb(Fl_Widget *w, void *data)
+{
+  if(!data) return;
+  std::string str((const char*)data);
+  if(str == "Point")
+    FlGui::instance()->callForSolverPlugin(0);
+  else if(str == "Line")
+    FlGui::instance()->callForSolverPlugin(1);
+
+  action_point_line_surface_volume(7, 0, str.c_str());
+}
+
+void mesh_save_cb(Fl_Widget *w, void *data)
+{
+  std::string name = CTX::instance()->outputFileName;
+  if(name.empty()){
+    if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO)
+      name = GetDefaultFileName(FORMAT_MSH);
+    else
+      name = GetDefaultFileName(CTX::instance()->mesh.fileFormat);
+  }
+  if(CTX::instance()->confirmOverwrite) {
+    if(!StatFile(name))
+      if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
+                    "Cancel", "Replace", 0, name.c_str()))
+        return;
+  }
+  CreateOutputFile(name, CTX::instance()->mesh.fileFormat);
+}
+
+void mesh_1d_cb(Fl_Widget *w, void *data)
+{
+  GModel::current()->mesh(1);
+  drawContext::global()->draw();
+}
+
+void mesh_2d_cb(Fl_Widget *w, void *data)
+{
+  GModel::current()->mesh(2);
+  drawContext::global()->draw();
+}
+
+void mesh_3d_cb(Fl_Widget *w, void *data)
+{
+  GModel::current()->mesh(3);
+  drawContext::global()->draw();
+}
+
+static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
+{
+  const char *str = (const char*)data;
+  int what;
+
+  if(!strcmp(str, "elements")){
+    CTX::instance()->pickElements = 1;
+    what = ENT_ALL;
+  }
+  else if(!strcmp(str, "lines")){
+    CTX::instance()->pickElements = 0;
+    what = ENT_LINE;
+  }
+  else if(!strcmp(str, "surfaces")){
+    CTX::instance()->pickElements = 0;
+    what = ENT_SURFACE;
+  }
+  else if(!strcmp(str, "volumes")){
+    CTX::instance()->pickElements = 0;
+    what = ENT_VOLUME;
+  }
+  else
+    return;
+
+  std::vector<MElement*> ele;
+  std::vector<GEntity*> ent;
+
+  while(1) {
+    CTX::instance()->mesh.changed = ENT_ALL;
+    drawContext::global()->draw();
+
+    if(ele.size() || ent.size())
+      Msg::StatusGl("Select %s\n"
+                    "[Press 'e' to end selection, 'u' to undo last selection or "
+                    "'q' to abort]", str);
+    else
+      Msg::StatusGl("Select %s\n"
+                    "[Press 'e' to end selection or 'q' to abort]", str);
+
+    char ib = FlGui::instance()->selectEntity(what);
+    if(ib == 'l') {
+      if(CTX::instance()->pickElements){
+        for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
+          if(FlGui::instance()->selectedElements[i]->getVisibility() != 2){
+            FlGui::instance()->selectedElements[i]->setVisibility(2);
+            ele.push_back(FlGui::instance()->selectedElements[i]);
+          }
+        }
+      }
+      else{
+        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
+          if(FlGui::instance()->selectedEdges[i]->getSelection() != 1){
+            FlGui::instance()->selectedEdges[i]->setSelection(1);
+            ent.push_back(FlGui::instance()->selectedEdges[i]);
+          }
+        }
+        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
+          if(FlGui::instance()->selectedFaces[i]->getSelection() != 1){
+            FlGui::instance()->selectedFaces[i]->setSelection(1);
+            ent.push_back(FlGui::instance()->selectedFaces[i]);
+          }
+        }
+        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
+          if(FlGui::instance()->selectedRegions[i]->getSelection() != 1){
+            FlGui::instance()->selectedRegions[i]->setSelection(1);
+            ent.push_back(FlGui::instance()->selectedRegions[i]);
+          }
+        }
+      }
+    }
+    if(ib == 'r') {
+      if(CTX::instance()->pickElements){
+        for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++)
+          FlGui::instance()->selectedElements[i]->setVisibility(1);
+      }
+      else{
+        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++)
+          FlGui::instance()->selectedEdges[i]->setSelection(0);
+        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++)
+          FlGui::instance()->selectedFaces[i]->setSelection(0);
+        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++)
+          FlGui::instance()->selectedRegions[i]->setSelection(0);
+      }
+    }
+    if(ib == 'u') {
+      if(CTX::instance()->pickElements){
+        if(ele.size()){
+          ele[ele.size() - 1]->setVisibility(1);
+          ele.pop_back();
+        }
+      }
+      else{
+        if(ent.size()){
+          ent[ent.size() - 1]->setSelection(0);
+          ent.pop_back();
+        }
+      }
+    }
+    if(ib == 'e') {
+      if(CTX::instance()->pickElements){
+        for(unsigned int i = 0; i < ele.size(); i++)
+          if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0);
+      }
+      else{
+        for(unsigned int i = 0; i < ent.size(); i++)
+          if(ent[i]->getSelection() == 1) ent[i]->setVisibility(0);
+      }
+      GModel::current()->removeInvisibleElements();
+      ele.clear();
+      ent.clear();
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      break;
+    }
+  }
+
+  CTX::instance()->mesh.changed = ENT_ALL;
+  CTX::instance()->pickElements = 0;
+  drawContext::global()->draw();
+  Msg::StatusGl("");
+}
+
+static std::vector<std::string> getInfoStrings(MElement *ele)
+{
+  std::vector<std::string> info;
+  {
+    std::ostringstream sstream;
+    sstream << "Element " << ele->getNum() << ":";
+    info.push_back(sstream.str());
+  }
+  {
+    std::ostringstream sstream;
+    const char *name;
+    MElement::getInfoMSH(ele->getTypeForMSH(), &name);
+    sstream << " " << name
+            << " (MSH type " << ele->getTypeForMSH()
+            << ", dimension "<< ele->getDim()
+            << ", order "<< ele->getPolynomialOrder()
+            << ", partition " << ele->getPartition()
+            << ")";
+    info.push_back(sstream.str());
+  }
+  {
+    std::ostringstream sstream;
+    sstream << " Vertices:";
+    for(int i = 0; i < ele->getNumVertices(); i++)
+      sstream << " " << ele->getVertex(i)->getNum();
+    info.push_back(sstream.str());
+  }
+  {
+    std::ostringstream sstream;
+    SPoint3 pt = ele->barycenter();
+    sstream << " Barycenter: (" << pt[0] << ", " << pt[1] << ", " << pt[2] << ")";
+    info.push_back(sstream.str());
+  }
+  {
+    std::ostringstream sstream;
+    sstream << " Quality: "
+            << "rho = " << ele->rhoShapeMeasure() << " "
+            << "gamma = " << ele->gammaShapeMeasure() << " "
+            << "eta = " << ele->etaShapeMeasure();
+    info.push_back(sstream.str());
+  }
+  {
+    std::ostringstream sstream;
+    double jmin, jmax;
+    ele->scaledJacRange(jmin, jmax);
+    sstream << " Scaled Jacobian range: " << jmin << " " << jmax;
+    info.push_back(sstream.str());
+  }
+  {
+    std::ostringstream sstream;
+    sstream << " Inner / outer radius: "
+            << ele->getInnerRadius() << " / " << ele->getOuterRadius();
+    info.push_back(sstream.str());
+  }
+  return info;
+}
+
+static void mesh_inspect_cb(Fl_Widget *w, void *data)
+{
+  CTX::instance()->pickElements = 1;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  drawContext::global()->draw();
+
+  while(1) {
+    Msg::StatusGl("Select element\n[Press 'q' to abort]");
+    char ib = FlGui::instance()->selectEntity(ENT_ALL);
+    if(ib == 'l') {
+      if(FlGui::instance()->selectedElements.size()){
+        MElement *ele = FlGui::instance()->selectedElements[0];
+        GModel::current()->setSelection(0);
+        ele->setVisibility(2);
+        CTX::instance()->mesh.changed = ENT_ALL;
+        drawContext::global()->draw();
+        std::vector<std::string> info = getInfoStrings(ele);
+        for(unsigned int i = 0; i < info.size(); i++)
+          Msg::Direct("%s", info[i].c_str());
+        if(CTX::instance()->tooltips){
+          std::string str;
+          for(unsigned int i = 0; i < info.size(); i++)
+            str += info[i] + "\n";
+          FlGui::instance()->getCurrentOpenglWindow()->drawTooltip(str);
+        }
+        else
+          FlGui::instance()->showMessages();
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      break;
+    }
+  }
+
+  CTX::instance()->pickElements = 0;
+  CTX::instance()->mesh.changed = ENT_ALL;
+  drawContext::global()->draw();
+  Msg::StatusGl("");
+}
+
+static void mesh_degree_cb(Fl_Widget *w, void *data)
+{
+  int degree = (intptr_t)data;
+  if(degree == 2)
+    SetOrderN(GModel::current(), 2, CTX::instance()->mesh.secondOrderLinear,
+              CTX::instance()->mesh.secondOrderIncomplete);
+  else if (degree == 1)
+    SetOrder1(GModel::current());
+  else // For now, use the same options as for second order meshes
+    SetOrderN(GModel::current(), degree,
+	      CTX::instance()->mesh.secondOrderLinear,
+              CTX::instance()->mesh.secondOrderIncomplete);
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  drawContext::global()->draw();
+}
+
+static void mesh_optimize_cb(Fl_Widget *w, void *data)
+{
+  if(CTX::instance()->lock) {
+    Msg::Info("I'm busy! Ask me that later...");
+    return;
+  }
+  CTX::instance()->lock = 1;
+  OptimizeMesh(GModel::current());
+  CTX::instance()->lock = 0;
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  drawContext::global()->draw();
+}
+
+static void mesh_refine_cb(Fl_Widget *w, void *data)
+{
+  RefineMesh(GModel::current(), CTX::instance()->mesh.secondOrderLinear);
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  drawContext::global()->draw();
+}
+
+static void mesh_optimize_netgen_cb(Fl_Widget *w, void *data)
+{
+  if(CTX::instance()->lock) {
+    Msg::Info("I'm busy! Ask me that later...");
+    return;
+  }
+  CTX::instance()->lock = 1;
+  OptimizeMeshNetgen(GModel::current());
+  CTX::instance()->lock = 0;
+  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
+  drawContext::global()->draw();
+}
+
+static void mesh_partition_cb(Fl_Widget *w, void *data)
+{
+  partition_dialog();
+}
+
+static void mesh_define_length_cb(Fl_Widget *w, void *data)
+{
+  action_point_line_surface_volume(8, 0, "Point");
+}
+
+static void mesh_define_recombine_cb(Fl_Widget *w, void *data)
+{
+  action_point_line_surface_volume(9, 0, "Surface");
+}
+
+static void add_transfinite_embedded(int dim, bool embed)
+{
+  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
+  switch (dim) {
+  case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break;
+  case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break;
+  case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break;
+  }
+  drawContext::global()->draw();
+
+  std::vector<int> p;
+  char ib;
+  while(1) {
+    switch (dim) {
+    case 1:
+      if(p.empty())
+        Msg::StatusGl("Select lines\n"
+                      "[Press 'e' to end selection or 'q' to abort]");
+      else
+        Msg::StatusGl("Select lines\n"
+                      "[Press 'e' to end selection, 'u' to undo last selection "
+                      "or 'q' to abort]");
+      ib = FlGui::instance()->selectEntity(ENT_LINE);
+      break;
+    case 2:
+      Msg::StatusGl("Select surface\n[Press 'q' to abort]");
+      ib = FlGui::instance()->selectEntity(ENT_SURFACE);
+      break;
+    case 3:
+      Msg::StatusGl("Select volume\n[Press 'q' to abort]");
+      ib = FlGui::instance()->selectEntity(ENT_VOLUME);
+      break;
+    default:
+      ib = 'l';
+      break;
+    }
+
+    if(ib == 'e') {
+      if(dim == 1) {
+        if(p.size())
+          add_trsfline(p, GModel::current()->getFileName(),
+                       FlGui::instance()->meshContext->choice[0]->text(),
+                       FlGui::instance()->meshContext->input[2]->value(),
+                       FlGui::instance()->meshContext->input[1]->value());
+      }
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      p.clear();
+    }
+    if(ib == 'u') {
+      if(dim == 1) {
+        if(p.size()){
+          GEdge *ge = GModel::current()->getEdgeByTag(p.back());
+          if(ge) ge->setSelection(0);
+          drawContext::global()->draw();
+          p.pop_back();
+        }
+      }
+    }
+    if(ib == 'q') {
+      GModel::current()->setSelection(0);
+      drawContext::global()->draw();
+      break;
+    }
+    if(ib == 'r') {
+      Msg::Warning("Entity de-selection not supported yet during "
+                   "transfinite definition");
+    }
+    if(ib == 'l') {
+      switch (dim) {
+      case 1:
+        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
+          FlGui::instance()->selectedEdges[i]->setSelection(1);
+          p.push_back(FlGui::instance()->selectedEdges[i]->tag());
+        }
+        drawContext::global()->draw();
+        break;
+      case 2:
+      case 3:
+        if(dim == 2){
+          FlGui::instance()->selectedFaces[0]->setSelection(1);
+          drawContext::global()->draw();
+          p.push_back(FlGui::instance()->selectedFaces[0]->tag());
+        }
+        else{
+          FlGui::instance()->selectedRegions[0]->setSelection(1);
+          drawContext::global()->draw();
+          p.push_back(FlGui::instance()->selectedRegions[0]->tag());
+        }
+        while(1) {
+          if(p.size() == 1)
+            Msg::StatusGl("Select %s points\n"
+                          "[Press 'e' to end selection or 'q' to abort]",
+                          embed ? "embedded" : "(ordered) boundary");
+          else
+            Msg::StatusGl("Select %s points\n"
+                          "[Press 'e' to end selection, 'u' to undo last selection "
+                          "or 'q' to abort]",
+                          embed ? "embedded" : "(ordered) boundary");
+          ib = FlGui::instance()->selectEntity(ENT_POINT);
+          if(ib == 'l') {
+            for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
+              FlGui::instance()->selectedVertices[i]->setSelection(1);
+              p.push_back(FlGui::instance()->selectedVertices[i]->tag());
+              if(!embed) break;
+            }
+            drawContext::global()->draw();
+          }
+          if(ib == 'u') {
+            if(p.size() > 1){
+              GVertex *gv = GModel::current()->getVertexByTag(p.back());
+              if(gv) gv->setSelection(0);
+              drawContext::global()->draw();
+              p.pop_back();
+            }
+          }
+          if(ib == 'r') {
+            Msg::Warning("Entity de-selection not supported yet during "
+                         "transfinite definition");
+          }
+          if(ib == 'e') {
+            switch (dim) {
+            case 2:
+              if(embed && p.size())
+                add_embedded("Point", p, GModel::current()->getFileName());
+              else if(!embed &&
+                      (p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1))
+                add_trsfsurf(p, GModel::current()->getFileName(),
+                             FlGui::instance()->meshContext->choice[1]->text());
+              else
+                Msg::Error("Wrong number of points for mesh constraint");
+              break;
+            case 3:
+              if(p.size() == 6 + 1 || p.size() == 8 + 1)
+                add_trsfvol(p, GModel::current()->getFileName());
+              else
+                Msg::Error("Wrong number of points for transfinite volume");
+              break;
+            }
+            GModel::current()->setSelection(0);
+            drawContext::global()->draw();
+            p.clear();
+            break;
+          }
+          if(ib == 'q') {
+            GModel::current()->setSelection(0);
+            drawContext::global()->draw();
+            goto stopall;
+          }
+        }
+        break;
+      }
+    }
+  }
+
+ stopall:
+  Msg::StatusGl("");
+}
+
+static void mesh_define_transfinite_line_cb(Fl_Widget *w, void *data)
+{
+  FlGui::instance()->meshContext->show(1);
+  add_transfinite_embedded(1, false);
+}
+
+static void mesh_define_transfinite_surface_cb(Fl_Widget *w, void *data)
+{
+  FlGui::instance()->meshContext->show(2);
+  add_transfinite_embedded(2, false);
+}
+
+static void mesh_define_transfinite_volume_cb(Fl_Widget *w, void *data)
+{
+  add_transfinite_embedded(3, false);
+}
+
+static void mesh_define_embedded_cb(Fl_Widget *w, void *data)
+{
+  add_transfinite_embedded(2, true);
+}
+
+static void mesh_define_compound_entity_cb(Fl_Widget *w, void *data)
+{
+  action_point_line_surface_volume(10, 0, (const char *)data);
+}
+
+// The static menus (we cannot use the 'g', 'm' 's' and 'p' mnemonics since they
+// are already defined as global shortcuts)
+static Fl_Menu_Item bar_table[] = {
+  {"&File", 0, 0, 0, FL_SUBMENU},
+    {"&New...",     FL_CTRL+'n', (Fl_Callback *)file_new_cb, 0},
+    {"&Open...",    FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0},
+    {"Open Recent", 0, 0, 0, FL_SUBMENU},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {0},
+    {"M&erge...",   FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0},
+    {"Watch Pattern...",    0, (Fl_Callback *)file_watch_cb, 0},
+    {"&Clear",      0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER},
+    {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
+      {"Start...",  0, (Fl_Callback *)file_remote_cb, (void*)"start"},
+      {"Merge...",  0, (Fl_Callback *)file_remote_cb, (void*)"merge"},
+      {"Clear",     0, (Fl_Callback *)file_remote_cb, (void*)"clear"},
+      {"Stop",      0, (Fl_Callback *)file_remote_cb, (void*)"stop"},
+      {0},
+    {"&Rename...",  FL_CTRL+'r', (Fl_Callback *)file_rename_cb, 0},
+    {"Save &As...", FL_CTRL+'s', (Fl_Callback *)file_save_as_cb, 0},
+    {"Sa&ve Mesh",  FL_CTRL+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0},
+    {"Save Options", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER},
+      {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"},
+      {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"},
+      {0},
+    {"&Quit",       FL_CTRL+'q', (Fl_Callback *)file_quit_cb, 0},
+    {0},
+  {"&Tools", 0, 0, 0, FL_SUBMENU},
+    {"&Options",         FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0},
+    {"Pl&ugins",         FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)},
+    {"&Visibility",      FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
+    {"&Clipping",        FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
+    {"&Manipulator",     FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0},
+#if defined(HAVE_3M)
+    {"&3M",              0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER},
+#endif
+    {"S&tatistics",      FL_CTRL+'i', (Fl_Callback *)statistics_cb, 0},
+    {"M&essage Console", FL_CTRL+'l', (Fl_Callback *)message_cb, 0},
+    {0},
+  {"&Window", 0, 0, 0, FL_SUBMENU},
+    {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new", FL_MENU_DIVIDER},
+    {"Split Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"},
+    {"Split Vertically",   0, (Fl_Callback *)file_window_cb, (void*)"split_v"},
+    {"Unsplit",            0, (Fl_Callback *)file_window_cb, (void*)"split_u", FL_MENU_DIVIDER},
+    {"Minimize",           FL_META+'m', (Fl_Callback *)window_cb, (void*)"minimize"},
+    {"Zoom",               0, (Fl_Callback *)window_cb, (void*)"zoom", FL_MENU_DIVIDER},
+    {"Bring All to Front", 0, (Fl_Callback *)window_cb, (void*)"front"},
+    {0},
+  {"&Help", 0, 0, 0, FL_SUBMENU},
+    {"On&line Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER},
+    {"M&ouse Actions",        0, (Fl_Callback *)help_mouse_cb, 0},
+    {"&Keyboard Shortcuts",   0, (Fl_Callback *)help_short_cb, 0},
+    {"C&ommand Line Options", 0, (Fl_Callback *)help_command_line_cb, 0},
+    {"&Current Options",      0, (Fl_Callback *)status_options_cb, (void*)"?", FL_MENU_DIVIDER},
+    {"&About Gmsh",           0, (Fl_Callback *)help_about_cb, 0},
+    {0},
+  {0}
+};
+
+#if defined(__APPLE__)
+
+// Alternative items for the MacOS system menu bar (removed '&' shortcuts: they
+// would cause spurious menu items to appear on the menu window; removed
+// File->Quit)
+static Fl_Menu_Item sysbar_table[] = {
+  {"File", 0, 0, 0, FL_SUBMENU},
+    {"New...",     FL_META+'n', (Fl_Callback *)file_new_cb, 0},
+    {"Open...",    FL_META+'o', (Fl_Callback *)file_open_cb, 0},
+    {"Open Recent", 0, 0, 0, FL_SUBMENU},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
+      {0},
+    {"Merge...",   FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0},
+    {"Watch Pattern...",   0, (Fl_Callback *)file_watch_cb, 0},
+    {"Clear",      0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER},
+    {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
+      {"Start...",  0, (Fl_Callback *)file_remote_cb, (void*)"start"},
+      {"Merge...",  0, (Fl_Callback *)file_remote_cb, (void*)"merge"},
+      {"Clear",     0, (Fl_Callback *)file_remote_cb, (void*)"clear"},
+      {"Stop",      0, (Fl_Callback *)file_remote_cb, (void*)"stop"},
+      {0},
+    {"Rename...",  FL_META+'r', (Fl_Callback *)file_rename_cb, 0},
+    {"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0},
+    {"Save Mesh",  FL_META+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0},
+    {"Save Options", 0, 0, 0, FL_SUBMENU},
+      {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"},
+      {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"},
+      {0},
+    {0},
+  {"Tools", 0, 0, 0, FL_SUBMENU},
+    {"Options",         FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0},
+    {"Plugins",         FL_META+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)},
+    {"Visibility",      FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
+    {"Clipping",        FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
+    {"Manipulator",     FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0},
+#if defined(HAVE_3M)
+    {"3M",              0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER},
+#endif
+    {"Statistics",      FL_META+'i', (Fl_Callback *)statistics_cb, 0},
+    {"Message Console", FL_META+'l', (Fl_Callback *)message_cb, 0},
+    {0},
+  {"Window", 0, 0, 0, FL_SUBMENU},
+    {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new", FL_MENU_DIVIDER},
+    {"Split Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"},
+    {"Split Vertically",   0, (Fl_Callback *)file_window_cb, (void*)"split_v"},
+    {"Unsplit",            0, (Fl_Callback *)file_window_cb, (void*)"split_u", FL_MENU_DIVIDER},
+    {"Minimize",           FL_META+'m', (Fl_Callback *)window_cb, (void*)"minimize"},
+    {"Zoom",               0, (Fl_Callback *)window_cb, (void*)"zoom", FL_MENU_DIVIDER},
+    {"Bring All to Front", 0, (Fl_Callback *)window_cb, (void*)"front"},
+    {0},
+  {"Help", 0, 0, 0, FL_SUBMENU},
+    {"Online Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER},
+    {"Mouse Actions",        0, (Fl_Callback *)help_mouse_cb, 0},
+    {"Keyboard Shortcuts",   0, (Fl_Callback *)help_short_cb, 0},
+    {"Command Line Options", 0, (Fl_Callback *)help_command_line_cb, 0},
+    {"Current Options",      0, (Fl_Callback *)status_options_cb, (void*)"?"},
+    {0},
+  {0}
+};
+
+#endif
 
 // Icons for the satus bar
 #define vv(x,y) fl_vertex(x,y)
@@ -285,7 +2426,7 @@ void status_options_cb(Fl_Widget *w, void *data)
     static int old_ve = (int)opt_mesh_volumes_edges(0, GMSH_GET, 0.);
     static int old_vf = (int)opt_mesh_volumes_faces(0, GMSH_GET, 0.);
     if(!value){ // retore visibility
-      Msg::StatusBar(2, false, "Mesh display restored");
+      Msg::StatusBar(false, "Mesh display restored");
       value = 1;
       opt_mesh_points(0, GMSH_SET | GMSH_GUI, old_p);
       opt_mesh_lines(0, GMSH_SET | GMSH_GUI, old_l);
@@ -295,7 +2436,7 @@ void status_options_cb(Fl_Widget *w, void *data)
       opt_mesh_volumes_faces(0, GMSH_SET | GMSH_GUI, old_vf);
     }
     else{
-      Msg::StatusBar(2, false, "Mesh display OFF");
+      Msg::StatusBar(false, "Mesh display OFF");
       value = 0;
       old_p = (int)opt_mesh_points(0, GMSH_GET, 0.);
       old_l = (int)opt_mesh_lines(0, GMSH_GET, 0.);
@@ -454,6 +2595,7 @@ void message_cb(Fl_Widget *w, void *data)
 {
   graphicWindow *g = getGraphicWindow
     (FlGui::instance()->getCurrentOpenglWindow()->parent());
+  if(!g->browser) return;
   if(g->browser->h())
     g->hideMessages();
   else
@@ -528,20 +2670,33 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true
     first = false;
   }
 
+  int mh = main ? BH : 0; // menu bar height
+#if defined(__APPLE__)
+  if(CTX::instance()->systemMenuBar) mh = 0;
+#endif
   int sh = 2 * FL_NORMAL_SIZE - 4; // status bar height
   int sw = FL_NORMAL_SIZE + 3; // status button width
-  int width = CTX::instance()->glSize[0];
-  int mheight = 10; // dummy (nonzero)
-  int glheight = CTX::instance()->glSize[1] - mheight;
-  int height = glheight + mheight + sh;
 
+  int mheight = main ? 10 : 0; // dummy (nonzero)
+  int glheight = CTX::instance()->glSize[1] - mheight;
+  int height = mh + glheight + mheight + sh;
   // make sure height < screen height
   if(height > Fl::h()){
     height = Fl::h();
-    glheight = height - mheight - sh;
+    glheight = height - mh - mheight - sh;
     CTX::instance()->glSize[1] = glheight;
   }
 
+  int twidth = main ? (13 * sw + 2 * FL_NORMAL_SIZE + 2) : 0;
+  int glwidth = CTX::instance()->glSize[0] - twidth;
+  int width = glwidth + twidth;
+  // make sure width < screen width
+  if(width > Fl::w()){
+    width = Fl::w();
+    glwidth = width - twidth;
+    CTX::instance()->glSize[0] = glwidth;
+  }
+
   // the graphic window should be a "normal" window (neither modal nor
   // non-modal)
   if(main){
@@ -553,70 +2708,92 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true
     win->callback(remove_graphic_window_cb);
   }
 
+  sysbar = 0;
+  bar = 0;
+  if(main){
+#if defined(__APPLE__)
+    if(CTX::instance()->systemMenuBar){
+      sysbar = new Fl_Sys_Menu_Bar(1, 1, 1, 1);
+      sysbar->menu(sysbar_table);
+      sysbar->global();
+      fillRecentHistoryMenu();
+    }
+    else{
+#endif
+      bar = new Fl_Menu_Bar(0, 0, width, BH);
+      bar->menu(bar_table);
+      bar->box(FL_UP_BOX);
+      bar->global();
+      fillRecentHistoryMenu();
+#if defined(__APPLE__)
+    }
+#endif
+  }
+
   // bottom button bar
-  bottom = new Fl_Box(0, glheight + mheight, width, sh);
+  bottom = new Fl_Box(0, mh + glheight + mheight, width, sh);
   bottom->box(FL_FLAT_BOX);
 
   int x = 2;
   int sht = sh - 4; // leave a 2 pixel border at the bottom
 
-  butt[5] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_models");
+  butt[5] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_models");
   butt[5]->callback(status_options_cb, (void *)"model");
   butt[5]->tooltip("Select active model");
   x += sw;
-  butt[0] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "X");
+  butt[0] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "X");
   butt[0]->callback(status_xyz1p_cb, (void *)"x");
   butt[0]->tooltip("Set +X or -X view (Alt+x or Alt+Shift+x)");
   x += sw;
-  butt[1] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "Y");
+  butt[1] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "Y");
   butt[1]->callback(status_xyz1p_cb, (void *)"y");
   butt[1]->tooltip("Set +Y or -Y view (Alt+y or Alt+Shift+y)");
   x += sw;
-  butt[2] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "Z");
+  butt[2] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "Z");
   butt[2]->callback(status_xyz1p_cb, (void *)"z");
   butt[2]->tooltip("Set +Z or -Z view (Alt+z or Alt+Shift+z)");
   x += sw;
-  butt[4] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_rotate");
+  butt[4] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_rotate");
   butt[4]->callback(status_xyz1p_cb, (void *)"r");
   butt[4]->tooltip("Rotate +90 or -90 (Shift) degrees, or sync rotations (Alt)");
   x += sw;
-  butt[3] = new Fl_Button(x, glheight + mheight + 2, 2 * FL_NORMAL_SIZE, sht, "1:1");
+  butt[3] = new Fl_Button(x, mh + glheight + mheight + 2, 2 * FL_NORMAL_SIZE, sht, "1:1");
   butt[3]->callback(status_xyz1p_cb, (void *)"1:1");
   butt[3]->tooltip("Set unit scale, sync scale between viewports (Alt), "
                    "or reset bounding box around visible entities (Shift)");
   x += 2 * FL_NORMAL_SIZE;
-  butt[8] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_ortho");
+  butt[8] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_ortho");
   butt[8]->callback(status_options_cb, (void *)"p");
   butt[8]->tooltip("Toggle projection mode (Alt+o or Alt+Shift+o)");
   x += sw;
-  butt[12] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "M");
+  butt[12] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "M");
   butt[12]->callback(status_options_cb, (void *)"M");
   butt[12]->tooltip("Toggle mesh visibility (Alt+m)");
   x += sw;
-  butt[13] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_clscale");
+  butt[13] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_clscale");
   butt[13]->callback(status_options_cb, (void *)"clscale");
   butt[13]->tooltip("Change mesh element size factor");
   x += sw;
-  butt[9] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "S");
+  butt[9] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "S");
   butt[9]->callback(status_options_cb, (void *)"S");
   butt[9]->tooltip("Toggle mouse selection ON/OFF (Escape)");
   x += sw;
-  butt[6] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_rewind");
+  butt[6] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_rewind");
   butt[6]->callback(status_rewind_cb);
   butt[6]->tooltip("Rewind animation");
   butt[6]->deactivate();
   x += sw;
-  butt[10] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_back");
+  butt[10] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_back");
   butt[10]->callback(status_stepbackward_cb);
   butt[10]->tooltip("Step backward");
   butt[10]->deactivate();
   x += sw;
-  butt[7] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_play");
+  butt[7] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_play");
   butt[7]->callback(status_play_cb);
   butt[7]->tooltip("Play/pause animation");
   butt[7]->deactivate();
   x += sw;
-  butt[11] = new Fl_Button(x, glheight + mheight + 2, sw, sht, "@-1gmsh_forward");
+  butt[11] = new Fl_Button(x, mh + glheight + mheight + 2, sw, sht, "@-1gmsh_forward");
   butt[11]->callback(status_stepforward_cb);
   butt[11]->tooltip("Step forward");
   butt[11]->deactivate();
@@ -629,19 +2806,13 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true
   }
 
   x += 2;
-  int wleft = (width - x) / 3 - 1;
-  int wright = (width - x) - (width - x) / 3 - 1;
-
-  label[0] = new Fl_Progress(x, glheight + mheight + 2, wleft, sht);
-  label[1] = new Fl_Progress(x + (width - x) / 3, glheight + mheight + 2, wright, sht);
-  for(int i = 0; i < 2; i++) {
-    label[i]->box(FL_THIN_DOWN_BOX);
-    label[i]->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
-    label[i]->color(FL_BACKGROUND_COLOR, FL_DARK2); // FL_DARK_GREEN
-  }
+  label = new Fl_Progress(x, mh + glheight + mheight + 2, width - x, sht);
+  label->box(FL_THIN_DOWN_BOX);
+  label->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  label->color(FL_BACKGROUND_COLOR, FL_DARK2); // FL_DARK_GREEN
 
   // dummy resizable box
-  dummyBox *resbox = new dummyBox(x, 0, width - x, glheight);
+  dummyBox *resbox = new dummyBox(x, mh, width - x, glheight);
   win->resizable(resbox);
 
   // set mininum window size
@@ -649,16 +2820,17 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true
   minHeight = 100;
   win->size_range(minWidth, minHeight);
 
-  // tiled opengl windows
-  tile = new Fl_Tile(0, 0, width, glheight + mheight);
+  // tiled windows (opengl, messages, menu)
+  tile = new Fl_Tile(0, mh, glwidth + twidth, glheight + mheight);
 
-  int w2 = width / 2, h2 = glheight / 2;
+  int w2 = glwidth / 2, h2 = glheight / 2;
   if(numTiles == 2){
-    gl.push_back(new openglWindow(0, 0, w2, glheight));
+    gl.push_back(new openglWindow(twidth, mh, w2, glheight));
     gl.back()->end();
-    gl.push_back(new openglWindow(w2, 0, width - w2, glheight));
+    gl.push_back(new openglWindow(twidth + w2, mh, glwidth - w2, glheight));
     gl.back()->end();
   }
+  /*
   else if(numTiles == 3){
     gl.push_back(new openglWindow(0, 0, w2, glheight));
     gl.back()->end();
@@ -676,9 +2848,9 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true
     gl.back()->end();
     gl.push_back(new openglWindow(w2, h2, width - w2, glheight - h2));
     gl.back()->end();
-  }
+    }*/
   else{
-    gl.push_back(new openglWindow(0, 0, width, glheight));
+    gl.push_back(new openglWindow(twidth, mh, glwidth, glheight));
     gl.back()->end();
   }
 
@@ -690,23 +2862,34 @@ graphicWindow::graphicWindow(bool main, int numTiles) : _autoScrollMessages(true
   }
   for(unsigned int i = 0; i < gl.size(); i++) gl[i]->mode(mode);
 
-  browser = new Fl_Browser(0, glheight, width, mheight);
-  browser->box(FL_THIN_DOWN_BOX);
-  browser->textfont(FL_COURIER);
-  browser->textsize(FL_NORMAL_SIZE - 1);
-  browser->type(FL_MULTI_BROWSER);
-  browser->callback(message_browser_cb, this);
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-  browser->scrollbar_size(10); // thinner scrollbars
-#endif
+  if(main){
+    browser = new Fl_Browser(twidth, mh + glheight, glwidth, mheight);
+    browser->box(FL_THIN_DOWN_BOX);
+    browser->textfont(FL_COURIER);
+    browser->textsize(FL_NORMAL_SIZE - 1);
+    browser->type(FL_MULTI_BROWSER);
+    browser->callback(message_browser_cb, this);
+    browser->scrollbar_size(std::max(10, FL_NORMAL_SIZE - 2)); // thinner scrollbars
 #if defined(__APPLE__)
-  // horizontal scrollbar is buggy on Mac when tiles are resized
-  browser->has_scrollbar(Fl_Browser_::VERTICAL);
+    // horizontal scrollbar is buggy on Mac when tiles are resized
+    browser->has_scrollbar(Fl_Browser_::VERTICAL);
 #endif
+  }
+  else{
+    browser = 0;
+  }
+
+  if(main){
+    onelab = new onelabGroup(0, mh, twidth, height - mh - sh);
+  }
+  else{
+    onelab = 0;
+  }
+
   tile->end();
 
   // resize the tile to match the prescribed sizes
-  tile->position(0, glheight, 0, CTX::instance()->glSize[1]);
+  tile->position(0, mh + glheight, 0, mh + CTX::instance()->glSize[1]);
   _savedMessageHeight = CTX::instance()->msgSize;
 
   win->position(CTX::instance()->glPosition[0], CTX::instance()->glPosition[1]);
@@ -732,8 +2915,8 @@ void graphicWindow::split(openglWindow *g, char how)
   if(tile->find(g) == tile->children()) return;
 
   if(how == 'u'){
-    // after many tries I cannot figure out how to do this cleanly, so
-    // let's be brutal :-)
+    // after many tries I cannot figure out how to do this cleanly, so let's be
+    // brutal :-)
     int mode = g->mode();
     openglWindow::setLastHandled(0);
     for(unsigned int i = 0; i < gl.size(); i++){
@@ -741,7 +2924,10 @@ void graphicWindow::split(openglWindow *g, char how)
       delete gl[i];
     }
     gl.clear();
-    openglWindow *g2 = new openglWindow(0, 0, tile->w(), tile->h() - browser->h());
+    openglWindow *g2 = new openglWindow(tile->x() + (onelab ? onelab->w() : 0),
+                                        tile->y(),
+                                        tile->w() - (onelab ? onelab->w() : 0),
+                                        tile->h() - (browser ? browser->h() : 0));
     g2->end();
     g2->mode(mode);
     gl.push_back(g2);
@@ -750,7 +2936,7 @@ void graphicWindow::split(openglWindow *g, char how)
   }
   else{
     // make sure browser is not zero-size when adding children
-    if(browser->h() == 0) resizeMessages(1);
+    if(browser && browser->h() == 0) resizeMessages(1);
     int x1 = g->x();
     int y1 = g->y();
     int w1 = (how == 'h') ? g->w() / 2 : g->w();
@@ -816,6 +3002,7 @@ void graphicWindow::checkAnimButtons()
 
 void graphicWindow::resizeMessages(int dh)
 {
+  if(!browser) return;
   for(unsigned int i = 0; i < gl.size(); i++){
     if(gl[i]->y() + gl[i]->h() == browser->y())
       gl[i]->resize(gl[i]->x(), gl[i]->y(), gl[i]->w(), gl[i]->h() - dh);
@@ -826,7 +3013,7 @@ void graphicWindow::resizeMessages(int dh)
 
 void graphicWindow::showMessages()
 {
-  if(!win->shown()) return;
+  if(!browser || !win->shown()) return;
   if(browser->h() < 5){
     int height = _savedMessageHeight;
     if(height < 5) height = 50;
@@ -840,18 +3027,21 @@ void graphicWindow::showMessages()
 
 void graphicWindow::hideMessages()
 {
+  if(!browser) return;
   _savedMessageHeight = browser->h();
   resizeMessages(-browser->h());
 }
 
 int graphicWindow::getMessageHeight()
 {
+  if(!browser) return 0;
   if(!browser->h()) return _savedMessageHeight;
   return browser->h();
 }
 
 void graphicWindow::addMessage(const char *msg)
 {
+  if(!browser) return;
   browser->add(msg, 0);
   if(_autoScrollMessages && win->shown() && browser->h() >= 10)
     browser->bottomline(browser->size());
@@ -859,11 +3049,14 @@ void graphicWindow::addMessage(const char *msg)
 
 void graphicWindow::clearMessages()
 {
+  if(!browser) return;
   browser->clear();
 }
 
 void graphicWindow::saveMessages(const char *filename)
 {
+  if(!browser) return;
+
   FILE *fp = fopen(filename, "w");
 
   if(!fp) {
@@ -871,7 +3064,7 @@ void graphicWindow::saveMessages(const char *filename)
     return;
   }
 
-  Msg::StatusBar(2, true, "Writing '%s'...", filename);
+  Msg::StatusBar(true, "Writing '%s'...", filename);
   for(int i = 1; i <= browser->size(); i++) {
     const char *c = browser->text(i);
     if(c[0] == '@')
@@ -879,12 +3072,14 @@ void graphicWindow::saveMessages(const char *filename)
     else
       fprintf(fp, "%s\n", c);
   }
-  Msg::StatusBar(2, true, "Done writing '%s'", filename);
+  Msg::StatusBar(true, "Done writing '%s'", filename);
   fclose(fp);
 }
 
 void graphicWindow::copySelectedMessagesToClipboard()
 {
+  if(!browser) return;
+
   std::string buff;
   for(int i = 1; i <= browser->size(); i++) {
     if(browser->selected(i)) {
@@ -900,3 +3095,260 @@ void graphicWindow::copySelectedMessagesToClipboard()
   Fl::copy(buff.c_str(), buff.size(), 0);
   Fl::copy(buff.c_str(), buff.size(), 1);
 }
+
+void graphicWindow::fillRecentHistoryMenu()
+{
+  if(!bar && !sysbar) return;
+  Fl_Menu_Item *table = bar_table;
+#if defined(__APPLE__)
+  if(CTX::instance()->systemMenuBar)
+    table = sysbar_table;
+#endif
+
+  for(int i = 0; i < 5; i++){
+    table[4 + i].text = CTX::instance()->recentFiles[i].c_str();
+    table[4 + i].user_data_ = (void*)CTX::instance()->recentFiles[i].c_str();
+  }
+
+#if defined(__APPLE__)
+  if(CTX::instance()->systemMenuBar)
+    sysbar->menu(table);
+#endif
+}
+
+typedef struct{
+  std::string label;
+  Fl_Callback *callback;
+  void *arg;
+} menuItem;
+
+static menuItem static_modules[] = {
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Parameter",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Parameter"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Point",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Straight line",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Spline",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Spline"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/B-Spline",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"BSpline"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Circle arc",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Circle"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Ellipse arc",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ellipse"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Plane surface",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Plane Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Ruled surface",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ruled Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Add/Volume",
+   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Point",
+   (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Line",
+   (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Surface",
+   (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Volume",
+   (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate point",
+   (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate line",
+   (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate surface",
+   (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Duplicate volume",
+   (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Extrude point",
+   (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Extrude line",
+   (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Translate/Extrude surface",
+   (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Point",
+   (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Line",
+   (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Surface",
+   (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Volume",
+   (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate point",
+   (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate line",
+   (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate surface",
+   (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Duplicate volume",
+   (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Extrude point",
+   (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Extrude line",
+   (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Rotate/Extrude surface",
+   (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Point",
+   (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Line",
+   (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Surface",
+   (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Volume",
+   (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate point",
+   (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate line",
+   (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate surface",
+   (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Scale/Duplicate volume",
+   (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Point",
+   (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Line",
+   (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Surface",
+   (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Volume",
+   (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate point",
+   (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate line",
+   (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate surface",
+   (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Symmetry/Duplicate volume",
+   (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Split/Line",
+   (Fl_Callback *)geometry_elementary_split_cb,(void*)"Line"},
+  {"0Gmsh modules/Geometry/Elementary entities/Delete/Point",
+   (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Point"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Delete/Line",
+   (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Delete/Surface",
+   (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Geometry/Elementary entities/Delete/Volume",
+   (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Geometry/Physical groups/Add/Point",
+   (Fl_Callback *)geometry_physical_add_cb, (void*)"Point" } ,
+  {"0Gmsh modules/Geometry/Physical groups/Add/Line",
+   (Fl_Callback *)geometry_physical_add_cb, (void*)"Line" } ,
+  {"0Gmsh modules/Geometry/Physical groups/Add/Surface",
+   (Fl_Callback *)geometry_physical_add_cb, (void*)"Surface" } ,
+  {"0Gmsh modules/Geometry/Physical groups/Add/Volume",
+   (Fl_Callback *)geometry_physical_add_cb, (void*)"Volume" } ,
+  {"0Gmsh modules/Geometry/Coherence",
+   (Fl_Callback *)geometry_elementary_coherence_cb} ,
+  {"0Gmsh modules/Geometry/Reload",
+   (Fl_Callback *)geometry_reload_cb} ,
+  {"0Gmsh modules/Geometry/Edit file",
+   (Fl_Callback *)geometry_edit_cb} ,
+  {"0Gmsh modules/Mesh/Define/Size fields",
+   (Fl_Callback *)field_cb},
+  {"0Gmsh modules/Mesh/Define/Element size at points",
+   (Fl_Callback *)mesh_define_length_cb  } ,
+  {"0Gmsh modules/Mesh/Define/Embedded points",
+   (Fl_Callback *)mesh_define_embedded_cb, (void*)"point" } ,
+  {"0Gmsh modules/Mesh/Define/Recombine",
+   (Fl_Callback *)mesh_define_recombine_cb  } ,
+  {"0Gmsh modules/Mesh/Define/Transfinite/Line",
+   (Fl_Callback *)mesh_define_transfinite_line_cb} ,
+  {"0Gmsh modules/Mesh/Define/Transfinite/Surface",
+   (Fl_Callback *)mesh_define_transfinite_surface_cb} ,
+  {"0Gmsh modules/Mesh/Define/Transfinite/Volume",
+   (Fl_Callback *)mesh_define_transfinite_volume_cb} ,
+  {"0Gmsh modules/Mesh/Define/Compound/Line",
+   (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Line"} ,
+  {"0Gmsh modules/Mesh/Define/Compound/Surface",
+   (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Surface"} ,
+  {"0Gmsh modules/Mesh/Define/Compound/Volume",
+   (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Volume"} ,
+  {"0Gmsh modules/Mesh/1D",
+   (Fl_Callback *)mesh_1d_cb} ,
+  {"0Gmsh modules/Mesh/2D",
+   (Fl_Callback *)mesh_2d_cb} ,
+  {"0Gmsh modules/Mesh/3D",
+   (Fl_Callback *)mesh_3d_cb} ,
+  {"0Gmsh modules/Mesh/Optimize 3D",
+   (Fl_Callback *)mesh_optimize_cb} ,
+#if defined(HAVE_NETGEN)
+  {"0Gmsh modules/Mesh/Optimize 3D (Netgen)",
+   (Fl_Callback *)mesh_optimize_netgen_cb} ,
+#endif
+  {"0Gmsh modules/Mesh/Set order 1",
+   (Fl_Callback *)mesh_degree_cb, (void*)1},
+  {"0Gmsh modules/Mesh/Set order 2",
+   (Fl_Callback *)mesh_degree_cb, (void*)2},
+  {"0Gmsh modules/Mesh/Set order 3",
+   (Fl_Callback *)mesh_degree_cb, (void*)3},
+  {"0Gmsh modules/Mesh/Optimize high order",
+   (Fl_Callback *)highordertools_cb},
+  {"0Gmsh modules/Mesh/Inspect",
+   (Fl_Callback *)mesh_inspect_cb} ,
+  {"0Gmsh modules/Mesh/Refine by splitting",
+   (Fl_Callback *)mesh_refine_cb} ,
+#if defined(HAVE_METIS) || defined(HAVE_CHACO)
+  {"0Gmsh modules/Mesh/Partition",
+   (Fl_Callback *)mesh_partition_cb} ,
+#endif
+  {"0Gmsh modules/Mesh/Reclassify 2D",
+   (Fl_Callback *)mesh_classify_cb} ,
+#if defined(HAVE_FOURIER_MODEL)
+  {"0Gmsh modules/Mesh/Reparameterize 2D",
+   (Fl_Callback *)mesh_parameterize_cb} ,
+#endif
+  {"0Gmsh modules/Mesh/Delete/Elements",
+   (Fl_Callback *)mesh_delete_parts_cb, (void*)"elements"} ,
+  {"0Gmsh modules/Mesh/Delete/Lines",
+   (Fl_Callback *)mesh_delete_parts_cb, (void*)"lines"} ,
+  {"0Gmsh modules/Mesh/Delete/Surfaces",
+   (Fl_Callback *)mesh_delete_parts_cb, (void*)"surfaces"} ,
+  {"0Gmsh modules/Mesh/Delete/Volumes",
+   (Fl_Callback *)mesh_delete_parts_cb, (void*)"volumes"} ,
+  {"0Gmsh modules/Mesh/Save",
+   (Fl_Callback *)mesh_save_cb} ,
+};
+
+void onelabGroup::_addGmshMenus()
+{
+  _tree->sortorder(FL_TREE_SORT_NONE);
+
+  // add static geometry and mesh module items
+  for(int i = 0; i < sizeof(static_modules) / sizeof(static_modules[0]); i++)
+    _addMenu(static_modules[i].label, static_modules[i].callback, static_modules[i].arg);
+
+  // add dynamic solver module items
+  for(int i = 0; i < 5; i++){
+    std::string name = opt_solver_name(i, GMSH_GET, "");
+    if(name.size()) _addMenu("0Gmsh modules/Solver/" + name, solver_cb, (void*)i);
+  }
+
+  // add dynamic post-processing module items
+  for(unsigned int i = 0; i < PView::list.size(); i++) _addViewMenu(i);
+
+  _tree->sortorder(FL_TREE_SORT_ASCENDING);
+
+  static bool first = true;
+  if(first){
+    first = false;
+    Fl_Tree_Item *n0 = _tree->find_item("0Gmsh modules");
+    for(Fl_Tree_Item *n = n0; n; n = n->next()){
+      if(!n->is_root() && n->has_children() && n->depth() > 1)
+        n->close();
+    }
+  }
+}
+
+std::set<std::string> onelabGroup::_getClosedGmshMenus()
+{
+  std::set<std::string> closed;
+  Fl_Tree_Item *n0 = _tree->find_item("0Gmsh modules");
+  for(Fl_Tree_Item *n = n0; n; n = n->next()){
+    if(!n->is_root() && n->has_children() && n->is_close()){
+      char path[1024];
+      _tree->item_pathname(path, sizeof(path), n);
+      closed.insert(path);
+    }
+  }
+  return closed;
+}
diff --git a/Fltk/graphicWindow.h b/Fltk/graphicWindow.h
index a5abb931dcc52c6bc7e77332538456ef7b5c5307..df08af9b159e4df5c4a3732d2c6414691baad551 100644
--- a/Fltk/graphicWindow.h
+++ b/Fltk/graphicWindow.h
@@ -1,4 +1,3 @@
-
 // Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
 //
 // See the LICENSE.txt file for license information. Please report all
@@ -15,7 +14,12 @@
 #include <FL/Fl_Tile.H>
 #include <FL/Fl_Browser.H>
 #include <FL/Fl_Progress.H>
+#if defined(__APPLE__)
+#include <FL/Fl_Sys_Menu_Bar.H>
+#endif
+#include <FL/Fl_Menu_Bar.H>
 #include "openglWindow.h"
+#include "onelabGroup.h"
 
 class graphicWindow{
  private:
@@ -24,12 +28,17 @@ class graphicWindow{
   bool _autoScrollMessages;
  public:
   Fl_Window *win;
+#if defined(__APPLE__)
+  Fl_Sys_Menu_Bar *sysbar;
+#endif
+  Fl_Menu_Bar *bar;
   Fl_Tile *tile;
   std::vector<openglWindow*> gl;
   Fl_Browser *browser;
+  onelabGroup *onelab;
   Fl_Box *bottom;
   Fl_Button *butt[14];
-  Fl_Progress *label[2];
+  Fl_Progress *label;
   int minWidth, minHeight;
  public:
   graphicWindow(bool main=true, int numTiles=1);
@@ -48,8 +57,22 @@ class graphicWindow{
   void clearMessages();
   void saveMessages(const char *filename);
   void copySelectedMessagesToClipboard();
+  void fillRecentHistoryMenu();
 };
 
+void file_quit_cb(Fl_Widget *w, void *data);
+void file_watch_cb(Fl_Widget *w, void *data);
+void mod_geometry_cb(Fl_Widget *w, void *data);
+void mod_mesh_cb(Fl_Widget *w, void *data);
+void mod_solver_cb(Fl_Widget *w, void *data);
+void mod_post_cb(Fl_Widget *w, void *data);
+void mod_back_cb(Fl_Widget *w, void *data);
+void mod_forward_cb(Fl_Widget *w, void *data);
+void geometry_reload_cb(Fl_Widget *w, void *data);
+void mesh_1d_cb(Fl_Widget *w, void *data);
+void mesh_2d_cb(Fl_Widget *w, void *data);
+void mesh_3d_cb(Fl_Widget *w, void *data);
+void help_about_cb(Fl_Widget *w, void *data);
 void status_xyz1p_cb(Fl_Widget *w, void *data);
 void status_options_cb(Fl_Widget *w, void *data);
 void status_play_manual(int time, int incr, bool redraw=true);
diff --git a/Fltk/inputRegion.cpp b/Fltk/inputRegion.cpp
index a40857cd4d90613ff3efb53d71b99fc643977023..b1208fb23e0068a60e7d313c7c862e90c92bae23 100644
--- a/Fltk/inputRegion.cpp
+++ b/Fltk/inputRegion.cpp
@@ -79,7 +79,7 @@ void inputRegion::_add_butt_cb(Fl_Widget *w, void *data)
 
   int dim = ENT_ALL; // TODO use onelab::region::dim
 
-  Msg::StatusBar(3, false, "Select entities\n[Press 'e' to end]");
+  Msg::StatusGl("Select entities\n[Press 'e' to end]");
   while(1){
     char ib = FlGui::instance()->selectEntity(dim);
     if(ib == 'l'){
@@ -96,7 +96,7 @@ void inputRegion::_add_butt_cb(Fl_Widget *w, void *data)
       break;
     }
   }
-  Msg::StatusBar(3, false, "");
+  Msg::StatusGl("");
 
   b->do_callback();
 
diff --git a/Fltk/menuWindow.cpp b/Fltk/menuWindow.cpp
deleted file mode 100644
index 18bb1e8c2bdf8ea05bb033e128af33c637474f9b..0000000000000000000000000000000000000000
--- a/Fltk/menuWindow.cpp
+++ /dev/null
@@ -1,3101 +0,0 @@
-// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
-//
-// See the LICENSE.txt file for license information. Please report all
-// bugs and problems to <gmsh@geuz.org>.
-
-#include "GmshConfig.h"
-#if !defined(HAVE_NO_STDINT_H)
-#include <stdint.h>
-#elif defined(HAVE_NO_INTPTR_T)
-typedef unsigned long intptr_t;
-#endif
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <time.h>
-#include <FL/Fl_Box.H>
-#include <FL/fl_ask.H>
-#include <FL/filename.H>
-#include "GmshMessage.h"
-#include "GmshSocket.h"
-#include "FlGui.h"
-#include "menuWindow.h"
-#include "mainWindow.h"
-#include "graphicWindow.h"
-#include "optionWindow.h"
-#include "statisticsWindow.h"
-#include "contextWindow.h"
-#include "visibilityWindow.h"
-#include "highOrderToolsWindow.h"
-#include "clippingWindow.h"
-#include "manipWindow.h"
-#include "fieldWindow.h"
-#include "pluginWindow.h"
-#include "aboutWindow.h"
-#include "onelabWindow.h"
-#include "fileDialogs.h"
-#include "extraDialogs.h"
-#include "partitionDialog.h"
-#include "projectionEditor.h"
-#include "classificationEditor.h"
-#include "Options.h"
-#include "CommandLine.h"
-#include "GModel.h"
-#include "PView.h"
-#include "PViewData.h"
-#include "PViewOptions.h"
-#include "OS.h"
-#include "StringUtils.h"
-#include "OpenFile.h"
-#include "CreateFile.h"
-#include "findLinks.h"
-#include "GeoStringInterface.h"
-#include "Options.h"
-#include "Context.h"
-#include "Generator.h"
-#include "HighOrder.h"
-#include "Field.h"
-#if defined(HAVE_ONELAB)
-#include "onelab.h"
-#endif
-#if defined(HAVE_3M)
-#include "3M.h"
-#endif
-
-static void file_new_cb(Fl_Widget *w, void *data)
-{
- test:
-  if(fileChooser(FILE_CHOOSER_CREATE, "New", "",
-                 GModel::current()->getFileName().c_str())) {
-    std::string name = fileChooserGetName(1);
-    if(!StatFile(name)){
-      if(fl_choice("File '%s' already exists.\n\nDo you want to erase it?",
-                   "Cancel", "Erase", 0, name.c_str()))
-        UnlinkFile(name);
-      else
-        goto test;
-    }
-    FILE *fp = fopen(name.c_str(), "w");
-    if(!fp){
-      Msg::Error("Unable to open file '%s'", name.c_str());
-      return;
-    }
-    time_t now;
-    time(&now);
-    fprintf(fp, "// Gmsh project created on %s", ctime(&now));
-    fclose(fp);
-    OpenProject(name);
-    drawContext::global()->draw();
-  }
-}
-
-#if defined(HAVE_NATIVE_FILE_CHOOSER)
-#  define TT "\t"
-#  define NN "\n"
-#else
-#  define TT " ("
-#  define NN ")\t"
-#endif
-
-static const char *input_formats =
-  "All Files" TT "*.*" NN
-  "Geometry - Gmsh GEO" TT "*.geo" NN
-#if defined(HAVE_ACIS)
-  "Geometry - ACIS" TT "*.sat" NN
-#endif
-#if defined(HAVE_OCC)
-  "Geometry - OpenCASCADE BRep" TT "*.brep" NN
-  "Geometry - OpenCASCADE IGES" TT "*.{igs,iges}" NN
-  "Geometry - OpenCASCADE STEP" TT "*.{stp,step}" NN
-#endif
-  "Mesh - Gmsh MSH" TT "*.msh" NN
-  "Mesh - Diffpack 3D" TT "*.diff" NN
-  "Mesh - I-deas Universal" TT "*.unv" NN
-#if defined(HAVE_MED)
-  "Mesh - MED" TT "*.{med,mmed}" NN
-#endif
-  "Mesh - INRIA Medit" TT "*.mesh" NN
-  "Mesh - Nastran Bulk Data File" TT "*.{bdf,nas}" NN
-  "Mesh - Plot3D Structured Mesh" TT "*.p3d" NN
-  "Mesh - STL Surface" TT "*.stl" NN
-  "Mesh - VTK" TT "*.vtk" NN
-  "Mesh - VRML Surface" TT "*.{wrl,vrml}" NN
-  "Mesh - PLY2 Surface" TT "*.ply2" NN
-  "Post-processing - Gmsh POS" TT "*.pos" NN
-#if defined(HAVE_MED)
-  "Post-processing - MED" TT "*.{rmed}" NN
-#endif
-  "Image - BMP" TT "*.bmp" NN
-#if defined(HAVE_LIBJPEG)
-  "Image - JPEG" TT "*.{jpg,jpeg}" NN
-#endif
-  "Image - PBM" TT "*.pbm" NN
-  "Image - PGM" TT "*.pgm" NN
-#if defined(HAVE_LIBPNG)
-  "Image - PNG" TT "*.png" NN
-#endif
-  "Image - PNM" TT "*.pnm" NN
-  "Image - PPM" TT "*.ppm" NN;
-
-static void file_open_cb(Fl_Widget *w, void *data)
-{
-  int n = PView::list.size();
-  if(fileChooser(FILE_CHOOSER_SINGLE, "Open", input_formats,
-                 GModel::current()->getFileName().c_str())) {
-    OpenProject(fileChooserGetName(1));
-    drawContext::global()->draw();
-  }
-  if(n != (int)PView::list.size())
-    FlGui::instance()->menu->setContext(menu_post, 0);
-  if(CTX::instance()->launchOnelabAtStartup != -2)
-    solver_cb(0, (void*)CTX::instance()->launchOnelabAtStartup);
-}
-
-static void file_merge_cb(Fl_Widget *w, void *data)
-{
-  int n = PView::list.size();
-  int f = fileChooser(FILE_CHOOSER_MULTI, "Merge", input_formats,
-                      GModel::current()->getFileName().c_str());
-  if(f) {
-    for(int i = 1; i <= f; i++)
-      MergeFile(fileChooserGetName(i));
-    drawContext::global()->draw();
-  }
-  if(n != (int)PView::list.size())
-    FlGui::instance()->menu->setContext(menu_post, 0);
-  if(CTX::instance()->launchOnelabAtStartup != -2)
-    solver_cb(0, (void*)CTX::instance()->launchOnelabAtStartup);
-}
-
-static void file_open_recent_cb(Fl_Widget *w, void *data)
-{
-  if(!data) return;
-  std::string str((const char*)data);
-  int n = PView::list.size();
-  OpenProject(str);
-  drawContext::global()->draw();
-  if(n != (int)PView::list.size())
-    FlGui::instance()->menu->setContext(menu_post, 0);
-}
-
-static void file_clear_cb(Fl_Widget *w, void *data)
-{
-  ClearProject();
-  drawContext::global()->draw();
-}
-
-static void file_remote_cb(Fl_Widget *w, void *data)
-{
-#if defined(HAVE_ONELAB)
-  onelab::localNetworkClient *c;
-  onelab::server::citer it = onelab::server::instance()->findClient("GmshRemote");
-  if(it == onelab::server::instance()->lastClient()){
-    c = new onelab::localNetworkClient("GmshRemote", "");
-    c->setSocketSwitch("-socket");
-  }
-  else
-    c = (onelab::localNetworkClient*)it->second;
-  GmshServer *server = c->getGmshServer();
-
-  std::string str((const char*)data);
-
-  if(str == "start"){
-    if(server){
-      Msg::Error("Cannot start: remote Gmsh is already running");
-      return;
-    }
-    c->setExecutable(connectionChooser());
-    if(c->getExecutable().size()) c->run();
-  }
-  else{
-    if(!server){
-      Msg::Error("Cannot %s: remote Gmsh not running", str.c_str());
-      return;
-    }
-    if(str == "stop"){
-      server->SendString(GmshSocket::GMSH_STOP, "Disconnect!");
-    }
-    else if(str == "merge"){
-      const char *file = fl_input("Merge", "/tmp/data.pos");
-      if(file) server->SendString(GmshSocket::GMSH_MERGE_FILE, file);
-    }
-    else if(str == "clear"){
-      server->SendString(GmshSocket::GMSH_PARSE_STRING, "Delete All;");
-      for(int i = PView::list.size() - 1; i >= 0; i--)
-        if(PView::list[i]->getData()->isRemote()) delete PView::list[i];
-      FlGui::instance()->updateViews();
-      drawContext::global()->draw();
-    }
-    else if(str == "test"){
-      server->SendString(GmshSocket::GMSH_SPEED_TEST, "Speed test");
-    }
-  }
-#endif
-}
-
-static void file_window_cb(Fl_Widget *w, void *data)
-{
-  std::string str((const char*)data);
-  if(str == "new"){
-    graphicWindow *g1 = FlGui::instance()->graph.back();
-    graphicWindow *g2 = new graphicWindow(false, CTX::instance()->numTiles);
-    FlGui::instance()->graph.push_back(g2);
-    FlGui::instance()->setGraphicTitle(GModel::current()->getFileName());
-    g2->win->resize(g1->win->x() + 10, g1->win->y() + 10,
-                    g1->win->w(), g1->win->h());
-    g2->win->show();
-  }
-  else if(str == "split_h"){
-    FlGui::instance()->splitCurrentOpenglWindow('h');
-  }
-  else if(str == "split_v"){
-    FlGui::instance()->splitCurrentOpenglWindow('v');
-  }
-  else if(str == "split_u"){
-    FlGui::instance()->splitCurrentOpenglWindow('u');
-  }
-  drawContext::global()->draw();
-}
-
-static int _save_msh(const char *name){ return mshFileDialog(name); }
-static int _save_mesh_stat(const char *name){ return meshStatFileDialog(name); }
-static int _save_options(const char *name){ return optionsFileDialog(name); }
-static int _save_geo(const char *name){ return geoFileDialog(name); }
-static int _save_brep(const char *name){ CreateOutputFile(name, FORMAT_BREP); return 1; }
-static int _save_step(const char *name){ CreateOutputFile(name, FORMAT_STEP); return 1; }
-static int _save_cgns(const char *name){ return cgnsFileDialog(name); }
-static int _save_unv(const char *name){ return unvFileDialog(name); }
-static int _save_vtk(const char *name){ return genericMeshFileDialog
-    (name, "VTK Options", FORMAT_VTK, true, false); }
-static int _save_diff(const char *name){ return genericMeshFileDialog
-    (name, "Diffpack Options", FORMAT_DIFF, true, false); }
-static int _save_inp(const char *name){ return genericMeshFileDialog
-    (name, "Abaqus INP Options", FORMAT_INP, false, false); }
-static int _save_med(const char *name){ return genericMeshFileDialog
-    (name, "MED Options", FORMAT_MED, false, false); }
-static int _save_mesh(const char *name){ return genericMeshFileDialog
-    (name, "MESH Options", FORMAT_MESH, false, true); }
-static int _save_mail(const char *name){ return genericMeshFileDialog
-    (name, "MAIL Options", FORMAT_MAIL, false, false); }
-static int _save_bdf(const char *name){ return bdfFileDialog(name); }
-static int _save_p3d(const char *name){ return genericMeshFileDialog
-    (name, "P3D Options", FORMAT_P3D, false, false); }
-static int _save_ir3(const char *name){ return genericMeshFileDialog
-    (name, "Iridium Options", FORMAT_IR3, false, true); }
-static int _save_stl(const char *name){ return genericMeshFileDialog
-    (name, "STL Options", FORMAT_STL, true, false); }
-static int _save_vrml(const char *name){ return genericMeshFileDialog
-    (name, "VRML Options", FORMAT_VRML, false, false); }
-static int _save_ply2(const char *name){ return genericMeshFileDialog
-    (name, "PLY2 Options", FORMAT_PLY2, false, false); }
-static int _save_eps(const char *name){ return gl2psFileDialog
-    (name, "EPS Options", FORMAT_EPS); }
-static int _save_gif(const char *name){ return gifFileDialog(name); }
-static int _save_jpeg(const char *name){ return jpegFileDialog(name); }
-static int _save_mpeg(const char *name){ return mpegFileDialog(name); }
-static int _save_tex(const char *name){ return latexFileDialog(name); }
-static int _save_pdf(const char *name){ return gl2psFileDialog
-    (name, "PDF Options", FORMAT_PDF); }
-static int _save_png(const char *name){ return genericBitmapFileDialog
-    (name, "PNG Options", FORMAT_PNG); }
-static int _save_ps(const char *name){ return gl2psFileDialog
-    (name, "PS Options", FORMAT_PS); }
-static int _save_ppm(const char *name){ return genericBitmapFileDialog
-    (name, "PPM Options", FORMAT_PPM); }
-static int _save_svg(const char *name){ return gl2psFileDialog
-    (name, "SVG Options", FORMAT_SVG); }
-static int _save_yuv(const char *name){ return genericBitmapFileDialog
-    (name, "YUV Options", FORMAT_YUV); }
-static int _save_view_pos(const char *name){ return posFileDialog(name); }
-static int _save_view_med(const char *name){ return genericViewFileDialog
-    (name, "MED Options", 6); }
-static int _save_view_txt(const char *name){ return genericViewFileDialog
-    (name, "TXT Options", 4); }
-
-static int _save_auto(const char *name)
-{
-  switch(GuessFileFormatFromFileName(name)){
-  case FORMAT_MSH  : return _save_msh(name);
-  case FORMAT_POS  : return _save_view_pos(name);
-  case FORMAT_TXT  : return _save_view_txt(name);
-  case FORMAT_OPT  : return _save_options(name);
-  case FORMAT_GEO  : return _save_geo(name);
-  case FORMAT_BREP : return _save_brep(name);
-  case FORMAT_STEP : return _save_step(name);
-  case FORMAT_CGNS : return _save_cgns(name);
-  case FORMAT_UNV  : return _save_unv(name);
-  case FORMAT_VTK  : return _save_vtk(name);
-  case FORMAT_MED  : return _save_med(name);
-  case FORMAT_RMED : return _save_view_med(name);
-  case FORMAT_MESH : return _save_mesh(name);
-  case FORMAT_MAIL : return _save_mail(name);
-  case FORMAT_BDF  : return _save_bdf(name);
-  case FORMAT_DIFF : return _save_diff(name);
-  case FORMAT_INP  : return _save_inp(name);
-  case FORMAT_P3D  : return _save_p3d(name);
-  case FORMAT_IR3  : return _save_ir3(name);
-  case FORMAT_STL  : return _save_stl(name);
-  case FORMAT_VRML : return _save_vrml(name);
-  case FORMAT_PLY2 : return _save_ply2(name);
-  case FORMAT_EPS  : return _save_eps(name);
-  case FORMAT_GIF  : return _save_gif(name);
-  case FORMAT_JPEG : return _save_jpeg(name);
-  case FORMAT_MPEG : return _save_mpeg(name);
-  case FORMAT_TEX  : return _save_tex(name);
-  case FORMAT_PDF  : return _save_pdf(name);
-  case FORMAT_PNG  : return _save_png(name);
-  case FORMAT_PS   : return _save_ps(name);
-  case FORMAT_PPM  : return _save_ppm(name);
-  case FORMAT_SVG  : return _save_svg(name);
-  case FORMAT_YUV  : return _save_yuv(name);
-  default :
-    CreateOutputFile(name, FORMAT_AUTO);
-    return 1;
-  }
-}
-
-typedef struct{
-  const char *pat;
-  int (*func) (const char *name);
-} patXfunc;
-
-static void file_save_as_cb(Fl_Widget *w, void *data)
-{
-  static patXfunc formats[] = {
-    {"Guess From Extension" TT "*.*", _save_auto},
-    {"Geometry - Gmsh Options" TT "*.opt", _save_options},
-    {"Geometry - Gmsh Unrolled GEO" TT "*.geo", _save_geo},
-#if defined(HAVE_OCC)
-    {"Geometry - OpenCASCADE STEP" TT "*.step", _save_step},
-    {"Geometry - OpenCASCADE BRep" TT "*.brep", _save_brep},
-#endif
-    {"Mesh - Gmsh MSH" TT "*.msh", _save_msh},
-    {"Mesh - Abaqus INP" TT "*.inp", _save_inp},
-#if defined(HAVE_LIBCGNS)
-    {"Mesh - CGNS (Experimental)" TT "*.cgns", _save_cgns},
-#endif
-    {"Mesh - Diffpack 3D" TT "*.diff", _save_diff},
-    {"Mesh - I-deas Universal" TT "*.unv", _save_unv},
-    {"Mesh - Iridum" TT "*.ir3", _save_ir3},
-#if defined(HAVE_MED)
-    {"Mesh - MED" TT "*.med", _save_med},
-#endif
-    {"Mesh - INRIA Medit" TT "*.mesh", _save_mesh},
-    {"Mesh - CEA Triangulation" TT "*.mail", _save_mail},
-    {"Mesh - Nastran Bulk Data File" TT "*.bdf", _save_bdf},
-    {"Mesh - Plot3D Structured Mesh" TT "*.p3d", _save_p3d},
-    {"Mesh - STL Surface" TT "*.stl", _save_stl},
-    {"Mesh - VRML Surface" TT "*.wrl", _save_vrml},
-    {"Mesh - VTK" TT "*.vtk", _save_vtk},
-    {"Mesh - PLY2 Surface" TT "*.ply2", _save_ply2},
-    {"Post-processing - Gmsh POS" TT "*.pos", _save_view_pos},
-#if defined(HAVE_MED)
-    {"Post-processing - MED" TT "*.rmed", _save_view_med},
-#endif
-    {"Post-processing - Generic TXT" TT "*.txt", _save_view_txt},
-    {"Post-processing - Mesh Statistics" TT "*.pos", _save_mesh_stat},
-    {"Image - Encapsulated PostScript" TT "*.eps", _save_eps},
-    {"Image - GIF" TT "*.gif", _save_gif},
-#if defined(HAVE_LIBJPEG)
-    {"Image - JPEG" TT "*.jpg", _save_jpeg},
-#endif
-    {"Image - LaTeX" TT "*.tex", _save_tex},
-    {"Image - PDF" TT "*.pdf", _save_pdf},
-#if defined(HAVE_LIBPNG)
-    {"Image - PNG" TT "*.png", _save_png},
-#endif
-    {"Image - PostScript" TT "*.ps", _save_ps},
-    {"Image - PPM" TT "*.ppm", _save_ppm},
-    {"Image - SVG" TT "*.svg", _save_svg},
-    {"Image - YUV" TT "*.yuv", _save_yuv},
-#if defined(HAVE_MPEG_ENCODE)
-    {"Movie - MPEG" TT "*.mpg", _save_mpeg},
-#endif
-  };
-  int nbformats = sizeof(formats) / sizeof(formats[0]);
-  static char *pat = 0;
-  if(!pat) {
-    pat = new char[nbformats * 256];
-    strcpy(pat, formats[0].pat);
-    for(int i = 1; i < nbformats; i++) {
-      strcat(pat, NN);
-      strcat(pat, formats[i].pat);
-    }
-  }
-
- test:
-  if(fileChooser(FILE_CHOOSER_CREATE, "Save As", pat,
-                 GModel::current()->getFileName().c_str())) {
-    std::string name = fileChooserGetName(1);
-    if(CTX::instance()->confirmOverwrite) {
-      if(!StatFile(name))
-        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-                      "Cancel", "Replace", 0, name.c_str()))
-          goto test;
-    }
-    int i = fileChooserGetFilter();
-    if(i >= 0 && i < nbformats){
-      if(!formats[i].func(name.c_str())) goto test;
-    }
-    else{ // handle any additional automatic fltk filter
-      if(!_save_auto(name.c_str())) goto test;
-    }
-  }
-}
-
-static void file_options_save_cb(Fl_Widget *w, void *data)
-{
-  std::string str((const char*)data), fileName;
-  if(str == "file")
-    fileName = GModel::current()->getFileName() + ".opt";
-  else
-    fileName = CTX::instance()->homeDir + CTX::instance()->optionsFileName;
-  Msg::StatusBar(2, true, "Writing '%s'...", fileName.c_str());
-  if(str == "file")
-    PrintOptions(0, GMSH_FULLRC, 1, 0, fileName.c_str());
-  else
-    PrintOptions(0, GMSH_OPTIONSRC, 1, 1, fileName.c_str());
-  Msg::StatusBar(2, true, "Done writing '%s'", fileName.c_str());
-}
-
-static void file_rename_cb(Fl_Widget *w, void *data)
-{
- test:
-  if(fileChooser(FILE_CHOOSER_CREATE, "Rename", "",
-                 GModel::current()->getFileName().c_str())) {
-    std::string name = fileChooserGetName(1);
-    if(CTX::instance()->confirmOverwrite) {
-      if(!StatFile(name))
-        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-                      "Cancel", "Replace", 0, name.c_str()))
-          goto test;
-    }
-    rename(GModel::current()->getFileName().c_str(), name.c_str());
-    GModel::current()->setFileName(name);
-    GModel::current()->setName(SplitFileName(name)[1]);
-    FlGui::instance()->setGraphicTitle(GModel::current()->getFileName());
-    drawContext::global()->draw();
-  }
-}
-
-void file_quit_cb(Fl_Widget *w, void *data)
-{
-  Msg::Exit(0);
-}
-
-void file_watch_cb(Fl_Widget *w, void *data)
-{
-  if(w) CTX::instance()->watchFilePattern = patternChooser();
-
-  if(CTX::instance()->watchFilePattern.empty()) return;
-
-  std::string pattern = FixRelativePath
-    (GModel::current()->getFileName(), CTX::instance()->watchFilePattern);
-  std::string directory = SplitFileName(pattern)[0];
-  if(directory.empty()) directory = "./";
-
-  dirent **files = 0;
-  int num = fl_filename_list(directory.c_str(), &files, fl_numericsort);
-  if(num <= 0) return;
-  std::vector<std::string> matches;
-  for (int i = 0; i < num; i++) {
-    std::string name = directory + files[i]->d_name;
-    if(fl_filename_match(name.c_str(), pattern.c_str()))
-      matches.push_back(name);
-    free((void*)files[i]);
-  }
-  if(files) free((void*)files);
-
-  Msg::Info("%d match%s for pattern '%s'", (int)matches.size(),
-            (matches.size() > 1) ? "es" : "", pattern.c_str());
-
-  std::set<std::string> allFiles;
-  for(unsigned int i = 0; i < GModel::list.size(); i++)
-    allFiles.insert(GetFileNameWithoutPath(GModel::list[i]->getFileName()));
-  for(unsigned int i = 0; i < PView::list.size(); i++)
-    for(int j = 0; j < PView::list[i]->getData()->getNumTimeSteps(); j++)
-      allFiles.insert(GetFileNameWithoutPath(PView::list[i]->getData()->getFileName(j)));
-
-  for(unsigned int i = 0; i < matches.size(); i++)
-    if(allFiles.find(GetFileNameWithoutPath(matches[i])) == allFiles.end())
-      MergeFile(matches[i]);
-  drawContext::global()->draw();
-}
-
-#if defined(__APPLE__)
-#  define CC(str) "Cmd+" str " "
-#else
-#  define CC(str) "Ctrl+" str
-#endif
-
-static void help_short_cb(Fl_Widget *w, void *data)
-{
-  Msg::Direct(" ");
-  Msg::Direct("Keyboard shortcuts:");
-  Msg::Direct(" ");
-  Msg::Direct("  Left arrow    Go to previous time step");
-  Msg::Direct("  Right arrow   Go to next time step");
-  Msg::Direct("  Up arrow      Make previous view visible");
-  Msg::Direct("  Down arrow    Make next view visible");
-  Msg::Direct(" ");
-  Msg::Direct("  <             Go back to previous context");
-  Msg::Direct("  >             Go forward to next context");
-  Msg::Direct("  0             Reload project file");
-  Msg::Direct("  1 or F1       Mesh lines");
-  Msg::Direct("  2 or F2       Mesh surfaces");
-  Msg::Direct("  3 or F3       Mesh volumes");
-  Msg::Direct("  Escape        Cancel lasso zoom/selection, toggle mouse selection ON/OFF");
-  Msg::Direct(" ");
-  Msg::Direct("  g             Go to geometry module");
-  Msg::Direct("  m             Go to mesh module");
-  Msg::Direct("  p             Go to post-processing module");
-  Msg::Direct("  s             Go to solver module");
-  Msg::Direct(" ");
-  Msg::Direct("  Shift+a       Bring all windows to front");
-  Msg::Direct("  Shift+g       Show geometry options");
-  Msg::Direct("  Shift+m       Show mesh options");
-  Msg::Direct("  Shift+o       Show general options");
-  Msg::Direct("  Shift+p       Show post-processing options");
-  Msg::Direct("  Shift+s       Show solver options");
-  Msg::Direct("  Shift+u       Show post-processing view plugins");
-  Msg::Direct("  Shift+w       Show post-processing view options");
-  Msg::Direct("  Shift+Escape  Enable full mouse selection");
-  Msg::Direct(" ");
-  Msg::Direct("  " CC("i") "        Show statistics window");
-  Msg::Direct("  " CC("l") "        Show message console");
-#if defined(__APPLE__)
-  Msg::Direct("  " CC("m") "        Minimize window");
-#endif
-  Msg::Direct("  " CC("n") "        Create new project file");
-  Msg::Direct("  " CC("o") "        Open project file");
-  Msg::Direct("  " CC("q") "        Quit");
-  Msg::Direct("  " CC("r") "        Rename project file");
-  Msg::Direct("  " CC("s") "        Save file as");
-  Msg::Direct(" ");
-  Msg::Direct("  Shift+" CC("c") "  Show clipping plane window");
-  Msg::Direct("  Shift+" CC("m") "  Show manipulator window");
-  Msg::Direct("  Shift+" CC("n") "  Show option window");
-  Msg::Direct("  Shift+" CC("o") "  Merge file(s)");
-  Msg::Direct("  Shift+" CC("s") "  Save mesh in default format");
-  Msg::Direct("  Shift+" CC("u") "  Show plugin window");
-  Msg::Direct("  Shift+" CC("v") "  Show visibility window");
-  Msg::Direct(" ");
-  Msg::Direct("  Alt+a         Loop through axes modes");
-  Msg::Direct("  Alt+b         Hide/show bounding boxes");
-  Msg::Direct("  Alt+c         Loop through predefined color schemes");
-  Msg::Direct("  Alt+e         Hide/Show element outlines for visible post-pro views");
-  Msg::Direct("  Alt+f         Change redraw mode (fast/full)");
-  Msg::Direct("  Alt+h         Hide/show all post-processing views");
-  Msg::Direct("  Alt+i         Hide/show all post-processing view scales");
-  Msg::Direct("  Alt+l         Hide/show geometry lines");
-  Msg::Direct("  Alt+m         Toggle visibility of all mesh entities");
-  Msg::Direct("  Alt+n         Hide/show all post-processing view annotations");
-  Msg::Direct("  Alt+o         Change projection mode (orthographic/perspective)");
-  Msg::Direct("  Alt+p         Hide/show geometry points");
-  Msg::Direct("  Alt+r         Loop through range modes for visible post-pro views");
-  Msg::Direct("  Alt+s         Hide/show geometry surfaces");
-  Msg::Direct("  Alt+t         Loop through interval modes for visible post-pro views");
-  Msg::Direct("  Alt+v         Hide/show geometry volumes");
-  Msg::Direct("  Alt+w         Enable/disable all lighting");
-  Msg::Direct("  Alt+x         Set X view");
-  Msg::Direct("  Alt+y         Set Y view");
-  Msg::Direct("  Alt+z         Set Z view");
-  Msg::Direct(" ");
-  Msg::Direct("  Alt+Shift+a   Hide/show small axes");
-  Msg::Direct("  Alt+Shift+b   Hide/show mesh volume faces");
-  Msg::Direct("  Alt+Shift+d   Hide/show mesh surface faces");
-  Msg::Direct("  Alt+Shift+l   Hide/show mesh lines");
-  Msg::Direct("  Alt+Shift+o   Adjust projection parameters");
-  Msg::Direct("  Alt+Shift+p   Hide/show mesh points");
-  Msg::Direct("  Alt+Shift+s   Hide/show mesh surface edges");
-  Msg::Direct("  Alt+Shift+v   Hide/show mesh volume edges");
-  Msg::Direct("  Alt+Shift+w   Reverse all mesh normals");
-  Msg::Direct("  Alt+Shift+x   Set -X view");
-  Msg::Direct("  Alt+Shift+y   Set -Y view");
-  Msg::Direct("  Alt+Shift+z   Set -Z view");
-  Msg::Direct(" ");
-  FlGui::instance()->showMessages();
-}
-
-#undef CC
-
-static void help_mouse_cb(Fl_Widget *w, void *data)
-{
-  Msg::Direct(" ");
-  Msg::Direct("Mouse actions:");
-  Msg::Direct(" ");
-  Msg::Direct("  Move                - Highlight the entity under the mouse pointer");
-  Msg::Direct("                        and display its properties in the status bar");
-  Msg::Direct("                      - Resize a lasso zoom or a lasso (un)selection");
-  Msg::Direct("  Left button         - Rotate");
-  Msg::Direct("                      - Select an entity");
-  Msg::Direct("                      - Accept a lasso zoom or a lasso selection");
-  Msg::Direct("  Ctrl+Left button    Start a lasso zoom or a lasso (un)selection");
-  Msg::Direct("  Middle button       - Zoom");
-  Msg::Direct("                      - Unselect an entity");
-  Msg::Direct("                      - Accept a lasso zoom or a lasso unselection");
-  Msg::Direct("  Ctrl+Middle button  Orthogonalize display");
-  Msg::Direct("  Right button        - Pan");
-  Msg::Direct("                      - Cancel a lasso zoom or a lasso (un)selection");
-  Msg::Direct("                      - Pop-up menu on post-processing view button");
-  Msg::Direct("  Ctrl+Right button   Reset to default viewpoint");
-  Msg::Direct(" ");
-  Msg::Direct("  For a 2 button mouse, Middle button = Shift+Left button");
-  Msg::Direct("  For a 1 button mouse, Middle button = Shift+Left button, "
-              "Right button = Alt+Left button");
-  Msg::Direct(" ");
-  FlGui::instance()->showMessages();
-}
-
-static void help_command_line_cb(Fl_Widget *w, void *data)
-{
-  Msg::Direct(" ");
-  PrintUsage("gmsh");
-  FlGui::instance()->showMessages();
-}
-
-static void help_online_cb(Fl_Widget *w, void *data)
-{
-  std::string prog = FixWindowsPath(CTX::instance()->webBrowser);
-  SystemCall(ReplaceSubString("%s", "http://geuz.org/gmsh/doc/texinfo/", prog));
-}
-
-void help_about_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->about->win->show();
-}
-
-void mod_geometry_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_geometry, 0);
-}
-
-void mod_mesh_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_mesh, 0);
-}
-
-void mod_solver_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_solver, 0);
-}
-
-void mod_post_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_post, 0);
-}
-
-void mod_back_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(0, -1);
-}
-
-void mod_forward_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(0, 1);
-}
-
-static void geometry_elementary_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_geometry_elementary, 0);
-}
-
-static void geometry_physical_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_geometry_physical, 0);
-}
-
-static void geometry_edit_cb(Fl_Widget *w, void *data)
-{
-  std::string prog = FixWindowsPath(CTX::instance()->editor);
-  std::string file = FixWindowsPath(GModel::current()->getFileName());
-  SystemCall(ReplaceSubString("%s", file, prog));
-}
-
-void geometry_reload_cb(Fl_Widget *w, void *data)
-{
-  std::string fileName = GModel::current()->getFileName();
-  OpenProject(fileName);
-  drawContext::global()->draw();
-}
-
-static void geometry_elementary_add_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_geometry_elementary_add, 0);
-}
-
-static void add_new_point()
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-
-  FlGui::instance()->geoContext->show(1);
-
-  while(1) {
-    for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
-      for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
-        FlGui::instance()->graph[i]->gl[j]->addPointMode = true;
-    Msg::StatusBar(3, false, "Move mouse and/or enter coordinates\n"
-                   "[Press 'Shift' to hold position, 'e' to add point "
-                   "or 'q' to abort]");
-    char ib = FlGui::instance()->selectEntity(ENT_NONE);
-    if(ib == 'e'){
-      add_point(GModel::current()->getFileName(),
-                FlGui::instance()->geoContext->input[2]->value(),
-                FlGui::instance()->geoContext->input[3]->value(),
-                FlGui::instance()->geoContext->input[4]->value(),
-                FlGui::instance()->geoContext->input[5]->value());
-      FlGui::instance()->resetVisibility();
-      drawContext::global()->draw();
-    }
-    if(ib == 'q'){
-      for(unsigned int i = 0; i < FlGui::instance()->graph.size(); i++)
-        for(unsigned int j = 0; j < FlGui::instance()->graph[i]->gl.size(); j++)
-          FlGui::instance()->graph[i]->gl[j]->addPointMode = false;
-      break;
-    }
-  }
-
-  // at the end, not during creation to avoid having things jumping around
-  SetBoundingBox();
-  Msg::StatusBar(3, false, "");
-}
-
-static void add_new_multiline(std::string type)
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-
-  std::vector<int> p;
-  while(1) {
-    if(p.empty())
-      Msg::StatusBar(3, false, "Select control points\n"
-                     "[Press 'e' to end selection or 'q' to abort]");
-    else
-      Msg::StatusBar(3, false, "Select control points\n"
-                     "[Press 'e' to end selection, 'u' to undo last selection "
-                     "or 'q' to abort]");
-    char ib = FlGui::instance()->selectEntity(ENT_POINT);
-    if(ib == 'l') {
-      for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-        FlGui::instance()->selectedVertices[i]->setSelection(1);
-        p.push_back(FlGui::instance()->selectedVertices[i]->tag());
-      }
-      drawContext::global()->draw();
-    }
-    if(ib == 'r') {
-      Msg::Warning("Entity de-selection not supported yet during multi-line creation");
-    }
-    if(ib == 'e') {
-      if(p.size() >= 2)
-        add_multline(type, p, GModel::current()->getFileName());
-      FlGui::instance()->resetVisibility();
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      p.clear();
-    }
-    if(ib == 'u') {
-      if(p.size()){
-        GVertex *gv = GModel::current()->getVertexByTag(p.back());
-        if(gv) gv->setSelection(0);
-        drawContext::global()->draw();
-        p.pop_back();
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      break;
-    }
-  }
-
-  Msg::StatusBar(3, false, "");
-}
-
-static void add_new_line()
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-
-  std::vector<int> p;
-  while(1) {
-    if(p.empty())
-      Msg::StatusBar(3, false, "Select start point\n"
-                     "[Press 'q' to abort]");
-    if(p.size() == 1)
-      Msg::StatusBar(3, false, "Select end point\n"
-                     "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = FlGui::instance()->selectEntity(ENT_POINT);
-    if(ib == 'l') {
-      FlGui::instance()->selectedVertices[0]->setSelection(1);
-      drawContext::global()->draw();
-      p.push_back(FlGui::instance()->selectedVertices[0]->tag());
-    }
-    if(ib == 'r') {
-      Msg::Warning("Entity de-selection not supported yet during line creation");
-    }
-    if(ib == 'u') {
-      if(p.size()){
-        GVertex *gv = GModel::current()->getVertexByTag(p.back());
-        if(gv) gv->setSelection(0);
-        drawContext::global()->draw();
-        p.pop_back();
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      break;
-    }
-    if(p.size() == 2) {
-      add_multline("Line", p, GModel::current()->getFileName());
-      FlGui::instance()->resetVisibility();
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      p.clear();
-    }
-  }
-
-  Msg::StatusBar(3, false, "");
-}
-
-static void add_new_circle()
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-
-  std::vector<int> p;
-  while(1) {
-    if(p.empty())
-      Msg::StatusBar(3, false, "Select start point\n"
-                     "[Press 'q' to abort]");
-    if(p.size() == 1)
-      Msg::StatusBar(3, false, "Select center point\n"
-                     "[Press 'u' to undo last selection or 'q' to abort]");
-    if(p.size() == 2)
-      Msg::StatusBar(3, false, "Select end point\n"
-                     "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = FlGui::instance()->selectEntity(ENT_POINT);
-    if(ib == 'l') {
-      FlGui::instance()->selectedVertices[0]->setSelection(1);
-      drawContext::global()->draw();
-      p.push_back(FlGui::instance()->selectedVertices[0]->tag());
-    }
-    if(ib == 'r') {
-      Msg::Warning("Entity de-selection not supported yet during circle creation");
-    }
-    if(ib == 'u') {
-      if(p.size()){
-        GVertex *gv = GModel::current()->getVertexByTag(p.back());
-        if(gv) gv->setSelection(0);
-        drawContext::global()->draw();
-        p.pop_back();
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      break;
-    }
-    if(p.size() == 3) {
-      add_circ(p[0], p[1], p[2], GModel::current()->getFileName()); // begin, center, end
-      FlGui::instance()->resetVisibility();
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      p.clear();
-    }
-  }
-
-  Msg::StatusBar(3, false, "");
-}
-
-static void add_new_ellipse()
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-
-  std::vector<int> p;
-  while(1) {
-    if(p.empty())
-      Msg::StatusBar(3, false, "Select start point\n"
-                     "[Press 'q' to abort]");
-    if(p.size() == 1)
-      Msg::StatusBar(3, false, "Select center point\n"
-                     "[Press 'u' to undo last selection or 'q' to abort]");
-    if(p.size() == 2)
-      Msg::StatusBar(3, false, "Select major axis point\n"
-                     "[Press 'u' to undo last selection or 'q' to abort]");
-    if(p.size() == 3)
-      Msg::StatusBar(3, false, "Select end point\n"
-                     "[Press 'u' to undo last selection or 'q' to abort]");
-    char ib = FlGui::instance()->selectEntity(ENT_POINT);
-    if(ib == 'l') {
-      FlGui::instance()->selectedVertices[0]->setSelection(1);
-      drawContext::global()->draw();
-      p.push_back(FlGui::instance()->selectedVertices[0]->tag());
-    }
-    if(ib == 'r') {
-      Msg::Warning("Entity de-selection not supported yet during ellipse creation");
-    }
-    if(ib == 'u') {
-      if(p.size()){
-        GVertex *gv = GModel::current()->getVertexByTag(p.back());
-        if(gv) gv->setSelection(0);
-        drawContext::global()->draw();
-        p.pop_back();
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      break;
-    }
-    if(p.size() == 4) {
-      add_ell(p[0], p[1], p[2], p[3], GModel::current()->getFileName());
-      FlGui::instance()->resetVisibility();
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      p.clear();
-    }
-  }
-
-  Msg::StatusBar(3, false, "");
-}
-
-static int select_contour(int type, int num, List_T * List)
-{
-  int k = 0;
-
-  switch (type) {
-  case ENT_LINE:
-    k = allEdgesLinked(num, List);
-    for(int i = 0; i < List_Nbr(List); i++) {
-      int ip;
-      List_Read(List, i, &ip);
-      GEdge *ge = GModel::current()->getEdgeByTag(abs(ip));
-      if(ge) ge->setSelection(1);
-    }
-    break;
-  case ENT_SURFACE:
-    k = allFacesLinked(num, List);
-    for(int i = 0; i < List_Nbr(List); i++) {
-      int ip;
-      List_Read(List, i, &ip);
-      GFace *gf = GModel::current()->getFaceByTag(abs(ip));
-      if(gf) gf->setSelection(1);
-    }
-    break;
-  }
-
-  drawContext::global()->draw();
-  return k;
-}
-
-static void add_new_surface_volume(int mode)
-{
-  List_T *List1 = List_Create(10, 10, sizeof(int));
-  List_T *List2 = List_Create(10, 10, sizeof(int));
-  int type;
-  if(mode == 2) {
-    type = ENT_SURFACE;
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
-    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else {
-    type = ENT_LINE;
-    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  drawContext::global()->draw();
-
-  while(1) {
-    List_Reset(List1);
-    List_Reset(List2);
-
-    while(1) {
-      if(type == ENT_LINE){
-        if(!List_Nbr(List1))
-          Msg::StatusBar(3, false, "Select surface boundary\n"
-                         "[Press 'q' to abort]");
-        else
-          Msg::StatusBar(3, false, "Select surface boundary\n"
-                         "[Press 'u' to undo last selection or 'q' to abort]");
-      }
-      else{
-        if(!List_Nbr(List1))
-          Msg::StatusBar(3, false, "Select volume boundary\n"
-                         "[Press 'q' to abort]");
-        else
-          Msg::StatusBar(3, false, "Select volume boundary\n"
-                         "[Press 'u' to undo last selection or 'q' to abort]");
-      }
-
-      char ib = FlGui::instance()->selectEntity(type);
-      if(ib == 'q') {
-        GModel::current()->setSelection(0);
-        drawContext::global()->draw();
-        goto stopall;
-      }
-      if(ib == 'u') {
-        if(List_Nbr(List1) > 0){
-          int num;
-          List_Read(List1, List_Nbr(List1)-1, &num);
-          if(type == ENT_LINE){
-            GEdge *ge = GModel::current()->getEdgeByTag(abs(num));
-            if(ge) ge->setSelection(0);
-          }
-          else{
-            GFace *gf = GModel::current()->getFaceByTag(abs(num));
-            if(gf) gf->setSelection(0);
-          }
-          List_Pop(List1);
-          drawContext::global()->draw();
-        }
-      }
-      if(ib == 'r') {
-        Msg::Warning("Entity de-selection not supported yet during "
-                     "surface/volume creation");
-      }
-      if(ib == 'l') {
-        int num = (type == ENT_LINE) ?
-          FlGui::instance()->selectedEdges[0]->tag() :
-          FlGui::instance()->selectedFaces[0]->tag();
-        if(select_contour(type, num, List1)) {
-          if(type == ENT_LINE)
-            add_lineloop(List1, GModel::current()->getFileName(), &num);
-          else
-            add_surfloop(List1, GModel::current()->getFileName(), &num);
-          List_Reset(List1);
-          List_Add(List2, &num);
-          while(1) {
-            if(!List_Nbr(List1))
-              Msg::StatusBar
-                (3, false, "Select hole boundaries (if none, press 'e')\n"
-                 "[Press 'e' to end selection or 'q' to abort]");
-            else
-              Msg::StatusBar
-                (3, false, "Select hole boundaries\n"
-                 "[Press 'e' to end selection, 'u' to undo last selection "
-                 "or 'q' to abort]");
-            ib = FlGui::instance()->selectEntity(type);
-            if(ib == 'q') {
-              GModel::current()->setSelection(0);
-              drawContext::global()->draw();
-              goto stopall;
-            }
-            if(ib == 'e') {
-              GModel::current()->setSelection(0);
-              drawContext::global()->draw();
-              List_Reset(List1);
-              break;
-            }
-            if(ib == 'u') {
-              if(List_Nbr(List1) > 0){
-                int num;
-                List_Read(List1, List_Nbr(List1)-1, &num);
-                if(type == ENT_LINE){
-                  GEdge *ge = GModel::current()->getEdgeByTag(abs(num));
-                  if(ge) ge->setSelection(0);
-                }
-                else{
-                  GFace *gf = GModel::current()->getFaceByTag(abs(num));
-                  if(gf) gf->setSelection(0);
-                }
-                List_Pop(List1);
-                drawContext::global()->draw();
-              }
-            }
-            if(ib == 'l') {
-              int size = (type == ENT_LINE) ?
-                FlGui::instance()->selectedEdges.size() :
-                FlGui::instance()->selectedFaces.size();
-              for(int i=0;i<size;i++){
-                int num = (type == ENT_LINE) ?
-                  FlGui::instance()->selectedEdges[i]->tag() :
-                  FlGui::instance()->selectedFaces[i]->tag();
-                if(select_contour(type, num, List1)) {
-                  if(type == ENT_LINE)
-                    add_lineloop(List1, GModel::current()->getFileName(), &num);
-                  else
-                    add_surfloop(List1, GModel::current()->getFileName(), &num);
-                  List_Reset(List1);
-                  List_Add(List2, &num);
-                }
-              }
-            }
-            if(ib == 'r') {
-              Msg::Warning("Entity de-selection not supported yet during "
-                           "surface/volume creation");
-            }
-          }
-          List_Unique(List2,fcmp_absint);
-          if(List_Nbr(List2)) {
-            switch (mode) {
-            case 0: add_surf("Plane Surface", List2,
-                             GModel::current()->getFileName()); break;
-            case 1: add_surf("Ruled Surface", List2,
-                             GModel::current()->getFileName()); break;
-            case 2: add_vol(List2, GModel::current()->getFileName()); break;
-            }
-            FlGui::instance()->resetVisibility();
-            GModel::current()->setSelection(0);
-            drawContext::global()->draw();
-            break;
-          }
-        } // if select_contour
-      }
-    }
-  }
-
- stopall:
-  List_Delete(List1);
-  List_Delete(List2);
-
-  Msg::StatusBar(3, false, "");
-}
-
-static void geometry_elementary_add_new_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_add_new, 0);
-    return;
-  }
-
-  std::string str((const char*)data);
-  if(str == "Parameter")
-    FlGui::instance()->geoContext->show(0);
-  else if(str == "Point")
-    add_new_point();
-  else if(str == "Line")
-    add_new_line();
-  else if(str == "Spline")
-    add_new_multiline(str);
-  else if(str == "BSpline")
-    add_new_multiline(str);
-  else if(str == "Circle")
-    add_new_circle();
-  else if(str == "Ellipse")
-    add_new_ellipse();
-  else if(str == "Plane Surface")
-    add_new_surface_volume(0);
-  else if(str == "Ruled Surface")
-    add_new_surface_volume(1);
-  else if(str == "Volume")
-    add_new_surface_volume(2);
-  else
-    Msg::Error("Unknown entity to create: %s", str.c_str());
-}
-
-static void split_selection()
-{
-  opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-  Msg::StatusBar(3, false, "Select a line to split\n"
-                 "[Press 'q' to abort]");
-  GEdge* edge_to_split = 0;
-  while(1){
-    char ib = FlGui::instance()->selectEntity(ENT_LINE);
-    if(ib == 'q')
-      break;
-    if(!FlGui::instance()->selectedEdges.empty()){
-      edge_to_split = FlGui::instance()->selectedEdges[0];
-      edge_to_split->setSelection(1);
-      break;
-    }
-  }
-  Msg::StatusBar(3, false, "");
-  if(FlGui::instance()->selectedEdges.empty()) return;
-  List_T *List1 = List_Create(5, 5, sizeof(int));
-  Msg::StatusBar(3, false, "Select break points\n"
-                 "[Press 'e' to end selection or 'q' to abort]");
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  drawContext::global()->draw();
-  while(1){
-    char ib = FlGui::instance()->selectEntity(ENT_POINT);
-    if(ib == 'q')
-      break;
-    if(ib == 'e'){
-      split_edge(edge_to_split->tag(), List1, GModel::current()->getFileName());
-      break;
-    }
-    for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-      int tag = FlGui::instance()->selectedVertices[i]->tag();
-      int index = List_ISearchSeq(List1, &tag, fcmp_int);
-      if(index < 0) List_Add(List1, &tag);
-      FlGui::instance()->selectedVertices[i]->setSelection(1);
-    }
-  }
-  Msg::StatusBar(3, false, "");
-  FlGui::instance()->resetVisibility();
-  GModel::current()->setSelection(0);
-  drawContext::global()->draw();
-}
-
-static void action_point_line_surface_volume(int action, int mode, const char *what)
-{
-  int type;
-  const char *str;
-
-  if(!strcmp(what, "Point")) {
-    type = ENT_POINT;
-    str = "points";
-    opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else if(!strcmp(what, "Line")) {
-    type = ENT_LINE;
-    str = "lines";
-    opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else if(!strcmp(what, "Surface")) {
-    type = ENT_SURFACE;
-    str = "surfaces";
-    opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else if(!strcmp(what, "Volume")) {
-    type = ENT_VOLUME;
-    str = "volumes";
-    opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1);
-  }
-  else{
-    Msg::Error("Unknown entity to select");
-    return;
-  }
-
-  if(action == 8){
-    FlGui::instance()->meshContext->show(0);
-  }
-
-  drawContext::global()->draw();
-
-  List_T *List1 = List_Create(5, 5, sizeof(int));
-  while(1) {
-    if(!List_Nbr(List1))
-      Msg::StatusBar(3, false, "Select %s\n"
-                     "[Press 'e' to end selection or 'q' to abort]", str);
-    else
-      Msg::StatusBar(3, false, "Select %s\n"
-                     "[Press 'e' to end selection, 'u' to undo last selection "
-                     "or 'q' to abort]", str);
-
-    char ib = FlGui::instance()->selectEntity(type);
-    if(ib == 'l') {
-      // we don't use List_Insert in order to keep the original
-      // ordering (this is slower, but this way undo works as
-      // expected)
-      int tag;
-      switch (type) {
-      case ENT_POINT:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-          FlGui::instance()->selectedVertices[i]->setSelection(1);
-          tag = FlGui::instance()->selectedVertices[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      case ENT_LINE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
-          FlGui::instance()->selectedEdges[i]->setSelection(1);
-          tag = FlGui::instance()->selectedEdges[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      case ENT_SURFACE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
-          FlGui::instance()->selectedFaces[i]->setSelection(1);
-          tag = FlGui::instance()->selectedFaces[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      case ENT_VOLUME:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
-          FlGui::instance()->selectedRegions[i]->setSelection(1);
-          tag = FlGui::instance()->selectedRegions[i]->tag();
-          if(List_ISearchSeq(List1, &tag, fcmp_int) < 0)
-            List_Add(List1, &tag);
-        }
-        break;
-      }
-      drawContext::global()->draw();
-    }
-    if(ib == 'r') {
-      // we don't use List_Suppress in order to keep the original
-      // ordering (this is slower, but this way undo works as
-      // expected)
-      int index, tag;
-      switch (type) {
-      case ENT_POINT:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-          tag = FlGui::instance()->selectedVertices[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedVertices[i]->setSelection(0);
-        }
-        break;
-      case ENT_LINE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
-          tag = FlGui::instance()->selectedEdges[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedEdges[i]->setSelection(0);
-        }
-        break;
-      case ENT_SURFACE:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
-          tag = FlGui::instance()->selectedFaces[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedFaces[i]->setSelection(0);
-        }
-        break;
-      case ENT_VOLUME:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
-          tag = FlGui::instance()->selectedRegions[i]->tag();
-          index = List_ISearchSeq(List1, &tag, fcmp_int);
-          if(index >= 0) List_PSuppress(List1, index);
-          FlGui::instance()->selectedRegions[i]->setSelection(0);
-        }
-        break;
-      }
-      drawContext::global()->draw();
-    }
-    if(ib == 'u') {
-      if(List_Nbr(List1)) {
-        int num;
-        List_Read(List1, List_Nbr(List1) - 1, &num);
-        if(type == ENT_POINT){
-          GVertex *gv = GModel::current()->getVertexByTag(num);
-          if(gv) gv->setSelection(0);
-        }
-        else if(type == ENT_LINE){
-          GEdge *ge = GModel::current()->getEdgeByTag(num);
-          if(ge) ge->setSelection(0);
-        }
-        else if(type == ENT_SURFACE){
-          GFace *gf = GModel::current()->getFaceByTag(num);
-          if(gf) gf->setSelection(0);
-        }
-        else if(type == ENT_VOLUME){
-          GRegion *gr = GModel::current()->getRegionByTag(num);
-          if(gr) gr->setSelection(0);
-        }
-        drawContext::global()->draw();
-        List_Pop(List1);
-      }
-    }
-    if(ib == 'i') {
-      Msg::Error("Inverting selection!");
-    }
-    if(ib == 'e') {
-      if(List_Nbr(List1)){
-        switch (action) {
-        case 0:
-          translate(mode, List1, GModel::current()->getFileName(), what,
-                    FlGui::instance()->geoContext->input[6]->value(),
-                    FlGui::instance()->geoContext->input[7]->value(),
-                    FlGui::instance()->geoContext->input[8]->value());
-          break;
-        case 1:
-          rotate(mode, List1, GModel::current()->getFileName(), what,
-                 FlGui::instance()->geoContext->input[12]->value(),
-                 FlGui::instance()->geoContext->input[13]->value(),
-                 FlGui::instance()->geoContext->input[14]->value(),
-                 FlGui::instance()->geoContext->input[9]->value(),
-                 FlGui::instance()->geoContext->input[10]->value(),
-                 FlGui::instance()->geoContext->input[11]->value(),
-                 FlGui::instance()->geoContext->input[15]->value());
-          break;
-        case 2:
-          dilate(mode, List1, GModel::current()->getFileName(), what,
-                 FlGui::instance()->geoContext->input[16]->value(),
-                 FlGui::instance()->geoContext->input[17]->value(),
-                 FlGui::instance()->geoContext->input[18]->value(),
-                 FlGui::instance()->geoContext->input[19]->value());
-          break;
-        case 3:
-          symmetry(mode, List1, GModel::current()->getFileName(), what,
-                   FlGui::instance()->geoContext->input[20]->value(),
-                   FlGui::instance()->geoContext->input[21]->value(),
-                   FlGui::instance()->geoContext->input[22]->value(),
-                   FlGui::instance()->geoContext->input[23]->value());
-          break;
-        case 4:
-          extrude(List1, GModel::current()->getFileName(), what,
-                  FlGui::instance()->geoContext->input[6]->value(),
-                  FlGui::instance()->geoContext->input[7]->value(),
-                  FlGui::instance()->geoContext->input[8]->value());
-          break;
-        case 5:
-          protude(List1, GModel::current()->getFileName(), what,
-                  FlGui::instance()->geoContext->input[12]->value(),
-                  FlGui::instance()->geoContext->input[13]->value(),
-                  FlGui::instance()->geoContext->input[14]->value(),
-                  FlGui::instance()->geoContext->input[9]->value(),
-                  FlGui::instance()->geoContext->input[10]->value(),
-                  FlGui::instance()->geoContext->input[11]->value(),
-                  FlGui::instance()->geoContext->input[15]->value());
-          break;
-        case 6:
-          delet(List1, GModel::current()->getFileName(), what);
-          break;
-        case 7:
-          add_physical(what, List1, GModel::current()->getFileName());
-          break;
-        case 8:
-          add_charlength(List1, GModel::current()->getFileName(),
-                         FlGui::instance()->meshContext->input[0]->value());
-          break;
-        case 9:
-          add_recosurf(List1, GModel::current()->getFileName());
-          break;
-        case 10:
-          add_compound(what, List1, GModel::current()->getFileName());
-          break;
-        default:
-          Msg::Error("Unknown action on selected entities");
-          break;
-        }
-        List_Reset(List1);
-        FlGui::instance()->resetVisibility();
-        GModel::current()->setSelection(0);
-        if(action <= 6) SetBoundingBox();
-        drawContext::global()->draw();
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      break;
-    }
-  }
-  List_Delete(List1);
-
-  Msg::StatusBar(3, false, "");
-}
-
-static void geometry_elementary_add_translate_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_add_translate, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(2);
-  action_point_line_surface_volume(0, 1, (const char*)data);
-}
-
-static void geometry_elementary_add_rotate_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_add_rotate, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(3);
-  action_point_line_surface_volume(1, 1, (const char*)data);
-}
-
-static void geometry_elementary_add_scale_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_add_scale, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(4);
-  action_point_line_surface_volume(2, 1, (const char*)data);
-}
-
-static void geometry_elementary_add_symmetry_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_add_symmetry, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(5);
-  action_point_line_surface_volume(3, 1, (const char*)data);
-}
-
-static void geometry_elementary_translate_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_translate, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(2);
-  action_point_line_surface_volume(0, 0, (const char*)data);
-}
-
-static void geometry_elementary_rotate_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_rotate, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(3);
-  action_point_line_surface_volume(1, 0, (const char*)data);
-}
-
-static void geometry_elementary_scale_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_scale, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(4);
-  action_point_line_surface_volume(2, 0, (const char*)data);
-}
-
-static void geometry_elementary_symmetry_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_symmetry, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(5);
-  action_point_line_surface_volume(3, 0, (const char*)data);
-}
-
-static void geometry_elementary_extrude_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_geometry_elementary_extrude, 0);
-}
-
-static void geometry_elementary_extrude_translate_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_extrude_translate, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(2);
-  action_point_line_surface_volume(4, 0, (const char*)data);
-}
-
-static void geometry_elementary_extrude_rotate_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_extrude_rotate, 0);
-    return;
-  }
-  FlGui::instance()->geoContext->show(3);
-  action_point_line_surface_volume(5, 0, (const char*)data);
-}
-
-static void geometry_elementary_delete_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_delete, 0);
-    return;
-  }
-  action_point_line_surface_volume(6, 0, (const char*)data);
-}
-
-static void geometry_elementary_split_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_elementary_split, 0);
-    return;
-  }
-  split_selection();
-}
-
-static void geometry_elementary_coherence_cb(Fl_Widget *w, void *data)
-{
-  coherence(GModel::current()->getFileName());
-}
-
-static void geometry_physical_add_cb(Fl_Widget *w, void *data)
-{
-  if(!data){
-    FlGui::instance()->menu->setContext(menu_geometry_physical_add, 0);
-    return;
-  }
-  std::string str((const char*)data);
-  if(str == "Point")
-    FlGui::instance()->callForSolverPlugin(0);
-  else if(str == "Line")
-    FlGui::instance()->callForSolverPlugin(1);
-
-  action_point_line_surface_volume(7, 0, str.c_str());
-}
-
-void mesh_save_cb(Fl_Widget *w, void *data)
-{
-  std::string name = CTX::instance()->outputFileName;
-  if(name.empty()){
-    if(CTX::instance()->mesh.fileFormat == FORMAT_AUTO)
-      name = GetDefaultFileName(FORMAT_MSH);
-    else
-      name = GetDefaultFileName(CTX::instance()->mesh.fileFormat);
-  }
-  if(CTX::instance()->confirmOverwrite) {
-    if(!StatFile(name))
-      if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-                    "Cancel", "Replace", 0, name.c_str()))
-        return;
-  }
-  CreateOutputFile(name, CTX::instance()->mesh.fileFormat);
-}
-
-static void mesh_define_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_mesh_define, 0);
-}
-
-void mesh_1d_cb(Fl_Widget *w, void *data)
-{
-  GModel::current()->mesh(1);
-  drawContext::global()->draw();
-}
-
-void mesh_2d_cb(Fl_Widget *w, void *data)
-{
-  GModel::current()->mesh(2);
-  drawContext::global()->draw();
-}
-
-void mesh_3d_cb(Fl_Widget *w, void *data)
-{
-  GModel::current()->mesh(3);
-  drawContext::global()->draw();
-}
-
-static void mesh_delete_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_mesh_delete, 0);
-}
-
-static void mesh_delete_parts_cb(Fl_Widget *w, void *data)
-{
-  const char *str = (const char*)data;
-  int what;
-
-  if(!strcmp(str, "elements")){
-    CTX::instance()->pickElements = 1;
-    what = ENT_ALL;
-  }
-  else if(!strcmp(str, "lines")){
-    CTX::instance()->pickElements = 0;
-    what = ENT_LINE;
-  }
-  else if(!strcmp(str, "surfaces")){
-    CTX::instance()->pickElements = 0;
-    what = ENT_SURFACE;
-  }
-  else if(!strcmp(str, "volumes")){
-    CTX::instance()->pickElements = 0;
-    what = ENT_VOLUME;
-  }
-  else
-    return;
-
-  std::vector<MElement*> ele;
-  std::vector<GEntity*> ent;
-
-  while(1) {
-    CTX::instance()->mesh.changed = ENT_ALL;
-    drawContext::global()->draw();
-
-    if(ele.size() || ent.size())
-      Msg::StatusBar(3, false, "Select %s\n"
-                     "[Press 'e' to end selection, 'u' to undo last selection or "
-                     "'q' to abort]", str);
-    else
-      Msg::StatusBar(3, false, "Select %s\n"
-                     "[Press 'e' to end selection or 'q' to abort]", str);
-
-    char ib = FlGui::instance()->selectEntity(what);
-    if(ib == 'l') {
-      if(CTX::instance()->pickElements){
-        for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
-          if(FlGui::instance()->selectedElements[i]->getVisibility() != 2){
-            FlGui::instance()->selectedElements[i]->setVisibility(2);
-            ele.push_back(FlGui::instance()->selectedElements[i]);
-          }
-        }
-      }
-      else{
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
-          if(FlGui::instance()->selectedEdges[i]->getSelection() != 1){
-            FlGui::instance()->selectedEdges[i]->setSelection(1);
-            ent.push_back(FlGui::instance()->selectedEdges[i]);
-          }
-        }
-        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++){
-          if(FlGui::instance()->selectedFaces[i]->getSelection() != 1){
-            FlGui::instance()->selectedFaces[i]->setSelection(1);
-            ent.push_back(FlGui::instance()->selectedFaces[i]);
-          }
-        }
-        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++){
-          if(FlGui::instance()->selectedRegions[i]->getSelection() != 1){
-            FlGui::instance()->selectedRegions[i]->setSelection(1);
-            ent.push_back(FlGui::instance()->selectedRegions[i]);
-          }
-        }
-      }
-    }
-    if(ib == 'r') {
-      if(CTX::instance()->pickElements){
-        for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++)
-          FlGui::instance()->selectedElements[i]->setVisibility(1);
-      }
-      else{
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++)
-          FlGui::instance()->selectedEdges[i]->setSelection(0);
-        for(unsigned int i = 0; i < FlGui::instance()->selectedFaces.size(); i++)
-          FlGui::instance()->selectedFaces[i]->setSelection(0);
-        for(unsigned int i = 0; i < FlGui::instance()->selectedRegions.size(); i++)
-          FlGui::instance()->selectedRegions[i]->setSelection(0);
-      }
-    }
-    if(ib == 'u') {
-      if(CTX::instance()->pickElements){
-        if(ele.size()){
-          ele[ele.size() - 1]->setVisibility(1);
-          ele.pop_back();
-        }
-      }
-      else{
-        if(ent.size()){
-          ent[ent.size() - 1]->setSelection(0);
-          ent.pop_back();
-        }
-      }
-    }
-    if(ib == 'e') {
-      if(CTX::instance()->pickElements){
-        for(unsigned int i = 0; i < ele.size(); i++)
-          if(ele[i]->getVisibility() == 2) ele[i]->setVisibility(0);
-      }
-      else{
-        for(unsigned int i = 0; i < ent.size(); i++)
-          if(ent[i]->getSelection() == 1) ent[i]->setVisibility(0);
-      }
-      GModel::current()->removeInvisibleElements();
-      ele.clear();
-      ent.clear();
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      break;
-    }
-  }
-
-  CTX::instance()->mesh.changed = ENT_ALL;
-  CTX::instance()->pickElements = 0;
-  drawContext::global()->draw();
-  Msg::StatusBar(3, false, "");
-}
-
-static std::vector<std::string> getInfoStrings(MElement *ele)
-{
-  std::vector<std::string> info;
-  {
-    std::ostringstream sstream;
-    sstream << "Element " << ele->getNum() << ":";
-    info.push_back(sstream.str());
-  }
-  {
-    std::ostringstream sstream;
-    const char *name;
-    MElement::getInfoMSH(ele->getTypeForMSH(), &name);
-    sstream << " " << name
-            << " (MSH type " << ele->getTypeForMSH()
-            << ", dimension "<< ele->getDim()
-            << ", order "<< ele->getPolynomialOrder()
-            << ", partition " << ele->getPartition()
-            << ")";
-    info.push_back(sstream.str());
-  }
-  {
-    std::ostringstream sstream;
-    sstream << " Vertices:";
-    for(int i = 0; i < ele->getNumVertices(); i++)
-      sstream << " " << ele->getVertex(i)->getNum();
-    info.push_back(sstream.str());
-  }
-  {
-    std::ostringstream sstream;
-    SPoint3 pt = ele->barycenter();
-    sstream << " Barycenter: (" << pt[0] << ", " << pt[1] << ", " << pt[2] << ")";
-    info.push_back(sstream.str());
-  }
-  {
-    std::ostringstream sstream;
-    sstream << " Quality: "
-            << "rho = " << ele->rhoShapeMeasure() << " "
-            << "gamma = " << ele->gammaShapeMeasure() << " "
-            << "eta = " << ele->etaShapeMeasure();
-    info.push_back(sstream.str());
-  }
-  {
-    std::ostringstream sstream;
-    double jmin, jmax;
-    ele->scaledJacRange(jmin, jmax);
-    sstream << " Scaled Jacobian range: " << jmin << " " << jmax;
-    info.push_back(sstream.str());
-  }
-  {
-    std::ostringstream sstream;
-    sstream << " Inner / outer radius: "
-            << ele->getInnerRadius() << " / " << ele->getOuterRadius();
-    info.push_back(sstream.str());
-  }
-  return info;
-}
-
-static void mesh_inspect_cb(Fl_Widget *w, void *data)
-{
-  CTX::instance()->pickElements = 1;
-  CTX::instance()->mesh.changed = ENT_ALL;
-  drawContext::global()->draw();
-
-  while(1) {
-    Msg::StatusBar(3, false, "Select element\n[Press 'q' to abort]");
-    char ib = FlGui::instance()->selectEntity(ENT_ALL);
-    if(ib == 'l') {
-      if(FlGui::instance()->selectedElements.size()){
-        MElement *ele = FlGui::instance()->selectedElements[0];
-        GModel::current()->setSelection(0);
-        ele->setVisibility(2);
-        CTX::instance()->mesh.changed = ENT_ALL;
-        drawContext::global()->draw();
-        std::vector<std::string> info = getInfoStrings(ele);
-        for(unsigned int i = 0; i < info.size(); i++)
-          Msg::Direct("%s", info[i].c_str());
-        if(CTX::instance()->tooltips){
-          std::string str;
-          for(unsigned int i = 0; i < info.size(); i++)
-            str += info[i] + "\n";
-          FlGui::instance()->getCurrentOpenglWindow()->drawTooltip(str);
-        }
-        else
-          FlGui::instance()->showMessages();
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      break;
-    }
-  }
-
-  CTX::instance()->pickElements = 0;
-  CTX::instance()->mesh.changed = ENT_ALL;
-  drawContext::global()->draw();
-  Msg::StatusBar(3, false, "");
-}
-
-static void mesh_change_order_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_mesh_degree, 0);
-}
-
-
-static void mesh_degree_cb(Fl_Widget *w, void *data)
-{
-  int degree = (intptr_t)data;
-  if(degree == 2)
-    SetOrderN(GModel::current(), 2, CTX::instance()->mesh.secondOrderLinear,
-              CTX::instance()->mesh.secondOrderIncomplete);
-  else if (degree == 1)
-    SetOrder1(GModel::current());
-  else // For now, use the same options as for second order meshes
-    SetOrderN(GModel::current(), degree,
-	      CTX::instance()->mesh.secondOrderLinear,
-              CTX::instance()->mesh.secondOrderIncomplete);
-  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-  drawContext::global()->draw();
-}
-
-static void mesh_optimize_cb(Fl_Widget *w, void *data)
-{
-  if(CTX::instance()->lock) {
-    Msg::Info("I'm busy! Ask me that later...");
-    return;
-  }
-  CTX::instance()->lock = 1;
-  OptimizeMesh(GModel::current());
-  CTX::instance()->lock = 0;
-  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-  drawContext::global()->draw();
-}
-
-static void mesh_refine_cb(Fl_Widget *w, void *data)
-{
-  RefineMesh(GModel::current(), CTX::instance()->mesh.secondOrderLinear);
-  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-  drawContext::global()->draw();
-}
-
-static void mesh_optimize_netgen_cb(Fl_Widget *w, void *data)
-{
-  if(CTX::instance()->lock) {
-    Msg::Info("I'm busy! Ask me that later...");
-    return;
-  }
-  CTX::instance()->lock = 1;
-  OptimizeMeshNetgen(GModel::current());
-  CTX::instance()->lock = 0;
-  CTX::instance()->mesh.changed |= (ENT_LINE | ENT_SURFACE | ENT_VOLUME);
-  drawContext::global()->draw();
-}
-
-static void mesh_partition_cb(Fl_Widget *w, void *data)
-{
-  partition_dialog();
-}
-
-static void mesh_define_length_cb(Fl_Widget *w, void *data)
-{
-  action_point_line_surface_volume(8, 0, "Point");
-}
-
-static void mesh_define_recombine_cb(Fl_Widget *w, void *data)
-{
-  action_point_line_surface_volume(9, 0, "Surface");
-}
-
-static void mesh_define_transfinite_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_mesh_define_transfinite, 0);
-}
-
-static void add_transfinite_embedded(int dim, bool embed)
-{
-  opt_geometry_points(0, GMSH_SET | GMSH_GUI, 1);
-  switch (dim) {
-  case 1: opt_geometry_lines(0, GMSH_SET | GMSH_GUI, 1); break;
-  case 2: opt_geometry_surfaces(0, GMSH_SET | GMSH_GUI, 1); break;
-  case 3: opt_geometry_volumes(0, GMSH_SET | GMSH_GUI, 1); break;
-  }
-  drawContext::global()->draw();
-
-  std::vector<int> p;
-  char ib;
-  while(1) {
-    switch (dim) {
-    case 1:
-      if(p.empty())
-        Msg::StatusBar(3, false, "Select lines\n"
-                       "[Press 'e' to end selection or 'q' to abort]");
-      else
-        Msg::StatusBar(3, false, "Select lines\n"
-                       "[Press 'e' to end selection, 'u' to undo last selection "
-                       "or 'q' to abort]");
-      ib = FlGui::instance()->selectEntity(ENT_LINE);
-      break;
-    case 2:
-      Msg::StatusBar(3, false, "Select surface\n[Press 'q' to abort]");
-      ib = FlGui::instance()->selectEntity(ENT_SURFACE);
-      break;
-    case 3:
-      Msg::StatusBar(3, false, "Select volume\n[Press 'q' to abort]");
-      ib = FlGui::instance()->selectEntity(ENT_VOLUME);
-      break;
-    default:
-      ib = 'l';
-      break;
-    }
-
-    if(ib == 'e') {
-      if(dim == 1) {
-        if(p.size())
-          add_trsfline(p, GModel::current()->getFileName(),
-                       FlGui::instance()->meshContext->choice[0]->text(),
-                       FlGui::instance()->meshContext->input[2]->value(),
-                       FlGui::instance()->meshContext->input[1]->value());
-      }
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      p.clear();
-    }
-    if(ib == 'u') {
-      if(dim == 1) {
-        if(p.size()){
-          GEdge *ge = GModel::current()->getEdgeByTag(p.back());
-          if(ge) ge->setSelection(0);
-          drawContext::global()->draw();
-          p.pop_back();
-        }
-      }
-    }
-    if(ib == 'q') {
-      GModel::current()->setSelection(0);
-      drawContext::global()->draw();
-      break;
-    }
-    if(ib == 'r') {
-      Msg::Warning("Entity de-selection not supported yet during "
-                   "transfinite definition");
-    }
-    if(ib == 'l') {
-      switch (dim) {
-      case 1:
-        for(unsigned int i = 0; i < FlGui::instance()->selectedEdges.size(); i++){
-          FlGui::instance()->selectedEdges[i]->setSelection(1);
-          p.push_back(FlGui::instance()->selectedEdges[i]->tag());
-        }
-        drawContext::global()->draw();
-        break;
-      case 2:
-      case 3:
-        if(dim == 2){
-          FlGui::instance()->selectedFaces[0]->setSelection(1);
-          drawContext::global()->draw();
-          p.push_back(FlGui::instance()->selectedFaces[0]->tag());
-        }
-        else{
-          FlGui::instance()->selectedRegions[0]->setSelection(1);
-          drawContext::global()->draw();
-          p.push_back(FlGui::instance()->selectedRegions[0]->tag());
-        }
-        while(1) {
-          if(p.size() == 1)
-            Msg::StatusBar(3, false, "Select %s points\n"
-                           "[Press 'e' to end selection or 'q' to abort]",
-                           embed ? "embedded" : "(ordered) boundary");
-          else
-            Msg::StatusBar(3, false, "Select %s points\n"
-                           "[Press 'e' to end selection, 'u' to undo last selection "
-                           "or 'q' to abort]",
-                           embed ? "embedded" : "(ordered) boundary");
-          ib = FlGui::instance()->selectEntity(ENT_POINT);
-          if(ib == 'l') {
-            for(unsigned int i = 0; i < FlGui::instance()->selectedVertices.size(); i++){
-              FlGui::instance()->selectedVertices[i]->setSelection(1);
-              p.push_back(FlGui::instance()->selectedVertices[i]->tag());
-              if(!embed) break;
-            }
-            drawContext::global()->draw();
-          }
-          if(ib == 'u') {
-            if(p.size() > 1){
-              GVertex *gv = GModel::current()->getVertexByTag(p.back());
-              if(gv) gv->setSelection(0);
-              drawContext::global()->draw();
-              p.pop_back();
-            }
-          }
-          if(ib == 'r') {
-            Msg::Warning("Entity de-selection not supported yet during "
-                         "transfinite definition");
-          }
-          if(ib == 'e') {
-            switch (dim) {
-            case 2:
-              if(embed && p.size())
-                add_embedded("Point", p, GModel::current()->getFileName());
-              else if(!embed &&
-                      (p.size() == 0 + 1 || p.size() == 3 + 1 || p.size() == 4 + 1))
-                add_trsfsurf(p, GModel::current()->getFileName(),
-                             FlGui::instance()->meshContext->choice[1]->text());
-              else
-                Msg::Error("Wrong number of points for mesh constraint");
-              break;
-            case 3:
-              if(p.size() == 6 + 1 || p.size() == 8 + 1)
-                add_trsfvol(p, GModel::current()->getFileName());
-              else
-                Msg::Error("Wrong number of points for transfinite volume");
-              break;
-            }
-            GModel::current()->setSelection(0);
-            drawContext::global()->draw();
-            p.clear();
-            break;
-          }
-          if(ib == 'q') {
-            GModel::current()->setSelection(0);
-            drawContext::global()->draw();
-            goto stopall;
-          }
-        }
-        break;
-      }
-    }
-  }
-
- stopall:
-  Msg::StatusBar(3, false, "");
-}
-
-static void mesh_define_transfinite_line_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->meshContext->show(1);
-  add_transfinite_embedded(1, false);
-}
-
-static void mesh_define_transfinite_surface_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->meshContext->show(2);
-  add_transfinite_embedded(2, false);
-}
-
-static void mesh_define_transfinite_volume_cb(Fl_Widget *w, void *data)
-{
-  add_transfinite_embedded(3, false);
-}
-
-static void mesh_define_embedded_cb(Fl_Widget *w, void *data)
-{
-  add_transfinite_embedded(2, true);
-}
-
-static void mesh_define_compound_cb(Fl_Widget *w, void *data)
-{
-  FlGui::instance()->menu->setContext(menu_mesh_define_compound, 0);
-}
-
-static void mesh_define_compound_entity_cb(Fl_Widget *w, void *data)
-{
-  action_point_line_surface_volume(10, 0, (const char *)data);
-}
-
-static void view_toggle_cb(Fl_Widget *w, void *data)
-{
-  int num = (intptr_t)data;
-  opt_view_visible(num, GMSH_SET,
-                   FlGui::instance()->menu->toggle[num]->value());
-  drawContext::global()->draw();
-}
-
-static void view_reload(int index)
-{
-  if(index >= 0 && index < (int)PView::list.size()){
-    PView *p = PView::list[index];
-
-    if(StatFile(p->getData()->getFileName())){
-      Msg::Error("File '%s' does not exist", p->getData()->getFileName().c_str());
-      return;
-    }
-
-    int n = PView::list.size();
-
-    // FIXME: use fileIndex
-    MergeFile(p->getData()->getFileName());
-
-    if((int)PView::list.size() > n){ // we loaded a new view
-      // delete old data and replace with new
-      delete p->getData();
-      p->setData(PView::list.back()->getData());
-      PView::list.back()->setData(0);
-      // delete new view
-      delete PView::list.back();
-      // in case the reloaded view has a different number of time steps
-      if(p->getOptions()->timeStep > p->getData()->getNumTimeSteps() - 1)
-        p->getOptions()->timeStep = 0;
-      p->setChanged(true);
-      FlGui::instance()->updateViews();
-    }
-  }
-}
-
-static void view_reload_cb(Fl_Widget *w, void *data)
-{
-  view_reload((intptr_t)data);
-  drawContext::global()->draw();
-}
-
-static void view_reload_all_cb(Fl_Widget *w, void *data)
-{
-  for(unsigned int i = 0; i < PView::list.size(); i++)
-    view_reload(i);
-  drawContext::global()->draw();
-}
-
-static void view_reload_visible_cb(Fl_Widget *w, void *data)
-{
-  for(unsigned int i = 0; i < PView::list.size(); i++)
-    if(opt_view_visible(i, GMSH_GET, 0))
-      view_reload(i);
-  drawContext::global()->draw();
-}
-
-static void view_remove_other_cb(Fl_Widget *w, void *data)
-{
-  if(PView::list.empty()) return;
-  for(int i = PView::list.size() - 1; i >= 0; i--)
-    if(i != (intptr_t)data) delete PView::list[i];
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_remove_all_cb(Fl_Widget *w, void *data)
-{
-  if(PView::list.empty()) return;
-  int mode = (intptr_t)data;
-  if(mode == -1){ // remove all
-    if(PView::list.empty()) return;
-    while(PView::list.size()) delete PView::list[0];
-  }
-  else if(mode == -2){ // remove all visible
-    for(int i = PView::list.size() - 1; i >= 0; i--)
-      if(opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i];
-  }
-  else if(mode == -3){ // remove all invisible
-    for(int i = PView::list.size() - 1; i >= 0; i--)
-      if(!opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i];
-  }
-  else if(mode == -4){ // remove all empty
-    for(int i = PView::list.size() - 1; i >= 0; i--)
-      if(PView::list[i]->getData()->empty()) delete PView::list[i];
-  }
-  else if(mode >=0 && mode < (int)PView::list.size()){ // remove by name
-    std::string name = PView::list[mode]->getData()->getName();
-    for(int i = PView::list.size() - 1; i >= 0; i--)
-      if(PView::list[i]->getData()->getName() == name) delete PView::list[i];
-  }
-
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_remove_cb(Fl_Widget *w, void *data)
-{
-  delete PView::list[(intptr_t)data];
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_save_cb(Fl_Widget *w, void *data)
-{
-  static const char *formats =
-    "Gmsh Parsed" TT "*.pos" NN
-    "Gmsh Mesh-based" TT "*.pos" NN
-    "Gmsh Legacy ASCII" TT "*.pos" NN
-    "Gmsh Legacy Binary" TT "*.pos" NN
-    "MED" TT "*.rmed" NN
-    "STL Surface" TT "*.stl" NN
-    "Generic TXT" TT "*.txt" NN;
-
-  PView *view = PView::list[(intptr_t)data];
- test:
-  if(fileChooser(FILE_CHOOSER_CREATE, "Save As", formats,
-                 view->getData()->getFileName().c_str())){
-    std::string name = fileChooserGetName(1);
-    if(CTX::instance()->confirmOverwrite) {
-      if(!StatFile(name))
-        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
-                      "Cancel", "Replace", 0, name.c_str()))
-          goto test;
-    }
-    int format = 0;
-    switch(fileChooserGetFilter()){
-    case 0: format = 2; break;
-    case 1: format = 5; break;
-    case 2: format = 0; break;
-    case 3: format = 1; break;
-    case 4: format = 6; break;
-    case 5: format = 3; break;
-    case 6: format = 4; break;
-    }
-    view->write(name, format);
-  }
-}
-
-#undef TT
-#undef NN
-
-static void view_alias_cb(Fl_Widget *w, void *data)
-{
-  new PView(PView::list[(intptr_t)data], false);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_alias_with_options_cb(Fl_Widget *w, void *data)
-{
-  new PView(PView::list[(intptr_t)data], true);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_combine_space_all_cb(Fl_Widget *w, void *data)
-{
-  PView::combine(false, 1, CTX::instance()->post.combineRemoveOrig);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_combine_space_visible_cb(Fl_Widget *w, void *data)
-{
-  PView::combine(false, 0, CTX::instance()->post.combineRemoveOrig);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_combine_space_by_name_cb(Fl_Widget *w, void *data)
-{
-  PView::combine(false, 2, CTX::instance()->post.combineRemoveOrig);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_combine_time_all_cb(Fl_Widget *w, void *data)
-{
-  PView::combine(true, 1, CTX::instance()->post.combineRemoveOrig);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_combine_time_visible_cb(Fl_Widget *w, void *data)
-{
-  PView::combine(true, 0, CTX::instance()->post.combineRemoveOrig);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_combine_time_by_name_cb(Fl_Widget *w, void *data)
-{
-  PView::combine(true, 2, CTX::instance()->post.combineRemoveOrig);
-  FlGui::instance()->updateViews();
-  drawContext::global()->draw();
-}
-
-static void view_all_visible_cb(Fl_Widget *w, void *data)
-{
-  int mode = (intptr_t)data;
-  std::string name;
-  if(mode >= 0) name = PView::list[mode]->getData()->getName();
-  for(unsigned int i = 0; i < PView::list.size(); i++)
-    opt_view_visible(i, GMSH_SET | GMSH_GUI,
-                     (mode == -1) ? 1 :
-                     (mode == -2) ? 0 :
-                     (mode == -3) ? !opt_view_visible(i, GMSH_GET, 0) :
-                     (name == PView::list[i]->getData()->getName()) ? 1 :
-                     0);
-  drawContext::global()->draw();
-}
-
-static void view_applybgmesh_cb(Fl_Widget *w, void *data)
-{
-  int index =  (intptr_t)data;
-  if(index >= 0 && index < (int)PView::list.size())
-    GModel::current()->getFields()->setBackgroundMesh(index);
-}
-
-// The static menus (we cannot use the 'g', 'm' 's' and 'p' mnemonics
-// since they are already defined as global shortcuts)
-static Fl_Menu_Item bar_table[] = {
-  {"&File", 0, 0, 0, FL_SUBMENU},
-    {"&New...",     FL_CTRL+'n', (Fl_Callback *)file_new_cb, 0},
-    {"&Open...",    FL_CTRL+'o', (Fl_Callback *)file_open_cb, 0},
-    {"Open Recent", 0, 0, 0, FL_SUBMENU},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {0},
-    {"M&erge...",   FL_CTRL+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0},
-    {"Watch Pattern...",    0, (Fl_Callback *)file_watch_cb, 0},
-    {"&Clear",      0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER},
-#if defined(HAVE_ONELAB)
-    {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
-      {"Start...",  0, (Fl_Callback *)file_remote_cb, (void*)"start"},
-      {"Merge...",  0, (Fl_Callback *)file_remote_cb, (void*)"merge"},
-      {"Clear",     0, (Fl_Callback *)file_remote_cb, (void*)"clear"},
-      {"Stop",      0, (Fl_Callback *)file_remote_cb, (void*)"stop"},
-      {0},
-#endif
-    {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new"},
-    {"Split Window", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
-      {"Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"},
-      {"Vertically",   0, (Fl_Callback *)file_window_cb, (void*)"split_v"},
-      {"Clear",        0, (Fl_Callback *)file_window_cb, (void*)"split_u"},
-      {0},
-    {"&Rename...",  FL_CTRL+'r', (Fl_Callback *)file_rename_cb, 0},
-    {"Save &As...", FL_CTRL+'s', (Fl_Callback *)file_save_as_cb, 0},
-    {"Sa&ve Mesh",  FL_CTRL+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0},
-    {"Save Options", 0, 0, 0, FL_SUBMENU | FL_MENU_DIVIDER},
-      {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"},
-      {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"},
-      {0},
-    {"&Quit",       FL_CTRL+'q', (Fl_Callback *)file_quit_cb, 0},
-    {0},
-  {"&Tools", 0, 0, 0, FL_SUBMENU},
-    {"&Options",         FL_CTRL+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0},
-    {"Pl&ugins",         FL_CTRL+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)},
-    {"&Visibility",      FL_CTRL+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
-    {"&Clipping",        FL_CTRL+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
-    {"&Manipulator",     FL_CTRL+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0},
-#if defined(HAVE_ONELAB)
-    {"&OneLab",          0, (Fl_Callback *)solver_cb, (void*)(-1), FL_MENU_DIVIDER},
-#endif
-#if defined(HAVE_3M)
-    {"&3M",              0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER},
-#endif
-    {"S&tatistics",      FL_CTRL+'i', (Fl_Callback *)statistics_cb, 0},
-    {"M&essage Console", FL_CTRL+'l', (Fl_Callback *)message_cb, 0},
-    {0},
-  {"&Help", 0, 0, 0, FL_SUBMENU},
-    {"On&line Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER},
-    {"M&ouse Actions",        0, (Fl_Callback *)help_mouse_cb, 0},
-    {"&Keyboard Shortcuts",   0, (Fl_Callback *)help_short_cb, 0},
-    {"C&ommand Line Options", 0, (Fl_Callback *)help_command_line_cb, 0},
-    {"&Current Options",      0, (Fl_Callback *)status_options_cb, (void*)"?", FL_MENU_DIVIDER},
-    {"&About Gmsh",           0, (Fl_Callback *)help_about_cb, 0},
-    {0},
-  {0}
-};
-
-#if defined(__APPLE__)
-
-// Alternative items for the MacOS system menu bar (removed '&'
-// shortcuts: they would cause spurious menu items to appear on the
-// menu window; removed File->Quit)
-static Fl_Menu_Item sysbar_table[] = {
-  {"File", 0, 0, 0, FL_SUBMENU},
-    {"New...",     FL_META+'n', (Fl_Callback *)file_new_cb, 0},
-    {"Open...",    FL_META+'o', (Fl_Callback *)file_open_cb, 0},
-  // system menu bar is not dynamic in fltk 1.1; it is in fltk 1.3
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-    {"Open Recent", 0, 0, 0, FL_SUBMENU},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {"", 0, (Fl_Callback *)file_open_recent_cb, 0},
-      {0},
-#endif
-    {"Merge...",   FL_META+FL_SHIFT+'o', (Fl_Callback *)file_merge_cb, 0},
-    {"Watch Pattern...",   0, (Fl_Callback *)file_watch_cb, 0},
-    {"Clear",      0, (Fl_Callback *)file_clear_cb, 0, FL_MENU_DIVIDER},
-    {"Remote", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
-      {"Start...",  0, (Fl_Callback *)file_remote_cb, (void*)"start"},
-      {"Merge...",  0, (Fl_Callback *)file_remote_cb, (void*)"merge"},
-      {"Clear",     0, (Fl_Callback *)file_remote_cb, (void*)"clear"},
-      {"Stop",      0, (Fl_Callback *)file_remote_cb, (void*)"stop"},
-      {0},
-    {"New Window", 0, (Fl_Callback *)file_window_cb, (void*)"new"},
-    {"Split Window", 0, 0, 0, FL_MENU_DIVIDER | FL_SUBMENU},
-      {"Horizontally", 0, (Fl_Callback *)file_window_cb, (void*)"split_h"},
-      {"Vertically",   0, (Fl_Callback *)file_window_cb, (void*)"split_v"},
-      {"Clear",        0, (Fl_Callback *)file_window_cb, (void*)"split_u"},
-      {0},
-    {"Rename...",  FL_META+'r', (Fl_Callback *)file_rename_cb, 0},
-    {"Save As...", FL_META+'s', (Fl_Callback *)file_save_as_cb, 0},
-    {"Save Mesh",  FL_META+FL_SHIFT+'s', (Fl_Callback *)mesh_save_cb, 0},
-    {"Save Options", 0, 0, 0, FL_SUBMENU},
-      {"For Current File", 0, (Fl_Callback *)file_options_save_cb, (void*)"file"},
-      {"As Default", 0, (Fl_Callback *)file_options_save_cb, (void*)"default"},
-      {0},
-    {0},
-  {"Tools", 0, 0, 0, FL_SUBMENU},
-    {"Options",         FL_META+FL_SHIFT+'n', (Fl_Callback *)options_cb, 0},
-    {"Plugins",         FL_META+FL_SHIFT+'u', (Fl_Callback *)plugin_cb, (void*)(-1)},
-    {"Visibility",      FL_META+FL_SHIFT+'v', (Fl_Callback *)visibility_cb, 0},
-    {"Clipping",        FL_META+FL_SHIFT+'c', (Fl_Callback *)clip_cb, 0},
-    {"Manipulator",     FL_META+FL_SHIFT+'m', (Fl_Callback *)manip_cb, 0},
-#if defined(HAVE_ONELAB)
-    {"OneLab",          0, (Fl_Callback *)solver_cb, (void*)(-1), FL_MENU_DIVIDER},
-#endif
-#if defined(HAVE_3M)
-    {"3M",              0, (Fl_Callback *)window3M_cb, 0, FL_MENU_DIVIDER},
-#endif
-    {"Statistics",      FL_META+'i', (Fl_Callback *)statistics_cb, 0},
-    {"Message Console", FL_META+'l', (Fl_Callback *)message_cb, 0},
-    {0},
-  {"Window", 0, 0, 0, FL_SUBMENU},
-    {"Minimize",           FL_META+'m', (Fl_Callback *)window_cb, (void*)"minimize"},
-    {"Zoom",               0, (Fl_Callback *)window_cb, (void*)"zoom", FL_MENU_DIVIDER},
-    {"Bring All to Front", 0, (Fl_Callback *)window_cb, (void*)"front"},
-    {0},
-  {"Help", 0, 0, 0, FL_SUBMENU},
-    {"Online Documentation", 0, (Fl_Callback *)help_online_cb, 0, FL_MENU_DIVIDER},
-    {"Mouse Actions",        0, (Fl_Callback *)help_mouse_cb, 0},
-    {"Keyboard Shortcuts",   0, (Fl_Callback *)help_short_cb, 0},
-    {"Command Line Options", 0, (Fl_Callback *)help_command_line_cb, 0},
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-    {"Current Options",      0, (Fl_Callback *)status_options_cb, (void*)"?"},
-#else
-    {"Current Options",      0, (Fl_Callback *)status_options_cb, (void*)"?", FL_MENU_DIVIDER},
-    {"About Gmsh",           0, (Fl_Callback *)help_about_cb, 0},
-#endif
-    {0},
-  {0}
-};
-
-#endif
-
-static Fl_Menu_Item module_table[] = {
-  {"Geometry",        'g', (Fl_Callback *)mod_geometry_cb, 0},
-  {"Mesh",            'm', (Fl_Callback *)mod_mesh_cb, 0},
-  {"Solver",          's', (Fl_Callback *)mod_solver_cb, 0},
-  {"Post-processing", 'p', (Fl_Callback *)mod_post_cb, 0},
-  {0}
-};
-
-// Dynamic menus contexts
-contextItem menu_geometry[] = {
-  {"0Geometry"} ,
-  {"Elementary entities", (Fl_Callback *)geometry_elementary_cb} ,
-  {"Physical groups",     (Fl_Callback *)geometry_physical_cb} ,
-  {"Edit",                (Fl_Callback *)geometry_edit_cb} ,
-  {"Reload",              (Fl_Callback *)geometry_reload_cb} ,
-  {""}
-};
-  contextItem menu_geometry_elementary[] = {
-    {"0Geometry>Elementary"} ,
-    {"Add",       (Fl_Callback *)geometry_elementary_add_cb} ,
-    {"Delete",    (Fl_Callback *)geometry_elementary_delete_cb, (void*)0} ,
-    {"Translate", (Fl_Callback *)geometry_elementary_translate_cb, (void*)0} ,
-    {"Rotate",    (Fl_Callback *)geometry_elementary_rotate_cb, (void*)0} ,
-    {"Split",     (Fl_Callback *)geometry_elementary_split_cb, (void*)0} ,
-    {"Scale",     (Fl_Callback *)geometry_elementary_scale_cb, (void*)0} ,
-    {"Symmetry",  (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)0} ,
-    {"Extrude",   (Fl_Callback *)geometry_elementary_extrude_cb, (void*)0} ,
-    {"Coherence", (Fl_Callback *)geometry_elementary_coherence_cb} ,
-    {""}
-  };
-    contextItem menu_geometry_elementary_add[] = {
-      {"0Geometry>Elementary>Add"} ,
-      {"New",       (Fl_Callback *)geometry_elementary_add_new_cb, (void*)0} ,
-      {"Translate", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)0} ,
-      {"Rotate",    (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)0} ,
-      {"Scale",     (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)0} ,
-      {"Symmetry",  (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)0} ,
-      {""}
-    };
-      contextItem menu_geometry_elementary_add_new[] = {
-        {"0Geometry>Elementary>Add>New"} ,
-        {"Parameter",     (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Parameter"} ,
-        {"Point",         (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Point"} ,
-        {"Straight line", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Line"} ,
-        {"Spline",        (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Spline"} ,
-        {"B-Spline",      (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"BSpline"} ,
-        {"Circle arc",    (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Circle"} ,
-        {"Ellipse arc",   (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ellipse"} ,
-        {"Plane surface", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Plane Surface"} ,
-        {"Ruled surface", (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Ruled Surface"} ,
-        {"Volume",        (Fl_Callback *)geometry_elementary_add_new_cb, (void*)"Volume"} ,
-        {""}
-      };
-      contextItem menu_geometry_elementary_add_translate[] = {
-        {"0Geometry>Elementary>Add>Translate"} ,
-        {"Point",   (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Point"} ,
-        {"Line",    (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Line"} ,
-        {"Surface", (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Surface"} ,
-        {"Volume",  (Fl_Callback *)geometry_elementary_add_translate_cb, (void*)"Volume"} ,
-        {""}
-      };
-      contextItem menu_geometry_elementary_add_rotate[] = {
-        {"0Geometry>Elementary>Add>Rotate"} ,
-        {"Point",   (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Point"} ,
-        {"Line",    (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Line"} ,
-        {"Surface", (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Surface"} ,
-        {"Volume",  (Fl_Callback *)geometry_elementary_add_rotate_cb, (void*)"Volume"} ,
-        {""}
-      };
-      contextItem menu_geometry_elementary_add_scale[] = {
-        {"0Geometry>Elementary>Add>Scale"} ,
-        {"Point",   (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Point"} ,
-        {"Line",    (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Line"} ,
-        {"Surface", (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Surface"} ,
-        {"Volume",  (Fl_Callback *)geometry_elementary_add_scale_cb, (void*)"Volume"} ,
-        {""}
-      };
-      contextItem menu_geometry_elementary_add_symmetry[] = {
-        {"0Geometry>Elementary>Add>Symmetry"} ,
-        {"Point",   (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Point"} ,
-        {"Line",    (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Line"} ,
-        {"Surface", (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Surface"} ,
-        {"Volume",  (Fl_Callback *)geometry_elementary_add_symmetry_cb, (void*)"Volume"} ,
-        {""}
-      };
-    contextItem menu_geometry_elementary_delete[] = {
-      {"0Geometry>Elementary>Delete"} ,
-      {"Point",   (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Point"} ,
-      {"Line",    (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Line"} ,
-      {"Surface", (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Surface"} ,
-      {"Volume",  (Fl_Callback *)geometry_elementary_delete_cb, (void*)"Volume"} ,
-      {""}
-    };
-    contextItem menu_geometry_elementary_split[] = {
-      {"0Geometry>Elementary>Split"},
-        {"Line",(Fl_Callback *)geometry_elementary_split_cb,(void*)"Line"},
-        {""}
-    };
-    contextItem menu_geometry_elementary_translate[] = {
-      {"0Geometry>Elementary>Translate"} ,
-      {"Point",   (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Point"} ,
-      {"Line",    (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Line"} ,
-      {"Surface", (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Surface"} ,
-      {"Volume",  (Fl_Callback *)geometry_elementary_translate_cb, (void*)"Volume"} ,
-      {""}
-    };
-    contextItem menu_geometry_elementary_rotate[] = {
-      {"0Geometry>Elementary>Rotate"} ,
-      {"Point",   (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Point"} ,
-      {"Line",    (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Line"} ,
-      {"Surface", (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Surface"} ,
-      {"Volume",  (Fl_Callback *)geometry_elementary_rotate_cb, (void*)"Volume"} ,
-      {""}
-    };
-    contextItem menu_geometry_elementary_scale[] = {
-      {"0Geometry>Elementary>Scale"} ,
-      {"Point",   (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Point"} ,
-      {"Line",    (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Line"} ,
-      {"Surface", (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Surface"} ,
-      {"Volume",  (Fl_Callback *)geometry_elementary_scale_cb, (void*)"Volume"} ,
-      {""}
-    };
-    contextItem menu_geometry_elementary_symmetry[] = {
-      {"0Geometry>Elementary>Symmetry"} ,
-      {"Point",   (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Point"} ,
-      {"Line",    (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Line"} ,
-      {"Surface", (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Surface"} ,
-      {"Volume",  (Fl_Callback *)geometry_elementary_symmetry_cb, (void*)"Volume"} ,
-      {""}
-    };
-    contextItem menu_geometry_elementary_extrude[] = {
-      {"0Geometry>Elementary>Extrude"} ,
-      {"Translate", (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)0} ,
-      {"Rotate",    (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)0} ,
-      {""}
-    };
-      contextItem menu_geometry_elementary_extrude_translate[] = {
-        {"0Geometry>Elementary>Extrude>Translate"} ,
-        {"Point",   (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Point"} ,
-        {"Line",    (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Line"} ,
-        {"Surface", (Fl_Callback *)geometry_elementary_extrude_translate_cb, (void*)"Surface"} ,
-        {""}
-      };
-      contextItem menu_geometry_elementary_extrude_rotate[] = {
-        {"0Geometry>Elementary>Extrude>Rotate"} ,
-        {"Point",   (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Point"} ,
-        {"Line",    (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Line"} ,
-        {"Surface", (Fl_Callback *)geometry_elementary_extrude_rotate_cb, (void*)"Surface"} ,
-        {""}
-      };
-  contextItem menu_geometry_physical[] = {
-    {"0Geometry>Physical"} ,
-    {"Add",    (Fl_Callback *)geometry_physical_add_cb, (void*)0} ,
-    {""}
-  };
-    contextItem menu_geometry_physical_add[] = {
-      {"0Geometry>Physical>Add"} ,
-      {"Point",   (Fl_Callback *)geometry_physical_add_cb, (void*)"Point" } ,
-      {"Line",    (Fl_Callback *)geometry_physical_add_cb, (void*)"Line" } ,
-      {"Surface", (Fl_Callback *)geometry_physical_add_cb, (void*)"Surface" } ,
-      {"Volume",  (Fl_Callback *)geometry_physical_add_cb, (void*)"Volume" } ,
-      {""}
-    };
-
-contextItem menu_mesh[] = {
-  {"1Mesh"} ,
-  {"Define",       (Fl_Callback *)mesh_define_cb} ,
-  {"1D",           (Fl_Callback *)mesh_1d_cb} ,
-  {"2D",           (Fl_Callback *)mesh_2d_cb} ,
-  {"3D",           (Fl_Callback *)mesh_3d_cb} ,
-  {"Optimize 3D",  (Fl_Callback *)mesh_optimize_cb} ,
-#if defined(HAVE_NETGEN)
-  {"Optimize 3D (Netgen)", (Fl_Callback *)mesh_optimize_netgen_cb} ,
-#endif
-  {"Set order",    (Fl_Callback *)mesh_change_order_cb} ,
-  {"Inspect",      (Fl_Callback *)mesh_inspect_cb} ,
-  {"Refine by splitting", (Fl_Callback *)mesh_refine_cb} ,
-#if defined(HAVE_METIS) || defined(HAVE_CHACO)
-  {"Partition",    (Fl_Callback *)mesh_partition_cb} ,
-#endif
-  {"Reclassify 2D", (Fl_Callback *)mesh_classify_cb} ,
-#if defined(HAVE_FOURIER_MODEL)
-  {"Reparameterize 2D", (Fl_Callback *)mesh_parameterize_cb} ,
-#endif
-  {"Delete",       (Fl_Callback *)mesh_delete_cb} ,
-  {"Save",         (Fl_Callback *)mesh_save_cb} ,
-  {""}
-};
-  contextItem menu_mesh_define[] = {
-    {"1Mesh>Define"} ,
-    {"Size fields",  (Fl_Callback *)field_cb},
-    {"Element size at points", (Fl_Callback *)mesh_define_length_cb  } ,
-    {"Embedded points", (Fl_Callback *)mesh_define_embedded_cb, (void*)"point" } ,
-    {"Recombine",   (Fl_Callback *)mesh_define_recombine_cb  } ,
-    {"Transfinite", (Fl_Callback *)mesh_define_transfinite_cb  } ,
-    {"Compound",    (Fl_Callback *)mesh_define_compound_cb  } ,
-    {""}
-  };
-    contextItem menu_mesh_define_transfinite[] = {
-      {"1Mesh>Define>Transfinite"} ,
-      {"Line",    (Fl_Callback *)mesh_define_transfinite_line_cb} ,
-      {"Surface", (Fl_Callback *)mesh_define_transfinite_surface_cb} ,
-      {"Volume",  (Fl_Callback *)mesh_define_transfinite_volume_cb} ,
-      {""}
-    };
-    contextItem menu_mesh_define_compound[] = {
-      {"1Mesh>Define>Compound"} ,
-      {"Line",    (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Line"} ,
-      {"Surface", (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Surface"} ,
-      {"Volume",  (Fl_Callback *)mesh_define_compound_entity_cb, (void*)"Volume"} ,
-      {""}
-    };
-  contextItem menu_mesh_delete[] = {
-    {"1Mesh>Edit>Delete"} ,
-    {"Elements", (Fl_Callback *)mesh_delete_parts_cb, (void*)"elements"} ,
-    {"Lines",    (Fl_Callback *)mesh_delete_parts_cb, (void*)"lines"} ,
-    {"Surfaces", (Fl_Callback *)mesh_delete_parts_cb, (void*)"surfaces"} ,
-    {"Volumes",  (Fl_Callback *)mesh_delete_parts_cb, (void*)"volumes"} ,
-    {""}
-  };
-  contextItem menu_mesh_degree[] = {
-    {"1Mesh>Set order"} ,
-    {"1",  (Fl_Callback *)mesh_degree_cb, (void*)1},
-    {"2",  (Fl_Callback *)mesh_degree_cb, (void*)2},
-    {"3",  (Fl_Callback *)mesh_degree_cb, (void*)3},
-    {"4",  (Fl_Callback *)mesh_degree_cb, (void*)4},
-    {"5",  (Fl_Callback *)mesh_degree_cb, (void*)5},
-    {"Optimize",  (Fl_Callback *)highordertools_cb},
-    {""}
-  };
-
-contextItem menu_solver[] = {
-  {"2Solver"} ,
-  {"Solver 0", (Fl_Callback *)solver_cb , (void*)0} ,
-  {"Solver 1", (Fl_Callback *)solver_cb , (void*)1} ,
-  {"Solver 2", (Fl_Callback *)solver_cb , (void*)2} ,
-  {"Solver 3", (Fl_Callback *)solver_cb , (void*)3} ,
-  {"Solver 4", (Fl_Callback *)solver_cb , (void*)4} ,
-  {""}
-};
-
-contextItem menu_post[] = {
-  {"3Post-processing"} ,
-  {""}
-};
-
-menuWindow::menuWindow()
-{
-  int width = 14 * FL_NORMAL_SIZE;
-
-  // this is the initial height: no dynamic button is shown
-#if defined(__APPLE__)
-  if(CTX::instance()->systemMenuBar){
-    _MH = BH + 6; // the menu bar is not in the application
-  }
-  else{
-#endif
-    _MH = BH + BH + 6;
-#if defined(__APPLE__)
-  }
-#endif
-
-  win = new mainWindow
-    (width, _MH + NB_BUTT_SCROLL * BH, CTX::instance()->nonModalWindows ?
-     true : false, "Gmsh");
-  win->box(GMSH_WINDOW_BOX);
-  win->callback(file_quit_cb);
-
-  int y;
-#if defined(__APPLE__)
-  if(CTX::instance()->systemMenuBar){
-    // the system menubar is kind of a hack in fltk < 1.1.7: it still
-    // creates a real (invisible) menubar. To avoid spurious mouse
-    // click events we make it a 1x1 pixel rectangle, 1 pixel off the
-    // edge (so it falls behind the navigation buttons)
-    sysbar = new Fl_Sys_Menu_Bar(1, 1, 1, 1);
-    sysbar->menu(sysbar_table);
-    sysbar->global();
-    fillRecentHistoryMenu();
-    Fl_Box *o = new Fl_Box(0, 0, width, BH + 6);
-    o->box(FL_UP_BOX);
-    y = 3;
-  }
-  else{
-#endif
-    bar = new Fl_Menu_Bar(0, 0, width, BH);
-    bar->menu(bar_table);
-    bar->box(FL_UP_BOX);
-    bar->global();
-    fillRecentHistoryMenu();
-    Fl_Box *o = new Fl_Box(0, BH, width, BH + 6);
-    o->box(FL_UP_BOX);
-    y = BH + 3;
-#if defined(__APPLE__)
-  }
-#endif
-
-  navig[0] = new Fl_Button(1, y, 18, BH / 2, "@#-1<");
-  navig[0]->labeltype(FL_SYMBOL_LABEL);
-  navig[0]->box(FL_FLAT_BOX);
-  navig[0]->selection_color(FL_WHITE);
-  navig[0]->callback(mod_back_cb);
-  navig[0]->tooltip("Go back one in the menu history (<)");
-
-  navig[1] = new Fl_Button(1, y + BH / 2, 18, BH / 2, "@#-1>");
-  navig[1]->labeltype(FL_SYMBOL_LABEL);
-  navig[1]->box(FL_FLAT_BOX);
-  navig[1]->selection_color(FL_WHITE);
-  navig[1]->callback(mod_forward_cb);
-  navig[1]->tooltip("Go forward one in the menu history (>)");
-
-  module = new Fl_Choice(19, y, width - 24, BH);
-  module->menu(module_table);
-  module->box(FL_THIN_DOWN_BOX);
-  // force the executation of the callback even if we didn't change
-  // the selection (we want to go back to the top-level menu every
-  // time we select one of the categories, even if the category is not
-  // changed):
-  module->when(FL_WHEN_RELEASE_ALWAYS);
-
-  // create an empty scroll area that will get populated dynamically
-  // in set_context()
-  scroll = new Fl_Scroll(0, _MH, width, NB_BUTT_SCROLL * BH);
-  scroll->type(Fl_Scroll::VERTICAL);
-  scroll->end();
-
-  win->size(width, _MH);
-  win->position(CTX::instance()->menuPosition[0],
-                CTX::instance()->menuPosition[1]);
-
-  win->end();
-}
-
-void menuWindow::setContext(contextItem *menu_asked, int flag)
-{
-  static int nb_back = 0, nb_forward = 0, init_context = 0;
-  static contextItem *menu_history[NB_HISTORY_MAX];
-  contextItem *menu;
-
-  if(!init_context) {
-    init_context = 1;
-    for(int i = 0; i < NB_HISTORY_MAX; i++) {
-      menu_history[i] = 0;
-    }
-  }
-
-  if(nb_back > NB_HISTORY_MAX - 2)
-    nb_back = 1; // we should do a circular list
-
-  if(flag == -1) {
-    if(nb_back > 1) {
-      nb_back--;
-      nb_forward++;
-      menu = menu_history[nb_back - 1];
-    }
-    else
-      return;
-  }
-  else if(flag == 1) {
-    if(nb_forward > 0) {
-      nb_back++;
-      nb_forward--;
-      menu = menu_history[nb_back - 1];
-    }
-    else
-      return;
-  }
-  else if(menu_asked){
-    menu = menu_asked;
-    if(!nb_back || menu_history[nb_back - 1] != menu) {
-      menu_history[nb_back++] = menu;
-    }
-    nb_forward = 0;
-  }
-  else{
-    Msg::Warning("No menu asked...");
-    return;
-  }
-
-  if(menu[0].label[0] == '0'){
-    module->value(0);
-  }
-  else if(menu[0].label[0] == '1'){
-    module->value(1);
-  }
-  else if(menu[0].label[0] == '2'){
-    module->value(2);
-    menu[1].label = opt_solver_name0(0, GMSH_GET, "");
-    menu[2].label = opt_solver_name1(0, GMSH_GET, "");
-    menu[3].label = opt_solver_name2(0, GMSH_GET, "");
-    menu[4].label = opt_solver_name3(0, GMSH_GET, "");
-    menu[5].label = opt_solver_name4(0, GMSH_GET, "");
-  }
-  else if(menu[0].label[0] == '3'){
-    module->value(3);
-  }
-  else {
-    Msg::Warning("Something is wrong in dynamic menu definition");
-    return;
-  }
-
-  Msg::StatusBar(1, false, menu[0].label.c_str() + 1);
-
-  // cannot use scroll->clear() in fltk 1.1 (should be fixed in 1.3)
-  for(unsigned int i = 0; i < push.size(); i++){
-    scroll->remove(push[i]);
-    Fl::delete_widget(push[i]);
-  }
-  for(unsigned int i = 0; i < toggle.size(); i++){
-    scroll->remove(toggle[i]);
-    Fl::delete_widget(toggle[i]);
-  }
-  for(unsigned int i = 0; i < toggle2.size(); i++){
-    scroll->remove(toggle2[i]);
-    Fl::delete_widget(toggle2[i]);
-  }
-  for(unsigned int i = 0; i < popup.size(); i++){
-    scroll->remove(popup[i]);
-    Fl::delete_widget(popup[i]);
-  }
-  for(unsigned int i = 0; i < popup2.size(); i++){
-    scroll->remove(popup2[i]);
-    Fl::delete_widget(popup2[i]);
-  }
-
-  // reset the vectors
-  push.clear();
-  toggle.clear();
-  toggle2.clear();
-  popup.clear();
-  popup2.clear();
-  for(unsigned int i = 0; i < label.size(); i++)
-    delete [] label[i];
-  label.clear();
-  for(unsigned int i = 0; i < label2.size(); i++)
-    delete [] label2[i];
-  label2.clear();
-
-  int width = win->w();
-  int popw = 4 * FL_NORMAL_SIZE + 3;
-
-  // construct the dynamic menu
-  int nb = 0;
-  if(module->value() == 3){ // post-processing context
-    for(nb = 0; nb < (int)PView::list.size(); nb++) {
-      PViewData *data = PView::list[nb]->getData();
-      PViewOptions *opt = PView::list[nb]->getOptions();
-
-      Fl_Light_Button *b1 = new Fl_Light_Button(0, _MH + nb * BH, width - popw, BH);
-      b1->callback(view_toggle_cb, (void *)nb);
-      b1->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
-      b1->value(opt->visible);
-      b1->copy_label(data->getName().c_str());
-      char *tmp2 = new char[data->getFileName().size() + 1];
-      strcpy(tmp2, data->getFileName().c_str());
-      b1->tooltip(tmp2);
-      label2.push_back(tmp2);
-
-      char *tmp = new char[32];
-      sprintf(tmp, "[%d]@#-1>", nb);
-      Fl_Button *b2 = new Fl_Button(width - popw, _MH + nb * BH, popw, BH, tmp);
-      label.push_back(tmp);
-      b2->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
-      b2->tooltip("Show view option menu (Shift+w)");
-
-      popupButton *p[2];
-      p[0] = new popupButton(width - popw, _MH + nb * BH, popw, BH);
-      p[0]->type(Fl_Menu_Button::POPUP123);
-      p[1] = new popupButton(0, _MH + nb * BH, width - popw, BH);
-      p[1]->type(Fl_Menu_Button::POPUP3);
-
-      for(int j = 0; j < 2; j++) {
-        p[j]->add("Reload/View", 'r',
-                  (Fl_Callback *) view_reload_cb, (void *)nb, 0);
-        p[j]->add("Reload/Visible Views", 0,
-                  (Fl_Callback *) view_reload_visible_cb, (void *)nb, 0);
-        p[j]->add("Reload/All Views", 0,
-                  (Fl_Callback *) view_reload_all_cb, (void *)nb, 0);
-        p[j]->add("Remove/View", FL_Delete,
-                  (Fl_Callback *) view_remove_cb, (void *)nb, 0);
-        p[j]->add("Remove/Other Views", 0,
-                  (Fl_Callback *) view_remove_other_cb, (void *)nb, 0);
-        p[j]->add("Remove/Visible Views", 0,
-                  (Fl_Callback *) view_remove_all_cb, (void *)-2, 0);
-        p[j]->add("Remove/Invisible Views", 0,
-                  (Fl_Callback *) view_remove_all_cb, (void *)-3, 0);
-        p[j]->add("Remove/Empty Views", 0,
-                  (Fl_Callback *) view_remove_all_cb, (void *)-4, 0);
-        p[j]->add("Remove/All Views", 0,
-                  (Fl_Callback *) view_remove_all_cb, (void *)-1, 0);
-        p[j]->add("Remove/By Name", 0,
-                  (Fl_Callback *) view_remove_all_cb, (void *)nb, 0);
-        p[j]->add("Alias/View without Options", 0,
-                  (Fl_Callback *) view_alias_cb, (void *)nb, 0);
-        p[j]->add("Alias/View with Options", 0,
-                  (Fl_Callback *) view_alias_with_options_cb, (void *)nb, 0);
-        p[j]->add("Combine Elements/From Visible Views", 0,
-                  (Fl_Callback *) view_combine_space_visible_cb, (void *)nb, 0);
-        p[j]->add("Combine Elements/From All Views", 0,
-                  (Fl_Callback *) view_combine_space_all_cb, (void *)nb, 0);
-        p[j]->add("Combine Elements/By View Name", 0,
-                  (Fl_Callback *) view_combine_space_by_name_cb, (void *)nb, 0);
-        p[j]->add("Combine Time Steps/From Visible Views", 0,
-                  (Fl_Callback *) view_combine_time_visible_cb, (void *)nb, 0);
-        p[j]->add("Combine Time Steps/From All Views", 0,
-                  (Fl_Callback *) view_combine_time_all_cb, (void *)nb, 0);
-        p[j]->add("Combine Time Steps/By View Name", 0,
-                 (Fl_Callback *) view_combine_time_by_name_cb, (void *)nb, 0);
-        p[j]->add("Set Visibility/All On", 0,
-                  (Fl_Callback *) view_all_visible_cb, (void *)-1, 0);
-        p[j]->add("Set Visibility/All Off", 0,
-                  (Fl_Callback *) view_all_visible_cb, (void *)-2, 0);
-        p[j]->add("Set Visibility/Invert", 0,
-                  (Fl_Callback *) view_all_visible_cb, (void *)-3, 0);
-        p[j]->add("Set Visibility/By name", 0,
-                  (Fl_Callback *) view_all_visible_cb, (void *)nb, 0);
-        p[j]->add("Apply As Background Mesh", 0,
-                  (Fl_Callback *) view_applybgmesh_cb, (void *)nb, 0);
-        p[j]->add("Save As...", 0,
-                  (Fl_Callback *) view_save_cb, (void *)nb, FL_MENU_DIVIDER);
-        p[j]->add("Options", 'o',
-                  (Fl_Callback *) view_options_cb, (void *)nb, 0);
-        p[j]->add("Plugins", 'p',
-                  (Fl_Callback *) plugin_cb, (void *)nb, 0);
-      }
-
-      toggle.push_back(b1);
-      toggle2.push_back(b2);
-      popup.push_back(p[0]);
-      popup2.push_back(p[1]);
-      scroll->add(b1);
-      scroll->add(b2);
-      scroll->add(p[0]);
-      scroll->add(p[1]);
-    }
-  }
-  else{ // geometry, mesh and solver contexts
-    while(menu[nb + 1].label.size()) {
-      Fl_Button *b = new Fl_Button(0, _MH + nb * BH, width, BH);
-      b->copy_label(menu[nb + 1].label.c_str());
-      b->callback(menu[nb + 1].callback, menu[nb + 1].arg);
-      push.push_back(b);
-      scroll->add(b);
-      nb++;
-    }
-  }
-
-  /* scroll to the end of the list
-  int hh = (nb - NB_BUTT_SCROLL) * BH;
-  if(hh > 0) scroll->scroll_to(0, hh);
-  */
-
-  scroll->redraw();
-
-  if(nb <= NB_BUTT_SCROLL)
-    win->size(width, _MH + nb * BH);
-  else
-    win->size(width, _MH + NB_BUTT_SCROLL * BH);
-}
-
-void menuWindow::fillRecentHistoryMenu()
-{
-  Fl_Menu_Item *table = bar_table;
-#if defined(__APPLE__) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-  if(CTX::instance()->systemMenuBar)
-    table = sysbar_table;
-#endif
-
-  for(int i = 0; i < 5; i++){
-    table[4 + i].text = CTX::instance()->recentFiles[i].c_str();
-    table[4 + i].user_data_ = (void*)CTX::instance()->recentFiles[i].c_str();
-  }
-
-#if defined(__APPLE__) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-  if(CTX::instance()->systemMenuBar)
-    sysbar->menu(table);
-#endif
-}
diff --git a/Fltk/menuWindow.h b/Fltk/menuWindow.h
deleted file mode 100644
index e3a82f2330a09a9634f1b929f335e01affda9437..0000000000000000000000000000000000000000
--- a/Fltk/menuWindow.h
+++ /dev/null
@@ -1,96 +0,0 @@
-// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
-//
-// See the LICENSE.txt file for license information. Please report all
-// bugs and problems to <gmsh@geuz.org>.
-
-#ifndef _MENU_WINDOW_H_
-#define _MENU_WINDOW_H_
-
-#include <string>
-#include <vector>
-#include <FL/Fl_Window.H>
-#if defined(__APPLE__)
-#include <FL/Fl_Sys_Menu_Bar.H>
-#endif
-#include <FL/Fl_Menu_Bar.H>
-#include <FL/Fl_Scroll.H>
-#include <FL/Fl_Choice.H>
-#include <FL/Fl_Button.H>
-#include <FL/Fl_Light_Button.H>
-#include "popupButton.h"
-
-// The dynamic menu contexts
-typedef struct{
-  std::string label;
-  Fl_Callback *callback;
-  void *arg;
-} contextItem;
-
-extern contextItem menu_geometry[]; 
-extern    contextItem menu_geometry_elementary[]; 
-extern        contextItem menu_geometry_elementary_add[]; 
-extern            contextItem menu_geometry_elementary_add_new[]; 
-extern            contextItem menu_geometry_elementary_add_translate[]; 
-extern            contextItem menu_geometry_elementary_add_rotate[]; 
-extern            contextItem menu_geometry_elementary_add_scale[]; 
-extern            contextItem menu_geometry_elementary_add_symmetry[]; 
-extern        contextItem menu_geometry_elementary_translate[]; 
-extern        contextItem menu_geometry_elementary_rotate[]; 
-extern        contextItem menu_geometry_elementary_scale[]; 
-extern        contextItem menu_geometry_elementary_symmetry[]; 
-extern        contextItem menu_geometry_elementary_extrude[]; 
-extern            contextItem menu_geometry_elementary_extrude_translate[]; 
-extern            contextItem menu_geometry_elementary_extrude_rotate[]; 
-extern        contextItem menu_geometry_elementary_delete[]; 
-extern        contextItem menu_geometry_elementary_split[]; 
-extern    contextItem menu_geometry_physical[]; 
-extern        contextItem menu_geometry_physical_add[]; 
-extern contextItem menu_mesh[]; 
-extern    contextItem menu_mesh_edit[]; 
-extern        contextItem menu_mesh_delete[]; 
-extern    contextItem menu_mesh_define[]; 
-extern        contextItem menu_mesh_define_transfinite[];
-extern        contextItem menu_mesh_define_compound[];
-extern    contextItem menu_mesh_degree[];
-extern contextItem menu_solver[]; 
-extern contextItem menu_post[]; 
-
-class menuWindow{
- private:
-  int _MH;
- public:
-  Fl_Window *win;
-#if defined(__APPLE__)
-  Fl_Sys_Menu_Bar *sysbar;
-#endif
-  Fl_Menu_Bar *bar;
-  Fl_Choice *module;
-  Fl_Button *navig[2];
-  Fl_Scroll *scroll;
-  std::vector<Fl_Button*> push;
-  std::vector<Fl_Light_Button*> toggle;
-  std::vector<Fl_Button*> toggle2;
-  std::vector<popupButton*> popup;
-  std::vector<popupButton*> popup2;
-  std::vector<char*> label, label2;
- public:
-  menuWindow();
-  void setContext(contextItem *menu_asked, int flag);
-  void fillRecentHistoryMenu();
-};
-
-void file_quit_cb(Fl_Widget *w, void *data);
-void file_watch_cb(Fl_Widget *w, void *data);
-void mod_geometry_cb(Fl_Widget *w, void *data);
-void mod_mesh_cb(Fl_Widget *w, void *data);
-void mod_solver_cb(Fl_Widget *w, void *data);
-void mod_post_cb(Fl_Widget *w, void *data);
-void mod_back_cb(Fl_Widget *w, void *data);
-void mod_forward_cb(Fl_Widget *w, void *data);
-void geometry_reload_cb(Fl_Widget *w, void *data);
-void mesh_1d_cb(Fl_Widget *w, void *data);
-void mesh_2d_cb(Fl_Widget *w, void *data);
-void mesh_3d_cb(Fl_Widget *w, void *data);
-void help_about_cb(Fl_Widget *w, void *data);
-
-#endif
diff --git a/Fltk/onelabWindow.cpp b/Fltk/onelabGroup.cpp
similarity index 90%
rename from Fltk/onelabWindow.cpp
rename to Fltk/onelabGroup.cpp
index af83909db00f639c4522091bfebc7e0e00b9994c..0d82e89a9927e5036ec75b2688ad4a6e342bd69a 100644
--- a/Fltk/onelabWindow.cpp
+++ b/Fltk/onelabGroup.cpp
@@ -12,28 +12,21 @@ typedef unsigned long intptr_t;
 #endif
 
 #include "GmshMessage.h"
-
-#if defined(HAVE_ONELAB)
 #include "onelab.h"
-#endif
-
-#if defined(HAVE_ONELAB_METAMODEL)
-#include "metamodel.h"
-#endif
-
-#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
-
 #include <FL/Fl_Check_Button.H>
 #include <FL/Fl_Box.H>
+#include <FL/Fl_Choice.H>
+#include <FL/Fl_Light_Button.H>
 #include <FL/Fl_Input_Choice.H>
 #include <FL/Fl_Output.H>
 #include <FL/fl_ask.H>
 #include "inputRange.h"
 #include "inputRegion.h"
+#include "viewButton.h"
 #include "paletteWindow.h"
-#include "menuWindow.h"
+#include "graphicWindow.h"
 #include "fileDialogs.h"
-#include "onelabWindow.h"
+#include "onelabGroup.h"
 #include "FlGui.h"
 #include "Context.h"
 #include "GModel.h"
@@ -47,9 +40,13 @@ typedef unsigned long intptr_t;
 #include "drawContext.h"
 #include "PView.h"
 
+#if defined(HAVE_ONELAB_METAMODEL)
+#include "metamodel.h"
+#endif
+
 // This file contains the Gmsh/FLTK specific parts of the OneLab
-// interface. You'll need to reimplement this if you plan to build
-// a different OneLab server.
+// interface. You'll need to reimplement this if you plan to build a different
+// OneLab server.
 
 class onelabGmshServer : public GmshServer{
  private:
@@ -148,7 +145,7 @@ bool onelab::localNetworkClient::run()
     return false;
   }
 
-  Msg::StatusBar(2, true, "Running '%s'...", _name.c_str());
+  Msg::StatusBar(true, "Running '%s'...", _name.c_str());
 
   while(1) {
 
@@ -286,7 +283,7 @@ bool onelab::localNetworkClient::run()
       }
       break;
     case GmshSocket::GMSH_PROGRESS:
-      Msg::StatusBar(2, false, "%s %s", _name.c_str(), message.c_str());
+      Msg::StatusBar(false, "%s %s", _name.c_str(), message.c_str());
       break;
     case GmshSocket::GMSH_INFO:
       Msg::Direct("%-8.8s: %s", _name.c_str(), message.c_str());
@@ -303,8 +300,10 @@ bool onelab::localNetworkClient::run()
         MergePostProcessingFile(message, CTX::instance()->solver.autoShowLastStep,
                                 CTX::instance()->solver.autoHideNewViews, true);
         drawContext::global()->draw();
-        if(n != PView::list.size())
-          FlGui::instance()->menu->setContext(menu_post, 0);
+        if(n != PView::list.size()){
+          FlGui::instance()->rebuildTree();
+          FlGui::instance()->openModule("Post-processing");
+        }
       }
       break;
     case GmshSocket::GMSH_PARSE_STRING:
@@ -333,7 +332,7 @@ bool onelab::localNetworkClient::run()
   server->Shutdown();
   delete server;
 
-  Msg::StatusBar(2, true, "Done running '%s'", _name.c_str());
+  Msg::StatusBar(true, "Done running '%s'", _name.c_str());
 
   if(command.empty()){
     Msg::Info("Client disconnected: starting new connection");
@@ -363,7 +362,7 @@ static void initializeLoops()
   onelabUtils::initializeLoop("3");
 
   if(onelab::server::instance()->getChanged())
-    FlGui::instance()->onelab->rebuildTree();
+    FlGui::instance()->rebuildTree();
 }
 
 static bool incrementLoops()
@@ -374,7 +373,7 @@ static bool incrementLoops()
   else if(onelabUtils::incrementLoop("1")) ret = true;
 
   if(onelab::server::instance()->getChanged())
-    FlGui::instance()->onelab->rebuildTree();
+    FlGui::instance()->rebuildTree();
 
   return ret;
 }
@@ -404,9 +403,9 @@ static std::string timeStamp()
 
 static void saveDb(const std::string &fileName)
 {
-  Msg::StatusBar(2, true, "Saving database '%s'...", fileName.c_str());
+  Msg::StatusBar(true, "Saving database '%s'...", fileName.c_str());
   if(onelab::server::instance()->toFile(fileName))
-    Msg::StatusBar(2, true, "Done saving database '%s'", fileName.c_str());
+    Msg::StatusBar(true, "Done saving database '%s'", fileName.c_str());
   else
     Msg::Error("Could not save database '%s'", fileName.c_str());
 }
@@ -449,14 +448,14 @@ static void archiveOutputFiles(const std::string &fileName)
     saveDb(split[0] + "archive/" + split[1] + stamp + split[2]);
   }
 
-  FlGui::instance()->onelab->rebuildTree();
+  FlGui::instance()->rebuildTree();
 }
 
 static void loadDb(const std::string &name)
 {
-  Msg::StatusBar(2, true, "Loading database '%s'...", name.c_str());
+  Msg::StatusBar(true, "Loading database '%s'...", name.c_str());
   if(onelab::server::instance()->fromFile(name))
-    Msg::StatusBar(2, true, "Done loading database '%s'", name.c_str());
+    Msg::StatusBar(true, "Done loading database '%s'", name.c_str());
   else
     Msg::Error("Could not load database '%s'", name.c_str());
 }
@@ -468,9 +467,7 @@ void onelab_cb(Fl_Widget *w, void *data)
 
   if(action == "refresh"){
     updateGraphs();
-    FlGui::instance()->onelab->rebuildTree();
-    if(!FlGui::instance()->onelab->shown())
-      FlGui::instance()->onelab->show();
+    FlGui::instance()->rebuildTree();
     return;
   }
 
@@ -591,7 +588,7 @@ void onelab_cb(Fl_Widget *w, void *data)
 
     if(action != "initialize"){
       updateGraphs();
-      FlGui::instance()->onelab->rebuildTree();
+      FlGui::instance()->rebuildTree();
     }
 
   } while(action == "compute" && !FlGui::instance()->onelab->stop() &&
@@ -691,6 +688,7 @@ static void onelab_tree_cb(Fl_Widget *w, void *data)
   std::vector<onelab::string> strings;
   std::vector<onelab::region> regions;
   std::vector<onelab::function> functions;
+
   switch(tree->callback_reason()){
   case FL_TREE_REASON_SELECTED: break;
   case FL_TREE_REASON_DESELECTED: break;
@@ -711,33 +709,31 @@ static void onelab_tree_cb(Fl_Widget *w, void *data)
   }
 }
 
-onelabWindow::onelabWindow(int deltaFontSize)
-  : _deltaFontSize(deltaFontSize), _stop(false)
+onelabGroup::onelabGroup(int x, int y, int w, int h, const char *l)
+  : Fl_Group(x,y,w,h,l), _stop(false)
 {
-  FL_NORMAL_SIZE -= _deltaFontSize;
-
-  int width = CTX::instance()->solverSize[0];
-  int height = CTX::instance()->solverSize[1];
-
-  _win = new paletteWindow
-    (width, height, CTX::instance()->nonModalWindows ? true : false, "OneLab");
-  _win->box(GMSH_WINDOW_BOX);
-
-  _tree = new Fl_Tree(WB, WB, width - 2 * WB, height - 3 * WB - BH);
+  _tree = new Fl_Tree(x, y, w, h - BH - 2 * WB);
   _tree->callback(onelab_tree_cb);
   _tree->connectorstyle(FL_TREE_CONNECTOR_SOLID);
   _tree->showroot(0);
+  _tree->box(FL_FLAT_BOX);
+  _tree->scrollbar_size(std::max(10, FL_NORMAL_SIZE - 2));
 
   _itemWidth = (int)(0.4 * _tree->w());
 
-  _butt[0] = new Fl_Button(width - 2*WB - 2*BB, height - WB - BH, BB, BH, "Check");
+  box(FL_FLAT_BOX);
+  color(_tree->color());
+
+  int BB2 = BB / 2 + 4;
+
+  _butt[0] = new Fl_Button(x + w - 3 * WB - 3 * BB2, y + h - WB - BH, BB2, BH, "Check");
   _butt[0]->callback(onelab_cb, (void*)"check");
-  _butt[1] = new Fl_Button(width - WB - BB, height - WB - BH, BB, BH, "Compute");
+
+  _butt[1] = new Fl_Button(x + w - 2 * WB - 2 * BB2, y + h - WB - BH, BB2, BH, "Run");
   _butt[1]->callback(onelab_cb, (void*)"compute");
 
-  int BB2 = BB / 2 + 4;
   _gear = new Fl_Menu_Button
-    (_butt[0]->x() - WB - BB2, _butt[0]->y(), BB2, BH, "@-1gmsh_gear");
+    (x + w - WB - BB2, y + h - WB - BH, BB2, BH, "@-1gmsh_gear");
   _gear->align(FL_ALIGN_CENTER | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
   _gear->add("Reset database", 0, onelab_cb, (void*)"reset");
   _gear->add("Save database...", 0, onelab_cb, (void*)"save");
@@ -762,19 +758,12 @@ onelabWindow::onelabWindow(int deltaFontSize)
 
   _gearOptionsEnd = _gear->menu()->size();
 
-  Fl_Box *resbox = new Fl_Box(WB, WB,
-                              width - 2 * BB - BB2 - 4 * WB,
-                              height - 3 * WB - BH);
-  _win->resizable(resbox);
-  _win->size_range(2 * BB + BB2 + 4 * WB + 1, 2 * BH + 3 * WB);
-
-  _win->position
-    (CTX::instance()->solverPosition[0], CTX::instance()->solverPosition[1]);
-  _win->end();
+  end();
 
-  setButtonVisibility();
+  Fl_Box *resbox = new Fl_Box(x + WB, y + WB, WB, WB);
+  resizable(resbox);
 
-  FL_NORMAL_SIZE += _deltaFontSize;
+  rebuildSolverList();
 }
 
 static bool getFlColor(const std::string &str, Fl_Color &c)
@@ -810,7 +799,7 @@ static void autoCheck(const T &pold, const T &pnew, bool force=false)
 }
 
 template<class T>
-void onelabWindow::_addParameter(T &p)
+void onelabGroup::_addParameter(T &p)
 {
   bool highlight = false;
   Fl_Color c;
@@ -825,6 +814,45 @@ void onelabWindow::_addParameter(T &p)
   _tree->end();
 }
 
+void onelabGroup::_addMenu(const std::string &path, Fl_Callback *callback, void *data)
+{
+  Fl_Tree_Item *n = _tree->add(path.c_str());
+  n->labelsize(FL_NORMAL_SIZE + 5);
+  _tree->begin();
+  Fl_Button *but = new Fl_Button(1, 1, (3 * _itemWidth) / 2, 1);
+  but->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  but->callback(callback, data);
+  _treeWidgets.push_back(but);
+  std::string label = path;
+  std::string::size_type last = path.find_last_of('/');
+  if(last != std::string::npos) label = path.substr(last + 1);
+  but->copy_label(label.c_str());
+  n->widget(but);
+  _tree->end();
+}
+
+void onelabGroup::_addViewMenu(int num)
+{
+  std::ostringstream path;
+  path << "0Gmsh modules/Post-processing/View" << num;
+  Fl_Tree_Item *n = _tree->add(path.str().c_str());
+  n->labelsize(FL_NORMAL_SIZE + 5);
+  _tree->begin();
+  viewButton *but = new viewButton(1, 1, (7 * _itemWidth) / 4, 1, num);
+  _treeWidgets.push_back(but);
+  n->widget(but);
+  _tree->end();
+}
+
+viewButton *onelabGroup::getViewButton(int num)
+{
+  char tmp[256];
+  sprintf(tmp, "0Gmsh modules/Post-processing/View%d", num);
+  Fl_Tree_Item *n = _tree->find_item(tmp);
+  if(n) return (viewButton*)n->widget();
+  return 0;
+}
+
 static void onelab_number_check_button_cb(Fl_Widget *w, void *data)
 {
   if(!data) return;
@@ -881,8 +909,8 @@ static void onelab_number_input_range_cb(Fl_Widget *w, void *data)
   }
 }
 
-Fl_Widget *onelabWindow::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n,
-                                             bool highlight, Fl_Color c)
+Fl_Widget *onelabGroup::_addParameterWidget(onelab::number &p, Fl_Tree_Item *n,
+                                            bool highlight, Fl_Color c)
 {
   // non-editable value
   if(p.getReadOnly()){
@@ -1002,12 +1030,12 @@ static void onelab_input_choice_file_merge_cb(Fl_Widget *w, void *data)
   drawContext::global()->draw();
 }
 
-Fl_Widget *onelabWindow::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n,
-                                             bool highlight, Fl_Color c)
+Fl_Widget *onelabGroup::_addParameterWidget(onelab::string &p, Fl_Tree_Item *n,
+                                            bool highlight, Fl_Color c)
 {
   // macro button
   if(p.getKind() == "macro"){
-    Fl_Button *but = new Fl_Button(1, 1, _itemWidth, 1);
+    Fl_Button *but = new Fl_Button(1, 1, (3 * _itemWidth) / 2, 1);
     but->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
     but->callback(onelab_string_button_cb, (void*)n);
     if(highlight) but->color(c);
@@ -1070,8 +1098,8 @@ static void onelab_region_input_cb(Fl_Widget *w, void *data)
   }
 }
 
-Fl_Widget *onelabWindow::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n,
-                                             bool highlight, Fl_Color c)
+Fl_Widget *onelabGroup::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n,
+                                            bool highlight, Fl_Color c)
 {
   // non-editable value
   if(p.getReadOnly()){
@@ -1090,8 +1118,8 @@ Fl_Widget *onelabWindow::_addParameterWidget(onelab::region &p, Fl_Tree_Item *n,
   return but;
 }
 
-Fl_Widget *onelabWindow::_addParameterWidget(onelab::function &p, Fl_Tree_Item *n,
-                                             bool highlight, Fl_Color c)
+Fl_Widget *onelabGroup::_addParameterWidget(onelab::function &p, Fl_Tree_Item *n,
+                                            bool highlight, Fl_Color c)
 {
   // non-editable value
   if(1 || p.getReadOnly()){
@@ -1103,13 +1131,18 @@ Fl_Widget *onelabWindow::_addParameterWidget(onelab::function &p, Fl_Tree_Item *
   }
 }
 
-void onelabWindow::rebuildTree()
+static void onelab_subtree_cb(Fl_Widget *w, void *data)
 {
-  FL_NORMAL_SIZE -= _deltaFontSize;
+  Fl_Tree_Item *n = (Fl_Tree_Item*)data;
+  n->open_toggle();
+  FlGui::instance()->onelab->redrawTree();
+}
 
+void onelabGroup::rebuildTree()
+{
   _itemWidth = (int)(0.4 * _tree->w());
 
-  std::set<std::string> closed;
+  std::set<std::string> closed = _getClosedGmshMenus();
 
   _tree->clear();
   _tree->sortorder(FL_TREE_SORT_ASCENDING);
@@ -1122,6 +1155,8 @@ void onelabWindow::rebuildTree()
     free(_treeStrings[i]);
   _treeStrings.clear();
 
+  _addGmshMenus();
+
   std::vector<onelab::number> numbers;
   onelab::server::instance()->get(numbers);
   for(unsigned int i = 0; i < numbers.size(); i++){
@@ -1161,8 +1196,11 @@ void onelabWindow::rebuildTree()
   for(Fl_Tree_Item *n = _tree->first(); n; n = n->next()){
     if(n->has_children()){
       _tree->begin();
-      Fl_Box *but = new Fl_Box(1, 1, _itemWidth, 1);
+      Fl_Button *but = new Fl_Button(1, 1, _itemWidth, 1);
+      but->box(FL_NO_BOX);
+      but->clear_visible_focus();
       but->align(FL_ALIGN_LEFT | FL_ALIGN_INSIDE);
+      but->callback(onelab_subtree_cb, (void*)n);
       _treeWidgets.push_back(but);
       onelab::string o(n->label());
       but->copy_label(o.getShortName().c_str());
@@ -1177,11 +1215,18 @@ void onelabWindow::rebuildTree()
   _tree->redraw();
 
   FlGui::check(); // necessary e.g. on windows to avoid "ghosting"
+}
 
-  FL_NORMAL_SIZE += _deltaFontSize;
+void onelabGroup::openTreeItem(const std::string &name)
+{
+  Fl_Tree_Item *n = _tree->find_item(name.c_str());
+  if(n && n->has_children()){
+    n->open();
+    _tree->redraw();
+  }
 }
 
-void onelabWindow::checkForErrors(const std::string &client)
+void onelabGroup::checkForErrors(const std::string &client)
 {
   if(Msg::GetErrorCount() > 0 && !CTX::instance()->expertMode){
     Msg::ResetErrorCounter();
@@ -1194,24 +1239,22 @@ void onelabWindow::checkForErrors(const std::string &client)
   }
 }
 
-void onelabWindow::setButtonVisibility()
+void onelabGroup::setButtonVisibility()
 {
-  if(_butt[0]->visible() && CTX::instance()->solver.autoCheck){
+  if(!CTX::instance()->solver.autoCheck)
+    _butt[0]->show();
+  else
     _butt[0]->hide();
-    _gear->position(_gear->x() + _butt[0]->w() + WB, _gear->y());
-    _win->init_sizes();
-    _win->redraw();
-  }
 
-  if(!_butt[0]->visible() && !CTX::instance()->solver.autoCheck){
-    _butt[0]->show();
-    _gear->position(_gear->x() - _butt[0]->w() - WB, _gear->y());
-    _win->init_sizes();
-    _win->redraw();
-  }
+  if(onelab::server::instance()->getNumClients() > 1)
+    _butt[1]->show();
+  else
+    _butt[1]->hide();
+
+  redraw();
 }
 
-void onelabWindow::setButtonMode(const std::string &butt0, const std::string &butt1)
+void onelabGroup::setButtonMode(const std::string &butt0, const std::string &butt1)
 {
   if(butt0 == "check"){
     _butt[0]->activate();
@@ -1224,7 +1267,7 @@ void onelabWindow::setButtonMode(const std::string &butt0, const std::string &bu
 
   if(butt1 == "compute"){
     _butt[1]->activate();
-    _butt[1]->label("Compute");
+    _butt[1]->label("Run");
     _butt[1]->callback(onelab_cb, (void*)"compute");
     for(int i = 0; i < _gear->menu()->size(); i++)
       ((Fl_Menu_Item*)_gear->menu())[i].activate();
@@ -1253,14 +1296,14 @@ void onelabWindow::setButtonMode(const std::string &butt0, const std::string &bu
   }
 }
 
-bool onelabWindow::isBusy()
+bool onelabGroup::isBusy()
 {
   std::string s(_butt[1]->label());
-  if(s == "Compute") return false;
+  if(s == "Run") return false;
   return true;
 }
 
-void onelabWindow::rebuildSolverList()
+void onelabGroup::rebuildSolverList()
 {
   // update OneLab window title and gear menu
   _title = "OneLab";
@@ -1295,7 +1338,7 @@ void onelabWindow::rebuildSolverList()
     _title += " " + it->second->getName();
   }
   _gear->add("Add new client...", 0, onelab_add_solver_cb);
-  _win->label(_title.c_str());
+  //label(_title.c_str());
 
   // update Gmsh solver menu
   std::vector<std::string> names, exes, hosts;
@@ -1321,11 +1364,13 @@ void onelabWindow::rebuildSolverList()
       opt_solver_remote_login(i, GMSH_SET, "");
     }
   }
-  FlGui::instance()->menu->setContext(menu_solver, 0);
+
+  setButtonVisibility();
+  rebuildTree();
 }
 
-void onelabWindow::addSolver(const std::string &name, const std::string &executable,
-                             const std::string &remoteLogin, int index)
+void onelabGroup::addSolver(const std::string &name, const std::string &executable,
+                            const std::string &remoteLogin, int index)
 {
   if(onelab::server::instance()->findClient(name) !=
      onelab::server::instance()->lastClient()) return; // solver already exists
@@ -1356,7 +1401,7 @@ void onelabWindow::addSolver(const std::string &name, const std::string &executa
   onelab_cb(0, (void*)"initialize");
 }
 
-void onelabWindow::removeSolver(const std::string &name)
+void onelabGroup::removeSolver(const std::string &name)
 {
   onelab::server::citer it = onelab::server::instance()->findClient(name);
   if(it != onelab::server::instance()->lastClient()){
@@ -1385,8 +1430,9 @@ void solver_cb(Fl_Widget *w, void *data)
     std::string host = opt_solver_remote_login(num, GMSH_GET, "");
     FlGui::instance()->onelab->addSolver(name, exe, host, num);
   }
-  else
+  else{
     FlGui::instance()->onelab->rebuildSolverList();
+  }
 
   if(CTX::instance()->solver.autoSaveDatabase){
     std::string db = SplitFileName(GModel::current()->getFileName())[0] + "onelab.db";
@@ -1398,7 +1444,7 @@ void solver_cb(Fl_Widget *w, void *data)
   else
     onelab_cb(0, (num >= 0) ? (void*)"check" : (void*)"refresh");
 
-  CTX::instance()->launchOnelabAtStartup = -2;
+  CTX::instance()->launchSolverAtStartup = -1;
 }
 
 void flgui_wait_cb(double time)
@@ -1440,34 +1486,3 @@ int metamodel_cb(const std::string &name, const std::string &action)
   return 0;
 #endif
 }
-
-#else
-
-#if defined(HAVE_ONELAB)
-
-bool onelab::localNetworkClient::run()
-{
-  Msg::Error("The solver interface requires OneLab and FLTK 1.3");
-  return false;
-}
-
-bool onelab::localNetworkClient::kill()
-{
-  Msg::Error("The solver interface requires OneLab and FLTK 1.3");
-  return false;
-}
-
-#endif
-
-void solver_cb(Fl_Widget *w, void *data)
-{
-  Msg::Error("The solver interface requires OneLab and FLTK 1.3");
-}
-
-int metamodel_cb(const std::string &name, const std::string &action)
-{
-  Msg::Error("Metamodels require OneLab and FLTK 1.3");
-  return 0;
-}
-
-#endif
diff --git a/Fltk/onelabWindow.h b/Fltk/onelabGroup.h
similarity index 82%
rename from Fltk/onelabWindow.h
rename to Fltk/onelabGroup.h
index 57ecc25e9a985d219087b5aa7f22be3a9d307b60..ee7c35fe5bdaec9f7f7632763bd1383c55c13bd7 100644
--- a/Fltk/onelabWindow.h
+++ b/Fltk/onelabGroup.h
@@ -6,21 +6,18 @@
 #ifndef _ONELAB_WINDOW_H_
 #define _ONELAB_WINDOW_H_
 
-#include "GmshConfig.h"
-#include <FL/Fl.H>
-
-#if defined(HAVE_ONELAB) && (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
 #include <vector>
-#include <FL/Fl_Window.H>
+#include <FL/Fl.H>
 #include <FL/Fl_Tree.H>
 #include <FL/Fl_Button.H>
 #include <FL/Fl_Menu_Button.H>
 #include <FL/Fl_Input.H>
 #include "onelab.h"
 
-class onelabWindow{
+class viewButton;
+
+class onelabGroup : public Fl_Group{
  private:
-  Fl_Window *_win;
   Fl_Tree *_tree;
   Fl_Button *_butt[2];
   Fl_Menu_Button *_gear;
@@ -28,7 +25,6 @@ class onelabWindow{
   std::vector<Fl_Widget*> _treeWidgets;
   std::vector<char*> _treeStrings;
   std::string _title;
-  int _deltaFontSize;
   bool _stop;
   int _itemWidth;
   template <class T> void _addParameter(T &p);
@@ -40,25 +36,26 @@ class onelabWindow{
                                  bool highlight, Fl_Color c);
   Fl_Widget *_addParameterWidget(onelab::function &p, Fl_Tree_Item *n,
                                  bool highlight, Fl_Color c);
+  void _addMenu(const std::string &path, Fl_Callback *callback, void *data);
+  void _addViewMenu(int num);
+  std::set<std::string> _getClosedGmshMenus();
+  void _addGmshMenus();
  public:
-  onelabWindow(int deltaFontSize=0);
-  int x(){ return _win->x(); }
-  int y(){ return _win->y(); }
-  int w(){ return _win->w(); }
-  int h(){ return _win->h(); }
+  onelabGroup(int x, int y, int w, int h, const char *l=0);
   void rebuildSolverList();
   void rebuildTree();
+  void redrawTree(){ _tree->redraw(); }
+  void openTreeItem(const std::string &name);
   void setButtonVisibility();
   void setButtonMode(const std::string &butt0, const std::string &butt1);
   bool isBusy();
-  void show(){ _win->show(); }
-  int shown(){ return _win->shown(); }
   std::string getPath(Fl_Tree_Item *item)
   {
     char path[1024];
     _tree->item_pathname(path, 1024, item);
     return std::string(path);
   }
+  viewButton *getViewButton(int num);
   void addSolver(const std::string &name, const std::string &exe,
                  const std::string &hostName, int index);
   void removeSolver(const std::string &name);
@@ -68,9 +65,6 @@ class onelabWindow{
 };
 
 void onelab_cb(Fl_Widget *w, void *data);
-
-#endif
-
 void solver_cb(Fl_Widget *w, void *data);
 int metamodel_cb(const std::string &name, const std::string &action="");
 
diff --git a/Fltk/openglWindow.cpp b/Fltk/openglWindow.cpp
index a767894aba8c18b95d09446dbffed42529a1ddd2..905a9e8f7e188f1ed1ee8bc2ea38195fea0e58cc 100644
--- a/Fltk/openglWindow.cpp
+++ b/Fltk/openglWindow.cpp
@@ -39,8 +39,8 @@ static void lassoZoom(drawContext *ctx, mousePosition &click1, mousePosition &cl
   FlGui::instance()->manip->update();
 }
 
-openglWindow::openglWindow(int x, int y, int w, int h, const char *l)
-  : Fl_Gl_Window(x, y, w, h, l), _lock(false),
+openglWindow::openglWindow(int x, int y, int w, int h)
+  : Fl_Gl_Window(x, y, w, h, "gl"), _lock(false),
     _selection(ENT_NONE), _trySelection(0)
 {
   _ctx = new drawContext();
@@ -85,40 +85,46 @@ void openglWindow::_drawScreenMessage()
 
 void openglWindow::_drawBorder()
 {
-  // draw thin border if the parent group has more than 2 children (it
-  // has at least 2: the message console and one opengl window)
-  if(parent()->children() > 2){
-    unsigned char r, g, b;
-    Fl::get_color(color(), r, g, b);
-    /* would need to redraw all gl's when _lastHandled is changed
-    if(_lastHandled == this)
-      Fl::get_color(FL_SELECTION_COLOR, r, g, b);
-    else
-      Fl::get_color(FL_BACKGROUND_COLOR, r, g, b);
-    */
-    glColor3ub(r, g, b);
-    glLineWidth(1.0F);
-    glBegin(GL_LINE_LOOP);
-    glVertex2d(_ctx->viewport[0], _ctx->viewport[1]);
-    glVertex2d(_ctx->viewport[2], _ctx->viewport[1]);
-    glVertex2d(_ctx->viewport[2], _ctx->viewport[3]);
-    glVertex2d(_ctx->viewport[0], _ctx->viewport[3]);
-    glEnd();
+  // draw thin border if the parent group has more than 2 opengl windows
+  int numgl = 0;
+  for(int i = 0; i < parent()->children(); i++){
+    if(parent()->child(i)->label() &&
+       !strcmp(parent()->child(i)->label(), label()))
+      numgl++;
   }
+  if(numgl < 2) return;
+
+  unsigned char r, g, b;
+  Fl::get_color(color(), r, g, b);
+  /* would need to redraw all gl's when _lastHandled is changed
+   if(_lastHandled == this)
+     Fl::get_color(FL_SELECTION_COLOR, r, g, b);
+   else
+     Fl::get_color(FL_BACKGROUND_COLOR, r, g, b);
+  */
+  glColor3ub(r, g, b);
+  glLineWidth(1.0F);
+  glBegin(GL_LINE_LOOP);
+  glVertex2d(_ctx->viewport[0], _ctx->viewport[1]);
+  glVertex2d(_ctx->viewport[2], _ctx->viewport[1]);
+  glVertex2d(_ctx->viewport[2], _ctx->viewport[3]);
+  glVertex2d(_ctx->viewport[0], _ctx->viewport[3]);
+  glEnd();
 }
 
 void openglWindow::draw()
 {
-  // some drawing routines can create data (STL triangulations, etc.):
-  // make sure that we don't fire draw() while we are already drawing,
-  // e.g. due to an impromptu Fl::check(). The same lock is also used
-  // in _select to guarantee that we don't mix GL_RENDER and GL_SELECT
-  // rendering passes.
+  // some drawing routines can create data (STL triangulations, etc.): make sure
+  // that we don't fire draw() while we are already drawing, e.g. due to an
+  // impromptu Fl::check(). The same lock is also used in _select to guarantee
+  // that we don't mix GL_RENDER and GL_SELECT rendering passes.
   if(_lock) return;
   _lock = true;
 
   Msg::Debug("openglWindow::draw()");
 
+  if(!context_valid()) _ctx->invalidateQuadricsAndDisplayLists();
+
   _ctx->viewport[0] = 0;
   _ctx->viewport[1] = 0;
   _ctx->viewport[2] = w();
@@ -127,8 +133,8 @@ void openglWindow::draw()
              _ctx->viewport[2], _ctx->viewport[3]);
 
   if(lassoMode) {
-    // draw the zoom or selection lasso on top of the current scene
-    // (without using overlays!)
+    // draw the zoom or selection lasso on top of the current scene (without
+    // using overlays!)
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrtho((double)_ctx->viewport[0], (double)_ctx->viewport[2],
@@ -224,7 +230,6 @@ void openglWindow::draw()
       _ctx->draw2d();
       _drawScreenMessage();
       _drawBorder();
-      //    glPushMatrix();
     }
     else if(CTX::instance()->stereo){
       Camera *cam = &(_ctx->camera);
@@ -588,7 +593,7 @@ int openglWindow::handle(int event)
         if(CTX::instance()->tooltips)
           drawTooltip(text);
         else
-          Msg::StatusBar(2, false, text.c_str());
+          Msg::StatusBar(false, text.c_str());
       }
     }
     _prev.set(_ctx, Fl::event_x(), Fl::event_y());
diff --git a/Fltk/openglWindow.h b/Fltk/openglWindow.h
index 9344a1d2c6f905eb587d2f9be39579f93c10c3df..6d18f53b4d9470be94e6916a70ebc472aad1560d 100644
--- a/Fltk/openglWindow.h
+++ b/Fltk/openglWindow.h
@@ -41,7 +41,7 @@ class openglWindow : public Fl_Gl_Window {
   bool addPointMode, lassoMode, selectionMode;
   int endSelection, undoSelection, invertSelection, quitSelection;
   std::string screenMessage[2];
-  openglWindow(int x, int y, int w, int h, const char *l=0);
+  openglWindow(int x, int y, int w, int h);
   ~openglWindow();
   drawContext *getDrawContext(){ return _ctx; }
   char selectEntity(int type,
diff --git a/Fltk/optionWindow.cpp b/Fltk/optionWindow.cpp
index ae493642518ebdc19cc3fbe28d157c1a57c6f1fb..34155a30238bd6d21132acbe56bbb176b7ab2d8a 100644
--- a/Fltk/optionWindow.cpp
+++ b/Fltk/optionWindow.cpp
@@ -17,8 +17,9 @@ typedef unsigned long intptr_t;
 #include "GmshMessage.h"
 #include "FlGui.h"
 #include "optionWindow.h"
+#include "graphicWindow.h"
+#include "openglWindow.h"
 #include "paletteWindow.h"
-#include "menuWindow.h"
 #include "extraDialogs.h"
 #include "drawContext.h"
 #include "Options.h"
@@ -29,8 +30,6 @@ typedef unsigned long intptr_t;
 #include "PViewOptions.h"
 #include "OS.h"
 #include "Context.h"
-#include "graphicWindow.h"
-#include "openglWindow.h"
 
 #if defined(HAVE_ONELAB)
 #include "onelab.h"
@@ -174,8 +173,7 @@ static void options_restore_defaults_cb(Fl_Widget *w, void *data)
   UnlinkFile(CTX::instance()->homeDir + CTX::instance()->optionsFileName);
   ReInitOptions(0);
   InitOptionsGUI(0);
-  if(FlGui::instance()->menu->module->value() == 3) // hack to refresh the buttons
-    FlGui::instance()->menu->setContext(menu_post, 0);
+  FlGui::instance()->rebuildTree();
   drawContext::global()->draw();
 }
 
@@ -193,7 +191,7 @@ static void general_options_color_scheme_cb(Fl_Widget *w, void *data)
 
 static void general_options_rotation_center_select_cb(Fl_Widget *w, void *data)
 {
-  Msg::StatusBar(3, false, "Select entity or element\n[Press 'q' to abort]");
+  Msg::StatusGl("Select entity or element\n[Press 'q' to abort]");
 
   CTX::instance()->pickElements = 1;
   CTX::instance()->mesh.changed = ENT_ALL;
@@ -221,7 +219,7 @@ static void general_options_rotation_center_select_cb(Fl_Widget *w, void *data)
   CTX::instance()->mesh.changed = ENT_ALL;
   GModel::current()->setSelection(0);
   drawContext::global()->draw();
-  Msg::StatusBar(3, false, "");
+  Msg::StatusGl("");
 }
 
 static void general_options_ok_cb(Fl_Widget *w, void *data)
diff --git a/Fltk/popupButton.h b/Fltk/popupButton.h
deleted file mode 100644
index b9966dcea36ed7bfca1be9b9d91c818ed677a6dd..0000000000000000000000000000000000000000
--- a/Fltk/popupButton.h
+++ /dev/null
@@ -1,66 +0,0 @@
-// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
-//
-// See the LICENSE.txt file for license information. Please report all
-// bugs and problems to <gmsh@geuz.org>.
-
-#ifndef _POPUP_BUTTON_H
-#define _POPUP_BUTTON_H
-
-#include <FL/Fl.H>
-#include <FL/Fl_Menu_Button.H>
-
-// This is needed for FLTK < 1.1.8 (popup() in 1.1.7 calls redraw()
-// after picked(), which can cause a crash if the button was deleted
-// by the callback)
-class popupButton : public Fl_Menu_Button {
- public:
-  popupButton(int x, int y, int w, int h, char *label=0) 
-    : Fl_Menu_Button(x, y, w, h, label) {}
-  void draw(){ Fl_Menu_Button::draw(); }
-  int handle(int e)
-  {
-    if (!menu() || !menu()->text) return 0;
-    switch (e) {
-    case FL_ENTER:
-    case FL_LEAVE:
-      return (box() && !type()) ? 1 : 0;
-    case FL_PUSH:
-      if (!box()) {
-        if (Fl::event_button() != 3) return 0;
-      } else if (type()) {
-        if (!(type() & (1 << (Fl::event_button()-1)))) return 0;
-      }
-      if (Fl::visible_focus()) Fl::focus(this);
-      popup();
-      return 1;
-    case FL_KEYBOARD:
-      if (!box()) return 0;
-      if (Fl::event_key() == ' ' &&
-          !(Fl::event_state() & (FL_SHIFT | FL_CTRL | FL_ALT | FL_META))) {
-        popup();
-        return 1;
-      } else return 0;
-    case FL_SHORTCUT:
-      if (Fl_Widget::test_shortcut()) {popup(); return 1;}
-      return test_shortcut() != 0;
-    case FL_FOCUS:
-    case FL_UNFOCUS:
-      if (box() && Fl::visible_focus()) {
-        redraw();
-        return 1;
-      }
-    default:
-      return 0;
-    }
-  }
-  const Fl_Menu_Item* popup()
-  {
-    const Fl_Menu_Item* m;
-    redraw();
-    m = menu()->popup(Fl::event_x(), Fl::event_y(), label(), mvalue(), this);
-    picked(m);
-    return m;
-  }
-};
-
-#endif
diff --git a/Fltk/projectionEditor.cpp b/Fltk/projectionEditor.cpp
index e8d7ba60034d47d4a46c843bf885e9b0923259d0..80c2290a680ec6367ffb2a5865c3bb39cd3d4501 100644
--- a/Fltk/projectionEditor.cpp
+++ b/Fltk/projectionEditor.cpp
@@ -63,10 +63,10 @@ static fourierProjectionFace *createProjectionFaceFromName(const char *name)
 }
 
 static void project_point(FM::ProjectionSurface *ps, double x, double y, double z,
-                          std::vector<double> &u, std::vector<double> &v, 
+                          std::vector<double> &u, std::vector<double> &v,
                           std::vector<double> &dist,
                           std::vector<std::complex<double> > &f)
-{                  
+{
   double uu, vv, p[3], n[3];
   ps->OrthoProjectionOnSurface(x, y, z, uu, vv);
   if(uu >= 0. && uu <= 1. && vv >= 0. && vv <= 1.){
@@ -95,7 +95,7 @@ static void getTangents(const SVector3 n, SVector3 &t1, SVector3 &t2, const doub
   b.normalize();
   double x = n[0], y = n[1], z = n[2];
   double c = cos(angle * M_PI / 180.), s = sin(angle * M_PI / 180.);
-  double rot[3][3] = 
+  double rot[3][3] =
     {{x * x * (1-c) + c    , x * y * (1-c) - z * s, x * z * (1-c) + y * s},
      {y * x * (1-c) + z * s, y * y * (1-c) + c    , y * z * (1-c) - x * s},
      {x * z * (1-c) - y * s, y * z * (1-c) + x * s, z * z * (1-c) + c    }};
@@ -173,7 +173,7 @@ static void browse_cb(Fl_Widget *w, void *data)
     projections[i]->face->setVisibility(false);
     projections[i]->group->hide();
   }
-  
+
   projection *p = e->getCurrentProjection();
   if(p){
     p->face->setVisibility(true);
@@ -282,18 +282,18 @@ static void select_cb(Fl_Widget *w, void *data)
     drawContext::global()->draw();
 
     if(ele.size() || ent.size())
-      Msg::StatusBar(3, false, "Select %s\n[Press 'e' to end selection, 'u' to undo" 
-                  "last selection or 'q' to abort]", str);
+      Msg::StatusGl("Select %s\n[Press 'e' to end selection, 'u' to undo"
+                    "last selection or 'q' to abort]", str);
     else
-      Msg::StatusBar(3, false, "Select %s\n"
-                  "[Press 'e' to end selection or 'q' to abort]", str);
+      Msg::StatusGl("Select %s\n"
+                    "[Press 'e' to end selection or 'q' to abort]", str);
 
     char ib = FlGui::instance()->selectEntity(what);
     if(ib == 'l') {
       if(CTX::instance()->pickElements){
         for(unsigned int i = 0; i < FlGui::instance()->selectedElements.size(); i++){
           if(FlGui::instance()->selectedElements[i]->getVisibility() != 2){
-            FlGui::instance()->selectedElements[i]->setVisibility(2); 
+            FlGui::instance()->selectedElements[i]->setVisibility(2);
             ele.push_back(FlGui::instance()->selectedElements[i]);
           }
         }
@@ -353,8 +353,8 @@ static void select_cb(Fl_Widget *w, void *data)
 
   CTX::instance()->mesh.changed = ENT_ALL;
   CTX::instance()->pickElements = 0;
-  drawContext::global()->draw();  
-  Msg::StatusBar(3, false, "");
+  drawContext::global()->draw();
+  Msg::StatusGl("");
 }
 
 static void filter_cb(Fl_Widget *w, void *data)
@@ -428,7 +428,7 @@ static void save_selection_cb(Fl_Widget *w, void *data)
     for(unsigned int i = 0; i < ent.size(); i++){
       GVertex *gv = dynamic_cast<GVertex*>(ent[i]);
       if(gv && gv->getSelection())
-        fprintf(fp, "Point(%d) = {%.16g,%.16g,%.16g,1};\n", gv->tag(), 
+        fprintf(fp, "Point(%d) = {%.16g,%.16g,%.16g,1};\n", gv->tag(),
                 gv->x(), gv->y(), gv->z());
     }
     std::vector<MElement*> &ele(e->getElements());
@@ -561,8 +561,8 @@ static void compute_cb(Fl_Widget *w, void *data)
     else {
       // create the Fourier faces (with boundaries)
       if(ps->IsUPeriodic()) {
-        FM::Patch* patchL = 
-          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+        FM::Patch* patchL =
+          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
                          uM, vM, h0, h1, h2, h3);
         patchL->SetMinU(-0.35);
         patchL->SetMaxU(0.35);
@@ -570,7 +570,7 @@ static void compute_cb(Fl_Widget *w, void *data)
           AddPatch(patchL);
         m->getFMInternals()->makeGFace(patchL,m);
         //makeGFace(patchL);
-        FM::Patch* patchR = 
+        FM::Patch* patchR =
           new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
                          uM, vM, h0, h1, h2, h3);
         patchR->SetMinU(0.15);
@@ -581,8 +581,8 @@ static void compute_cb(Fl_Widget *w, void *data)
         //makeGFace(patchR);
       }
       else if (ps->IsVPeriodic()) {
-        FM::Patch* patchL = 
-          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+        FM::Patch* patchL =
+          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
                          uM, vM, h0, h1, h2, h3);
         patchL->SetMinV(-0.35);
         patchL->SetMaxV(0.35);
@@ -590,7 +590,7 @@ static void compute_cb(Fl_Widget *w, void *data)
           AddPatch(patchL);
         m->getFMInternals()->makeGFace(patchL,m);
         //makeGFace(patchL);
-        FM::Patch* patchR = 
+        FM::Patch* patchR =
           new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
                          uM, vM, h0, h1, h2, h3);
         patchR->SetMinV(0.15);
@@ -601,8 +601,8 @@ static void compute_cb(Fl_Widget *w, void *data)
         //makeGFace(patchR);
       }
       else {
-        FM::Patch* patch = 
-          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes, 
+        FM::Patch* patch =
+          new FM::FPatch(0, ps->clone(), u, v, f, 3, uModes, vModes,
                          uM, vM, h0, h1, h2, h3);
         m->getFMInternals()->current()->GetGroup(0)->GetBlendGroup()->
           AddPatch(patch);
@@ -665,7 +665,7 @@ static void action_cb(Fl_Widget *w, void *data)
   if(what == "delete_last" || what == "save_last"){
     int id = -1;
     for(GModel::fiter it = m->firstFace(); it != m->lastFace(); it++)
-      if((*it)->getNativeType() == GEntity::FourierModel) 
+      if((*it)->getNativeType() == GEntity::FourierModel)
         id = std::max(id, (*it)->tag());
     if(id > 0) faces.push_back(m->getFaceByTag(id));
   }
@@ -675,16 +675,16 @@ static void action_cb(Fl_Widget *w, void *data)
         faces.push_back(*it);
   }
   else if(what == "delete_select" || what == "save_select"){
-    Msg::StatusBar(3, false, "Select Surface\n[Press 'e' to end selection 'q' to abort]");
+    Msg::StatusGl("Select Surface\n[Press 'e' to end selection 'q' to abort]");
     char ib = FlGui::instance()->selectEntity(ENT_SURFACE);
-    if(ib == 'l') faces.insert(faces.end(), 
-                               FlGui::instance()->selectedFaces.begin(), 
+    if(ib == 'l') faces.insert(faces.end(),
+                               FlGui::instance()->selectedFaces.begin(),
                                FlGui::instance()->selectedFaces.end());
-    Msg::StatusBar(3, false, "");
+    Msg::StatusGl("");
   }
 
   if(what[0] == 'd'){
-    for(unsigned int i = 0; i < faces.size(); i++) 
+    for(unsigned int i = 0; i < faces.size(); i++)
       delete_fourier(faces[i]);
   }
   else{
@@ -702,7 +702,7 @@ static void action_cb(Fl_Widget *w, void *data)
       fclose(fp);
     }
   }
-  
+
   drawContext::global()->draw();
 }
 
@@ -713,10 +713,10 @@ uvPlot::uvPlot(int x, int y, int w, int h, const char *l)
   ColorTable_Recompute(&_colorTable);
 }
 
-void uvPlot::set(std::vector<double> &u, std::vector<double> &v, 
+void uvPlot::set(std::vector<double> &u, std::vector<double> &v,
                  std::vector<double> &dist, std::vector<std::complex<double> > &f)
-{ 
-  _u = u; 
+{
+  _u = u;
   _v = v;
   _dist = dist;
   _f = f;
@@ -787,17 +787,17 @@ void uvPlot::draw()
   fl_draw(max, pw - (int)fl_width(max) - 5, h() - 5);
 }
 
-projection::projection(fourierProjectionFace *f, int x, int y, int w, int h, 
-                       int bb, int bh, projectionEditor *e) 
+projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
+                       int bb, int bh, projectionEditor *e)
   : face(f)
 {
   group = new Fl_Scroll(x, y, w, h);
   SBoundingBox3d bounds = GModel::current()->bounds();
   FM::ProjectionSurface *ps = (FM::ProjectionSurface*)f->getNativePtr();
-  
+
   Fl_Toggle_Button *b = new Fl_Toggle_Button(x, y, bb, bh, "Set position");
   b->callback(set_position_cb, e);
-  
+
   { // origin is stored in parameters[0,1,2]
     SPoint3 pc = bounds.center();
     for(int i = 0; i < 3; i++){
@@ -812,9 +812,9 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
     ps->SetOrigin(pc[0], pc[1], pc[2]);
     Fl_Repeat_Button *bm[3], *bp[3];
     for(int i = 0; i < 3; i++){
-      new Fl_Box(x + w - bb / 3 - bb / 6, y + (1 + i) * bh, bb / 8, bh, 
+      new Fl_Box(x + w - bb / 3 - bb / 6, y + (1 + i) * bh, bb / 8, bh,
                  (i == 0) ? "E0" : (i == 1) ? "E1" : "E2");
-      bp[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh, 
+      bp[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh,
                                    bb / 8, bh / 2, "+");
       bm[i] = new Fl_Repeat_Button(x + w - bb / 3, y + (1 + i) * bh + bh / 2,
                                    bb / 8, bh / 2, "-");
@@ -881,24 +881,24 @@ projection::projection(fourierProjectionFace *f, int x, int y, int w, int h,
   group->hide();
 }
 
-projectionEditor::projectionEditor() 
+projectionEditor::projectionEditor()
 {
   GModel *m = GModel::current();
 
-  // construct FM_Internals 
+  // construct FM_Internals
   m->readFourier();
   printf("readerSize = %d\n",m->getFMInternals()->getSize());
   printf("currentSize = %d\n",m->getFMInternals()->current()->GetNumGroups());
 
   // construct GUI in terms of standard sizes
   const int width = (int)(3.75 * BB), height = 24 * BH;
-  
+
   // create all widgets (we construct this once, we never deallocate!)
   _window = new paletteWindow
     (width, height, CTX::instance()->nonModalWindows ? true : false, "Reparameterize");
-  
+
   new Fl_Box(WB, WB + BH / 2, BB / 2, BH, "Select:");
-  
+
   Fl_Group *o = new Fl_Group(WB, WB, 2 * BB, 3 * BH);
   _select[0] = new Fl_Round_Button(2 * WB + BB / 2, WB, BB, BH, "Points");
   _select[1] = new Fl_Round_Button(2 * WB + BB / 2, WB + BH, BB, BH, "Elements");
@@ -912,7 +912,7 @@ projectionEditor::projectionEditor()
   }
   o->end();
 
-  {  
+  {
     Fl_Toggle_Button *b1 = new Fl_Toggle_Button
       (width - WB - 3 * BB / 2, WB, 3 * BB / 2, BH, "Hide unselected");
     b1->callback(proj_hide_cb);
@@ -944,13 +944,13 @@ projectionEditor::projectionEditor()
   int uvw = width - 2 * WB - 2 * hard - 3 * WB;
   int uvh = height - 7 * WB - 14 * BH - 2 * hard;
 
-  _hardEdges[0] = new Fl_Toggle_Button(WB, 3 * WB + 9 * BH + hard, 
+  _hardEdges[0] = new Fl_Toggle_Button(WB, 3 * WB + 9 * BH + hard,
                                        hard, uvh);
   _hardEdges[1] = new Fl_Toggle_Button(width - 4 * WB - hard, 3 * WB + 9 * BH + hard,
                                        hard, uvh);
-  _hardEdges[2] = new Fl_Toggle_Button(WB + hard, 3 * WB + 9 * BH, 
+  _hardEdges[2] = new Fl_Toggle_Button(WB + hard, 3 * WB + 9 * BH,
                                        uvw, hard);
-  _hardEdges[3] = new Fl_Toggle_Button(WB + hard, height - 4 * WB - 5 * BH - hard, 
+  _hardEdges[3] = new Fl_Toggle_Button(WB + hard, height - 4 * WB - 5 * BH - hard,
                                        uvw, hard);
   for(int i = 0; i < 4; i++)
     _hardEdges[i]->tooltip("Push to mark edge as `hard'");
@@ -965,7 +965,7 @@ projectionEditor::projectionEditor()
   _slider->callback(filter_cb, this);
   _slider->tooltip("Filter selection by distance to projection surface");
 
-  _orientation = new Fl_Toggle_Button(width - 3 * WB, height - 4 * WB - 5 * BH - hard, 
+  _orientation = new Fl_Toggle_Button(width - 3 * WB, height - 4 * WB - 5 * BH - hard,
                                       2 * WB, hard);
   _orientation->callback(filter_cb, this);
   _orientation->tooltip("Filter elements using orientation");
@@ -986,12 +986,12 @@ projectionEditor::projectionEditor()
 
   _modes[0] = new Fl_Value_Input(WB, height - 3 * WB - 4 * BH, BB  / 2, BH);
   _modes[0]->tooltip("Number of Fourier modes along u");
-  _modes[1] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 4 * BH, BB  / 2, BH, 
+  _modes[1] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 4 * BH, BB  / 2, BH,
                                  "Fourier modes");
   _modes[1]->tooltip("Number of Fourier modes along v");
   _modes[2] = new Fl_Value_Input(WB, height - 3 * WB - 3 * BH, BB  / 2, BH);
   _modes[2]->tooltip("Number of Chebyshev modes along u");
-  _modes[3] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 3 * BH, BB  / 2, BH, 
+  _modes[3] = new Fl_Value_Input(WB + BB / 2, height - 3 * WB - 3 * BH, BB  / 2, BH,
                                  "Chebyshev modes");
   _modes[3]->tooltip("Number of Chebyshev modes along v");
   for(int i = 0; i < 4; i++){
@@ -1000,10 +1000,10 @@ projectionEditor::projectionEditor()
     _modes[i]->minimum(1);
     _modes[i]->step(1);
     _modes[i]->align(FL_ALIGN_RIGHT);
-  }    
+  }
 
   {
-    Fl_Button *b = new Fl_Button(width - WB - BB, height - 3 * WB - 4 * BH, 
+    Fl_Button *b = new Fl_Button(width - WB - BB, height - 3 * WB - 4 * BH,
                                   BB, 2 * BH, "Generate\nPatch");
     b->callback(compute_cb, this);
   }
@@ -1011,7 +1011,7 @@ projectionEditor::projectionEditor()
   {
     int bb = (int)(0.37 * BB);
     new Fl_Box(WB, height - 2 * WB - 2 * BH, BB / 2, BH, "Delete:");
-    Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 2 * WB - 2 * BH, 
+    Fl_Button *b1 = new Fl_Button(WB + BB / 2, height - 2 * WB - 2 * BH,
                                   bb, BH, "last");
     b1->callback(action_cb, (void*)"delete_last");
     Fl_Button *b2 = new Fl_Button(WB + BB / 2 + bb, height - 2 * WB - 2 * BH,
@@ -1038,11 +1038,11 @@ projectionEditor::projectionEditor()
   }
 
   {
-    Fl_Button *b1 = new Fl_Button(WB, height - WB - BH, BB, BH, 
+    Fl_Button *b1 = new Fl_Button(WB, height - WB - BH, BB, BH,
                                   "Blend");
     b1->callback(blend_cb, this);
-    
-    //Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - WB - BH, BB, 
+
+    //Fl_Button *b2 = new Fl_Button(2 * WB + BB, height - WB - BH, BB,
     //                            BH, "Intersect");
   }
 
@@ -1063,13 +1063,13 @@ void projectionEditor::load(fourierProjectionFace *face, std::string tag)
 }
 
 void projectionEditor::show()
-{ 
-  _window->show(); 
-  select_cb(0, this); 
+{
+  _window->show();
+  select_cb(0, this);
 }
 
-int projectionEditor::getSelectionMode() 
-{ 
+int projectionEditor::getSelectionMode()
+{
   if(_select[0]->value())
     return ENT_POINT;
   else
diff --git a/Fltk/viewButton.cpp b/Fltk/viewButton.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..47ced27f049776f945ee585fb37f8cf6d2cd48a6
--- /dev/null
+++ b/Fltk/viewButton.cpp
@@ -0,0 +1,335 @@
+// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#include <FL/fl_ask.H>
+#include "FlGui.h"
+#include "drawContext.h"
+#include "fileDialogs.h"
+#include "optionWindow.h"
+#include "pluginWindow.h"
+#include "Context.h"
+#include "GModel.h"
+#include "PView.h"
+#include "PViewData.h"
+#include "PViewOptions.h"
+#include "Options.h"
+#include "OpenFile.h"
+#include "Field.h"
+#include "OS.h"
+#include "onelabGroup.h"
+#include "viewButton.h"
+
+static void view_toggle_cb(Fl_Widget *w, void *data)
+{
+  int num = (intptr_t)data;
+  viewButton *but = FlGui::instance()->onelab->getViewButton(num);
+  if(but){
+    opt_view_visible(num, GMSH_SET, but->value());
+    drawContext::global()->draw();
+  }
+}
+
+static void view_reload(int index)
+{
+  if(index >= 0 && index < (int)PView::list.size()){
+    PView *p = PView::list[index];
+
+    if(StatFile(p->getData()->getFileName())){
+      Msg::Error("File '%s' does not exist", p->getData()->getFileName().c_str());
+      return;
+    }
+
+    int n = PView::list.size();
+
+    // FIXME: use fileIndex
+    MergeFile(p->getData()->getFileName());
+
+    if((int)PView::list.size() > n){ // we loaded a new view
+      // delete old data and replace with new
+      delete p->getData();
+      p->setData(PView::list.back()->getData());
+      PView::list.back()->setData(0);
+      // delete new view
+      delete PView::list.back();
+      // in case the reloaded view has a different number of time steps
+      if(p->getOptions()->timeStep > p->getData()->getNumTimeSteps() - 1)
+        p->getOptions()->timeStep = 0;
+      p->setChanged(true);
+      FlGui::instance()->updateViews();
+    }
+  }
+}
+
+static void view_reload_cb(Fl_Widget *w, void *data)
+{
+  view_reload((intptr_t)data);
+  drawContext::global()->draw();
+}
+
+static void view_reload_all_cb(Fl_Widget *w, void *data)
+{
+  for(unsigned int i = 0; i < PView::list.size(); i++)
+    view_reload(i);
+  drawContext::global()->draw();
+}
+
+static void view_reload_visible_cb(Fl_Widget *w, void *data)
+{
+  for(unsigned int i = 0; i < PView::list.size(); i++)
+    if(opt_view_visible(i, GMSH_GET, 0))
+      view_reload(i);
+  drawContext::global()->draw();
+}
+
+static void view_remove_other_cb(Fl_Widget *w, void *data)
+{
+  if(PView::list.empty()) return;
+  for(int i = PView::list.size() - 1; i >= 0; i--)
+    if(i != (intptr_t)data) delete PView::list[i];
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_remove_all_cb(Fl_Widget *w, void *data)
+{
+  if(PView::list.empty()) return;
+  int mode = (intptr_t)data;
+  if(mode == -1){ // remove all
+    if(PView::list.empty()) return;
+    while(PView::list.size()) delete PView::list[0];
+  }
+  else if(mode == -2){ // remove all visible
+    for(int i = PView::list.size() - 1; i >= 0; i--)
+      if(opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i];
+  }
+  else if(mode == -3){ // remove all invisible
+    for(int i = PView::list.size() - 1; i >= 0; i--)
+      if(!opt_view_visible(i, GMSH_GET, 0)) delete PView::list[i];
+  }
+  else if(mode == -4){ // remove all empty
+    for(int i = PView::list.size() - 1; i >= 0; i--)
+      if(PView::list[i]->getData()->empty()) delete PView::list[i];
+  }
+  else if(mode >=0 && mode < (int)PView::list.size()){ // remove by name
+    std::string name = PView::list[mode]->getData()->getName();
+    for(int i = PView::list.size() - 1; i >= 0; i--)
+      if(PView::list[i]->getData()->getName() == name) delete PView::list[i];
+  }
+
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_remove_cb(Fl_Widget *w, void *data)
+{
+  delete PView::list[(intptr_t)data];
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+#if defined(HAVE_NATIVE_FILE_CHOOSER)
+#  define TT "\t"
+#  define NN "\n"
+#else
+#  define TT " ("
+#  define NN ")\t"
+#endif
+
+static void view_save_cb(Fl_Widget *w, void *data)
+{
+  static const char *formats =
+    "Gmsh Parsed" TT "*.pos" NN
+    "Gmsh Mesh-based" TT "*.pos" NN
+    "Gmsh Legacy ASCII" TT "*.pos" NN
+    "Gmsh Legacy Binary" TT "*.pos" NN
+    "MED" TT "*.rmed" NN
+    "STL Surface" TT "*.stl" NN
+    "Generic TXT" TT "*.txt" NN;
+
+  PView *view = PView::list[(intptr_t)data];
+ test:
+  if(fileChooser(FILE_CHOOSER_CREATE, "Save As", formats,
+                 view->getData()->getFileName().c_str())){
+    std::string name = fileChooserGetName(1);
+    if(CTX::instance()->confirmOverwrite) {
+      if(!StatFile(name))
+        if(!fl_choice("File '%s' already exists.\n\nDo you want to replace it?",
+                      "Cancel", "Replace", 0, name.c_str()))
+          goto test;
+    }
+    int format = 0;
+    switch(fileChooserGetFilter()){
+    case 0: format = 2; break;
+    case 1: format = 5; break;
+    case 2: format = 0; break;
+    case 3: format = 1; break;
+    case 4: format = 6; break;
+    case 5: format = 3; break;
+    case 6: format = 4; break;
+    }
+    view->write(name, format);
+  }
+}
+
+#undef TT
+#undef NN
+
+static void view_alias_cb(Fl_Widget *w, void *data)
+{
+  new PView(PView::list[(intptr_t)data], false);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_alias_with_options_cb(Fl_Widget *w, void *data)
+{
+  new PView(PView::list[(intptr_t)data], true);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_combine_space_all_cb(Fl_Widget *w, void *data)
+{
+  PView::combine(false, 1, CTX::instance()->post.combineRemoveOrig);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_combine_space_visible_cb(Fl_Widget *w, void *data)
+{
+  PView::combine(false, 0, CTX::instance()->post.combineRemoveOrig);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_combine_space_by_name_cb(Fl_Widget *w, void *data)
+{
+  PView::combine(false, 2, CTX::instance()->post.combineRemoveOrig);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_combine_time_all_cb(Fl_Widget *w, void *data)
+{
+  PView::combine(true, 1, CTX::instance()->post.combineRemoveOrig);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_combine_time_visible_cb(Fl_Widget *w, void *data)
+{
+  PView::combine(true, 0, CTX::instance()->post.combineRemoveOrig);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_combine_time_by_name_cb(Fl_Widget *w, void *data)
+{
+  PView::combine(true, 2, CTX::instance()->post.combineRemoveOrig);
+  FlGui::instance()->updateViews();
+  drawContext::global()->draw();
+}
+
+static void view_all_visible_cb(Fl_Widget *w, void *data)
+{
+  int mode = (intptr_t)data;
+  std::string name;
+  if(mode >= 0) name = PView::list[mode]->getData()->getName();
+  for(unsigned int i = 0; i < PView::list.size(); i++)
+    opt_view_visible(i, GMSH_SET | GMSH_GUI,
+                     (mode == -1) ? 1 :
+                     (mode == -2) ? 0 :
+                     (mode == -3) ? !opt_view_visible(i, GMSH_GET, 0) :
+                     (name == PView::list[i]->getData()->getName()) ? 1 :
+                     0);
+  drawContext::global()->draw();
+}
+
+static void view_applybgmesh_cb(Fl_Widget *w, void *data)
+{
+  int index =  (intptr_t)data;
+  if(index >= 0 && index < (int)PView::list.size())
+    GModel::current()->getFields()->setBackgroundMesh(index);
+}
+
+viewButton::viewButton(int x, int y, int w, int h, int num)
+  : Fl_Group(x,y,w,h)
+{
+  int popw = 4 * FL_NORMAL_SIZE + 3;
+
+  PView *view = PView::list[num];
+  PViewData *data = view->getData();
+  PViewOptions *opt = view->getOptions();
+
+  _toggle = new Fl_Light_Button(x, y, w - popw, h);
+  _toggle->callback(view_toggle_cb, (void *)num);
+  _toggle->align(FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  _toggle->value(opt->visible);
+  _toggle->copy_label(data->getName().c_str());
+  strcpy(_tooltip, data->getFileName().c_str());
+  _toggle->tooltip(_tooltip);
+  sprintf(_arrow, "[%d]@#-1>", num);
+  _butt = new Fl_Button(x + w - popw, y, popw, h, _arrow);
+  _butt->align(FL_ALIGN_RIGHT | FL_ALIGN_INSIDE | FL_ALIGN_CLIP);
+  _butt->tooltip("Show view option menu (Shift+w)");
+
+  _popup = new Fl_Menu_Button(x + w - popw, y, popw, h);
+  _popup->type(Fl_Menu_Button::POPUP123);
+  _popup->add("Reload/View", 'r',
+              (Fl_Callback *) view_reload_cb, (void *)num, 0);
+  _popup->add("Reload/Visible Views", 0,
+              (Fl_Callback *) view_reload_visible_cb, (void *)num, 0);
+  _popup->add("Reload/All Views", 0,
+              (Fl_Callback *) view_reload_all_cb, (void *)num, 0);
+  _popup->add("Remove/View", FL_Delete,
+              (Fl_Callback *) view_remove_cb, (void *)num, 0);
+  _popup->add("Remove/Other Views", 0,
+              (Fl_Callback *) view_remove_other_cb, (void *)num, 0);
+  _popup->add("Remove/Visible Views", 0,
+              (Fl_Callback *) view_remove_all_cb, (void *)-2, 0);
+  _popup->add("Remove/Invisible Views", 0,
+              (Fl_Callback *) view_remove_all_cb, (void *)-3, 0);
+  _popup->add("Remove/Empty Views", 0,
+              (Fl_Callback *) view_remove_all_cb, (void *)-4, 0);
+  _popup->add("Remove/All Views", 0,
+              (Fl_Callback *) view_remove_all_cb, (void *)-1, 0);
+  _popup->add("Remove/By Name", 0,
+              (Fl_Callback *) view_remove_all_cb, (void *)num, 0);
+  _popup->add("Alias/View without Options", 0,
+              (Fl_Callback *) view_alias_cb, (void *)num, 0);
+  _popup->add("Alias/View with Options", 0,
+              (Fl_Callback *) view_alias_with_options_cb, (void *)num, 0);
+  _popup->add("Combine Elements/From Visible Views", 0,
+              (Fl_Callback *) view_combine_space_visible_cb, (void *)num, 0);
+  _popup->add("Combine Elements/From All Views", 0,
+              (Fl_Callback *) view_combine_space_all_cb, (void *)num, 0);
+  _popup->add("Combine Elements/By View Name", 0,
+              (Fl_Callback *) view_combine_space_by_name_cb, (void *)num, 0);
+  _popup->add("Combine Time Steps/From Visible Views", 0,
+              (Fl_Callback *) view_combine_time_visible_cb, (void *)num, 0);
+  _popup->add("Combine Time Steps/From All Views", 0,
+              (Fl_Callback *) view_combine_time_all_cb, (void *)num, 0);
+  _popup->add("Combine Time Steps/By View Name", 0,
+              (Fl_Callback *) view_combine_time_by_name_cb, (void *)num, 0);
+  _popup->add("Set Visibility/All On", 0,
+              (Fl_Callback *) view_all_visible_cb, (void *)-1, 0);
+  _popup->add("Set Visibility/All Off", 0,
+              (Fl_Callback *) view_all_visible_cb, (void *)-2, 0);
+  _popup->add("Set Visibility/Invert", 0,
+              (Fl_Callback *) view_all_visible_cb, (void *)-3, 0);
+  _popup->add("Set Visibility/By name", 0,
+              (Fl_Callback *) view_all_visible_cb, (void *)num, 0);
+  _popup->add("Apply As Background Mesh", 0,
+              (Fl_Callback *) view_applybgmesh_cb, (void *)num, 0);
+  _popup->add("Save As...", 0,
+              (Fl_Callback *) view_save_cb, (void *)num, FL_MENU_DIVIDER);
+  _popup->add("Options", 'o',
+              (Fl_Callback *) view_options_cb, (void *)num, 0);
+  _popup->add("Plugins", 'p',
+              (Fl_Callback *) plugin_cb, (void *)num, 0);
+
+  end(); // close the group
+  resizable(_toggle);
+}
diff --git a/Fltk/viewButton.h b/Fltk/viewButton.h
new file mode 100644
index 0000000000000000000000000000000000000000..cf97751d4f7efccdb943a17dd56ff0720e5df8ae
--- /dev/null
+++ b/Fltk/viewButton.h
@@ -0,0 +1,29 @@
+// Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
+//
+// See the LICENSE.txt file for license information. Please report all
+// bugs and problems to <gmsh@geuz.org>.
+
+#ifndef _VIEW_BUTTON_H_
+#define _VIEW_BUTTON_H_
+
+#include <string>
+#include <FL/Fl.H>
+#include <FL/Fl_Group.H>
+#include <FL/Fl_Light_Button.H>
+#include <FL/Fl_Menu_Button.H>
+
+class viewButton : public Fl_Group {
+ private:
+  Fl_Light_Button *_toggle;
+  Fl_Button *_butt;
+  Fl_Menu_Button *_popup;
+  char _tooltip[256], _arrow[32];
+ public:
+  viewButton(int x, int y, int w, int h, int num);
+  double value() { return _toggle->value(); }
+  void value(double val) { _toggle->value(val); }
+  void copy_label(const std::string &label){ _toggle->copy_label(label.c_str()); }
+  std::string label(){ return _toggle->label(); }
+};
+
+#endif
diff --git a/Fltk/visibilityWindow.cpp b/Fltk/visibilityWindow.cpp
index 3226f62c9678ca4d378c745b280b1445092ada70..39283851f3426372ab49d76ed66c2076a9d0f0cf 100644
--- a/Fltk/visibilityWindow.cpp
+++ b/Fltk/visibilityWindow.cpp
@@ -466,8 +466,6 @@ class listBrowser : public Fl_Browser{
     : Fl_Browser(x, y, w, h, c){}
 };
 
-#if defined(HAVE_FL_TREE)
-
 static void _add_vertex(GVertex *gv, Fl_Tree *tree, std::string path)
 {
   std::ostringstream vertex;
@@ -730,8 +728,6 @@ class treeBrowser : public Fl_Tree{
     : Fl_Tree(x, y, w, h, c){}
 };
 
-#endif
-
 void visibility_cb(Fl_Widget *w, void *data)
 {
   // get the visibility info from the model, and update the browser
@@ -743,15 +739,13 @@ void visibility_cb(Fl_Widget *w, void *data)
     FlGui::instance()->visibility->show(false);
 
   _rebuild_list_browser();
-#if defined(HAVE_FL_TREE)
   _rebuild_tree_browser(false);
-#endif
   FlGui::instance()->visibility->updatePerWindow(true);
 }
 
 static void visibility_save_cb(Fl_Widget *w, void *data)
 {
-  Msg::StatusBar(2, true, "Appending visibility info to '%s'...",
+  Msg::StatusBar(true, "Appending visibility info to '%s'...",
                  GModel::current()->getFileName().c_str());
   // get the whole visibility information in geo format
   std::vector<int> state[4][2];
@@ -803,7 +797,7 @@ static void visibility_save_cb(Fl_Widget *w, void *data)
   }
   str += "}\n";
   add_infile(str, GModel::current()->getFileName());
-  Msg::StatusBar(2, true, "Done appending visibility info");
+  Msg::StatusBar(true, "Done appending visibility info");
 }
 
 static void _set_visibility_by_number(int what, int num, char val, bool recursive,
@@ -1063,8 +1057,8 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data)
     if(what == ENT_ALL)
       CTX::instance()->mesh.changed = ENT_ALL;
     drawContext::global()->draw();
-    Msg::StatusBar(3, false, "Select %s\n[Press %s'q' to abort]",
-                   str.c_str(), mode ? "" : "'u' to undo or ");
+    Msg::StatusGl("Select %s\n[Press %s'q' to abort]",
+                  str.c_str(), mode ? "" : "'u' to undo or ");
 
     char ib = FlGui::instance()->selectEntity(what);
     if(ib == 'l') {
@@ -1087,7 +1081,7 @@ static void visibility_interactive_cb(Fl_Widget *w, void *data)
   CTX::instance()->mesh.changed = ENT_ALL;
   CTX::instance()->pickElements = 0;
   drawContext::global()->draw();
-  Msg::StatusBar(3, false, "");
+  Msg::StatusGl("");
 }
 
 static void visibility_per_window_cb(Fl_Widget *w, void *data)
@@ -1220,7 +1214,6 @@ visibilityWindow::visibilityWindow(int deltaFontSize)
     g->end();
     Fl_Group::current()->resizable(g);
   }
-#if defined(HAVE_FL_TREE)
   {
     Fl_Group *g = new Fl_Group
       (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Tree browser");
@@ -1245,7 +1238,6 @@ visibilityWindow::visibilityWindow(int deltaFontSize)
     g->resizable(tree);
     g->end();
   }
-#endif
   {
     Fl_Group *g = new Fl_Group
       (WB, WB + BH, width - 2 * WB, height - 3 * WB - 2 * BH, "Numeric");
diff --git a/Fltk/visibilityWindow.h b/Fltk/visibilityWindow.h
index bcc1823caab469a649a4c665511c9f88014ae1b7..a282df49a00486deace7044b37b0b605cb932efe 100644
--- a/Fltk/visibilityWindow.h
+++ b/Fltk/visibilityWindow.h
@@ -13,11 +13,7 @@
 #include <FL/Fl_Button.H>
 #include <FL/Fl_Check_Button.H>
 #include <FL/Fl_Input.H>
-#include "GmshConfig.h"
-
-#if defined(HAVE_FL_TREE)
-#include "FL/Fl_Tree.H"
-#endif
+#include <FL/Fl_Tree.H>
 
 class visibilityWindow{
  public:
@@ -25,10 +21,8 @@ class visibilityWindow{
   Fl_Choice *browser_type;
   Fl_Browser *browser;
   Fl_Multi_Browser *per_window;
-#if defined(HAVE_FL_TREE)
   Fl_Tree *tree;
   Fl_Button *tree_create;
-#endif
   Fl_Check_Button *butt[2];
   Fl_Button *push[2];
   Fl_Input *input[10];
diff --git a/Geo/Curvature.cpp b/Geo/Curvature.cpp
index bdde3e6642c79a554ccb11a3732432c63de9470f..9605fda053817dd3c0101051e23a58d154cdafa5 100644
--- a/Geo/Curvature.cpp
+++ b/Geo/Curvature.cpp
@@ -621,7 +621,7 @@ void Curvature::computeRusinkiewiczNormals()
       // Pointer to one element
       MElement *e = face->getMeshElement(iElem);
       const int E = _ElementToInt[e->getNum()];
-    
+
       // Pointers to vertices of triangle
       MVertex* A = e->getVertex(0);
       MVertex* B = e->getVertex(1);
@@ -865,7 +865,7 @@ void Curvature::computeCurvature(GModel* model, typeOfCurvature typ)
   _model = model;
 
   double t0 = Cpu();
-  Msg::StatusBar(2, true, "(C) Computing Curvature");
+  Msg::StatusBar(true, "(C) Computing Curvature");
   if (typ == RUSIN)
     computeCurvature_Rusinkiewicz(0);
   else if (typ == RBF)
@@ -874,7 +874,7 @@ void Curvature::computeCurvature(GModel* model, typeOfCurvature typ)
     computeCurvature_Simple();
 
   double t1 = Cpu();
-  Msg::StatusBar(2, true, "(C) Done Computing Curvature (%g s)", t1-t0);
+  Msg::StatusBar(true, "(C) Done Computing Curvature (%g s)", t1-t0);
 
   //writeToMshFile("curvature.msh");
   writeToPosFile("curvature.pos");
@@ -1233,7 +1233,7 @@ void Curvature::computeCurvature_RBF()
 {
   retrieveCompounds();
   initializeMap();
-  
+
   //fill set of MVertex
   std::set<MVertex*> allNodes;
   for (unsigned int i = 0; i< _EntityArray.size(); ++i)  {
@@ -1261,10 +1261,10 @@ void Curvature::computeCurvature_RBF()
   std::vector<MVertex*> _ordered;
   std::map<MVertex*, double> curvRBF;
   //GLOBAL
-  //GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered); 
+  //GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered);
   //_rbf->computeCurvature(_rbf->getXYZ(),curvRBF);
   //LOCAL FD
-  GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered, true); 
+  GRbf *_rbf = new GRbf(sizeBox, 0, 1, _normals, allNodes, _ordered, true);
   _rbf->computeLocalCurvature(_rbf->getXYZ(),curvRBF);
 
   //fill vertex curve
@@ -1300,17 +1300,17 @@ void Curvature::triangleNodalValues(MTriangle* triangle, double& c0, double& c1,
     if ( vertexIterator != _VertexToInt.end() )  V0 = (*vertexIterator).second;
     else
       std::cout << "Didn't find vertex with number " << A->getNum() << " in _VertextToInt !" << std::endl;
-    
+
     vertexIterator = _VertexToInt.find( B->getNum() );
     if ( vertexIterator != _VertexToInt.end() )   V1 = (*vertexIterator).second;
     else
       std::cout << "Didn't find vertex with number " << B->getNum() << " in _VertextToInt !" << std::endl;
-    
+
     vertexIterator = _VertexToInt.find( C->getNum() );
     if ( vertexIterator != _VertexToInt.end() )  V2 = (*vertexIterator).second;
     else
       std::cout << "Didn't find vertex with number " << C->getNum() << " in _VertextToInt !" << std::endl;
-    
+
     if (isAbs){
       c0 = std::abs(_VertexCurve[V0]); //Mean curvature in vertex 0
       c1 = std::abs(_VertexCurve[V1]); //Mean curvature in vertex 1
@@ -1405,11 +1405,11 @@ void Curvature::edgeNodalValues(MLine* edge, double& c0, double& c1, int isAbs)
      vertexIterator = _VertexToInt.find( A->getNum() );
      if ( vertexIterator != _VertexToInt.end() )  V0 = (*vertexIterator).second;
      else  std::cout << "Didn't find vertex with number " << A->getNum() << " in _VertextToInt !" << std::endl;
-     
+
      vertexIterator = _VertexToInt.find( B->getNum() );
      if ( vertexIterator != _VertexToInt.end() ) V1 = (*vertexIterator).second;
      else std::cout << "Didn't find vertex with number " << B->getNum() << " in _VertextToInt !" << std::endl;
-     
+
      if (isAbs){
        c0 = std::abs(_VertexCurve[V0]); //Mean curvature in vertex 0
        c1 = std::abs(_VertexCurve[V1]); //Mean curvature in vertex 1
@@ -1484,8 +1484,8 @@ void Curvature::vertexNodalValues(MVertex* A, double& c0, int isAbs)
      vertexIterator = _VertexToInt.find( A->getNum() );
      if ( vertexIterator != _VertexToInt.end() )  V0 = (*vertexIterator).second;
      else  std::cout << "Didn't find vertex with number " << A->getNum() << " in _VertextToInt !" << std::endl;
- 
-     
+
+
      if (isAbs){
        c0 = std::abs(_VertexCurve[V0]); //Mean curvature in vertex 0
       }
@@ -1497,9 +1497,9 @@ void Curvature::vertexNodalValues(MVertex* A, double& c0, int isAbs)
 
 void Curvature::vertexNodalValuesAndDirections(MVertex *A, SVector3* dMax, SVector3* dMin, double* cMax, double* cMin, int isAbs)
 {
-   
+
     int V0 = 0;
-   
+
     std::map<int,int>::iterator vertexIterator;
     vertexIterator = _VertexToInt.find( A->getNum() );
     if ( vertexIterator != _VertexToInt.end() )  V0 = (*vertexIterator).second;
@@ -1675,8 +1675,8 @@ void Curvature::writeToPosFile( const std::string & filename)
     GFace* face = _EntityArray[i];
 
     for (unsigned iElem = 0; iElem < face->getNumMeshElements(); iElem++){
-      MElement *e = face->getMeshElement(iElem);  
-      //const int E = _ElementToInt[e->getNum()]; 
+      MElement *e = face->getMeshElement(iElem);
+      //const int E = _ElementToInt[e->getNum()];
       //std::cout << "We are now looking at element Nr: " << E << std::endl;
 
       MVertex* A = e->getVertex(0);  //Pointers to vertices of triangle
@@ -1712,7 +1712,7 @@ void Curvature::writeToPosFile( const std::string & filename)
       idxelem++;
 
   } //Loop over elements
- 
+
 } // Loop over ptFinalEntityList
 
 outfile << "};" << std::endl;
diff --git a/Geo/GModel.cpp b/Geo/GModel.cpp
index 28231946bfffca78d85056541b91d12982d953a2..544f4b702f7c964794c4f4a4a8892ebdbe17c8b1 100644
--- a/Geo/GModel.cpp
+++ b/Geo/GModel.cpp
@@ -1416,7 +1416,7 @@ void GModel::checkMeshCoherence(double tolerance)
   int numEle = getNumMeshElements();
   if(!numEle) return;
 
-  Msg::StatusBar(2, true, "Checking mesh coherence (%d elements)...", numEle);
+  Msg::StatusBar(true, "Checking mesh coherence (%d elements)...", numEle);
 
   SBoundingBox3d bbox = bounds();
   double lc = bbox.empty() ? 1. : norm(SVector3(bbox.max(), bbox.min()));
@@ -1469,12 +1469,12 @@ void GModel::checkMeshCoherence(double tolerance)
     if(num) Msg::Error("%d duplicate element%s", num, num > 1 ? "s" : "");
   }
 
-  Msg::StatusBar(2, true, "Done checking mesh coherence");
+  Msg::StatusBar(true, "Done checking mesh coherence");
 }
 
 int GModel::removeDuplicateMeshVertices(double tolerance)
 {
-  Msg::StatusBar(2, true, "Removing duplicate mesh vertices...");
+  Msg::StatusBar(true, "Removing duplicate mesh vertices...");
 
   SBoundingBox3d bbox = bounds();
   double lc = bbox.empty() ? 1. : norm(SVector3(bbox.max(), bbox.min()));
@@ -1546,7 +1546,7 @@ int GModel::removeDuplicateMeshVertices(double tolerance)
   if(num)
     Msg::Info("Removed %d duplicate mesh %s", num, num > 1 ? "vertices" : "vertex");
 
-  Msg::StatusBar(2, true, "Done removing duplicate mesh vertices");
+  Msg::StatusBar(true, "Done removing duplicate mesh vertices");
   return num;
 }
 
@@ -1817,7 +1817,7 @@ void GModel::makeDiscreteFacesSimplyConnected()
 
 void GModel::createTopologyFromMesh(int ignoreHoles)
 {
-  Msg::StatusBar(2, true, "Creating topology from mesh...");
+  Msg::StatusBar(true, "Creating topology from mesh...");
   double t1 = Cpu();
 
   removeDuplicateMeshVertices(CTX::instance()->geom.tolerance);
@@ -1842,7 +1842,7 @@ void GModel::createTopologyFromMesh(int ignoreHoles)
   exportDiscreteGEOInternals();
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done creating topology from mesh (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done creating topology from mesh (%g s)", t2 - t1);
 }
 
 void GModel::createTopologyFromRegions(std::vector<discreteRegion*> &discRegions)
diff --git a/Geo/Homology.cpp b/Geo/Homology.cpp
index 057a128c411fabcb00bec423a9f7517ee056f403..19c943ac721d9f0420b7bcf24b399d3895b44c3f 100644
--- a/Geo/Homology.cpp
+++ b/Geo/Homology.cpp
@@ -86,7 +86,7 @@ void Homology::_getElements(const std::vector<GEntity*>& entities,
 
 void Homology::_createCellComplex()
 {
-  Msg::StatusBar(2, true, "Creating cell complex...");
+  Msg::StatusBar(true, "Creating cell complex...");
   double t1 = Cpu();
 
   if(_domainEntities.empty()) Msg::Error("Domain is empty");
@@ -117,7 +117,7 @@ void Homology::_createCellComplex()
     Msg::Error("Cell Complex is empty: check the domain and the mesh");
   }
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done creating cell complex (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done creating cell complex (%g s)", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges, and %d vertices",
             _cellComplex->getSize(3), _cellComplex->getSize(2),
 	    _cellComplex->getSize(1), _cellComplex->getSize(0));
@@ -174,7 +174,7 @@ void Homology::findHomologyBasis(std::vector<int> dim)
 {
   if(_cellComplex == NULL) _createCellComplex();
   if(_cellComplex->isReduced()) _cellComplex->restoreComplex();
-  Msg::StatusBar(2, true, "Reducing cell complex...");
+  Msg::StatusBar(true, "Reducing cell complex...");
 
   double t1 = Cpu();
   int omitted = _cellComplex->reduceComplex(_combine, _omit);
@@ -188,17 +188,17 @@ void Homology::findHomologyBasis(std::vector<int> dim)
   }
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done reducing cell complex (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done reducing cell complex (%g s)", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges, and %d vertices",
             _cellComplex->getSize(3), _cellComplex->getSize(2),
 	    _cellComplex->getSize(1), _cellComplex->getSize(0));
 
-  Msg::StatusBar(2, true, "Computing homology space bases ...");
+  Msg::StatusBar(true, "Computing homology space bases ...");
   t1 = Cpu();
   ChainComplex chainComplex = ChainComplex(_cellComplex);
   chainComplex.computeHomology();
   t2 = Cpu();
-  Msg::StatusBar(2, true, "Done computing homology space bases (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done computing homology space bases (%g s)", t2 - t1);
 
   std::string domain = _getDomainString(_domain, _subdomain);
   _deleteChains(dim);
@@ -235,7 +235,7 @@ void Homology::findHomologyBasis(std::vector<int> dim)
   Msg::Info("H_3 = %d", _betti[3]);
   if(omitted != 0) Msg::Info("The computation of basis elements in the highest dimension was omitted");
 
-  Msg::StatusBar(2, false, "H_0: %d, H_1: %d, H_2: %d, H_3: %d",
+  Msg::StatusBar(false, "H_0: %d, H_1: %d, H_2: %d, H_3: %d",
 		 _betti[0], _betti[1], _betti[2], _betti[3]);
 
   if(dim.empty()) {
@@ -253,7 +253,7 @@ void Homology::findCohomologyBasis(std::vector<int> dim)
   if(_cellComplex == NULL) _createCellComplex();
   if(_cellComplex->isReduced()) _cellComplex->restoreComplex();
 
-  Msg::StatusBar(2, true, "Reducing cell complex...");
+  Msg::StatusBar(true, "Reducing cell complex...");
 
   double t1 = Cpu();
 
@@ -270,18 +270,18 @@ void Homology::findCohomologyBasis(std::vector<int> dim)
 
   double t2 = Cpu();
 
-  Msg::StatusBar(2, true, "Done reducing cell complex (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done reducing cell complex (%g s)", t2 - t1);
   Msg::Info("%d volumes, %d faces, %d edges, and %d vertices",
             _cellComplex->getSize(3), _cellComplex->getSize(2),
 	    _cellComplex->getSize(1), _cellComplex->getSize(0));
 
-  Msg::StatusBar(2, true, "Computing cohomology space bases ...");
+  Msg::StatusBar(true, "Computing cohomology space bases ...");
   t1 = Cpu();
   ChainComplex chainComplex = ChainComplex(_cellComplex);
   chainComplex.transposeHMatrices();
   chainComplex.computeHomology(true);
   t2 = Cpu();
-  Msg::StatusBar(2, true, "Done computing cohomology space bases (%g s)", t2- t1);
+  Msg::StatusBar(true, "Done computing cohomology space bases (%g s)", t2- t1);
 
   std::string domain = _getDomainString(_domain, _subdomain);
   _deleteCochains(dim);
@@ -318,7 +318,7 @@ void Homology::findCohomologyBasis(std::vector<int> dim)
   Msg::Info("H^3 = %d", _betti[3]);
   if(omitted != 0) Msg::Info("The computation of basis elements in the highest dimension was omitted");
 
-  Msg::StatusBar(2, false, "H^0: %d, H^1: %d, H^2: %d, H^3: %d",
+  Msg::StatusBar(false, "H^0: %d, H^1: %d, H^2: %d, H^3: %d",
 		 _betti[0], _betti[1], _betti[2], _betti[3]);
 
   if(dim.empty()) {
diff --git a/Graphics/drawContext.cpp b/Graphics/drawContext.cpp
index c3989ac6d97e847ef11159ac8f8397d1d96b7dc4..03592a7d90aa7826439596cbf1e0c67bd892c030 100644
--- a/Graphics/drawContext.cpp
+++ b/Graphics/drawContext.cpp
@@ -51,13 +51,11 @@ drawContext::drawContext(drawTransform *transform)
 
   _quadric = 0; // cannot create it here: needs valid opengl context
   _displayLists = 0;
-
 }
 
 drawContext::~drawContext()
 {
-  if(_quadric) gluDeleteQuadric(_quadric);
-  if(_displayLists) glDeleteLists(_displayLists, 3);
+  invalidateQuadricsAndDisplayLists();
 }
 
 drawContextGlobal *drawContext::global()
@@ -66,6 +64,12 @@ drawContextGlobal *drawContext::global()
   return _global;
 }
 
+void drawContext::invalidateQuadricsAndDisplayLists()
+{
+  if(_quadric){ gluDeleteQuadric(_quadric); _quadric = 0; }
+  if(_displayLists){ glDeleteLists(_displayLists, 3); _displayLists = 0; }
+}
+
 void drawContext::createQuadricsAndDisplayLists()
 {
   if(!_quadric) _quadric = gluNewQuadric();
@@ -232,22 +236,20 @@ static int needPolygonOffset()
 
 void drawContext::draw3d()
 {
-  // We can only create this when a valid opengl context exists. (It's
-  // cheap to create so we just do it at each redraw: this makes it
-  // much simpler to deal with option changes, e.g. arrow shape
-  // changes)
+  // We can only create this when a valid opengl context exists. (It's cheap to
+  // create so we just do it at each redraw: this makes it much simpler to deal
+  // with option changes, e.g. arrow shape changes)
   createQuadricsAndDisplayLists();
 
-  // We should only enable the polygon offset when there is a mix of
-  // lines and polygons to be drawn; enabling it all the time can lead
-  // to very small but annoying artifacts in the picture. Since there
-  // are so many ways in Gmsh to combine polygons and lines
-  // (geometries + meshes + views...), we do our best here to
-  // automatically detect if we should enable it. Note: the formula
-  // for the offset is "offset = factor*DZ+r*units", where DZ is a
-  // measurement of the change in depth relative to the screen area of
-  // the polygon, and r is the smallest value that is guaranteed to
-  // produce a resolvable offset for a given implementation.
+  // We should only enable the polygon offset when there is a mix of lines and
+  // polygons to be drawn; enabling it all the time can lead to very small but
+  // annoying artifacts in the picture. Since there are so many ways in Gmsh to
+  // combine polygons and lines (geometries + meshes + views...), we do our best
+  // here to automatically detect if we should enable it. Note: the formula for
+  // the offset is "offset = factor*DZ+r*units", where DZ is a measurement of
+  // the change in depth relative to the screen area of the polygon, and r is
+  // the smallest value that is guaranteed to produce a resolvable offset for a
+  // given implementation.
   glPolygonOffset((float)CTX::instance()->polygonOffsetFactor,
                   (float)CTX::instance()->polygonOffsetUnits);
   if(CTX::instance()->polygonOffsetFactor || CTX::instance()->polygonOffsetUnits)
@@ -258,7 +260,6 @@ void drawContext::draw3d()
 
   // speedup drawing of textured fonts on cocoa mac version
 #if defined(HAVE_FLTK) && defined(__APPLE__) && defined(HAVE_64BIT_SIZE_T)
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
   int numStrings = GModel::current()->getNumVertices();
   if(CTX::instance()->mesh.pointsNum)
     numStrings = std::max(numStrings, GModel::current()->getNumMeshVertices());
@@ -268,7 +269,6 @@ void drawContext::draw3d()
   numStrings *= 2;
   if(gl_texture_pile_height() < numStrings)
     gl_texture_pile_height(numStrings);
-#endif
 #endif
 
   glDepthFunc(GL_LESS);
@@ -446,10 +446,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
   // no initial translation of the model
   t_init[0] = t_init[1] = t_init[2] = 0.;
 
-  // set up the near and far clipping planes so that the box is large
-  // enough to manipulate the model and zoom, but not too big
-  // (otherwise the z-buffer resolution e.g. with Mesa can become
-  // insufficient)
+  // set up the near and far clipping planes so that the box is large enough to
+  // manipulate the model and zoom, but not too big (otherwise the z-buffer
+  // resolution e.g. with Mesa can become insufficient)
   double zmax = std::max(fabs(CTX::instance()->min[2]),
 			 fabs(CTX::instance()->max[2]));
   if(zmax < CTX::instance()->lc) zmax = CTX::instance()->lc;
@@ -502,10 +501,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
       glDisable(GL_DEPTH_TEST);
       glPushMatrix();
       glLoadIdentity();
-      // the z values and the translation are only needed for GL2PS,
-      // which does not understand "no depth test" (hence we must make
-      // sure that we draw the background behind the rest of the
-      // scene)
+      // the z values and the translation are only needed for GL2PS, which does
+      // not understand "no depth test" (hence we must make sure that we draw
+      // the background behind the rest of the scene)
       glOrtho((double)viewport[0], (double)viewport[2],
 	      (double)viewport[1], (double)viewport[3],
 	      clip_near, clip_far);
@@ -525,9 +523,9 @@ void drawContext::initProjection(int xpick, int ypick, int wpick, int hpick)
       glLoadIdentity();
     }
     else {
-      // recenter the model such that the perspective is always at the
-      // center of gravity (we should maybe add an option to choose
-      // this, as we do for the rotation center)
+      // recenter the model such that the perspective is always at the center of
+      // gravity (we should maybe add an option to choose this, as we do for the
+      // rotation center)
       t_init[0] = CTX::instance()->cg[0];
       t_init[1] = CTX::instance()->cg[1];
       vxmin -= t_init[0];
@@ -610,12 +608,11 @@ void drawContext::initRenderModel()
 
   glShadeModel(GL_SMOOTH);
 
-  // Normalize the normals automatically. We could use the more
-  // efficient glEnable(GL_RESCALE_NORMAL) instead (since we initially
-  // specify unit normals), but GL_RESCALE_NORMAL does only work with
-  // isotropic scalings (and we allow anistotropic scalings in
-  // myZoom). Note that GL_RESCALE_NORMAL is only available in
-  // GL_VERSION_1_2.
+  // Normalize the normals automatically. We could use the more efficient
+  // glEnable(GL_RESCALE_NORMAL) instead (since we initially specify unit
+  // normals), but GL_RESCALE_NORMAL does only work with isotropic scalings (and
+  // we allow anistotropic scalings in myZoom). Note that GL_RESCALE_NORMAL is
+  // only available in GL_VERSION_1_2.
   glEnable(GL_NORMALIZE);
 
   // lighting is enabled/disabled for each particular primitive later
@@ -648,9 +645,9 @@ void drawContext::initPosition()
                  -CTX::instance()->rotationCenter[1],
                  -CTX::instance()->rotationCenter[2]);
 
-  // store the projection and modelview matrices at this precise
-  // moment (so that we can use them at any later time, even if the
-  // context has changed, i.e., even if we are out of draw())
+  // store the projection and modelview matrices at this precise moment (so that
+  // we can use them at any later time, even if the context has changed, i.e.,
+  // even if we are out of draw())
   glGetDoublev(GL_PROJECTION_MATRIX, proj);
   glGetDoublev(GL_MODELVIEW_MATRIX, model);
 
@@ -658,9 +655,9 @@ void drawContext::initPosition()
     glClipPlane((GLenum)(GL_CLIP_PLANE0 + i), CTX::instance()->clipPlane[i]);
 }
 
-// Takes a cursor position in window coordinates and returns the line
-// (given by a point and a unit direction vector), in real space, that
-// corresponds to that cursor position
+// Takes a cursor position in window coordinates and returns the line (given by
+// a point and a unit direction vector), in real space, that corresponds to that
+// cursor position
 void drawContext::unproject(double x, double y, double p[3], double d[3])
 {
   GLint vp[4];
@@ -671,8 +668,8 @@ void drawContext::unproject(double x, double y, double p[3], double d[3])
   GLdouble x0, y0, z0, x1, y1, z1;
 
   // we use the stored model and proj matrices instead of directly
-  // getGetDouble'ing the matrices since unproject can be called in or
-  // after draw2d
+  // getGetDouble'ing the matrices since unproject can be called in or after
+  // draw2d
   if(!gluUnProject(x, y, 0.0, model, proj, vp, &x0, &y0, &z0))
     Msg::Warning("unproject1 failed");
   if(!gluUnProject(x, y, 1.0, model, proj, vp, &x1, &y1, &z1))
@@ -725,8 +722,8 @@ class hitDepthLessThan{
   }
 };
 
-// returns the element at a given position in a vertex array (element
-// pointers are not always stored: returning 0 is not an error)
+// returns the element at a given position in a vertex array (element pointers
+// are not always stored: returning 0 is not an error)
 static MElement *getElement(GEntity *e, int va_type, int index)
 {
   switch(va_type){
@@ -756,8 +753,8 @@ bool drawContext::select(int type, bool multiple, bool mesh,
   regions.clear();
   elements.clear();
 
-  // in our case the selection buffer size is equal to between 5 and 7
-  // times the maximum number of possible hits
+  // in our case the selection buffer size is equal to between 5 and 7 times the
+  // maximum number of possible hits
   GModel *m = GModel::current();
   int eles = (mesh && CTX::instance()->pickElements) ? 4 * m->getNumMeshElements() : 0;
   int size = 7 * (m->getNumVertices() + m->getNumEdges() + m->getNumFaces() +
@@ -799,14 +796,13 @@ bool drawContext::select(int type, bool multiple, bool mesh,
   for(int i = 0; i < numhits; i++) {
     // in Gmsh 'names' should always be 0, 2 or 4:
     // * names == 0 means that there is nothing on the stack
-    // * if names == 2, the first name is the type of the entity
-    //   (0 for point, 1 for edge, 2 for face or 3 for volume) and
-    //   the second is the entity number;
-    // * if names == 4, the first name is the type of the entity,
-    //   the second is the entity number, the third is the type
-    //   of vertex array (2 for line, 3 for triangle, 4 for quad)
-    //   and the fourth is the index of the element in the vertex
-    //   array
+    // * if names == 2, the first name is the type of the entity (0 for point, 1
+    //   for edge, 2 for face or 3 for volume) and the second is the entity
+    //   number;
+    // * if names == 4, the first name is the type of the entity, the second is
+    //   the entity number, the third is the type of vertex array (2 for line, 3
+    //   for triangle, 4 for quad) and the fourth is the index of the element in
+    //   the vertex array
     GLuint names = *ptr++;
     *ptr++; // mindepth
     GLuint maxdepth = *ptr++;
@@ -835,9 +831,9 @@ bool drawContext::select(int type, bool multiple, bool mesh,
   // sort hits to get closest entities first
   std::sort(hits.begin(), hits.end(), hitDepthLessThan());
 
-  // filter result: if type == ENT_NONE, return the closest entity of
-  // "lowest dimension" (point < line < surface < volume). Otherwise,
-  // return the closest entity of type "type"
+  // filter result: if type == ENT_NONE, return the closest entity of "lowest
+  // dimension" (point < line < surface < volume). Otherwise, return the closest
+  // entity of type "type"
   GLuint typmin = 10;
   for(unsigned int i = 0; i < hits.size(); i++)
     typmin = std::min(typmin, hits[i].type);
diff --git a/Graphics/drawContext.h b/Graphics/drawContext.h
index 42ff998e1f0a6369f15aa8f3f1d8678ca15a3312..37febe748f3d1045917456018cdb1657556fb427 100644
--- a/Graphics/drawContext.h
+++ b/Graphics/drawContext.h
@@ -79,8 +79,8 @@ class drawTransformScaled : public drawTransform {
   }
 };
 
-// global drawing functions, which need to be redefined for each
-// widget toolkit (FLTK, Qt, etc.)
+// global drawing functions, which need to be redefined for each widget toolkit
+// (FLTK, Qt, etc.)
 class drawContextGlobal {
  public:
   drawContextGlobal(){}
@@ -160,6 +160,7 @@ class drawContext {
   bool isVisible(GModel *m){ return (_hiddenModels.find(m) == _hiddenModels.end()); }
   bool isVisible(PView *v){ return (_hiddenViews.find(v) == _hiddenViews.end()); }
   void createQuadricsAndDisplayLists();
+  void invalidateQuadricsAndDisplayLists();
   void buildRotationMatrix();
   void setQuaternion(double p1x, double p1y, double p2x, double p2y);
   void addQuaternion(double p1x, double p1y, double p2x, double p2y);
@@ -264,8 +265,8 @@ class mousePosition {
   }
   void recenter(drawContext *ctx)
   {
-    // compute the equivalent translation to apply *after* the scaling
-    // so that the scaling is done around the point which was clicked:
+    // compute the equivalent translation to apply *after* the scaling so that
+    // the scaling is done around the point which was clicked:
     ctx->t[0] = t[0] * (s[0] / ctx->s[0]) - wnr[0] * (1. - (s[0] / ctx->s[0]));
     ctx->t[1] = t[1] * (s[1] / ctx->s[1]) - wnr[1] * (1. - (s[1] / ctx->s[1]));
   }
diff --git a/Graphics/drawPost.cpp b/Graphics/drawPost.cpp
index 1106c665b591b973d2e459080372ba0ddd2be2ec..1b72eb3ec2578bff3ff59d7b53ae31f09d331503 100644
--- a/Graphics/drawPost.cpp
+++ b/Graphics/drawPost.cpp
@@ -284,7 +284,6 @@ static void drawGlyphs(drawContext *ctx, PView *p)
 
   // speedup drawing of textured fonts on cocoa mac version
 #if defined(HAVE_FLTK) && defined(__APPLE__) && defined(HAVE_64BIT_SIZE_T)
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 3)
   if(opt->intervalsType == PViewOptions::Numeric){
     int numStrings = 0;
     for(int ent = 0; ent < data->getNumEntities(opt->timeStep); ent++)
@@ -292,7 +291,6 @@ static void drawGlyphs(drawContext *ctx, PView *p)
     if(gl_texture_pile_height() < numStrings)
       gl_texture_pile_height(numStrings);
   }
-#endif
 #endif
 
   //double xyz[PVIEW_NMAX][3], val[PVIEW_NMAX][9];
diff --git a/Mesh/Generator.cpp b/Mesh/Generator.cpp
index 2115fd90950552d5460b6d08b0d5d7922ca19370..b4d2c14e000f9beb56847a138ec603ec47030187 100644
--- a/Mesh/Generator.cpp
+++ b/Mesh/Generator.cpp
@@ -358,7 +358,7 @@ static void Mesh0D(GModel *m)
 static void Mesh1D(GModel *m)
 {
   if(TooManyElements(m, 1)) return;
-  Msg::StatusBar(2, true, "Meshing 1D...");
+  Msg::StatusBar(true, "Meshing 1D...");
   double t1 = Cpu();
 
   for(GModel::eiter it = m->firstEdge(); it != m->lastEdge(); ++it)
@@ -383,7 +383,7 @@ static void Mesh1D(GModel *m)
 
   double t2 = Cpu();
   CTX::instance()->meshTimer[0] = t2 - t1;
-  Msg::StatusBar(2, true, "Done meshing 1D (%g s)", CTX::instance()->meshTimer[0]);
+  Msg::StatusBar(true, "Done meshing 1D (%g s)", CTX::instance()->meshTimer[0]);
 }
 
 static void PrintMesh2dStatistics(GModel *m)
@@ -441,7 +441,7 @@ static void PrintMesh2dStatistics(GModel *m)
 static void Mesh2D(GModel *m)
 {
   if(TooManyElements(m, 2)) return;
-  Msg::StatusBar(2, true, "Meshing 2D...");
+  Msg::StatusBar(true, "Meshing 2D...");
   double t1 = Cpu();
 
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it)
@@ -520,7 +520,7 @@ static void Mesh2D(GModel *m)
 
   double t2 = Cpu();
   CTX::instance()->meshTimer[1] = t2 - t1;
-  Msg::StatusBar(2, true, "Done meshing 2D (%g s)", CTX::instance()->meshTimer[1]);
+  Msg::StatusBar(true, "Done meshing 2D (%g s)", CTX::instance()->meshTimer[1]);
 
   PrintMesh2dStatistics(m);
 }
@@ -535,7 +535,7 @@ static void FindConnectedRegions(std::vector<GRegion*> &delaunay,
 static void Mesh3D(GModel *m)
 {
   if(TooManyElements(m, 3)) return;
-  Msg::StatusBar(2, true, "Meshing 3D...");
+  Msg::StatusBar(true, "Meshing 3D...");
   double t1 = Cpu();
 
   // mesh the extruded volumes first
@@ -567,46 +567,46 @@ static void Mesh3D(GModel *m)
 
   double t2 = Cpu();
   CTX::instance()->meshTimer[2] = t2 - t1;
-  Msg::StatusBar(2, true, "Done meshing 3D (%g s)", CTX::instance()->meshTimer[2]);
+  Msg::StatusBar(true, "Done meshing 3D (%g s)", CTX::instance()->meshTimer[2]);
 }
 
 void OptimizeMeshNetgen(GModel *m)
 {
-  Msg::StatusBar(2, true, "Optimizing 3D mesh with Netgen...");
+  Msg::StatusBar(true, "Optimizing 3D mesh with Netgen...");
   double t1 = Cpu();
 
   std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegionNetgen());
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done optimizing 3D mesh with Netgen (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done optimizing 3D mesh with Netgen (%g s)", t2 - t1);
 }
 
 void OptimizeMesh(GModel *m)
 {
-  Msg::StatusBar(2, true, "Optimizing 3D mesh...");
+  Msg::StatusBar(true, "Optimizing 3D mesh...");
   double t1 = Cpu();
 
   std::for_each(m->firstRegion(), m->lastRegion(), optimizeMeshGRegionGmsh());
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done optimizing 3D mesh (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done optimizing 3D mesh (%g s)", t2 - t1);
 }
 
 void AdaptMesh(GModel *m)
 {
-  Msg::StatusBar(2, true, "Adapting 3D mesh...");
+  Msg::StatusBar(true, "Adapting 3D mesh...");
   double t1 = Cpu();
 
   for(int i = 0; i < 10; i++)
     std::for_each(m->firstRegion(), m->lastRegion(), adaptMeshGRegion());
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done adaptating 3D mesh (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done adaptating 3D mesh (%g s)", t2 - t1);
 }
 
 void RecombineMesh(GModel *m)
 {
-  Msg::StatusBar(2, true, "Recombining 2D mesh...");
+  Msg::StatusBar(true, "Recombining 2D mesh...");
   double t1 = Cpu();
 
   for(GModel::fiter it = m->firstFace(); it != m->lastFace(); ++it){
@@ -617,7 +617,7 @@ void RecombineMesh(GModel *m)
   CTX::instance()->mesh.changed = ENT_ALL;
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done recombining 2D mesh (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done recombining 2D mesh (%g s)", t2 - t1);
 }
 
 //#include <google/profiler.h>
diff --git a/Mesh/HighOrder.cpp b/Mesh/HighOrder.cpp
index a49a21a27c8d7f8bace4f571653e8a85d40d3a08..8c9d998450c26142865f0bbe79e446e6b3362fdc 100644
--- a/Mesh/HighOrder.cpp
+++ b/Mesh/HighOrder.cpp
@@ -1021,8 +1021,8 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices,
     getEdgeVertices(gr, p, ve, edgeVertices, linear, nPts);
     if (nPts == 1) {
       if(incomplete) {
-        pyramids2.push_back(new MPyramid13(p->getVertex(0), p->getVertex(1), 
-                            p->getVertex(2), p->getVertex(3), 
+        pyramids2.push_back(new MPyramid13(p->getVertex(0), p->getVertex(1),
+                            p->getVertex(2), p->getVertex(3),
                             p->getVertex(4), ve[0], ve[1], ve[2],
 			                      ve[3], ve[4], ve[5], ve[6], ve[7]));
       }
@@ -1080,7 +1080,7 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices,
         verts_lvl1[0] = 31;
         verts_lvl1[1] = 37;
         verts_lvl1[2] = 40;
-        verts_lvl1[3] = 34;     
+        verts_lvl1[3] = 34;
         break;
       case(2):
         verts_lvl1[0] = 21;
@@ -1104,7 +1104,7 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices,
             veq.push_back(ve[verts_lvl3[f]-5]);
         else if (nPts-q == 3)
           for (int f = 0; f < 8; f++)
-            veq.push_back(ve[verts_lvl2[f]-5]);        
+            veq.push_back(ve[verts_lvl2[f]-5]);
         else if (nPts-q == 2)
           for (int f = 0; f < 4; f++)
             veq.push_back(ve[verts_lvl1[f]-5]);
@@ -1152,7 +1152,7 @@ static void setHighOrder(GRegion *gr, edgeContainer &edgeVertices,
                                { -0.5,  0.5},
                                {  0.0, -0.5},
                                {  0.5,  0.0},
-                               {  0.0,  0.5},                               
+                               {  0.0,  0.5},
                                { -0.5,  0.0},
                                {  0.0,  0.0}
                                  };
@@ -1454,7 +1454,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisi
   char msg[256];
   sprintf(msg, "Meshing order %d (curvilinear %s)...", order, linear ? "off" : "on");
 
-  Msg::StatusBar(2, true, msg);
+  Msg::StatusBar(true, msg);
 
   double t1 = Cpu();
 
@@ -1520,7 +1520,7 @@ void SetOrderN(GModel *m, int order, bool linear, bool incomplete, bool onlyVisi
   checkHighOrderTetrahedron("Volume Mesh", m, bad, worst);
   // m->writeMSH("CORRECTED.msh");
 
-  Msg::StatusBar(2, true, "Done meshing order %d (%g s)", order, t2 - t1);
+  Msg::StatusBar(true, "Done meshing order %d (%g s)", order, t2 - t1);
 }
 
 void computeDistanceFromMeshToGeometry (GModel *m, distanceFromMeshToGeometry_t &dist)
diff --git a/Mesh/meshPartition.cpp b/Mesh/meshPartition.cpp
index 140c57cec0ae77766f9b9ba40f510d07e41b838c..ba28bb81457a44e4a1643f0fa7de22a414f89790 100644
--- a/Mesh/meshPartition.cpp
+++ b/Mesh/meshPartition.cpp
@@ -65,11 +65,11 @@ extern "C" void METIS_mCPartGraphKway
  *============================================================================*/
 
 template <typename FaceT> struct LFaceTr;
-template <> struct LFaceTr<MEdge> 
+template <> struct LFaceTr<MEdge>
 {
   typedef std::map<MEdge, MElement*, Less_Edge> FaceMap;
 };
-template <> struct LFaceTr<MFace> 
+template <> struct LFaceTr<MFace>
 {
   typedef std::map<MFace, MElement*, Less_Face> FaceMap;
 };
@@ -96,7 +96,7 @@ void MakeGraphDIM(const EntIter begin, const EntIter end,
                   const EntIterBE beginBE, const EntIterBE endBE,
                   Graph &graph, BoElemGrVec *const boElemGrVec);
 
-                  
+
 /*******************************************************************************
  *
  * Routine partitionMesh
@@ -116,15 +116,15 @@ void MakeGraphDIM(const EntIter begin, const EntIter end,
  *
  ******************************************************************************/
 
-int RenumberMesh(GModel *const model, meshPartitionOptions &options, 
+int RenumberMesh(GModel *const model, meshPartitionOptions &options,
                  std::vector<MElement*> &numbered)
 {
   Graph graph;
   BoElemGrVec boElemGrVec;
   int ier;
-  Msg::StatusBar(2, true, "Building graph...");
+  Msg::StatusBar(true, "Building graph...");
   ier = MakeGraph(model, graph, options, &boElemGrVec);
-  Msg::StatusBar(2, true, "Renumbering graph...");
+  Msg::StatusBar(true, "Renumbering graph...");
   if(!ier) ier = RenumberGraph(graph, options);
   if(ier) return 1;
 
@@ -136,7 +136,7 @@ int RenumberMesh(GModel *const model, meshPartitionOptions &options,
     numbered[graph.partition[i]-1] = graph.element[i];
   }
 
-  Msg::StatusBar(2, true, "Done renumbering graph");
+  Msg::StatusBar(true, "Done renumbering graph");
   return 0;
 }
 
@@ -148,23 +148,23 @@ int PartitionMeshElements(std::vector<MElement*> &elements, meshPartitionOptions
   for (unsigned i=0;i<elements.size();++i)
     for (int j=0;j<elements[i]->getNumVertices();j++)
       setv.insert(elements[i]->getVertex(j));
-  
+
   for (std::set<MVertex* >::iterator it = setv.begin(); it != setv.end(); it++)
     gf->mesh_vertices.push_back(*it);
-  
+
   for (std::vector<MElement* >::iterator it = elements.begin(); it != elements.end(); it++){
-    if ((*it)->getType() == TYPE_TRI) 
+    if ((*it)->getType() == TYPE_TRI)
       gf->triangles.push_back((MTriangle*)(*it));
-    else if  ((*it)->getType() == TYPE_QUA) 
+    else if  ((*it)->getType() == TYPE_QUA)
       gf->quadrangles.push_back((MQuadrangle*)(*it));
   }
   tmp_model->add(gf);
-  
-  PartitionMesh(tmp_model,options); 
-  
+
+  PartitionMesh(tmp_model,options);
+
   tmp_model->remove(gf);
   delete tmp_model;
-  
+
   return 1;
 }
 
@@ -173,9 +173,9 @@ int PartitionMeshFace(std::list<GFace*> &cFaces, meshPartitionOptions &options)
   GModel *tmp_model = new GModel();
   for(std::list<GFace*>::iterator it = cFaces.begin(); it != cFaces.end(); it++)
     tmp_model->add(*it);
-  
-  PartitionMesh(tmp_model,options); 
-  
+
+  PartitionMesh(tmp_model,options);
+
   for(std::list<GFace*>::iterator it = cFaces.begin(); it != cFaces.end(); it++)
     tmp_model->remove(*it);
   delete tmp_model;
@@ -196,13 +196,13 @@ int RenumberMeshElements(std::vector<MElement*> &elements, meshPartitionOptions
     for (std::set<MVertex* >::iterator it = setv.begin(); it != setv.end(); it++)
       gf->mesh_vertices.push_back(*it);
     for (std::vector<MElement* >::iterator it = elements.begin(); it != elements.end(); it++){
-      if ((*it)->getType() == TYPE_TRI) 
+      if ((*it)->getType() == TYPE_TRI)
         gf->triangles.push_back((MTriangle*)(*it));
-      else if  ((*it)->getType() == TYPE_QUA) 
+      else if  ((*it)->getType() == TYPE_QUA)
         gf->quadrangles.push_back((MQuadrangle*)(*it));
     }
     tmp_model->add(gf);
-    RenumberMesh(tmp_model, options, elements);    
+    RenumberMesh(tmp_model, options, elements);
     tmp_model->remove(gf);
   }
   else if (elements[0]->getDim() == 3){
@@ -210,13 +210,13 @@ int RenumberMeshElements(std::vector<MElement*> &elements, meshPartitionOptions
     for (std::set<MVertex* >::iterator it = setv.begin(); it != setv.end(); it++)
       gr->mesh_vertices.push_back(*it);
     for (std::vector<MElement* >::iterator it = elements.begin(); it != elements.end(); it++){
-      if ((*it)->getType() == TYPE_TET) 
+      if ((*it)->getType() == TYPE_TET)
         gr->tetrahedra.push_back((MTetrahedron*)(*it));
-      else if  ((*it)->getType() == TYPE_HEX) 
+      else if  ((*it)->getType() == TYPE_HEX)
         gr->hexahedra.push_back((MHexahedron*)(*it));
-      else if  ((*it)->getType() == TYPE_PRI) 
+      else if  ((*it)->getType() == TYPE_PRI)
         gr->prisms.push_back((MPrism*)(*it));
-      else if  ((*it)->getType() == TYPE_PYR) 
+      else if  ((*it)->getType() == TYPE_PYR)
         gr->pyramids.push_back((MPyramid*)(*it));
     }
     tmp_model->add(gr);
@@ -225,7 +225,7 @@ int RenumberMeshElements(std::vector<MElement*> &elements, meshPartitionOptions
   return 1;
 }
 
-int RenumberMesh(GModel *const model, meshPartitionOptions &options)  
+int RenumberMesh(GModel *const model, meshPartitionOptions &options)
 {
   for (GModel::fiter it = model->firstFace() ; it != model->lastFace() ; ++it){
     std::vector<MElement *> temp;
@@ -249,14 +249,14 @@ int RenumberMesh(GModel *const model, meshPartitionOptions &options)
     temp.insert(temp.begin(), (*it)->tetrahedra.begin(), (*it)->tetrahedra.end());
     RenumberMeshElements(temp, options);
     (*it)->tetrahedra.clear();
-    for (unsigned int i = 0; i < temp.size(); i++) 
+    for (unsigned int i = 0; i < temp.size(); i++)
       (*it)->tetrahedra.push_back((MTetrahedron*)temp[i]);
     temp.clear();
 
     temp.insert(temp.begin(),(*it)->hexahedra.begin(),(*it)->hexahedra.end());
     RenumberMeshElements(temp, options);
     (*it)->hexahedra.clear();
-    for (unsigned int i = 0; i < temp.size(); i++) 
+    for (unsigned int i = 0; i < temp.size(); i++)
       (*it)->hexahedra.push_back((MHexahedron*)temp[i]);
   }
   return 1;
@@ -267,12 +267,12 @@ int PartitionMesh(GModel *const model, meshPartitionOptions &options)
   Graph graph;
   BoElemGrVec boElemGrVec;
   int ier;
-  Msg::StatusBar(2, true, "Building graph...");
+  Msg::StatusBar(true, "Building graph...");
   ier = MakeGraph(model, graph, options, &boElemGrVec);
-  Msg::StatusBar(2, true, "Partitioning graph...");
+  Msg::StatusBar(true, "Partitioning graph...");
   if(!ier) ier = PartitionGraph(graph, options);
   if(ier) return 1;
-    
+
   // Count partition sizes and assign partitions to internal elements
   std::vector<int> ssize(options.num_partitions, 0);
   const int n = graph.getNumVertex();
@@ -299,7 +299,7 @@ int PartitionMesh(GModel *const model, meshPartitionOptions &options)
   if (options.createPartitionBoundaries || options.createGhostCells)
     CreatePartitionBoundaries (model, options.createGhostCells);
 
-  Msg::StatusBar(2, true, "Done partitioning graph");
+  Msg::StatusBar(true, "Done partitioning graph");
   return 0;
 }
 
@@ -506,7 +506,7 @@ int RenumberGraph(Graph &graph, meshPartitionOptions &options)
       const int iSec = 0;
       int options = 0;
       int *perm = new int[n];
-      METIS_NodeND(&n, 
+      METIS_NodeND(&n,
                    &graph.xadj[graph.section[iSec]],
                    &graph.adjncy[graph.section[iSec]], &numflag,&options,perm,&graph.partition[graph.section[iSec]]);
       delete [] perm;
@@ -568,7 +568,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options,
 /*--------------------------------------------------------------------*
  * Make a graph for the entire domain
  *--------------------------------------------------------------------*/
-    
+
 //--Get the dimension of the mesh and count the numbers of elements
 
       unsigned numElem[5];
@@ -590,7 +590,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options,
             // maximum possible number of corresponding edges for the mesh
             const int maxGrEdge = (numElem[ElemTypeTri]*3 + numElem[ElemTypeQuad]*4
                                    + numElem[ElemTypePolyg]*4)/2;
-  
+
             graph.allocate(numGrVert, maxGrEdge);
             // Make the graph
             MakeGraphDIM<2>(model->firstFace(), model->lastFace(),
@@ -630,7 +630,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options,
       }
 
 //     break;
-    
+
 //   case PartitionByPhysical:
 //     {
 
@@ -721,7 +721,7 @@ int MakeGraph(GModel *const model, Graph &graph, meshPartitionOptions &options,
 //             (numElem[ElemTypeTetra]*4 + numElem[ElemTypeHexa]*6 +
 //              (numElem[ElemTypePrism] + numElem[ElemTypePyramid])*5)/2;
 //           graph.allocate(numGrVert, maxGrEdge);
-          
+
 //           // Make the graph
 //           for(PhysGroupMap::iterator itPhys = groups[region].begin();
 //               itPhys != groups[region].end(); ++itPhys) {
@@ -760,9 +760,9 @@ void MakeGraphDIM(const EntIter begin, const EntIter end,
 
   typedef typename DimTr<DIM>::FaceT FaceT;
   typedef typename LFaceTr<FaceT>::FaceMap FaceMap;
-  
+
   graph.markSection();
-  
+
   FaceMap faceMap;
   GrVertexMap grVertMap;
 
@@ -881,7 +881,7 @@ struct MatchBoElemToGrVertex
 {
   typedef typename DimTr<DIM>::FaceT FaceT;  // The type/dimension of face
   typedef typename LFaceTr<FaceT>::FaceMap FaceMap;  // The corresponding map
-      
+
   static void eval(const GEntity *const entity, const FaceMap &faceMap,
                    const GrVertexMap &grVertMap, const Graph &graph,
                    std::vector<BoElemGr> &boElemGrVec)
@@ -967,7 +967,7 @@ void assignPartitionBoundary(GModel *model, MFace &me,
     if (!found)v2.push_back(v[i]->getPartition());
   }
   if (v2.size() < 2)return;
-  
+
   partitionFace pe(model, 1, v2);
   std::set<partitionFace*, Less_partitionFace>::iterator it = pfaces.find(&pe);
   partitionFace *ppe;
@@ -1012,7 +1012,7 @@ void assignPartitionBoundary(GModel *model,
   partitionFace pf(model, 1, v2);
   std::set<partitionFace*, Less_partitionFace>::iterator itf = pfaces.find(&pf);
   if (itf != pfaces.end())return;
-  
+
   partitionEdge pe  (model, 1, 0, 0, v2);
   std::set<partitionEdge*, Less_partitionEdge>::iterator it = pedges.find(&pe);
   partitionEdge *ppe;
@@ -1036,7 +1036,7 @@ void  splitBoundaryEdges(GModel *model,  std::set<partitionEdge*, Less_partition
     for (unsigned int i = 0; i < ge->lines.size(); i++){
       segments.push_back(ge->lines[i]);
     }
-    
+
     while (!segments.empty()) {
       std::vector<MLine*> myLines;
       std::list<MLine*>::iterator it = segments.begin();
@@ -1046,7 +1046,7 @@ void  splitBoundaryEdges(GModel *model,  std::set<partitionEdge*, Less_partition
       segments.erase(it);
       it++;
       for (int i=0; i<2; i++) {
-        for (std::list<MLine*>::iterator it = segments.begin() ; it != segments.end(); ++it){ 
+        for (std::list<MLine*>::iterator it = segments.begin() ; it != segments.end(); ++it){
           MVertex *v1 = (*it)->getVertex(0);
           MVertex *v2 = (*it)->getVertex(1);
           std::list<MLine*>::iterator itp;
@@ -1074,7 +1074,7 @@ void  splitBoundaryEdges(GModel *model,  std::set<partitionEdge*, Less_partition
         vB = vE;
         vE = temp;
       }
-      if (nbSplit == 0 && segments.empty()) break; 
+      if (nbSplit == 0 && segments.empty()) break;
       int numEdge = model->getMaxElementaryNumber(1) + 1;
       discreteEdge *newGe = new discreteEdge(model, numEdge, 0, 0);
       newGe->lines.insert(newGe->lines.end(), myLines.begin(), myLines.end());
@@ -1082,11 +1082,11 @@ void  splitBoundaryEdges(GModel *model,  std::set<partitionEdge*, Less_partition
       newGe->orderMLines(); //this creates also mesh_vertices
 
       nbSplit++;
-      printf("*** split partitionEdge with tag =%d\n", numEdge);      
+      printf("*** split partitionEdge with tag =%d\n", numEdge);
     }
     if (nbSplit > 0) model->remove(ge);
   }
-  
+
   return;
 
 }
@@ -1111,7 +1111,7 @@ void assignPartitionBoundary(GModel *model,
     if (!found)v2.push_back(v[i]->getPartition());
   }
   if (v2.size() < 2)return;
-  
+
   partitionFace pf(model, 1, v2);
   std::set<partitionFace*, Less_partitionFace>::iterator itf = pfaces.find(&pf);
   if (itf != pfaces.end()) return;
@@ -1132,8 +1132,8 @@ void assignPartitionBoundary(GModel *model,
   ppv->points.push_back(new MPoint (ve));
 }
 
-static void addGhostCells(GEntity *ge, 
-                          std::multimap<MVertex*, MElement*> &vertexToElement, 
+static void addGhostCells(GEntity *ge,
+                          std::multimap<MVertex*, MElement*> &vertexToElement,
                           std::multimap<MElement*, short> &ghosts)
 {
   // get all the nodes on the partition boundary (we need to recompute
@@ -1144,7 +1144,7 @@ static void addGhostCells(GEntity *ge,
     for(int j = 0; j < e->getNumVertices(); j++)
       verts.insert(e->getVertex(j));
   }
-  
+
   // get all the elements that touch these nodes
   for(std::set<MVertex*>::iterator it = verts.begin(); it != verts.end(); it++){
     std::pair<std::multimap<MVertex*, MElement*>::iterator,
@@ -1193,7 +1193,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA
   std::multimap<MFace, MElement*, Less_Face> faceToElement;
   std::multimap<MEdge, MElement*, Less_Edge> edgeToElement;
   std::multimap<MVertex*, MElement*> vertexToElement;
-  
+
   // create partition faces
   if (meshDim == 3){
     for(GModel::riter it = model->firstRegion(); it != model->lastRegion(); ++it){
@@ -1202,7 +1202,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA
       fillit_(faceToElement, (*it)->prisms.begin(), (*it)->prisms.end());
       fillit_(faceToElement, (*it)->pyramids.begin(), (*it)->pyramids.end());
       fillit_(faceToElement, (*it)->polyhedra.begin(), (*it)->polyhedra.end());
-    }    
+    }
     std::multimap<MFace, MElement*, Less_Face>::iterator it = faceToElement.begin();
     Equal_Face oper;
     while (it != faceToElement.end()){
@@ -1216,7 +1216,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA
       assignPartitionBoundary(model, e, pfaces, voe);
     }
   }
-  
+
   // create partition edges
   if (meshDim > 1){
     if (meshDim == 2 || createAllDims){
@@ -1233,7 +1233,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA
         fillit_(edgeToElement, (*it)->prisms.begin(), (*it)->prisms.end());
         fillit_(edgeToElement, (*it)->pyramids.begin(), (*it)->pyramids.end());
         fillit_(edgeToElement, (*it)->polyhedra.begin(), (*it)->polyhedra.end());
-      }    
+      }
     }
     std::multimap<MEdge, MElement*, Less_Edge>::iterator it = edgeToElement.begin();
     Equal_Edge oper;
@@ -1267,7 +1267,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA
         fillit_(vertexToElement, (*it)->pyramids.begin(), (*it)->pyramids.end());
         fillit_(vertexToElement, (*it)->polyhedra.begin(), (*it)->polyhedra.end());
       }
-    }    
+    }
     std::multimap<MVertex*, MElement*>::iterator it = vertexToElement.begin();
     while (it != vertexToElement.end()){
       MVertex *v = it->first;
@@ -1299,7 +1299,7 @@ int CreatePartitionBoundaries(GModel *model, bool createGhostCells, bool createA
   return 1;
 }
 
-void createPartitionFaces(GModel *model,  std::vector<MElement *> &elements, int N, 
+void createPartitionFaces(GModel *model,  std::vector<MElement *> &elements, int N,
                           std::vector<discreteFace*> &discreteFaces)
 {
 #if defined(HAVE_SOLVER)
@@ -1318,21 +1318,21 @@ void createPartitionFaces(GModel *model,  std::vector<MElement *> &elements, int
   for(unsigned int i = 0; i < elements.size(); ++i){
     MElement *e = elements[i];
     int part = e->getPartition()-1;
-    for(int j = 0; j < 3; j++){   
+    for(int j = 0; j < 3; j++){
       allNodes[part].insert(e->getVertex(j));
     }
     discreteFaces[part]->triangles.push_back(new MTriangle(e->getVertex(0),e->getVertex(1),e->getVertex(2))) ;
   }
 
   for(int i = 0; i < N; i++){
-    for (std::set<MVertex*>::iterator it = allNodes[i].begin(); it != allNodes[i].end(); it++){ 
+    for (std::set<MVertex*>::iterator it = allNodes[i].begin(); it != allNodes[i].end(); it++){
       discreteFaces[i]->mesh_vertices.push_back(*it);
     }
  }
-  
+
 #endif
 }
-  
+
 /*******************************************************************************
  *
  * Explicit instantiations of routine MakeGraphDIM
diff --git a/Mesh/meshRefine.cpp b/Mesh/meshRefine.cpp
index 75cab94456e9c4775201933eca26a8bdb36fd4f7..0fdb2d2d076848a9a923d8a41f38d835cec8a4c6 100644
--- a/Mesh/meshRefine.cpp
+++ b/Mesh/meshRefine.cpp
@@ -45,7 +45,7 @@ static void Subdivide(GEdge *ge)
   ge->lines = lines2;
 
   // 2nd order meshing destroyed the ordering of the vertices on the edge
-  std::sort(ge->mesh_vertices.begin(), ge->mesh_vertices.end(), 
+  std::sort(ge->mesh_vertices.begin(), ge->mesh_vertices.end(),
             MVertexLessThanParam());
   for(unsigned int i = 0; i < ge->mesh_vertices.size(); i++)
     ge->mesh_vertices[i]->setPolynomialOrder(1);
@@ -105,7 +105,7 @@ static void Subdivide(GFace *gf, bool splitIntoQuads, bool splitIntoHexas,
         }
         MVertex *newv;
         if (reparamOK){
-          GPoint gp = gf->point(pt);            
+          GPoint gp = gf->point(pt);
           newv = new MFaceVertex(gp.x(), gp.y(), gp.z(), gf, pt[0], pt[1]);
         }
         else {
@@ -159,7 +159,7 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti
     }
     gr->tetrahedra = tetrahedra2;
   }
-  
+
   std::vector<MHexahedron*> hexahedra2;
   for(unsigned int i = 0; i < gr->hexahedra.size(); i++){
     MHexahedron *h = gr->hexahedra[i];
@@ -273,40 +273,40 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti
 
   }
   gr->hexahedra = hexahedra2;
-  
+
   std::vector<MPrism*> prisms2;
   for(unsigned int i = 0; i < gr->prisms.size(); i++){
     MPrism *p = gr->prisms[i];
     if(p->getNumVertices() == 18){
       prisms2.push_back
-        (new MPrism(p->getVertex(0), p->getVertex(6), p->getVertex(7), 
+        (new MPrism(p->getVertex(0), p->getVertex(6), p->getVertex(7),
                     p->getVertex(8), p->getVertex(15), p->getVertex(16)));
       prisms2.push_back
-        (new MPrism(p->getVertex(8), p->getVertex(15), p->getVertex(16), 
-                    p->getVertex(3), p->getVertex(12), p->getVertex(13)));              
+        (new MPrism(p->getVertex(8), p->getVertex(15), p->getVertex(16),
+                    p->getVertex(3), p->getVertex(12), p->getVertex(13)));
       prisms2.push_back
-        (new MPrism(p->getVertex(6), p->getVertex(1), p->getVertex(9), 
-                    p->getVertex(15), p->getVertex(10), p->getVertex(17)));             
+        (new MPrism(p->getVertex(6), p->getVertex(1), p->getVertex(9),
+                    p->getVertex(15), p->getVertex(10), p->getVertex(17)));
       prisms2.push_back
-        (new MPrism(p->getVertex(15), p->getVertex(10), p->getVertex(17), 
-                    p->getVertex(12), p->getVertex(4), p->getVertex(14)));              
+        (new MPrism(p->getVertex(15), p->getVertex(10), p->getVertex(17),
+                    p->getVertex(12), p->getVertex(4), p->getVertex(14)));
       prisms2.push_back
-        (new MPrism(p->getVertex(7), p->getVertex(9), p->getVertex(2), 
-                    p->getVertex(16), p->getVertex(17), p->getVertex(11)));             
+        (new MPrism(p->getVertex(7), p->getVertex(9), p->getVertex(2),
+                    p->getVertex(16), p->getVertex(17), p->getVertex(11)));
       prisms2.push_back
-        (new MPrism(p->getVertex(16), p->getVertex(17), p->getVertex(11), 
-                    p->getVertex(13), p->getVertex(14), p->getVertex(5)));              
+        (new MPrism(p->getVertex(16), p->getVertex(17), p->getVertex(11),
+                    p->getVertex(13), p->getVertex(14), p->getVertex(5)));
       prisms2.push_back
-        (new MPrism(p->getVertex(9), p->getVertex(7), p->getVertex(6), 
-                    p->getVertex(17), p->getVertex(16), p->getVertex(15)));             
+        (new MPrism(p->getVertex(9), p->getVertex(7), p->getVertex(6),
+                    p->getVertex(17), p->getVertex(16), p->getVertex(15)));
       prisms2.push_back
-        (new MPrism(p->getVertex(17), p->getVertex(16), p->getVertex(15), 
+        (new MPrism(p->getVertex(17), p->getVertex(16), p->getVertex(15),
                     p->getVertex(14), p->getVertex(13), p->getVertex(12)));
-    }      
+    }
     delete p;
   }
   gr->prisms = prisms2;
-  
+
   std::vector<MPyramid*> pyramids2;
   for(unsigned int i = 0; i < gr->pyramids.size(); i++){
     if(splitIntoHexas){
@@ -317,31 +317,31 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti
     if(p->getNumVertices() == 14){
       // Base
       pyramids2.push_back
-        (new MPyramid(p->getVertex(0), p->getVertex(5), p->getVertex(13), 
+        (new MPyramid(p->getVertex(0), p->getVertex(5), p->getVertex(13),
                       p->getVertex(6), p->getVertex(7)));
       pyramids2.push_back
-        (new MPyramid(p->getVertex(5), p->getVertex(1), p->getVertex(8), 
+        (new MPyramid(p->getVertex(5), p->getVertex(1), p->getVertex(8),
                       p->getVertex(13), p->getVertex(9)));
       pyramids2.push_back
-        (new MPyramid(p->getVertex(13), p->getVertex(8), p->getVertex(2), 
+        (new MPyramid(p->getVertex(13), p->getVertex(8), p->getVertex(2),
                       p->getVertex(10), p->getVertex(11)));
       pyramids2.push_back
         (new MPyramid(p->getVertex(6), p->getVertex(13), p->getVertex(10),
                       p->getVertex(3), p->getVertex(12)));
-      
+
       // Split remaining into tets
       // Top
       gr->tetrahedra.push_back
         ((new MTetrahedron(p->getVertex(7), p->getVertex(9), p->getVertex(12), p->getVertex(4))));
       gr->tetrahedra.push_back
         ((new MTetrahedron(p->getVertex(9), p->getVertex(11), p->getVertex(12), p->getVertex(4))));
-      
+
       // Upside down one
       gr->tetrahedra.push_back
         ((new MTetrahedron(p->getVertex(9), p->getVertex(12), p->getVertex(11), p->getVertex(13))));
       gr->tetrahedra.push_back
         ((new MTetrahedron(p->getVertex(7), p->getVertex(12), p->getVertex(9), p->getVertex(13))));
-      
+
       // Four tets around bottom perimeter
       gr->tetrahedra.push_back
         ((new MTetrahedron(p->getVertex(7), p->getVertex(9), p->getVertex(5), p->getVertex(13))));
@@ -363,9 +363,9 @@ static void Subdivide(GRegion *gr, bool splitIntoHexas, faceContainer &faceVerti
 
 void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas)
 {
-  Msg::StatusBar(2, true, "Refining mesh...");
+  Msg::StatusBar(true, "Refining mesh...");
   double t1 = Cpu();
-        
+
   // Create 2nd order mesh (using "2nd order complete" elements) to
   // generate vertex positions
   SetOrderN(m, 2, linear, false);
@@ -389,5 +389,5 @@ void RefineMesh(GModel *m, bool linear, bool splitIntoQuads, bool splitIntoHexas
 
 
   double t2 = Cpu();
-  Msg::StatusBar(2, true, "Done refining mesh (%g s)", t2 - t1);
+  Msg::StatusBar(true, "Done refining mesh (%g s)", t2 - t1);
 }
diff --git a/Parser/Gmsh.tab.cpp b/Parser/Gmsh.tab.cpp
index 88f6b84c650406e7aaa6d2702fde3cab3d63fbe4..1a5e50790397b439e655ce7da716de47c22421aa 100644
--- a/Parser/Gmsh.tab.cpp
+++ b/Parser/Gmsh.tab.cpp
@@ -7106,7 +7106,7 @@ yyreduce:
     {
       if(!strcmp((yyvsp[(1) - (3)].c), "Include")){
         std::string tmp = FixRelativePath(gmsh_yyname, (yyvsp[(2) - (3)].c));
-	Msg::StatusBar(2, true, "Reading '%s'...", tmp.c_str());
+	Msg::StatusBar(true, "Reading '%s'...", tmp.c_str());
 	// Warning: we explicitly ask ParseFile not to fclose() the included
         // file, in order to allow user functions definitions in these files.
         // The files will be closed in the next time OpenFile terminates. If
@@ -7117,7 +7117,7 @@ yyreduce:
         // instead of using the FILE pointer...)
 	ParseFile(tmp, false, true);
 	SetBoundingBox();
-	Msg::StatusBar(2, true, "Done reading '%s'", tmp.c_str());
+	Msg::StatusBar(true, "Done reading '%s'", tmp.c_str());
       }
       else if(!strcmp((yyvsp[(1) - (3)].c), "Print")){
 	// make sure we have the latest data from GEO_Internals in GModel
@@ -10579,7 +10579,7 @@ int PrintListOfDouble(char *format, List_T *list, char *buffer)
   // if format does not contain formatting characters, dump the list (useful for
   // quick debugging of lists)
   int numFormats = 0;
-  for(int i = 0; i < strlen(format); i++)
+  for(unsigned int i = 0; i < strlen(format); i++)
     if(format[i] == '%') numFormats++;
   if(!numFormats){
     strcpy(buffer, format);
diff --git a/Parser/Gmsh.y b/Parser/Gmsh.y
index 45aeb4fcfbe3f22fed53002409f200c5aba785a2..e1767323c15d765a8134232b5163a6f0e02d0684 100644
--- a/Parser/Gmsh.y
+++ b/Parser/Gmsh.y
@@ -2535,7 +2535,7 @@ Command :
     {
       if(!strcmp($1, "Include")){
         std::string tmp = FixRelativePath(gmsh_yyname, $2);
-	Msg::StatusBar(2, true, "Reading '%s'...", tmp.c_str());
+	Msg::StatusBar(true, "Reading '%s'...", tmp.c_str());
 	// Warning: we explicitly ask ParseFile not to fclose() the included
         // file, in order to allow user functions definitions in these files.
         // The files will be closed in the next time OpenFile terminates. If
@@ -2546,7 +2546,7 @@ Command :
         // instead of using the FILE pointer...)
 	ParseFile(tmp, false, true);
 	SetBoundingBox();
-	Msg::StatusBar(2, true, "Done reading '%s'", tmp.c_str());
+	Msg::StatusBar(true, "Done reading '%s'", tmp.c_str());
       }
       else if(!strcmp($1, "Print")){
 	// make sure we have the latest data from GEO_Internals in GModel
diff --git a/Post/PViewIO.cpp b/Post/PViewIO.cpp
index 371eb71c1561bfcb67be9ad3a1154735bf42b45e..63eb8e4d7ec98aed4115f4ca0a53f8e3a05c58f8 100644
--- a/Post/PViewIO.cpp
+++ b/Post/PViewIO.cpp
@@ -300,7 +300,7 @@ bool PView::readMED(const std::string &fileName, int fileIndex)
 
 bool PView::write(const std::string &fileName, int format, bool append)
 {
-  Msg::StatusBar(2, true, "Writing '%s'...", fileName.c_str());
+  Msg::StatusBar(true, "Writing '%s'...", fileName.c_str());
 
   bool ret;
   switch(format){
@@ -329,6 +329,6 @@ bool PView::write(const std::string &fileName, int format, bool append)
   default: ret = false; Msg::Error("Unknown view format %d", format); break;
   }
 
-  if(ret) Msg::StatusBar(2, true, "Done writing '%s'", fileName.c_str());
+  if(ret) Msg::StatusBar(true, "Done writing '%s'", fileName.c_str());
   return ret;
 }
diff --git a/README.txt b/README.txt
index 4e458c43a43e3e19078a6f255cc90ba414ea0df7..c9654a6b9f7c18d07643fa23605bc54d2df1393f 100644
--- a/README.txt
+++ b/README.txt
@@ -10,9 +10,8 @@ is located in doc/texinfo/. See the demos/ directory and the web site
 http://geuz.org/gmsh for additional examples.
 
 Building Gmsh from its source code requires a C++ compiler and CMake
-(http://cmake.org).  Building the graphical user interface requires FLTK 1.1.7
-or above (http://fltk.org), configured with OpenGL support. Building the 64 bit
-graphical version on MacOS X requires FLTK 1.3.
+(http://cmake.org).  Building the graphical user interface requires FLTK 1.3
+(http://fltk.org), configured with OpenGL support.
 
 
 Build Gmsh using CMake's graphical user interface
diff --git a/contrib/Fl_Tree/CMakeLists.txt b/contrib/Fl_Tree/CMakeLists.txt
deleted file mode 100644
index 0337353f64ace2729f2ad26eb9fecbd38fa781ad..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/CMakeLists.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-# Gmsh - Copyright (C) 1997-2012 C. Geuzaine, J.-F. Remacle
-#
-# See the LICENSE.txt file for license information. Please report all
-# bugs and problems to <gmsh@geuz.org>.
-
-set(SRC
-  Fl_Tree.cxx
-  Fl_Tree_Item.cxx
-  Fl_Tree_Item_Array.cxx
-  Fl_Tree_Prefs.cxx
-)
-
-file(GLOB_RECURSE HDR RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} *.H)
-append_gmsh_src(contrib/Fl_Tree "${SRC};${HDR}")
diff --git a/contrib/Fl_Tree/COPYING b/contrib/Fl_Tree/COPYING
deleted file mode 100644
index 94ee154c676fe47a849c1f04e3732285b91707fb..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/COPYING
+++ /dev/null
@@ -1,528 +0,0 @@
-                           Fl_Tree License
-                           May 29, 2005
-
-The Fl_Tree library and included programs are provided under the terms
-of the GNU Library General Public License (LGPL) with the following
-exceptions:
-
-    1. Modifications to the Fl_Tree configure script, config
-       header file, and makefiles by themselves to support
-       a specific platform do not constitute a modified or
-       derivative work.
-
-       The authors do request that such modifications be
-       contributed to the Fl_Tree project - send all
-       contributions to "erco at seriss dot com".
-
-    2. Widgets that are subclassed from Fl_Tree widgets do not
-       constitute a derivative work.
-
-    3. Static linking of applications and widgets to the
-       Fl_Tree library does not constitute a derivative work
-       and does not require the author to provide source
-       code for the application or widget, use the shared
-       Fl_Tree libraries, or link their applications or
-       widgets against a user-supplied version of Fl_Tree.
-
-       If you link the application or widget to a modified
-       version of Fl_Tree, then the changes to Fl_Tree must be
-       provided under the terms of the LGPL in sections
-       1, 2, and 4.
-
-    4. You do not have to provide a copy of the Fl_Tree license
-       with programs that are linked to the Fl_Tree library, nor
-       do you have to identify the Fl_Tree license in your
-       program or documentation as required by section 6
-       of the LGPL.
-
-       However, programs must still identify their use of Fl_Tree.
-       The following example statement can be included in user
-       documentation to satisfy this requirement:
-
-           [program/widget] is based in part on the work of
-           the Fl_Tree project http://seriss.com/people/erco/fltk/Fl_Tree/
-
------------------------------------------------------------------------
-
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-			 Version 2, June 1991
-
-	  Copyright (C) 1991 Free Software Foundation, Inc.
-       59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
-
-     Everyone is permitted to copy and distribute verbatim copies
-      of this license document, but changing it is not allowed.
-
-    [This is the first released version of the library GPL.  It is
-   numbered 2 because it goes with version 2 of the ordinary GPL.]
-
-			       Preamble
-
-  The licenses for most software are designed to take away your
-freedom to share and change it.  By contrast, the GNU General Public
-Licenses are intended to guarantee your freedom to share and change
-free software--to make sure the software is free for all its users.
-
-  This license, the Library General Public License, applies to some
-specially designated Free Software Foundation software, and to any
-other libraries whose authors decide to use it.  You can use it for
-your libraries, too.
-
-  When we speak of free software, we are referring to freedom, not
-price.  Our General Public Licenses are designed to make sure that you
-have the freedom to distribute copies of free software (and charge for
-this service if you wish), that you receive source code or can get it
-if you want it, that you can change the software or use pieces of it
-in new free programs; and that you know you can do these things.
-
-  To protect your rights, we need to make restrictions that forbid
-anyone to deny you these rights or to ask you to surrender the rights.
-These restrictions translate to certain responsibilities for you if
-you distribute copies of the library, or if you modify it.
-
-  For example, if you distribute copies of the library, whether gratis
-or for a fee, you must give the recipients all the rights that we gave
-you.  You must make sure that they, too, receive or can get the source
-code.  If you link a program with the library, you must provide
-complete object files to the recipients so that they can relink them
-with the library, after making changes to the library and recompiling
-it.  And you must show them these terms so they know their rights.
-
-  Our method of protecting your rights has two steps: (1) copyright
-the library, and (2) offer you this license which gives you legal
-permission to copy, distribute and/or modify the library.
-
-  Also, for each distributor's protection, we want to make certain
-that everyone understands that there is no warranty for this free
-library.  If the library is modified by someone else and passed on, we
-want its recipients to know that what they have is not the original
-version, so that any problems introduced by others will not reflect on
-the original authors' reputations.
-
-  Finally, any free program is threatened constantly by software
-patents.  We wish to avoid the danger that companies distributing free
-software will individually obtain patent licenses, thus in effect
-transforming the program into proprietary software.  To prevent this,
-we have made it clear that any patent must be licensed for everyone's
-free use or not licensed at all.
-
-  Most GNU software, including some libraries, is covered by the ordinary
-GNU General Public License, which was designed for utility programs.  This
-license, the GNU Library General Public License, applies to certain
-designated libraries.  This license is quite different from the ordinary
-one; be sure to read it in full, and don't assume that anything in it is
-the same as in the ordinary license.
-
-  The reason we have a separate public license for some libraries is that
-they blur the distinction we usually make between modifying or adding to a
-program and simply using it.  Linking a program with a library, without
-changing the library, is in some sense simply using the library, and is
-analogous to running a utility program or application program.  However, in
-a textual and legal sense, the linked executable is a combined work, a
-derivative of the original library, and the ordinary General Public License
-treats it as such.
-
-  Because of this blurred distinction, using the ordinary General
-Public License for libraries did not effectively promote software
-sharing, because most developers did not use the libraries.  We
-concluded that weaker conditions might promote sharing better.
-
-  However, unrestricted linking of non-free programs would deprive the
-users of those programs of all benefit from the free status of the
-libraries themselves.  This Library General Public License is intended to
-permit developers of non-free programs to use free libraries, while
-preserving your freedom as a user of such programs to change the free
-libraries that are incorporated in them.  (We have not seen how to achieve
-this as regards changes in header files, but we have achieved it as regards
-changes in the actual functions of the Library.)  The hope is that this
-will lead to faster development of free libraries.
-
-  The precise terms and conditions for copying, distribution and
-modification follow.  Pay close attention to the difference between a
-"work based on the library" and a "work that uses the library".  The
-former contains code derived from the library, while the latter only
-works together with the library.
-
-  Note that it is possible for a library to be covered by the ordinary
-General Public License rather than by this special one.
-
-		  GNU LIBRARY GENERAL PUBLIC LICENSE
-   TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
-
-  0. This License Agreement applies to any software library which
-contains a notice placed by the copyright holder or other authorized
-party saying it may be distributed under the terms of this Library
-General Public License (also called "this License").  Each licensee is
-addressed as "you".
-
-  A "library" means a collection of software functions and/or data
-prepared so as to be conveniently linked with application programs
-(which use some of those functions and data) to form executables.
-
-  The "Library", below, refers to any such software library or work
-which has been distributed under these terms.  A "work based on the
-Library" means either the Library or any derivative work under
-copyright law: that is to say, a work containing the Library or a
-portion of it, either verbatim or with modifications and/or translated
-straightforwardly into another language.  (Hereinafter, translation is
-included without limitation in the term "modification".)
-
-  "Source code" for a work means the preferred form of the work for
-making modifications to it.  For a library, complete source code means
-all the source code for all modules it contains, plus any associated
-interface definition files, plus the scripts used to control compilation
-and installation of the library.
-
-  Activities other than copying, distribution and modification are not
-covered by this License; they are outside its scope.  The act of
-running a program using the Library is not restricted, and output from
-such a program is covered only if its contents constitute a work based
-on the Library (independent of the use of the Library in a tool for
-writing it).  Whether that is true depends on what the Library does
-and what the program that uses the Library does.
-
-  1. You may copy and distribute verbatim copies of the Library's
-complete source code as you receive it, in any medium, provided that
-you conspicuously and appropriately publish on each copy an
-appropriate copyright notice and disclaimer of warranty; keep intact
-all the notices that refer to this License and to the absence of any
-warranty; and distribute a copy of this License along with the
-Library.
-
-  You may charge a fee for the physical act of transferring a copy,
-and you may at your option offer warranty protection in exchange for a
-fee.
-
-  2. You may modify your copy or copies of the Library or any portion
-of it, thus forming a work based on the Library, and copy and
-distribute such modifications or work under the terms of Section 1
-above, provided that you also meet all of these conditions:
-
-    a) The modified work must itself be a software library.
-
-    b) You must cause the files modified to carry prominent notices
-    stating that you changed the files and the date of any change.
-
-    c) You must cause the whole of the work to be licensed at no
-    charge to all third parties under the terms of this License.
-
-    d) If a facility in the modified Library refers to a function or a
-    table of data to be supplied by an application program that uses
-    the facility, other than as an argument passed when the facility
-    is invoked, then you must make a good faith effort to ensure that,
-    in the event an application does not supply such function or
-    table, the facility still operates, and performs whatever part of
-    its purpose remains meaningful.
-
-    (For example, a function in a library to compute square roots has
-    a purpose that is entirely well-defined independent of the
-    application.  Therefore, Subsection 2d requires that any
-    application-supplied function or table used by this function must
-    be optional: if the application does not supply it, the square
-    root function must still compute square roots.)
-
-These requirements apply to the modified work as a whole.  If
-identifiable sections of that work are not derived from the Library,
-and can be reasonably considered independent and separate works in
-themselves, then this License, and its terms, do not apply to those
-sections when you distribute them as separate works.  But when you
-distribute the same sections as part of a whole which is a work based
-on the Library, the distribution of the whole must be on the terms of
-this License, whose permissions for other licensees extend to the
-entire whole, and thus to each and every part regardless of who wrote
-it.
-
-Thus, it is not the intent of this section to claim rights or contest
-your rights to work written entirely by you; rather, the intent is to
-exercise the right to control the distribution of derivative or
-collective works based on the Library.
-
-In addition, mere aggregation of another work not based on the Library
-with the Library (or with a work based on the Library) on a volume of
-a storage or distribution medium does not bring the other work under
-the scope of this License.
-
-  3. You may opt to apply the terms of the ordinary GNU General Public
-License instead of this License to a given copy of the Library.  To do
-this, you must alter all the notices that refer to this License, so
-that they refer to the ordinary GNU General Public License, version 2,
-instead of to this License.  (If a newer version than version 2 of the
-ordinary GNU General Public License has appeared, then you can specify
-that version instead if you wish.)  Do not make any other change in
-these notices.
-
-  Once this change is made in a given copy, it is irreversible for
-that copy, so the ordinary GNU General Public License applies to all
-subsequent copies and derivative works made from that copy.
-
-  This option is useful when you wish to copy part of the code of
-the Library into a program that is not a library.
-
-  4. You may copy and distribute the Library (or a portion or
-derivative of it, under Section 2) in object code or executable form
-under the terms of Sections 1 and 2 above provided that you accompany
-it with the complete corresponding machine-readable source code, which
-must be distributed under the terms of Sections 1 and 2 above on a
-medium customarily used for software interchange.
-
-  If distribution of object code is made by offering access to copy
-from a designated place, then offering equivalent access to copy the
-source code from the same place satisfies the requirement to
-distribute the source code, even though third parties are not
-compelled to copy the source along with the object code.
-
-  5. A program that contains no derivative of any portion of the
-Library, but is designed to work with the Library by being compiled or
-linked with it, is called a "work that uses the Library".  Such a
-work, in isolation, is not a derivative work of the Library, and
-therefore falls outside the scope of this License.
-
-  However, linking a "work that uses the Library" with the Library
-creates an executable that is a derivative of the Library (because it
-contains portions of the Library), rather than a "work that uses the
-library".  The executable is therefore covered by this License.
-Section 6 states terms for distribution of such executables.
-
-  When a "work that uses the Library" uses material from a header file
-that is part of the Library, the object code for the work may be a
-derivative work of the Library even though the source code is not.
-Whether this is true is especially significant if the work can be
-linked without the Library, or if the work is itself a library.  The
-threshold for this to be true is not precisely defined by law.
-
-  If such an object file uses only numerical parameters, data
-structure layouts and accessors, and small macros and small inline
-functions (ten lines or less in length), then the use of the object
-file is unrestricted, regardless of whether it is legally a derivative
-work.  (Executables containing this object code plus portions of the
-Library will still fall under Section 6.)
-
-  Otherwise, if the work is a derivative of the Library, you may
-distribute the object code for the work under the terms of Section 6.
-Any executables containing that work also fall under Section 6,
-whether or not they are linked directly with the Library itself.
-
-  6. As an exception to the Sections above, you may also compile or
-link a "work that uses the Library" with the Library to produce a
-work containing portions of the Library, and distribute that work
-under terms of your choice, provided that the terms permit
-modification of the work for the customer's own use and reverse
-engineering for debugging such modifications.
-
-  You must give prominent notice with each copy of the work that the
-Library is used in it and that the Library and its use are covered by
-this License.  You must supply a copy of this License.  If the work
-during execution displays copyright notices, you must include the
-copyright notice for the Library among them, as well as a reference
-directing the user to the copy of this License.  Also, you must do one
-of these things:
-
-    a) Accompany the work with the complete corresponding
-    machine-readable source code for the Library including whatever
-    changes were used in the work (which must be distributed under
-    Sections 1 and 2 above); and, if the work is an executable linked
-    with the Library, with the complete machine-readable "work that
-    uses the Library", as object code and/or source code, so that the
-    user can modify the Library and then relink to produce a modified
-    executable containing the modified Library.  (It is understood
-    that the user who changes the contents of definitions files in the
-    Library will not necessarily be able to recompile the application
-    to use the modified definitions.)
-
-    b) Accompany the work with a written offer, valid for at
-    least three years, to give the same user the materials
-    specified in Subsection 6a, above, for a charge no more
-    than the cost of performing this distribution.
-
-    c) If distribution of the work is made by offering access to copy
-    from a designated place, offer equivalent access to copy the above
-    specified materials from the same place.
-
-    d) Verify that the user has already received a copy of these
-    materials or that you have already sent this user a copy.
-
-  For an executable, the required form of the "work that uses the
-Library" must include any data and utility programs needed for
-reproducing the executable from it.  However, as a special exception,
-the source code distributed need not include anything that is normally
-distributed (in either source or binary form) with the major
-components (compiler, kernel, and so on) of the operating system on
-which the executable runs, unless that component itself accompanies
-the executable.
-
-  It may happen that this requirement contradicts the license
-restrictions of other proprietary libraries that do not normally
-accompany the operating system.  Such a contradiction means you cannot
-use both them and the Library together in an executable that you
-distribute.
-
-  7. You may place library facilities that are a work based on the
-Library side-by-side in a single library together with other library
-facilities not covered by this License, and distribute such a combined
-library, provided that the separate distribution of the work based on
-the Library and of the other library facilities is otherwise
-permitted, and provided that you do these two things:
-
-    a) Accompany the combined library with a copy of the same work
-    based on the Library, uncombined with any other library
-    facilities.  This must be distributed under the terms of the
-    Sections above.
-
-    b) Give prominent notice with the combined library of the fact
-    that part of it is a work based on the Library, and explaining
-    where to find the accompanying uncombined form of the same work.
-
-  8. You may not copy, modify, sublicense, link with, or distribute
-the Library except as expressly provided under this License.  Any
-attempt otherwise to copy, modify, sublicense, link with, or
-distribute the Library is void, and will automatically terminate your
-rights under this License.  However, parties who have received copies,
-or rights, from you under this License will not have their licenses
-terminated so long as such parties remain in full compliance.
-
-  9. You are not required to accept this License, since you have not
-signed it.  However, nothing else grants you permission to modify or
-distribute the Library or its derivative works.  These actions are
-prohibited by law if you do not accept this License.  Therefore, by
-modifying or distributing the Library (or any work based on the
-Library), you indicate your acceptance of this License to do so, and
-all its terms and conditions for copying, distributing or modifying
-the Library or works based on it.
-
-  10. Each time you redistribute the Library (or any work based on the
-Library), the recipient automatically receives a license from the
-original licensor to copy, distribute, link with or modify the Library
-subject to these terms and conditions.  You may not impose any further
-restrictions on the recipients' exercise of the rights granted herein.
-You are not responsible for enforcing compliance by third parties to
-this License.
-
-  11. If, as a consequence of a court judgment or allegation of patent
-infringement or for any other reason (not limited to patent issues),
-conditions are imposed on you (whether by court order, agreement or
-otherwise) that contradict the conditions of this License, they do not
-excuse you from the conditions of this License.  If you cannot
-distribute so as to satisfy simultaneously your obligations under this
-License and any other pertinent obligations, then as a consequence you
-may not distribute the Library at all.  For example, if a patent
-license would not permit royalty-free redistribution of the Library by
-all those who receive copies directly or indirectly through you, then
-the only way you could satisfy both it and this License would be to
-refrain entirely from distribution of the Library.
-
-If any portion of this section is held invalid or unenforceable under any
-particular circumstance, the balance of the section is intended to apply,
-and the section as a whole is intended to apply in other circumstances.
-
-It is not the purpose of this section to induce you to infringe any
-patents or other property right claims or to contest validity of any
-such claims; this section has the sole purpose of protecting the
-integrity of the free software distribution system which is
-implemented by public license practices.  Many people have made
-generous contributions to the wide range of software distributed
-through that system in reliance on consistent application of that
-system; it is up to the author/donor to decide if he or she is willing
-to distribute software through any other system and a licensee cannot
-impose that choice.
-
-This section is intended to make thoroughly clear what is believed to
-be a consequence of the rest of this License.
-
-  12. If the distribution and/or use of the Library is restricted in
-certain countries either by patents or by copyrighted interfaces, the
-original copyright holder who places the Library under this License may add
-an explicit geographical distribution limitation excluding those countries,
-so that distribution is permitted only in or among countries not thus
-excluded.  In such case, this License incorporates the limitation as if
-written in the body of this License.
-
-  13. The Free Software Foundation may publish revised and/or new
-versions of the Library General Public License from time to time.
-Such new versions will be similar in spirit to the present version,
-but may differ in detail to address new problems or concerns.
-
-Each version is given a distinguishing version number.  If the Library
-specifies a version number of this License which applies to it and
-"any later version", you have the option of following the terms and
-conditions either of that version or of any later version published by
-the Free Software Foundation.  If the Library does not specify a
-license version number, you may choose any version ever published by
-the Free Software Foundation.
-
-  14. If you wish to incorporate parts of the Library into other free
-programs whose distribution conditions are incompatible with these,
-write to the author to ask for permission.  For software which is
-copyrighted by the Free Software Foundation, write to the Free
-Software Foundation; we sometimes make exceptions for this.  Our
-decision will be guided by the two goals of preserving the free status
-of all derivatives of our free software and of promoting the sharing
-and reuse of software generally.
-
-			    NO WARRANTY
-
-  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
-WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
-EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
-OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
-KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
-IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
-PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
-LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
-THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
-
-  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
-WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
-AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
-FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
-CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
-LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
-RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
-FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
-SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
-DAMAGES.
-
-		     END OF TERMS AND CONDITIONS
-
-     Appendix: How to Apply These Terms to Your New Libraries
-
-  If you develop a new library, and you want it to be of the greatest
-possible use to the public, we recommend making it free software that
-everyone can redistribute and change.  You can do so by permitting
-redistribution under these terms (or, alternatively, under the terms of the
-ordinary General Public License).
-
-  To apply these terms, attach the following notices to the library.  It is
-safest to attach them to the start of each source file to most effectively
-convey the exclusion of warranty; and each file should have at least the
-"copyright" line and a pointer to where the full notice is found.
-
-    <one line to give the library's name and a brief idea of what it does.>
-    Copyright (C) <year>  <name of author>
-
-    This library is free software; you can redistribute it and/or
-    modify it under the terms of the GNU Library General Public
-    License as published by the Free Software Foundation; either
-    version 2 of the License, or (at your option) any later version.
-
-    This library is distributed in the hope that it will be useful,
-    but WITHOUT ANY WARRANTY; without even the implied warranty of
-    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-    Library General Public License for more details.
-
-    You should have received a copy of the GNU Library General Public
-    License along with this library; if not, write to the Free
-    Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
-Also add information on how to contact you by electronic and paper mail.
-
-You should also get your employer (if you work as a programmer) or your
-school, if any, to sign a "copyright disclaimer" for the library, if
-necessary.  Here is a sample; alter the names:
-
-  Yoyodyne, Inc., hereby disclaims all copyright interest in the
-  library `Frob' (a library for tweaking knobs) written by James Random Hacker.
-
-  <signature of Ty Coon>, 1 April 1990
-  Ty Coon, President of Vice
-
-That's all there is to it!
diff --git a/contrib/Fl_Tree/FL/Fl_Tree.H b/contrib/Fl_Tree/FL/Fl_Tree.H
deleted file mode 100644
index e2e5e304b63b67025828f44142bedba67d854f50..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/FL/Fl_Tree.H
+++ /dev/null
@@ -1,634 +0,0 @@
-#ifndef FL_TREE_H
-#define FL_TREE_H
-
-#include <FL/Fl.H>
-#include <FL/Fl_Group.H>
-#include <FL/Fl_Scrollbar.H>
-#include <FL/fl_draw.H>
-
-#include <FL/Fl_Tree_Item.H>
-#include <FL/Fl_Tree_Prefs.H>
-
-//////////////////////
-// FL/Fl_Tree.H
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-///
-/// \file
-/// \brief This file contains the definitions of the Fl_Tree class
-///
-
-/// \class Fl_Tree
-///
-/// \brief Tree widget.
-///
-/// \code
-///     Fl_Tree                                         // Top level widget
-///        |--- Fl_Tree_Item                            // Items in the tree
-///        |--- Fl_Tree_Prefs                           // Preferences for the tree
-///                  |--- Fl_Tree_Connector (enum)      // Connection modes
-///                  |--- Fl_Tree_Select (enum)         // Selection modes
-///                  |--- Fl_Tree_Sort (enum)           // Sort behavior
-/// \endcode
-///
-///     An expandable tree widget.
-///
-///     Similar to Fl_Browser, Fl_Tree is browser of Fl_Tree_Item's, which can be
-///     in a parented hierarchy. Subtrees can be expanded or closed. Items can be
-///     added, deleted, inserted, sorted and re-ordered.
-///
-///     The tree items may also contain other FLTK widgets, like buttons, input fields,
-///     or even "custom" widgets.
-///
-///     The simple way to define a tree:
-/// \code
-///    Fl_Tree tree(X,Y,W,H);
-///    tree.begin();
-///      tree.add("Flintstones/Fred");
-///      tree.add("Flintstones/Wilma");
-///      tree.add("Flintstones/Pebbles");
-///      tree.add("Simpsons/Homer");
-///      tree.add("Simpsons/Marge");
-///      tree.add("Simpsons/Bart");
-///      tree.add("Simpsons/Lisa");
-///    tree.end();
-/// \endcode
-///     
-///     Items can be added with Fl_Tree::add(),
-///     removed with Fl_Tree::remove(),
-///     inserted with Fl_Tree::insert_above(),
-///     selected/deselected with Fl_Tree::select() and Fl_Tree::deselect().
-///     Items can be swapped with Fl_Tree_Item::swap_children(), sorting control via
-///     Fl_Tree::sortorder().
-///
-///     The tree can have different selection behaviors controlled by Fl_Tree::selectmode().
-///
-///     FLTK and custom FLTK widgets can be assigned to tree items via Fl_Tree_Item::widget().
-///
-///     Parent nodes can be open/closed with open() and close(), icons can be assigned
-///     or redefined with some or all items via 
-///     Fl_Tree_Item::openicon(), 
-///     Fl_Tree_Item::closeicon(),
-///     Fl_Tree_Item::usericon().
-///
-///     Various default preferences can be manipulated vi Fl_Tree_Prefs, including
-///     colors, margins, connection lines. 
-///
-///     \image html tree-elements.png
-///
-
-class Fl_Tree : public Fl_Group {
-    Fl_Tree_Item  *_root;		// can be null!
-    Fl_Tree_Item  *_item_clicked;
-    Fl_Tree_Prefs  _prefs;		// all the tree's settings
-    Fl_Scrollbar  *_vscroll;
-
-protected:
-    /// Find the item that was clicked.
-    /// You probably want to use item_clicked() instead, which is fast.
-    ///
-    /// This method walks the entire tree looking for the first item that is
-    /// under the mouse (ie. at Fl::event_x()/Fl:event_y().
-    ///
-    /// Use this method /only/ if you've subclassed Fl_Tree, and are receiving
-    /// events before Fl_Tree has been able to process and update item_clicked().
-    /// 
-    /// \returns the item clicked, or 0 if no item was under the current event.
-    ///
-    const Fl_Tree_Item *find_clicked() const {
-        if ( ! _root ) return(0);
-        return(_root->find_clicked());
-    }
-    /// Set the item that was last clicked.
-    /// Should only be used by subclasses needing to change this value.
-    /// Normally Fl_Tree manages this value.
-    ///
-    void item_clicked(Fl_Tree_Item* val) {
-        _item_clicked = val;
-    }
-
-public:
-    Fl_Tree(int X, int Y, int W, int H, const char *L=0);
-    ~Fl_Tree();
-    int handle(int e);
-    void draw();
-
-    ///////////////////////
-    // root methods
-    ///////////////////////
-
-    /// Set the label for the root item. 
-    ///
-    /// Makes an internally managed copy of 'new_label'.
-    ///
-    void root_label(const char *new_label) {
-        if ( ! _root ) return;
-        _root->label(new_label);
-    }
-    /// Returns the root item.
-    Fl_Tree_Item* root() {
-        return(_root);
-    }
-
-    ////////////////////////////////
-    // Item creation/removal methods
-    ////////////////////////////////
-    Fl_Tree_Item *add(const char *path);
-    Fl_Tree_Item *insert_above(Fl_Tree_Item *above, const char *name);
-
-    /// Remove the specified 'item' from the tree.
-    /// If it has children, all those are removed too.
-    /// \returns 0 if done, -1 if 'item' not found.
-    ///
-    int remove(Fl_Tree_Item *item) {
-        if ( !item ) return(0);
-        if ( item == _root ) {
-	    clear();
-	} else {
-	    Fl_Tree_Item *parent = item->parent();	// find item's parent
-	    if ( ! parent ) return(-1);
-	    parent->remove_child(item);			// remove child + children
-	}
-	return(0);
-    } 
-    /// Clear all children from the tree.
-    /// The tree will be left completely empty.
-    ///
-    void clear() {
-        if ( ! _root ) return;
-	_root->clear_children();
-	delete _root; _root = 0;
-    } 
-    /// Clear all the children of a particular node in the tree.
-    void clear_children(Fl_Tree_Item *item) {
-        if ( item->has_children() ) {
-	    item->clear_children();
-	    redraw();			// redraw only if there were children to clear
-	}
-    } 
-
-    ////////////////////////
-    // Item lookup methods
-    ////////////////////////
-    Fl_Tree_Item *find_item(const char *path);
-    const Fl_Tree_Item *find_item(const char *path) const;
-
-    /// Return the parent for specified 'item'.
-    ///
-    /// \returns item's parent, or 0 if none (root).
-    ///
-    Fl_Tree_Item *parent(Fl_Tree_Item *item) {
-        return(item->parent());
-    }
-    /// Return the item that was last clicked.
-    ///
-    /// Valid only from within an Fl_Tree::callback().
-    ///
-    /// \returns the item clicked, or 0 if none.
-    ///
-    Fl_Tree_Item *item_clicked() {
-        return(_item_clicked);
-    }
-    /// Returns the first item in the tree.
-    ///
-    /// Use this to walk the tree in the forward direction, eg:
-    /// \code
-    /// for ( Fl_Tree_Item *item = tree->first(); item; item = item->next() ) {
-    ///     printf("Item: %s\n", item->label());
-    /// }
-    /// \endcode
-    ///
-    /// \returns first item in tree, or 0 if none (tree empty).
-    ///
-    Fl_Tree_Item *first() {
-        return(_root);					// first item always root
-    }
-    /// Returns the last item in the tree.
-    ///
-    /// Use this to walk the tree in reverse, eg:
-    ///
-    /// \code
-    /// for ( Fl_Tree_Item *item = tree->last(); item; item = item->prev() ) {
-    ///     printf("Item: %s\n", item->label());
-    /// }
-    /// \endcode
-    ///
-    /// \returns last item in the tree, or 0 if none (tree empty).
-    ///
-    Fl_Tree_Item *last() {
-        if ( ! _root ) return(0);
-        Fl_Tree_Item *item = _root;
-        while ( item->has_children() ) {
-	    item = item->child(item->children()-1);
-	}
-	return(item);
-    }
-
-    //////////////////////////
-    // Item open/close methods
-    //////////////////////////
-
-    /// Open the specified 'item'.
-    /// This causes the item's children (if any) to be shown.
-    /// Handles redrawing if anything was actually changed.
-    ///
-    void open(Fl_Tree_Item *item) {
-        if ( ! item->is_open() ) {
-	    item->open();
-	    redraw();
-	}
-    }
-    /// Opens the item specified by a 'menu item' style pathname (eg: "Parent/child/item").
-    /// This causes the item's children (if any) to be shown.
-    /// Handles redrawing if anything was actually changed.
-    ///
-    /// \returns
-    ///     -   0 : OK
-    ///     -  -1 : item was not found
-    ///         
-    int open(const char *path) {
-        Fl_Tree_Item *item = find_item(path);
-        if ( item ) {
-	    open(item);
-	    return(0);
-	}
-	return(-1);
-    }
-    /// Closes the 'item'.
-    /// Handles redrawing if anything was actually changed.
-    ///
-    void close(Fl_Tree_Item *item) {
-        if ( ! item->is_close() ) {
-	    item->close();
-	    redraw();
-	}
-    }
-    /// Closes the item specified by 'path', eg: "Parent/child/item".
-    ///
-    /// Handles redrawing if anything was actually changed.
-    ///
-    /// \returns
-    ///     -   0 -- OK
-    ///     -  -1 -- item was not found
-    ///         
-    int close(const char *path) {
-        Fl_Tree_Item *item = find_item(path);
-        if ( item ) {
-	    close(item);
-	    return(0);
-	}
-	return(-1);
-    }
-    /// See if item is open.
-    ///
-    /// Items that are 'open' are themselves not necessarily visible;
-    /// one of the item's parents might be closed.
-    ///
-    /// \returns
-    ///     -  1 : item is open
-    ///     -  0 : item is closed
-    ///
-    int is_open(Fl_Tree_Item *item) const {
-        return(item->is_open()?1:0);
-    }
-    /// See if item specified by 'path' (eg: "Parent/child/item") is open.
-    ///
-    /// Items that are 'open' are themselves not necessarily visible;
-    /// one of the item's parents might be closed.
-    ///
-    /// \returns
-    ///     -    1 : item is open
-    ///     -    0 : item is closed
-    ///     -   -1 : item was not found
-    ///
-    int is_open(const char *path) const {
-        const Fl_Tree_Item *item = find_item(path);
-        if ( item ) return(item->is_open()?1:0);
-	return(-1);
-    }
-    /// See if item is closed.
-    /// \returns
-    ///     -   1 : item is open
-    ///     -   0 : item is closed
-    ///
-    int is_close(Fl_Tree_Item *item) const {
-        return(item->is_close());
-    }
-    /// See if item specified by 'path' (eg: "Parent/child/item") is closed.
-    ///
-    /// \returns
-    ///     -   1 : item is closed
-    ///     -   0 : item is open
-    ///     -  -1 : item was not found
-    ///
-    int is_close(const char *path) const {
-        const Fl_Tree_Item *item = find_item(path);
-        if ( item ) return(item->is_close()?1:0);
-	return(-1);
-    }
-
-    /////////////////////////
-    // Item selection methods
-    /////////////////////////
-
-    /// Select the specified item. Use 'deselect()' to de-select it.
-    /// Handles redrawing if anything was actually changed.
-    ///
-    void select(Fl_Tree_Item *item) {
-        if ( ! item->is_selected() ) {
-	    item->select();
-	    redraw();
-	}
-    }
-    /// Select an item specified by 'path' (eg: "Parent/child/item").
-    /// Handles redrawing if anything was actually changed.
-    ///
-    /// \returns
-    ///     -   0 : OK
-    ///     -  -1 : item was not found
-    ///
-    int select(const char *path) {
-        Fl_Tree_Item *item = find_item(path);
-        if ( item ) {
-	    select(item);
-	    return(0);
-	}
-	return(-1);
-    }
-    /// Toggle item's select state.
-    /// Handles redrawing.
-    ///
-    void select_toggle(Fl_Tree_Item *item) {
-        item->select_toggle();
-	redraw();
-    }
-    /// De-select the specified item.
-    /// Handles redrawing if anything was actually changed.
-    ///
-    void deselect(Fl_Tree_Item *item) {
-        if ( item->is_selected() ) {
-	    item->deselect();
-	    redraw();
-	}
-    }
-    /// De-select an item specified by 'path' (eg: "Parent/child/item").
-    /// Handles redrawing if anything was actually changed.
-    ///
-    ///  \returns
-    ///     -   0 : OK
-    ///     -  -1 : item was not found
-    ///
-    int deselect(const char *path) {
-        Fl_Tree_Item *item = find_item(path);
-        if ( item ) {
-	    deselect(item);
-	    return(0);
-	}
-	return(-1);
-    }
-
-    int deselect_all(Fl_Tree_Item *item=0);
-    int select_only(Fl_Tree_Item *selitem);
-
-    /// See if the specified item is selected.
-    /// \return
-    ///     -   1 : item selected
-    ///     -   0 : item deselected
-    ///
-    int is_selected(Fl_Tree_Item *item) const {
-        return(item->is_selected()?1:0);
-    }
-    /// See if item specified by 'path' (eg: "Parent/child/item") is selected.
-    ///
-    /// \returns
-    ///     -   1 : item selected
-    ///     -   0 : item deselected
-    ///     -  -1 : item was not found
-    ///
-    int is_selected(const char *path) {
-        Fl_Tree_Item *item = find_item(path);
-        if ( item ) return(is_selected(item));
-	return(-1);
-    }
-    /// Print the tree as 'ascii art' to stdout.
-    /// Used mainly for debugging.
-    ///
-    void show_self() {
-        if ( ! _root ) return;
-        _root->show_self();
-    }
-
-    /////////////////////////////////
-    // Item attribute related methods
-    /////////////////////////////////
-
-    /// Get the default label fontsize used for creating new items.
-    int labelsize() const {
-        return(_prefs.labelsize());
-    }
-    /// Set the default label font size used for creating new items.
-    /// To change the font size on a per-item basis, use Fl_Tree_Item::labelsize(int)
-    ///
-    void labelsize(int val) {
-        _prefs.labelsize(val);
-    }
-
-    /// Get the default font face used for item's labels when new items are created.
-    ///
-    /// Don't use this if you want to change an existing label() size; use
-    /// item->labelfont() instead.
-    ///
-    int labelfont() const {
-        return(_prefs.labelfont());
-    }
-    /// Set the default font face used for item's labels when new items are created.
-    ///
-    /// Don't use this if you want to change an existing label() size; use
-    /// item->labelfont(int) instead.
-    ///
-    void labelfont(int val) {
-        _prefs.labelfont(val);
-    }
-    /// Get the amount of white space (in pixels) that should appear
-    /// between the widget's left border and the tree's contents.
-    ///
-    int  marginleft() const {
-        return(_prefs.marginleft());
-    }
-    /// Set the amount of white space (in pixels) that should appear
-    /// between the widget's left border and the left side of the tree's contents.
-    ///
-    void marginleft(int val) {
-        _prefs.marginleft(val);
-	redraw();
-    }
-    /// Get the amount of white space (in pixels) that should appear
-    /// between the widget's top border and the top of the tree's contents.
-    ///
-    int  margintop() const {
-        return(_prefs.margintop());
-    }
-    /// Sets the amount of white space (in pixels) that should appear
-    /// between the widget's top border and the top of the tree's contents.
-    ///
-    void margintop(int val) {
-        _prefs.margintop(val);
-	redraw();
-    }
-    /// Gets the width of the horizontal connection lines (in pixels) 
-    /// that appear to the left of each tree item's label.
-    ///
-    int  connectorwidth() const {
-        return(_prefs.connectorwidth());
-    }
-    /// Sets the width of the horizontal connection lines (in pixels) 
-    /// that appear to the left of each tree item's label.
-    ///
-    void connectorwidth(int val) {
-        _prefs.connectorwidth(val);
-	redraw();
-    }
-    /// Returns the Fl_Pixmap being used as the default user icon for newly created items.
-    /// Returns zero if no icon has been set, which is the default.
-    ///
-    Fl_Pixmap *usericon() const {
-        return(_prefs.usericon());
-    }
-    /// Sets the Fl_Pixmap to be used as the default user icon for all
-    /// newly created items.
-    ///
-    /// If you want to specify user icons on a per-item basis,
-    /// use Fl_Tree_Item::usericon() instead.
-    ///
-    /// \param[in] val -- The new pixmap to be used, or
-    ///                   zero to disable user icons.
-    ///
-    void usericon(Fl_Pixmap *val) {
-        _prefs.usericon(val);
-	redraw();
-    }
-    /// Returns the icon to be used as the 'open' icon.
-    /// If none was set, the internal default is returned,
-    /// a simple '[+]' icon.
-    ///
-    Fl_Pixmap *openicon() const {
-        return(_prefs.openicon());
-    }
-    /// Sets the icon to be used as the 'open' icon.
-    /// This overrides the built in default '[+]' icon.
-    ///
-    /// \param[in] val -- The new pixmap, or zero to use the default [+] icon.
-    ///
-    void openicon(Fl_Pixmap *val) {
-        _prefs.openicon(val);
-	redraw();
-    }
-    /// Returns the icon to be used as the 'close' icon.
-    /// If none was set, the internal default is returned,
-    /// a simple '[-]' icon.
-    ///
-    Fl_Pixmap *closeicon() const {
-        return(_prefs.closeicon());
-    }
-    /// Sets the icon to be used as the 'close' icon.
-    /// This overrides the built in default '[-]' icon.
-    ///
-    /// \param[in] val -- The new pixmap, or zero to use the default [-] icon.
-    ///
-    void closeicon(Fl_Pixmap *val) {
-        _prefs.closeicon(val);
-	redraw();
-    }
-    /// Returns 1 if the collapse icon is enabled, 0 if not.
-    int showcollapse() const {
-        return(_prefs.showcollapse());
-    }
-    /// Set if we should show the collapse icon or not.
-    /// If collapse icons are disabled, the user will not be able
-    /// to interactively collapse items in the tree, unless the application
-    /// provides some other means via open() and close().
-    ///
-    /// \param[in] val 1: shows collapse icons (default),\n
-    ///                0: hides collapse icons.
-    ///
-    void showcollapse(int val) {
-        _prefs.showcollapse(val);
-	redraw();
-    }
-    /// Returns 1 if the root item is to be shown, or 0 if not.
-    int showroot() const {
-        return(_prefs.showroot());
-    }
-    /// Set if the root item should be shown or not.
-    /// \param[in] val 1 -- show the root item (default)\n
-    ///                0 -- hide the root item.
-    ///
-    void showroot(int val) {
-        _prefs.showroot(val);
-	redraw();
-    }
-    /// Returns the line drawing style for inter-connecting items.
-    Fl_Tree_Connector connectorstyle() const {
-        return(_prefs.connectorstyle());
-    }
-    /// Sets the line drawing style for inter-connecting items.
-    void connectorstyle(Fl_Tree_Connector val) {
-        _prefs.connectorstyle(val);
-	redraw();
-    }
-    /// Set the default sort order used when items are added to the tree.
-    ///     See Fl_Tree_Sort for possible values.
-    ///
-    Fl_Tree_Sort sortorder() const {
-        return(_prefs.sortorder());
-    }
-    /// Gets the sort order used to add items to the tree.
-    void sortorder(Fl_Tree_Sort val) {
-        _prefs.sortorder(val);
-	// no redraw().. only affects new add()itions
-    }
-    /// Sets the style of box used to draw selected items.
-    /// This is an fltk Fl_Boxtype.
-    /// The default is influenced by FLTK's current Fl::scheme()
-    ///
-    Fl_Boxtype selectbox() const {
-        return(_prefs.selectbox());
-    }
-    /// Gets the style of box used to draw selected items.
-    /// This is an fltk Fl_Boxtype.
-    /// The default is influenced by FLTK's current Fl::scheme()
-    ///
-    void selectbox(Fl_Boxtype val) {
-        _prefs.selectbox(val);
-	redraw();
-    }
-    /// Gets the tree's current selection mode.
-    Fl_Tree_Select selectmode() const {
-        return(_prefs.selectmode());
-    }
-    /// Sets the tree's selection mode.
-    void selectmode(Fl_Tree_Select val) {
-        _prefs.selectmode(val);
-    }
-};
-
-#endif /*FL_TREE_H*/
diff --git a/contrib/Fl_Tree/FL/Fl_Tree_Item.H b/contrib/Fl_Tree/FL/Fl_Tree_Item.H
deleted file mode 100644
index b2d67ba76b3900aef9805003ea9411c9bc5aa4dc..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/FL/Fl_Tree_Item.H
+++ /dev/null
@@ -1,301 +0,0 @@
-#ifndef FL_TREE_ITEM_H
-#define FL_TREE_ITEM_H
-
-#include <FL/Fl.H>
-#include <FL/Fl_Widget.H>
-#include <FL/Fl_Pixmap.H>
-#include <FL/fl_draw.H>
-
-#include <FL/Fl_Tree_Item_Array.H>
-#include <FL/Fl_Tree_Prefs.H>
-
-//////////////////////
-// FL/Fl_Tree_Item.H
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-///
-/// \file
-/// \brief This file contains the definitions for Fl_Tree_Item
-///
-
-/// \brief Tree item
-///
-/// This class is a single tree item, and manages all of the item's attributes.
-/// Fl_Tree_Item is used by Fl_Tree, which is comprised of many instances of Fl_Tree_Item.
-///
-/// Fl_Tree_Item is hierarchical; it dynamically manages an Fl_Tree_Item_Array of children
-/// that are themselves instances of Fl_Tree_Item. Each item can have zero or more children.
-/// When an item has children, close() and open() can be used to hide or show them.
-///
-/// Items have their own attributes; font size, face, color.
-/// Items maintain their own hierarchy of children.
-///
-/// When you make changes to items, you'll need to tell the tree to redraw()
-/// for the changes to show up.
-///
-///
-class Fl_Tree_Item {
-    const char    *_label;			// label (memory managed)
-    int            _labelfont;			// label's font face
-    int            _labelsize;			// label's font size
-    Fl_Color       _labelfgcolor;		// label's fg color
-    Fl_Color       _labelbgcolor;		// label's bg color
-    char           _open;			// item is open?
-    char           _visible;			// item is visible?
-    char           _active;			// item activated?
-    char           _selected;			// item selected?
-    int            _xywh[4];			// xywh of this widget (if visible)
-    int            _collapse_xywh[4];		// xywh of collapse icon (if any)
-    int            _label_xywh[4];		// xywh of label
-    Fl_Widget     *_widget;			// item's label widget (optional)
-    Fl_Pixmap     *_usericon;			// item's user-specific icon (optional)
-    void          *_userdata;			// item's user-specific data (optional) GMSH
-    Fl_Tree_Item_Array _children;		// array of child items
-    Fl_Tree_Item  *_parent;			// parent item (=0 if root)
-protected:
-    void show_widgets();
-    void hide_widgets();
-    void draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs);
-    void draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs);
-public:
-    Fl_Tree_Item(const Fl_Tree_Prefs &prefs);	// CTOR
-    ~Fl_Tree_Item();				// DTOR
-    Fl_Tree_Item(const Fl_Tree_Item *o);	// COPY CTOR
-    void draw(int X, int &Y, int W, Fl_Widget *tree, const Fl_Tree_Prefs &prefs, int lastchild=1);
-    void show_self(const char *indent = "") const;
-    void label(const char *val);
-    const char *label() const;
-
-    /// Set item's label font face.
-    void labelfont(int val) {
-        _labelfont = val; 
-    }
-    /// Get item's label font face.
-    int labelfont() const {
-        return(_labelfont);
-    }
-    /// Set item's label font size.
-    void labelsize(int val) {
-        _labelsize = val; 
-    }
-    /// Get item's label font size.
-    int labelsize() const {
-        return(_labelsize);
-    }
-    /// Set item's label foreground text color.
-    void labelfgcolor(Fl_Color val) {
-        _labelfgcolor = val; 
-    }
-    /// Set item's label text color.
-    void labelcolor(Fl_Color val) {
-        _labelfgcolor = val; 
-    }
-    /// Return item's label text color.
-    Fl_Color labelcolor() const {
-        return(_labelfgcolor); 
-    }
-    /// Return item's label foreground text color.
-    Fl_Color labelfgcolor() const {
-        return(_labelfgcolor); 
-    }
-    /// Set item's label background color.
-    void labelbgcolor(Fl_Color val) {
-        _labelbgcolor = val; 
-    }
-    /// Return item's background text color.
-    Fl_Color labelbgcolor() const {
-        return(_labelbgcolor); 
-    }
-    /// Assign an FLTK widget to this item.
-    void widget(Fl_Widget *val) {
-        _widget = val; 
-    }
-    /// Return FLTK widget assigned to this item.
-    Fl_Widget *widget() const {
-        return(_widget); 
-    }
-    /// Return the number of children this item has.
-    int children() const {
-        return(_children.total()); 
-    }
-    /// Return the child item for the given 'index'.
-    Fl_Tree_Item *child(int index) {
-        return(_children[index]); 
-    }
-    /// Return the const child item for the given 'index'.
-    const Fl_Tree_Item *child(int t) const;
-    /// See if this item has children.
-    int has_children() const {
-        return(children()); 
-    }
-    int find_child(const char *name);
-    int find_child(Fl_Tree_Item *item);
-    int remove_child(Fl_Tree_Item *item);
-    int remove_child(const char *new_label);
-    void clear_children();
-    void swap_children(int ax, int bx);
-    int swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b);
-    const Fl_Tree_Item *find_item(char **arr) const;
-    Fl_Tree_Item *find_item(char **arr);
-    //////////////////
-    // Adding items
-    //////////////////
-    Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, const char *new_label);
-    Fl_Tree_Item *add(const Fl_Tree_Prefs &prefs, char **arr);
-    Fl_Tree_Item *insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos=0);
-    Fl_Tree_Item *insert_above(const Fl_Tree_Prefs &prefs, const char *new_label);
-    int depth() const;
-    Fl_Tree_Item *prev();
-    Fl_Tree_Item *next();
-
-    /// Return the parent for this item.
-    Fl_Tree_Item *parent() {
-        return(_parent);
-    }
-    /// Return the const parent for this item.
-    const Fl_Tree_Item *parent() const {
-        return(_parent);
-    }
-    /// Set the parent for this item.
-    /// Should only be used by Fl_Tree's internals.
-    ///
-    void parent(Fl_Tree_Item *val) {
-        _parent = val;
-    }
-    //////////////////
-    // State
-    //////////////////
-    void open();
-    void close();
-    /// See if the item is 'open'.
-    int is_open() const {
-        return(_open?1:0);
-    }
-    /// See if the item is 'closed'.
-    int is_close() const {
-        return(_open?0:1);
-    }
-    /// Toggle the item's open/closed state.
-    void open_toggle() {
-        _open?close():open();
-    }
-    /// Change the item's selection state to the optionally specified 'val'.
-    /// If 'val' is not specified, the item will be selected.
-    ///
-    void select(int val=1) {
-        _selected = val;
-    }
-    /// Toggle the item's selection state.
-    void select_toggle() {
-        if ( is_selected() ) {
-	    deselect();		// deselect if selected
-	} else {
-	    select();		// select if deselected
-	}
-    }
-    /// Disable the item's selection state.
-    void deselect() {
-        _selected = 0;
-    }
-    /// Deselect self and all children
-    ///     Returns count of how many items were in the 'selected' state,
-    ///     ie. how many items were "changed".
-    ///
-    int deselect_all() {
-        int count = 0;
-        if ( is_selected() ) {
-	    deselect();
-	    ++count;
-	}
-	for ( int t=0; t<children(); t++ ) {
-	    count += child(t)->deselect_all();
-	}
-	return(count);
-    }
-    /// See if the item is selected.
-    char is_selected() const {
-        return(_selected);
-    }
-    /// Change the item's activation state to the optionally specified 'val'.
-    ///
-    /// When deactivated, the item will be 'grayed out'; the callback() 
-    /// won't be invoked if the user clicks on the label. If the item
-    /// has a widget() associated with the item, its activation state
-    /// will be changed as well.
-    ///
-    /// If 'val' is not specified, the item will be activated.
-    ///
-    void activate(int val=1) {
-        _active = val;
-	if ( _widget && val != _widget->active() ) {
-	    if ( val ) {
-	        _widget->activate();
-	    } else {
-	        _widget->deactivate();
-	    }
-	    _widget->redraw();
-	}
-    }
-    /// Deactivate the item; the callback() won't be invoked when clicked.
-    /// Same as activate(0)
-    ///
-    void deactivate() {
-        activate(0);
-    }
-    /// See if the item is activated.
-    char is_activated() const {
-        return(_active);
-    }
-    /// See if the item is activated.
-    char is_active() const {
-        return(_active);
-    }
-    /// Set the user icon's pixmap. '0' will disable.
-    void usericon(Fl_Pixmap *val) {
-        _usericon = val;
-    }
-    /// Get the user icon. Returns '0' if disabled.
-    Fl_Pixmap *usericon() const {
-        return(_usericon);
-    }
-    /// Set the user data.
-    void user_data(void *val) {
-        _userdata = val;
-    }
-    /// Get the user data.
-    void *user_data() const {
-        return(_userdata);
-    }
-    //////////////////
-    // Events
-    //////////////////
-    const Fl_Tree_Item *find_clicked() const;
-    Fl_Tree_Item *find_clicked();
-    int event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const;
-    int event_on_label(const Fl_Tree_Prefs &prefs) const;
-    /// Is this item the root of the tree?
-    int is_root() const {
-        return(_parent==0?1:0);
-    }
-};
-
-#endif /*FL_TREE_ITEM_H*/
diff --git a/contrib/Fl_Tree/FL/Fl_Tree_Item_Array.H b/contrib/Fl_Tree/FL/Fl_Tree_Item_Array.H
deleted file mode 100644
index b7f455ac865396cdc8c40373f5dcbf2a7a747cfa..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/FL/Fl_Tree_Item_Array.H
+++ /dev/null
@@ -1,80 +0,0 @@
-#ifndef _FL_TREE_ITEM_ARRAY_H
-#define _FL_TREE_ITEM_ARRAY_H
-
-class Fl_Tree_Item;		// forward decl must *precede* first doxygen comment block
-				// or doxygen will not document our class..
-
-//////////////////////
-// FL/Fl_Tree_Item_Array.H
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-///
-/// \file
-/// \brief This file defines a class that manages an array of Fl_Tree_Item pointers.
-///
-
-/// \brief Manages an array of Fl_Tree_Item pointers.
-///
-/// Because FLTK 1.x.x. has mandated that templates and STL not be used,
-/// we use this class to dynamically manage the arrays.
-///
-/// None of the methods do range checking on index values; the caller
-/// must be sure that index values are within the range 0<index<total()
-/// (unless otherwise noted).
-///
-
-class Fl_Tree_Item_Array {
-    Fl_Tree_Item **_items;	// items array
-    int _total;			// #items in array
-    int _size;			// #items *allocated* for array
-    int _chunksize;		// #items to enlarge mem allocation
-    void enlarge(int count);
-public:
-    Fl_Tree_Item_Array(int new_chunksize = 10);		// CTOR
-    ~Fl_Tree_Item_Array();				// DTOR
-    Fl_Tree_Item_Array(const Fl_Tree_Item_Array *o);	// COPY CTOR
-    /// Return the item and index \p i.
-    Fl_Tree_Item *operator[](int i) {
-        return(_items[i]);
-    }
-    /// Const version of operator[](int i)
-    const Fl_Tree_Item *operator[](int i) const {
-        return(_items[i]);
-    }
-    /// Return the total items in the array, or 0 if empty.
-    int total() const {
-        return(_total);
-    }
-    /// Swap the two items at index positions \p ax and \p bx.
-    void swap(int ax, int bx) {
-        Fl_Tree_Item *asave = _items[ax];
-	_items[ax] = _items[bx];
-	_items[bx] = asave;
-    }
-    void clear();
-    void add(Fl_Tree_Item *val);
-    void insert(int pos, Fl_Tree_Item *new_item);
-    void remove(int index);
-    int  remove(Fl_Tree_Item *item);
-};
-
-#endif /*_FL_TREE_ITEM_ARRAY_H*/
diff --git a/contrib/Fl_Tree/FL/Fl_Tree_Prefs.H b/contrib/Fl_Tree/FL/Fl_Tree_Prefs.H
deleted file mode 100644
index c9ce6e1dc62331db0b79caae1cd075b2737e0cb5..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/FL/Fl_Tree_Prefs.H
+++ /dev/null
@@ -1,340 +0,0 @@
-#ifndef FL_TREE_PREFS_H
-#define FL_TREE_PREFS_H
-
-//////////////////////
-// FL/Fl_Tree_Prefs.H
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-///
-/// \file
-/// \brief This file contains the definitions for Fl_Tree's preferences.
-///
-/// \code
-///                  Fl_Tree_Prefs
-///                       :
-///                  .....:.......
-///                  :           :
-///               Fl_Tree        :
-///                  |_____ Fl_Tree_Item
-///
-/// \endcode
-///
-
-/// \class Fl_Tree_Prefs
-/// \brief Tree widget's preferences.
-
-/// \enum Fl_Tree_Sort
-/// Sort order options for items added to the tree
-///
-enum Fl_Tree_Sort {
-    FL_TREE_SORT_NONE=0,	///< No sorting; items are added in the order defined (default).
-    FL_TREE_SORT_ASCENDING=1,	///< Add items in ascending sort order.
-    FL_TREE_SORT_DESCENDING=2	///< Add items in descending sort order.
-};
-
-/// \enum Fl_Tree_Connector
-/// Defines the style of connection lines between items.
-///
-enum Fl_Tree_Connector {
-    FL_TREE_CONNECTOR_NONE=0,	///< Use no lines connecting items
-    FL_TREE_CONNECTOR_DOTTED=1,	///< Use dotted lines connecting items (default)
-    FL_TREE_CONNECTOR_SOLID=2	///< Use solid lines connecting items
-};
-
-/// \enum Fl_Tree_Select
-/// Tree selection style.
-///
-enum Fl_Tree_Select {
-    FL_TREE_SELECT_NONE=0,	///< Nothing selected when items are clicked
-    FL_TREE_SELECT_SINGLE,	///< Single item selected when item is clicked (default)
-    FL_TREE_SELECT_MULTI	///< Multiple items can be selected by clicking with
-                                ///< SHIFT or CTRL or mouse drags.
-};
-
-/// \class Fl_Tree_Prefs
-///
-/// \brief Fl_Tree's Preferences class.
-///
-/// This class manages the Fl_Tree's defaults.
-/// You should probably be using the methods in Fl_Tree
-/// instead of trying to accessing tree's preferences settings directly.
-///
-class Fl_Tree_Prefs {
-    int _labelfont;			// label's font face
-    int _labelsize;			// label's font size
-    int _margintop;			// -- 
-    int _marginleft;			//   |- tree's margins
-    //int _marginright;			//   |
-    //int _marginbottom;		// --
-    int _usericonmarginleft;		// space to left of user icon (if any)
-    int _labelmarginleft;		// space to left of label
-    int _connectorwidth;		// connector width (right of open/close icon)
-    int _linespacing;			// vertical space between lines
-    // Colors
-    Fl_Color _fgcolor;			// label's foreground color
-    Fl_Color _bgcolor;			// background color
-    Fl_Color _selectcolor;		// selection color
-    Fl_Color _inactivecolor;		// inactive color
-    Fl_Color _connectorcolor;		// connector dotted line color
-    Fl_Tree_Connector _connectorstyle;	// connector line style
-    Fl_Pixmap *_openpixmap;		// the 'open' icon [+]
-    Fl_Pixmap *_closepixmap;		// the 'close' icon [-]
-    Fl_Pixmap *_userpixmap;		// user's own icon
-    char _showcollapse;			// 1=show collapse icons, 0=don't
-    char _showroot;			// show the root item as part of the tree
-    Fl_Tree_Sort   _sortorder;		// none, ascening, descending, etc.
-    Fl_Boxtype     _selectbox;		// selection box type
-    Fl_Tree_Select _selectmode;		// selection mode
-public:
-    Fl_Tree_Prefs();
-
-    ////////////////////////////
-    // Labels
-    ////////////////////////////
-    /// Return the label's font.
-    inline int labelfont() const {
-        return(_labelfont);
-    }
-    /// Set the label's font to \p val.
-    inline void labelfont(int val) {
-        _labelfont = val;
-    }
-    /// Return the label's size in pixels.
-    inline int labelsize() const {
-        return(_labelsize);
-    }
-    /// Set the label's size in pixels to \p val.
-    inline void labelsize(int val) {
-        _labelsize = val;
-    }
-
-    ////////////////////////////
-    // Margins
-    ////////////////////////////
-    /// Get the left margin's value in pixels
-    inline int marginleft() const {
-        return(_marginleft);
-    }
-    /// Set the left margin's value in pixels
-    inline void marginleft(int val) {
-        _marginleft = val;
-    }
-    /// Get the top margin's value in pixels
-    inline int margintop() const {
-        return(_margintop);
-    }
-    /// Set the top margin's value in pixels
-    inline void margintop(int val) {
-        _margintop = val;
-    }
-
-/****** NOT IMPLEMENTED
-    inline int marginright() const {
-        return(_marginright);
-    }
-    inline void marginright(int val) {
-        _marginright = val;
-    }
-    inline int marginbottom() const {
-        return(_marginbottom);
-    }
-    inline void marginbottom(int val) {
-        _marginbottom = val;
-    }
-*******/
-
-    /// Get the user icon's left margin value in pixels
-    inline int usericonmarginleft() const {
-        return(_usericonmarginleft);
-    }
-    /// Set the user icon's left margin value in pixels
-    inline void usericonmarginleft(int val) {
-        _usericonmarginleft = val;
-    }
-    /// Get the label's left margin value in pixels
-    inline int labelmarginleft() const {
-        return(_labelmarginleft);
-    }
-    /// Set the label's left margin value in pixels
-    inline void labelmarginleft(int val) {
-        _labelmarginleft = val;
-    }
-    /// Get the line spacing value in pixels
-    inline int linespacing() const {
-        return(_linespacing);
-    }
-    /// Set the line spacing value in pixels
-    inline void linespacing(int val) {
-        _linespacing = val;
-    }
-
-    ////////////////////////////
-    // Colors and Styles
-    ////////////////////////////
-    /// Get the default label foreground color
-    inline Fl_Color fgcolor() const {
-        return(_fgcolor);
-    }
-    /// Set the default label foreground color
-    inline void fgcolor(Fl_Color val) {
-        _fgcolor = val;
-    }
-    /// Get the default label background color
-    inline Fl_Color bgcolor() const {
-        return(_bgcolor);
-    }
-    /// Set the default label background color
-    inline void bgcolor(Fl_Color val) {
-        _bgcolor = val;
-    }
-    /// Get the default selection color
-    inline Fl_Color selectcolor() const {
-        return(_selectcolor);
-    }
-    /// Set the default selection color
-    inline void selectcolor(Fl_Color val) {
-        _selectcolor = val;
-    }
-    /// Get the default inactive color
-    inline Fl_Color inactivecolor() const {
-        return(_inactivecolor);
-    }
-    /// Set the default inactive color
-    inline void inactivecolor(Fl_Color val) {
-        _inactivecolor = val;
-    }
-    /// Get the connector color; the color used for tree connection lines
-    inline Fl_Color connectorcolor() const {
-        return(_connectorcolor);
-    }
-    /// Set the connector color; the color used for tree connection lines
-    inline void connectorcolor(Fl_Color val) {
-        _connectorcolor = val;
-    }
-    /// Get the connector style
-    inline Fl_Tree_Connector connectorstyle() const {
-        return(_connectorstyle);
-    }
-    /// Set the connector style
-    inline void connectorstyle(Fl_Tree_Connector val) {
-        _connectorstyle = val;
-    }
-    /// Get the tree connection line's width
-    inline int connectorwidth() const {
-        return(_connectorwidth);
-    }
-    /// Set the tree connection line's width
-    inline void connectorwidth(int val) {
-        _connectorwidth = val;
-    }
-
-    ////////////////////////////
-    // Icons
-    ////////////////////////////
-    /// Get the current default 'open' icon.
-    ///     Returns the Fl_Pixmap* of the icon, or 0 if none.
-    ///
-    inline Fl_Pixmap *openicon() const {
-        return(_openpixmap);
-    }
-    void openicon(Fl_Pixmap *val);
-    /// Gets the default 'close' icon
-    ///     Returns the Fl_Pixmap* of the icon, or 0 if none.
-    ///
-    inline Fl_Pixmap *closeicon() const {
-        return(_closepixmap);
-    }
-    void closeicon(Fl_Pixmap *val);
-    /// Gets the default 'user icon' (default is 0)
-    inline Fl_Pixmap *usericon() const {
-        return(_userpixmap);
-    }
-    /// Sets the default 'user icon'
-    ///     Returns the Fl_Pixmap* of the icon, or 0 if none (default).
-    ///
-    inline void usericon(Fl_Pixmap *val) {
-        _userpixmap = val;
-    }
-
-    ////////////////////////////
-    // Options
-    ////////////////////////////
-    /// Returns 1 if the collapse icon is enabled, 0 if not.
-    inline char showcollapse() const {
-        return(_showcollapse);
-    }
-    /// Set if we should show the collapse icon or not.
-    /// If collapse icons are disabled, the user will not be able
-    /// to interactively collapse items in the tree, unless the application
-    /// provides some other means via open() and close().
-    ///
-    /// \param[in] val 1: shows collapse icons (default),\n
-    ///                0: hides collapse icons.
-    ///
-    inline void showcollapse(int val) {
-        _showcollapse = val;
-    }
-    /// Get the default sort order value
-    inline Fl_Tree_Sort sortorder() const {
-        return(_sortorder);
-    }
-    /// Set the default sort order value.
-    ///     Defines the order new items appear when add()ed to the tree.
-    ///     See Fl_Tree_Sort for possible values.
-    ///
-    inline void sortorder(Fl_Tree_Sort val) {
-        _sortorder = val;
-    }
-    /// Get the default selection box's box drawing style as an Fl_Boxtype.
-    inline Fl_Boxtype selectbox() const {
-        return(_selectbox);
-    }
-    /// Set the default selection box's box drawing style to \p val.
-    inline void selectbox(Fl_Boxtype val) {
-        _selectbox = val;
-    }
-    /// Returns 1 if the root item is to be shown, or 0 if not.
-    inline int showroot() const {
-        return(int(_showroot));
-    }
-    /// Set if the root item should be shown or not.
-    /// \param[in] val 1 -- show the root item (default)\n
-    ///                0 -- hide the root item.
-    ///
-    inline void showroot(int val) {
-        _showroot = char(val);
-    }
-    /// Get the selection mode used for the tree
-    inline Fl_Tree_Select selectmode() const {
-        return(_selectmode);
-    }
-    /// Set the selection mode used for the tree to \p val.
-    ///     This affects how items in the tree are selected
-    ///     when clicked on and dragged over by the mouse.
-    ///     See Fl_Tree_Select for possible values.
-    ///
-    inline void selectmode(Fl_Tree_Select val) {
-        _selectmode = val;
-    }
-};
-
-#endif /*FL_TREE_PREFS_H*/
diff --git a/contrib/Fl_Tree/Fl_Tree.cxx b/contrib/Fl_Tree/Fl_Tree.cxx
deleted file mode 100644
index 7ca569568a8dc6eee443dd1a06a31fd0c70cbe6f..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/Fl_Tree.cxx
+++ /dev/null
@@ -1,407 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <FL/Fl_Tree.H>
-
-#define SCROLL_W 15
-
-//////////////////////
-// Fl_Tree.cxx
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-/// \mainpage Fl_Tree Widget
-///
-/// \image html tree-simple-screenshot.png
-///
-/// \code
-///     Fl_Tree                                         // Top level widget
-///        |--- Fl_Tree_Item                            // Items in the tree
-///        |--- Fl_Tree_Prefs                           // Preferences for the tree
-///                  |--- Fl_Tree_Connector (enum)      // Connection modes
-///                  |--- Fl_Tree_Select (enum)         // Selection modes
-///                  |--- Fl_Tree_Sort (enum)           // Sort behavior
-///
-/// \endcode
-///
-/// \b Overview
-/// <P>
-/// This is a hierarchical 'tree' browser widget that presents its data
-/// in a hierarchy. Nodes can optionally be open/closed, and items can
-/// be individually created, deleted, sorted, and attributes customized
-/// for different fonts and colors.
-///
-/// The simple way to define a tree:
-/// \code
-///    Fl_Tree tree(X,Y,W,H);
-///    tree.begin();
-///      tree.add("Flintstones/Fred");
-///      tree.add("Flintstones/Wilma");
-///      tree.add("Flintstones/Pebbles");
-///      tree.add("Simpsons/Homer");
-///      tree.add("Simpsons/Marge");
-///      tree.add("Simpsons/Bart");
-///      tree.add("Simpsons/Lisa");
-///    tree.end();
-/// \endcode
-///
-/// Items can also be FLTK widgets, instead of just simple labels (default).
-///
-/// Fl_Tree derives from FLTK's Fl_Group, so that if FLTK widgets are added
-/// to the tree, they become children of the group.
-///
-/// Each item in the tree is an Fl_Tree_Item, which has customizable
-/// values for setting the font, color, and other attributes on a per-item
-/// basis.
-///
-/// Each tree contains an instance of the Fl_Tree_Prefs class, which handles
-/// global preferences for the tree, and the default values used for newly
-/// created items in the tree.
-///
-/// By default, when items are added to the tree, they're added in the order created.
-/// Sorting can be specified with the Fl_Tree::sortorder() method.
-///
-///     \image html tree-elements.png
-///
-
-// INTERNAL: scroller callback
-static void scroll_cb(Fl_Widget*,void *data) {
-    ((Fl_Tree*)data)->redraw();
-}
-
-// INTERNAL: Parse elements from path
-//    Path="/aa/bb"
-//    Return: arr[0]="aa", arr[1]="bb", arr[2]=0
-//    Caller must: free(arr[0]); free(arr);
-//
-static char **parse_path(const char *path) {
-    while ( *path == '/' ) path++;	// skip leading '/' 
-    // First pass: identify, null terminate, and count separators
-    int seps = 1;			// separator count (1: first item)
-    int arrsize = 1;			// array size (1: first item)
-    char *save = strdup(path);		// make copy we can modify
-    char *s = save;
-    while ( ( s = strchr(s, '/') ) ) {
-	while ( *s == '/' ) { *s++ = 0; seps++; }
-	if ( *s ) { arrsize++; }
-    }
-    arrsize++;				// (room for terminating NULL) 
-    // Second pass: create array, save nonblank elements
-    char **arr = (char**)malloc(sizeof(char*) * arrsize);
-    int t = 0;
-    s = save;
-    while ( seps-- > 0 ) {
-        if ( *s ) { arr[t++] = s; }	// skips empty fields, eg. '//'
-        s += (strlen(s) + 1);
-    }
-    arr[t] = 0;
-    return(arr);
-}
-
-// INTERNAL: Recursively descend tree hierarchy, accumulating total child count
-static int find_total_children(Fl_Tree_Item *item, int count=0) {
-    count++;
-    for ( int t=0; t<item->children(); t++ ) {
-	count = find_total_children(item->child(t), count);
-    }
-    return(count);
-}
-
-/// Constructor.
-Fl_Tree::Fl_Tree(int X, int Y, int W, int H, const char *L) : Fl_Group(X,Y,W,H,L) { 
-    _root = new Fl_Tree_Item(_prefs);
-    _root->parent(0);				// we are root of tree
-    _root->label("ROOT");
-    _item_clicked = 0;
-    box(FL_DOWN_BOX);
-    color(FL_WHITE);
-    when(FL_WHEN_CHANGED);
-    _vscroll = new Fl_Scrollbar(0,0,0,0);	// will be resized by draw()
-    _vscroll->hide();
-    _vscroll->type(FL_VERTICAL);
-    _vscroll->step(1);
-    _vscroll->callback(scroll_cb, (void*)this);
-    end();
-}
-
-/// Destructor.
-Fl_Tree::~Fl_Tree() {
-    if ( _root ) { delete _root; _root = 0; }
-}
-
-/// Adds a new item, given a 'menu style' path, eg: "/Parent/Child/item".
-/// Any parent nodes that don't already exist are created automatically.
-/// Adds the item based on the value of sortorder().
-/// \returns the child item created, or 0 on error.
-///
-Fl_Tree_Item* Fl_Tree::add(const char *path) {
-    if ( ! _root ) {					// Create root if none
-	_root = new Fl_Tree_Item(_prefs);
-	_root->parent(0);
-	_root->label("ROOT");
-    }
-    char **arr = parse_path(path);
-    Fl_Tree_Item *item = _root->add(_prefs, arr);
-    free((void*)arr[0]);
-    free((void*)arr);
-    return(item);
-}
-
-/// Inserts a new item above the specified Fl_Tree_Item, with the label set to 'name'.
-/// \returns the item that was added, or 0 if 'above' could not be found.
-/// 
-Fl_Tree_Item* Fl_Tree::insert_above(Fl_Tree_Item *above, const char *name) {
-    return(above->insert_above(_prefs, name));
-}
-
-/// Find the item, given a menu style path, eg: "/Parent/Child/item".
-///
-/// There is both a const and non-const version of this method.
-/// Const version allows pure const methods to use this method 
-/// to do lookups without causing compiler errors.
-/// \returns the item, or 0 if not found.
-///
-Fl_Tree_Item *Fl_Tree::find_item(const char *path) {
-    if ( ! _root ) return(0);
-    char **arr = parse_path(path);
-    Fl_Tree_Item *item = _root->find_item(arr);
-    free((void*)arr[0]);
-    free((void*)arr);
-    return(item);
-}
-
-/// A const version of Fl_Tree::find_item(const char *path)
-const Fl_Tree_Item *Fl_Tree::find_item(const char *path) const {
-    if ( ! _root ) return(0);
-    char **arr = parse_path(path);
-    const Fl_Tree_Item *item = _root->find_item(arr);
-    free((void*)arr[0]);
-    free((void*)arr);
-    return(item);
-}
-
-/// Standard FLTK draw() method, handles draws the tree widget.
-void Fl_Tree::draw() {
-    // Let group draw box+label but *NOT* children.
-    // *We* handle drawing children ourselves by calling each item's draw()
-    //
-    Fl_Group::draw_box();
-    Fl_Group::draw_label();
-    if ( ! _root ) return;
-    int cx = x() + Fl::box_dx(box());
-    int cy = y() + Fl::box_dy(box());
-    int cw = w() - Fl::box_dw(box());
-    int ch = h() - Fl::box_dh(box());
-    // These valued changed during drawing
-    // 'Y' will be the lowest point on the tree
-    int X = cx + _prefs.marginleft();
-    int Y = cy + _prefs.margintop() - (_vscroll->visible() ? _vscroll->value() : 0);
-    int W = cw - _prefs.marginleft();		// - _prefs.marginright();
-    int Ysave = Y;
-    fl_push_clip(cx,cy,cw,ch);
-    {
-        fl_font(_prefs.labelfont(), _prefs.labelsize());
-        _root->draw(X, Y, W, this, _prefs);
-    }
-    fl_pop_clip();
-    // Should we show vertical scrollbar?
-    int ydiff = (Y+_prefs.margintop())-Ysave;		// ydiff=size of tree
-    int ytoofar = (cy+ch) - Y;				// ytoofar -- scrolled beyond bottom (eg. stow)
-
-    //printf("ydiff=%d ch=%d Ysave=%d ytoofar=%d value=%d\n",
-    //int(ydiff),int(ch),int(Ysave),int(ytoofar), int(_vscroll->value()));
-
-    if ( ytoofar > 0 ) ydiff += ytoofar;
-    if ( Ysave<cy || ydiff > ch || int(_vscroll->value()) > 1 ) {
-        _vscroll->visible();
-	int sx = x()+w()-Fl::box_dx(box())-SCROLL_W;
-	int sy = y()+Fl::box_dy(box());
-	int sw = SCROLL_W;
-	int sh = h()-Fl::box_dh(box());
-	_vscroll->show();
-	_vscroll->range(0.0,ydiff-ch);
-	_vscroll->resize(sx,sy,sw,sh);
-	_vscroll->slider_size(float(ch)/float(ydiff));
-    } else {
-        _vscroll->Fl_Slider::value(0);
-        _vscroll->hide();
-    }
-    fl_push_clip(cx,cy,cw,ch);
-        Fl_Group::draw_children();
-    fl_pop_clip();
-}
-
-/// Standard FLTK event handler for this widget.
-int Fl_Tree::handle(int e) {
-    static Fl_Tree_Item *lastselect = 0;
-    int changed = 0;
-    int ret = Fl_Group::handle(e);
-    if ( ! _root ) return(ret);
-    switch ( e ) {
-	case FL_PUSH: {
-	    lastselect = 0;
-	    item_clicked(0);	// assume no item was clicked
-	    Fl_Tree_Item *o = _root->find_clicked();
-	    if ( o ) {
-		ret |= 1;					// handled
-	        if ( Fl::event_button() == FL_LEFT_MOUSE ) {
-		    // Was collapse icon clicked?
-		    if ( o->event_on_collapse_icon(_prefs) ) {
-			o->open_toggle();
-			redraw();
-		    }
-		    // Item's label clicked?
-		    else if ( o->event_on_label(_prefs) && 
-			      (!o->widget() || !Fl::event_inside(o->widget())) &&
-			      callback() &&
-			      (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) {
-			item_clicked(o);			// save item clicked
-			// Handle selection behavior
-			switch ( _prefs.selectmode() ) {
-			    case FL_TREE_SELECT_NONE: {		// no selection changes
-			        break;
-			    }
-			    case FL_TREE_SELECT_SINGLE: {
-				changed = select_only(o);
-			        break;
-			    }
-			    case FL_TREE_SELECT_MULTI: {
-			        int state = Fl::event_state();
-			        if ( state & FL_SHIFT ) {
-				    if ( ! o->is_selected() ) {
-					o->select();		// add to selection
-					changed = 1;		// changed
-				    }
-				} else if ( state & FL_CTRL ) {
-				    changed = 1;		// changed
-				    o->select_toggle();		// toggle selection state
-				    lastselect = o;		// save we toggled it (prevents oscillation)
-				} else {
-				    changed = select_only(o);
-				}
-			        break;
-			    }
-			}
-			if ( changed ) {
-			    redraw();				// make change(s) visible
-			    if ( when() & FL_WHEN_CHANGED ) {
-				set_changed();
-				do_callback((Fl_Widget*)this, user_data());	// item callback
-			    }
-			}
-		    }
-		}
-	    }
-	    break;
-	}
-	case FL_DRAG: {
-	    Fl_Tree_Item *o = _root->find_clicked();
-	    if ( o ) {
-		ret |= 1;				// handled
-		// Item's label clicked?
-		if ( o->event_on_label(_prefs) && 
-			  (!o->widget() || !Fl::event_inside(o->widget())) &&
-			  callback() &&
-			  (!_vscroll->visible() || !Fl::event_inside(_vscroll)) ) {
-		    item_clicked(o);			// save item clicked
-		    // Handle selection behavior
-		    switch ( _prefs.selectmode() ) {
-			case FL_TREE_SELECT_NONE: {	// no selection changes
-			    break;
-			}
-			case FL_TREE_SELECT_SINGLE: {
-			    changed = select_only(o);
-			    break;
-			}
-			case FL_TREE_SELECT_MULTI: {
-			    int state = Fl::event_state();
-			    if ( state & FL_CTRL ) {
-				if ( lastselect != o ) {// not already toggled from last microdrag?
-				    changed = 1;	// changed
-				    o->select_toggle();	// toggle selection
-				    lastselect = o;	// save we toggled it (prevents oscillation)
-				    redraw();		// make change(s) visible
-				}
-			    } else {
-				changed = 1;		// changed
-				o->select();		// select this
-				redraw();		// make change(s) visible
-			    }
-			    break;
-			}
-		    }
-		    if ( changed ) {
-			redraw();				// make change(s) visible
-			if ( when() & FL_WHEN_CHANGED ) {
-			    set_changed();
-			    do_callback((Fl_Widget*)this, user_data());	// item callback
-			}
-		    }
-		}
-	    }
-	}
-	case FL_RELEASE: {
-	    if ( Fl::event_button() == FL_LEFT_MOUSE ) {
-		ret |= 1;
-	    }
-	    break;
-	}
-    }
-    return(ret);
-}
-
-/// Deselect item and all its children.
-///     If item is NULL, root() is used.
-///     Handles calling redraw() if anything was changed.
-///     Returns count of how many items were in the 'selected' state,
-///     ie. how many items were "changed".
-///
-int Fl_Tree::deselect_all(Fl_Tree_Item *item) {
-    item = item ? item : root();		// NULL? use root()
-    int count = item->deselect_all();
-    if ( count ) redraw();			// anything changed? cause redraw
-    return(count);
-}
-
-/// Select only this item.
-///     If item is NULL, root() is used.
-///     Handles calling redraw() if anything was changed.
-///     Returns how many items were changed, if any.
-///
-int Fl_Tree::select_only(Fl_Tree_Item *selitem) {
-    selitem = selitem ? selitem : root();		// NULL? use root()
-    int changed = 0;
-    for ( Fl_Tree_Item *item = first(); item; item = item->next() ) {
-        if ( item == selitem ) {
-	    if ( item->is_selected() ) continue;	// don't count if already selected
-	    item->select();
-	    ++changed;
-	} else {
-	    if ( item->is_selected() ) {
-	       item->deselect();
-	       ++changed;
-	    }
-        }
-    }
-    if ( changed ) redraw();				// anything changed? redraw
-    return(changed);
-}
diff --git a/contrib/Fl_Tree/Fl_Tree_Item.cxx b/contrib/Fl_Tree/Fl_Tree_Item.cxx
deleted file mode 100644
index dc99b7fa7ecf9cb37309522fc39470e431aaefa6..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/Fl_Tree_Item.cxx
+++ /dev/null
@@ -1,693 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <FL/Fl_Widget.H>
-#include <FL/Fl_Tree_Item.H>
-#include <FL/Fl_Tree_Prefs.H>
-
-//////////////////////
-// Fl_Tree_Item.cxx
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-// Was the last event inside the specified xywh?
-static int event_inside(const int xywh[4]) {
-    return(Fl::event_inside(xywh[0],xywh[1],xywh[2],xywh[3]));
-}
-
-/// Constructor.
-///     Makes a new instance of Fl_Tree_Item using defaults from 'prefs'.
-///
-Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Prefs &prefs) {
-    _label        = 0;
-    _labelfont    = prefs.labelfont();
-    _labelsize    = prefs.labelsize();
-    _labelfgcolor = prefs.fgcolor();
-    _labelbgcolor = prefs.bgcolor();
-    _widget       = 0;
-    _open         = 1;
-    _visible      = 1;
-    _active       = 1;
-    _selected     = 0;
-    _xywh[0]      = 0;
-    _xywh[1]      = 0;
-    _xywh[2]      = 0;
-    _xywh[3]      = 0;
-    _collapse_xywh[0] = 0;
-    _collapse_xywh[1] = 0;
-    _collapse_xywh[2] = 0;
-    _collapse_xywh[3] = 0;
-    _label_xywh[0]    = 0;
-    _label_xywh[1]    = 0;
-    _label_xywh[2]    = 0;
-    _label_xywh[3]    = 0;
-    _usericon         = 0;
-    _userdata         = 0; // GMSH
-    _parent           = 0;
-}
-
-// DTOR
-Fl_Tree_Item::~Fl_Tree_Item() {
-    if ( _label ) { 
-        free((void*)_label);
-	_label = 0;
-    }
-    _widget = 0;			// Fl_Group will handle destruction
-    _usericon = 0;			// user handled allocation
-    //_children.clear();		// array's destructor handles itself
-}
-
-/// Copy constructor.
-Fl_Tree_Item::Fl_Tree_Item(const Fl_Tree_Item *o) {
-    _label        = o->label() ? strdup(o->label()) : 0;
-    _labelfont    = o->labelfont();
-    _labelsize    = o->labelsize();
-    _labelfgcolor = o->labelfgcolor();
-    _labelbgcolor = o->labelbgcolor();
-    _widget       = o->widget();
-    _open         = o->_open;
-    _visible      = o->_visible;
-    _active       = o->_active;
-    _selected     = o->_selected;
-    _xywh[0]      = o->_xywh[0];
-    _xywh[1]      = o->_xywh[1];
-    _xywh[2]      = o->_xywh[2];
-    _xywh[3]      = o->_xywh[3];
-    _collapse_xywh[0] = o->_collapse_xywh[0];
-    _collapse_xywh[1] = o->_collapse_xywh[1];
-    _collapse_xywh[2] = o->_collapse_xywh[2];
-    _collapse_xywh[3] = o->_collapse_xywh[3];
-    _label_xywh[0]    = o->_label_xywh[0];
-    _label_xywh[1]    = o->_label_xywh[1];
-    _label_xywh[2]    = o->_label_xywh[2];
-    _label_xywh[3]    = o->_label_xywh[3];
-    _usericon         = o->usericon();
-    _parent           = o->_parent;
-}
-
-/// Print the tree as 'ascii art' to stdout.
-/// Used mainly for debugging.
-///
-void Fl_Tree_Item::show_self(const char *indent) const {
-    if ( label() ) {
-        printf("%s-%s (%d children, this=%p, parent=%p depth=%d)\n",
-	    indent,label(),children(),(void*)this, (void*)_parent, depth());
-    }
-    if ( children() ) {
-	char *i2 = (char*)malloc(strlen(indent) + 2);
-	strcpy(i2, indent);
-	strcat(i2, " |");
-	for ( int t=0; t<children(); t++ ) {
-	    child(t)->show_self(i2);
-	}
-    }
-    fflush(stdout);
-}
-
-/// Set the label. Makes a copy of the name.
-void Fl_Tree_Item::label(const char *name) {
-    if ( _label ) { free((void*)_label); _label = 0; }
-    _label = name ? strdup(name) : 0;
-}
-
-/// Return the label.
-const char *Fl_Tree_Item::label() const {
-    return(_label);
-}
-
-/// Return child item for the specified 'index'.
-const Fl_Tree_Item *Fl_Tree_Item::child(int index) const {
-    return(_children[index]);
-}
-
-/// Clear all the children for this item.
-void Fl_Tree_Item::clear_children() {
-    _children.clear();
-}
-
-/// Return the index of the immediate child of this item that has the label 'name'.
-///
-/// \returns index of found item, or -1 if not found.
-///
-int Fl_Tree_Item::find_child(const char *name) {
-    for ( int t=0; t<children(); t++ ) {
-        if ( child(t)->label() ) {
-	    if ( strcmp(child(t)->label(), name) == 0 ) {
-		return(t);
-	    }
-	}
-    }
-    return(-1);
-}
-
-/// Find item by descending array of names.
-/// Only Fl_Tree should need this method.
-///
-/// \returns item, or 0 if not found
-///
-const Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) const {
-    for ( int t=0; t<children(); t++ ) {
-        if ( child(t)->label() ) {
-	    if ( strcmp(child(t)->label(), *arr) == 0 ) {	// match?
-	        if ( *(arr+1) ) {				// more in arr? descend
-		    return(_children[t]->find_item(arr+1));
-		} else {					// end of arr? done
-		    return(_children[t]);
-		}
-	    }
-	}
-    }
-    return(0);
-}
-
-/// Find item by by descending array of names.
-/// Only Fl_Tree should need this method.
-///
-/// \returns item, or 0 if not found
-///
-Fl_Tree_Item *Fl_Tree_Item::find_item(char **arr) {
-    for ( int t=0; t<children(); t++ ) {
-        if ( child(t)->label() ) {
-	    if ( strcmp(child(t)->label(), *arr) == 0 ) {	// match?
-	        if ( *(arr+1) ) {				// more in arr? descend
-		    return(_children[t]->find_item(arr+1));
-		} else {					// end of arr? done
-		    return(_children[t]);
-		}
-	    }
-	}
-    }
-    return(0);
-}
-
-/// Find the index number for the specified 'item'
-/// in the current item's list of children.
-///
-/// \returns the index, or -1 if not found.
-///
-int Fl_Tree_Item::find_child(Fl_Tree_Item *item) {
-    for ( int t=0; t<children(); t++ ) {
-	if ( item == child(t) ) {
-	    return(t);
-	}
-    }
-    return(-1);
-}
-
-/// Add a new child to this item with the name 'new_label', with defaults from 'prefs'.
-/// An internally managed copy is made of the label string.
-/// Adds the item based on the value of prefs.sortorder().
-///
-Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, const char *new_label) {
-    Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
-    item->label(new_label);
-    item->_parent = this;
-    switch ( prefs.sortorder() ) {
-        case FL_TREE_SORT_NONE: {
-	    _children.add(item);
-	    return(item);
-	}
-        case FL_TREE_SORT_ASCENDING: {
-	    for ( int t=0; t<_children.total(); t++ ) {
-	        Fl_Tree_Item *c = _children[t];
-	        if ( c->label() && strcmp(c->label(), new_label) > 0 ) {
-		    _children.insert(t, item);
-		    return(item);
-		}
-	    }
-	    _children.add(item);
-	    return(item);
-	}
-        case FL_TREE_SORT_DESCENDING: {
-	    for ( int t=0; t<_children.total(); t++ ) {
-	        Fl_Tree_Item *c = _children[t];
-	        if ( c->label() && strcmp(c->label(), new_label) < 0 ) {
-		    _children.insert(t, item);
-		    return(item);
-		}
-	    }
-	    _children.add(item);
-	    return(item);
-	}
-    }
-    return(item);
-}
-
-/// Add a child recursively into tree.
-/// Should be used only by Fl_Tree's internals.
-/// Adds the item based on the value of prefs.sortorder().
-///
-Fl_Tree_Item *Fl_Tree_Item::add(const Fl_Tree_Prefs &prefs, char **arr) {
-    int t = find_child(*arr);
-    Fl_Tree_Item *item;
-    if ( t == -1 ) {
-        item = (Fl_Tree_Item*)add(prefs, *arr);
-    } else {
-        item = (Fl_Tree_Item*)child(t);
-    }
-    if ( *(arr+1) ) {		// descend?
-        return(item->add(prefs, arr+1));
-    } else {
-        return(item);		// end? done
-    }
-}
-
-/// Insert a new item into current item's children at a specified position.
-Fl_Tree_Item *Fl_Tree_Item::insert(const Fl_Tree_Prefs &prefs, const char *new_label, int pos) {
-    Fl_Tree_Item *item = new Fl_Tree_Item(prefs);
-    item->label(new_label);
-    item->_parent = this;
-    _children.insert(pos, item);
-    return(item);
-}
-
-/// Insert a new item above this item.
-Fl_Tree_Item *Fl_Tree_Item::insert_above(const Fl_Tree_Prefs &prefs, const char *new_label) {
-    Fl_Tree_Item *p = _parent;
-    if ( ! p ) return(0);
-    // Walk our parent's children to find ourself
-    for ( int t=0; t<p->children(); t++ ) {
-        Fl_Tree_Item *c = p->child(t);
-	if ( this == c ) {
-	    return(p->insert(prefs, new_label, t));
-	}
-    }
-    return(0);
-}
-
-/// Remove child by item.
-///    Returns 0 if removed, -1 if item not an immediate child.
-///
-int Fl_Tree_Item::remove_child(Fl_Tree_Item *item) {
-    for ( int t=0; t<children(); t++ ) {
-        if ( child(t) == item ) {
-	    item->clear_children();
-	    _children.remove(t);
-	    return(0);
-	}
-    }
-    return(-1);
-}
-
-/// Remove immediate child (and its children) by its label 'name'.
-///    Returns 0 if removed, -1 if not found.
-///
-int Fl_Tree_Item::remove_child(const char *name) {
-    for ( int t=0; t<children(); t++ ) {
-        if ( child(t)->label() ) {
-	    if ( strcmp(child(t)->label(), name) == 0 ) {
-	        _children.remove(t);
-		return(0);
-	    }
-	}
-    }
-    return(-1);
-}
-
-/// Swap two of our children, given two child index values.
-/// Use this eg. for sorting.
-///
-/// This method is FAST, and does not involve lookups.
-///
-/// No range checking is done on either index value.
-///
-/// \returns
-///    -    0 : OK
-///    -   -1 : failed: 'a' or 'b' is not our immediate child
-///
-void Fl_Tree_Item::swap_children(int ax, int bx) {
-    _children.swap(ax, bx);
-}
-
-/// Swap two of our children, given item pointers.
-/// Use this eg. for sorting. 
-///
-/// This method is SLOW because it involves linear lookups.
-/// For speed, use swap_children(int,int) instead.
-///
-/// \returns
-///    -    0 : OK
-///    -   -1 : failed: 'a' or 'b' is not our immediate child
-///
-int Fl_Tree_Item::swap_children(Fl_Tree_Item *a, Fl_Tree_Item *b) {
-    int ax = -1, bx = -1;
-    for ( int t=0; t<children(); t++ ) {	// find index for a and b
-        if ( _children[t] == a ) { ax = t; if ( bx != -1 ) break; else continue; }
-	if ( _children[t] == b ) { bx = t; if ( ax != -1 ) break; else continue; }
-    }
-    if ( ax == -1 || bx == -1 ) return(-1);	// not found? fail
-    swap_children(ax,bx);
-    return(0);
-}
-
-/// Internal: Horizontal connector line based on preference settings.
-void Fl_Tree_Item::draw_horizontal_connector(int x1, int x2, int y, const Fl_Tree_Prefs &prefs) {
-    fl_color(prefs.connectorcolor());
-    switch ( prefs.connectorstyle() ) {
-        case FL_TREE_CONNECTOR_SOLID:
-	    y |= 1;				// force alignment w/dot pattern
-	    fl_line(x1,y,x2,y);
-	    return;
-        case FL_TREE_CONNECTOR_DOTTED:
-	    y |= 1;				// force alignment w/dot pattern
-	    for ( int xx=x1; xx<=x2; xx++ ) {
-		if ( !(xx & 1) ) fl_point(xx, y);
-	    }
-	    return;
-        case FL_TREE_CONNECTOR_NONE:
-	    return;
-    }
-}
-
-/// Internal: Vertical connector line based on preference settings.
-void Fl_Tree_Item::draw_vertical_connector(int x, int y1, int y2, const Fl_Tree_Prefs &prefs) {
-    fl_color(prefs.connectorcolor());
-    switch ( prefs.connectorstyle() ) {
-        case FL_TREE_CONNECTOR_SOLID:
-	    y1 |= 1;				// force alignment w/dot pattern
-	    y2 |= 1;				// force alignment w/dot pattern
-	    fl_line(x,y1,x,y2);
-	    return;
-        case FL_TREE_CONNECTOR_DOTTED:
-	    y1 |= 1;				// force alignment w/dot pattern
-	    y2 |= 1;				// force alignment w/dot pattern
-	    for ( int yy=y1; yy<=y2; yy++ ) {
-		if ( yy & 1 ) fl_point(x, yy);
-	    }
-	    return;
-        case FL_TREE_CONNECTOR_NONE:
-	    return;
-    }
-}
-
-/// Find the item that the last event was over.
-///
-///    Returns the item if its visible, and mouse is over it.
-///    Works even if widget deactivated.
-///    Use event_on_collapse_icon() to determine if collapse button was pressed.
-///
-///    \returns const visible item under the event if found, or 0 if none.
-///
-const Fl_Tree_Item *Fl_Tree_Item::find_clicked() const {
-    if ( ! _visible ) return(0);
-    if ( event_inside(_xywh) ) {		// event within this item?
-	return(this);				// found
-    }
-    if ( is_open() ) {				// open? check children of this item
-	for ( int t=0; t<children(); t++ ) {
-	    const Fl_Tree_Item *item;
-	    if ( ( item = _children[t]->find_clicked() ) != NULL) {	// check child and its descendents
-	        return(item);						// found?
-	    }
-	}
-    }
-    return(0);
-}
-
-/// Non-const version of the above.
-/// Find the item that the last event was over.
-///
-///    Returns the item if its visible, and mouse is over it.
-///    Works even if widget deactivated.
-///    Use event_on_collapse_icon() to determine if collapse button was pressed.
-///
-///    \returns the visible item under the event if found, or 0 if none.
-///
-Fl_Tree_Item *Fl_Tree_Item::find_clicked() {
-    if ( ! _visible ) return(0);
-    if ( event_inside(_xywh) ) {		// event within this item?
-	return(this);				// found
-    }
-    if ( is_open() ) {				// open? check children of this item
-	for ( int t=0; t<children(); t++ ) {
-	    Fl_Tree_Item *item;
-	    if ( ( item = _children[t]->find_clicked() ) != NULL ) {	// check child and its descendents
-	        return(item);						// found?
-	    }
-	}
-    }
-    return(0);
-}
-
-/// Draw this item and its children.
-void Fl_Tree_Item::draw(int X, int &Y, int W, Fl_Widget *tree, 
-                        const Fl_Tree_Prefs &prefs, int lastchild) {
-    if ( ! _visible ) return; 
-    fl_font(_labelfont, _labelsize);
-    int H = _labelsize + fl_descent() + prefs.linespacing();
-    // Colors, fonts
-    Fl_Color fg = _selected ? prefs.bgcolor()     : _labelfgcolor;
-    Fl_Color bg = _selected ? prefs.selectcolor() : _labelbgcolor;
-    if ( ! _active ) {
-	fg = fl_inactive(fg);
-	if ( _selected ) bg = fl_inactive(bg);
-    }
-    // Update the xywh of this item
-    _xywh[0] = X;
-    _xywh[1] = Y;
-    _xywh[2] = W;
-    _xywh[3] = H;
-    // Text size
-    int textw=0, texth=0;
-    fl_measure(_label, textw, texth, 0);
-    int textycenter = Y+(H/2);
-    int &icon_x = _collapse_xywh[0] = X-1;
-    int &icon_y = _collapse_xywh[1] = textycenter - (prefs.openicon()->h()/2);
-    int &icon_w = _collapse_xywh[2] = prefs.openicon()->w();
-    _collapse_xywh[3] = prefs.openicon()->h();
-    // Horizontal connector values
-    int hstartx  = X+icon_w/2-1;
-    int hendx    = hstartx + prefs.connectorwidth();
-    int hcenterx = X + icon_w + ((hendx - (X + icon_w)) / 2);
-
-    // See if we should draw this item
-    //    If this item is root, and showroot() is disabled, don't draw.
-    //
-    char drawthis = ( is_root() && prefs.showroot() == 0 ) ? 0 : 1;
-    if ( drawthis ) {
-	// Draw connectors
-	if ( prefs.connectorstyle() != FL_TREE_CONNECTOR_NONE ) {
-	    // Horiz connector between center of icon and text
-	    draw_horizontal_connector(hstartx, hendx, textycenter, prefs);
-	    if ( has_children() && is_open() ) {
-		// Small vertical line down to children
-		draw_vertical_connector(hcenterx, textycenter, Y+H, prefs);
-	    }
-	    // Connectors for last child
-	    if ( ! is_root() ) {
-		if ( lastchild ) {
-		    draw_vertical_connector(hstartx, Y, textycenter, prefs);
-		} else {
-		    draw_vertical_connector(hstartx, Y, Y+H, prefs);
-		}
-	    }
-	} 
-	// Draw collapse icon
-	if ( has_children() && prefs.showcollapse() ) {
-	    // Draw icon image
-	    if ( is_open() ) {
-		prefs.closeicon()->draw(icon_x,icon_y);
-	    } else {
-		prefs.openicon()->draw(icon_x,icon_y);
-	    }
-	}
-	// Background for this item
-	int &bx = _label_xywh[0] = X+(icon_w/2-1+prefs.connectorwidth());
-	int &by = _label_xywh[1] = Y;
-	int &bw = _label_xywh[2] = W-(icon_w/2-1+prefs.connectorwidth());
-	int &bh = _label_xywh[3] = texth;
-	// Draw bg only if different from tree's bg
-	if ( bg != tree->color() || is_selected() ) {
-	    if ( is_selected() ) {
-		// Selected? Use selectbox() style
-		fl_draw_box(prefs.selectbox(), bx, by, bw, bh, bg);
-	    } else {
-		// Not Selected? use plain filled rectangle
-		fl_color(bg);
-		fl_rectf(bx, by, bw, bh);
-	    }
-	}
-	// Draw user icon (if any)
-	int useroff = (icon_w/2-1+prefs.connectorwidth());
-	if ( usericon() ) {
-	    // Item has user icon? Use it
-	    useroff += prefs.usericonmarginleft();
-	    usericon()->draw(X+useroff,icon_y);
-	    useroff += usericon()->w();
-	} else if ( prefs.usericon() ) {
-	    // Prefs has user icon? Use it
-	    useroff += prefs.usericonmarginleft();
-	    prefs.usericon()->draw(X+useroff,icon_y);
-	    useroff += prefs.usericon()->w();
-	}
-	useroff += prefs.labelmarginleft();
-	// Draw label
-	if ( widget() ) {
-	    // Widget? Draw it
-	    int lx = X+useroff;
-	    int ly = by;
-	    int lw = widget()->w();
-	    int lh = bh;
-	    if ( widget()->x() != lx || widget()->y() != ly ||
-		 widget()->w() != lw || widget()->h() != lh ) {
-		widget()->resize(lx, ly, lw, lh);		// fltk will handle drawing this
-	    }
-	} else {
-	    // No label widget? Draw text label
-	    if ( _label ) {
-		fl_color(fg);
-		fl_draw(_label, X+useroff, Y+H-fl_descent()-1);
-	    }
-	}
-	Y += H;
-    }			// end drawthis
-    // Draw children
-    if ( has_children() && is_open() ) {
-	int child_x = drawthis ? 			// offset children to right,
-	              (hcenterx - (icon_w/2) + 1) : X;	// unless didn't drawthis
-	int child_w = W - (child_x-X);
-	int child_y_start = Y;
-	for ( int t=0; t<children(); t++ ) {
-	    int lastchild = ((t+1)==children()) ? 1 : 0;
-	    _children[t]->draw(child_x, Y, child_w, tree, prefs, lastchild);
-	}
-	if ( ! lastchild ) {
-	    draw_vertical_connector(hstartx, child_y_start, Y, prefs);
-	}
-    }
-}
-
-/// Was the event on the 'collapse' button?
-///
-int Fl_Tree_Item::event_on_collapse_icon(const Fl_Tree_Prefs &prefs) const {
-    if ( _visible && _active && has_children() && prefs.showcollapse() ) {
-        return(event_inside(_collapse_xywh) ? 1 : 0);
-    } else {
-	return(0);
-    }
-}
-
-/// Was event on the label()?
-///
-int Fl_Tree_Item::event_on_label(const Fl_Tree_Prefs &prefs) const {
-    if ( _visible && _active ) {
-        return(event_inside(_label_xywh) ? 1 : 0);
-    } else {
-	return(0);
-    }
-}
-
-/// Internal: Show the FLTK widget() for this item and all children.
-/// Used by open() to re-show widgets that were hidden by a previous close()
-///
-void Fl_Tree_Item::show_widgets() {
-    if ( _widget ) _widget->show();
-    if ( is_open() ) {
-	for ( int t=0; t<_children.total(); t++ ) {
-	    _children[t]->show_widgets();
-	}
-    }
-}
-
-/// Internal: Hide the FLTK widget() for this item and all children.
-/// Used by close() to hide widgets.
-///
-void Fl_Tree_Item::hide_widgets() {
-    if ( _widget ) _widget->hide();
-    for ( int t=0; t<_children.total(); t++ ) {
-	_children[t]->hide_widgets();
-    }
-}
-
-/// Open this item and all its children.
-void Fl_Tree_Item::open() {
-    _open = 1;
-    // Tell children to show() their widgets
-    for ( int t=0; t<_children.total(); t++ ) {
-        _children[t]->show_widgets();
-    }
-}
-
-/// Close this item and all its children.
-void Fl_Tree_Item::close() {
-    _open = 0;
-    // Tell children to hide() their widgets
-    for ( int t=0; t<_children.total(); t++ ) {
-        _children[t]->hide_widgets();
-    }
-}
-
-/// Returns how many levels deep this item is in the hierarchy.
-///
-/// For instance; root has a depth of zero, and its immediate children
-/// would have a depth of 1, and so on.
-///
-int Fl_Tree_Item::depth() const {
-    int count = 0;
-    const Fl_Tree_Item *item = parent();
-    while ( item ) {
-	++count;
-	item = item->parent();
-    }
-    return(count);
-}
-
-/// Return the next item in the tree.
-///
-/// This method can be used to walk the tree forward.
-/// For an example of how to use this method, see Fl_Tree::first().
-/// 
-/// \returns the next item in the tree, or 0 if there's no more items.
-///
-Fl_Tree_Item *Fl_Tree_Item::next() {
-    Fl_Tree_Item *p, *c = this;
-    if ( c->has_children() ) {
-	return(c->child(0));
-    }
-    while ( ( p = c->parent() ) != NULL ) {	// loop upwards through parents
-	int t = p->find_child(c);		// find our position in parent's children[] array
-	if ( ++t < p->children() )		// not last child?
-	    return(p->child(t));		// return next child
-	c = p;					// child becomes parent to move up generation
-    }						// loop: moves up to next parent
-    return(0);					// hit root? done
-}
-
-/// Return the previous item in the tree.
-///
-/// This method can be used to walk the tree backwards.
-/// For an example of how to use this method, see Fl_Tree::last().
-/// 
-/// \returns the previous item in the tree, or 0 if there's no item above this one (hit the root).
-///
-Fl_Tree_Item *Fl_Tree_Item::prev() {
-    Fl_Tree_Item *p=parent();		// start with parent
-    if ( ! p ) return(0);		// hit root? done
-    int t = p->find_child(this);	// find our position in parent's children[] array
-    if ( --t == -1 ) {	 		// are we first child?
-	return(p);			// return immediate parent
-    }
-    p = p->child(t);			// take parent's previous child
-    while ( p->has_children() ) {	// has children?
-	p = p->child(p->children()-1);	// take last child
-    }
-    return(p);
-}
diff --git a/contrib/Fl_Tree/Fl_Tree_Item_Array.cxx b/contrib/Fl_Tree/Fl_Tree_Item_Array.cxx
deleted file mode 100644
index a26a8a217dbf56541739f1472ecfc095149196a3..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/Fl_Tree_Item_Array.cxx
+++ /dev/null
@@ -1,149 +0,0 @@
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <FL/Fl_Tree_Item_Array.H>
-#include <FL/Fl_Tree_Item.H>
-
-//////////////////////
-// Fl_Tree_Item_Array.cxx
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-/// Constructor; creates an empty array.
-///
-///     The optional 'chunksize' can be specified to optimize
-///     memory allocation for potentially large arrays. Default chunksize is 10.
-/// 
-Fl_Tree_Item_Array::Fl_Tree_Item_Array(int new_chunksize) {
-    _items     = 0;
-    _total     = 0;
-    _size      = 0;
-    _chunksize = new_chunksize;
-}
-
-/// Destructor. Calls each item's destructor, destroys internal _items array.
-Fl_Tree_Item_Array::~Fl_Tree_Item_Array() {
-    clear();
-}
-
-/// Copy constructor. Makes new copy of array, with new instances of each item.
-Fl_Tree_Item_Array::Fl_Tree_Item_Array(const Fl_Tree_Item_Array* o) {
-    _items = (Fl_Tree_Item**)malloc(o->_size * sizeof(Fl_Tree_Item*));
-    _total     = o->_total;
-    _size      = o->_size;
-    _chunksize = o->_chunksize;
-    for ( int t=0; t<o->_total; t++ ) {
-        _items[t] = new Fl_Tree_Item(o->_items[t]);
-    }
-}
-
-/// Clear the entire array.
-///
-///     Each item will be deleted (destructors will be called),
-///     and the array will be cleared. total() will return 0.
-///
-void Fl_Tree_Item_Array::clear() {
-    if ( _items ) {
-	for ( int t=0; t<_total; t++ ) {
-	    delete _items[t];
-	    _items[t] = 0;
-	}
-	free((void*)_items); _items = 0;
-    }
-    _total = _size = 0;
-}
-
-// Internal: Enlarge the items array.
-//
-//    Adjusts size/items memory allocation as needed.
-//    Does NOT change total.
-//
-void Fl_Tree_Item_Array::enlarge(int count) {
-    int newtotal = _total + count;	// new total
-    if ( newtotal >= _size ) {		// more than we have allocated?
-	// Increase size of array
-	int newsize = _size + _chunksize;
-	Fl_Tree_Item **newitems = (Fl_Tree_Item**)malloc(newsize * sizeof(Fl_Tree_Item*));
-	if ( _items ) { 
-	    // Copy old array -> new, delete old
-	    memmove(newitems, _items, _size * sizeof(Fl_Tree_Item*));
-	    free((void*)_items); _items = 0;
-	}
-	// Adjust items/sizeitems
-	_items = newitems;
-	_size = newsize;
-    }
-}
-
-/// Insert an item at index position \p pos.
-///
-///     Handles enlarging array if needed, total increased by 1.
-///     If \p pos == total(), an empty item is appended to the array.
-///
-void Fl_Tree_Item_Array::insert(int pos, Fl_Tree_Item *new_item) {
-    enlarge(1);
-    // printf("*** POS=%d TOTAL-1=%d NITEMS=%d\n", pos, _total-1, (_total-pos));
-    if ( pos <= (_total - 1) ) {	// need to move memory around?
-	int nitems = _total - pos;
-	memmove(&_items[pos+1], &_items[pos], sizeof(Fl_Tree_Item*) * nitems);
-    } 
-    _items[pos] = new_item;
-    _total++;
-}
-
-/// Add an item* to the end of the array.
-///
-///     Assumes the item was created with 'new', and will remain
-///     allocated.. Fl_Tree_Item_Array will handle calling the
-///     item's destructor when the array is cleared or the item remove()'ed.
-///
-void Fl_Tree_Item_Array::add(Fl_Tree_Item *val) {
-    insert(_total, val);
-}
-
-/// Remove the item at \param[in] index from the array.
-///
-///     The item will be delete'd (if non-NULL), so its destructor will be called.
-///
-void Fl_Tree_Item_Array::remove(int index) {
-    if ( _items[index] ) {		// delete if non-zero
-        delete _items[index];
-    }
-    _items[index] = 0;
-    for ( _total--; index<_total; index++ ) {
-        _items[index] = _items[index+1];
-    }
-}
-
-/// Remove the item from the array.
-///
-///     \returns 0 if removed, or -1 if the item was not in the array.
-///
-int Fl_Tree_Item_Array::remove(Fl_Tree_Item *item) {
-    for ( int t=0; t<_total; t++ ) {
-        if ( item == _items[t] ) {
-	    remove(t);
-	    return(0);
-	}
-    }
-    return(-1);
-}
diff --git a/contrib/Fl_Tree/Fl_Tree_Prefs.cxx b/contrib/Fl_Tree/Fl_Tree_Prefs.cxx
deleted file mode 100644
index 22f3e56db1cb3ef035910e822efa8e2dd7b3b27c..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/Fl_Tree_Prefs.cxx
+++ /dev/null
@@ -1,126 +0,0 @@
-#include <string.h>
-#include <FL/Fl.H>
-#include <FL/Fl_Pixmap.H>
-#include <FL/Fl_Tree_Prefs.H>
-
-//////////////////////
-// Fl_Tree_Prefs.cxx
-//////////////////////
-//
-// Fl_Tree -- This file is part of the Fl_Tree widget for FLTK
-// Copyright (C) 2009 by Greg Ercolano.
-//
-// This library is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Library General Public
-// License as published by the Free Software Foundation; either
-// version 2 of the License, or (at your option) any later version.
-//
-// This library is distributed in the hope that it will be useful,
-// but WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// Library General Public License for more details.
-//
-// You should have received a copy of the GNU Library General Public
-// License along with this library; if not, write to the Free Software
-// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-// USA.
-//
-
-// INTERNAL: BUILT IN OPEN/STOW XPMS
-//    These can be replaced via prefs.openicon()/closeicon()
-//
-static const char *L_open_xpm[] = {
-    "11 11 3 1",
-    ".	c #fefefe",
-    "#	c #444444",
-    "@	c #000000",
-    "###########",
-    "#.........#",
-    "#.........#",
-    "#....@....#",
-    "#....@....#",
-    "#..@@@@@..#",
-    "#....@....#",
-    "#....@....#",
-    "#.........#",
-    "#.........#",
-    "###########"};
-static Fl_Pixmap L_openpixmap(L_open_xpm);
-
-static const char *L_close_xpm[] = {
-    "11 11 3 1",
-    ".	c #fefefe",
-    "#	c #444444",
-    "@	c #000000",
-    "###########",
-    "#.........#",
-    "#.........#",
-    "#.........#",
-    "#.........#",
-    "#..@@@@@..#",
-    "#.........#",
-    "#.........#",
-    "#.........#",
-    "#.........#",
-    "###########"};
-static Fl_Pixmap L_closepixmap(L_close_xpm);
-
-/// Sets the default icon to be used as the 'open' icon
-/// when items are add()ed to the tree.
-/// This overrides the built in default '[+]' icon.
-///
-/// \param[in] val -- The new pixmap, or zero to use the default [+] icon.
-///
-void Fl_Tree_Prefs::openicon(Fl_Pixmap *val) {
-    _openpixmap = val ? val : &L_openpixmap;
-}
-
-/// Sets the icon to be used as the 'close' icon.
-/// This overrides the built in default '[-]' icon.
-///
-/// \param[in] val -- The new pixmap, or zero to use the default [-] icon.
-///
-void Fl_Tree_Prefs::closeicon(Fl_Pixmap *val) {
-    _closepixmap = val ? val : &L_closepixmap;
-}
-
-/// Fl_Tree_Prefs constructor
-Fl_Tree_Prefs::Fl_Tree_Prefs() {
-    _labelfont          = FL_HELVETICA;
-    _labelsize          = FL_NORMAL_SIZE;
-    _marginleft         = 6;
-    _margintop          = 3;
-    //_marginright      = 3;
-    //_marginbottom     = 3;
-    _usericonmarginleft = 3;
-    _labelmarginleft    = 3;
-    _linespacing        = 0;
-    _fgcolor            = FL_BLACK;
-    _bgcolor            = FL_WHITE;
-    _selectcolor        = FL_DARK_BLUE;
-    _inactivecolor      = FL_GRAY;
-    _connectorcolor     = Fl_Color(43);
-    _connectorstyle     = FL_TREE_CONNECTOR_DOTTED;
-    _openpixmap         = &L_openpixmap;
-    _closepixmap        = &L_closepixmap;
-    _userpixmap         = 0;
-    _showcollapse       = 1;
-    _showroot           = 1;
-    _connectorwidth     = 17;
-    _sortorder          = FL_TREE_SORT_NONE;
-    _selectbox          = FL_FLAT_BOX;
-    _selectmode         = FL_TREE_SELECT_SINGLE;
-    // Let fltk's current 'scheme' affect defaults
-    if ( Fl::scheme() ) {
-	if ( strcmp(Fl::scheme(), "gtk+") == 0 ) {
-#if (FL_MAJOR_VERSION == 1) && (FL_MINOR_VERSION == 1) && (FL_PATCH_VERSION < 9)
-          // GMSH PATCH for fltk < 1.1.9 compat
-          _selectbox = FL_FLAT_BOX;
-#else
-          _selectbox = _FL_GTK_THIN_UP_BOX;
-#endif
-	} else if ( strcmp(Fl::scheme(), "plastic") == 0 ) {
-	    _selectbox = _FL_PLASTIC_THIN_UP_BOX;
-	}
-    }
-}
diff --git a/contrib/Fl_Tree/README.txt b/contrib/Fl_Tree/README.txt
deleted file mode 100644
index 11e93a406035ccede01fc868b7649be87c3d344a..0000000000000000000000000000000000000000
--- a/contrib/Fl_Tree/README.txt
+++ /dev/null
@@ -1,56 +0,0 @@
-
-This is a slightly modified version of the Fl_Tree widget for
-Gmsh. The following modifications (marked with "GMSH" in the source
-code) were applied:
-
-  - added userdata() membre to Fl_Tree_Item so we can store user data
-    in each node
-
-
-Fl_Tree -- FLTK 'Tree' Widget
-------------------------------------
-
-WHAT IS "Fl_Tree"?
-
-    Fl_Tree is a 'tree' widget aimed at becoming part of the FLTK's core,
-    or fltk extensions library.
-
-LICENSING
-
-    Fl_Tree comes with complete free source code. 
-    Fl_Tree is available under the terms of the GNU Library 
-    General Public License. See COPYING for more info.
-
-    Contrary to popular belief, it can be used in commercial
-    software!
-
-BUILD INSTRUCTIONS
-
-    Tested under Linux and Mac OSX with fltk 1.1.9.
-    (TBD: Windows, though will probably compile+run OK)
-
-    To build the test programs and related Fl_Tree object files:
-
-	make
-
-   These test programs are created:
-
-       	test-simple   -- Simple example of how to use the Fl_Tree widget
-	test-Fl_Tree  -- Exerciser app to test Fl_Tree's features
-
-WHERE'S THE DOCUMENTATION?
-
-    See documentation/html/index.html
-
-    The docs are in ./documentation/html and are doxyen based
-    (comments in code), and can be re-generated by running 
-    'make docs' or by simply running 'doxygen' while in ./documentation.
-
-
-RELEASE NOTES/VERSION INFORMATION
-    
-    See ./CHANGES
-
-BUGS?
-    
-    Send them to erco at seriss dot com
diff --git a/demos/indheat.geo b/demos/indheat.geo
index f706faed031d8118d07e2de160b8b0cec4fb9abe..5e7c22fe4f7c2ab0aef01b80b48d3b498415356a 100644
--- a/demos/indheat.geo
+++ b/demos/indheat.geo
@@ -13,10 +13,10 @@ DefineConstant
  lb = {1, Label "Infinite box width"},
  left = {1, Choices{0,1}, Label "Terminals on the left?"}
  //macro = {"aa.pos", Label "Run my macro!", Kind "macro", Path "Actions"},
- // showLines = {1, Choices {0,1}, Label "Show lines?"}
+  showLines = {1, Choices {0,1}, Label "Show lines?"}
 ];
 
-//Geometry.Lines = showLines;
+Geometry.Lines = showLines;
 
 // inductor
 p = newp;
diff --git a/doc/CREDITS.txt b/doc/CREDITS.txt
index e363db09ba1d78e77c82d8f074efc80256764e71..90968526a119830abaa3fdf3a48101b110776572 100644
--- a/doc/CREDITS.txt
+++ b/doc/CREDITS.txt
@@ -66,9 +66,6 @@ written by Bruce Hendrickson and Robert Leland at Sandia National Laboratories
 under US Department of Energy contract DE-AC04-76DP00789 and is copyrighted by
 Sandia Corporation: check the configuration options.
 
-This version of Gmsh may contain code (in the contrib/Fl_Tree subdirectory),
-copyright (C) 2009 Greg Ercolano: check the configuration options.
-
 This version of Gmsh may contain code (in the contrib/gmm subdirectory)
 copyright (C) 2002-2008 Yves Renard: check the configuration options.
 
diff --git a/doc/VERSIONS.txt b/doc/VERSIONS.txt
index b2cdce7bbe5f2b3e06a92a9c04243e91e9eb6968..b90079573319e0b17027be726ef97680303157f0 100644
--- a/doc/VERSIONS.txt
+++ b/doc/VERSIONS.txt
@@ -1,4 +1,5 @@
-faster STEP/BRep import; minor bug fixes.
+?: new single-window GUI, with dynamically customizable widget tree; faster
+STEP/BRep import; minor bug fixes.
 
 2.6.1 (July 15, 2012): minor improvements and bug fixes.