Index: plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc
===================================================================
--- plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc	(revision 1177751)
+++ plugins/tools/tool_perspectivetransform/kis_tool_perspectivetransform.cc	(working copy)
@@ -162,7 +162,6 @@
     m_handleHalfSize = 8;
     m_handleSize = 2 * m_handleHalfSize;
     m_handleSelected = NOHANDLE;
-    m_drawing = false;
 }
 
 KisToolPerspectiveTransform::~KisToolPerspectiveTransform()
@@ -312,13 +311,16 @@
 
 void KisToolPerspectiveTransform::mousePressEvent(KoPointerEvent *event)
 {
-    if (image()) {
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        setMode(KisTool::PAINT_MODE);
+
         switch (m_interractionMode) {
         case DRAWRECTINTERRACTION: {
             m_currentPt = convertToPixelCoord(event);
 
             if (m_points.isEmpty()) {
-                m_drawing = true;
                 m_hasMoveAfterFirstTime = false;
                 m_points.append(m_currentPt);
             } else {
@@ -330,7 +332,7 @@
             break;
         }
         case EDITRECTINTERRACTION: {
-            if (currentImage() && currentNode()->paintDevice() && event->button() == Qt::LeftButton) {
+            if (currentImage() && currentNode()->paintDevice()) {
                 m_actualyMoveWhileSelected = false;
                 m_dragEnd = convertToPixelCoord(event);
                 QPoint mousep = m_dragEnd.toPoint();
@@ -372,93 +374,98 @@
             }
         }
         }
+
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 void KisToolPerspectiveTransform::mouseMoveEvent(KoPointerEvent *event)
 {
-    switch (m_interractionMode) {
-    case DRAWRECTINTERRACTION: {
-        if (m_drawing) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+
+        switch (m_interractionMode) {
+        case DRAWRECTINTERRACTION: {
             // erase old lines on canvas
             updateCanvasPixelRect(image()->bounds());
-
             // update current point
             m_currentPt = convertToPixelCoord(event);
-
             // draw new lines on canvas
             updateCanvasPixelRect(image()->bounds());
+            break;
         }
-        break;
-    }
 
-    case EDITRECTINTERRACTION: {
-        if (m_currentSelectedPoint) {
-            updateCanvasPixelRect(image()->bounds());
-            QPointF translate = convertToPixelCoord(event) - m_dragEnd;
-            m_dragEnd = convertToPixelCoord(event);
-            *m_currentSelectedPoint += translate;
-            updateCanvasPixelRect(image()->bounds());
-            m_actualyMoveWhileSelected = true;
-        } else if (m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) {
-            updateCanvasPixelRect(image()->bounds());
+        case EDITRECTINTERRACTION: {
+            if (m_currentSelectedPoint) {
+                updateCanvasPixelRect(image()->bounds());
+                QPointF translate = convertToPixelCoord(event) - m_dragEnd;
+                m_dragEnd = convertToPixelCoord(event);
+                *m_currentSelectedPoint += translate;
+                updateCanvasPixelRect(image()->bounds());
+                m_actualyMoveWhileSelected = true;
+            } else if (m_handleSelected == TOPHANDLE || m_handleSelected == LEFTHANDLE || m_handleSelected == BOTTOMHANDLE || m_handleSelected == RIGHTHANDLE) {
+                updateCanvasPixelRect(image()->bounds());
 
-            QPointF translate = convertToPixelCoord(event) - m_dragEnd;
-            m_dragEnd = convertToPixelCoord(event);
+                QPointF translate = convertToPixelCoord(event) - m_dragEnd;
+                m_dragEnd = convertToPixelCoord(event);
 
-            switch (m_handleSelected) {
-            case TOPHANDLE:
+                switch (m_handleSelected) {
+                case TOPHANDLE:
+                    m_topleft += translate;
+                    m_topright += translate;
+                    break;
+                case LEFTHANDLE:
+                    m_topleft += translate;
+                    m_bottomleft += translate;
+                    break;
+                case BOTTOMHANDLE:
+                    m_bottomleft += translate;
+                    m_bottomright += translate;
+                    break;
+                case RIGHTHANDLE:
+                    m_topright += translate;
+                    m_bottomright += translate;
+                    break;
+                case MIDDLEHANDLE:
+                case NOHANDLE:
+                    dbgPlugins << "Should NOT happen";
+                }
+
+                updateCanvasPixelRect(image()->bounds());
+                m_actualyMoveWhileSelected = true;
+            } else if (m_handleSelected == MIDDLEHANDLE) {
+                updateCanvasPixelRect(image()->bounds());
+                QPointF translate = convertToPixelCoord(event) - m_dragEnd;
+                m_dragEnd = convertToPixelCoord(event);
                 m_topleft += translate;
                 m_topright += translate;
-                break;
-            case LEFTHANDLE:
-                m_topleft += translate;
                 m_bottomleft += translate;
-                break;
-            case BOTTOMHANDLE:
-                m_bottomleft += translate;
                 m_bottomright += translate;
-                break;
-            case RIGHTHANDLE:
-                m_topright += translate;
-                m_bottomright += translate;
-                break;
-            case MIDDLEHANDLE:
-            case NOHANDLE:
-                dbgPlugins << "Should NOT happen";
+
+                updateCanvasPixelRect(image()->bounds());
+                m_actualyMoveWhileSelected = true;
             }
-
-            updateCanvasPixelRect(image()->bounds());
-            m_actualyMoveWhileSelected = true;
-        } else if (m_handleSelected == MIDDLEHANDLE) {
-            updateCanvasPixelRect(image()->bounds());
-            QPointF translate = convertToPixelCoord(event) - m_dragEnd;
-            m_dragEnd = convertToPixelCoord(event);
-            m_topleft += translate;
-            m_topright += translate;
-            m_bottomleft += translate;
-            m_bottomright += translate;
-
-            updateCanvasPixelRect(image()->bounds());
-            m_actualyMoveWhileSelected = true;
         }
+        }
     }
+    else {
+        KisTool::mouseMoveEvent(event);
     }
 }
 
 void KisToolPerspectiveTransform::mouseReleaseEvent(KoPointerEvent * event)
 {
-    if (!currentImage())
-        return;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (event->button() == Qt::LeftButton) {
         switch (m_interractionMode) {
         case DRAWRECTINTERRACTION: {
-            if (m_drawing && event->button() == Qt::LeftButton && m_hasMoveAfterFirstTime)  {
+            if (m_hasMoveAfterFirstTime)  {
                 updateCanvasPixelRect(image()->bounds());
 
                 m_points.append(m_currentPt);
-                
+
                 if(m_points.size() == 4) {
                     QPolygonF polygon;
                     polygon << m_points[0] << m_points[1] << m_points[2] << m_points[3];
@@ -469,8 +476,8 @@
                         setStatusText(QString());
                     }
                 }
-                
 
+
                 if (m_points.size() == 4) {
                     // from the points, select which is topleft ? topright ? bottomright ? and bottomleft ?
                     orderHandles();
@@ -518,6 +525,9 @@
         }
         }
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolPerspectiveTransform::paintOutline()
Index: plugins/tools/tool_grid/kis_tool_grid.cc
===================================================================
--- plugins/tools/tool_grid/kis_tool_grid.cc	(revision 1177751)
+++ plugins/tools/tool_grid/kis_tool_grid.cc	(working copy)
@@ -37,7 +37,6 @@
 {
     Q_ASSERT(m_canvas);
     setObjectName("tool_grid");
-    m_dragging = false;
 }
 
 KisToolGrid::~KisToolGrid()
@@ -60,26 +59,34 @@
 
 void KisToolGrid::mousePressEvent(KoPointerEvent *event)
 {
-    m_dragging = true;
-    m_dragStart = convertToPixelCoord(event);
-    KisConfig cfg;
-    if (event->modifiers() == Qt::ControlModifier) {
-        m_currentMode = SCALE;
-    } else {
-        m_currentMode = TRANSLATION;
-    }
+    if(PRESS_CONDITION_OM(event, KisTool::HOVER_MODE,
+                          Qt::LeftButton, Qt::ControlModifier)) {
 
-    if (m_currentMode == TRANSLATION) {
-        m_initialOffset = QPoint(cfg.getGridOffsetX(), cfg.getGridOffsetY());
-    } else {
-        m_initialSpacing = QPoint(cfg.getGridHSpacing(), cfg.getGridVSpacing());
+        setMode(KisTool::PAINT_MODE);
+
+        m_dragStart = convertToPixelCoord(event);
+        KisConfig cfg;
+        if (event->modifiers() == Qt::ControlModifier) {
+            m_currentMode = SCALE;
+        } else {
+            m_currentMode = TRANSLATION;
+        }
+
+        if (m_currentMode == TRANSLATION) {
+            m_initialOffset = QPoint(cfg.getGridOffsetX(), cfg.getGridOffsetY());
+        } else {
+            m_initialSpacing = QPoint(cfg.getGridHSpacing(), cfg.getGridVSpacing());
+        }
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 
 void KisToolGrid::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         KisConfig cfg;
         int subdivisions = cfg.getGridSubdivisions();
         m_dragEnd = convertToPixelCoord(event);
@@ -93,15 +100,20 @@
             if (newSize.y() >= 1) cfg.setGridVSpacing(newSize.y());
         }
         m_canvas->updateCanvas();
-    } else {
-        event->ignore();
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
 void KisToolGrid::mouseReleaseEvent(KoPointerEvent *event)
 {
-    Q_UNUSED(event);
-    m_dragging = false;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
+    }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolGrid::paint(QPainter& gc, const KoViewConverter &converter)
Index: plugins/tools/tool_grid/kis_tool_grid.h
===================================================================
--- plugins/tools/tool_grid/kis_tool_grid.h	(revision 1177751)
+++ plugins/tools/tool_grid/kis_tool_grid.h	(working copy)
@@ -55,7 +55,6 @@
     QPoint m_initialSpacing;
 
     Mode m_currentMode;
-    bool m_dragging;
 };
 
 
Index: plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc
===================================================================
--- plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc	(revision 1177751)
+++ plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.cc	(working copy)
@@ -51,8 +51,6 @@
 {
     Q_ASSERT(m_canvas);
     setObjectName("tool_perspectivegrid");
-
-    m_drawing = false;
 }
 
 KisToolPerspectiveGrid::~KisToolPerspectiveGrid()
@@ -65,10 +63,10 @@
 
     m_canvas->view()->perspectiveGridManager()->startEdition();
     if (! m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid()->hasSubGrids()) {
-        m_mode = MODE_CREATION;
+        m_internalMode = MODE_CREATION;
         m_points.clear();
     } else {
-        m_mode = MODE_EDITING;
+        m_internalMode = MODE_EDITING;
         useCursor(KisCursor::arrowCursor());
         m_canvas->view()->perspectiveGridManager()->setVisible(true);
         m_canvas->updateCanvas(); // TODO only the correct rect
@@ -78,9 +76,8 @@
 void KisToolPerspectiveGrid::deactivate()
 {
     m_canvas->view()->perspectiveGridManager()->stopEdition();
-    if (m_mode == MODE_CREATION) {
+    if (m_internalMode == MODE_CREATION) {
         m_points.clear();
-        m_drawing = false;
     }
     m_canvas->updateCanvas();
 }
@@ -112,168 +109,187 @@
 
 void KisToolPerspectiveGrid::mousePressEvent(KoPointerEvent *event)
 {
-    KisPerspectiveGrid* pGrid = m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid();
-    if (!pGrid->hasSubGrids() && m_mode != MODE_CREATION) { // it's possible that the perspectiv grid was cleared
-        m_mode = MODE_CREATION;
-        m_points.clear();
-    }
-    if (m_mode == MODE_CREATION && event->button() == Qt::LeftButton) {
-        m_drawing = true;
-        m_currentPt = event->point;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-        if (m_points.isEmpty()) {
-            m_points.append(m_currentPt);
-            m_isFirstPoint = true;
-        } else {
-            m_isFirstPoint = false;
+        setMode(KisTool::PAINT_MODE);
+
+        KisPerspectiveGrid* pGrid = m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid();
+        if (!pGrid->hasSubGrids() && m_internalMode != MODE_CREATION) { // it's possible that the perspectiv grid was cleared
+            m_internalMode = MODE_CREATION;
+            m_points.clear();
         }
-        m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-    } else if (m_mode == MODE_EDITING && event->button() == Qt::LeftButton) {
-        // Look for the handle which was pressed
-        QPointF mousep = m_canvas->viewConverter()->documentToView(event->point);
-        for (QList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) {
-            KisSubPerspectiveGrid* grid = *it;
-            QPointF gridCenter = grid->center();
-            dbgKrita << "click at " << event->point << " top left at " << *grid->topLeft();
-            if (m_selectedNode1 = nodeNearPoint(grid, mousep)) {
-                m_mode = MODE_DRAGING_NODE;
-                break;
-            } else if (mouseNear(mousep, ((pixelToView(*grid->topLeft()) + pixelToView(*grid->bottomLeft()))*0.5))) {
-                dbgPlugins << " PRESS LEFT HANDLE";
-                m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
-                m_selectedNode1 = new KisPerspectiveGridNode(*grid->topLeft());
-                m_selectedNode2 = new KisPerspectiveGridNode(*grid->bottomLeft());
-                KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2);
-                m_dragEnd = convertToPixelCoord(event->point);
-                pGrid->addNewSubGrid(newsubgrid);
-                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-                break;
-            } else if (mouseNear(mousep, ((pixelToView(*grid->topRight()) + pixelToView(*grid->bottomRight()))*0.5))) {
-                dbgPlugins << " PRESS RIGHT HANDLE";
-                m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
-                m_selectedNode1 = new KisPerspectiveGridNode(*grid->topRight());
-                m_selectedNode2 = new KisPerspectiveGridNode(*grid->bottomRight());
-                KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight());
-                m_dragEnd = convertToPixelCoord(event->point);
-                pGrid->addNewSubGrid(newsubgrid);
-                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-                break;
-            } else if (mouseNear(mousep, ((pixelToView(*grid->topLeft()) + pixelToView(*grid->topRight()))*0.5))) {
-                dbgPlugins << " PRESS TOP HANDLE";
-                m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
-                m_selectedNode1 = new KisPerspectiveGridNode(*grid->topLeft());
-                m_selectedNode2 = new KisPerspectiveGridNode(*grid->topRight());
-                KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(m_selectedNode1, m_selectedNode2,  grid->topRight(), grid->topLeft());
-                m_dragEnd = convertToPixelCoord(event->point);
-                pGrid->addNewSubGrid(newsubgrid);
-                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-                break;
-            } else if (mouseNear(mousep, ((pixelToView(*grid->bottomLeft()) + pixelToView(*grid->bottomRight()))*0.5))) {
-                dbgPlugins << " PRESS BOTTOM HANDLE";
-                m_mode = MODE_DRAGING_TRANSLATING_TWONODES;
-                m_selectedNode1 = new KisPerspectiveGridNode(*grid->bottomLeft());
-                m_selectedNode2 = new KisPerspectiveGridNode(*grid->bottomRight());
-                KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1);
-                m_dragEnd = convertToPixelCoord(event->point);
-                pGrid->addNewSubGrid(newsubgrid);
-                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-                break;
-            } else if (pixelToView(QRectF((gridCenter.x() - 16), (gridCenter.y() - 16), 32, 32)).contains(mousep)) {
-                dbgPlugins << " PRESS DELETE ICON";
-                pGrid->deleteSubGrid(grid);
-                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-                if (!pGrid->hasSubGrids()) {
-                    m_mode = MODE_CREATION;
-                    useCursor(KisCursor::load("tool_perspectivegrid_cursor.png", 6, 6));
-                    m_points.clear();
+        if (m_internalMode == MODE_CREATION) {
+            m_currentPt = event->point;
+
+            if (m_points.isEmpty()) {
+                m_points.append(m_currentPt);
+                m_isFirstPoint = true;
+            } else {
+                m_isFirstPoint = false;
+            }
+            m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+        } else if (m_internalMode == MODE_EDITING) {
+            // Look for the handle which was pressed
+            QPointF mousep = m_canvas->viewConverter()->documentToView(event->point);
+            for (QList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) {
+                KisSubPerspectiveGrid* grid = *it;
+                QPointF gridCenter = grid->center();
+                dbgKrita << "click at " << event->point << " top left at " << *grid->topLeft();
+                if (m_selectedNode1 = nodeNearPoint(grid, mousep)) {
+                    m_internalMode = MODE_DRAGING_NODE;
+                    break;
+                } else if (mouseNear(mousep, ((pixelToView(*grid->topLeft()) + pixelToView(*grid->bottomLeft()))*0.5))) {
+                    dbgPlugins << " PRESS LEFT HANDLE";
+                    m_internalMode = MODE_DRAGING_TRANSLATING_TWONODES;
+                    m_selectedNode1 = new KisPerspectiveGridNode(*grid->topLeft());
+                    m_selectedNode2 = new KisPerspectiveGridNode(*grid->bottomLeft());
+                    KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(m_selectedNode1, grid->topLeft() , grid->bottomLeft(), m_selectedNode2);
+                    m_dragEnd = convertToPixelCoord(event->point);
+                    pGrid->addNewSubGrid(newsubgrid);
+                    m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                    break;
+                } else if (mouseNear(mousep, ((pixelToView(*grid->topRight()) + pixelToView(*grid->bottomRight()))*0.5))) {
+                    dbgPlugins << " PRESS RIGHT HANDLE";
+                    m_internalMode = MODE_DRAGING_TRANSLATING_TWONODES;
+                    m_selectedNode1 = new KisPerspectiveGridNode(*grid->topRight());
+                    m_selectedNode2 = new KisPerspectiveGridNode(*grid->bottomRight());
+                    KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(grid->topRight(), m_selectedNode1, m_selectedNode2, grid->bottomRight());
+                    m_dragEnd = convertToPixelCoord(event->point);
+                    pGrid->addNewSubGrid(newsubgrid);
+                    m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                    break;
+                } else if (mouseNear(mousep, ((pixelToView(*grid->topLeft()) + pixelToView(*grid->topRight()))*0.5))) {
+                    dbgPlugins << " PRESS TOP HANDLE";
+                    m_internalMode = MODE_DRAGING_TRANSLATING_TWONODES;
+                    m_selectedNode1 = new KisPerspectiveGridNode(*grid->topLeft());
+                    m_selectedNode2 = new KisPerspectiveGridNode(*grid->topRight());
+                    KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(m_selectedNode1, m_selectedNode2,  grid->topRight(), grid->topLeft());
+                    m_dragEnd = convertToPixelCoord(event->point);
+                    pGrid->addNewSubGrid(newsubgrid);
+                    m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                    break;
+                } else if (mouseNear(mousep, ((pixelToView(*grid->bottomLeft()) + pixelToView(*grid->bottomRight()))*0.5))) {
+                    dbgPlugins << " PRESS BOTTOM HANDLE";
+                    m_internalMode = MODE_DRAGING_TRANSLATING_TWONODES;
+                    m_selectedNode1 = new KisPerspectiveGridNode(*grid->bottomLeft());
+                    m_selectedNode2 = new KisPerspectiveGridNode(*grid->bottomRight());
+                    KisSubPerspectiveGrid* newsubgrid = new KisSubPerspectiveGrid(grid->bottomLeft(), grid->bottomRight(), m_selectedNode2, m_selectedNode1);
+                    m_dragEnd = convertToPixelCoord(event->point);
+                    pGrid->addNewSubGrid(newsubgrid);
+                    m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                    break;
+                } else if (pixelToView(QRectF((gridCenter.x() - 16), (gridCenter.y() - 16), 32, 32)).contains(mousep)) {
+                    dbgPlugins << " PRESS DELETE ICON";
+                    pGrid->deleteSubGrid(grid);
+                    m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                    if (!pGrid->hasSubGrids()) {
+                        m_internalMode = MODE_CREATION;
+                        useCursor(KisCursor::load("tool_perspectivegrid_cursor.png", 6, 6));
+                        m_points.clear();
+                    }
+                    break;
                 }
-                break;
             }
         }
+
+
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 
 void KisToolPerspectiveGrid::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_mode == MODE_CREATION) {
-        if (!m_points.isEmpty()) {
-            // get current mouse position
-            m_currentPt = event->point;
-            // draw new lines on canvas
-            m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+        if (m_internalMode == MODE_CREATION) {
+            if (!m_points.isEmpty()) {
+                // get current mouse position
+                m_currentPt = event->point;
+                // draw new lines on canvas
+                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+            }
+        } else {
+            if (m_internalMode == MODE_DRAGING_NODE) {
+                QPointF pos = convertToPixelCoord(event);
+                m_selectedNode1->setX(pos.x());
+                m_selectedNode1->setY(pos.y());
+                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+            }
+            if (m_internalMode == MODE_DRAGING_TRANSLATING_TWONODES) {
+                QPointF translate = convertToPixelCoord(event->point) - m_dragEnd;
+                m_dragEnd = convertToPixelCoord(event->point);
+                *m_selectedNode1 += translate;;
+                *m_selectedNode2 += translate;;
+                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+            }
         }
-    } else {
-        if (m_mode == MODE_DRAGING_NODE) {
-            QPointF pos = convertToPixelCoord(event);
-            m_selectedNode1->setX(pos.x());
-            m_selectedNode1->setY(pos.y());
-            m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+        bool wasHiglightedNode = m_higlightedNode != 0;
+        QPointF mousep = m_canvas->viewConverter()->documentToView(event->point);
+        KisPerspectiveGrid* pGrid = m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid();
+        for (QList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) {
+            KisSubPerspectiveGrid* grid = *it;
+            if (m_higlightedNode = nodeNearPoint(grid, mousep)) {
+                if (m_higlightedNode == m_selectedNode1 || m_higlightedNode == m_selectedNode2) {
+                    m_higlightedNode = 0;
+                } else {
+                    m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                    break;
+                }
+            }
         }
-        if (m_mode == MODE_DRAGING_TRANSLATING_TWONODES) {
-            QPointF translate = convertToPixelCoord(event->point) - m_dragEnd;
-            m_dragEnd = convertToPixelCoord(event->point);
-            *m_selectedNode1 += translate;;
-            *m_selectedNode2 += translate;;
+        if (wasHiglightedNode && !m_higlightedNode) {
             m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
         }
     }
-    bool wasHiglightedNode = m_higlightedNode != 0;
-    QPointF mousep = m_canvas->viewConverter()->documentToView(event->point);
-    KisPerspectiveGrid* pGrid = m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid();
-    for (QList<KisSubPerspectiveGrid*>::const_iterator it = pGrid->begin(); it != pGrid->end(); ++it) {
-        KisSubPerspectiveGrid* grid = *it;
-        if (m_higlightedNode = nodeNearPoint(grid, mousep)) {
-            if (m_higlightedNode == m_selectedNode1 || m_higlightedNode == m_selectedNode2) {
-                m_higlightedNode = 0;
-            } else {
-                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-                break;
-            }
-        }
+    else {
+        KisTool::mouseMoveEvent(event);
     }
-    if (wasHiglightedNode && !m_higlightedNode) {
-        m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-    }
 }
 
 void KisToolPerspectiveGrid::mouseReleaseEvent(KoPointerEvent *event)
 {
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (m_mode == MODE_CREATION) {
-        if (m_drawing && event->button() == Qt::LeftButton && !m_isFirstPoint)  {
-            m_points.append(m_currentPt);
-            if (m_points.size() == 4) { // wow we have a grid, isn't that cool ?
-                m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid()->addNewSubGrid(
-                    new KisSubPerspectiveGrid(
-                        new KisPerspectiveGridNode(convertToPixelCoord(m_points[0])),
-                        new KisPerspectiveGridNode(convertToPixelCoord(m_points[1])),
-                        new KisPerspectiveGridNode(convertToPixelCoord(m_points[2])),
-                        new KisPerspectiveGridNode(convertToPixelCoord(m_points[3]))));
-                m_canvas->view()->perspectiveGridManager()->setVisible(true);
-                m_mode = MODE_EDITING;
-                useCursor(KisCursor::arrowCursor());
+        if (m_internalMode == MODE_CREATION) {
+            if (!m_isFirstPoint)  {
+                m_points.append(m_currentPt);
+                if (m_points.size() == 4) { // wow we have a grid, isn't that cool ?
+                    m_canvas->view()->resourceProvider()->currentImage()->perspectiveGrid()->addNewSubGrid(
+                        new KisSubPerspectiveGrid(
+                            new KisPerspectiveGridNode(convertToPixelCoord(m_points[0])),
+                            new KisPerspectiveGridNode(convertToPixelCoord(m_points[1])),
+                            new KisPerspectiveGridNode(convertToPixelCoord(m_points[2])),
+                            new KisPerspectiveGridNode(convertToPixelCoord(m_points[3]))));
+                    m_canvas->view()->perspectiveGridManager()->setVisible(true);
+                    m_internalMode = MODE_EDITING;
+                    useCursor(KisCursor::arrowCursor());
+                }
             }
-        }
-        m_drawing = false;
-        m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-    } else {
-        m_mode = MODE_EDITING;
-        // Check if there is a need for merging two nodes
-        if (m_higlightedNode && m_selectedNode2 == 0) {
-            m_higlightedNode->mergeWith(m_selectedNode1);
             m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+        } else {
+            m_internalMode = MODE_EDITING;
+            // Check if there is a need for merging two nodes
+            if (m_higlightedNode && m_selectedNode2 == 0) {
+                m_higlightedNode->mergeWith(m_selectedNode1);
+                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+            }
+            m_selectedNode1 = 0;
+            m_selectedNode2 = 0;
         }
-        m_selectedNode1 = 0;
-        m_selectedNode2 = 0;
     }
-
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolPerspectiveGrid::paint(QPainter& gc, const KoViewConverter &converter)
 {
     Q_UNUSED(converter);
-    if (m_mode == MODE_CREATION) {
+    if (m_internalMode == MODE_CREATION) {
         drawGridCreation(gc);
     } else {
         drawGrid(gc);
Index: plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h
===================================================================
--- plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h	(revision 1177751)
+++ plugins/tools/tool_perspectivegrid/kis_tool_perspectivegrid.h	(working copy)
@@ -72,14 +72,13 @@
 protected:
     QPointF m_dragEnd;
 
-    bool m_drawing;
     bool m_isFirstPoint;
     QPointF m_currentPt;
 private:
     typedef QVector<QPointF> QPointFVector;
 
     QPointFVector m_points;
-    PerspectiveGridEditionMode m_mode;
+    PerspectiveGridEditionMode m_internalMode;
     qint32 m_handleSize, m_handleHalfSize;
     KisPerspectiveGridNodeSP m_selectedNode1, m_selectedNode2, m_higlightedNode;
     KisCanvas2* m_canvas;
Index: plugins/tools/tool_crop/kis_tool_crop.cc
===================================================================
--- plugins/tools/tool_crop/kis_tool_crop.cc	(revision 1177751)
+++ plugins/tools/tool_crop/kis_tool_crop.cc	(working copy)
@@ -52,7 +52,6 @@
         : KisTool(canvas, KisCursor::load("tool_crop_cursor.png", 6, 6))
 {
     setObjectName("tool_crop");
-    m_selecting = false;
     m_rectCrop = QRect(0, 0, 0, 0);
     m_handleSize = 13;
     m_haveCropSelection = false;
@@ -88,7 +87,6 @@
 
 void KisToolCrop::deactivate()
 {
-    m_selecting = false;
     m_haveCropSelection = false;
     m_rectCrop = QRect(0, 0, 0, 0);
     updateWidgetValues();
@@ -117,191 +115,188 @@
     paintOutlineWithHandles(painter);
 }
 
-void KisToolCrop::mousePressEvent(KoPointerEvent *e)
+void KisToolCrop::mousePressEvent(KoPointerEvent *event)
 {
-    if (canvas()) {
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-        if (!currentNode())
-            return;
+        setMode(KisTool::PAINT_MODE);
 
-        if (currentImage() && e->button() == Qt::LeftButton) {
+        QPoint pos = convertToIntPixelCoord(event);
 
-            QPoint pos = convertToIntPixelCoord(e);
+        pos.setX(qBound(0, pos.x(), image()->width() - 1));
+        pos.setY(qBound(0, pos.y(), image()->height() - 1));
 
-            pos.setX(qBound(0, pos.x(), image()->width() - 1));
-            pos.setY(qBound(0, pos.y(), image()->height() - 1));
-
-            m_selecting = true;
-
-            if (!m_haveCropSelection) { //if the selection is not set
-                m_rectCrop = QRect(pos.x(), pos.y(), 1, 1);
-                updateCanvasPixelRect(image()->bounds());
-            } else {
-                m_mouseOnHandleType = mouseOnHandle(pixelToView(convertToPixelCoord(e)));
-                m_dragStart = pos;
-            }
+        if (!m_haveCropSelection) { //if the selection is not set
+            m_rectCrop = QRect(pos.x(), pos.y(), 1, 1);
+            updateCanvasPixelRect(image()->bounds());
+        } else {
+            m_mouseOnHandleType = mouseOnHandle(pixelToView(convertToPixelCoord(event)));
+            m_dragStart = pos;
         }
+
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
-#include <QDebug>
-
-void KisToolCrop::mouseMoveEvent(KoPointerEvent *e)
+void KisToolCrop::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (canvas() && currentImage()) {
-        if (m_selecting) { //if the user selects
-            QPoint pos = convertToIntPixelCoord(e);
+    QPointF pos = convertToPixelCoord(event);
 
-            if (!m_haveCropSelection) { //if the cropSelection is not yet set
-                QRectF updateRect = boundingRect();
+    if (m_haveCropSelection) {  //if the crop selection is set
+        qint32 type = mouseOnHandle(pixelToView(pos));
+        //set resize cursor if we are on one of the handles
+        setMoveResizeCursor(type);
+    }
 
-                m_rectCrop.setBottomRight(convertToIntPixelCoord(e));
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
 
-                m_rectCrop.setRight(qBound(0, m_rectCrop.right(), image()->width() - 1));
-                m_rectCrop.setBottom(qBound(0, m_rectCrop.bottom(), image()->height() - 1));
+        if (!m_haveCropSelection) { //if the cropSelection is not yet set
+            QRectF updateRect = boundingRect();
+            m_rectCrop.setBottomRight(pos.toPoint());
 
-                updateRect |= boundingRect();
-                updateCanvasViewRect(updateRect);
+            m_rectCrop.setRight(qBound(0, m_rectCrop.right(), image()->width() - 1));
+            m_rectCrop.setBottom(qBound(0, m_rectCrop.bottom(), image()->height() - 1));
 
-                QRect r = m_rectCrop.normalized();
-                setOptionWidgetRatio((double)r.width() / (double)r.height());
+            updateRect |= boundingRect();
+            updateCanvasViewRect(updateRect);
 
-            } else { //if the crop selection is set
-                QPoint dragStop = pos;
-                QPoint drag = dragStop - m_dragStart;
+            QRect r = m_rectCrop.normalized();
+            setOptionWidgetRatio((double)r.width() / (double)r.height());
 
-                if (m_mouseOnHandleType != None && m_dragStart != dragStop) {
+        } else { //if the crop selection is set
+            QPoint dragStop = pos.toPoint();
+            QPoint drag = dragStop - m_dragStart;
 
-                    qint32 imageWidth = currentImage()->width();
-                    qint32 imageHeight = currentImage()->height();
+            if (m_mouseOnHandleType != None && m_dragStart != dragStop) {
 
-                    QRectF updateRect = boundingRect();
+                qint32 imageWidth = currentImage()->width();
+                qint32 imageHeight = currentImage()->height();
 
-                    if (m_mouseOnHandleType == Inside) {
-                        m_rectCrop.translate(drag);
+                QRectF updateRect = boundingRect();
 
-                        if (m_rectCrop.left() < 0) {
-                            m_rectCrop.moveLeft(0);
+                if (m_mouseOnHandleType == Inside) {
+                    m_rectCrop.translate(drag);
+
+                    if (m_rectCrop.left() < 0) {
+                        m_rectCrop.moveLeft(0);
+                    }
+                    if (m_rectCrop.right() > imageWidth - 1) {
+                        m_rectCrop.moveRight(imageWidth - 1);
+                    }
+                    if (m_rectCrop.top() < 0) {
+                        m_rectCrop.moveTop(0);
+                    }
+                    if (m_rectCrop.bottom() > imageHeight - 1) {
+                        m_rectCrop.moveBottom(imageHeight - 1);
+                    }
+                } else if (m_optWidget->boolRatio->isChecked()) {
+                    if (! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked()) {
+                        QRect newRect = m_rectCrop;
+                        switch (m_mouseOnHandleType) {
+                        case(UpperLeft): {
+                            qint32 dep = (drag.x() + drag.y()) / 2;
+                            newRect.setTop(newRect.top() + dep);
+                            newRect.setLeft(newRect.right() - m_optWidget->doubleRatio->value() * newRect.height());
                         }
-                        if (m_rectCrop.right() > imageWidth - 1) {
-                            m_rectCrop.moveRight(imageWidth - 1);
+                            break;
+                        case(LowerRight): {
+                            qint32 dep = (drag.x() + drag.y()) / 2;
+                            newRect.setBottom(newRect.bottom() + dep);
+                            newRect.setWidth((int)(m_optWidget->doubleRatio->value() * newRect.height()));
+                            break;
                         }
-                        if (m_rectCrop.top() < 0) {
-                            m_rectCrop.moveTop(0);
+                        case(UpperRight): {
+                            qint32 dep = (drag.x() - drag.y()) / 2;
+                            newRect.setTop(newRect.top() - dep);
+                            newRect.setWidth((int)(m_optWidget->doubleRatio->value() * newRect.height()));
+                            break;
                         }
-                        if (m_rectCrop.bottom() > imageHeight - 1) {
-                            m_rectCrop.moveBottom(imageHeight - 1);
+                        case(LowerLeft): {
+                            qint32 dep = (drag.x() - drag.y()) / 2;
+                            newRect.setBottom(newRect.bottom() - dep);
+                            newRect.setLeft((int)(newRect.right() - m_optWidget->doubleRatio->value() * newRect.height()));
+                            break;
                         }
-                    } else if (m_optWidget->boolRatio->isChecked()) {
-                        if (! m_optWidget->boolWidth->isChecked() && !m_optWidget->boolHeight->isChecked()) {
-                            QRect newRect = m_rectCrop;
-                            switch (m_mouseOnHandleType) {
-                            case(UpperLeft): {
-                                qint32 dep = (drag.x() + drag.y()) / 2;
-                                newRect.setTop(newRect.top() + dep);
-                                newRect.setLeft(newRect.right() - m_optWidget->doubleRatio->value() * newRect.height());
-                            }
+                        case(Upper):
+                            newRect.setTop(pos.y());
+                            newRect.setWidth((int)(newRect.height() * m_optWidget->doubleRatio->value()));
                             break;
-                            case(LowerRight): {
-                                qint32 dep = (drag.x() + drag.y()) / 2;
-                                newRect.setBottom(newRect.bottom() + dep);
-                                newRect.setWidth((int)(m_optWidget->doubleRatio->value() * newRect.height()));
-                                break;
-                            }
-                            case(UpperRight): {
-                                qint32 dep = (drag.x() - drag.y()) / 2;
-                                newRect.setTop(newRect.top() - dep);
-                                newRect.setWidth((int)(m_optWidget->doubleRatio->value() * newRect.height()));
-                                break;
-                            }
-                            case(LowerLeft): {
-                                qint32 dep = (drag.x() - drag.y()) / 2;
-                                newRect.setBottom(newRect.bottom() - dep);
-                                newRect.setLeft((int)(newRect.right() - m_optWidget->doubleRatio->value() * newRect.height()));
-                                break;
-                            }
-                            case(Upper):
-                                newRect.setTop(pos.y());
-                                newRect.setWidth((int)(newRect.height() * m_optWidget->doubleRatio->value()));
-                                break;
-                            case(Lower):
-                                newRect.setBottom(pos.y());
-                                newRect.setWidth((int)(newRect.height() * m_optWidget->doubleRatio->value()));
-                                break;
-                            case(Left):
-                                newRect.setLeft(pos.x());
-                                newRect.setHeight((int)(newRect.width() / m_optWidget->doubleRatio->value()));
-                                break;
-                            case(Right):
-                                newRect.setRight(pos.x());
-                                newRect.setHeight((int)(newRect.width() / m_optWidget->doubleRatio->value()));
-                                break;
-                            case(Inside):  // never happen
-                                break;
-                            }
-                            if (newRect.intersected(QRect(0,0,imageWidth,imageHeight))==newRect)
-                                m_rectCrop=newRect;
+                        case(Lower):
+                            newRect.setBottom(pos.y());
+                            newRect.setWidth((int)(newRect.height() * m_optWidget->doubleRatio->value()));
+                            break;
+                        case(Left):
+                            newRect.setLeft(pos.x());
+                            newRect.setHeight((int)(newRect.width() / m_optWidget->doubleRatio->value()));
+                            break;
+                        case(Right):
+                            newRect.setRight(pos.x());
+                            newRect.setHeight((int)(newRect.width() / m_optWidget->doubleRatio->value()));
+                            break;
+                        case(Inside):  // never happen
+                            break;
                         }
+                        if (newRect.intersected(QRect(0,0,imageWidth,imageHeight))==newRect)
+                            m_rectCrop=newRect;
+                    }
+                } else {
+                    if (m_optWidget->boolWidth->isChecked()) {
+                        m_rectCrop.setWidth(m_optWidget->intWidth->value());
                     } else {
-                        if (m_optWidget->boolWidth->isChecked()) {
-                            m_rectCrop.setWidth(m_optWidget->intWidth->value());
-                        } else {
-                            switch (m_mouseOnHandleType) {
-                            case(LowerLeft):
-                            case(Left):
-                            case(UpperLeft):
-                                m_rectCrop.setLeft(pos.x());
-                                break;
-                            case(Right):
-                            case(UpperRight):
-                            case(LowerRight):
-                                m_rectCrop.setRight(pos.x());
-                                break;
-                            default:
-                                break;
-                            }
+                        switch (m_mouseOnHandleType) {
+                        case(LowerLeft):
+                        case(Left):
+                        case(UpperLeft):
+                            m_rectCrop.setLeft(pos.x());
+                        break;
+                        case(Right):
+                        case(UpperRight):
+                        case(LowerRight):
+                            m_rectCrop.setRight(pos.x());
+                        break;
+                        default:
+                            break;
                         }
-                        if (m_optWidget->boolHeight->isChecked()) {
-                            m_rectCrop.setHeight(m_optWidget->intHeight->value());
-                        } else {
-                            switch (m_mouseOnHandleType) {
-                            case(UpperLeft):
-                            case(Upper):
-                            case(UpperRight):
-                                m_rectCrop.setTop(pos.y());
-                                break;
-                            case(LowerRight):
-                            case(LowerLeft):
-                            case(Lower):
-                                m_rectCrop.setBottom(pos.y());
-                                break;
-                            default:
-                                break;
-                            }
+                    }
+                    if (m_optWidget->boolHeight->isChecked()) {
+                        m_rectCrop.setHeight(m_optWidget->intHeight->value());
+                    } else {
+                        switch (m_mouseOnHandleType) {
+                        case(UpperLeft):
+                        case(Upper):
+                        case(UpperRight):
+                            m_rectCrop.setTop(pos.y());
+                        break;
+                        case(LowerRight):
+                        case(LowerLeft):
+                        case(Lower):
+                            m_rectCrop.setBottom(pos.y());
+                        break;
+                        default:
+                            break;
                         }
                     }
+                }
 
-                    m_rectCrop.setLeft(qBound(0, m_rectCrop.left(), image()->width() - 1));
-                    m_rectCrop.setRight(qBound(0, m_rectCrop.right(), image()->width() - 1));
-                    m_rectCrop.setTop(qBound(0, m_rectCrop.top(), image()->height() - 1));
-                    m_rectCrop.setBottom(qBound(0, m_rectCrop.bottom(), image()->height() - 1));
+                m_rectCrop.setLeft(qBound(0, m_rectCrop.left(), image()->width() - 1));
+                m_rectCrop.setRight(qBound(0, m_rectCrop.right(), image()->width() - 1));
+                m_rectCrop.setTop(qBound(0, m_rectCrop.top(), image()->height() - 1));
+                m_rectCrop.setBottom(qBound(0, m_rectCrop.bottom(), image()->height() - 1));
 
-                    m_dragStart = dragStop;
+                m_dragStart = dragStop;
 
-                    updateRect |= boundingRect();
-                    updateCanvasViewRect(updateRect);
-                }
+                updateRect |= boundingRect();
+                updateCanvasViewRect(updateRect);
             }
-            updateWidgetValues();
-        } else { //if we are not selecting
-            if (m_haveCropSelection) {  //if the crop selection is set
-                QPointF pos = convertToPixelCoord(e);
-                qint32 type = mouseOnHandle(pixelToView(pos));
-                //set resize cursor if we are on one of the handles
-                setMoveResizeCursor(type);
-            }
         }
+        updateWidgetValues();
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
 void KisToolCrop::updateWidgetValues(bool updateratio)
@@ -317,11 +312,11 @@
         setOptionWidgetRatio((double)r.width() / (double)r.height());
 }
 
-void KisToolCrop::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolCrop::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (canvas() && currentImage() && m_selecting && e->button() == Qt::LeftButton) {
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-        m_selecting = false;
         m_haveCropSelection = true;
         m_rectCrop = m_rectCrop.normalized();
 
@@ -332,6 +327,9 @@
         updateRect |= boundingRect();
         updateCanvasViewRect(updateRect);
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolCrop::mouseDoubleClickEvent(KoPointerEvent *)
@@ -377,7 +375,7 @@
 
 void KisToolCrop::paintOutlineWithHandles(QPainter& gc)
 {
-    if (canvas() && (m_selecting || m_haveCropSelection)) {
+    if (canvas() && (mode() == KisTool::PAINT_MODE || m_haveCropSelection)) {
         gc.save();
 
 #if FADE_AREA_OUTSIDE_CROP
Index: plugins/tools/tool_crop/kis_tool_crop.h
===================================================================
--- plugins/tools/tool_crop/kis_tool_crop.h	(revision 1177751)
+++ plugins/tools/tool_crop/kis_tool_crop.h	(working copy)
@@ -116,7 +116,6 @@
 
 private:
     QRect m_rectCrop; // Is the coordinate of the region to crop.
-    bool m_selecting;
     QPoint m_dragStart;
 
     WdgToolCrop* m_optWidget;
Index: plugins/tools/tool_curves/kis_tool_curve.cc
===================================================================
--- plugins/tools/tool_curves/kis_tool_curve.cc	(revision 1177751)
+++ plugins/tools/tool_curves/kis_tool_curve.cc	(working copy)
@@ -65,7 +65,6 @@
 
     m_curve = 0;
 
-    m_dragging = false;
     m_draggingCursor = false;
     m_drawPivots = true;
     m_drawingPen = QPen(Qt::black, 0, Qt::SolidLine);
@@ -91,17 +90,18 @@
     }
 
     m_actionOptions = NOOPTIONS;
-    m_dragging = false;
     m_drawPivots = true;
 }
 
 void KisToolCurve::mousePressEvent(KoPointerEvent *event)
 {
     updateOptions(QApplication::keyboardModifiers());
-    if (!m_currentImage)
-        return;
-    if (event->button() == Qt::LeftButton) {
-        m_dragging = true;
+
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        setMode(KisTool::PAINT_MODE);
+
         m_currentPoint = event->pos().toPointF();
         PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos()).toPointF());
         if (temp.first == m_curve->end() && !(m_actionOptions)) {
@@ -118,23 +118,66 @@
             else
                 m_current = selectByMouse(temp.first);
 
-            if (!(*m_current).isSelected())
-                m_dragging = false;
+            if (!(*m_current).isSelected()) {
+                setMode(KisTool::PAINT_HOVER);
+            }
+
             draw(true, true);
         }
     }
+    else {
+        KisToolPaint::mousePressEvent(event);
+    }
 }
 
+void KisToolCurve::mouseMoveEvent(KoPointerEvent *event)
+{
+    updateOptions(QApplication::keyboardModifiers());
+    PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos()).toPointF());
+    if (temp.first == m_curve->end() && !mode() == KisTool::PAINT_MODE) {
+        if (m_draggingCursor) {
+            setCursor(KisCursor::load(m_cursor, 6, 6));
+            m_draggingCursor = false;
+        }
+    } else {
+        setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6));
+/////////////////
+        m_draggingCursor = true;
+    }
+
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+        QPointF trans = event->pos().toPointF() - m_currentPoint;
+        m_curve->moveSelected(trans);
+        m_currentPoint = event->pos().toPointF();
+        draw();
+    }
+    else {
+        KisToolPaint::mouseMoveEvent(event);
+    }
+}
+
+void KisToolCurve::mouseReleaseEvent(KoPointerEvent *event)
+{
+    updateOptions(QApplication::keyboardModifiers());
+
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
+    }
+    else {
+        KisToolPaint::mouseReleaseEvent(event);
+    }
+}
+
 void KisToolCurve::keyPressEvent(QKeyEvent *event)
 {
     if (event->key() == Qt::Key_Return) {
-        m_dragging = false;
+        setMode(KisTool::HOVER_MODE);
         commitCurve();
     } else if (event->key() == Qt::Key_Escape) {
-        m_dragging = false;
+        setMode(KisTool::HOVER_MODE);
         m_curve->clear();
     } else if (event->key() == Qt::Key_Delete) {
-        m_dragging = false;
+        setMode(KisTool::HOVER_MODE);
         m_curve->deleteSelected();
         m_current = m_curve->lastIterator();
         m_previous = m_curve->selectPivot(m_current);
@@ -147,38 +190,13 @@
 
 }
 
-void KisToolCurve::mouseReleaseEvent(KoPointerEvent *event)
-{
-    updateOptions(QApplication::keyboardModifiers());
-    m_dragging = false;
-}
-
 void KisToolCurve::mouseDoubleClick(KoPointerEvent *)
 {
     commitCurve();
 }
 
-void KisToolCurve::mouseMoveEvent(KoPointerEvent *event)
-{
-    updateOptions(QApplication::keyboardModifiers());
-    PointPair temp = pointUnderMouse(m_subject->canvasController()->windowToView(event->pos()).toPointF());
-    if (temp.first == m_curve->end() && !m_dragging) {
-        if (m_draggingCursor) {
-            setCursor(KisCursor::load(m_cursor, 6, 6));
-            m_draggingCursor = false;
-        }
-    } else {
-        setCursor(KisCursor::load("tool_curve_dragging.png", 6, 6));
-        m_draggingCursor = true;
-    }
-    if (m_dragging) {
-        QPointF trans = event->pos().toPointF() - m_currentPoint;
-        m_curve->moveSelected(trans);
-        m_currentPoint = event->pos().toPointF();
-        draw();
-    }
-}
 
+
 double pointToSegmentDistance(const QPointF& pp, const QPointF& pl0, const QPointF& pl1)
 {
     QPointF l0 = pl0, l1 = pl1, p = pp;
Index: plugins/tools/tool_curves/kis_tool_curve.h
===================================================================
--- plugins/tools/tool_curves/kis_tool_curve.h	(revision 1177751)
+++ plugins/tools/tool_curves/kis_tool_curve.h	(working copy)
@@ -151,7 +151,6 @@
     KisCurve::iterator m_previous;
     QPointF m_currentPoint;
 
-    bool m_dragging;
     bool m_drawPivots;
     QPen m_drawingPen;
     QPen m_pivotPen;
Index: plugins/tools/defaulttools/kis_tool_gradient.cc
===================================================================
--- plugins/tools/defaulttools/kis_tool_gradient.cc	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_gradient.cc	(working copy)
@@ -71,8 +71,7 @@
 #endif
 
 KisToolGradient::KisToolGradient(KoCanvasBase * canvas)
-        : KisToolPaint(canvas, KisCursor::load("tool_gradient_cursor.png", 6, 6)),
-        m_dragging(false)
+        : KisToolPaint(canvas, KisCursor::load("tool_gradient_cursor.png", 6, 6))
 {
     setObjectName("tool_gradient");
 
@@ -96,7 +95,7 @@
 
 void KisToolGradient::paint(QPainter &painter, const KoViewConverter &converter)
 {
-    if (m_dragging && m_startPos != m_endPos) {
+    if (mode() == KisTool::PAINT_MODE && m_startPos != m_endPos) {
 
 #if defined(HAVE_OPENGL) && defined(HAVE_GLEW)
         if (m_gradientProgram) {
@@ -172,18 +171,15 @@
     }
 }
 
-void KisToolGradient::mousePressEvent(KoPointerEvent *e)
+void KisToolGradient::mousePressEvent(KoPointerEvent *event)
 {
-    if (!currentImage()) {
-        return;
-    }
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-    QPointF pos = convertToPixelCoord(e);
+        setMode(KisTool::PAINT_MODE);
 
-    if (e->button() == Qt::LeftButton) {
-        m_dragging = true;
-        m_startPos = pos;
-        m_endPos = pos;
+        m_startPos = convertToPixelCoord(event);
+        m_endPos = m_startPos;
 
 #if defined(HAVE_OPENGL) && defined(HAVE_GLEW)
         KisConfig cfg;
@@ -194,11 +190,8 @@
             KoColorProfile *monitorProfile = 0;
 
             Q_ASSERT(canvas);
+            monitorProfile = canvas->monitorProfile();
 
-            if (canvas) {
-                monitorProfile = canvas->monitorProfile();
-            }
-
             KisOpenGL::makeContextCurrent();
             m_gradientProgram = new KisOpenGLGradientProgram(currentGradient(),
                     m_shape,
@@ -210,19 +203,20 @@
         }
 #endif
     }
+    else {
+        KisToolPaint::mousePressEvent(event);
+    }
 }
 
-void KisToolGradient::mouseMoveEvent(KoPointerEvent *e)
+void KisToolGradient::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
-        QPointF pos = convertToPixelCoord(e);
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+        QPointF pos = convertToPixelCoord(event);
 
-        QRectF bound;
-        bound.setTopLeft(m_startPos);
-        bound.setBottomRight(m_endPos);
+        QRectF bound(m_startPos, m_endPos);
         canvas()->updateCanvas(convertToPt(bound.normalized()));
 
-        if ((e->modifiers() & Qt::ShiftModifier) == Qt::ShiftModifier) {
+        if (event->modifiers() == Qt::ShiftModifier) {
             m_endPos = straightLine(pos);
         } else {
             m_endPos = pos;
@@ -232,37 +226,38 @@
         bound.setBottomRight(m_endPos);
         canvas()->updateCanvas(convertToPt(bound.normalized()));
     }
+    else {
+        KisToolPaint::mouseMoveEvent(event);
+    }
 }
 
-void KisToolGradient::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolGradient::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (!currentNode() || currentNode()->systemLocked())
-       return;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (m_dragging && e->button() == Qt::LeftButton) {
+        if (!currentNode() || currentNode()->systemLocked())
+            return;
 
-        setCurrentNodeLocked(true);
-
 #if defined(HAVE_OPENGL) && defined(HAVE_GLEW)
         delete m_gradientProgram;
         m_gradientProgram = 0;
 #endif
 
-        m_dragging = false;
+        QPointF pos = convertToPixelCoord(event);
 
-        if (m_startPos == m_endPos) {
-            m_dragging = false;
-            return;
-        }
-
-        QPointF pos = convertToPixelCoord(e);
-
-        if ((e->modifiers() & Qt::ShiftModifier) == Qt::ShiftModifier) {
+        if (event->modifiers() == Qt::ShiftModifier) {
             m_endPos = straightLine(pos);
         } else {
             m_endPos = pos;
         }
 
+        if (m_startPos == m_endPos) {
+            return;
+        }
+
+        setCurrentNodeLocked(true);
+
         KisPaintDeviceSP device;
 
         if (currentImage() && (device = currentNode()->paintDevice())) {
@@ -300,6 +295,9 @@
         canvas()->updateCanvas(convertToPt(currentImage()->bounds()));
         setCurrentNodeLocked(false);
     }
+    else {
+        KisToolPaint::mouseReleaseEvent(event);
+    }
 }
 
 QPointF KisToolGradient::straightLine(QPointF point)
Index: plugins/tools/defaulttools/kis_tool_measure.h
===================================================================
--- plugins/tools/defaulttools/kis_tool_measure.h	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_measure.h	(working copy)
@@ -93,7 +93,6 @@
     }
 
 private:
-    bool m_dragging;
     KisToolMeasureOptionsWidget *m_optWidget;
 
     QPointF m_startPos;
Index: plugins/tools/defaulttools/kis_tool_move.cc
===================================================================
--- plugins/tools/defaulttools/kis_tool_move.cc	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_move.cc	(working copy)
@@ -56,7 +56,6 @@
         :  KisTool(canvas, KisCursor::moveCursor())
 {
     setObjectName("tool_move");
-    m_dragging = false;
     m_optionsWidget = 0;
 }
 
@@ -112,16 +111,22 @@
     return 0;
 }
 
-void KisToolMove::mousePressEvent(KoPointerEvent *e)
+void KisToolMove::mousePressEvent(KoPointerEvent *event)
 {
-    if (canvas() && e->button() == Qt::LeftButton) {
-        QPointF pos = convertToPixelCoord(e);
+    if(PRESS_CONDITION_OM(event, KisTool::HOVER_MODE,
+                          Qt::LeftButton,
+                          Qt::ControlModifier | Qt::ShiftModifier)) {
 
+        setMode(KisTool::PAINT_MODE);
+
         KisNodeSP node;
         KisImageWSP image = currentImage();
         if (!image || !image->rootLayer() || image->rootLayer()->childCount() == 0) {
             return;
         }
+
+        QPointF pos = convertToPixelCoord(event);
+
         // shortcut: if the pixel at projection is transparent, it's all transparent
         const KoColorSpace* cs = image->projection()->colorSpace();
         KoColor color(cs);
@@ -129,9 +134,10 @@
 
         KisSelectionSP selection = currentSelection();
 
-        if (cs->opacityU8(color.data()) == OPACITY_TRANSPARENT_U8
-                || m_optionsWidget->radioSelectedLayer->isChecked()
-                || e->modifiers() == Qt::ControlModifier) {
+        if (cs->opacityU8(color.data()) == OPACITY_TRANSPARENT_U8 ||
+            m_optionsWidget->radioSelectedLayer->isChecked() ||
+            event->modifiers() == Qt::ControlModifier) {
+
             node = currentNode();
         } else {
 
@@ -140,7 +146,7 @@
             node = findNode(node, pos.x(), pos.y());
 
             // if there is a selection, we cannot move the group
-            if (node && !selection && (m_optionsWidget->radioGroup->isChecked() || e->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))) {
+            if (node && !selection && (m_optionsWidget->radioGroup->isChecked() || event->modifiers() == (Qt::ControlModifier | Qt::ShiftModifier))) {
                 node = node->parent();
             }
         }
@@ -153,7 +159,6 @@
         currentImage()->undoAdapter()->beginMacro(i18n("Move"));
 
         if (selection && !selection->isTotallyUnselected(image->bounds()) && !selection->isDeselected()) {
-            //selection->convertToQImage(0).save("selection.png");
             // Create a temporary layer with the contents of the selection of the current layer.
             Q_ASSERT(!node->inherits("KisGroupLayer"));
 
@@ -207,20 +212,21 @@
             m_targetLayer = 0;
         }
 
-        m_dragging = true;
-        m_dragStart = QPoint(static_cast<int>(pos.x()), static_cast<int>(pos.y()));
         m_layerStart.setX(node->x());
         m_layerStart.setY(node->y());
         m_layerPosition = m_layerStart;
+        m_dragStart = pos.toPoint();
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
-void KisToolMove::mouseMoveEvent(KoPointerEvent *e)
+void KisToolMove::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (canvas() && m_dragging) {
-        QPointF posf = convertToPixelCoord(e);
-        QPoint pos = QPoint(static_cast<int>(posf.x()), static_cast<int>(posf.y()));
-        if ((e->modifiers() & Qt::AltModifier) || (e->modifiers() & Qt::ControlModifier)) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+        QPoint pos = convertToPixelCoord(event).toPoint();
+        if ((event->modifiers() & Qt::AltModifier) || (event->modifiers() & Qt::ControlModifier)) {
             if (fabs(static_cast<double>(pos.x() - m_dragStart.x())) > fabs(static_cast<double>(pos.y() - m_dragStart.y())))
                 pos.setY(m_dragStart.y());
             else
@@ -230,26 +236,31 @@
 
         notifyModified();
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
-void KisToolMove::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolMove::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
-        if (canvas() && e->button() == Qt::LeftButton) {
-            QPointF pos = convertToPixelCoord(e);
-            if (m_selectedNode) {
-                drag(QPoint(static_cast<int>(pos.x()), static_cast<int>(pos.y())));
-                m_dragging = false;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-                QUndoCommand *cmd = new KisNodeMoveCommand(m_selectedNode, m_layerStart, m_layerPosition);
-                Q_CHECK_PTR(cmd);
+        if (m_selectedNode) {
+            QPoint pos = convertToPixelCoord(event).toPoint();
+            drag(pos);
 
-                canvas()->addCommand(cmd);
-                currentImage()->undoAdapter()->endMacro();
-            }
-            currentImage()->setModified();
+            QUndoCommand *cmd = new KisNodeMoveCommand(m_selectedNode, m_layerStart, m_layerPosition);
+            Q_CHECK_PTR(cmd);
+
+            canvas()->addCommand(cmd);
+            currentImage()->undoAdapter()->endMacro();
         }
+        currentImage()->setModified();
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolMove::drag(const QPoint& original)
Index: plugins/tools/defaulttools/kis_tool_move.h
===================================================================
--- plugins/tools/defaulttools/kis_tool_move.h	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_move.h	(working copy)
@@ -77,7 +77,6 @@
     QPoint m_dragStart;
     QPoint m_layerStart;
     QPoint m_layerPosition;
-    bool m_dragging;
     KisNodeSP m_selectedNode;
     KisNodeSP m_targetLayer;
     KisSelectionSP m_selection;
Index: plugins/tools/defaulttools/kis_tool_fill.cc
===================================================================
--- plugins/tools/defaulttools/kis_tool_fill.cc	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_fill.cc	(working copy)
@@ -172,35 +172,39 @@
     return true;
 }
 
-void KisToolFill::mousePressEvent(KoPointerEvent *e)
+void KisToolFill::mousePressEvent(KoPointerEvent *event)
 {
-    QPointF pos = convertToPixelCoord(e);
-    m_startPos = pos;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        setMode(KisTool::PAINT_MODE);
+
+        m_startPos = convertToPixelCoord(event).toPoint();
+    }
+    else {
+        KisToolPaint::mousePressEvent(event);
+    }
 }
 
-void KisToolFill::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolFill::mouseReleaseEvent(KoPointerEvent *event)
 {
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (!canvas()) return;
-    if (!currentNode() || currentNode()->systemLocked()) return;
-    if (!currentImage() || !currentNode()->paintDevice()) return;
-    if (e->button() == Qt::LeftButton) {
-        setCurrentNodeLocked(true);
-        int x, y;
+        if (!currentNode() || currentNode()->systemLocked() ||
+            !currentImage()->bounds().contains(m_startPos)) {
 
-        x = static_cast<int>(m_startPos.x());
-        y = static_cast<int>(m_startPos.y());
-
-        if (!currentImage()->bounds().contains(x, y)) {
             return;
         }
 
-        flood(x, y);
+        setCurrentNodeLocked(true);
+        flood(m_startPos.x(), m_startPos.y());
         setCurrentNodeLocked(false);
         notifyModified();
-    } else {
-        KisToolPaint::mouseReleaseEvent(e);
     }
+    else {
+        KisToolPaint::mouseReleaseEvent(event);
+    }
 }
 
 QWidget* KisToolFill::createOptionWidget()
Index: plugins/tools/defaulttools/kis_tool_fill.h
===================================================================
--- plugins/tools/defaulttools/kis_tool_fill.h	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_fill.h	(working copy)
@@ -63,7 +63,7 @@
     virtual void slotSetFillSelection(bool);
 
 private:
-    QPointF m_startPos;
+    QPoint m_startPos;
     int m_threshold;
     qint32 m_depth;
     quint8* m_oldColor, *m_color;
Index: plugins/tools/defaulttools/kis_tool_line.h
===================================================================
--- plugins/tools/defaulttools/kis_tool_line.h	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_line.h	(working copy)
@@ -62,8 +62,6 @@
 
 private:
 
-    bool m_dragging;
-
     QPointF m_startPos;
     QPointF m_endPos;
 
Index: plugins/tools/defaulttools/kis_tool_gradient.h
===================================================================
--- plugins/tools/defaulttools/kis_tool_gradient.h	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_gradient.h	(working copy)
@@ -89,8 +89,6 @@
 
     QPointF straightLine(QPointF point);
 
-    bool m_dragging;
-
     QPointF m_startPos;
     QPointF m_endPos;
 
Index: plugins/tools/defaulttools/kis_tool_measure.cc
===================================================================
--- plugins/tools/defaulttools/kis_tool_measure.cc	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_measure.cc	(working copy)
@@ -30,8 +30,8 @@
 #include <kis_debug.h>
 #include <klocale.h>
 
-
 #include "kis_image.h"
+#include "kis_cursor.h"
 #include "KoPointerEvent.h"
 #include "KoCanvasBase.h"
 
@@ -93,8 +93,7 @@
 
 
 KisToolMeasure::KisToolMeasure(KoCanvasBase * canvas)
-        : KisTool(canvas, QCursor(Qt::CrossCursor)),
-        m_dragging(false)
+    : KisTool(canvas, KisCursor::crossCursor())
 {
     m_startPos = QPointF(0, 0);
     m_endPos = QPointF(0, 0);
@@ -109,8 +108,6 @@
     qreal sx, sy;
     converter.zoom(&sx, &sy);
 
-    if (!currentImage()) return;
-
     gc.scale(sx / currentImage()->xRes(), sy / currentImage()->yRes());
 
     QPen old = gc.pen();
@@ -139,50 +136,60 @@
     gc.setPen(old);
 }
 
-void KisToolMeasure::mousePressEvent(KoPointerEvent *e)
+void KisToolMeasure::mousePressEvent(KoPointerEvent *event)
 {
-    if (!currentImage()) return;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-    // Erase old temporary lines
-    canvas()->updateCanvas(convertToPt(boundingRect()));
+        setMode(KisTool::PAINT_MODE);
 
-    QPointF pos = convertToPixelCoord(e);
+        // Erase old temporary lines
+        canvas()->updateCanvas(convertToPt(boundingRect()));
 
-    if (e->button() == Qt::LeftButton) {
-        m_dragging = true;
-        m_startPos = pos;
-        m_endPos = pos;
+        m_startPos = convertToPixelCoord(event);
+        m_endPos = m_startPos;
+
+        emit sigDistanceChanged(0.0);
+        emit sigAngleChanged(0.0);
     }
-    emit sigDistanceChanged(0.0);
-    emit sigAngleChanged(0.0);
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
-void KisToolMeasure::mouseMoveEvent(KoPointerEvent *e)
+void KisToolMeasure::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         // Erase old temporary lines
         canvas()->updateCanvas(convertToPt(boundingRect()));
 
-        QPointF pos = convertToPixelCoord(e);
+        QPointF pos = convertToPixelCoord(event);
 
-        if (e->modifiers() & Qt::AltModifier) {
+        if (event->modifiers() == Qt::AltModifier) {
             QPointF trans = pos - m_endPos;
             m_startPos += trans;
             m_endPos += trans;
-        } else
+        } else {
             m_endPos = pos;
+        }
 
         canvas()->updateCanvas(convertToPt(boundingRect()));
         emit sigDistanceChanged(distance());
         emit sigAngleChanged(angle());
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
-void KisToolMeasure::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolMeasure::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (m_dragging && e->button() == Qt::LeftButton) {
-        m_dragging = false;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 QWidget* KisToolMeasure::createOptionWidget()
Index: plugins/tools/defaulttools/kis_tool_colorpicker.cc
===================================================================
--- plugins/tools/defaulttools/kis_tool_colorpicker.cc	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_colorpicker.cc	(working copy)
@@ -64,7 +64,6 @@
     m_updateColor = true;
     m_normaliseValues = false;
     m_pickedColor = KoColor();
-    m_colorPicking = false;
     m_toForegroundColor = true;
 }
 
@@ -153,14 +152,10 @@
 
 void KisToolColorPicker::mousePressEvent(KoPointerEvent *event)
 {
-    if (canvas()) {
-        if (event->button() != Qt::LeftButton && event->button() != Qt::RightButton){
-            return;
-        }
+    if(PRESS_CONDITION_WB(event, KisTool::HOVER_MODE,
+                          Qt::LeftButton | Qt::RightButton, Qt::NoModifier)) {
 
-        if (!currentImage()){
-            return;
-        }
+        setMode(KisTool::PAINT_MODE);
 
         bool sampleMerged = m_optionsWidget->cmbSources->currentIndex() == SAMPLE_MERGED;
         if (!sampleMerged) {
@@ -180,40 +175,48 @@
             return;
         }
 
-        m_colorPicking = true;
         m_toForegroundColor = (event->button() == Qt::LeftButton);
-
         pickColor(pos);
         displayPickedColor();
-
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 void KisToolColorPicker::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_colorPicking){
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         QPoint pos = convertToIntPixelCoord(event);
         pickColor(pos);
         displayPickedColor();
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
-void KisToolColorPicker::mouseReleaseEvent(KoPointerEvent */*event*/)
+void KisToolColorPicker::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (m_addPalette) {
-        KoColorSetEntry ent;
-        ent.color = m_pickedColor;
-        // We don't ask for a name, too intrusive here
+    if(RELEASE_CONDITION_WB(event, KisTool::PAINT_MODE, Qt::LeftButton | Qt::RightButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-        KoColorSet* palette = m_palettes.at(m_optionsWidget->cmbPalette->currentIndex());
-        palette->add(ent);
+        if (m_addPalette) {
+            KoColorSetEntry ent;
+            ent.color = m_pickedColor;
+            // We don't ask for a name, too intrusive here
 
-        if (!palette->save()) {
-            KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.", palette->filename()), i18n("Palette"));
+            KoColorSet* palette = m_palettes.at(m_optionsWidget->cmbPalette->currentIndex());
+            palette->add(ent);
+
+            if (!palette->save()) {
+                KMessageBox::error(0, i18n("Cannot write to palette file %1. Maybe it is read-only.", palette->filename()), i18n("Palette"));
+            }
         }
     }
-
-    m_colorPicking = false;
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolColorPicker::displayPickedColor()
Index: plugins/tools/defaulttools/kis_tool_colorpicker.h
===================================================================
--- plugins/tools/defaulttools/kis_tool_colorpicker.h	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_colorpicker.h	(working copy)
@@ -72,7 +72,6 @@
     void pickColor(const QPointF& pos);
 
     bool m_toForegroundColor;
-    bool m_colorPicking;
     bool m_updateColor;
     bool m_addPalette;
     bool m_normaliseValues;
Index: plugins/tools/defaulttools/kis_tool_line.cc
===================================================================
--- plugins/tools/defaulttools/kis_tool_line.cc	(revision 1177751)
+++ plugins/tools/defaulttools/kis_tool_line.cc	(working copy)
@@ -60,8 +60,7 @@
 
 
 KisToolLine::KisToolLine(KoCanvasBase * canvas)
-        : KisToolPaint(canvas, KisCursor::load("tool_line_cursor.png", 6, 6)),
-        m_dragging(false)
+        : KisToolPaint(canvas, KisCursor::load("tool_line_cursor.png", 6, 6))
 {
     setObjectName("tool_line");
 
@@ -80,127 +79,126 @@
 {
     qreal sx, sy;
     converter.zoom(&sx, &sy);
-    if (m_dragging) {
+    if (mode() == KisTool::PAINT_MODE) {
         paintLine(gc, QRect());
     }
 }
 
 
-void KisToolLine::mousePressEvent(KoPointerEvent *e)
+void KisToolLine::mousePressEvent(KoPointerEvent *event)
 {
-    if (!canvas() || !currentImage()) return;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-    QPointF pos = convertToPixelCoord(e);
+        setMode(KisTool::PAINT_MODE);
 
-    if (e->button() == Qt::LeftButton) {
-        m_dragging = true;
-        m_startPos = pos;
-        m_endPos = pos;
+        m_startPos = convertToPixelCoord(event);
+        m_endPos = m_startPos;
     }
-
-    if (m_dragging == true && (e->button() == Qt::MidButton || e->button() == Qt::RightButton)) {
-        // end painting, if calling the menu or the pop up palette. otherwise there is weird behaviour
-        m_dragging = false;
-        updatePreview();
+    else {
+        KisToolPaint::mousePressEvent(event);
     }
 }
 
 
-void KisToolLine::mouseMoveEvent(KoPointerEvent *e)
+void KisToolLine::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         // First ensure the old temp line is deleted
         updatePreview();
 
-        QPointF pos = convertToPixelCoord(e);
+        QPointF pos = convertToPixelCoord(event);
 
-        if (e->modifiers() & Qt::AltModifier) {
+        if (event->modifiers() == Qt::AltModifier) {
             QPointF trans = pos - m_endPos;
             m_startPos += trans;
             m_endPos += trans;
-        } else if (e->modifiers() & Qt::ShiftModifier) {
+        } else if (event->modifiers() == Qt::ShiftModifier) {
             m_endPos = straightLine(pos);
         } else {
             m_endPos = pos;
         }
         updatePreview();
     }
+    else {
+        KisToolPaint::mouseMoveEvent(event);
+    }
 }
 
-void KisToolLine::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolLine::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (m_dragging && e->button() == Qt::LeftButton) {
-        m_dragging = false;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
+
         updatePreview();
 
-        if (canvas()) {
+        QPointF pos = convertToPixelCoord(event);
 
-            if (m_startPos == m_endPos) {
-                m_dragging = false;
-                return;
-            }
+        if (event->modifiers() == Qt::AltModifier) {
+            QPointF trans = pos - m_endPos;
+            m_startPos += trans;
+            m_endPos += trans;
+        } else if (event->modifiers() == Qt::ShiftModifier) {
+            m_endPos = straightLine(pos);
+        } else {
+            m_endPos = pos;
+        }
 
-            QPointF pos = convertToPixelCoord(e);
+        if (m_startPos == m_endPos) {
+            return;
+        }
 
-            if ((e->modifiers() & Qt::ShiftModifier) == Qt::ShiftModifier) {
-                m_endPos = straightLine(pos);
-            } else {
-                m_endPos = pos;
-            }
-
 #ifdef ENABLE_RECORDING
-            if (image()) {
-                KisRecordedPathPaintAction linePaintAction(KisNodeQueryPath::absolutePath(currentNode()), currentPaintOpPreset());
-                setupPaintAction(&linePaintAction);
-                linePaintAction.addLine(m_startPos, m_endPos);
-                image()->actionRecorder()->addAction(linePaintAction);
-            }
+        if (image()) {
+            KisRecordedPathPaintAction linePaintAction(KisNodeQueryPath::absolutePath(currentNode()), currentPaintOpPreset());
+            setupPaintAction(&linePaintAction);
+            linePaintAction.addLine(m_startPos, m_endPos);
+            image()->actionRecorder()->addAction(linePaintAction);
+        }
 #endif
 
-            if (!currentNode()->inherits("KisShapeLayer")) {
-                KisPaintDeviceSP device;
+        if (!currentNode()->inherits("KisShapeLayer")) {
+            KisPaintDeviceSP device;
 
-                if (currentNode() && (device = currentNode()->paintDevice())) {
-                    delete m_painter;
-                    m_painter = new KisPainter(device, currentSelection());
-                    Q_CHECK_PTR(m_painter);
+            if (currentNode() && (device = currentNode()->paintDevice())) {
+                delete m_painter;
+                m_painter = new KisPainter(device, currentSelection());
+                Q_CHECK_PTR(m_painter);
 
-                    m_painter->beginTransaction(i18nc("a straight drawn line", "Line"));
-                    
-                    setupPainter(m_painter);
-                    
-                    m_painter->paintLine(m_startPos, m_endPos);
+                m_painter->beginTransaction(i18nc("a straight drawn line", "Line"));
+                setupPainter(m_painter);
+                m_painter->paintLine(m_startPos, m_endPos);
 
-                    QRegion dirtyRegion = m_painter->dirtyRegion();
-                    device->setDirty(dirtyRegion);
-                    notifyModified();
+                QRegion dirtyRegion = m_painter->dirtyRegion();
+                m_painter->endTransaction(image()->undoAdapter());
 
+                device->setDirty(dirtyRegion);
+                notifyModified();
 
-                    m_painter->endTransaction(image()->undoAdapter());
-                    delete m_painter;
-                    m_painter = 0;
-                }
+                delete m_painter;
+                m_painter = 0;
             }
-            else {
-                KoPathShape* path = new KoPathShape();
-                path->setShapeId(KoPathShapeId);
+        }
+        else {
+            KoPathShape* path = new KoPathShape();
+            path->setShapeId(KoPathShapeId);
 
-                QTransform resolutionMatrix;
-                resolutionMatrix.scale(1 / currentImage()->xRes(), 1 / currentImage()->yRes());
-                path->moveTo(resolutionMatrix.map(m_startPos));
-                path->lineTo(resolutionMatrix.map(m_endPos));
-                path->normalize();
+            QTransform resolutionMatrix;
+            resolutionMatrix.scale(1 / currentImage()->xRes(), 1 / currentImage()->yRes());
+            path->moveTo(resolutionMatrix.map(m_startPos));
+            path->lineTo(resolutionMatrix.map(m_endPos));
+            path->normalize();
 
-                KoLineBorder* border = new KoLineBorder(1.0, currentFgColor().toQColor());
-                path->setBorder(border);
+            KoLineBorder* border = new KoLineBorder(1.0, currentFgColor().toQColor());
+            path->setBorder(border);
 
-                QUndoCommand * cmd = canvas()->shapeController()->addShape(path);
-                canvas()->addCommand(cmd);
-            }
+            QUndoCommand * cmd = canvas()->shapeController()->addShape(path);
+            canvas()->addCommand(cmd);
         }
-    } else {
-        KisToolPaint::mouseReleaseEvent(e);
     }
+    else {
+        KisToolPaint::mouseReleaseEvent(event);
+    }
 }
 
 
Index: plugins/tools/selectiontools/kis_tool_select_contiguous.cc
===================================================================
--- plugins/tools/selectiontools/kis_tool_select_contiguous.cc	(revision 1177751)
+++ plugins/tools/selectiontools/kis_tool_select_contiguous.cc	(working copy)
@@ -61,12 +61,11 @@
 {
 }
 
-void KisToolSelectContiguous::mousePressEvent(KoPointerEvent * e)
+void KisToolSelectContiguous::mousePressEvent(KoPointerEvent *event)
 {
-    if (e->button() != Qt::LeftButton)
-        return;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-    if (canvas() && currentImage()) {
         QApplication::setOverrideCursor(KisCursor::waitCursor());
 
         if (!currentNode())
@@ -76,7 +75,7 @@
         if (!dev || !currentNode()->visible())
             return;
 
-        QPoint pos = convertToIntPixelCoord(e);
+        QPoint pos = convertToIntPixelCoord(event);
         QRect rc = currentImage()->bounds();
         KisFillPainter fillpainter(dev);
         fillpainter.setHeight(rc.height());
@@ -95,6 +94,9 @@
 
         QApplication::restoreOverrideCursor();
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 void KisToolSelectContiguous::paint(QPainter &painter, const KoViewConverter &converter)
Index: plugins/tools/selectiontools/kis_tool_select_outline.cc
===================================================================
--- plugins/tools/selectiontools/kis_tool_select_outline.cc	(revision 1177751)
+++ plugins/tools/selectiontools/kis_tool_select_outline.cc	(working copy)
@@ -55,7 +55,6 @@
 KisToolSelectOutline::KisToolSelectOutline(KoCanvasBase * canvas)
         : KisToolSelectBase(canvas, KisCursor::load("tool_outline_selection_cursor.png", 5, 5)), m_paintPath(new QPainterPath())
 {
-    m_dragging = false;
 }
 
 KisToolSelectOutline::~KisToolSelectOutline()
@@ -66,22 +65,27 @@
 
 void KisToolSelectOutline::mousePressEvent(KoPointerEvent *event)
 {
-    if (event->button() == Qt::LeftButton) {
-        m_dragging = true;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        setMode(KisTool::PAINT_MODE);
+
         m_points.clear();
         m_points.append(convertToPixelCoord(event));
-
         m_paintPath->moveTo(pixelToView(convertToPixelCoord(event)));
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 void KisToolSelectOutline::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         QPointF point = convertToPixelCoord(event);
         //don't add the point, if the distance is very small
-        if (m_points.size()>0) {
-            QPointF diff = point-m_points.at(m_points.size()-1);
+        if (!m_points.isEmpty()) {
+            QPointF diff = point - m_points.last();
             if(fabs(diff.x())<3 && fabs(diff.y())<3)
                 return;
         }
@@ -89,18 +93,18 @@
         m_points.append(point);
         updateFeedback();
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
 void KisToolSelectOutline::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (!canvas())
-        return;
-
-    if (m_dragging && event->button() == Qt::LeftButton) {
-        m_dragging = false;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
         deactivate();
 
-        if (currentImage() && m_points.count() > 2) {
+        if (m_points.count() > 2) {
             QApplication::setOverrideCursor(KisCursor::waitCursor());
 
             KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
@@ -150,6 +154,9 @@
         delete m_paintPath;
         m_paintPath = new QPainterPath();
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 
@@ -157,7 +164,7 @@
 {
     Q_UNUSED(converter);
 
-    if (m_dragging && m_points.count() > 1) {
+    if (mode() == KisTool::PAINT_MODE && !m_points.isEmpty()) {
             paintToolOutline(&gc, *m_paintPath);
     }
 }
Index: plugins/tools/selectiontools/kis_tool_select_outline.h
===================================================================
--- plugins/tools/selectiontools/kis_tool_select_outline.h	(revision 1177751)
+++ plugins/tools/selectiontools/kis_tool_select_outline.h	(working copy)
@@ -51,7 +51,6 @@
 private:
     void updateFeedback();
 
-    bool m_dragging;
     QPainterPath * m_paintPath;
     vQPointF m_points;
 
Index: plugins/tools/selectiontools/kis_tool_select_similar.cc
===================================================================
--- plugins/tools/selectiontools/kis_tool_select_similar.cc	(revision 1177751)
+++ plugins/tools/selectiontools/kis_tool_select_similar.cc	(working copy)
@@ -91,27 +91,20 @@
 }
 
 
-void KisToolSelectSimilar::mousePressEvent(KoPointerEvent *e)
+void KisToolSelectSimilar::mousePressEvent(KoPointerEvent *event)
 {
-    if (canvas()) {
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
         QApplication::setOverrideCursor(KisCursor::waitCursor());
         quint8 opacity = OPACITY_OPAQUE_U8;
 
-        if (e->button() != Qt::LeftButton)
-            return;
-
-        if (!currentImage())
-            return;
-
-        if (!currentNode())
-            return;
-
         KisPaintDeviceSP dev = currentNode()->paintDevice();
 
         if (!dev || !currentNode()->visible())
             return;
 
-        QPointF pos = convertToPixelCoord(e);
+        QPointF pos = convertToPixelCoord(event);
 
         KisCanvas2 * kisCanvas = dynamic_cast<KisCanvas2*>(canvas());
         if (!kisCanvas)
@@ -131,6 +124,9 @@
 
         QApplication::restoreOverrideCursor();
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
 
Index: plugins/tools/selectiontools/kis_tool_select_brush.cc
===================================================================
--- plugins/tools/selectiontools/kis_tool_select_brush.cc	(revision 1177751)
+++ plugins/tools/selectiontools/kis_tool_select_brush.cc	(working copy)
@@ -49,7 +49,6 @@
 KisToolSelectBrush::KisToolSelectBrush(KoCanvasBase * canvas)
         : KisToolSelectBase(canvas, KisCursor::load("tool_brush_selection_cursor.png", 6, 6)),
         m_brushRadius(15),
-        m_dragging(false),
         m_lastMousePosition(-1, -1)
 {
     resetSelection();
@@ -86,7 +85,7 @@
 void KisToolSelectBrush::paint(QPainter& gc, const KoViewConverter &converter)
 {
     Q_UNUSED(converter);
-    if(m_dragging) {
+    if(mode() == KisTool::PAINT_MODE) {
         paintToolOutline(&gc, pixelToView(m_selection));
     }
     else  if(m_lastMousePosition!=QPoint(-1, -1)) {
@@ -96,27 +95,51 @@
     }
 }
 
-void KisToolSelectBrush::mousePressEvent(KoPointerEvent *e)
+void KisToolSelectBrush::mousePressEvent(KoPointerEvent *event)
 {
-    if (e->button() == Qt::LeftButton) {
-        m_dragging = true;
-        m_lastPoint=convertToPixelCoord(e->point);
-        addPoint(convertToPixelCoord(e->point));
-        e->accept();
+    if(mode() == KisTool::PAINT_MODE) {
+        /**
+         * Cancalling must be done at KisTool level
+         */
+//        resetSelection();
+//        return;
     }
-    else if (e->button()==Qt::RightButton || e->button()==Qt::MidButton) {
-        m_dragging = false;
-        resetSelection();
-        e->accept();
+
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        setMode(KisTool::PAINT_MODE);
+
+        m_lastPoint = convertToPixelCoord(event->point);
+        addPoint(m_lastPoint);
     }
+    else {
+        KisTool::mousePressEvent(event);
+    }
 }
 
-void KisToolSelectBrush::mouseMoveEvent(KoPointerEvent *e)
+void KisToolSelectBrush::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    /**
+     * Update outline
+     */
+    QRect brushRect(-m_brushRadius, -m_brushRadius, 2*m_brushRadius, 2*m_brushRadius);
+    brushRect.adjust(-2, -2, 2, 2);     //width of tool outline
 
+    brushRect.moveCenter(m_lastMousePosition);
+    updateCanvasPixelRect(brushRect);
+
+    m_lastMousePosition = convertToPixelCoord(event).toPoint();
+
+    brushRect.moveCenter(m_lastMousePosition);
+    updateCanvasPixelRect(brushRect);
+
+    /**
+     * Do selection
+     */
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         // this gives better performance
-        if(Vector2f((m_lastPoint-convertToPixelCoord(e->point)).x(), (m_lastPoint-convertToPixelCoord(e->point)).y()).norm()<m_brushRadius/6)
+        if(Vector2f((m_lastPoint-convertToPixelCoord(event->point)).x(), (m_lastPoint-convertToPixelCoord(event->point)).y()).norm()<m_brushRadius/6)
             return;
 
         //randomise the point to workaround a bug in QPainterPath::operator|=()
@@ -127,29 +150,22 @@
         qreal randomY=rand()%100;
         randomY/=1000.;
         QPointF smallRandomPoint(randomX, randomY);
-        addPoint(convertToPixelCoord(e->point)+smallRandomPoint);
+        addPoint(convertToPixelCoord(event->point)+smallRandomPoint);
     }
     else {
-        QRect brushRect(-m_brushRadius, -m_brushRadius, 2*m_brushRadius, 2*m_brushRadius);
-        brushRect.adjust(-2, -2, 2, 2);     //width of tool outline
-
-        brushRect.moveCenter(m_lastMousePosition);
-        updateCanvasPixelRect(brushRect);
-
-        m_lastMousePosition = convertToPixelCoord(e).toPoint();
-
-        brushRect.moveCenter(m_lastMousePosition);
-        updateCanvasPixelRect(brushRect);
+        KisTool::mouseMoveEvent(event);
     }
 }
 
-void KisToolSelectBrush::mouseReleaseEvent(KoPointerEvent *e)
+void KisToolSelectBrush::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (m_dragging && e->button() == Qt::LeftButton) {
-        m_dragging = false;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
         applyToSelection(m_selection);
-        e->accept();
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolSelectBrush::activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes)
@@ -201,7 +217,6 @@
 void KisToolSelectBrush::resetSelection()
 {
     updateCanvasPixelRect(m_selection.boundingRect());
-    m_dragging=false;
     m_selection = QPainterPath();
 }
 
Index: plugins/tools/tool_star/kis_tool_star.cc
===================================================================
--- plugins/tools/tool_star/kis_tool_star.cc	(revision 1177751)
+++ plugins/tools/tool_star/kis_tool_star.cc	(working copy)
@@ -55,8 +55,7 @@
 #include <recorder/kis_node_query_path.h>
 
 KisToolStar::KisToolStar(KoCanvasBase * canvas)
-        : KisToolShape(canvas, KisCursor::load("tool_star_cursor.png", 6, 6)),
-        m_dragging(false)
+        : KisToolShape(canvas, KisCursor::load("tool_star_cursor.png", 6, 6))
 {
     setObjectName("tool_star");
     m_innerOuterRatio = 40;
@@ -68,27 +67,27 @@
 }
 void KisToolStar::mousePressEvent(KoPointerEvent *event)
 {
-    if (!currentNode() || currentNode()->systemLocked()) {
-        return;
-    }
-    
-    if (canvas() && event->button() == Qt::LeftButton) {
-        m_dragging = true;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        if (!currentNode() || currentNode()->systemLocked())
+            return;
+
+        setMode(KisTool::PAINT_MODE);
+
         m_dragStart = convertToPixelCoord(event);
         m_dragEnd = convertToPixelCoord(event);
         m_vertices = m_verticesSlider->value();
         m_innerOuterRatio = m_ratioSlider->value();
     }
-    if(m_dragging && (event->button() == Qt::MidButton || event->button() == Qt::RightButton)) {
-        //end painting, if calling the menu or the pop up palette. otherwise there is weird behaviour
-        m_dragging=false;
-        updatePreview();
+    else {
+        KisToolShape::mousePressEvent(event);
     }
 }
 
 void KisToolStar::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         //Erase old lines
         updatePreview();
         if (event->modifiers() & Qt::AltModifier) {
@@ -100,16 +99,16 @@
         }
         updatePreview();
     }
+    else {
+        KisToolShape::mouseMoveEvent(event);
+    }
 }
 
 void KisToolStar::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (!canvas())
-        return;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (m_dragging && event->button() == Qt::LeftButton) {
-        m_dragging = false;
-
         if (m_dragStart == m_dragEnd)
             return;
 
@@ -168,18 +167,18 @@
             canvas()->addCommand(cmd);
         }
     }
+    else {
+        KisToolShape::mouseReleaseEvent(event);
+    }
 }
 
 void KisToolStar::paint(QPainter& gc, const KoViewConverter &converter)
 {
     Q_UNUSED(converter);
 
-    if (!m_dragging)
+    if (mode() != KisTool::PAINT_MODE)
         return;
 
-    if (!canvas())
-        return;
-
     vQPointF points = starCoordinates(m_vertices, m_dragStart.x(), m_dragStart.y(), m_dragEnd.x(), m_dragEnd.y());
 
     QPainterPath path;
Index: plugins/tools/tool_star/kis_tool_star.h
===================================================================
--- plugins/tools/tool_star/kis_tool_star.h	(revision 1177751)
+++ plugins/tools/tool_star/kis_tool_star.h	(working copy)
@@ -49,8 +49,6 @@
     QPointF m_dragStart;
     QPointF m_dragEnd;
     QRect m_final_lines;
-
-    bool m_dragging;
 private:
     vQPointF starCoordinates(int N, double mx, double my, double x, double y);
     void updatePreview();
Index: plugins/assistants/RulerAssistant/kis_ruler_assistant_tool.cc
===================================================================
--- plugins/assistants/RulerAssistant/kis_ruler_assistant_tool.cc	(revision 1177751)
+++ plugins/assistants/RulerAssistant/kis_ruler_assistant_tool.cc	(working copy)
@@ -73,38 +73,59 @@
 
 void KisRulerAssistantTool::mousePressEvent(KoPointerEvent *event)
 {
-    m_handleDrag = 0;
-    foreach(const KisPaintingAssistantHandleSP handle, m_handles) {
-        if (norm2(event->point - *handle) < 10) {
-            m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-            m_handleDrag = handle;
-            break;
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
+
+        setMode(KisTool::PAINT_MODE);
+
+        m_handleDrag = 0;
+        foreach(const KisPaintingAssistantHandleSP handle, m_handles) {
+            if (norm2(event->point - *handle) < 10) {
+                m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+                m_handleDrag = handle;
+                break;
+            }
         }
+        if (!m_handleDrag) {
+            event->ignore();
+        }
     }
-    if (!m_handleDrag) {
-        event->ignore();
+    else {
+        KisTool::mousePressEvent(event);
     }
 }
 
 
 void KisRulerAssistantTool::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_handleDrag) {
-        *m_handleDrag = event->point;
-        m_canvas->updateCanvas();
-    } else {
-        event->ignore();
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
+        if (m_handleDrag) {
+            *m_handleDrag = event->point;
+            m_canvas->updateCanvas();
+        } else {
+            event->ignore();
+        }
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
 void KisRulerAssistantTool::mouseReleaseEvent(KoPointerEvent *event)
 {
-    if (m_handleDrag) {
-        m_handleDrag = 0;
-        m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
-    } else {
-        event->ignore();
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
+
+        if (m_handleDrag) {
+            m_handleDrag = 0;
+            m_canvas->updateCanvas(); // TODO update only the relevant part of the canvas
+        } else {
+            event->ignore();
+        }
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 void KisRulerAssistantTool::paint(QPainter& _gc, const KoViewConverter &_converter)
Index: ui/canvas/kis_canvas2.cpp
===================================================================
--- ui/canvas/kis_canvas2.cpp	(revision 1177751)
+++ ui/canvas/kis_canvas2.cpp	(working copy)
@@ -674,14 +674,11 @@
 }
 
 
-bool KisCanvas2::handlePopupPaletteIsVisible(KoPointerEvent* e)
+bool KisCanvas2::handlePopupPaletteIsVisible()
 {
-    e->accept();
-
-    //TODO: port favoriteResourceManager to KisCanvas2, then enable this function.
-    if (e->button() && (Qt::LeftButton || Qt::MidButton || Qt::RightButton)
-        && favoriteResourceManager()
+    if (favoriteResourceManager()
         && favoriteResourceManager()->isPopupPaletteVisible()) {
+
         favoriteResourceManager()->slotShowPopupPalette();
         return true;
     }
Index: ui/canvas/kis_canvas2.h
===================================================================
--- ui/canvas/kis_canvas2.h	(revision 1177751)
+++ ui/canvas/kis_canvas2.h	(working copy)
@@ -212,7 +212,7 @@
 
     void createFavoriteResourceManager(KisPaintopBox*);
     KoFavoriteResourceManager* favoriteResourceManager();
-    bool handlePopupPaletteIsVisible(KoPointerEvent *);
+    bool handlePopupPaletteIsVisible();
 
 private:
     Q_DISABLE_COPY(KisCanvas2);
Index: ui/tool/kis_tool_ellipse_base.h
===================================================================
--- ui/tool/kis_tool_ellipse_base.h	(revision 1177751)
+++ ui/tool/kis_tool_ellipse_base.h	(working copy)
@@ -47,7 +47,6 @@
     QPointF m_dragCenter;
     QPointF m_dragStart;
     QPointF m_dragEnd;
-    bool m_dragging;
 };
 
 #endif // KIS_TOOL_ELLIPSE_BASE_H
Index: ui/tool/kis_tool_rectangle_base.cpp
===================================================================
--- ui/tool/kis_tool_rectangle_base.cpp	(revision 1177751)
+++ ui/tool/kis_tool_rectangle_base.cpp	(working copy)
@@ -25,7 +25,7 @@
 
 
 KisToolRectangleBase::KisToolRectangleBase(KoCanvasBase * canvas, const QCursor & cursor) :
-    KisToolShape(canvas, cursor), m_dragStart(0, 0), m_dragEnd(0, 0), m_dragging(false)
+    KisToolShape(canvas, cursor), m_dragStart(0, 0), m_dragEnd(0, 0)
 {
 }
 
@@ -34,41 +34,35 @@
     Q_UNUSED(converter);
     Q_ASSERT(currentImage());
 
-    if (m_dragging)
+    if (mode() == KisTool::PAINT_MODE)
         paintRectangle(gc, QRect());
 }
 
 void KisToolRectangleBase::deactivate()
 {
-    m_dragging=false;
     updateArea();
 }
 
 
-void KisToolRectangleBase::mousePressEvent(KoPointerEvent *e)
+void KisToolRectangleBase::mousePressEvent(KoPointerEvent *event)
 {
-    Q_ASSERT(canvas() && currentImage());
-    
-    if (!currentNode() || currentNode()->systemLocked()) {
-        return;
-    }
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-    if (e->button() == Qt::LeftButton) {
-        QPointF pos = convertToPixelCoord(e);
-        m_dragging = true;
-        m_dragStart = m_dragCenter = m_dragEnd = pos;
-        e->accept();
+        if (!currentNode() || currentNode()->systemLocked())
+            return;
+
+        setMode(KisTool::PAINT_MODE);
+        m_dragStart = m_dragCenter = m_dragEnd = convertToPixelCoord(event);
     }
-    else if (e->button()==Qt::RightButton || e->button()==Qt::MidButton) {
-        m_dragging = false;
-        updateArea();
-        e->accept();
+    else {
+        KisToolPaint::mousePressEvent(event);
     }
 }
 
 void KisToolRectangleBase::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         QPointF pos = convertToPixelCoord(event);
         updateArea();
 
@@ -101,24 +95,25 @@
 
         m_dragCenter = QPointF((m_dragStart.x() + m_dragEnd.x()) / 2,
                                (m_dragStart.y() + m_dragEnd.y()) / 2);
-    } else {
-        KisToolPaint::mouseReleaseEvent(event);
     }
+    else {
+        KisToolPaint::mouseMoveEvent(event);
+    }
 }
 
 void KisToolRectangleBase::mouseReleaseEvent(KoPointerEvent *event)
 {
-    Q_ASSERT(canvas() && currentImage());
-    if (!currentNode()) return;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (m_dragging && event->button() == Qt::LeftButton) {
         updateArea();
-        m_dragging = false;
         setCurrentNodeLocked(true);
         finishRect(QRectF(m_dragStart, m_dragEnd));
         setCurrentNodeLocked(false);
-        event->accept();
     }
+    else {
+        KisToolPaint::mouseReleaseEvent(event);
+    }
 }
 
 
Index: ui/tool/kis_tool_rectangle_base.h
===================================================================
--- ui/tool/kis_tool_rectangle_base.h	(revision 1177751)
+++ ui/tool/kis_tool_rectangle_base.h	(working copy)
@@ -47,7 +47,6 @@
     QPointF m_dragStart;
     QPointF m_dragEnd;
     QRect m_final_lines;
-    bool m_dragging;
 };
 
 #endif // KIS_TOOL_RECTANGLE_BASE_H
Index: ui/tool/kis_tool_paint.cc
===================================================================
--- ui/tool/kis_tool_paint.cc	(revision 1177751)
+++ ui/tool/kis_tool_paint.cc	(working copy)
@@ -66,6 +66,7 @@
 #include "kis_canvas_resource_provider.h"
 #include <recorder/kis_recorded_paint_action.h>
 #include <kis_cubic_curve.h>
+#include "kis_color_picker_utils.h"
 
 
 KisToolPaint::KisToolPaint(KoCanvasBase * canvas, const QCursor & cursor)
@@ -78,13 +79,14 @@
 
     m_opacity = OPACITY_OPAQUE_U8;
     m_compositeOp = 0;
-    
+
     updateTabletPressureSamples();
-    
+
     m_supportOutline = false;
-    
+
     KisCanvas2 * kiscanvas = static_cast<KisCanvas2*>(canvas);
     connect(kiscanvas->view()->resourceProvider(), SIGNAL(sigCompositeOpChanged(QString)), this, SLOT(slotSetCompositeMode(QString))); 
+    connect(this, SIGNAL(sigFavoritePaletteCalled(const QPoint&)), kiscanvas, SIGNAL(favoritePaletteCalled(const QPoint&)));
 }
 
 
@@ -123,26 +125,84 @@
 {
 }
 
+void KisToolPaint::mousePressEvent(KoPointerEvent *event)
+{
+    if(mode() == KisTool::HOVER_MODE &&
+       (event->button() == Qt::LeftButton || event->button() == Qt::RightButton) &&
+       event->modifiers() & Qt::ControlModifier &&
+       !specialModifierActive()) {
 
-void KisToolPaint::mouseReleaseEvent(KoPointerEvent *e)
+        setMode(SECONDARY_PAINT_MODE);
+        useCursor(KisCursor::pickerCursor());
+
+        m_toForegroundColor = event->button() == Qt::LeftButton;
+        pickColor(event->point, event->modifiers() & Qt::AltModifier,
+                  m_toForegroundColor);
+        event->accept();
+    }
+    else if(mode() == KisTool::HOVER_MODE &&
+            event->button() == Qt::RightButton &&
+            event->modifiers() == Qt::NoModifier &&
+            !specialModifierActive()) {
+
+        emit sigFavoritePaletteCalled(event->pos());
+        event->accept();
+    }
+    else {
+        KisTool::mousePressEvent(event);
+    }
+}
+
+void KisToolPaint::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (e->button() == Qt::RightButton) {
-        //CALLING POP UP PALETTE
-        emit sigFavoritePaletteCalled(e->pos());
+    if(mode() == KisTool::SECONDARY_PAINT_MODE) {
+        pickColor(event->point, event->modifiers() & Qt::AltModifier,
+                  m_toForegroundColor);
+        event->accept();
+    }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
+}
 
-//        KoResourceManager * resourceProvider = 0;
-//        if (canvas() && (resourceProvider = canvas()->resourceProvider())) {
-//            QVariant fg = resourceProvider->resource(KoCanvasResource::ForegroundColor);
-//            if (!fg.isValid()) return;
-//            QVariant bg = resourceProvider->resource(KoCanvasResource::BackgroundColor);
-//            if (!bg.isValid()) return;
-//            resourceProvider->setResource(KoCanvasResource::ForegroundColor, bg);
-//            resourceProvider->setResource(KoCanvasResource::BackgroundColor, fg);
-//        }
+void KisToolPaint::mouseReleaseEvent(KoPointerEvent *event)
+{
+    if(mode() == KisTool::SECONDARY_PAINT_MODE) {
+        setMode(KisTool::HOVER_MODE);
+        resetCursorStyle();
+        event->accept();
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
+void KisToolPaint::keyPressEvent(QKeyEvent *event)
+{
+    KisTool::keyPressEvent(event);
+}
 
+void KisToolPaint::keyReleaseEvent(QKeyEvent* event)
+{
+    KisTool::keyReleaseEvent(event);
+}
+
+void KisToolPaint::pickColor(const QPointF &documentPixel,
+                             bool fromCurrentNode,
+                             bool toForegroundColor)
+{
+    int resource = toForegroundColor ?
+        KoCanvasResource::ForegroundColor : KoCanvasResource::BackgroundColor;
+
+    KisPaintDeviceSP device = fromCurrentNode ?
+        currentNode()->paintDevice() : image()->projection();
+
+    QPoint imagePoint = image()->documentToIntPixel(documentPixel);
+
+    canvas()->resourceManager()->
+        setResource(resource, KisToolUtils::pick(device, imagePoint));
+}
+
 QWidget * KisToolPaint::createOptionWidget()
 {
 
Index: ui/tool/kis_tool_freehand.cc
===================================================================
--- ui/tool/kis_tool_freehand.cc	(revision 1177751)
+++ ui/tool/kis_tool_freehand.cc	(working copy)
@@ -24,64 +24,49 @@
 #include "kis_tool_freehand.h"
 #include "kis_tool_freehand_p.h"
 
-#include <QEvent>
-#include <QLabel>
-#include <QLayout>
-#include <QMutex>
-#include <QMutexLocker>
-#include "QPainter"
+#include <QPainter>
 #include <QRect>
 #include <QThreadPool>
-#include <QWidget>
 
-#include <klocale.h>
 #include <kaction.h>
 
 #include <KoPointerEvent.h>
-#include <KoCanvasBase.h>
-#include <KoResourceManager.h>
-#include <KoCanvasController.h>
 #include <KoViewConverter.h>
 
 //pop up palette
-#include <ko_favorite_resource_manager.h>
 #include <kis_canvas_resource_provider.h>
 
 // Krita/image
 #include <recorder/kis_action_recorder.h>
-#include <kis_fill_painter.h>
-#include <kis_group_layer.h>
+#include <recorder/kis_recorded_path_paint_action.h>
 #include <kis_layer.h>
 #include <kis_paint_layer.h>
 #include <kis_painter.h>
 #include <kis_paintop.h>
-#include <recorder/kis_recorded_path_paint_action.h>
 #include <kis_selection.h>
 #include <kis_paintop_preset.h>
-#include <kis_debug.h>
-#include <kis_transaction.h>
 
+
 // Krita/ui
 #include "kis_config.h"
 #include <opengl/kis_opengl.h>
 #include "canvas/kis_canvas2.h"
 #include "kis_cursor.h"
-#include "kis_painting_assistant.h"
 #include <recorder/kis_node_query_path.h>
 #include <kis_view2.h>
 #include <kis_painting_assistants_manager.h>
 #include <kis_3d_object_model.h>
-#include "kis_color_picker_utils.h"
 
 #define ENABLE_RECORDING
 static const int HIDE_OUTLINE_TIMEOUT = 800; // ms
 
 KisToolFreehand::KisToolFreehand(KoCanvasBase * canvas, const QCursor & cursor, const QString & transactionText)
     : KisToolPaint(canvas, cursor)
-    , m_dragDist(0)
     , m_transactionText(transactionText)
-    , m_mode(HOVER)
 {
+    m_explicitShowOutline = false;
+
+
     m_painter = 0;
     m_paintIncremental = false;
     m_executor = new QThreadPool(this);
@@ -112,13 +97,10 @@
     addAction("decrease_brush_size", m_decreaseBrushSize);
 
     KisCanvas2* canvas2 = static_cast<KisCanvas2*>(canvas);
-    connect(this, SIGNAL(sigFavoritePaletteCalled(const QPoint&)), canvas2, SIGNAL(favoritePaletteCalled(const QPoint&)));
     connect(this, SIGNAL(sigPainting()), canvas2->view()->resourceProvider(), SLOT(slotPainting()));
 
-    m_showOutline = false;
-    m_timer.setSingleShot(true);
-    connect(&m_timer, SIGNAL(timeout()), this, SLOT( hideOutline() ));
-
+    m_outlineTimer.setSingleShot(true);
+    connect(&m_outlineTimer, SIGNAL(timeout()), this, SLOT(hideOutline()));
 }
 
 KisToolFreehand::~KisToolFreehand()
@@ -132,271 +114,178 @@
     KisToolPaint::deactivate();
 }
 
+inline double norm(const QPointF& p)
+{
+    return sqrt(p.x()*p.x() + p.y()*p.y());
+}
+
+inline double angle(const QPointF& p1, const QPointF& p2)
+{
+    return atan2(p1.y(), p1.x()) - atan2(p2.y(), p2.x());
+}
+
 void KisToolFreehand::mousePressEvent(KoPointerEvent *e)
 {
-    if (currentPaintOpPreset() && currentPaintOpPreset()->settings()) {
-        m_paintIncremental = currentPaintOpPreset()->settings()->paintIncremental();
+    if(mode() == KisTool::PAINT_MODE)
+        return;
+
+    if(mode() == KisTool::HOVER_MODE &&
+       e->button() == Qt::LeftButton &&
+       e->modifiers() == Qt::NoModifier &&
+       !specialModifierActive()) {
+
         currentPaintOpPreset()->settings()->mousePressEvent(e);
         if (e->isAccepted()) {
             return;
         }
-    }
 
-    KisCanvas2 *canvas2 = dynamic_cast<KisCanvas2 *>(canvas());
-    if (canvas2->handlePopupPaletteIsVisible(e)) return;
+        setMode(KisTool::PAINT_MODE);
 
-    m_strokeTimeMeasure.start();
+        initPaint(e);
+        m_previousPaintInformation = KisPaintInformation(convertToPixelCoord(adjustPosition(e->point)),
+                                                         pressureToCurve(e->pressure()), e->xTilt(), e->yTilt(),
+                                                         KisVector2D::Zero(),
+                                                         e->rotation(), e->tangentialPressure(), m_strokeTimeMeasure.elapsed());
 
-    //    dbgUI << "mousePressEvent" << m_mode;
-    //     if (!currentImage())
-    //    return;
-    if (m_mode == PAN) {
-        e->accept();
-        return;
-    }
-    if (e->button() == Qt::MidButton) {
-        initPan();
-        e->accept();
-        return;
-    }
+        m_outlineDocPoint = e->point;
 
-    if (!currentNode())
-        return;
+        KisConfig cfg;
+        if(cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) {
+            updateOutlineRect();
+        }
 
-    if (!currentNode()->paintDevice())
-        return;
-
-    // control-click gets the color at the current point. For now, only with a ratio of 1
-    // get the current color of the project, as per Deevad's suggestion.
-    // this shouldn't be changed back to the current node :-)
-    // CTRL+ALT picks color from current layer
-    // CTRL picks color from projection
-    if (e->modifiers() & Qt::ControlModifier) {
-
-        m_toForegroundColor = (e->button() == Qt::LeftButton);
-        pickColor(convertToIntPixelCoord(e),e->modifiers() & Qt::AltModifier);
-        m_mode = COLOR_PICKING;
-        useCursor(KisCursor::pickerCursor());
         e->accept();
-
-   } else if (e->modifiers() == Qt::ShiftModifier) {
-        m_mode = EDIT_BRUSH;
-        m_prevMousePos = e->point;
-        m_originalPos = e->globalPos();
-        m_originalMousePos = e->point;
-        e->accept();
-        return;
-    } else { // No modifiers
-
-        if (e->button() == Qt::LeftButton) {
-            initPaint(e);
-            m_previousPaintInformation = KisPaintInformation(convertToPixelCoord(adjustPosition(e->point)),
-                                                             pressureToCurve(e->pressure()), e->xTilt(), e->yTilt(),
-                                                             KisVector2D::Zero(),
-                                                             e->rotation(), e->tangentialPressure(), m_strokeTimeMeasure.elapsed());
-        } else if (m_mode == PAINT && (e->button() == Qt::RightButton || e->button() == Qt::MidButton)) {
-            // end painting, if calling the menu or the pop up palette. otherwise there is weird behaviour
-            endPaint();
-        }
     }
-    e->accept();
+    else {
+        KisToolPaint::mousePressEvent(e);
+    }
 }
 
-inline double norm(const QPointF& p)
-{
-    return sqrt(p.x()*p.x() + p.y()*p.y());
-}
-
-inline double angle(const QPointF& p1, const QPointF& p2)
-{
-    return atan2(p1.y(), p1.x()) - atan2(p2.y(), p2.x());
-}
-
 void KisToolFreehand::mouseMoveEvent(KoPointerEvent *e)
 {
-    //    dbgUI << "mouseMoveEvent " << m_mode << " " << e->button() << " " << e->buttons();
-    switch (m_mode) {
-    case PAINT: {
-            QPointF pos = convertToPixelCoord(adjustPosition(e->point));
-            QPointF dragVec = pos - m_previousPaintInformation.pos();
+    /**
+     * Update outline
+     */
+    if(mode() == KisTool::HOVER_MODE ||
+       mode() == KisTool::PAINT_MODE) {
+        m_outlineDocPoint = e->point;
 
-            KisPaintInformation info = KisPaintInformation(pos,
-                                                           pressureToCurve(e->pressure()), e->xTilt(), e->yTilt(),
-                                                           toKisVector2D(dragVec),
-                                                           e->rotation(), e->tangentialPressure(), m_strokeTimeMeasure.elapsed());
+        KisConfig cfg;
+        if(cfg.cursorStyle() == CURSOR_STYLE_OUTLINE) {
+            updateOutlineRect();
+        }
 
-            if (m_smooth) {
-                QPointF newTangent = dragVec;
-
-                if (norm(newTangent) != 0) {
-                    newTangent /= norm(newTangent) ;
-                }
-                double normVec = 0.5 * m_smoothness * norm(dragVec);
-                QPointF control1 = m_previousPaintInformation.pos() + m_previousTangent * normVec;
-                QPointF control2 = info.pos() - newTangent * normVec;
-                paintBezierCurve(m_previousPaintInformation,
-                                 control1,
-                                 control2,
-                                 info);
-                m_previousTangent = newTangent;
-                m_previousDrag = dragVec;
-            } else {
-                paintLine(m_previousPaintInformation, info);
+#if defined(HAVE_OPENGL)
+        else if (cfg.cursorStyle() == CURSOR_STYLE_3D_MODEL) {
+            if (isCanvasOpenGL()) {
+                m_xTilt = e->xTilt();
+                m_yTilt = e->yTilt();
+                // TODO : optimize? but you need to know the size of the 3d brush?
+                canvas()->updateCanvas(QRect(QPoint(0, 0), QSize(currentImage()->width(), currentImage()->height())));
             }
-
-            m_previousPaintInformation = info;
         }
-        break;
-    case EDIT_BRUSH: {
-            useCursor(KisCursor::blankCursor());
-            qreal dx = m_prevMousePos.x() - e->point.x();
-            qreal dy = m_prevMousePos.y() - e->point.y();
-            currentPaintOpPreset()->settings()->changePaintOpSize(-dx, -dy);
-            m_prevMousePos = e->point;
-        }
-        break;
-    case PAN: {
-            pan(e);
-        }
-        break;
-    case COLOR_PICKING:{
-            useCursor(KisCursor::pickerCursor());
-            if (e->modifiers() & Qt::ControlModifier) {
-                pickColor(convertToIntPixelCoord(e), e->modifiers() & Qt::AltModifier);
-            }else {
-                // DO Nothing
-            }
-
-        }
-        break;
-    default:
-        ;
+#endif
     }
 
-    KisConfig cfg;
-    KisPaintOpSettings::OutlineMode outlineMode;
-    if ((m_mode != PAINT  || cfg.showOutlineWhilePainting()) &&
-        (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE || m_mode == EDIT_BRUSH || m_showOutline)) {
-        outlineMode = KisPaintOpSettings::CursorIsOutline;
-    } else {
-        outlineMode = KisPaintOpSettings::CursorIsNotOutline;
+    if(mode() != KisTool::PAINT_MODE) {
+        KisToolPaint::mouseMoveEvent(e);
+        return;
     }
 
-    if (!m_oldOutlineRect.isEmpty()) {
-        canvas()->updateCanvas(m_oldOutlineRect.adjusted(-2,-2,2,2)); // erase the old guy
-    }
+    /**
+     * Actual painting
+     */
+    QPointF pos = convertToPixelCoord(adjustPosition(e->point));
+    QPointF dragVec = pos - m_previousPaintInformation.pos();
 
-    m_mousePos = e->point;
+    KisPaintInformation info =
+        KisPaintInformation(pos, pressureToCurve(e->pressure()),
+                            e->xTilt(), e->yTilt(), toKisVector2D(dragVec),
+                            e->rotation(), e->tangentialPressure(),
+                            m_strokeTimeMeasure.elapsed());
 
-#if defined(HAVE_OPENGL)
-    if (cfg.cursorStyle() == CURSOR_STYLE_3D_MODEL) {
-        if (isCanvasOpenGL()) {
-            m_xTilt = e->xTilt();
-            m_yTilt = e->yTilt();
-            // TODO : optimize? but you need to know the size of the 3d brush?
-            canvas()->updateCanvas(QRect(QPoint(0, 0), QSize(currentImage()->width(), currentImage()->height())));
+    if (m_smooth) {
+        QPointF newTangent = dragVec;
+
+        if (norm(newTangent) != 0) {
+            newTangent /= norm(newTangent) ;
         }
+        double normVec = 0.5 * m_smoothness * norm(dragVec);
+        QPointF control1 = m_previousPaintInformation.pos() + m_previousTangent * normVec;
+        QPointF control2 = info.pos() - newTangent * normVec;
+        paintBezierCurve(m_previousPaintInformation,
+                         control1,
+                         control2,
+                         info);
+        m_previousTangent = newTangent;
+    } else {
+        paintLine(m_previousPaintInformation, info);
     }
-#endif
 
-
-    QPainterPath path;
-    if (m_painter && m_painter->paintOp()){
-        path = currentPaintOpPreset()->settings()->brushOutline(currentImage()->documentToPixel(outlinePos()), 
-                                                                         outlineMode,
-                                                                         m_painter->paintOp()->currentScale(),
-                                                                         m_painter->paintOp()->currentRotation());
-    }else{
-        path = currentPaintOpPreset()->settings()->brushOutline(currentImage()->documentToPixel(outlinePos()),outlineMode);
-    }
-    m_oldOutlineRect = currentImage()->pixelToDocument(path.boundingRect());
-    if (!m_oldOutlineRect.isEmpty()) {
-        canvas()->updateCanvas(m_oldOutlineRect.adjusted(-2,-2,2,2));
-    }
-
+    m_previousPaintInformation = info;
 }
 
 void KisToolFreehand::mouseReleaseEvent(KoPointerEvent* e)
 {
-    KisCanvas2 *canvas2 = dynamic_cast<KisCanvas2 *>(canvas());
-    if (canvas2->handlePopupPaletteIsVisible(e)) {
-        return;
-    }
-    else if (e->button() == Qt::LeftButton) {
-        //TODO: There is a bug here. If pop up palette is visible and a new colour is selected,
-        //the new colour will be added when the user clicks on the canvas to hide the palette
-        //This is used to handle recently used colour (KoFavoriteResourceManager)
-        emit sigPainting();
-    }
+    if(mode() == KisTool::PAINT_MODE &&
+       e->button() == Qt::LeftButton) {
 
-    switch (m_mode) {
-    case PAINT:
-        if (!m_hasPaintAtLeastOnce)
-        {
+        if (!m_hasPaintAtLeastOnce) {
             paintAt(m_previousPaintInformation);
+
+            // Let's add history information about recently used colors
+            emit sigPainting();
         }
-        endPaint();
-        break;
-    case PAN:
-        if (e->button() == Qt::MidButton) {
-            endPan();
-            e->accept();
-        }
-        return;
-    case EDIT_BRUSH:
-        QCursor::setPos(m_originalPos);
-        break;
-    default:
-        ;
-    };
 
-    if (m_mode != COLOR_PICKING){
+        setMode(KisTool::HOVER_MODE);
+        endPaint();
+        e->accept();
+    }
+    else {
         KisToolPaint::mouseReleaseEvent(e);
     }
-
-    m_mode = HOVER;
-    resetCursorStyle();
 }
 
 void KisToolFreehand::keyPressEvent(QKeyEvent *event)
 {
-    if (m_mode != HOVER) {
-        event->accept(); // Make sure nothing disturb the painting
+    if(mode() != KisTool::PAINT_MODE) {
+        KisToolPaint::keyPressEvent(event);
+        return;
     }
-    else if (event->key() == Qt::Key_Space) {
-        initPan();
-        event->accept();
-    }/* else if (event->key() == Qt::Key_Control){ // we need to reset the cursor back when the user does not hold any key so commented so far
-        useCursor(KisCursor::pickerCursor());
-    }*/else {
-        event->ignore();
-    }
+
+    event->ignore();
 }
 
 void KisToolFreehand::keyReleaseEvent(QKeyEvent* event)
 {
-    if (m_mode == PAN && event->key() == Qt::Key_Space) {
-        endPan();
-        event->accept();
+    if(mode() != KisTool::PAINT_MODE) {
+        KisToolPaint::keyReleaseEvent(event);
+        return;
     }
-    KoToolBase::keyReleaseEvent(event);
+
+    event->ignore();
 }
 
+void KisToolFreehand::gesture(const QPointF &offsetInDocPixels, const QPointF &initialDocPoint)
+{
+    currentPaintOpPreset()->settings()->changePaintOpSize(offsetInDocPixels.x(), offsetInDocPixels.y());
+
+    m_outlineDocPoint = initialDocPoint;
+
+    updateOutlineRect();
+}
+
 void KisToolFreehand::initPaint(KoPointerEvent *)
 {
     KisCanvas2 *canvas2 = dynamic_cast<KisCanvas2 *>(canvas());
     if(canvas2)
         canvas2->view()->disableControls();
 
-    //    dbgUI << "initPaint";
     if (!currentNode() || !currentNode()->paintDevice() || currentNode()->systemLocked())
         return;
 
     setCurrentNodeLocked(true);
-    
-    m_mode = PAINT;
     m_hasPaintAtLeastOnce = false;
-    m_dragDist = 0;
 
     KisPaintDeviceSP paintDevice = currentNode()->paintDevice();
     KisPaintDeviceSP targetDevice;
@@ -404,6 +293,8 @@
     if (!m_compositeOp)
         m_compositeOp = paintDevice->colorSpace()->compositeOp(COMPOSITE_OVER);
 
+    m_strokeTimeMeasure.start();
+    m_paintIncremental = currentPaintOpPreset()->settings()->paintIncremental();
 
     if (!m_paintIncremental) {
         KisIndirectPaintingSupport* indirect =
@@ -441,7 +332,6 @@
     }
 
     m_previousTangent = QPointF(0, 0);
-    m_previousDrag = QPointF(0, 0);
 
 
 #ifdef ENABLE_RECORDING // Temporary, to figure out what is going without being
@@ -457,13 +347,11 @@
 
 void KisToolFreehand::endPaint()
 {
-    //    dbgUI << "endPaint";
-
     KisCanvas2 *canvas2 = dynamic_cast<KisCanvas2 *>(canvas());
-    if(canvas2)
+    if(canvas2) {
         canvas2->view()->enableControls();
+    }
 
-    m_mode = HOVER;
     if (m_painter) {
 
         m_executor->waitForDone();
@@ -549,7 +437,7 @@
 
 void KisToolFreehand::setDirty(const QRegion& region)
 {
-    if (region.numRects() < 1)
+    if (region.isEmpty())
         return;
 
     currentNode()->setDirty(region);
@@ -569,7 +457,6 @@
     m_assistant = assistant;
 }
 
-#define ZET 7
 void KisToolFreehand::paint(QPainter& gc, const KoViewConverter &converter)
 {
     KisConfig cfg;
@@ -591,7 +478,7 @@
             }
 
             if (glIsList(m_displayList)) {
-                QPointF pos = converter.documentToView(m_mousePos);
+                QPointF pos = converter.documentToView(m_outlineDocPoint);
 
                 glColor3f(0.0, 1.0, 0.0);
                 glShadeModel(GL_SMOOTH);
@@ -646,32 +533,17 @@
 
     {
         KisPaintOpSettings::OutlineMode outlineMode;
-        if (m_mode == PAINT) {
-            m_showOutline = false;
-        }
+        outlineMode = KisPaintOpSettings::CursorIsNotOutline;
 
-        if ((m_mode != PAINT || cfg.showOutlineWhilePainting()) &&
-            (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE || m_mode == EDIT_BRUSH || m_showOutline)) {
+        if(m_explicitShowOutline ||
+           mode() == KisTool::GESTURE_MODE ||
+           (cfg.cursorStyle() == CURSOR_STYLE_OUTLINE &&
+            (mode() != PAINT_MODE || cfg.showOutlineWhilePainting()))) {
+
             outlineMode = KisPaintOpSettings::CursorIsOutline;
-        } else {
-            outlineMode = KisPaintOpSettings::CursorIsNotOutline;
         }
 
-        qreal zoomX, zoomY;
-        converter.zoom(&zoomX, &zoomY);
-
-
-        QPainterPath path;
-        if (m_painter && m_painter->paintOp()){
-            path = currentPaintOpPreset()->settings()->brushOutline(currentImage()->documentToPixel(outlinePos()), 
-                                                                                outlineMode,
-                                                                                m_painter->paintOp()->currentScale(),
-                                                                                m_painter->paintOp()->currentRotation());
-        }else{
-            path = currentPaintOpPreset()->settings()->brushOutline(currentImage()->documentToPixel(outlinePos()),outlineMode);
-        }
-        m_oldOutlineRect = currentImage()->pixelToDocument(path.boundingRect());
-
+        QPainterPath path = getOutlinePath(m_outlineDocPoint, outlineMode);
         paintToolOutline(&gc,pixelToView(path));
     }
 }
@@ -685,46 +557,26 @@
     return point;
 }
 
-void KisToolFreehand::initPan()
+QPainterPath KisToolFreehand::getOutlinePath(const QPointF &documentPos,
+                                             KisPaintOpSettings::OutlineMode outlineMode)
 {
-    m_mode = PAN;
-    m_lastPosition = convertDocumentToWidget(m_mousePos);
-    useCursor(QCursor(Qt::ClosedHandCursor));
-}
+    qreal scale = 1.0;
+    qreal rotation = 0;
+    if (m_painter && m_painter->paintOp()){
+        scale = m_painter->paintOp()->currentScale();
+        rotation = m_painter->paintOp()->currentRotation();
+    }
 
-void KisToolFreehand::pan(KoPointerEvent *event)
-{
-    Q_ASSERT(canvas());
-    Q_ASSERT(canvas()->canvasController());
+    QPointF imagePos = currentImage()->documentToPixel(documentPos);
+    QPainterPath path = currentPaintOpPreset()->settings()->
+        brushOutline(imagePos, outlineMode, scale, rotation);
 
-    event->accept();
-
-    QPointF actualPosition = convertDocumentToWidget(event->point);
-    QPointF distance(m_lastPosition - actualPosition);
-    canvas()->canvasController()->pan(distance.toPoint());
-
-    m_lastPosition = actualPosition;
+    return path;
 }
 
-void KisToolFreehand::endPan()
-{
-    m_mode = HOVER;
-    resetCursorStyle();
-}
-
-void KisToolFreehand::customMoveEvent(KoPointerEvent * event)
-{
-    if (m_mode == PAN) {
-        canvas()->canvasController()->pan(QPoint(-event->x(), -event->y()));
-        event->accept();
-    }
-    event->ignore();
-}
-
 void KisToolFreehand::increaseBrushSize()
 {
     currentPaintOpPreset()->settings()->changePaintOpSize(1, 0);
-    m_oldOutlineRect.adjust(-1, -1, 1, 1);
     showOutlineTemporary();
 }
 
@@ -734,41 +586,27 @@
     showOutlineTemporary();
 }
 
-QPointF KisToolFreehand::outlinePos() const
+void KisToolFreehand::updateOutlineRect()
 {
-    if (m_mode == EDIT_BRUSH) {
-        return m_originalMousePos;
-    } else {
-        return m_mousePos;
-    }
+    QRectF outlinePixelRect = getOutlinePath(m_outlineDocPoint, KisPaintOpSettings::CursorIsOutline).boundingRect();
+    QRectF outlineDocRect = currentImage()->pixelToDocument(outlinePixelRect);
+
+#warning "Remove adjusted() call -- it smells hacky"
+    canvas()->updateCanvas(outlineDocRect.adjusted(-2,-2,2,2));
 }
 
 void KisToolFreehand::showOutlineTemporary()
 {
-    m_showOutline = true;
-    m_timer.start(HIDE_OUTLINE_TIMEOUT);
-    //canvas()->updateCanvas(m_oldOutlineRect);
-    canvas()->updateCanvas(QRect(QPoint(0, 0), QSize(currentImage()->width(), currentImage()->height())));
+    m_explicitShowOutline = true;
+    m_outlineTimer.start(HIDE_OUTLINE_TIMEOUT);
+    updateOutlineRect();
 }
 
 void KisToolFreehand::hideOutline()
 {
-    m_showOutline = false;
-    //canvas()->updateCanvas(m_oldOutlineRect);
-    canvas()->updateCanvas(QRect(QPoint(0, 0), QSize(currentImage()->width(), currentImage()->height())));
+    m_explicitShowOutline = false;
+    updateOutlineRect();
 }
 
-
-void KisToolFreehand::pickColor(const QPoint &pos, bool fromCurrentNode)
-{
-    int key = m_toForegroundColor ? KoCanvasResource::ForegroundColor : KoCanvasResource::BackgroundColor;
-    if (fromCurrentNode){
-            canvas()->resourceManager()->setResource(key,KisToolUtils::pick( currentNode()->paintDevice(),pos));
-    } else /* projection */{
-            canvas()->resourceManager()->setResource(key,KisToolUtils::pick( image()->projection(), pos));
-    }
-}
-
-
 #include "kis_tool_freehand.moc"
 
Index: ui/tool/kis_tool_paint.h
===================================================================
--- ui/tool/kis_tool_paint.h	(revision 1177751)
+++ ui/tool/kis_tool_paint.h	(working copy)
@@ -54,14 +54,6 @@
 
 class KisSliderSpinBox;
 
-enum enumBrushMode {
-    PAINT,
-    HOVER,
-    EDIT_BRUSH,
-    PAN,
-    COLOR_PICKING
-};
-
 // wacom 
 const static int LEVEL_OF_PRESSURE_RESOLUTION = 1024;
 
@@ -76,14 +68,20 @@
     virtual ~KisToolPaint();
 
 
-public:
+protected:
 
     virtual void resourceChanged(int key, const QVariant & v);
 
     virtual void paint(QPainter& gc, const KoViewConverter &converter);
 
+    virtual void mousePressEvent(KoPointerEvent *event);
     virtual void mouseReleaseEvent(KoPointerEvent *event);
+    virtual void mouseMoveEvent(KoPointerEvent *event);
 
+    virtual void keyPressEvent(QKeyEvent *event);
+    virtual void keyReleaseEvent(QKeyEvent* event);
+
+
     /** If the paint tool support outline like brushes, set to true.
     *   If not (e.g. gradient tool), set to false. Default is false.
     */
@@ -114,7 +112,8 @@
     qreal pressureToCurve(qreal pressure){
         return m_pressureSamples.at( qRound(pressure * LEVEL_OF_PRESSURE_RESOLUTION) );
     }
-    
+
+
 public slots:
     virtual void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes);
 
@@ -137,7 +136,11 @@
     QVector<qreal> m_pressureSamples;
 
 private:
+    void pickColor(const QPointF &documentPixel, bool fromCurrentNode,
+                   bool toForegroundColor);
 
+private:
+
     QGridLayout *m_optionWidgetLayout;
 
     QLabel *m_lbOpacity;
@@ -145,6 +148,11 @@
 
     bool m_supportOutline;
 
+    /**
+     * Used as a switch for pickColor
+     */
+    bool m_toForegroundColor;
+
 signals:
     void sigFavoritePaletteCalled(const QPoint&);
     void sigPainting();
Index: ui/tool/kis_tool_freehand.h
===================================================================
--- ui/tool/kis_tool_freehand.h	(revision 1177751)
+++ ui/tool/kis_tool_freehand.h	(working copy)
@@ -40,6 +40,16 @@
 class KisRecordedPathPaintAction;
 class FreehandPaintJobExecutor;
 
+#include "kis_paintop_settings.h"
+
+enum KDE_DEPRECATED enumBrushMode {
+    PAINT,
+    HOVER,
+    EDIT_BRUSH,
+    PAN,
+    COLOR_PICKING
+};
+
 class KRITAUI_EXPORT KisToolFreehand : public KisToolPaint
 {
 
@@ -51,21 +61,24 @@
     KisToolFreehand(KoCanvasBase * canvas, const QCursor & cursor, const QString & transactionText);
     virtual ~KisToolFreehand();
 
+    virtual void setDirty(const QRegion& region);
+
+signals:
+    void sigPainting();
+
+protected:
+    void gesture(const QPointF &offsetInDocPixels,
+                 const QPointF &initialDocPoint);
+
     virtual void mousePressEvent(KoPointerEvent *e);
     virtual void mouseMoveEvent(KoPointerEvent *e);
     virtual void mouseReleaseEvent(KoPointerEvent *e);
-    virtual void customMoveEvent(KoPointerEvent * event); // only for panning
     virtual void keyPressEvent(QKeyEvent *event);
     virtual void keyReleaseEvent(QKeyEvent* event);
     virtual bool wantsAutoScroll() const;
-    virtual void setDirty(const QRegion& region);
     virtual void deactivate();
 
-signals:
-    void sigPainting();
 
-protected:
-
     /// Paint a single brush footprint on the current layer
     virtual void paintAt(const KisPaintInformation &pi);
 
@@ -82,10 +95,6 @@
     virtual void endPaint();
     virtual void paint(QPainter& gc, const KoViewConverter &converter);
 
-    virtual void initPan();
-    virtual void pan(KoPointerEvent *e);
-    virtual void endPan();
-
 protected slots:
 
     void setSmooth(bool smooth);
@@ -98,18 +107,22 @@
     QPointF adjustPosition(const QPointF& point);
     void queuePaintJob(FreehandPaintJob* job, FreehandPaintJob* previousJob);
     void showOutlineTemporary();
-    void pickColor(const QPoint &pos, bool currentNode);
-    
-private slots:
 
+    void updateOutlineRect();
+    QPainterPath getOutlinePath(const QPointF &documentPos,
+                                KisPaintOpSettings::OutlineMode outlineMode);
+
+private slots:
     void increaseBrushSize();
     void decreaseBrushSize();
     void hideOutline();
 protected:
 
+    // For Dyna brush
+    QPointF m_outlineDocPoint;
+
     KisPaintInformation m_previousPaintInformation;
     QPointF m_previousTangent;
-    QPointF m_previousDrag;
     double m_dragDist;
 
     bool m_paintIncremental;
@@ -123,7 +136,6 @@
     double m_magnetism;
 
 private:
-    QPointF outlinePos() const;
 #if defined(HAVE_OPENGL)
     qreal m_xTilt;
     qreal m_yTilt;
@@ -135,34 +147,20 @@
     QString m_brushModelName;
 #endif
 
-    QPointF m_mousePos;
-    QPointF m_prevMousePos;
-    QPointF m_originalMousePos;
-    QPoint  m_originalPos;
+    QTimer m_outlineTimer;
+    bool m_explicitShowOutline;
 
-    // for painting
-    QRectF m_oldOutlineRect;
-    QPointF m_oldOutlinePosition;
-    
-    
     QRegion m_incrementalDirtyRegion;
     QList<FreehandPaintJob*> m_paintJobs;
     KisRecordedPathPaintAction* m_pathPaintAction;
     QThreadPool* m_executor;
 
-    // for panning
-    QPointF m_lastPosition;
     QTime m_strokeTimeMeasure;
 
     KAction* m_increaseBrushSize;
     KAction* m_decreaseBrushSize;
-    
+
     bool m_hasPaintAtLeastOnce; ///< this indicates whether mouseReleaseEvent should call paintAt or not
-    
-    QTimer m_timer;
-    bool m_showOutline;
-    
-    bool m_toForegroundColor;
 };
 
 
Index: ui/tool/kis_tool.cc
===================================================================
--- ui/tool/kis_tool.cc	(revision 1177751)
+++ ui/tool/kis_tool.cc	(working copy)
@@ -71,11 +71,13 @@
 #include <recorder/kis_recorded_paint_action.h>
 
 struct KisTool::Private {
-    Private() : currentPattern(0),
-            currentGradient(0),
-            currentPaintOpPreset(0),
-            currentGenerator(0),
-            optionWidget(0) { }
+    Private()
+        : currentPattern(0),
+          currentGradient(0),
+          currentPaintOpPreset(0),
+          currentGenerator(0),
+          optionWidget(0),
+          spacePressed(0) { }
     QCursor cursor; // the cursor that should be shown on tool activation.
 
     // From the canvas resources
@@ -93,6 +95,10 @@
     KAction* toggleFgBg;
     KAction* resetFgBg;
 
+    bool spacePressed;
+    QPointF lastDocumentPoint;
+    QPointF initialGestureDocPoint;
+    QPoint initialGestureGlobalPoint;
 };
 
 KisTool::KisTool(KoCanvasBase * canvas, const QCursor & cursor)
@@ -114,6 +120,7 @@
     connect(d->resetFgBg, SIGNAL(triggered()), this, SLOT(slotResetFgBg()));
     addAction("reset_fg_bg", d->resetFgBg);
 
+    setMode(HOVER_MODE);
 }
 
 KisTool::~KisTool()
@@ -373,21 +380,183 @@
     return d->currentGenerator;
 }
 
+bool KisTool::specialModifierActive()
+{
+    KisCanvas2 *canvas2 = dynamic_cast<KisCanvas2 *>(canvas());
+    bool popupPalletActive = canvas2->handlePopupPaletteIsVisible();
+
+    KisConfig cfg;
+    return popupPalletActive || (d->spacePressed && !cfg.clicklessSpacePan());
+}
+
+void KisTool::setMode(ToolMode mode) {
+    m_mode = mode;
+}
+
+KisTool::ToolMode KisTool::mode() {
+    return m_mode;
+}
+
 void KisTool::mousePressEvent(KoPointerEvent *event)
 {
-    event->ignore();
+    KisConfig cfg;
+
+    if (mode() == KisTool::HOVER_MODE &&
+        ((event->button() == Qt::MidButton &&
+          event->modifiers() == Qt::NoModifier) ||
+         (d->spacePressed && !cfg.clicklessSpacePan()))) {
+
+        initPan(event->point);
+        event->accept();
+    }
+    else if (mode() == KisTool::HOVER_MODE &&
+             (event->button() == Qt::LeftButton &&
+              event->modifiers() == Qt::ShiftModifier)) {
+
+        initGesture(event->point);
+        event->accept();
+    }
+
+
+    d->lastDocumentPoint = event->point;
 }
 
 void KisTool::mouseMoveEvent(KoPointerEvent *event)
 {
-    event->ignore();
+    if(mode() == PAN_MODE) {
+        pan(event->point);
+        event->accept();
+    }
+    else if (mode() == GESTURE_MODE) {
+        processGesture(event->point);
+        event->accept();
+    }
+
+    d->lastDocumentPoint = event->point;
 }
 
 void KisTool::mouseReleaseEvent(KoPointerEvent *event)
 {
+    KisConfig cfg;
+
+    if(mode() == PAN_MODE) {
+        if (event->button() == Qt::MidButton ||
+            (event->button() == Qt::LeftButton && !cfg.clicklessSpacePan())) {
+
+            endPan();
+            event->accept();
+        }
+    }
+    else if (mode() == GESTURE_MODE) {
+        if (event->button() == Qt::LeftButton) {
+            endGesture();
+            event->accept();
+        }
+    }
+
+    d->lastDocumentPoint = event->point;
+}
+
+void KisTool::keyPressEvent(QKeyEvent *event)
+{
+    if (event->key() == Qt::Key_Space) {
+
+        KisConfig cfg;
+        if(cfg.clicklessSpacePan()) {
+            initPan(d->lastDocumentPoint);
+        }
+        else {
+            d->spacePressed = true;
+        }
+
+        event->accept();
+        return;
+    }
+
     event->ignore();
 }
 
+void KisTool::keyReleaseEvent(QKeyEvent* event)
+{
+    if (event->key() == Qt::Key_Space) {
+
+        KisConfig cfg;
+        if(cfg.clicklessSpacePan()) {
+            endPan();
+        }
+        else {
+            d->spacePressed = false;
+        }
+
+        event->accept();
+        return;
+    }
+
+    event->ignore();
+}
+
+void KisTool::initPan(const QPointF &docPoint)
+{
+    setMode(PAN_MODE);
+    m_lastPosition = convertDocumentToWidget(docPoint);
+    useCursor(QCursor(Qt::ClosedHandCursor));
+}
+
+void KisTool::pan(const QPointF &docPoint)
+{
+    Q_ASSERT(canvas());
+    Q_ASSERT(canvas()->canvasController());
+
+    QPointF actualPosition = convertDocumentToWidget(docPoint);
+    QPointF distance(m_lastPosition - actualPosition);
+    canvas()->canvasController()->pan(distance.toPoint());
+
+    m_lastPosition = actualPosition;
+}
+
+void KisTool::endPan()
+{
+    setMode(HOVER_MODE);
+    resetCursorStyle();
+}
+
+void KisTool::initGesture(const QPointF &docPoint)
+{
+    setMode(GESTURE_MODE);
+    d->initialGestureDocPoint = docPoint;
+    d->initialGestureGlobalPoint = QCursor::pos();
+    useCursor(KisCursor::blankCursor());
+}
+
+void KisTool::processGesture(const QPointF &docPoint)
+{
+    QPointF lastWidgetPosition = convertDocumentToWidget(d->lastDocumentPoint);
+    QPointF actualWidgetPosition = convertDocumentToWidget(docPoint);
+
+    QPointF offset = actualWidgetPosition - lastWidgetPosition;
+
+    /**
+     * view pixels != widget pixels, but we do this anyway, we only
+     * need to scale the gesture down, not rotate or anything
+     */
+    QPointF scaledOffset = canvas()->viewConverter()->viewToDocument(offset);
+    gesture(scaledOffset, d->initialGestureDocPoint);
+}
+
+void KisTool::endGesture()
+{
+    gesture(QPointF(), d->initialGestureDocPoint);
+    setMode(HOVER_MODE);
+    resetCursorStyle();
+    QCursor::setPos(d->initialGestureGlobalPoint);
+}
+
+void KisTool::gesture(const QPointF &offsetInDocPixels, const QPointF &initialDocPoint)
+{
+    Q_UNUSED(offsetInDocPixels);
+    Q_UNUSED(initialDocPoint);
+}
+
 void KisTool::setupPainter(KisPainter* painter)
 {
     Q_ASSERT(currentImage());
Index: ui/tool/kis_tool.h
===================================================================
--- ui/tool/kis_tool.h	(revision 1177751)
+++ ui/tool/kis_tool.h	(working copy)
@@ -28,6 +28,28 @@
 #include <krita_export.h>
 #include <kis_types.h>
 
+#define PRESS_CONDITION(_event, _mode, _button, _modifier)              \
+    (mode() == (_mode) && (_event)->button() == (_button) &&            \
+     (_event)->modifiers() == (_modifier) && !specialModifierActive())
+
+#define PRESS_CONDITION_WB(_event, _mode, _button, _modifier)            \
+    (mode() == (_mode) && (_event)->button() & (_button) &&            \
+     (_event)->modifiers() == (_modifier) && !specialModifierActive())
+
+#define PRESS_CONDITION_OM(_event, _mode, _button, _modifier)           \
+    (mode() == (_mode) && (_event)->button() == (_button) &&            \
+     ((_event)->modifiers() & (_modifier) ||                            \
+      (_event)->modifiers() == Qt::NoModifier) &&                       \
+     !specialModifierActive())
+
+#define RELEASE_CONDITION(_event, _mode, _button)               \
+    (mode() == (_mode) && (_event)->button() == (_button))
+
+#define RELEASE_CONDITION_WB(_event, _mode, _button)               \
+    (mode() == (_mode) && (_event)->button() & (_button))
+
+#define MOVE_CONDITION(_event, _mode) (mode() == (_mode))
+
 class KoCanvasBase;
 class KisPattern;
 class KoAbstractGradient;
@@ -74,17 +96,15 @@
 
     virtual void resourceChanged(int key, const QVariant & res);
 
-public:
+protected:
 
-    /// reimplemented from superclass
     virtual void mousePressEvent(KoPointerEvent *event);
-
-    /// reimplemented from superclass
     virtual void mouseMoveEvent(KoPointerEvent *event);
-
-    /// reimplemented from superclass
     virtual void mouseReleaseEvent(KoPointerEvent *event);
 
+    virtual void keyPressEvent(QKeyEvent *event);
+    virtual void keyReleaseEvent(QKeyEvent* event);
+
     /// reimplemented from superclass
     virtual void mouseDoubleClickEvent(KoPointerEvent *) {}  // when a krita tool is enabled, don't push double click on
 
@@ -135,6 +155,10 @@
 
 protected:
 
+    bool specialModifierActive();
+    virtual void gesture(const QPointF &offsetInDocPixels,
+                         const QPointF &initialDocPoint);
+
     KisImageWSP image() const;
     QCursor cursor() const;
 
@@ -176,6 +200,20 @@
     /// Sets the systemLocked for the current node, this will not deactivate the tool buttons
     void setCurrentNodeLocked(bool locked);
 
+protected:
+    enum ToolMode {
+        HOVER_MODE,
+        PAINT_MODE,
+        SECONDARY_PAINT_MODE,
+        GESTURE_MODE,
+        PAN_MODE,
+        OTHER // not used now
+    };
+
+    void setMode(ToolMode mode);
+    ToolMode mode();
+
+
 protected slots:
     /**
      * Called whenever the configuration settings change.
@@ -188,7 +226,18 @@
     void slotResetFgBg();
 
 private:
+    void initPan(const QPointF &docPoint);
+    void pan(const QPointF &docPoint);
+    void endPan();
+
+    void initGesture(const QPointF &docPoint);
+    void processGesture(const QPointF &docPoint);
+    void endGesture();
+
+private:
     PaintMode m_outlinePaintMode;
+    ToolMode m_mode;
+    QPointF m_lastPosition;
 
     struct Private;
     Private* const d;
Index: ui/tool/kis_tool_ellipse_base.cpp
===================================================================
--- ui/tool/kis_tool_ellipse_base.cpp	(revision 1177751)
+++ ui/tool/kis_tool_ellipse_base.cpp	(working copy)
@@ -29,8 +29,7 @@
 KisToolEllipseBase::KisToolEllipseBase(KoCanvasBase * canvas, const QCursor & cursor) :
         KisToolShape(canvas, cursor),
         m_dragStart(0,0),
-        m_dragEnd(0,0),
-        m_dragging(false)
+        m_dragEnd(0,0)
 {
 }
 
@@ -42,41 +41,38 @@
 {
     Q_UNUSED(converter);
     Q_ASSERT(currentImage());
-    if (m_dragging)
+    if (mode() == KisTool::PAINT_MODE)
         paintEllipse(gc, QRect());
 }
 
 void KisToolEllipseBase::deactivate()
 {
-    m_dragging=false;
     updateArea();
 }
 
 
 void KisToolEllipseBase::mousePressEvent(KoPointerEvent *event)
 {
-    Q_ASSERT(canvas() && currentImage());
+    if(PRESS_CONDITION(event, KisTool::HOVER_MODE,
+                       Qt::LeftButton, Qt::NoModifier)) {
 
-    if (!currentNode() || currentNode()->systemLocked()) {
-        return;
-    }
-    
-    if (event->button() == Qt::LeftButton) {
+        if (!currentNode() || currentNode()->systemLocked())
+            return;
+
+        setMode(KisTool::PAINT_MODE);
+
         QPointF pos = convertToPixelCoord(event);
-        m_dragging = true;
         m_dragStart = m_dragCenter = m_dragEnd = pos;
         event->accept();
     }
-    else if (event->button()==Qt::RightButton || event->button()==Qt::MidButton) {
-        m_dragging = false;
-        updateArea();
-        event->accept();
+    else {
+        KisTool::mousePressEvent(event);
     }
 }
 
 void KisToolEllipseBase::mouseMoveEvent(KoPointerEvent *event)
 {
-    if (m_dragging) {
+    if(MOVE_CONDITION(event, KisTool::PAINT_MODE)) {
         updateArea();
 
         QPointF pos = convertToPixelCoord(event);
@@ -109,21 +105,26 @@
         m_dragCenter = QPointF((m_dragStart.x() + m_dragEnd.x()) / 2,
                                (m_dragStart.y() + m_dragEnd.y()) / 2);
     }
+    else {
+        KisTool::mouseMoveEvent(event);
+    }
 }
 
 void KisToolEllipseBase::mouseReleaseEvent(KoPointerEvent *event)
 {
-    Q_ASSERT(canvas() && currentImage());
-    if (!currentNode()) return;
+    if(RELEASE_CONDITION(event, KisTool::PAINT_MODE, Qt::LeftButton)) {
+        setMode(KisTool::HOVER_MODE);
 
-    if (m_dragging && event->button() == Qt::LeftButton) {
         updateArea();
-        m_dragging = false;
+
         setCurrentNodeLocked(true);
         finishEllipse(QRectF(m_dragStart, m_dragEnd).normalized());
         setCurrentNodeLocked(false);
         event->accept();
     }
+    else {
+        KisTool::mouseReleaseEvent(event);
+    }
 }
 
 
Index: ui/kis_config.cc
===================================================================
--- ui/kis_config.cc	(revision 1177751)
+++ ui/kis_config.cc	(working copy)
@@ -754,7 +754,6 @@
     m_cfg.writeEntry("presetChooserViewMode", mode);
 }
 
-
 bool KisConfig::firstRun() const
 {
     return m_cfg.readEntry("firstRun", true);
@@ -764,3 +763,13 @@
 {
     m_cfg.writeEntry("firstRun", first);
 }
+
+bool KisConfig::clicklessSpacePan() const
+{
+    return m_cfg.readEntry("clicklessSpacePan", true);
+}
+
+void KisConfig::setClicklessSpacePan(const bool toggle) const
+{
+    m_cfg.writeEntry("clicklessSpacePan", toggle);
+}
Index: ui/kis_config.h
===================================================================
--- ui/kis_config.h	(revision 1177751)
+++ ui/kis_config.h	(working copy)
@@ -269,8 +269,9 @@
     bool firstRun() const;
     void setFirstRun(const bool firstRun) const;
 
+    bool clicklessSpacePan() const;
+    void setClicklessSpacePan(const bool toggle) const;
 
-
 private:
     KisConfig(const KisConfig&);
     KisConfig& operator=(const KisConfig&);
