Salome HOME
Merge Qt5 porting.
[modules/gui.git] / src / GLViewer / GLViewer_ViewPort2d.cxx
index cd505e7bad223991b0fbb81900a9530bb1fccea8..641760fa7b196accb24665ffbec91844ea0adb66 100644 (file)
@@ -1,31 +1,55 @@
+// Copyright (C) 2007-2015  CEA/DEN, EDF R&D, 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_MimeSource.h"
+#include "GLViewer_MimeData.h"
 #include "GLViewer_Context.h"
 #include "GLViewer_Compass.h"
 #include "GLViewer_Grid.h"
-
-#include <QtxToolTip.h>
-
-#include <qlayout.h>
-#include <qevent.h>
-#include <qrect.h>
-#include <qpopupmenu.h>
-#include <qtooltip.h>
-#include <qapplication.h>
-#include <qclipboard.h>
-#include <qpainter.h>
-#include <qbitmap.h>
-#include <qlabel.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
@@ -44,47 +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 ), myWidth( WIDTH ), myHeight( HEIGHT ),
+  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;
 
-    myGrid = 0;
-    myCompass = 0;
-    myBorder = new GLViewer_Rect();
+  myGrid = 0;
+  myCompass = 0;
+  myBorder = new GLViewer_Rect();
 
-    QBoxLayout* qbl = new QHBoxLayout( this );
-    myGLWidget = new GLViewer_Widget( this, 0 ) ;
-    qbl->addWidget( myGLWidget );
-    myGLWidget->setFocusProxy( this );
-    setMouseTracking( TRUE );
+  QBoxLayout* qbl = new QHBoxLayout( this );
+  qbl->setSpacing( 0 );
+  qbl->setMargin( 0 );
 
-    myIsDragProcess = noDrag;
-    //myCurDragMousePos = QPoint();
-    myCurDragPosX = NULL;
-    myCurDragPosY = NULL;
+  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 )
@@ -95,8 +131,14 @@ GLViewer_ViewPort2d::~GLViewer_ViewPort2d()
 
     delete myBorder;
     delete myGLWidget;
+
+    if ( myRectBand ) myRectBand->hide();
+    delete myRectBand;
 }
 
+/*!
+  SLOT: initializes drag process
+*/
 void GLViewer_ViewPort2d::onStartDragObject( )
 {
     if( myIsDragProcess == noDrag )
@@ -109,17 +151,20 @@ void GLViewer_ViewPort2d::onStartDragObject( )
         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 );
@@ -130,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 );
@@ -164,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();
@@ -202,7 +253,7 @@ void GLViewer_ViewPort2d::onPasteObject()
         GLViewer_Object* aObject = GLViewer_MimeSource::getObject( anArray, aType );
         if( !aObject )
             return;
-        
+
         ((GLViewer_Viewer2d*)getViewFrame()->getViewer())->getGLContext()->insertObject( aObject, true );
     }
     */
@@ -213,7 +264,7 @@ void GLViewer_ViewPort2d::onPasteObject()
     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();
@@ -223,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);
@@ -246,8 +300,8 @@ 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 ) )
     {
@@ -261,14 +315,14 @@ void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
     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);
-  
+
   delete myCurDragPosX;
   delete myCurDragPosY;
   myCurDragPosX = new float(aX);
-  myCurDragPosY = new float(anY);    
+  myCurDragPosY = new float(anY);
 
   myGLWidget->updateGL();
 }
@@ -277,20 +331,20 @@ void GLViewer_ViewPort2d::onDragObject( QMouseEvent* e )
     Emits 'mouseEvent' signal. [ virtual protected ]
 */
 void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
-{    
+{
     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();
+
+    bool accel = e->modifiers() & GLViewer_ViewTransformer::accelKey();
     if( ( anObject && !( accel || e->button() == Qt::RightButton ) ) ||
         ( aContext->NbSelected() && !accel && e->button() == Qt::MidButton )  )
-    {       
+    {
         myIsDragProcess = inDrag;
     }
 }
@@ -301,11 +355,11 @@ void GLViewer_ViewPort2d::mousePressEvent( QMouseEvent* e )
 void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
 {
     emit vpMouseEvent( e );
-    
+
     if( myIsDragProcess == inDrag )
         onDragObject( e );
 
-    /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();   
+    /*GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
     GLViewer_Context* aContext = aViewer->getGLContext();
 
     GLViewer_Object* anObj = aContext->getCurrentObject();
@@ -330,7 +384,14 @@ void GLViewer_ViewPort2d::mouseMoveEvent( QMouseEvent* e )
     Emits 'mouseEvent' signal. [ virtual protected ]
 */
 void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
-{    
+{
+    if ( myIsMouseReleaseBlock )
+    {
+      // skip mouse release after double click
+      myIsMouseReleaseBlock = false;
+      return;
+    }
+
     /* show popup menu */
     if ( e->button() == Qt::RightButton )
     {
@@ -340,7 +401,7 @@ void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
         //destroyPopup( /*popup*/ );
     }
     emit vpMouseEvent( e );
-    
+
     if( myIsDragProcess == inDrag )
     {
       bool isAnyMoved = false;
@@ -353,11 +414,11 @@ void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
         if( aMovingObject )
           isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
       }
-      
+
       aMovingObject = aContext->getCurrentObject();
       if( aMovingObject )
         isAnyMoved = aMovingObject->finishMove() || isAnyMoved;
-      
+
       myIsDragProcess = noDrag;
       //myCurDragMousePos.setX( 0 );
       //myCurDragMousePos.setY( 0 );
@@ -374,6 +435,21 @@ void GLViewer_ViewPort2d::mouseReleaseEvent( QMouseEvent* e )
     }
 }
 
+/*!
+  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 )
@@ -382,12 +458,16 @@ 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_Grid( 2*WIDTH, 2*HEIGHT,
-                                    2*WIDTH, 2*HEIGHT, 
+                                    2*WIDTH, 2*HEIGHT,
                                     GRID_XSIZE, GRID_YSIZE,
                                     myXPan, myYPan,
                                     myXScale, myYScale );
@@ -396,6 +476,11 @@ void GLViewer_ViewPort2d::turnGrid( GLboolean on )
         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 )
@@ -409,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 );
@@ -419,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;
@@ -435,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 );
@@ -474,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;
@@ -481,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 )
     {
@@ -522,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;
@@ -553,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;
@@ -582,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;
@@ -593,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 )
     {
@@ -614,7 +730,7 @@ void GLViewer_ViewPort2d::zoom( int x0, int y0, int x, int y )
         {// undo
             myXScale = bX;
             myYScale = bY;
-        } 
+        }
     }
     else
     {
@@ -624,33 +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 )
 {
     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; 
+    zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
 
     float aDX = ( vpWidth / 2. - centerX ) / myXScale;
     float aDY = ( vpHeight / 2. - centerY ) / myYScale;
@@ -676,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() ));
@@ -697,6 +820,10 @@ void GLViewer_ViewPort2d::fitSelect()
   }
 }
 
+/*!
+  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;
@@ -705,7 +832,7 @@ void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
     float dx, dy, zm;
     float xScale, yScale;
 
-    myMargin = QMAX( myBorder->width(), myBorder->height() ) / 5;
+    myMargin = qMax( myBorder->width(), myBorder->height() ) / 5;
 
     xa = myBorder->left() - myMargin;
     xb = myBorder->right() + myMargin;
@@ -748,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 )
     {
@@ -761,19 +888,19 @@ void GLViewer_ViewPort2d::fitAll( bool keepScale, bool withZ )
     xScale = myXScale;
     yScale = myYScale;
     if( dx && dy )
-        zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy; 
+        zm = vpWidth / dx < vpHeight / dy ? vpWidth / dx : vpHeight / dy;
     else
         zm = 1.0;
-    myXScale = zm; 
-    myYScale = zm;    
-    
+    myXScale = zm;
+    myYScale = zm;
+
 
     if( myGrid )
     {
         myGrid->setPan( myXPan, myYPan );
         if( dx > dy )
             myGrid->setZoom(  zm / xScale );
-        else  
+        else
             myGrid->setZoom( zm / yScale );
     }
 
@@ -785,11 +912,19 @@ 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 )
 {
     myGLWidget->setRotationStart( x, y, 1.0 );
 }
 
+/*!
+  Performs rotation
+  \param intX, intY - current point
+*/
 void GLViewer_ViewPort2d::rotate( int intX, int intY )
 {
     GLint val[4];
@@ -836,6 +971,9 @@ void GLViewer_ViewPort2d::rotate( int intX, int intY )
     myGLWidget->updateGL();
 }
 
+/*!
+  Finishes rotation
+*/
 void GLViewer_ViewPort2d::endRotation()
 {
     float ra, rx, ry, rz;
@@ -843,6 +981,9 @@ void GLViewer_ViewPort2d::endRotation()
     myGLWidget->setRotationAngle( ra );
 }
 
+/*!
+  Draws compass
+*/
 void GLViewer_ViewPort2d::drawCompass()
 {
     if( !myCompass->getVisible() )
@@ -873,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:
@@ -888,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.;
@@ -900,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
@@ -915,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 );
@@ -935,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" );
@@ -968,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 );
@@ -985,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 );
@@ -999,21 +1140,28 @@ void GLViewer_ViewPort2d::drawCompass()
 
     glEndList();
 
-    if ( aTextList != -1 ) 
+    if ( 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 )
@@ -1021,58 +1169,77 @@ 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();
@@ -1096,6 +1263,8 @@ bool GLViewer_ViewPort2d::startPulling( GLViewer_Pnt point )
     return false;
 }
 
+/*!
+*/
 void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
 {
     GLViewer_Viewer2d* aViewer = (GLViewer_Viewer2d*)getViewFrame()->getViewer();
@@ -1121,6 +1290,8 @@ void GLViewer_ViewPort2d::drawPulling( GLViewer_Pnt point )
     myPullingObject->pull( point, aLockedObject );
 }
 
+/*!
+*/
 void GLViewer_ViewPort2d::finishPulling()
 {
     myIsPulling = false;
@@ -1128,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;
@@ -1145,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 );
@@ -1154,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;
@@ -1171,7 +1350,7 @@ 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( viewport[3] - (int)winy1 );
   aRect.setRight( (int)winx2 );
@@ -1180,6 +1359,9 @@ QRect GLViewer_ViewPort2d::GLV2win( const GLViewer_Rect& theRect ) const
   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();
@@ -1193,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();
         }
       }