00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #ifdef KDE_USE_FINAL
00020 #ifdef KeyRelease
00021 #undef KeyRelease
00022 #endif
00023 #endif
00024
00025 #include <kcursor.h>
00026
00027 #include <qbitmap.h>
00028 #include <qcursor.h>
00029 #include <qevent.h>
00030 #include <qtimer.h>
00031 #include <qwidget.h>
00032
00033 #include <kglobal.h>
00034 #include <kconfig.h>
00035 #include <qscrollview.h>
00036
00037 #include "kcursor_private.h"
00038
00039 KCursor::KCursor()
00040 {
00041 }
00042
00043 QCursor KCursor::handCursor()
00044 {
00045 static QCursor *hand_cursor = 0;
00046
00047 if (!hand_cursor)
00048 {
00049 KConfig *config = KGlobal::config();
00050 KConfigGroupSaver saver( config, "General" );
00051
00052 #ifndef Q_WS_WIN // this mask doesn't work too well on win32
00053 if ( config->readEntry("handCursorStyle", "Windows") == "Windows" )
00054 {
00055 static const unsigned char HAND_BITS[] = {
00056 0x80, 0x01, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x02,
00057 0x00, 0x40, 0x02, 0x00, 0x40, 0x02, 0x00, 0x40, 0x1e, 0x00, 0x40,
00058 0xf2, 0x00, 0x40, 0x92, 0x01, 0x70, 0x92, 0x02, 0x50, 0x92, 0x04,
00059 0x48, 0x80, 0x04, 0x48, 0x00, 0x04, 0x48, 0x00, 0x04, 0x08, 0x00,
00060 0x04, 0x08, 0x00, 0x04, 0x10, 0x00, 0x04, 0x10, 0x00, 0x04, 0x20,
00061 0x00, 0x02, 0x40, 0x00, 0x02, 0x40, 0x00, 0x01, 0xc0, 0xff, 0x01};
00062 static const unsigned char HAND_MASK_BITS[] = {
00063 0x80, 0x01, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03,
00064 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x03, 0x00, 0xc0, 0x1f, 0x00, 0xc0,
00065 0xff, 0x00, 0xc0, 0xff, 0x01, 0xf0, 0xff, 0x03, 0xf0, 0xff, 0x07,
00066 0xf8, 0xff, 0x07, 0xf8, 0xff, 0x07, 0xf8, 0xff, 0x07, 0xf8, 0xff,
00067 0x07, 0xf8, 0xff, 0x07, 0xf0, 0xff, 0x07, 0xf0, 0xff, 0x07, 0xe0,
00068 0xff, 0x03, 0xc0, 0xff, 0x03, 0xc0, 0xff, 0x01, 0xc0, 0xff, 0x01};
00069 QBitmap hand_bitmap(22, 22, HAND_BITS, true);
00070 QBitmap hand_mask(22, 22, HAND_MASK_BITS, true);
00071 hand_cursor = new QCursor(hand_bitmap, hand_mask, 7, 0);
00072
00073
00074 hand_cursor->handle();
00075 }
00076 else
00077 #endif
00078 hand_cursor = new QCursor(PointingHandCursor);
00079 }
00080
00081 Q_CHECK_PTR(hand_cursor);
00082 return *hand_cursor;
00083 }
00084
00085
00086 static const char * const working_cursor_xpm[]={
00087 "32 32 3 1",
00088 "# c None",
00089 "a c #000000",
00090 ". c #ffffff",
00091 "..##############################",
00092 ".a.##########.aaaa.#############",
00093 ".aa.#########.aaaa.#############",
00094 ".aaa.#######.aaaaaa.############",
00095 ".aaaa.#####.a...a..a..##########",
00096 ".aaaaa.####a....a...aa##########",
00097 ".aaaaaa.###a...aa...aa##########",
00098 ".aaaaaaa.##a..a.....aa##########",
00099 ".aaaaaaaa.#.aa.....a..##########",
00100 ".aaaaa....##.aaaaaa.############",
00101 ".aa.aa.######.aaaa.#############",
00102 ".a.#.aa.#####.aaaa.#############",
00103 "..##.aa.########################",
00104 "#####.aa.#######################",
00105 "#####.aa.#######################",
00106 "######..########################",
00107 "################################",
00108 "################################",
00109 "################################",
00110 "################################",
00111 "################################",
00112 "################################",
00113 "################################",
00114 "################################",
00115 "################################",
00116 "################################",
00117 "################################",
00118 "################################",
00119 "################################",
00120 "################################",
00121 "################################",
00122 "################################"};
00123
00124
00125 QCursor KCursor::workingCursor()
00126 {
00127 static QCursor *working_cursor = 0;
00128
00129 if (!working_cursor)
00130 {
00131 QPixmap pm( const_cast< const char** >( working_cursor_xpm ));
00132 working_cursor = new QCursor( pm, 1, 1 );
00133
00134
00135 working_cursor->handle();
00136 }
00137
00138 Q_CHECK_PTR(working_cursor);
00139 return *working_cursor;
00140 }
00141
00146 QCursor KCursor::arrowCursor()
00147 {
00148 return Qt::arrowCursor;
00149 }
00150
00151
00152 QCursor KCursor::upArrowCursor()
00153 {
00154 return Qt::upArrowCursor;
00155 }
00156
00157
00158 QCursor KCursor::crossCursor()
00159 {
00160 return Qt::crossCursor;
00161 }
00162
00163
00164 QCursor KCursor::waitCursor()
00165 {
00166 return Qt::waitCursor;
00167 }
00168
00169
00170 QCursor KCursor::ibeamCursor()
00171 {
00172 return Qt::ibeamCursor;
00173 }
00174
00175
00176 QCursor KCursor::sizeVerCursor()
00177 {
00178 return Qt::sizeVerCursor;
00179 }
00180
00181
00182 QCursor KCursor::sizeHorCursor()
00183 {
00184 return Qt::sizeHorCursor;
00185 }
00186
00187
00188 QCursor KCursor::sizeBDiagCursor()
00189 {
00190 return Qt::sizeBDiagCursor;
00191 }
00192
00193
00194 QCursor KCursor::sizeFDiagCursor()
00195 {
00196 return Qt::sizeFDiagCursor;
00197 }
00198
00199
00200 QCursor KCursor::sizeAllCursor()
00201 {
00202 return Qt::sizeAllCursor;
00203 }
00204
00205
00206 QCursor KCursor::blankCursor()
00207 {
00208 return Qt::blankCursor;
00209 }
00210
00211 QCursor KCursor::whatsThisCursor()
00212 {
00213 return Qt::whatsThisCursor;
00214 }
00215
00216
00217
00218 void KCursor::setAutoHideCursor( QWidget *w, bool enable )
00219 {
00220 setAutoHideCursor( w, enable, false );
00221 }
00222
00223 void KCursor::setAutoHideCursor( QWidget *w, bool enable,
00224 bool customEventFilter )
00225 {
00226 KCursorPrivate::self()->setAutoHideCursor( w, enable, customEventFilter );
00227 }
00228
00229 void KCursor::autoHideEventFilter( QObject *o, QEvent *e )
00230 {
00231 KCursorPrivate::self()->eventFilter( o, e );
00232 }
00233
00234 void KCursor::setHideCursorDelay( int ms )
00235 {
00236 KCursorPrivate::self()->hideCursorDelay = ms;
00237 }
00238
00239 int KCursor::hideCursorDelay()
00240 {
00241 return KCursorPrivate::self()->hideCursorDelay;
00242 }
00243
00244
00245
00246 KCursorPrivateAutoHideEventFilter::KCursorPrivateAutoHideEventFilter( QWidget* widget )
00247 : m_widget( widget )
00248 , m_wasMouseTracking( m_widget->hasMouseTracking() )
00249 , m_isCursorHidden( false )
00250 , m_isOwnCursor( false )
00251 {
00252 m_widget->setMouseTracking( true );
00253 connect( &m_autoHideTimer, SIGNAL( timeout() ),
00254 this, SLOT( hideCursor() ) );
00255 }
00256
00257 KCursorPrivateAutoHideEventFilter::~KCursorPrivateAutoHideEventFilter()
00258 {
00259 if( m_widget != NULL )
00260 m_widget->setMouseTracking( m_wasMouseTracking );
00261 }
00262
00263 void KCursorPrivateAutoHideEventFilter::resetWidget()
00264 {
00265 m_widget = NULL;
00266 }
00267
00268 void KCursorPrivateAutoHideEventFilter::hideCursor()
00269 {
00270 m_autoHideTimer.stop();
00271
00272 if ( m_isCursorHidden )
00273 return;
00274
00275 m_isCursorHidden = true;
00276
00277 QWidget* w = actualWidget();
00278
00279 m_isOwnCursor = w->ownCursor();
00280 if ( m_isOwnCursor )
00281 m_oldCursor = w->cursor();
00282
00283 w->setCursor( KCursor::blankCursor() );
00284 }
00285
00286 void KCursorPrivateAutoHideEventFilter::unhideCursor()
00287 {
00288 m_autoHideTimer.stop();
00289
00290 if ( !m_isCursorHidden )
00291 return;
00292
00293 m_isCursorHidden = false;
00294
00295 QWidget* w = actualWidget();
00296
00297 if ( w->cursor().shape() != Qt::BlankCursor )
00298 return;
00299
00300 if ( m_isOwnCursor )
00301 w->setCursor( m_oldCursor );
00302 else
00303 w->unsetCursor();
00304 }
00305
00306 QWidget* KCursorPrivateAutoHideEventFilter::actualWidget() const
00307 {
00308 QWidget* w = m_widget;
00309
00310
00311 QScrollView * sv = dynamic_cast<QScrollView *>( w );
00312 if ( sv )
00313 w = sv->viewport();
00314
00315 return w;
00316 }
00317
00318 bool KCursorPrivateAutoHideEventFilter::eventFilter( QObject *o, QEvent *e )
00319 {
00320 Q_ASSERT( o == m_widget );
00321
00322 switch ( e->type() )
00323 {
00324 case QEvent::Create:
00325
00326 m_widget->setMouseTracking( true );
00327 break;
00328 case QEvent::Leave:
00329 case QEvent::FocusOut:
00330 case QEvent::WindowDeactivate:
00331 unhideCursor();
00332 break;
00333 case QEvent::KeyPress:
00334 case QEvent::AccelOverride:
00335 hideCursor();
00336 break;
00337 case QEvent::Enter:
00338 case QEvent::FocusIn:
00339 case QEvent::MouseButtonPress:
00340 case QEvent::MouseButtonRelease:
00341 case QEvent::MouseButtonDblClick:
00342 case QEvent::MouseMove:
00343 case QEvent::Show:
00344 case QEvent::Hide:
00345 case QEvent::Wheel:
00346 unhideCursor();
00347 if ( m_widget->hasFocus() )
00348 m_autoHideTimer.start( KCursorPrivate::self()->hideCursorDelay, true );
00349 break;
00350 default:
00351 break;
00352 }
00353
00354 return false;
00355 }
00356
00357 KCursorPrivate * KCursorPrivate::s_self = 0L;
00358
00359 KCursorPrivate * KCursorPrivate::self()
00360 {
00361 if ( !s_self )
00362 s_self = new KCursorPrivate;
00363
00364
00365 return s_self;
00366 }
00367
00368 KCursorPrivate::KCursorPrivate()
00369 {
00370 hideCursorDelay = 5000;
00371
00372 KConfig *kc = KGlobal::config();
00373 KConfigGroupSaver ks( kc, QString::fromLatin1("KDE") );
00374 enabled = kc->readBoolEntry(
00375 QString::fromLatin1("Autohiding cursor enabled"), true );
00376 }
00377
00378 KCursorPrivate::~KCursorPrivate()
00379 {
00380 }
00381
00382 void KCursorPrivate::setAutoHideCursor( QWidget *w, bool enable, bool customEventFilter )
00383 {
00384 if ( !w || !enabled )
00385 return;
00386
00387 if ( enable )
00388 {
00389 if ( m_eventFilters.find( w ) != NULL )
00390 return;
00391 KCursorPrivateAutoHideEventFilter* filter = new KCursorPrivateAutoHideEventFilter( w );
00392 m_eventFilters.insert( w, filter );
00393 if ( !customEventFilter )
00394 w->installEventFilter( filter );
00395 connect( w, SIGNAL( destroyed(QObject*) ),
00396 this, SLOT( slotWidgetDestroyed(QObject*) ) );
00397 }
00398 else
00399 {
00400 KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( w );
00401 if ( filter == NULL )
00402 return;
00403 w->removeEventFilter( filter );
00404 delete filter;
00405 disconnect( w, SIGNAL( destroyed(QObject*) ),
00406 this, SLOT( slotWidgetDestroyed(QObject*) ) );
00407 }
00408 }
00409
00410 bool KCursorPrivate::eventFilter( QObject *o, QEvent *e )
00411 {
00412 if ( !enabled )
00413 return false;
00414
00415 KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.find( o );
00416
00417 Q_ASSERT( filter != NULL );
00418 if ( filter == NULL )
00419 return false;
00420
00421 return filter->eventFilter( o, e );
00422 }
00423
00424 void KCursorPrivate::slotWidgetDestroyed( QObject* o )
00425 {
00426 KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( o );
00427
00428 Q_ASSERT( filter != NULL );
00429
00430 filter->resetWidget();
00431 delete filter;
00432 }
00433
00434 #include "kcursor_private.moc"