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 ( m_isOwnCursor )
00298 w->setCursor( m_oldCursor );
00299 else
00300 w->unsetCursor();
00301 }
00302
00303 QWidget* KCursorPrivateAutoHideEventFilter::actualWidget() const
00304 {
00305 QWidget* w = m_widget;
00306
00307
00308 QScrollView * sv = dynamic_cast<QScrollView *>( w );
00309 if ( sv )
00310 w = sv->viewport();
00311
00312 return w;
00313 }
00314
00315 bool KCursorPrivateAutoHideEventFilter::eventFilter( QObject *o, QEvent *e )
00316 {
00317 Q_ASSERT( o == m_widget );
00318
00319 switch ( e->type() )
00320 {
00321 case QEvent::Create:
00322
00323 m_widget->setMouseTracking( true );
00324 break;
00325 case QEvent::Leave:
00326 case QEvent::FocusOut:
00327 case QEvent::WindowDeactivate:
00328 unhideCursor();
00329 break;
00330 case QEvent::KeyPress:
00331 case QEvent::AccelOverride:
00332 hideCursor();
00333 break;
00334 case QEvent::Enter:
00335 case QEvent::FocusIn:
00336 case QEvent::MouseButtonPress:
00337 case QEvent::MouseButtonRelease:
00338 case QEvent::MouseButtonDblClick:
00339 case QEvent::MouseMove:
00340 case QEvent::Show:
00341 case QEvent::Hide:
00342 case QEvent::Wheel:
00343 unhideCursor();
00344 if ( m_widget->hasFocus() )
00345 m_autoHideTimer.start( KCursorPrivate::self()->hideCursorDelay, true );
00346 break;
00347 default:
00348 break;
00349 }
00350
00351 return false;
00352 }
00353
00354 KCursorPrivate * KCursorPrivate::s_self = 0L;
00355
00356 KCursorPrivate * KCursorPrivate::self()
00357 {
00358 if ( !s_self )
00359 s_self = new KCursorPrivate;
00360
00361
00362 return s_self;
00363 }
00364
00365 KCursorPrivate::KCursorPrivate()
00366 {
00367 hideCursorDelay = 5000;
00368
00369 KConfig *kc = KGlobal::config();
00370 KConfigGroupSaver ks( kc, QString::fromLatin1("KDE") );
00371 enabled = kc->readBoolEntry(
00372 QString::fromLatin1("Autohiding cursor enabled"), true );
00373 }
00374
00375 KCursorPrivate::~KCursorPrivate()
00376 {
00377 }
00378
00379 void KCursorPrivate::setAutoHideCursor( QWidget *w, bool enable, bool customEventFilter )
00380 {
00381 if ( !w || !enabled )
00382 return;
00383
00384 if ( enable )
00385 {
00386 if ( m_eventFilters.find( w ) != NULL )
00387 return;
00388 KCursorPrivateAutoHideEventFilter* filter = new KCursorPrivateAutoHideEventFilter( w );
00389 m_eventFilters.insert( w, filter );
00390 if ( !customEventFilter )
00391 w->installEventFilter( filter );
00392 connect( w, SIGNAL( destroyed(QObject*) ),
00393 this, SLOT( slotWidgetDestroyed(QObject*) ) );
00394 }
00395 else
00396 {
00397 KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( w );
00398 if ( filter == NULL )
00399 return;
00400 w->removeEventFilter( filter );
00401 delete filter;
00402 disconnect( w, SIGNAL( destroyed(QObject*) ),
00403 this, SLOT( slotWidgetDestroyed(QObject*) ) );
00404 }
00405 }
00406
00407 bool KCursorPrivate::eventFilter( QObject *o, QEvent *e )
00408 {
00409 if ( !enabled )
00410 return false;
00411
00412 KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.find( o );
00413
00414 Q_ASSERT( filter != NULL );
00415 if ( filter == NULL )
00416 return false;
00417
00418 return filter->eventFilter( o, e );
00419 }
00420
00421 void KCursorPrivate::slotWidgetDestroyed( QObject* o )
00422 {
00423 KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( o );
00424
00425 Q_ASSERT( filter != NULL );
00426
00427 filter->resetWidget();
00428 delete filter;
00429 }
00430
00431 #include "kcursor_private.moc"