Salome HOME
updated copyright message
[modules/gui.git] / src / GLViewer / GLViewer_ViewPort2d.cxx
index 6c09a2a47f40d9d31ef959689e602173d296f83d..495bb52a2c6792909b3f3a2aaf88204fb9f1f102 100644 (file)
+// Copyright (C) 2007-2023  CEA, EDF, OPEN CASCADE
+//
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License, or (at your option) any later version.
+//
+// This library is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+// Lesser General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+//
+
+//  Author : OPEN CASCADE
 // File:      GLViewer_ViewPort2d.cxx
 // Created:   November, 2004
-// Author:    OCC team
-// Copyright (C) CEA 2004
-
+//
 /* GLViewer_ViewPort2d Source File */
 
+//#include <GLViewerAfx.h>
 #include "GLViewer_ViewPort2d.h"
 #include "GLViewer_Viewer2d.h"
 #include "GLViewer_ViewFrame.h"
+#include "GLViewer_MimeData.h"
 #include "GLViewer_Context.h"
-#include "GLViewer_Object.h"
-#include "QtxToolTip.h"
-
-//#include "QAD_Desktop.h"
-
-#include <Precision.hxx>
-
-#include <cmath>
-using namespace std;
-//#include <math.h>
-//#include <stdlib.h>
-//#include <iostream.h>
-
-#include <qevent.h>
-#include <qrect.h>
-#include <qlayout.h>
-#include <qpopupmenu.h>
-#include <qimage.h>
-#include <qtooltip.h>
-#include <qapplication.h>
-#include <qclipboard.h>
-#include <qpainter.h>
-#include <qbitmap.h>
-
-/***************************************************************************
-**  Class:   GLViewer_RectangularGrid
-**  Descr:   OpenGL Grid for GLViewer_ViewPort2d
-**  Module:  GLViewer
-**  Created: UI team, 16.09.02
-****************************************************************************/
-
-#define SEGMENTS   20
-#define STEP       2*PI/SEGMENTS
-#define XSIZE      100
-#define YSIZE      100
-#define MIN_SIZE   1
-
-GLViewer_RectangularGrid::GLViewer_RectangularGrid() :
-       myGridList( -1 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
-       myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
-       myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
-       myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLint)5.0 ), 
-       myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
-{
-  myGridColor[0] = 0.5;
-  myGridColor[1] = 0.5;
-  myGridColor[2] = 0.5;
-  myAxisColor[0] = 0.75;
-  myAxisColor[1] = 0.75;
-  myAxisColor[2] = 0.75;
-}
-
-GLViewer_RectangularGrid::GLViewer_RectangularGrid( GLfloat width, GLfloat height,
-                          GLfloat winW, GLfloat winH,
-                          GLfloat xSize, GLfloat ySize,
-                          GLfloat xPan, GLfloat yPan,
-                          GLfloat xScale, GLfloat yScale ) :
-       myGridList( -1 ), myGridHeight( (GLfloat)0.0 ), myGridWidth( (GLfloat)0.0 ),
-       myWinW( (GLfloat)0.0 ), myWinH( (GLfloat)0.0 ), myXSize( (GLfloat)0.0 ), myYSize( (GLfloat)0.0 ),
-       myXPan( (GLfloat)0.0 ), myYPan( (GLfloat)0.0 ), myXScale( (GLfloat)1.0 ), myYScale( (GLfloat)1.0 ),
-       myLineWidth( (GLfloat)0.05 ), myCenterWidth( (GLfloat)1.5 ), myCenterRadius( (GLint)5.0 ), 
-       myScaleFactor( 10 ), myIsUpdate( GL_FALSE )
-{
-  myGridColor[0] = 0.5;
-  myGridColor[1] = 0.5;
-  myGridColor[2] = 0.5;
-  myAxisColor[0] = 0.75;
-  myAxisColor[1] = 0.75;
-  myAxisColor[2] = 0.75;
-}
-
-GLViewer_RectangularGrid::~GLViewer_RectangularGrid()
-{
-}
-
-void GLViewer_RectangularGrid::draw()
-{
-  if ( myGridList == -1 || myIsUpdate )
-    initList();
-
-  glCallList( myGridList );
-}
-
-void GLViewer_RectangularGrid::setGridColor( GLfloat r, GLfloat g, GLfloat b )
-{
-  if( myGridColor[0] == r && myGridColor[1] == g && myGridColor[2] == b )
-    return;
-
-  myGridColor[0] = r;
-  myGridColor[1] = g;
-  myGridColor[2] = b;
-  myIsUpdate = GL_TRUE;
-}
-
-void GLViewer_RectangularGrid::setAxisColor( GLfloat r, GLfloat g, GLfloat b )
-{
-  if( myAxisColor[0] == r && myAxisColor[1] == g && myAxisColor[2] == b )
-    return;
-
-  myAxisColor[0] = r;
-  myAxisColor[1] = g;
-  myAxisColor[2] = b;
-  myIsUpdate = GL_TRUE;
-}
-
-void GLViewer_RectangularGrid::setGridWidth( float w )
-{
-  if( myGridWidth == w )
-    return;
-
-  myGridWidth = w;
-  myIsUpdate = GL_TRUE;
-}
-
-void GLViewer_RectangularGrid::setCenterRadius( int r )
-{
-  if( myCenterRadius == r )
-    return;
-
-  myCenterRadius = r;
-  myIsUpdate = GL_TRUE;
-}
-
-void GLViewer_RectangularGrid::setSize( float xSize, float ySize )
-{
-  if( myXSize == xSize && myYSize == ySize )
-    return;
-  
-  myXSize = xSize;
-  myYSize = ySize;
-  myIsUpdate = GL_TRUE;
-}
-
-void GLViewer_RectangularGrid::setPan( float xPan, float yPan )
-{
-  if( myXPan == xPan && myYPan == yPan )
-    return;
-  myXPan = xPan;
-  myYPan = yPan;
-  myIsUpdate = GL_TRUE; 
-}
-
-bool GLViewer_RectangularGrid::setZoom( float zoom )
-{
-  if( zoom == 1.0 )
-    return true;
-  
-  //backup values
-  float bXScale = myXScale;
-  float bYScale = myYScale;
-
-  myXScale /= zoom; 
-  myYScale /= zoom;
-
-  if( fabs(myXScale) < Precision::Confusion() || fabs(myYScale) < Precision::Confusion() )
-  { //undo
-    myXScale = bXScale;
-    myYScale = bYScale;
-    return false;
-  }
-  
-  myGridWidth /= zoom; 
-  myGridHeight /= zoom;  
-  myIsUpdate = GL_TRUE;
-  return true;
-}
-
-void GLViewer_RectangularGrid::setResize( float WinW, float WinH, float zoom )
-{
-  if( myWinW == WinW && myWinH == WinH && zoom == 1.0 )
-    return;
-
-  myGridWidth = myGridWidth + ( WinW - myWinW ) * myXScale; 
-  myGridHeight = myGridHeight + ( WinH - myWinH ) * myYScale;
-  myWinW = WinW;
-  myWinH = WinH;
-  setZoom( zoom );
-  myIsUpdate = GL_TRUE;
-}
-
-void GLViewer_RectangularGrid::getSize( float& xSize, float& ySize ) const
-{
-  xSize = myXSize;
-  ySize = myYSize;
-}
-
-void GLViewer_RectangularGrid::getPan( float& xPan, float& yPan ) const
-{
-  xPan = myXPan;
-  yPan = myYPan;
-}
-
-void GLViewer_RectangularGrid::getScale( float& xScale, float& yScale ) const
-{
-  xScale = myXScale;
-  yScale = myYScale;
-}
-
-bool GLViewer_RectangularGrid::initList()
-{
-  myIsUpdate = GL_FALSE;
-  int n, m; 
-  float xLoc, yLoc; 
-  int xLoc1, yLoc1; 
-   
-    if( myXSize == (GLfloat)0.0 )
-        myXSize = (GLfloat)0.1;
-    if( myYSize == (GLfloat)0.0 )
-        myYSize = (GLfloat)0.1;
-
-label:
-  if( ( myXSize >= myGridWidth/5 ) && ( myYSize >= myGridHeight/5 ) )
-  { //zoom in
-    myXSize /= myScaleFactor;
-    myYSize /= myScaleFactor;
-    goto label;
-  }
-  else if( ( myXSize * myScaleFactor < myGridWidth/5 ) 
-        || ( myYSize * myScaleFactor < myGridHeight/5 ) )
-  { //zoom out
-    myXSize *= myScaleFactor;
-    myYSize *= myScaleFactor;
-    goto label;
-  }
-
-  n = ( int )( myGridWidth / myXSize );
-  m = ( int )( myGridHeight / myYSize );
-        
-  if( ( n != 0 ) || ( m != 0 ) ) 
-  { 
-    if ( myGridList != -1 )  
-    { 
-      glDeleteLists( myGridList, 1 ); 
-      if ( glGetError() != GL_NO_ERROR ) 
-    return FALSE;
-    } 
-         
-    xLoc1 = ( int )( myXPan / myXSize ); 
-    yLoc1 = ( int )( myYPan / myYSize ); 
-
-    xLoc = xLoc1 * myXSize; 
-    yLoc = yLoc1 * myYSize; 
-    myGridList = glGenLists( 1 ); 
-    glNewList( myGridList, GL_COMPILE ); 
-
-    glColor3f( myGridColor[0], myGridColor[1], myGridColor[2] );  
-    glLineWidth( myLineWidth ); 
-    
-    glBegin( GL_LINES ); 
-    for( int j = 0; ( j-1 ) * myXSize <= myGridWidth / 2 ; j++ )
-    { 
-      glVertex2d( -myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
-      glVertex2d( -myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc ); 
-      glVertex2d(  myXSize * j - xLoc, -myGridHeight / 2 - myYSize - yLoc );
-      glVertex2d(  myXSize * j - xLoc,  myGridHeight / 2 + myYSize - yLoc );
-    }
-    for( int i = 0; ( i-1 ) * myYSize <= myGridHeight / 2 ; i++)  
-    {
-      glVertex2d( -myGridWidth / 2 - myXSize - xLoc, -myYSize * i - yLoc ); 
-      glVertex2d(  myGridWidth / 2 + myXSize - xLoc, -myYSize * i - yLoc ); 
-      glVertex2d( -myGridWidth / 2 - myXSize - xLoc,  myYSize * i - yLoc ); 
-      glVertex2d(  myGridWidth / 2 + myXSize - xLoc,  myYSize * i - yLoc ); 
-    } 
-    glEnd();
-
-    glColor3f( myAxisColor[0], myAxisColor[1], myAxisColor[2] );
-    glLineWidth( myCenterWidth );
-
-    glBegin( GL_LINES );
-    glVertex2d(  myGridWidth / 2 + myXSize - xLoc, 0); 
-    glVertex2d( -myGridWidth / 2 - myXSize - xLoc, 0); 
-    glVertex2d( 0,  myGridHeight / 2 + myYSize - yLoc );
-    glVertex2d( 0, -myGridHeight / 2 - myYSize - yLoc );    
-    glEnd();
-
-    glBegin( GL_LINE_LOOP ); 
-    double angle = 0.0;
-    for ( int k = 0; k < SEGMENTS; k++ )     
-    { 
-      glVertex2f( cos(angle) * myCenterRadius * myXScale,
-          sin(angle) * myCenterRadius * myYScale ); 
-      angle += STEP; 
-    } 
-    glEnd();
-
-    glEndList();
-  }
-  return TRUE;
-}
-/***************************************************************************
-**  Class:   GLViewer_Compass
-**  Descr:   OpenGL Compass for ViewPort 2D
-**  Module:  GLViewer
-**  Created: UI team, 29.03.04
-****************************************************************************/
-GLViewer_Compass::GLViewer_Compass ( const QColor& color, const int size, const Position pos,
-                               const int WidthTop, const int WidthBottom, const int HeightTop,
-                               const int HeightBottom ){
-    myCol = color;
-    mySize = size;
-    myPos = pos;
-    myArrowWidthTop = WidthTop;
-    myArrowWidthBottom = WidthBottom;
-    myArrowHeightTop = HeightTop;
-    myArrowHeightBottom = HeightBottom;
-    myIsVisible = true;
-    QFont* aFont = new QFont("Times",16);
-    myFont = new GLViewer_TexFont( aFont );
-    isGenereted = false;
-    //myFont->generateTexture();
-}
-
-GLViewer_TexFont* GLViewer_Compass::getFont()
-{ 
-    if(!isGenereted) 
-    {
-        myFont->generateTexture();
-        isGenereted = true;
-    }    
-    return myFont;
-}
-
-
-/***************************************************************************
-**  Class:   GLViewer_ViewPort2d
-**  Descr:   OpenGL ViewPort 2D
-**  Module:  GLViewer
-**  Created: UI team, 02.09.02
-****************************************************************************/
-
-#define WIDTH    640
-#define HEIGHT   480
-#define MARGIN   10
+#include "GLViewer_Compass.h"
+#include "GLViewer_Grid.h"
+#include "GLViewer_Drawer.h"
+
+// TODO: Porting to Qt4
+//#include <QtxToolTip.h>
+
+#include <QHBoxLayout>
+#include <QMouseEvent>
+#include <QRect>
+//#include <QMenu>
+//#include <QToolTip>
+#include <QApplication>
+#include <QClipboard>
+#include <QBitmap>
+#include <QLabel>
+#include <QWidget>
+#include <QRubberBand>
+
+#define WIDTH       640
+#define HEIGHT      480
+#define MARGIN      100
+
+#define GRID_XSIZE  100
+#define GRID_YSIZE  100
 
 int static aLastViewPostId = 0;
 
@@ -355,48 +68,59 @@ void rotate_point( float& theX, float& theY, float theAngle )
     theY = aTempY;
 }
 
-GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame ) :
-       GLViewer_ViewPort( parent ),
-       myMargin( MARGIN ), myWidth( WIDTH ), myHeight( HEIGHT ),
-       myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
-       myXPan( 0.0 ), myYPan( 0.0 )
+/*!
+  Constructor
+*/
+GLViewer_ViewPort2d::GLViewer_ViewPort2d( QWidget* parent, GLViewer_ViewFrame* theViewFrame )
+: GLViewer_ViewPort( parent ),
+  myMargin( MARGIN ), myHeight( HEIGHT ), myWidth( WIDTH ),
+  myXScale( 1.0 ), myYScale( 1.0 ), myXOldScale( 1.0 ), myYOldScale( 1.0 ),
+  myXPan( 0.0 ), myYPan( 0.0 ),
+  myIsMouseReleaseBlock( false ),
+  myRectBand( 0 )
 {
-    if( theViewFrame == NULL )
-        myViewFrame = ( GLViewer_ViewFrame* )parent;
-    else
-        myViewFrame = theViewFrame;
+  if ( !theViewFrame )
+    myViewFrame = (GLViewer_ViewFrame*)parent;
+  else
+    myViewFrame = theViewFrame;
 
-    myBorder = new QRect(0,0,0,0);
-    myGrid = NULL;
-    QBoxLayout* qbl = new QHBoxLayout( this );
-    myGLWidget = new GLViewer_Widget( this, 0 ) ;
-    qbl->addWidget( myGLWidget );
-    myGLWidget->setFocusProxy( this );
-    setMouseTracking( TRUE );
+  myGrid = 0;
+  myCompass = 0;
+  myBorder = new GLViewer_Rect();
 
-    myIsDragProcess = noDrag;
-    //myCurDragMousePos = QPoint();
-    myCurDragPosX = NULL;
-    myCurDragPosY = NULL;
+  QBoxLayout* qbl = new QHBoxLayout( this );
+  qbl->setSpacing( 0 );
+  qbl->setMargin( 0 );
 
-    myCompass = 0;
-    //myCompass = new GLViewer_Compass();
-    //myCompass = new GLViewer_Compass( Qt::green, 30, GLViewer_Compass::TopRight, 10, 5, 12, 3 );
+  myGLWidget = new GLViewer_Widget( this, 0 ) ;
+  qbl->addWidget( myGLWidget );
+  myGLWidget->setFocusProxy( this );
+  setMouseTracking( true );
 
-    myIsPulling = false;
+  myIsDragProcess = noDrag;
+  //myCurDragMousePos = QPoint();
+  myCurDragPosX = NULL;
+  myCurDragPosY = NULL;
+
+  myIsPulling = false;
 
-    myViewPortId = aLastViewPostId;
-    aLastViewPostId++;
+  myViewPortId = aLastViewPostId;
+  aLastViewPostId++;
 
-    mypFirstPoint = NULL;
-    mypLastPoint = NULL;
+  mypFirstPoint = NULL;
+  mypLastPoint = NULL;
 
-    myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
+    // TODO: Porting to Qt4
+    /*myObjectTip = new QtxToolTip( myGLWidget );///GLViewer_ObjectTip( this );
+    myObjectTip->setShowDelayTime( 60000 );
     connect( myObjectTip, SIGNAL( maybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ),
-             this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );
+             this, SLOT( onMaybeTip( QPoint, QString&, QFont&, QRect&, QRect& ) ) );*/
 //    myGLWidget->installEventFilter( myObjectTip );
 }
 
+/*!
+  Destructor
+*/
 GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
 {
     if( myCompass )
@@ -407,240 +131,40 @@ GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
 
     delete myBorder;
     delete myGLWidget;
-}
-
-void GLViewer_ViewPort2d::onCreatePopup()
-{
-    //cout << "GLViewer_ViewPort2d::onCreatePopup" << endl;
-
-    //QAD_Desktop* desktop = (QAD_Desktop*) QAD_Application::getDesktop();
-    
-    QString theContext;
-    QString theParent("Viewer");
-    QString theObject;
-    
-    //desktop->definePopup( theContext, theParent, theObject );
-    //desktop->createPopup( myPopup, theContext, theParent, theObject);
-    //desktop->customPopup( myPopup, theContext, theParent, theObject );
-
-    /*
-    if ( myPopup->count() > 0 )
-      myIDs.append ( myPopup->insertSeparator() );  
-    int id;
-    myIDs.append ( id = myPopup->insertItem (tr ("MEN_VP3D_CHANGEBGR")) );  
-    QAD_ASSERT ( myPopup->connectItem ( id, this, SLOT(onChangeBackgroundColor())) );
-    */
-    
-    /*
-    if ( myPopup )
-    {
-        GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
-
-        QAD_ASSERT( myPopupActions.isEmpty() );
-
-        QAction* a = new QAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
-        a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
-        connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor() ) );
-        myPopupActions.append( a );
-        a->addTo( myPopup );        
-
-        myPopup->insertSeparator();
 
-        a = new QAction( "", tr( "MEN_VP_CREATE_GLMARKERS" ), 0, this );
-        a->setStatusTip( tr( "PRP_VP_CREATE_GLMARKERS" ) );
-        connect( a, SIGNAL( activated() ), aViewer, SLOT( onCreateGLMarkers() ) );
-        myPopupActions.append( a );
-        a->addTo( myPopup );        
-
-        a = new QAction( "", tr( "MEN_VP_CREATE_GLPOLYLINE" ), 0, this );
-        a->setStatusTip( tr( "PRP_VP_CREATE_GLPOLYLINE" ) );
-        connect( a, SIGNAL( activated() ), aViewer, SLOT( onCreateGLPolyline() ) );
-        myPopupActions.append( a );
-        a->addTo( myPopup );        
-
-        a = new QAction( "", tr( "MEN_VP_CREATE_GLTEXT" ), 0, this );
-        a->setStatusTip( tr( "PRP_VP_CREATE_GLTEXT" ) );
-        connect( a, SIGNAL( activated() ), aViewer, SLOT( onCreateGLText() ) );
-        myPopupActions.append( a );
-        a->addTo( myPopup );        
-
-        myPopup->insertSeparator();
-
-        //GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
-        int aSelObjects = aViewer->getGLContext()->NbSelected();
-        if( aSelObjects > 0 )
-        {
-            a = new QAction( "", tr( "MEN_VP_CUTOBJ" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_CUTOBJ" ) );
-            connect( a, SIGNAL( activated() ), SLOT( onCutObject() ) );
-            myPopupActions.append( a );
-            a->addTo( myPopup );
-
-            a = new QAction( "", tr( "MEN_VP_COPYOBJ" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_COPYOBJ" ) );
-            connect( a, SIGNAL( activated() ), SLOT( onCopyObject() ) );
-            myPopupActions.append( a );
-            a->addTo( myPopup );
-        }
-
-        a = new QAction( "", tr( "MEN_VP_PASTEOBJ" ), 0, this );
-        a->setStatusTip( tr( "PRP_VP_PASTEOBJ" ) );
-        connect( a, SIGNAL( activated() ), SLOT( onPasteObject() ) );
-        myPopupActions.append( a );
-        a->addTo( myPopup );
-
-        QClipboard *aClipboard = QApplication::clipboard();
-        QMimeSource* aMimeSource = aClipboard->data();
-        if( !aMimeSource->provides( "GLViewer_Objects" ) )
-            a->setEnabled( false );
-        
-    
-        if( aSelObjects > 0 )
-        {
-            myPopup->insertSeparator();
-            a = new QAction( "", tr( "MEN_VP_DRAGOBJ" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_DRAGOBJ" ) );
-            connect( a, SIGNAL( activated() ), SLOT( onStartDragObject() ) );
-            myPopupActions.append( a );
-            a->addTo( myPopup );
-            myCurDragPosX = new float((float)QCursor::pos().x());
-            myCurDragPosY = new float((float)QCursor::pos().y());
-            //myCurDragMousePos = QCursor::pos();            
-        }
-    }
-    */
+    if ( myRectBand ) myRectBand->hide();
+    delete myRectBand;
 }
 
-void GLViewer_ViewPort2d::onCreatePopup( QPopupMenu* popup )
-{
-/*
-    if ( popup )
-    {
-        GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
-        if( !aViewer->isSketchingActive() )
-        {
-            if( !myPopupActions.isEmpty() )
-                return;
-            QAction* a = new QAction( "", tr( "MEN_VP_CHANGEBGR" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_CHANGEBGR" ) );
-            connect( a, SIGNAL( activated() ), SLOT( onChangeBgColor() ) );
-            myPopupActions.append( a );
-            a->addTo( popup );        
-
-            popup->insertSeparator();
-
-            //GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
-            int aSelObjects = aViewer->getGLContext()->NbSelected();
-            if( aSelObjects > 0 )
-            {
-                a = new QAction( "", tr( "MEN_VP_CUTOBJ" ), 0, this );
-                a->setStatusTip( tr( "PRP_VP_CUTOBJ" ) );
-                connect( a, SIGNAL( activated() ), SLOT( onCutObject() ) );
-                myPopupActions.append( a );
-                a->addTo( popup );
-
-                a = new QAction( "", tr( "MEN_VP_COPYOBJ" ), 0, this );
-                a->setStatusTip( tr( "PRP_VP_COPYOBJ" ) );
-                connect( a, SIGNAL( activated() ), SLOT( onCopyObject() ) );
-                myPopupActions.append( a );
-                a->addTo( popup );
-            }
-
-            a = new QAction( "", tr( "MEN_VP_PASTEOBJ" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_PASTEOBJ" ) );
-            connect( a, SIGNAL( activated() ), SLOT( onPasteObject() ) );
-            myPopupActions.append( a );
-            a->addTo( popup );
-
-            QClipboard *aClipboard = QApplication::clipboard();
-            QMimeSource* aMimeSource = aClipboard->data();
-            if( !aMimeSource->provides( "GLViewer_Objects" ) )
-                a->setEnabled( false );
-            
-        
-            if( aSelObjects > 0 )
-            {
-                popup->insertSeparator();
-                a = new QAction( "", tr( "MEN_VP_DRAGOBJ" ), 0, this );
-                a->setStatusTip( tr( "PRP_VP_DRAGOBJ" ) );
-                connect( a, SIGNAL( activated() ), SLOT( onStartDragObject() ) );
-                myPopupActions.append( a );
-                a->addTo( popup );
-                myCurDragPosX = new float((float)QCursor::pos().x());
-                myCurDragPosY = new float((float)QCursor::pos().y());
-                //myCurDragMousePos = QCursor::pos();            
-            }
-        }
-        else
-        {//sketching mode
-            QAD_ASSERT( myPopupActions.isEmpty() );
-            QAction* a = new QAction( "", tr( "MEN_VP_SKETCH_DEL_OBJECT" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_SKETCH_DEL_OBJECT" ) );
-            connect( a, SIGNAL( activated() ), aViewer, SLOT( onSketchDelObject() ) );
-            myPopupActions.append( a );
-            a->addTo( popup );        
-
-            popup->insertSeparator();
-
-            a = new QAction( "", tr( "MEN_VP_SKETCH_UNDO_LAST" ), 0, this );
-            a->setStatusTip( tr( "PRP_VP_SKETCH_UNDO_LAST" ) );
-            connect( a, SIGNAL( activated() ), aViewer, SLOT( onSketchUndoLast() ) );
-            myPopupActions.append( a );
-            a->addTo( popup );
-
-            int aSkType = aViewer->getSketchingType();
-            if( ( aSkType == GLViewer_Viewer2d::Polyline ) || 
-                ( aSkType == GLViewer_Viewer2d::Curve) ||
-                ( aSkType == GLViewer_Viewer2d::Scribble ) )
-            {
-                a = new QAction( "", tr( "MEN_VP_SKETCH_FINISH" ), 0, this );
-                a->setStatusTip( tr( "PRP_VP_SKETCH_FINISH" ) );
-                connect( a, SIGNAL( activated() ), aViewer, SLOT( onSketchFinish() ) );
-                myPopupActions.append( a );
-                a->addTo( popup );
-            }
-        }
-    }
-*/
-}
-    
-void GLViewer_ViewPort2d::onDestroyPopup( QPopupMenu* popup )
-{
-/*
-    if ( popup )
-    {
-        for ( QAction* a = myPopupActions.first(); a; a = myPopupActions.next() )
-            a->removeFrom( popup );
-        myPopupActions.clear();
-        popup->clear();
-    }
+/*!
+  SLOT: initializes drag process
 */
-}
-
-
 void GLViewer_ViewPort2d::onStartDragObject( )
 {
     if( myIsDragProcess == noDrag )
     {
         myIsDragProcess = initDrag;
-        QCursor::setPos( ( int )( *myCurDragPosX ), ( int )( *myCurDragPosY ) );
+        QCursor::setPos( (int)(*myCurDragPosX), (int)(*myCurDragPosY) );
         //myCurDragMousePos = QPoint( 0, 0 );
         delete myCurDragPosX;
         delete myCurDragPosY;
         myCurDragPosX = NULL;
         myCurDragPosY = NULL;
         return;
-    } 
+    }
 }
 
+/*!
+  SLOT: cuts object to clipboard
+*/
 void GLViewer_ViewPort2d::onCutObject()
-{ 
+{
     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
-    if( aMovingObject )    
-    {        
+    if( aMovingObject )
+    {
         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
         aMimeSource->setObject( aMovingObject );
-        
+
         QClipboard *aClipboard = QApplication::clipboard();
         aClipboard->clear();
         aClipboard->setData( aMimeSource );
@@ -651,31 +175,34 @@ void GLViewer_ViewPort2d::onCutObject()
     int aObjNum = aContext->NbSelected();
     if( aObjNum > 0 )
     {
-        QValueList<GLViewer_Object*> aObjects;
-        GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
+        QList<GLViewer_Object*> aObjects;
+        GLViewer_MimeData* aMimeData = new GLViewer_MimeData();
         aContext->InitSelected();
         for( ; aContext->MoreSelected(); aContext->NextSelected() )
             aObjects.append( aContext->SelectedObject() );
 
-        //aMimeSource->setObjects( aObjects ); ouv 6.05.04
+        //aMimeData->setObjects( aObjects ); ouv 6.05.04
 
         QClipboard *aClipboard = QApplication::clipboard();
         aClipboard->clear();
-        aClipboard->setData( aMimeSource );
+        aClipboard->setMimeData( aMimeData );
 
         for( int i = 0; i < aObjNum; i++ )
             aContext->deleteObject( aObjects[i] );
     }
 }
 
+/*!
+  SLOT: copies object to clipboard
+*/
 void GLViewer_ViewPort2d::onCopyObject()
 {
     /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
-    if( aMovingObject )    
-    {        
+    if( aMovingObject )
+    {
         GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
         aMimeSource->setObject( aMovingObject );
-        
+
         QClipboard *aClipboard = QApplication::clipboard();
         aClipboard->clear();
         aClipboard->setData( aMimeSource );
@@ -685,20 +212,23 @@ void GLViewer_ViewPort2d::onCopyObject()
     int aObjNum = aContext->NbSelected();
     if( aObjNum > 0 )
     {
-        QValueList<GLViewer_Object*> aObjects;
-        GLViewer_MimeSource* aMimeSource = new GLViewer_MimeSource();
+        QList<GLViewer_Object*> aObjects;
+        GLViewer_MimeData* aMimeData = new GLViewer_MimeData();
         aContext->InitSelected();
         for( ; aContext->MoreSelected(); aContext->NextSelected() )
             aObjects.append( aContext->SelectedObject() );
 
-        //aMimeSource->setObjects( aObjects ); ouv 6.05.04
+        //aMimeData->setObjects( aObjects ); ouv 6.05.04
 
         QClipboard *aClipboard = QApplication::clipboard();
         aClipboard->clear();
-        aClipboard->setData( aMimeSource );
+        aClipboard->setMimeData( aMimeData );
     }
 }
 
+/*!
+  SLOT: pastes object from clipboard
+*/
 void GLViewer_ViewPort2d::onPasteObject()
 {
     /*QClipboard *aClipboard = QApplication::clipboard();
@@ -723,18 +253,18 @@ void GLViewer_ViewPort2d::onPasteObject()
         GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
         if( !aObject )
             return;
-        
+
         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
     }
     */
-    //QClipboard *aClipboard = QApplication::clipboard();
-    //QMimeSource* aMimeSource = aClipboard->data();
-
     /* ouv 6.05.04
+    QClipboard *aClipboard = QApplication::clipboard();
+
+    QMimeSource* aMimeSource = aClipboard->data();
     if( aMimeSource->provides( "GLViewer_Objects" ) )
     {
         QByteArray anArray = aMimeSource->encodedData( "GLViewer_Objects" );
-        QValueList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
+        QList<GLViewer_Object*> aObjects = GLViewer_MimeSource::getObjects( anArray, "GLViewer_Objects" );
         if( aObjects.empty() )
             return;
         GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
@@ -744,20 +274,23 @@ void GLViewer_ViewPort2d::onPasteObject()
     */
 }
 
+/*!
+  SLOT: called when object is being dragged
+*/
 void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
 {
   //cout << "---GLViewer_ViewPort2d::onDragObject()---" << endl;
   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
   GLViewer_Context* aContext = aViewer->getGLContext();
   GLViewer_Object* anObject = aContext->getCurrentObject();
-  
+
   if( !aContext )
     return;
 
   float aX = e->pos().x();
   float anY = e->pos().y();
   aViewer->transPoint( aX, anY );
-    
+
   if( myCurDragPosX == NULL && myCurDragPosY == NULL )
   {
     myCurDragPosX = new float(aX);
@@ -767,38 +300,29 @@ void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
 
   //QPoint aNewPos = e->pos();
   //GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
-  
-  if( anObject && (e->state() & LeftButton ) )
+
+  if( anObject && (e->buttons() & Qt::LeftButton ) )
   {
     if( aContext->isSelected( anObject ) )
     {
       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
       {
-       GLViewer_Object* aMovingObject = aContext->SelectedObject();
-       //= aViewer->getGLContext()->getCurrentObject();
-       if( aMovingObject )
-       {
-         aMovingObject->moveObject( aX - *myCurDragPosX ,
-                                    anY - *myCurDragPosY);
-         //QRect* rect = aMovingObject->getRect()->toQRect();
-         //aViewer->updateBorders( *rect );
-         aViewer->updateBorders();
-       }
+        GLViewer_Object* aMovingObject = aContext->SelectedObject();
+        if( aMovingObject )
+          aMovingObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
       }
     }
     else
       anObject->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
   }
-  else if( aContext->NbSelected() && (e->state() & MidButton ) )
+  else if( aContext->NbSelected() && (e->buttons() & Qt::MidButton ) )
     for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
-      (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
-  
-  aViewer->updateBorders();
+        (aContext->SelectedObject())->moveObject( aX - *myCurDragPosX, anY - *myCurDragPosY);
 
   delete myCurDragPosX;
   delete myCurDragPosY;
   myCurDragPosX = new float(aX);
-  myCurDragPosY = new float(anY);    
+  myCurDragPosY = new float(anY);
 
   myGLWidget->updateGL();
 }
@@ -806,30 +330,22 @@ void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
 /*!
     Emits 'mouseEvent' signal. [ virtual protected ]
 */
-void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent *e )
+void GLViewer_ViewPort2d::mousePressEvent( QMouseEvente )
 {
-    
-    //if(  )
-    /*GLViewer_Object* aMovingObject = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->getCurrentObject();
-    if( aMovingObject )
-    {
-        onStartDragObject();
-    }*/
     emit vpMouseEvent( e );
-    
-    GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
+
+    GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
     GLViewer_Context* aContext = aViewer->getGLContext();
 
     GLViewer_Object* anObject = NULL;
     if( aContext )
-      anObject = aContext->getCurrentObject();
-    
-    bool accel = e->state() & GLViewer_ViewTransformer::accelKey();
-    if( ( anObject && !( accel || e->button() == Qt::RightButton ) )
-        ||
+        anObject = aContext->getCurrentObject();
+
+    bool accel = e->modifiers() & GLViewer_ViewTransformer::accelKey();
+    if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
         ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton )  )
-    {       
-      myIsDragProcess = inDrag;
+    {
+        myIsDragProcess = inDrag;
     }
 }
 
@@ -838,16 +354,14 @@ void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent *e )
 */
 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
 {
-    //GLViewer_Context* context = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
-    //if( context->getCurrentObject() ) cout << "LASTPICKED" << endl;
     emit vpMouseEvent( e );
-    
-    GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
-    GLViewer_Context* aContext = aViewer->getGLContext();
 
     if( myIsDragProcess == inDrag )
         onDragObject( e );
-    
+
+    /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
+    GLViewer_Context* aContext = aViewer->getGLContext();
+
     GLViewer_Object* anObj = aContext->getCurrentObject();
     if( anObj && aContext->currentObjectIsChanged() )
     {
@@ -863,34 +377,20 @@ void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
         //QRect* aRect = (aViewer->getWinObjectRect(anObj));
         //QToolTip::remove( myGLWidget, *aRect );
         myGLWidget->removeToolTip();
-    }
+    }*/
 }
 
 /*!
     Emits 'mouseEvent' signal. [ virtual protected ]
 */
-void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent *e )
+void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvente )
 {
-  /*if( myIsDragProcess == inDrag )
+    if ( myIsMouseReleaseBlock )
     {
-        GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
-        GLViewer_Context* aContext = aViewer->getGLContext();
-        for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
-        {
-            GLViewer_Object* aMovingObject = aContext->SelectedObject();
-            if( aMovingObject )
-                aMovingObject->finishMove();
-        }
-
-        myIsDragProcess = noDrag;
-        //yCurDragMousePos.setX( 0 );
-        //myCurDragMousePos.setY( 0 );
-        delete myCurDragPosX;
-        delete myCurDragPosY;
-        myCurDragPosX = NULL;
-        myCurDragPosY = NULL;
-       }*/
-    
+      // skip mouse release after double click
+      myIsMouseReleaseBlock = false;
+      return;
+    }
 
     /* show popup menu */
     if ( e->button() == Qt::RightButton )
@@ -901,37 +401,55 @@ void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent *e )
         //destroyPopup( /*popup*/ );
     }
     emit vpMouseEvent( e );
-    
+
     if( myIsDragProcess == inDrag )
     {
       bool isAnyMoved = false;
       GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
       GLViewer_Context* aContext = aViewer->getGLContext();
+      GLViewer_Object* aMovingObject;
       for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
       {
-        GLViewer_Object* aMovingObject = aContext->SelectedObject();
+        aMovingObject = aContext->SelectedObject();
         if( aMovingObject )
-        {
-          aMovingObject->finishMove();
-          isAnyMoved = true;
-        }
+          isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
       }
-      
-      GLViewer_Object* anObject = aContext->getCurrentObject();
-      if( anObject )
-        anObject->finishMove();
-      
+
+      aMovingObject = aContext->getCurrentObject();
+      if( aMovingObject )
+        isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
+
       myIsDragProcess = noDrag;
-      //yCurDragMousePos.setX( 0 );
+      //myCurDragMousePos.setX( 0 );
       //myCurDragMousePos.setY( 0 );
       delete myCurDragPosX;
       delete myCurDragPosY;
       myCurDragPosX = NULL;
       myCurDragPosY = NULL;
-      emit objectMoved();
+
+      if( isAnyMoved )
+      {
+        emit objectMoved();
+        aViewer->updateBorders();
+      }
     }
 }
 
+/*!
+  Custom mouse double click event handler
+*/
+void GLViewer_ViewPort2d::mouseDoubleClickEvent( QMouseEvent * e )
+{
+  //redefined to block mouse release after mouse double click
+  myIsMouseReleaseBlock = true;
+  // invoke base implementation
+  GLViewer_ViewPort::mouseDoubleClickEvent( e );
+}
+
+/*!
+  Creates or deletes compass
+  \param on - if it is true, then to create
+*/
 void GLViewer_ViewPort2d::turnCompass( GLboolean on )
 {
     if( on )
@@ -940,18 +458,29 @@ void GLViewer_ViewPort2d::turnCompass( GLboolean on )
         delete myCompass;
 }
 
+/*!
+  Creates or deletes grid
+  \param on - if it is true, then to create
+*/
 void GLViewer_ViewPort2d::turnGrid( GLboolean on )
 {
     if( on )
-      myGrid = new GLViewer_RectangularGrid( 2*WIDTH, 2*HEIGHT,
-                                            2*WIDTH, 2*HEIGHT, 
-                                            XSIZE, YSIZE,
-                                            myXPan, myYPan,
-                                            myXScale, myYScale );
+    {
+        myGrid = new GLViewer_Grid( 2*WIDTH, 2*HEIGHT,
+                                    2*WIDTH, 2*HEIGHT,
+                                    GRID_XSIZE, GRID_YSIZE,
+                                    myXPan, myYPan,
+                                    myXScale, myYScale );
+    }
     else if( myGrid )
-      delete myGrid;
+        delete myGrid;
 }
 
+/*!
+  Changes grid color
+  \param gridColor - new grid color
+  \param axisColor - new axis color
+*/
 void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axisColor )
 {
     if( myGrid )
@@ -965,6 +494,10 @@ void GLViewer_ViewPort2d::setGridColor( const QColor gridColor, const QColor axi
     }
 }
 
+/*!
+  Changes background color
+  \param color - new background color
+*/
 void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
 {
     GLViewer_ViewPort::setBackgroundColor( color );
@@ -975,11 +508,17 @@ void GLViewer_ViewPort2d::setBackgroundColor( const QColor& color )
     myGLWidget->repaint();
 }
 
+/*!
+  \return background color
+*/
 QColor GLViewer_ViewPort2d::backgroundColor() const
 {
     return GLViewer_ViewPort::backgroundColor();
 }
 
+/*!
+  Resize view
+*/
 void GLViewer_ViewPort2d::initResize( int x, int y )
 {
     float xa, xb, ya, yb;
@@ -991,38 +530,38 @@ void GLViewer_ViewPort2d::initResize( int x, int y )
     GLfloat zoom, xzoom, yzoom;
     GLfloat w = x;
     GLfloat h = y;
-    bool max = FALSE;
+    bool max = false;
 
-    xzoom = (GLfloat)x / myWidth; 
-    yzoom = (GLfloat)y / myHeight; 
+    xzoom = (GLfloat)x / myWidth;
+    yzoom = (GLfloat)y / myHeight;
 
-    if ( ( xzoom < yzoom ) && ( xzoom < 1 ) ) 
-        zoom = xzoom; 
-    else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) ) 
-        zoom = yzoom; 
-    else 
-    { 
-        max = TRUE; 
-        zoom = xzoom > yzoom ? xzoom : yzoom; 
-    } 
+    if ( ( xzoom < yzoom ) && ( xzoom < 1 ) )
+        zoom = xzoom;
+    else if ( ( yzoom < xzoom ) && ( yzoom < 1 ) )
+        zoom = yzoom;
+    else
+    {
+        max = true;
+        zoom = xzoom > yzoom ? xzoom : yzoom;
+    }
 
     if ( !max && ( ! ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
-             ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || 
+             ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
              ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
-             ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) ) 
-        zoom = 1; 
+             ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) )
+        zoom = 1;
 
     if ( max && ( ( ( myXPan + w/2 ) < xb * myXScale * zoom ) ||
-            ( ( myXPan - w/2 ) > xa * myXScale * zoom ) || 
-            ( ( myYPan + h/2 ) < yb * myYScale * zoom ) || 
-            ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) ) 
-        zoom = 1; 
+            ( ( myXPan - w/2 ) > xa * myXScale * zoom ) ||
+            ( ( myYPan + h/2 ) < yb * myYScale * zoom ) ||
+            ( ( myYPan - h/2 ) > ya * myYScale * zoom ) ) )
+        zoom = 1;
+
     myWidth = x;
-    myHeight = y; 
+    myHeight = y;
 
-    myXScale *= zoom; 
-    myYScale = myXScale; 
+    myXScale *= zoom;
+    myYScale = myXScale;
 
     if ( myGrid )
         myGrid->setResize( 2*x, 2*y, zoom );
@@ -1030,6 +569,9 @@ void GLViewer_ViewPort2d::initResize( int x, int y )
     myGLWidget->setScale( myXScale, myYScale, 1.0 );
 }
 
+/*!
+  Custom paint event handler
+*/
 void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
 {
     //cout << "GLViewer_ViewPort2d::paintEvent" << endl;
@@ -1037,28 +579,34 @@ void GLViewer_ViewPort2d::paintEvent( QPaintEvent* e )
     GLViewer_ViewPort::paintEvent( e );
 }
 
+/*!
+  Custom resize event handler
+*/
 void GLViewer_ViewPort2d::resizeEvent( QResizeEvent* e )
 {
     //cout << "GLViewer_ViewPort2d::resizeEvent" << endl;
     GLViewer_ViewPort::resizeEvent( e );
 }
 
+/*!
+  Resets view to start state
+*/
 void GLViewer_ViewPort2d::reset()
 {
     //cout << "GLViewer_ViewPort2d::reset" << endl;
 
-    GLint val[4]; 
-    GLint vpWidth, vpHeight; 
+    GLint val[4];
+    GLint vpWidth, vpHeight;
 
     myGLWidget->makeCurrent();
     glGetIntegerv( GL_VIEWPORT, val );
-    vpWidth = val[2]; 
-    vpHeight = val[3]; 
+    vpWidth = val[2];
+    vpHeight = val[3];
 
     GLint w = myGLWidget->getWidth();
     GLint h = myGLWidget->getHeight();
-    GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ? 
-                 vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h; 
+    GLfloat zoom = vpWidth / ( GLfloat )w < vpHeight / ( GLfloat )h ?
+                 vpWidth / ( GLfloat )w : vpHeight / ( GLfloat )h;
 
     if( myGrid )
     {
@@ -1078,6 +626,11 @@ void GLViewer_ViewPort2d::reset()
     myGLWidget->updateGL();
 }
 
+/*!
+  Sets offset to view
+  \param dx - X offset
+  \param dy - Y offset
+*/
 void GLViewer_ViewPort2d::pan( int dx, int dy )
 {
     //cout << "GLViewer_ViewPort2d::pan " << dx << " " << dy << endl;
@@ -1109,17 +662,21 @@ void GLViewer_ViewPort2d::pan( int dx, int dy )
     myGLWidget->updateGL();
 }
 
+/*!
+  Sets view center in global coords
+  \param x, y - global co-ordinates of center
+*/
 void GLViewer_ViewPort2d::setCenter( int x, int y )
 {
     //cout << "GLViewer_ViewPort2d::setCenter" << endl;
 
-    GLint val[4]; 
-    GLint vpWidth, vpHeight; 
+    GLint val[4];
+    GLint vpWidth, vpHeight;
 
     myGLWidget->makeCurrent();
     glGetIntegerv( GL_VIEWPORT, val );
-    vpWidth = val[2]; 
-    vpHeight = val[3]; 
+    vpWidth = val[2];
+    vpHeight = val[3];
 
     myXPan -= ( x - vpWidth/2 ) / myXScale;
     myYPan += ( y - vpHeight/2 ) / myYScale;
@@ -1138,10 +695,13 @@ void GLViewer_ViewPort2d::setCenter( int x, int y )
     myGLWidget->updateGL();
 }
 
+/*!
+  Process zoming transformation with mouse tracking from ( x0, y0 ) to ( x1, y1 )
+*/
 void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
 {
     //cout << "GLViewer_ViewPort2d::zoom" << endl;
-  
+
     float dx, dy, zm;
     dx = x - x0;
     dy = y - y0;
@@ -1149,14 +709,14 @@ void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
     if ( dx == 0. && dy == 0. )
         return;
 
-    zm = sqrt(dx * dx + dy * dy) / 100. + 1; 
-    zm = (dx > 0.) ?  zm : 1. / zm; 
+    zm = sqrt(dx * dx + dy * dy) / 100. + 1;
+    zm = (dx > 0.) ?  zm : 1. / zm;
 
     //backup values
     float bX = myXScale;
     float bY = myYScale;
-    myXScale *= zm; 
-    myYScale *= zm; 
+    myXScale *= zm;
+    myYScale *= zm;
 
     if( myGrid )
     {
@@ -1170,7 +730,7 @@ void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
         {// undo
             myXScale = bX;
             myYScale = bY;
-        } 
+        }
     }
     else
     {
@@ -1180,38 +740,37 @@ void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
     }
 }
 
+/*!
+  Transforms view by rectangle
+  \param rect - rectangle
+*/
 void GLViewer_ViewPort2d::fitRect( const QRect& rect )
 {
-    //cout << "GLViewer_ViewPort2d::fitRect" << endl;
-
     float x0, x1, y0, y1;
-    float dx, dy, zm, centerX, centerY; 
+    float dx, dy, zm, centerX, centerY;
 
-    GLint val[4]; 
-    GLint vpWidth, vpHeight; 
+    GLint val[4];
+    GLint vpWidth, vpHeight;
 
     myGLWidget->makeCurrent();
     glGetIntegerv( GL_VIEWPORT, val );
-    vpWidth = val[2]; 
-    vpHeight = val[3]; 
+    vpWidth = val[2];
+    vpHeight = val[3];
 
     x0 = rect.left();
     x1 = rect.right();
     y0 = rect.top();
     y1 = rect.bottom();
 
-    dx = fabs( x1 - x0 ); 
-    dy = fabs( y1 - y0 ); 
-    centerX = ( x0 + x1 ) / 2.; 
-    centerY = ( y0 + y1 ) / 2.; 
+    dx = fabs( x1 - x0 );
+    dy = fabs( y1 - y0 );
+    centerX = ( x0 + x1 ) / 2.;
+    centerY = ( y0 + y1 ) / 2.;
 
     if ( dx == 0. || dy == 0. )
         return;
 
-    zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
-
-    //myXPan += ( vpWidth / 2. - centerX ) / myXScale;
-    //myYPan -= ( vpHeight / 2. - centerY ) / myYScale;
+    zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
 
     float aDX = ( vpWidth / 2. - centerX ) / myXScale;
     float aDY = ( vpHeight / 2. - centerY ) / myYScale;
@@ -1237,13 +796,16 @@ void GLViewer_ViewPort2d::fitRect( const QRect& rect )
     myGLWidget->updateGL();
 }
 
+/*!
+  Transforms view by selection
+*/
 void GLViewer_ViewPort2d::fitSelect()
 {
   GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
   GLViewer_Context* aContext = aViewer->getGLContext();
   if( !aContext )
     return;
-  
+
   QRect aSelRect;
   for( aContext->InitSelected(); aContext->MoreSelected(); aContext->NextSelected() )
     aSelRect |= *(aViewer->getWinObjectRect( aContext->SelectedObject() ));
@@ -1258,7 +820,11 @@ void GLViewer_ViewPort2d::fitSelect()
   }
 }
 
-void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
+/*!
+  Transform view by view borders
+  \param keepScale - if it is true, zoom does not change
+*/
+void GLViewer_ViewPort2d::fitAll( bool keepScale, bool /*withZ*/ )
 {
     //cout << "GLViewer_ViewPort2d::fitAll" << endl;
 
@@ -1266,12 +832,12 @@ void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
     float dx, dy, zm;
     float xScale, yScale;
 
-    myMargin = QMAX( myBorder->width(), myBorder->height() ) / 10;
+    myMargin = qMax( myBorder->width(), myBorder->height() ) / 5;
 
     xa = myBorder->left() - myMargin;
     xb = myBorder->right() + myMargin;
-    ya = myBorder->top() - myMargin;
-    yb = myBorder->bottom() + myMargin;
+    ya = myBorder->bottom() - myMargin;
+    yb = myBorder->top() + myMargin;
 
     float aPoints[8] = { xa, ya, xb, ya, xa, yb, xb, yb };
 
@@ -1309,9 +875,9 @@ void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
     dx = fabs( aBorders[1] - aBorders[0] );
     dy = fabs( aBorders[3] - aBorders[2] );
 
-    myXPan = -( aBorders[0] + aBorders[1] ) / 2; 
+    myXPan = -( aBorders[0] + aBorders[1] ) / 2;
     myYPan = -( aBorders[2] + aBorders[3] ) / 2;
-    
+
 
     if( keepScale )
     {
@@ -1321,17 +887,20 @@ void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
 
     xScale = myXScale;
     yScale = myYScale;
-    zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
-    myXScale = zm; 
-    myYScale = zm;    
-    
+    if( dx && dy )
+        zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
+    else
+        zm = 1.0;
+    myXScale = zm;
+    myYScale = zm;
+
 
     if( myGrid )
     {
         myGrid->setPan( myXPan, myYPan );
         if( dx > dy )
             myGrid->setZoom(  zm / xScale );
-        else  
+        else
             myGrid->setZoom( zm / yScale );
     }
 
@@ -1343,17 +912,21 @@ void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
         emit vpUpdateValues();
 }
 
+/*!
+  Begins rotation
+  \param x, y - start point
+*/
 void GLViewer_ViewPort2d::startRotation( int x, int y )
 {
-    //cout << "GLViewer_ViewPort2d::startRotation" << endl;
-
     myGLWidget->setRotationStart( x, y, 1.0 );
 }
 
-void GLViewer_ViewPort2d::rotate( int x, int y )
+/*!
+  Performs rotation
+  \param intX, intY - current point
+*/
+void GLViewer_ViewPort2d::rotate( int intX, int intY )
 {
-    //cout << "GLViewer_ViewPort2d::rotate " << x << " " << y << endl;
-
     GLint val[4];
     GLint vpWidth, vpHeight;
 
@@ -1362,6 +935,7 @@ void GLViewer_ViewPort2d::rotate( int x, int y )
     vpWidth = val[2];
     vpHeight = val[3];
 
+    float x = intX, y = intY;
     float x0 = vpWidth/2;
     float y0 = vpHeight/2;
 
@@ -1369,10 +943,10 @@ void GLViewer_ViewPort2d::rotate( int x, int y )
     myGLWidget->getRotationStart( xs, ys, zs );
 
     xs = xs - x0;
-    x = ( int )( x - x0 );
+    x = x - x0;
     dx = x - xs;
     ys = y0 - ys;
-    y = ( int )( y0 - y );
+    y = y0 - y;
     dy = y - ys;
 
     float l1 = pow( double( xs*xs + ys*ys ), 0.5 );
@@ -1389,22 +963,7 @@ void GLViewer_ViewPort2d::rotate( int x, int y )
     float angleNew = sign * acos( ( l1*l1 + l2*l2 - l*l ) / ( 2 * l1 * l2 )) * 180. / PI;
     float angle = anglePrev + angleNew;
 
-    //GLfloat anAngle = angle * PI / 180.;
-
-    //if( myGrid )
-    //    myGrid->setPan( myXPan*cos(anAngle) + myYPan*sin(anAngle),
-    //                    -myXPan*sin(anAngle) + myYPan*cos(anAngle) );
-
-    //cout << l1 << endl;
-    //cout << l2 << endl;
-    //cout << l << endl;
-
-    //cout << xs << " " << ys << " " << x << " " << y << endl;
-    //cout << "MULTIPLICATION : " << mult << endl;
-
-    //cout << "ANGLE_PREV = " << anglePrev << endl;
-    //cout << "ANGLE_NEW = " << angleNew << endl;
-    //cout << "ANGLE = " << angle << endl;
+    // GLfloat anAngle = angle * PI / 180.; unused
 
     float ra, rx, ry, rz;
     myGLWidget->getRotation( ra, rx, ry, rz );
@@ -1412,17 +971,23 @@ void GLViewer_ViewPort2d::rotate( int x, int y )
     myGLWidget->updateGL();
 }
 
+/*!
+  Finishes rotation
+*/
 void GLViewer_ViewPort2d::endRotation()
 {
-    //cout << "GLViewer_ViewPort2d::endRotation" << endl;
-
     float ra, rx, ry, rz;
     myGLWidget->getRotation( ra, rx, ry, rz );
     myGLWidget->setRotationAngle( ra );
 }
 
-void GLViewer_ViewPort2d::drawCompass(){
-    if( !myCompass->getVisible() ) return;
+/*!
+  Draws compass
+*/
+void GLViewer_ViewPort2d::drawCompass()
+{
+    if( !myCompass->getVisible() )
+        return;
 
     GLfloat xScale, yScale, xPan, yPan;
 
@@ -1431,15 +996,15 @@ void GLViewer_ViewPort2d::drawCompass(){
 
     int cPos = myCompass->getPos();
     int cSize = myCompass->getSize();
-    QColor* cCol = &(myCompass->getColor());
+    QColor cCol = myCompass->getColor();
     int cWidthTop = myCompass->getArrowWidthTop();
     int cWidthBot = myCompass->getArrowWidthBottom();
     int cHeightTop = myCompass->getArrowHeightTop();
     int cHeightBot = myCompass->getArrowHeightBottom();
 
-    GLfloat colorR = (cCol->red())/255;
-    GLfloat colorG = (cCol->green())/255;
-    GLfloat colorB = (cCol->blue())/255;
+    GLfloat colorR = (cCol.red())/255;
+    GLfloat colorG = (cCol.green())/255;
+    GLfloat colorB = (cCol.blue())/255;
 
     float delX = cSize * 0.5;
     float delY = cSize * 0.5;
@@ -1449,7 +1014,7 @@ void GLViewer_ViewPort2d::drawCompass(){
 
     float centerX = (xPos/2 - delX - cSize)/xScale;
     float centerY = (yPos/2 - delY - cSize)/yScale;
-    
+
     switch ( cPos )
     {
     case GLViewer_Compass::TopLeft:
@@ -1464,7 +1029,7 @@ void GLViewer_ViewPort2d::drawCompass(){
             break;
         default: break;
     }
-    
+
     float ra, rx, ry, rz;
     myGLWidget->getRotation( ra, rx, ry, rz );
     GLfloat angle = ra * PI / 180.;
@@ -1476,14 +1041,14 @@ void GLViewer_ViewPort2d::drawCompass(){
     centerY -= yPan;
 
     glColor3f( colorR, colorG, colorB );
-    glBegin( GL_POLYGON );     
+    glBegin( GL_POLYGON );
     //arrow
-        x = centerX;                      y = centerY + cSize / yScale;    
+        x = centerX;                      y = centerY + cSize / yScale;
         glVertex2f( x, y );
         //point #2
         x = centerX + cWidthTop / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
         glVertex2f( x, y );
-        //point #3    
+        //point #3
         x = centerX + cWidthBot / xScale; y = centerY + ( cSize - cHeightTop ) / yScale ;
         glVertex2f( x, y );
         //point #4
@@ -1491,7 +1056,7 @@ void GLViewer_ViewPort2d::drawCompass(){
         glVertex2f( x, y );
         //point #5
         x = centerX;                      y = centerY - (cSize - cHeightBot) / yScale ;
-        glVertex2f( x, y ); 
+        glVertex2f( x, y );
         //point #6
         x = centerX - cWidthBot / xScale; y = centerY - cSize/yScale;
         glVertex2f( x, y );
@@ -1511,18 +1076,18 @@ void GLViewer_ViewPort2d::drawCompass(){
         {
             x = centerX + cos(aCircAngle) * cSize / xScale;
             y = centerY + sin(aCircAngle) * cSize / yScale;
-            glVertex2f( x, y );    
+            glVertex2f( x, y );
             aCircAngle += float( STEP ) / 2;
-        }        
-    glEnd(); 
-    
+        }
+    glEnd();
+
     GLdouble        modelMatrix[16], projMatrix[16];
     GLint           viewport[4];
     GLdouble        winxN, winyN, winz;
     GLdouble        winxE, winyE;
     GLdouble        winxS, winyS;
     GLdouble        winxW, winyW;
-    GLuint          aTextList;    
+    GLuint          aTextList;
 
     GLViewer_TexFont* aFont = myCompass->getFont();
     float widN = (float)aFont->getStringWidth( "N" );
@@ -1544,13 +1109,13 @@ void GLViewer_ViewPort2d::drawCompass(){
     glGetIntegerv (GL_VIEWPORT, viewport);
     glGetDoublev (GL_MODELVIEW_MATRIX, modelMatrix);
     glGetDoublev (GL_PROJECTION_MATRIX, projMatrix);
-    
+
     gluProject (centerX, centerY + cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxN, &winyN, &winz);
     gluProject (centerX + cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxE, &winyE, &winz);
     gluProject (centerX, centerY - cSize / yScale, 0, modelMatrix, projMatrix, viewport, &winxS, &winyS, &winz);
     gluProject (centerX - cSize / xScale, centerY, 0, modelMatrix, projMatrix, viewport, &winxW, &winyW, &winz);
 
-    glColor3f( 1.0, 1.0, 1.0 );    
+    glColor3f( 1.0, 1.0, 1.0 );
 
     aTextList = glGenLists( 1 );
     glNewList( aTextList, GL_COMPILE );
@@ -1561,7 +1126,7 @@ void GLViewer_ViewPort2d::drawCompass(){
     glOrtho(0,viewport[2],0,viewport[3],-100,100);
     glMatrixMode(GL_MODELVIEW);
     glPushMatrix();
-    glLoadIdentity();    
+    glLoadIdentity();
 
     aFont->drawString( "N", winxN + xGapN, winyN + yGapN );
     aFont->drawString( "E", winxE + xGapE, winyE + yGapE );
@@ -1575,21 +1140,28 @@ void GLViewer_ViewPort2d::drawCompass(){
 
     glEndList();
 
-    if ( aTextList != -1 ) 
+    if ( (int)aTextList != -1 )
         glCallList( aTextList );
 }
 
+/*!
+  \return blocking status for current started operations
+*/
 BlockStatus GLViewer_ViewPort2d::currentBlock()
 {
     if( myIsDragProcess == inDrag && myCurDragPosX != NULL && myCurDragPosY != NULL)
         return BlockStatus(BS_Highlighting | BS_Selection);
-    
+
     if( mypFirstPoint && mypLastPoint )
         return BlockStatus(BS_Highlighting | BS_Selection);
-    
+
     return BS_NoBlock;
 }
 
+/*!
+  Initializes rectangle selection
+  \param x, y - start point
+*/
 void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
 {
     if( !mypFirstPoint && !mypLastPoint )
@@ -1597,72 +1169,92 @@ void GLViewer_ViewPort2d::startSelectByRect( int x, int y )
         mypFirstPoint = new QPoint( x, y );
         mypLastPoint = new QPoint( x, y );
     }
+
+    if ( !myRectBand ) {
+      myRectBand = new QRubberBand( QRubberBand::Rectangle, this );
+      QPalette palette;
+      palette.setColor(myRectBand->foregroundRole(), Qt::white);
+      myRectBand->setPalette(palette);
+    }
+    myRectBand->hide();
 }
+
+/*!
+  Draws rectangle selection
+  \param x, y - current point
+*/
 void GLViewer_ViewPort2d::drawSelectByRect( int x, int y )
 {
     if( mypFirstPoint && mypLastPoint )
     {
-
-        QPainter p( getPaintDevice() );
-        p.setPen( Qt::white );
-        p.setRasterOp( Qt::XorROP );
-
-        p.drawRect( selectionRect() );    /* erase */
+        myRectBand->hide();    /* erase */
 
         mypLastPoint->setX( x );
         mypLastPoint->setY( y );
-        
-        p.drawRect( selectionRect() );    /* draw */
+
+        QRect aRect = selectionRect();
+        myRectBand->setGeometry( aRect );    /* draw */
+        myRectBand->setVisible( aRect.isValid() );
     }
 
 }
+
+/*!
+  Finishes rectangle selection
+*/
 void GLViewer_ViewPort2d::finishSelectByRect()
 {
     if( mypFirstPoint && mypLastPoint )
     {
 
-        QPainter p( getPaintDevice() );
-        p.setPen( Qt::white );
-        p.setRasterOp( Qt::XorROP );
 
-        p.drawRect( selectionRect() );    /* erase */
+        if ( myRectBand ) myRectBand->hide();    /* erase */
 
         delete mypFirstPoint;
         delete mypLastPoint;
 
         mypFirstPoint = NULL;
         mypLastPoint = NULL;
+
+        delete myRectBand;
+        myRectBand = 0;
     }
 }
 
+/*!
+  \return rectangle selection
+*/
 QRect GLViewer_ViewPort2d::selectionRect()
 {
     QRect aRect;
     if( mypFirstPoint && mypLastPoint )
     {
-        aRect.setLeft( QMIN( mypFirstPoint->x(), mypLastPoint->x() ) );
-        aRect.setTop( QMIN( mypFirstPoint->y(), mypLastPoint->y() ) );
-        aRect.setRight( QMAX( mypFirstPoint->x(), mypLastPoint->x() ) );
-        aRect.setBottom( QMAX( mypFirstPoint->y(), mypLastPoint->y() ) );
+        aRect.setLeft( qMin( mypFirstPoint->x(), mypLastPoint->x() ) );
+        aRect.setTop( qMin( mypFirstPoint->y(), mypLastPoint->y() ) );
+        aRect.setRight( qMax( mypFirstPoint->x(), mypLastPoint->x() ) );
+        aRect.setBottom( qMax( mypFirstPoint->y(), mypLastPoint->y() ) );
     }
 
     return aRect;
 }
 
+/*!
+*/
 bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
 {
     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
     GLViewer_Context* aContext = aViewer->getGLContext();
-    ObjectMap anObjects = aContext->getObjects();
+    ObjList anObjects = aContext->getObjects();
 
-    for( ObjectMap::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
+    for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
     {
-        GLViewer_Rect* aRect = it.key()->getRect();
+        GLViewer_Object* anObject = *it;
+        GLViewer_Rect aRect = anObject->getPullingRect();
 
-        if( aRect->contains( point ) && it.key()->startPulling( point ) )
+        if( aRect.contains( point ) && anObject->startPulling( point ) )
         {
             myIsPulling = true;
-            myPullingObject = it.key();
+            myPullingObject = anObject;
             setCursor( *getHandCursor() );
             return true;
         }
@@ -1671,20 +1263,26 @@ bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
     return false;
 }
 
+/*!
+*/
 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
 {
     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
     GLViewer_Context* aContext = aViewer->getGLContext();
-    ObjectMap anObjects = aContext->getObjects();
+    ObjList anObjects = aContext->getObjects();
 
     GLViewer_Object* aLockedObject = 0;
-    for( ObjectMap::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
+    for( ObjList::Iterator it = anObjects.begin(); it != anObjects.end(); ++it )
     {
-        GLViewer_Rect* aRect = it.key()->getRect();
+        GLViewer_Object* anObject = *it;
+        if( !anObject->getVisible() )
+            continue;
+
+        GLViewer_Rect aRect = anObject->getPullingRect();
 
-        if( aRect->contains( point ) && it.key()->portContains( point ) )
+        if( aRect.contains( point ) && anObject->portContains( point ) )
         {
-            aLockedObject = it.key();
+            aLockedObject = anObject;
             break;
         }
     }
@@ -1692,6 +1290,8 @@ void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
     myPullingObject->pull( point, aLockedObject );
 }
 
+/*!
+*/
 void GLViewer_ViewPort2d::finishPulling()
 {
     myIsPulling = false;
@@ -1699,6 +1299,10 @@ void GLViewer_ViewPort2d::finishPulling()
     setCursor( *getDefaultCursor() );
 }
 
+/*!
+  Convert rectangle in window co-ordinates to GL co-ordinates
+  \return converted rectangle
+*/
 GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
 {
   GLViewer_Rect aRect;
@@ -1716,7 +1320,7 @@ GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
 
   gluUnProject( theRect.left(), viewport[3] - theRect.top(), 0, modelMatrix, projMatrix, viewport, &objx1, &objy1, &objz );
   gluUnProject( theRect.right(), viewport[3] - theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &objx2, &objy2, &objz );
-  
+
   aRect.setLeft( objx1 );
   aRect.setTop( objy1 );
   aRect.setRight( objx2 );
@@ -1725,6 +1329,10 @@ GLViewer_Rect GLViewer_ViewPort2d::win2GLV( const QRect& theRect ) const
   return aRect;
 }
 
+/*!
+  Convert rectangle in GL co-ordinates to window co-ordinates
+  \return converted rectangle
+*/
 QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
 {
   QRect aRect;
@@ -1742,15 +1350,18 @@ QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
 
   gluProject( theRect.left(), theRect.top(), 0, modelMatrix, projMatrix, viewport, &winx1, &winy1, &winz );
   gluProject( theRect.right(), theRect.bottom(), 0, modelMatrix, projMatrix, viewport, &winx2, &winy2, &winz );
-  
-  aRect.setLeft( (int)(winx1) );
-  aRect.setTop( (int)(viewport[3] - winy1) );
-  aRect.setRight( (int)(winx2) );
-  aRect.setBottom( (int)(viewport[3] - winy2) );
+
+  aRect.setLeft( (int)winx1 );
+  aRect.setTop( viewport[3] - (int)winy1 );
+  aRect.setRight( (int)winx2 );
+  aRect.setBottom( viewport[3] - (int)winy2 );
 
   return aRect;
 }
 
+/*!
+  SLOT: called when tooltip should be shown
+*/
 void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont& theFont, QRect& theTextReg, QRect& theRegion )
 {
   GLViewer_Context* aContext = ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext();
@@ -1764,19 +1375,17 @@ void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont&
 
     QStringList aList;
     if( anObj->isTooTipHTML() )
-      aList = QStringList::split( "<br>", theText );
+      aList = theText.split( "<br>", QString::SkipEmptyParts );
     else
-      aList = QStringList::split( "\n", theText );
+      aList = theText.split( "\n", QString::SkipEmptyParts );
 
     if( !aList.isEmpty() )
     {
-      int index = 0;
       int str_size = aList.first().length();
       for( int i = 1, size = aList.count(); i < size; i++ )
       {
-        if( str_size < aList[i].length() )
+        if ( str_size < (int)aList[i].length() )
         {
-          index = i;
           str_size = aList[i].length();
         }
       }
@@ -1789,9 +1398,11 @@ void GLViewer_ViewPort2d::onMaybeTip( QPoint thePoint, QString& theText, QFont&
         if( aBitmap )
           cur_height = aBitmap->height();
       }
-      QFontMetrics fm( theFont );
+
       //temp
-      theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height, fm.width( /*theText*/aList[index] ), fm.height()*aList.count() + 2 );
+      QSize aSize = QLabel( theText, 0 ).sizeHint();
+      theTextReg = QRect( thePoint.x(), thePoint.y() + cur_height,
+                          aSize.width(), aSize.height() );
       theRegion = QRect( thePoint.x(), thePoint.y(), 1, 1 );
     }
   }