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