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 #include <kapplication.h>
00027
00028 #include <qbitmap.h>
00029 #include <qcursor.h>
00030 #include <qevent.h>
00031 #include <qtimer.h>
00032 #include <qwidget.h>
00033
00034 #include <kglobal.h>
00035 #include <kconfig.h>
00036 #include <qscrollview.h>
00037
00038 #include "kcursor_private.h"
00039
00040 KCursor::KCursor()
00041 {
00042 }
00043
00044 QCursor KCursor::handCursor()
00045 {
00046 static QCursor *hand_cursor = 0;
00047
00048 if (hand_cursor == 0)
00049 {
00050 KConfig *config = KGlobal::config();
00051 KConfigGroupSaver saver( config, "General" );
00052
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 hand_cursor = new QCursor(PointingHandCursor);
00078 }
00079
00080 Q_CHECK_PTR(hand_cursor);
00081 return *hand_cursor;
00082 }
00083
00084
00085 static const char * const working_cursor_xpm[]={
00086 "32 32 3 1",
00087 "# c None",
00088 "a c #000000",
00089 ". c #ffffff",
00090 "..##############################",
00091 ".a.##########.aaaa.#############",
00092 ".aa.#########.aaaa.#############",
00093 ".aaa.#######.aaaaaa.############",
00094 ".aaaa.#####.a...a..a..##########",
00095 ".aaaaa.####a....a...aa##########",
00096 ".aaaaaa.###a...aa...aa##########",
00097 ".aaaaaaa.##a..a.....aa##########",
00098 ".aaaaaaaa.#.aa.....a..##########",
00099 ".aaaaa....##.aaaaaa.############",
00100 ".aa.aa.######.aaaa.#############",
00101 ".a.#.aa.#####.aaaa.#############",
00102 "..##.aa.########################",
00103 "#####.aa.#######################",
00104 "#####.aa.#######################",
00105 "######..########################",
00106 "################################",
00107 "################################",
00108 "################################",
00109 "################################",
00110 "################################",
00111 "################################",
00112 "################################",
00113 "################################",
00114 "################################",
00115 "################################",
00116 "################################",
00117 "################################",
00118 "################################",
00119 "################################",
00120 "################################",
00121 "################################"};
00122
00123
00124 QCursor KCursor::workingCursor()
00125 {
00126 static QCursor *working_cursor = 0;
00127
00128 if (working_cursor == 0)
00129 {
00130 QPixmap pm( const_cast< const char** >( working_cursor_xpm ));
00131 working_cursor = new QCursor( pm, 1, 1 );
00132
00133
00134 working_cursor->handle();
00135 }
00136
00137 Q_CHECK_PTR(working_cursor);
00138 return *working_cursor;
00139 }
00140
00145 QCursor KCursor::arrowCursor()
00146 {
00147 return Qt::arrowCursor;
00148 }
00149
00150
00151 QCursor KCursor::upArrowCursor()
00152 {
00153 return Qt::upArrowCursor;
00154 }
00155
00156
00157 QCursor KCursor::crossCursor()
00158 {
00159 return Qt::crossCursor;
00160 }
00161
00162
00163 QCursor KCursor::waitCursor()
00164 {
00165 return Qt::waitCursor;
00166 }
00167
00168
00169 QCursor KCursor::ibeamCursor()
00170 {
00171 return Qt::ibeamCursor;
00172 }
00173
00174
00175 QCursor KCursor::sizeVerCursor()
00176 {
00177 return Qt::sizeVerCursor;
00178 }
00179
00180
00181 QCursor KCursor::sizeHorCursor()
00182 {
00183 return Qt::sizeHorCursor;
00184 }
00185
00186
00187 QCursor KCursor::sizeBDiagCursor()
00188 {
00189 return Qt::sizeBDiagCursor;
00190 }
00191
00192
00193 QCursor KCursor::sizeFDiagCursor()
00194 {
00195 return Qt::sizeFDiagCursor;
00196 }
00197
00198
00199 QCursor KCursor::sizeAllCursor()
00200 {
00201 return Qt::sizeAllCursor;
00202 }
00203
00204
00205 QCursor KCursor::blankCursor()
00206 {
00207 return Qt::blankCursor;
00208 }
00209
00210 QCursor KCursor::whatsThisCursor()
00211 {
00212 return Qt::whatsThisCursor;
00213 }
00214
00215
00216
00217 void KCursor::setAutoHideCursor( QWidget *w, bool enable )
00218 {
00219 setAutoHideCursor( w, enable, false );
00220 }
00221
00222 void KCursor::setAutoHideCursor( QWidget *w, bool enable,
00223 bool customEventFilter )
00224 {
00225 if ( !w )
00226 return;
00227
00228 KCursorPrivate *kp = KCursorPrivate::self();
00229 if ( !kp->enabled )
00230 return;
00231
00232 if ( enable ) {
00233 kp->start();
00234 w->setMouseTracking( true );
00235
00236 if ( !customEventFilter )
00237 w->installEventFilter( kp );
00238 else
00239 w->removeEventFilter( kp );
00240 }
00241
00242 else {
00243 w->setMouseTracking( false );
00244 w->removeEventFilter( kp );
00245 kp->stop();
00246 }
00247 }
00248
00249 void KCursor::autoHideEventFilter( QObject *o, QEvent *e )
00250 {
00251 KCursorPrivate::self()->eventFilter( o, e );
00252 }
00253
00254 void KCursor::setHideCursorDelay( int ms )
00255 {
00256 KCursorPrivate::self()->hideCursorDelay = ms;
00257 }
00258
00259 int KCursor::hideCursorDelay()
00260 {
00261 return KCursorPrivate::self()->hideCursorDelay;
00262 }
00263
00264
00265
00266
00267
00268 KCursorPrivate * KCursorPrivate::s_self = 0L;
00269
00270 KCursorPrivate * KCursorPrivate::self()
00271 {
00272 if ( !s_self )
00273 s_self = new KCursorPrivate;
00274
00275
00276 return s_self;
00277 }
00278
00279 KCursorPrivate::KCursorPrivate()
00280 {
00281 count = 0;
00282 autoHideTimer = 0;
00283 hideCursorDelay = 5000;
00284 isCursorHidden = false;
00285 isOwnCursor = false;
00286 hideWidget = 0L;
00287
00288 KConfig *kc = KGlobal::config();
00289 KConfigGroupSaver ks( kc, QString::fromLatin1("KDE") );
00290 enabled = kc->readBoolEntry(
00291 QString::fromLatin1("Autohiding cursor enabled"), true );
00292 }
00293
00294 KCursorPrivate::~KCursorPrivate()
00295 {
00296 }
00297
00298 void KCursorPrivate::start()
00299 {
00300 if ( !autoHideTimer ) {
00301 autoHideTimer = new QTimer(qApp);
00302 QObject::connect( autoHideTimer, SIGNAL( timeout() ),
00303 this, SLOT( slotHideCursor() ));
00304 }
00305 count++;
00306 }
00307
00308 void KCursorPrivate::stop()
00309 {
00310 count--;
00311 if ( count <= 0 ) {
00312 delete autoHideTimer;
00313 autoHideTimer = 0L;
00314 count = 0;
00315 }
00316 }
00317
00318 void KCursorPrivate::hideCursor( QWidget *w )
00319 {
00320 if ( !w )
00321 return;
00322
00323 QScrollView * sv = dynamic_cast<QScrollView *>( w );
00324 if ( sv )
00325 w = sv->viewport();
00326
00327 isCursorHidden = true;
00328 isOwnCursor = w->ownCursor();
00329 if ( isOwnCursor )
00330 oldCursor = w->cursor();
00331
00332 w->setCursor( KCursor::blankCursor() );
00333 }
00334
00335 void KCursorPrivate::unhideCursor( QWidget *w )
00336 {
00337 isCursorHidden = false;
00338
00339 if ( w ) {
00340 QScrollView * sv = dynamic_cast<QScrollView *>( w );
00341 if ( sv )
00342 w = sv->viewport();
00343
00344 if ( isOwnCursor )
00345 w->setCursor( oldCursor );
00346 else
00347 w->unsetCursor();
00348 }
00349 }
00350
00351
00352
00353
00354 bool KCursorPrivate::eventFilter( QObject *o, QEvent *e )
00355 {
00356 if ( !enabled || !o->isWidgetType() )
00357 return false;
00358
00359 int t = e->type();
00360
00361
00362 if( ! ( (t >= QEvent::MouseButtonPress && t <= QEvent::Leave) ||
00363 (t >= QEvent::Destroy && t <= QEvent::Hide) ||
00364 t == QEvent::AccelOverride ||
00365 t == QEvent::Wheel ) )
00366 return false;
00367
00368
00369 if ( o != hideWidget ) {
00370 if ( hideWidget ) {
00371 disconnect( hideWidget, SIGNAL( destroyed() ),
00372 this, SLOT( slotWidgetDestroyed()));
00373 }
00374 connect( o, SIGNAL( destroyed() ),
00375 this, SLOT( slotWidgetDestroyed()));
00376 }
00377
00378 QWidget *w = static_cast<QWidget *>( o );
00379 hideWidget = w;
00380
00381 if ( t == QEvent::Leave || t == QEvent::FocusOut || t == QEvent::Destroy) {
00382 if ( autoHideTimer )
00383 autoHideTimer->stop();
00384
00385 if ( isCursorHidden && t != QEvent::Destroy )
00386 unhideCursor( w );
00387
00388 return false;
00389 }
00390
00391 if ( t == QEvent::Create )
00392 w->setMouseTracking( true );
00393
00394
00395
00396 if ( !w->isActiveWindow() || (w->isFocusEnabled() && !w->hasFocus()) ) {
00397 disconnect( hideWidget, SIGNAL( destroyed() ),
00398 this, SLOT( slotWidgetDestroyed() ));
00399 hideWidget = 0L;
00400 return false;
00401 }
00402
00403 else if ( t == QEvent::Enter ) {
00404 if ( isCursorHidden )
00405 unhideCursor( w );
00406 if ( autoHideTimer )
00407 autoHideTimer->start( hideCursorDelay, true );
00408 }
00409
00410 else {
00411
00412 if ( isCursorHidden ) {
00413 if ( t == QEvent::MouseButtonPress ||
00414 t == QEvent::MouseButtonRelease ||
00415 t == QEvent::MouseButtonDblClick || t == QEvent::MouseMove ||
00416 t == QEvent::Show || t == QEvent::Hide ) {
00417 unhideCursor( w );
00418 autoHideTimer->start( hideCursorDelay, true );
00419 }
00420 }
00421
00422 else {
00423 if ( t == QEvent::KeyPress || t == QEvent::AccelOverride ) {
00424 if ( insideWidget( QCursor::pos(), w )) {
00425 hideCursor( w );
00426 autoHideTimer->stop();
00427 }
00428 }
00429
00430
00431 else if ( (t >= QEvent::MouseButtonPress &&
00432 t <= QEvent::KeyRelease) ||
00433 t == QEvent::Wheel || t == QEvent::AccelOverride ) {
00434
00435 if ( insideWidget( QCursor::pos(), w ) && autoHideTimer )
00436 autoHideTimer->start( hideCursorDelay, true );
00437 }
00438 }
00439 }
00440 return false;
00441 }
00442
00443 void KCursorPrivate::slotHideCursor()
00444 {
00445 if ( !isCursorHidden )
00446 hideCursor( hideWidget );
00447 }
00448
00449 void KCursorPrivate::slotWidgetDestroyed()
00450 {
00451 isCursorHidden = false;
00452 hideWidget = 0L;
00453 }
00454
00455 bool KCursorPrivate::insideWidget( const QPoint &p, QWidget *w )
00456 {
00457 return w->rect().contains( w->mapFromGlobal( p ) );
00458 }
00459
00460 #include "kcursor_private.moc"