diff --git a/plugins/pyqcustomplot/CMakeLists.txt b/plugins/pyqcustomplot/CMakeLists.txt
index 8e7fe9cccef2e836a90443e52ffd4b045126e378..a751a24b5d3891b12cb6b5795133f7619f8912fc 100644
--- a/plugins/pyqcustomplot/CMakeLists.txt
+++ b/plugins/pyqcustomplot/CMakeLists.txt
@@ -32,6 +32,8 @@ GEPETTO_GUI_PLUGIN(pyqcustomplot
   qcustomplot.h
   plugin.hh
   decorator.hh
+  wrapper/qcp.hh
+  qcpitemrichtext.hh
 
   SOURCES
   qcustomplot.cpp
diff --git a/plugins/pyqcustomplot/decorator.cc b/plugins/pyqcustomplot/decorator.cc
index e3d5cd7e9aa7342b6359e1612015ddfbe7991550..29643394a3b193fb1ba35d2c400506d8fcbcc7b9 100644
--- a/plugins/pyqcustomplot/decorator.cc
+++ b/plugins/pyqcustomplot/decorator.cc
@@ -15,16 +15,51 @@
 // gepetto-viewer-corba. If not, see <http://www.gnu.org/licenses/>.
 
 #include <decorator.hh>
+#include <wrapper/qcp.hh>
 
 #include <PythonQt.h>
 
 void registerQCustomPlot ()
 {
+  PythonQt::self()->registerCPPClass ("QCP", "", "QCustomPlot", PythonQtCreateObject<wrapper::PyQCP>, NULL);
+
+  PythonQt::self()->registerClass (&QCustomPlot     ::staticMetaObject    , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPPainter      ::staticMetaObject    , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPLayer        ::staticMetaObject    , "QCustomPlot");
+
+  PythonQt::self()->registerClass (&QCPLayerable    ::staticMetaObject, "QCustomPlot");
+
+  PythonQt::self()->registerClass (&QCPAbstractPlottable::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPBars             ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPColorMap         ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPCurve            ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPFinancial        ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPGraph            ::staticMetaObject, "QCustomPlot");
+
+  PythonQt::self()->registerClass (&QCPAbstractItem ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemBracket     ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemCurve       ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemEllipse     ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemLine        ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemPixmap      ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemRect        ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemStraightLine::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemText        ::staticMetaObject , "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemRichText    ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPItemTracer      ::staticMetaObject , "QCustomPlot");
+  //PythonQt::self()->addParentClass ("QCPItemRichText", "QCPItemText", PythonQtUpcastingOffset<QCPItemRichText,QCPItemText>());
+
+  PythonQt::self()->registerClass (&QCPLayoutElement::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPLayout       ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPAxisRect     ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPLayoutGrid   ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPLegend       ::staticMetaObject, "QCustomPlot");
+  PythonQt::self()->registerClass (&QCPAxis         ::staticMetaObject, "QCustomPlot");
+
   PythonQt::self()->addDecorators (new QCustomPlotDecorator ());
   PythonQt::self()->registerCPPClass ("QCPPainter"           , "QPainter", "QCustomPlot");
   PythonQt::self()->registerCPPClass ("QCustomPlot"          , "QWidget" , "QCustomPlot");
   // PythonQt::self()->registerCPPClass ("QCPAxisPainterPrivate", "QGraphicsItem" , "QCustomPlot");
-  // PythonQt::self()->registerCPPClass ("QCPItemPosition"      , "QGraphicsItem" , "QCustomPlot");
   PythonQt::self()->registerCPPClass ("QCPLayer"             , "QObject" , "QCustomPlot");
   // PythonQt::self()->registerCPPClass ("QCPPlotTitle"         , "QGraphicsItem" , "QCustomPlot");
   // PythonQt::self()->registerCPPClass ("QCPAbstractLegendItem", "QGraphicsItem" , "QCustomPlot");
@@ -32,11 +67,24 @@ void registerQCustomPlot ()
   // PythonQt::self()->registerCPPClass ("QCPColorScale"        , "QGraphicsItem" , "QCustomPlot");
   // PythonQt::self()->registerCPPClass ("QCPBars"              , "QGraphicsItem" , "QCustomPlot");
 
+  PythonQt::self()->registerCPPClass ("QCPItemAnchor"        , NULL , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemPosition"      , "QCPItemAnchor" , "QCustomPlot");
+
   // Children of QCPLayerable
   PythonQt::self()->registerCPPClass ("QCPLayerable"         , "QObject" , "QCustomPlot");
 
   PythonQt::self()->registerCPPClass ("QCPAbstractItem"      , "QCPLayerable" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemBracket"       , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemCurve"         , "QCPAbstractItem" , "QCustomPlot");
   PythonQt::self()->registerCPPClass ("QCPItemEllipse"       , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemLine"          , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemPixmap"        , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemRect"          , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemStraightLine"  , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemText"          , "QCPAbstractItem" , "QCustomPlot");
+  PythonQt::self()->registerCPPClass ("QCPItemTracer"        , "QCPAbstractItem" , "QCustomPlot");
+
+  PythonQt::self()->registerCPPClass ("QCPItemRichText"      , "QCPItemText"     , "QCustomPlot");
 
   PythonQt::self()->registerCPPClass ("QCPAbstractPlottable" , "QCPLayerable" , "QCustomPlot");
   PythonQt::self()->registerCPPClass ("QCPBars"              , "QCPAbstractPlottable" , "QCustomPlot");
diff --git a/plugins/pyqcustomplot/decorator.hh b/plugins/pyqcustomplot/decorator.hh
index 8f5b3cb507bcdc62e6483c27b55fe5b4c5296691..cb8dadb767bea473e7d0ce4facd96960827cedb6 100644
--- a/plugins/pyqcustomplot/decorator.hh
+++ b/plugins/pyqcustomplot/decorator.hh
@@ -1,4 +1,5 @@
 #include <qcustomplot.h>
+#include <qcpitemrichtext.hh>
 
 #include <QObject>
 
@@ -36,32 +37,37 @@ class QCustomPlotDecorator : public QObject
     {
       return o->graph(graphnum);
     }
-    void replot (QCustomPlot* o) //replot object to visualise new data
+    void rescaleAxes(QCustomPlot* o, bool v = true) //rescale axis automatically if data does not fit
     {
-      o->replot();
+      o->rescaleAxes(v);
     }
-    void show (QCustomPlot* o) //open new window with graph
+    /// \param interaction See QCP::Interaction
+    void setInteraction(QCustomPlot* o, int interaction, bool enabled = true)
     {
-      o->show();
+      o->setInteraction((QCP::Interaction)interaction, enabled);
     }
-    void setWindowTitle(QCustomPlot* o,QString title) //set title of window of graph
+
+    bool savePdf (QCustomPlot* o, const QString &fileName, bool noCosmeticPen=false, int width=0, int height=0, const QString &pdfCreator=QString(), const QString &pdfTitle=QString())
     {
-      o->setWindowTitle(title);
+      return o->savePdf (fileName, noCosmeticPen, width, height, pdfCreator, pdfTitle);
     }
-    void rescaleAxes(QCustomPlot* o, bool v = true) //rescale axis automatically if data does not fit
+    bool savePng (QCustomPlot* o, const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1)
     {
-      o->rescaleAxes(v);
+      return o->savePng (fileName, width, height, scale, quality);
     }
-    QCPLayoutGrid* plotLayout (QCustomPlot* o) { return o->plotLayout (); }
-    void setAutoAddPlottableToLegend (QCustomPlot* o, bool v)
+    bool saveJpg (QCustomPlot* o, const QString &fileName, int width=0, int height=0, double scale=1.0, int quality=-1)
     {
-      o->setAutoAddPlottableToLegend (v);
+      return o->saveJpg (fileName, width, height, scale, quality);
     }
-    /// \param interaction See QCP::Interaction
-    void setInteraction(QCustomPlot* o, int interaction, bool enabled = true)
+    bool saveBmp (QCustomPlot* o, const QString &fileName, int width=0, int height=0, double scale=1.0)
     {
-      o->setInteraction((QCP::Interaction)interaction, enabled);
+      return o->saveBmp (fileName, width, height, scale);
+    }
+    bool saveRastered (QCustomPlot* o, const QString &fileName, int width, int height, double scale, const char *format, int quality=-1)
+    {
+      return o->saveRastered (fileName, width, height, scale, format, quality);
     }
+
     QCPAxis* xAxis  (QCustomPlot* o) { return o->xAxis ; }
     QCPAxis* xAxis2 (QCustomPlot* o) { return o->xAxis2; }
     QCPAxis* yAxis  (QCustomPlot* o) { return o->yAxis ; }
@@ -71,6 +77,8 @@ class QCustomPlotDecorator : public QObject
     /// \}
 
     /// \name QCPAxis
+    /// \todo Most of this function should be removed as they duplicates the
+    ///       QProperty methods.
     /// \{
     int selectedParts(const QCPAxis* a)
     {
@@ -169,22 +177,10 @@ class QCustomPlotDecorator : public QObject
     {
       ap->rescaleAxes(v);
     }
-    void setName (QCPAbstractPlottable* ap, const QString &n)
-    {
-      ap->setName(n);
-    }
-    void setPen (QCPAbstractPlottable* ap, const QPen &pen)
-    {
-      ap->setPen(pen);
-    }
     /// \}
 
     /// \name QCPLayerable
     /// \{
-    void setVisible (QCPLayerable* l, const bool &v)
-    {
-      l->setVisible(v);
-    }
     /// \}
 
     /// \name QCPLayoutGrid
@@ -210,4 +206,41 @@ class QCustomPlotDecorator : public QObject
       ar->setRangeZoomAxes (horizontal, vertical);
     }
     /// \}
+
+    /// \name QCPItemPosition
+    /// \{
+    void setType (QCPItemPosition* ip, int type) { return ip->setType((QCPItemPosition::PositionType)type); }
+    bool setParentAnchor (QCPItemPosition* ip, QCPItemAnchor* a) { return ip->setParentAnchor (a); }
+    void setCoords (QCPItemPosition* ip, double k, double v) { return ip->setCoords (k, v); }
+    /// \}
+
+    /// \name QCPAbstractItem
+    /// \{
+    QCPItemPosition* position (QCPAbstractItem* ai, QString p) { return ai->position(p); }
+    QCPItemAnchor  * anchor   (QCPAbstractItem* ai, QString a) { return ai->anchor  (a); }
+    /// \}
+
+    /// \name QCPItemTracer
+    /// \{
+    QCPItemTracer* new_QCPItemTracer (QCustomPlot* parent) { return new QCPItemTracer (parent); }
+    void delete_QCPItemTracer (QCPItemTracer* it) { delete it; }
+    /// \}
+
+    /// \name QCPItemRichText
+    /// \{
+    QCPItemRichText* new_QCPItemRichText (QCustomPlot* parent) { return new QCPItemRichText (parent); }
+    void delete_QCPItemRichText (QCPItemRichText* it) { delete it; }
+    /// \}
+
+    /// \name QCPItemText
+    /// \{
+    QCPItemText* new_QCPItemText (QCustomPlot* parent) { return new QCPItemText (parent); }
+    void delete_QCPItemText (QCPItemText* it) { delete it; }
+    /// \}
+
+    /// \name QCPItemEllipse
+    /// \{
+    QCPItemEllipse* new_QCPItemEllipse (QCustomPlot* parent) { return new QCPItemEllipse (parent); }
+    void delete_QCPItemEllipse (QCPItemEllipse* it) { delete it; }
+    /// \}
 };
diff --git a/plugins/pyqcustomplot/qcpitemrichtext.hh b/plugins/pyqcustomplot/qcpitemrichtext.hh
new file mode 100644
index 0000000000000000000000000000000000000000..eb28da6ac0600ecb089b3e85c1510b6d6f549961
--- /dev/null
+++ b/plugins/pyqcustomplot/qcpitemrichtext.hh
@@ -0,0 +1,56 @@
+#ifndef QCP_ITEM_RICH_TEXT
+#define QCP_ITEM_RICH_TEXT
+#include <qcustomplot.h>
+
+class QCP_LIB_DECL QCPItemRichText : public QCPItemText
+{ Q_OBJECT
+  Q_PROPERTY(QString text READ text WRITE setText)
+public:
+  QCPItemRichText(QCustomPlot *parentPlot)
+    : QCPItemText (parentPlot) {}
+  virtual ~QCPItemRichText() {}
+
+  void setText(const QString &text)
+  {
+    QCPItemText::setText (text);
+    doc.setHtml(text);
+  }
+  
+protected:
+  // reimplemented virtual methods:
+  virtual void draw(QCPPainter *painter)
+  {
+    QPointF pos(position->pixelPoint());
+    QTransform transform = painter->transform();
+    transform.translate(pos.x(), pos.y());
+    if (!qFuzzyIsNull(mRotation))
+      transform.rotate(mRotation);
+    painter->setFont(mainFont());
+    QRect textRect = painter->fontMetrics().boundingRect(0, 0, 0, 0, Qt::TextDontClip|mTextAlignment, mText);
+    QRect textBoxRect = textRect.adjusted(-mPadding.left(), -mPadding.top(), mPadding.right(), mPadding.bottom());
+    QPointF textPos = getTextDrawPoint(QPointF(0, 0), textBoxRect, mPositionAlignment); // 0, 0 because the transform does the translation
+    textRect.moveTopLeft(textPos.toPoint()+QPoint(mPadding.left(), mPadding.top()));
+    textBoxRect.moveTopLeft(textPos.toPoint());
+    qreal clipPadF = mainPen().widthF();
+    int clipPad = (int)clipPadF;
+    QRect boundingRect = textBoxRect.adjusted(-clipPad, -clipPad, clipPad, clipPad);
+    if (transform.mapRect(boundingRect).intersects(painter->transform().mapRect(clipRect())))
+    {
+      painter->setTransform(transform);
+      if ((mainBrush().style() != Qt::NoBrush && mainBrush().color().alpha() != 0) ||
+          (mainPen().style() != Qt::NoPen && mainPen().color().alpha() != 0))
+      {
+        painter->setPen(mainPen());
+        painter->setBrush(mainBrush());
+        painter->drawRect(textBoxRect);
+      }
+      painter->setBrush(Qt::NoBrush);
+      painter->setPen(QPen(mainColor()));
+      doc.setDefaultFont(mainFont());
+      doc.drawContents(painter);
+    }
+  }
+
+  QTextDocument doc;
+};
+#endif // QCP_ITEM_RICH_TEXT
diff --git a/plugins/pyqcustomplot/wrapper/qcp.hh b/plugins/pyqcustomplot/wrapper/qcp.hh
new file mode 100644
index 0000000000000000000000000000000000000000..7f5417dd2b0ff4a37fcb422baece6e5eccc0081b
--- /dev/null
+++ b/plugins/pyqcustomplot/wrapper/qcp.hh
@@ -0,0 +1,58 @@
+#ifndef WRAPPER_QCP_HH
+# define WRAPPER_QCP_HH
+# include <qcustomplot.h>
+
+namespace wrapper {
+class PyQCP : public QObject
+{ Q_OBJECT
+  public:
+    Q_ENUMS(MarginSide  AntialiasedElement  PlottingHint  Interaction )
+    Q_FLAGS(MarginSides AntialiasedElements PlottingHints Interactions)
+
+enum MarginSide { msLeft     = QCP::msLeft  
+                  ,msRight   = QCP::msRight 
+                  ,msTop     = QCP::msTop   
+                  ,msBottom  = QCP::msBottom
+                  ,msAll     = QCP::msAll   
+                  ,msNone    = QCP::msNone  
+                };
+Q_DECLARE_FLAGS(MarginSides, MarginSide)
+
+enum AntialiasedElement { aeAxes           = QCP::aeAxes       
+                          ,aeGrid          = QCP::aeGrid       
+                          ,aeSubGrid       = QCP::aeSubGrid    
+                          ,aeLegend        = QCP::aeLegend     
+                          ,aeLegendItems   = QCP::aeLegendItems
+                          ,aePlottables    = QCP::aePlottables 
+                          ,aeItems         = QCP::aeItems      
+                          ,aeScatters      = QCP::aeScatters   
+                          ,aeErrorBars     = QCP::aeErrorBars  
+                          ,aeFills         = QCP::aeFills      
+                          ,aeZeroLine      = QCP::aeZeroLine   
+                          ,aeAll           = QCP::aeAll        
+                          ,aeNone          = QCP::aeNone       
+                        };
+Q_DECLARE_FLAGS(AntialiasedElements, AntialiasedElement)
+
+enum PlottingHint { phNone            = QCP::phNone         
+                    ,phFastPolylines  = QCP::phFastPolylines
+                    ,phForceRepaint   = QCP::phForceRepaint 
+                    ,phCacheLabels    = QCP::phCacheLabels  
+                  };
+Q_DECLARE_FLAGS(PlottingHints, PlottingHint)
+
+enum Interaction { iRangeDrag         = QCP::iRangeDrag       
+                   ,iRangeZoom        = QCP::iRangeZoom       
+                   ,iMultiSelect      = QCP::iMultiSelect     
+                   ,iSelectPlottables = QCP::iSelectPlottables
+                   ,iSelectAxes       = QCP::iSelectAxes      
+                   ,iSelectLegend     = QCP::iSelectLegend    
+                   ,iSelectItems      = QCP::iSelectItems     
+                   ,iSelectOther      = QCP::iSelectOther     
+                 };
+Q_DECLARE_FLAGS(Interactions, Interaction)
+
+};
+}
+
+#endif // WRAPPER_QCP_HH
diff --git a/pyplugins/gepetto/gui/qcp_example.py b/pyplugins/gepetto/gui/qcp_example.py
new file mode 100644
index 0000000000000000000000000000000000000000..e1a2174600657008bb12d5a73fc805eca9734bb3
--- /dev/null
+++ b/pyplugins/gepetto/gui/qcp_example.py
@@ -0,0 +1,32 @@
+from PythonQt import QtGui
+from PythonQt.QCustomPlot import QCustomPlot, QCPItemTracer, QCPItemRichText, QCP
+
+class Plugin (QtGui.QDockWidget):
+    def __init__ (self, mainWindow, flags = None):
+        if flags is None:
+            super(Plugin, self).__init__ ("QCP example plugin", mainWindow)
+        else:
+            super(Plugin, self).__init__ ("QCP example plugin", mainWindow, flags)
+        self.setObjectName("QCP example plugin")
+
+        self.main = mainWindow
+        self.qcp = QCustomPlot ()
+        self.qcp.setInteraction (QCP.iRangeDrag, True)
+        self.qcp.setInteraction (QCP.iRangeZoom, True)
+        self.setWidget (self.qcp)
+
+        self.graph = self.qcp.addGraph ()
+        self.graph.setData ([0,1,2,3], [0.1,0.3,0.2,0])
+        self.qcp.replot()
+
+        self.tracer = QCPItemTracer (self.qcp)
+        self.tracer.graph = self.graph
+        self.tracer.graphKey = 0
+        self.tracer.style = 3
+
+        self.text = QCPItemRichText (self.qcp)
+        self.text.text = u"q<sub>0,0</sub>"
+        self.text.position("position").setParentAnchor(self.tracer.anchor("position"))
+        self.text.position("position").setCoords (0, -20)
+
+        self.graph.setData ([0,1,2,3], [1,0.3,0.2,0])