Salome HOME
Update from BR_V5_DEV 13Feb2009
[modules/gui.git] / src / Qtx / QtxToolTip.cxx
1 //  Copyright (C) 2007-2008  CEA/DEN, EDF R&D, OPEN CASCADE
2 //
3 //  Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
5 //
6 //  This library is free software; you can redistribute it and/or
7 //  modify it under the terms of the GNU Lesser General Public
8 //  License as published by the Free Software Foundation; either
9 //  version 2.1 of the License.
10 //
11 //  This library is distributed in the hope that it will be useful,
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14 //  Lesser General Public License for more details.
15 //
16 //  You should have received a copy of the GNU Lesser General Public
17 //  License along with this library; if not, write to the Free Software
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
19 //
20 //  See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 // File:      QtxToolTip.cxx
23 // Author:    Sergey TELKOV
24 //
25 #include "QtxToolTip.h"
26
27 #include <QFont>
28 #include <QTimer>
29 #include <QCursor>
30 #include <QFontMetrics>
31 #include <QApplication>
32 #include <QPalette>
33 #include <QMouseEvent>
34
35 #define TOOLTIP_SHOW_DELAY 0500
36 #define TOOLTIP_HIDE_DELAY 7000
37
38 /*!
39   Constructor
40 */
41 QtxToolTip::QtxToolTip( QWidget* parent )
42 : QLabel( parent, Qt::FramelessWindowHint | Qt::X11BypassWindowManagerHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::Window )
43 {
44   setObjectName( "" );
45   setIndent( 3 );
46   setAlignment( Qt::AlignLeft | Qt::AlignVCenter );
47   QPalette palette;
48   palette.setColor( backgroundRole(), QColor( 255, 255, 231 ) );
49   setPalette( palette );
50
51         myWidgetRegion = QRect( -1, -1, -1, -1 );
52
53         setFrameShape( QFrame::Panel );
54         setFrameShadow( QFrame::Plain );
55
56   parent->setMouseTracking( true );
57         parent->installEventFilter( this );
58         installEventFilter( this );
59
60         mySleepTimer = new QTimer( this );
61         mySleepTimer->setSingleShot( true );
62         myWakeUpTimer = new QTimer( this );
63         myWakeUpTimer->setSingleShot( true );
64         connect( mySleepTimer,  SIGNAL( timeout() ), this, SLOT( onSleepTimeOut()  ) );
65         connect( myWakeUpTimer, SIGNAL( timeout() ), this, SLOT( onWakeUpTimeOut() ) );
66
67   myWakeUpDelayTime = 700;
68   myShowDelayTime = 5000;
69 }
70
71 /*!
72   Destructor
73 */
74 QtxToolTip::~QtxToolTip()
75 {
76 }
77
78 /*!
79   Custom event filter
80 */
81 bool QtxToolTip::eventFilter( QObject* o, QEvent* e )
82 {
83         if ( ( e->type() == QEvent::Destroy ) || ( e->type() == QEvent::Close ) || ( e->type() == QEvent::Hide ) )
84         {
85                 hideTip();
86         }
87         if ( e->type() == QEvent::Leave )
88         {
89                 if ( isVisible() && ( o == this ) )
90                         hideTip();
91                 myWakeUpTimer->stop();
92         }
93         if ( e->type() == QEvent::MouseMove )
94         {
95                 QMouseEvent* me = (QMouseEvent*)e;
96                 QPoint thePos = parentWidget()->mapFromGlobal( me->globalPos() );
97                 if ( myWakeUpTimer->isActive() )
98                 {
99                         myWakeUpTimer->stop();
100                         myWakeUpTimer->start( myWakeUpDelayTime );
101                 }
102                 if ( isVisible() )
103                 {
104                         if ( !myWidgetRegion.contains( thePos ) )
105       {
106                                 hideTip();
107         myWidgetRegion = QRect( -1, -1, -1, -1 );
108       }
109                 }
110                 else
111                 {
112                         if ( !myWidgetRegion.isValid() || myWidgetRegion.contains( thePos ) )
113                                 myWakeUpTimer->start( myWakeUpDelayTime );
114                 }
115         }
116         if ( e->type() == QEvent::KeyPress )
117         {
118                 hideTip();
119         }
120         if ( o == parent() && ( e->type() == QEvent::MouseButtonPress ||
121                           e->type() == QEvent::MouseButtonRelease ) )
122         {
123                 hideTip();
124         }
125         return false;
126 }
127
128 /*!
129   Shows tool tip
130   \param aPos - position
131   \param text - tooltip text
132   \param aWidgetRegion - rectangle
133 */
134 void QtxToolTip::showTip( const QPoint& aPos, const QString& text, const QRect& aWidgetRegion )
135 {
136         QFontMetrics theFM = fontMetrics();
137         int theHeight = theFM.height();
138         int theWidth = theFM.width( text ) + 2;
139         showTip( QRect( QPoint( aPos.x(), aPos.y() + 10 ), QSize( theWidth, theHeight ) ), text, aWidgetRegion );
140 }
141
142 /*!
143   Shows tool tip
144   \param aRegion - tooltip region
145   \param text - tooltip text
146   \param aWidgetRegion - widget rectangle
147 */
148 void QtxToolTip::showTip( const QRect& aRegion, const QString& text, const QRect& aWidgetRegion )
149 {
150         setText( text );
151         myWidgetRegion = aWidgetRegion;
152         setGeometry( aRegion );
153         if ( myShowDelayTime != 0 )
154                 mySleepTimer->start( myShowDelayTime );
155         show();
156 }
157
158 /*!
159   Hides tooltip
160 */
161 void QtxToolTip::hideTip()
162 {
163         hide();
164   myWidgetRegion = QRect( -1, -1, -1, -1 );
165         mySleepTimer->stop();
166 }
167
168 /*!
169   It is called when there is a possibility that a tool tip should be shown and
170   must decide whether there is a tool tip for the point p in the widget that this QToolTip object relates to
171   \param pos - position
172 */
173 void QtxToolTip::maybeTip( const QPoint& pos )
174 {
175         QString text;
176         QRect textRegion, theRegion( -1, -1, -1, -1 );
177         QFont theFnt = font();
178
179     emit maybeTip( pos, text, theFnt, textRegion, theRegion );
180
181     if ( theRegion.isValid() )
182         {
183                 setFont( theFnt );
184                 int margin = lineWidth() + indent();
185                 QRect dspRegion( QPoint( textRegion.x() - margin, textRegion.y() ),
186                                          QSize( textRegion.width() + 2 * margin, textRegion.height() ) );
187                 QRect tipRegion( parentWidget()->mapToGlobal( dspRegion.topLeft() ), dspRegion.size() );
188                 if ( tipRegion.left() < 0 )
189                         tipRegion.translate( -1 * tipRegion.left(), 0 );
190                 showTip( tipRegion, text, theRegion );
191         }
192 }
193
194 /*!
195   SLOT: called when sleep time is out
196 */
197 void QtxToolTip::onSleepTimeOut()
198 {
199         mySleepTimer->stop();
200         hideTip();
201 }
202
203 /*!
204   SLOT: called when wake time is out
205 */
206 void QtxToolTip::onWakeUpTimeOut()
207 {
208         myWakeUpTimer->stop();
209   QPoint pos = QCursor::pos();
210   if ( parentWidget() )
211     pos = parentWidget()->mapFromGlobal( pos );
212   maybeTip( pos );
213 }
214
215 /*!
216   Custom mouse press event handler
217 */
218 void QtxToolTip::mousePressEvent( QMouseEvent* e )
219 {
220         hideTip();
221         QWidget* reciever = parentWidget();
222         QMouseEvent* me = new QMouseEvent( QEvent::MouseButtonPress,
223                                                                            reciever->mapFromGlobal( e->globalPos() ),
224                                                                            e->button(), e->buttons(), Qt::KeypadModifier );
225         QApplication::sendEvent( reciever, me );
226 }
227
228 /*!
229   Custom mouse double click event handler
230 */
231 void QtxToolTip::mouseDoubleClickEvent( QMouseEvent* e )
232 {
233         hideTip();
234         QWidget* reciever = parentWidget();
235         QMouseEvent* me = new QMouseEvent( QEvent::MouseButtonDblClick,
236                                                                            reciever->mapFromGlobal( e->globalPos() ),
237                                                                            e->button(), e->buttons(), Qt::KeypadModifier );
238         QApplication::sendEvent( reciever, me );
239 }
240
241 /*!
242   Sets wake delay time
243   \param theTime
244 */
245 void QtxToolTip::setWakeUpDelayTime( int theTime )
246 {
247   if( !(theTime < 0) )
248     myWakeUpDelayTime = theTime;
249 }
250
251 /*!
252   Sets show delay time
253   \param theTime
254 */
255 void QtxToolTip::setShowDelayTime( int theTime )
256 {
257   if( !(theTime < 0) )
258     myShowDelayTime = theTime;
259 }
260
261 /*!
262   \return timer measuring time of sleeping
263 */
264 QTimer* QtxToolTip::sleepTimer() const
265 {
266   return mySleepTimer;
267 }
268
269 /*!
270   \return timer measuring time of waking up
271 */
272 QTimer* QtxToolTip::wakeUpTimer() const
273 {
274   return myWakeUpTimer;
275 }