Fix crash if key bindings specified in profile cannot be found. Improve
[personal-kdebase.git] / apps / lib / konq / konq_filetip.cc
blobbae796fb6458ba0ff761cc66db58bd52d8de6804
1 /* This file is part of the KDE projects
2 Copyright (C) 1998, 1999 Torben Weis <weis@kde.org>
3 Copyright (C) 2000, 2001, 2002 David Faure <faure@kde.org>
4 Copyright (C) 2004 Martin Koller <m.koller@surfeu.at>
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; either
9 version 2 of the License, or (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; see the file COPYING. If not, write to
18 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
19 Boston, MA 02110-1301, USA.
22 #include <konq_filetip.h>
24 #include <kfileitem.h>
25 #include <kglobalsettings.h>
26 #include <kstandarddirs.h>
28 #include <QLabel>
29 #include <QToolTip>
30 #include <QApplication>
31 #include <QScrollBar>
32 #include <QLayout>
33 #include <QPainter>
34 #include <QScrollArea>
35 #include <QTimer>
36 #include <QPixmap>
37 #include <QGridLayout>
38 #include <QEvent>
39 #include <QFrame>
40 #include <QResizeEvent>
42 #ifdef Q_WS_X11
43 #include <fixx11h.h>
44 #endif
45 //--------------------------------------------------------------------------------
47 KonqFileTip::KonqFileTip( QScrollArea* parent )
48 : QFrame( 0 ),
49 m_on( false ),
50 m_preview( false ),
51 m_filter( false ),
52 m_corner( 0 ),
53 m_num( 0 ),
54 m_view( parent ),
55 m_previewJob( 0 )
57 setWindowFlags( Qt::FramelessWindowHint | Qt::Tool | Qt::WindowStaysOnTopHint | Qt::X11BypassWindowManagerHint );
58 m_iconLabel = new QLabel(this);
59 m_textLabel = new QLabel(this);
60 m_textLabel->setAlignment(Qt::AlignLeft | Qt::AlignTop);
62 QGridLayout* layout = new QGridLayout(this);
63 layout->setMargin(8);
64 layout->setSpacing(0);
65 layout->addWidget(m_iconLabel, 0, 0);
66 layout->addWidget(m_textLabel, 0, 1);
67 layout->setSizeConstraint(QLayout::SetFixedSize);
69 setPalette( QToolTip::palette() );
70 setContentsMargins( 1, 1, 1, 1 );
71 setFrameStyle( QFrame::Plain | QFrame::Box );
73 m_timer = new QTimer(this);
75 hide();
78 KonqFileTip::~KonqFileTip()
80 if ( m_previewJob ) {
81 m_previewJob->kill();
82 m_previewJob = 0;
86 void KonqFileTip::setPreview(bool on)
88 m_preview = on;
89 if(on)
90 m_iconLabel->show();
91 else
92 m_iconLabel->hide();
95 void KonqFileTip::setOptions( bool on, bool preview, int num )
97 setPreview(preview);
98 m_on = on;
99 m_num = num;
102 void KonqFileTip::setItem( const KFileItem &item, const QRect &rect, const QPixmap *pixmap )
104 hideTip();
106 if (!m_on) return;
108 if ( m_previewJob ) {
109 m_previewJob->kill();
110 m_previewJob = 0;
113 m_rect = rect;
114 m_item = item;
116 if ( !m_item.isNull() ) {
117 if (m_preview) {
118 if ( pixmap )
119 m_iconLabel->setPixmap( *pixmap );
120 else
121 m_iconLabel->setPixmap( QPixmap() );
124 // Don't start immediately, because the user could move the mouse over another item
125 // This avoids a quick sequence of started preview-jobs
126 m_timer->disconnect( this );
127 connect(m_timer, SIGNAL(timeout()), this, SLOT(startDelayed()));
128 m_timer->setSingleShot( true );
129 m_timer->start( 300 );
133 void KonqFileTip::reposition()
135 if ( m_rect.isEmpty() || !m_view || !m_view->viewport() ) return;
137 QRect rect = m_rect;
138 //QPoint off = m_view->viewport()->mapToGlobal( m_view->contentsToViewport( rect.topRight() ) );
139 int xOffset = m_view->horizontalScrollBar()->value();
140 int yOffset = m_view->verticalScrollBar()->value();
141 QPoint off = m_view->viewport()->mapToGlobal( QPoint( rect.x() - xOffset, rect.y() - yOffset ) );
142 rect.moveTopRight( off );
144 QPoint pos = rect.center();
145 // m_corner:
146 // 0: upperleft
147 // 1: upperright
148 // 2: lowerleft
149 // 3: lowerright
150 // 4+: none
151 m_corner = 0;
152 // should the tooltip be shown to the left or to the right of the ivi ?
153 QRect desk = KGlobalSettings::desktopGeometry(rect.center());
154 if (rect.center().x() + width() > desk.right())
156 // to the left
157 if (pos.x() - width() < 0) {
158 pos.setX(0);
159 m_corner = 4;
160 } else {
161 pos.setX( pos.x() - width() );
162 m_corner = 1;
165 // should the tooltip be shown above or below the ivi ?
166 if (rect.bottom() + height() > desk.bottom())
168 // above
169 pos.setY( rect.top() - height() );
170 m_corner += 2;
172 else pos.setY( rect.bottom() + 1 );
174 move( pos );
175 update();
178 void KonqFileTip::gotPreview( const KFileItem& item, const QPixmap& pixmap )
180 m_previewJob = 0;
181 if (item.url() != m_item.url()) return;
183 m_iconLabel -> setPixmap(pixmap);
186 void KonqFileTip::gotPreviewResult()
188 m_previewJob = 0;
191 void KonqFileTip::paintEvent(QPaintEvent *)
193 QPainter p( this );
194 static const char * const names[] = {
195 "arrow_topleft",
196 "arrow_topright",
197 "arrow_bottomleft",
198 "arrow_bottomright"
201 if (m_corner >= 4) { // 4 is empty, so don't draw anything
202 return;
205 if ( m_corners[m_corner].isNull())
206 m_corners[m_corner].load( KStandardDirs::locate( "data", QString::fromLatin1( "konqueror/pics/%1.png" ).arg( names[m_corner] ) ) );
208 QPixmap &pix = m_corners[m_corner];
210 switch ( m_corner )
212 case 0:
213 p.drawPixmap( 3, 3, pix );
214 break;
215 case 1:
216 p.drawPixmap( width() - pix.width() - 3, 3, pix );
217 break;
218 case 2:
219 p.drawPixmap( 3, height() - pix.height() - 3, pix );
220 break;
221 case 3:
222 p.drawPixmap( width() - pix.width() - 3, height() - pix.height() - 3, pix );
223 break;
227 void KonqFileTip::setFilter( bool enable )
229 if ( enable == m_filter ) return;
231 if ( enable ) {
232 qApp->installEventFilter( this );
234 else {
235 qApp->removeEventFilter( this );
237 m_filter = enable;
240 void KonqFileTip::showTip()
242 QString text = m_item.getToolTipText(m_num);
244 if ( text.isEmpty() ) return;
246 m_timer->disconnect( this );
247 connect(m_timer, SIGNAL(timeout()), this, SLOT(hideTip()));
248 m_timer->setSingleShot( true );
249 m_timer->start( 15000 );
251 m_textLabel->setText( text );
253 setFilter( true );
255 reposition();
256 show();
259 void KonqFileTip::hideTip()
261 m_timer->stop();
262 setFilter( false );
263 if ( isVisible() && m_view && m_view->viewport() &&
264 (m_view->horizontalScrollBar()->isVisible() || m_view->verticalScrollBar()->isVisible()) )
265 m_view->viewport()->update();
266 hide();
268 void KonqFileTip::startDelayed()
270 if ( m_preview ) {
271 KFileItemList oneItem;
272 oneItem.append( m_item );
274 m_previewJob = KIO::filePreview( oneItem, 256, 256, 64, 70, true, true, 0);
275 connect( m_previewJob, SIGNAL( gotPreview(const KFileItem &, const QPixmap &) ),
276 this, SLOT( gotPreview(const KFileItem &, const QPixmap &) ) );
277 connect( m_previewJob, SIGNAL( result( KJob * ) ),
278 this, SLOT( gotPreviewResult() ) );
281 m_timer->disconnect( this );
282 connect(m_timer, SIGNAL(timeout()), this, SLOT(showTip()));
283 m_timer->setSingleShot( true );
284 m_timer->start( 400 );
287 void KonqFileTip::resizeEvent( QResizeEvent* event )
289 QFrame::resizeEvent(event);
290 reposition();
293 bool KonqFileTip::eventFilter( QObject *, QEvent *e )
295 switch ( e->type() )
297 case QEvent::Leave:
298 case QEvent::MouseButtonPress:
299 case QEvent::MouseButtonRelease:
300 case QEvent::KeyPress:
301 case QEvent::KeyRelease:
302 case QEvent::FocusIn:
303 case QEvent::FocusOut:
304 case QEvent::Wheel:
305 hideTip();
306 default: break;
309 return false;
312 #include "konq_filetip.moc"