konq_filetip.cc

00001 /* This file is part of the KDE projects
00002    Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
00003    Copyright (C) 2000, 2001, 2002 David Faure <david@mandrakesoft.com>
00004    Copyright (C) 2004 Martin Koller <m.koller@surfeu.at>
00005 
00006    This program is free software; you can redistribute it and/or
00007    modify it under the terms of the GNU General Public
00008    License as published by the Free Software Foundation; either
00009    version 2 of the License, or (at your option) any later version.
00010 
00011    This program is distributed in the hope that it will be useful,
00012    but WITHOUT ANY WARRANTY; without even the implied warranty of
00013    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00014    General Public License for more details.
00015 
00016    You should have received a copy of the GNU General Public License
00017    along with this program; see the file COPYING.  If not, write to
00018    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00019    Boston, MA 02110-1301, USA.
00020 */
00021 
00022 #include <konq_filetip.h>
00023 
00024 #include <kfileitem.h>
00025 #include <kglobalsettings.h>
00026 #include <kstandarddirs.h>
00027 #include <kapplication.h>
00028 
00029 #include <qlabel.h>
00030 #include <qtooltip.h>
00031 #include <qlayout.h>
00032 #include <qpainter.h>
00033 #include <qscrollview.h>
00034 #include <qtimer.h>
00035 
00036 #include <fixx11h.h>
00037 //--------------------------------------------------------------------------------
00038 
00039 KonqFileTip::KonqFileTip( QScrollView* parent )
00040   : QFrame( 0, 0, WStyle_Customize | WStyle_NoBorder | WStyle_Tool | WStyle_StaysOnTop | WX11BypassWM ),
00041     m_on( false ),
00042     m_preview( false ),
00043     m_filter( false ),
00044     m_corner( 0 ),
00045     m_num( 0 ),
00046     m_view( parent ),
00047     m_item( 0 ),
00048     m_previewJob( 0 )
00049 {
00050     m_iconLabel = new QLabel(this);
00051     m_textLabel = new QLabel(this);
00052     m_textLabel->setAlignment(Qt::AlignAuto | Qt::AlignTop);
00053 
00054     QGridLayout* layout = new QGridLayout(this, 1, 2, 8, 0);
00055     layout->addWidget(m_iconLabel, 0, 0);
00056     layout->addWidget(m_textLabel, 0, 1);
00057     layout->setResizeMode(QLayout::Fixed);
00058 
00059     setPalette( QToolTip::palette() );
00060     setMargin( 1 );
00061     setFrameStyle( QFrame::Plain | QFrame::Box );
00062 
00063     m_timer = new QTimer(this);
00064 
00065     hide();
00066 }
00067 
00068 KonqFileTip::~KonqFileTip()
00069 {
00070    if ( m_previewJob ) {
00071         m_previewJob->kill();
00072         m_previewJob = 0;
00073     }
00074 }
00075 
00076 void KonqFileTip::setPreview(bool on)
00077 {
00078     m_preview = on;
00079     if(on)
00080         m_iconLabel->show();
00081     else
00082         m_iconLabel->hide();
00083 }
00084 
00085 void KonqFileTip::setOptions( bool on, bool preview, int num )
00086 {
00087     setPreview(preview);
00088     m_on = on;
00089     m_num = num;
00090 }
00091 
00092 void KonqFileTip::setItem( KFileItem *item, const QRect &rect, const QPixmap *pixmap )
00093 {
00094     hideTip();
00095 
00096     if (!m_on) return;
00097 
00098     if ( m_previewJob ) {
00099         m_previewJob->kill();
00100         m_previewJob = 0;
00101     }
00102 
00103     m_rect = rect;
00104     m_item = item;
00105 
00106     if ( m_item ) {
00107         if (m_preview) {
00108             if ( pixmap )
00109               m_iconLabel->setPixmap( *pixmap );
00110             else
00111               m_iconLabel->setPixmap( QPixmap() );
00112         }
00113 
00114         // Don't start immediately, because the user could move the mouse over another item
00115         // This avoids a quick sequence of started preview-jobs
00116         m_timer->disconnect( this );
00117         connect(m_timer, SIGNAL(timeout()), this, SLOT(startDelayed()));
00118         m_timer->start( 300, true );
00119     }
00120 }
00121 
00122 void KonqFileTip::reposition()
00123 {
00124     if ( m_rect.isEmpty() || !m_view || !m_view->viewport() ) return;
00125 
00126     QRect rect = m_rect;
00127     QPoint off = m_view->viewport()->mapToGlobal( m_view->contentsToViewport( rect.topRight() ) );
00128     rect.moveTopRight( off );
00129 
00130     QPoint pos = rect.center();
00131     // m_corner:
00132     // 0: upperleft
00133     // 1: upperright
00134     // 2: lowerleft
00135     // 3: lowerright
00136     // 4+: none
00137     m_corner = 0;
00138     // should the tooltip be shown to the left or to the right of the ivi ?
00139     QRect desk = KGlobalSettings::desktopGeometry(rect.center());
00140     if (rect.center().x() + width() > desk.right())
00141     {
00142         // to the left
00143         if (pos.x() - width() < 0) {
00144             pos.setX(0);
00145             m_corner = 4;
00146         } else {
00147             pos.setX( pos.x() - width() );
00148             m_corner = 1;
00149         }
00150     }
00151     // should the tooltip be shown above or below the ivi ?
00152     if (rect.bottom() + height() > desk.bottom())
00153     {
00154         // above
00155         pos.setY( rect.top() - height() );
00156         m_corner += 2;
00157     }
00158     else pos.setY( rect.bottom() + 1 );
00159 
00160     move( pos );
00161     update();
00162 }
00163 
00164 void KonqFileTip::gotPreview( const KFileItem* item, const QPixmap& pixmap )
00165 {
00166     m_previewJob = 0;
00167     if (item != m_item) return;
00168 
00169     m_iconLabel -> setPixmap(pixmap);
00170 }
00171 
00172 void KonqFileTip::gotPreviewResult()
00173 {
00174     m_previewJob = 0;
00175 }
00176 
00177 void KonqFileTip::drawContents( QPainter *p )
00178 {
00179     static const char * const names[] = {
00180         "arrow_topleft",
00181         "arrow_topright",
00182         "arrow_bottomleft",
00183         "arrow_bottomright"
00184     };
00185 
00186     if (m_corner >= 4) {  // 4 is empty, so don't draw anything
00187         QFrame::drawContents( p );
00188         return;
00189     }
00190 
00191     if ( m_corners[m_corner].isNull())
00192         m_corners[m_corner].load( locate( "data", QString::fromLatin1( "konqueror/pics/%1.png" ).arg( names[m_corner] ) ) );
00193 
00194     QPixmap &pix = m_corners[m_corner];
00195 
00196     switch ( m_corner )
00197     {
00198         case 0:
00199             p->drawPixmap( 3, 3, pix );
00200             break;
00201         case 1:
00202             p->drawPixmap( width() - pix.width() - 3, 3, pix );
00203             break;
00204         case 2:
00205             p->drawPixmap( 3, height() - pix.height() - 3, pix );
00206             break;
00207         case 3:
00208             p->drawPixmap( width() - pix.width() - 3, height() - pix.height() - 3, pix );
00209             break;
00210     }
00211 
00212     QFrame::drawContents( p );
00213 }
00214 
00215 void KonqFileTip::setFilter( bool enable )
00216 {
00217     if ( enable == m_filter ) return;
00218 
00219     if ( enable ) {
00220         kapp->installEventFilter( this );
00221         QApplication::setGlobalMouseTracking( true );
00222     }
00223     else {
00224         QApplication::setGlobalMouseTracking( false );
00225         kapp->removeEventFilter( this );
00226     }
00227     m_filter = enable;
00228 }
00229 
00230 void KonqFileTip::showTip()
00231 {
00232     QString text = m_item->getToolTipText(m_num);
00233 
00234     if ( text.isEmpty() ) return;
00235 
00236     m_timer->disconnect( this );
00237     connect(m_timer, SIGNAL(timeout()), this, SLOT(hideTip()));
00238     m_timer->start( 15000, true );
00239 
00240     m_textLabel->setText( text );
00241 
00242     setFilter( true );
00243 
00244     reposition();
00245     show();
00246 }
00247 
00248 void KonqFileTip::hideTip()
00249 {
00250     m_timer->stop();
00251     setFilter( false );
00252     if ( isShown() && m_view && m_view->viewport() &&
00253          (m_view->horizontalScrollBar()->isShown() || m_view->verticalScrollBar()->isShown()) )
00254       m_view->viewport()->update();
00255     hide();
00256 }
00257 void KonqFileTip::startDelayed()
00258 {
00259     if ( m_preview ) {
00260         KFileItemList oneItem;
00261         oneItem.append( m_item );
00262 
00263         m_previewJob = KIO::filePreview( oneItem, 256, 256, 64, 70, true, true, 0);
00264         connect( m_previewJob, SIGNAL( gotPreview( const KFileItem *, const QPixmap & ) ),
00265                  this, SLOT( gotPreview( const KFileItem *, const QPixmap & ) ) );
00266         connect( m_previewJob, SIGNAL( result( KIO::Job * ) ),
00267                  this, SLOT( gotPreviewResult() ) );
00268     }
00269 
00270     m_timer->disconnect( this );
00271     connect(m_timer, SIGNAL(timeout()), this, SLOT(showTip()));
00272     m_timer->start( 400, true );
00273 }
00274 
00275 void KonqFileTip::resizeEvent( QResizeEvent* event )
00276 {
00277     QFrame::resizeEvent(event);
00278     reposition();
00279 }
00280 
00281 bool KonqFileTip::eventFilter( QObject *, QEvent *e )
00282 {
00283     switch ( e->type() )
00284     {
00285         case QEvent::Leave:
00286         case QEvent::MouseButtonPress:
00287         case QEvent::MouseButtonRelease:
00288         case QEvent::KeyPress:
00289         case QEvent::KeyRelease:
00290         case QEvent::FocusIn:
00291         case QEvent::FocusOut:
00292         case QEvent::Wheel:
00293             hideTip();
00294         default: break;
00295     }
00296 
00297     return false;
00298 }
00299 
00300 #include "konq_filetip.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys