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     KCursorPrivate::self()->setAutoHideCursor( w, enable, customEventFilter );
00226 }
00227 
00228 void KCursor::autoHideEventFilter( QObject *o, QEvent *e )
00229 {
00230     KCursorPrivate::self()->eventFilter( o, e );
00231 }
00232 
00233 void KCursor::setHideCursorDelay( int ms )
00234 {
00235     KCursorPrivate::self()->hideCursorDelay = ms;
00236 }
00237 
00238 int KCursor::hideCursorDelay()
00239 {
00240     return KCursorPrivate::self()->hideCursorDelay;
00241 }
00242 
00243 
00244 
00245 KCursorPrivateAutoHideEventFilter::KCursorPrivateAutoHideEventFilter( QWidget* widget )
00246     : m_widget( widget )
00247     , m_wasMouseTracking( m_widget->hasMouseTracking() )
00248     , m_isCursorHidden( false )
00249     , m_isOwnCursor( false )
00250 {
00251     m_widget->setMouseTracking( true );
00252     connect( &m_autoHideTimer, SIGNAL( timeout() ),
00253              this, SLOT( hideCursor() ) );
00254 }
00255 
00256 KCursorPrivateAutoHideEventFilter::~KCursorPrivateAutoHideEventFilter()
00257 {
00258     if( m_widget != NULL )
00259         m_widget->setMouseTracking( m_wasMouseTracking );
00260 }
00261 
00262 void KCursorPrivateAutoHideEventFilter::resetWidget()
00263 {
00264     m_widget = NULL;
00265 }
00266 
00267 void KCursorPrivateAutoHideEventFilter::hideCursor()
00268 {
00269     m_autoHideTimer.stop();
00270 
00271     if ( m_isCursorHidden )
00272         return;
00273 
00274     m_isCursorHidden = true;
00275 
00276     QWidget* w = actualWidget();
00277 
00278     m_isOwnCursor = w->ownCursor();
00279     if ( m_isOwnCursor )
00280         m_oldCursor = w->cursor();
00281 
00282     w->setCursor( KCursor::blankCursor() );
00283 }
00284 
00285 void KCursorPrivateAutoHideEventFilter::unhideCursor()
00286 {
00287     m_autoHideTimer.stop();
00288 
00289     if ( !m_isCursorHidden )
00290         return;
00291 
00292     m_isCursorHidden = false;
00293 
00294     QWidget* w = actualWidget();
00295 
00296     if ( m_isOwnCursor )
00297         w->setCursor( m_oldCursor );
00298     else
00299         w->unsetCursor();
00300 }
00301 
00302 QWidget* KCursorPrivateAutoHideEventFilter::actualWidget() const
00303 {
00304     QWidget* w = m_widget;
00305 
00306     
00307     QScrollView * sv = dynamic_cast<QScrollView *>( w );
00308     if ( sv )
00309         w = sv->viewport();
00310 
00311     return w;
00312 }
00313 
00314 bool KCursorPrivateAutoHideEventFilter::eventFilter( QObject *o, QEvent *e )
00315 {
00316     Q_ASSERT( o == m_widget );
00317 
00318     switch ( e->type() )
00319     {
00320     case QEvent::Create:
00321         
00322         m_widget->setMouseTracking( true );
00323         break;
00324     case QEvent::Leave:
00325     case QEvent::FocusOut:
00326     case QEvent::WindowDeactivate:
00327         unhideCursor();
00328         break;
00329     case QEvent::KeyPress:
00330     case QEvent::AccelOverride:
00331         hideCursor();
00332         break;
00333     case QEvent::Enter:
00334     case QEvent::FocusIn:
00335     case QEvent::MouseButtonPress:
00336     case QEvent::MouseButtonRelease:
00337     case QEvent::MouseButtonDblClick:
00338     case QEvent::MouseMove:
00339     case QEvent::Show:
00340     case QEvent::Hide:
00341     case QEvent::Wheel:
00342         unhideCursor();
00343         if ( m_widget->hasFocus() )
00344             m_autoHideTimer.start( KCursorPrivate::self()->hideCursorDelay, true );
00345         break;
00346     default:
00347         break;
00348     }
00349 
00350     return false;
00351 }
00352 
00353 KCursorPrivate * KCursorPrivate::s_self = 0L;
00354 
00355 KCursorPrivate * KCursorPrivate::self()
00356 {
00357     if ( !s_self )
00358         s_self = new KCursorPrivate;
00359     
00360 
00361     return s_self;
00362 }
00363 
00364 KCursorPrivate::KCursorPrivate()
00365 {
00366     hideCursorDelay = 5000; 
00367 
00368     KConfig *kc = KGlobal::config();
00369     KConfigGroupSaver ks( kc, QString::fromLatin1("KDE") );
00370     enabled = kc->readBoolEntry(
00371           QString::fromLatin1("Autohiding cursor enabled"), true );
00372 }
00373 
00374 KCursorPrivate::~KCursorPrivate()
00375 {
00376 }
00377 
00378 void KCursorPrivate::setAutoHideCursor( QWidget *w, bool enable, bool customEventFilter )
00379 {
00380     if ( !w || !enabled )
00381         return;
00382 
00383     if ( enable )
00384     {
00385         if ( m_eventFilters.find( w ) != NULL )
00386             return;
00387         KCursorPrivateAutoHideEventFilter* filter = new KCursorPrivateAutoHideEventFilter( w );
00388         m_eventFilters.insert( w, filter );
00389         if ( !customEventFilter )
00390             w->installEventFilter( filter );
00391         connect( w, SIGNAL( destroyed(QObject*) ),
00392                  this, SLOT( slotWidgetDestroyed(QObject*) ) );
00393     }
00394     else
00395     {
00396         KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( w );
00397         if ( filter == NULL )
00398             return;
00399         w->removeEventFilter( filter );
00400         delete filter;
00401         disconnect( w, SIGNAL( destroyed(QObject*) ),
00402                     this, SLOT( slotWidgetDestroyed(QObject*) ) );
00403     }
00404 }
00405 
00406 bool KCursorPrivate::eventFilter( QObject *o, QEvent *e )
00407 {
00408     if ( !enabled )
00409         return false;
00410 
00411     KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.find( o );
00412 
00413     Q_ASSERT( filter != NULL );
00414     if ( filter == NULL )
00415         return false;
00416 
00417     return filter->eventFilter( o, e );
00418 }
00419 
00420 void KCursorPrivate::slotWidgetDestroyed( QObject* o )
00421 {
00422     KCursorPrivateAutoHideEventFilter* filter = m_eventFilters.take( o );
00423 
00424     Q_ASSERT( filter != NULL );
00425 
00426     filter->resetWidget(); 
00427     delete filter;
00428 }
00429 
00430 #include "kcursor_private.moc"