00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "kimagefilepreview.h"
00012
00013 #include <QtGui/QLayout>
00014 #include <QtGui/QLabel>
00015 #include <QtGui/QPainter>
00016 #include <QtGui/QComboBox>
00017 #include <QtGui/QCheckBox>
00018 #include <QtGui/QResizeEvent>
00019 #include <QtCore/QTimer>
00020 #include <QtCore/QTimeLine>
00021
00022 #include <kapplication.h>
00023 #include <kglobalsettings.h>
00024 #include <kconfig.h>
00025 #include <kglobal.h>
00026 #include <kiconloader.h>
00027 #include <kpushbutton.h>
00028 #include <kstandarddirs.h>
00029 #include <kdebug.h>
00030 #include <klocale.h>
00031 #include <kfiledialog.h>
00032 #include <kfileitem.h>
00033 #include <kio/previewjob.h>
00034 #include <kconfiggroup.h>
00035
00036 #include <config-kfile.h>
00037
00038
00039
00040 class KImageFilePreview::KImageFilePreviewPrivate
00041 {
00042 public:
00043 KImageFilePreviewPrivate()
00044 : m_job(0)
00045 , clear(true)
00046 {
00047 m_timeLine = new QTimeLine(150);
00048 m_timeLine->setCurveShape(QTimeLine::EaseInCurve);
00049 m_timeLine->setDirection(QTimeLine::Forward);
00050 m_timeLine->setFrameRange(0, 100);
00051 }
00052
00053 ~KImageFilePreviewPrivate()
00054 {
00055 delete m_timeLine;
00056 }
00057
00058 void _k_slotResult( KJob* );
00059 void _k_slotFailed( const KFileItem& );
00060 void _k_slotStepAnimation( int frame );
00061 void _k_slotFinished( );
00062 void _k_slotActuallyClear( );
00063
00064 KUrl currentURL;
00065 KUrl lastShownURL;
00066 QLabel *imageLabel;
00067 KIO::PreviewJob *m_job;
00068 QTimeLine *m_timeLine;
00069 QPixmap m_pmCurrent;
00070 QPixmap m_pmTransition;
00071 float m_pmCurrentOpacity;
00072 float m_pmTransitionOpacity;
00073 bool clear;
00074 };
00075
00076 KImageFilePreview::KImageFilePreview( QWidget *parent )
00077 : KPreviewWidgetBase(parent), d(new KImageFilePreviewPrivate)
00078 {
00079 QVBoxLayout *vb = new QVBoxLayout( this );
00080 vb->setMargin( 0 );
00081 vb->setSpacing( KDialog::spacingHint() );
00082
00083 d->imageLabel = new QLabel(this);
00084 d->imageLabel->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
00085 d->imageLabel->setSizePolicy(QSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding));
00086 vb->addWidget(d->imageLabel);
00087
00088 setSupportedMimeTypes( KIO::PreviewJob::supportedMimeTypes() );
00089 setMinimumWidth( 50 );
00090
00091 connect(d->m_timeLine, SIGNAL(frameChanged(int)), this, SLOT(_k_slotStepAnimation(int)));
00092 connect(d->m_timeLine, SIGNAL(finished()), this, SLOT(_k_slotFinished()));
00093 }
00094
00095 KImageFilePreview::~KImageFilePreview()
00096 {
00097 if (d->m_job) {
00098 d->m_job->kill();
00099 }
00100
00101 delete d;
00102 }
00103
00104 void KImageFilePreview::showPreview()
00105 {
00106
00107 KUrl url = d->currentURL;
00108 showPreview( url, true );
00109 }
00110
00111
00112 void KImageFilePreview::showPreview( const KUrl& url )
00113 {
00114 showPreview( url, false );
00115 }
00116
00117 void KImageFilePreview::showPreview( const KUrl &url, bool force )
00118 {
00119 if (!url.isValid() ||
00120 (d->lastShownURL.isValid() &&
00121 url.equals(d->lastShownURL, KUrl::CompareWithoutTrailingSlash) &&
00122 d->currentURL.isValid()))
00123 return;
00124
00125 d->clear = false;
00126 d->currentURL = url;
00127 d->lastShownURL = url;
00128
00129 int w = d->imageLabel->contentsRect().width() - 4;
00130 int h = d->imageLabel->contentsRect().height() - 4;
00131
00132 if (d->m_job) {
00133 disconnect(d->m_job, SIGNAL(result(KJob *)),
00134 this, SLOT( _k_slotResult( KJob * )));
00135 disconnect(d->m_job, SIGNAL(gotPreview(const KFileItem&,
00136 const QPixmap& )), this,
00137 SLOT( gotPreview( const KFileItem&, const QPixmap& ) ));
00138
00139 disconnect(d->m_job, SIGNAL(failed(const KFileItem&)),
00140 this, SLOT(_k_slotFailed(const KFileItem&)));
00141
00142 d->m_job->kill();
00143 }
00144
00145 d->m_job = createJob(url, w, h);
00146 if ( force )
00147 d->m_job->setIgnoreMaximumSize(true);
00148
00149 connect(d->m_job, SIGNAL(result(KJob *)),
00150 this, SLOT( _k_slotResult( KJob * )));
00151 connect(d->m_job, SIGNAL(gotPreview(const KFileItem&,
00152 const QPixmap& )),
00153 SLOT( gotPreview( const KFileItem&, const QPixmap& ) ));
00154
00155 connect(d->m_job, SIGNAL(failed(const KFileItem&)),
00156 this, SLOT(_k_slotFailed(const KFileItem&)));
00157 }
00158
00159 void KImageFilePreview::resizeEvent( QResizeEvent *e )
00160 {
00161 clearPreview();
00162 d->currentURL = KUrl();
00163 showPreview( d->lastShownURL );
00164 }
00165
00166 QSize KImageFilePreview::sizeHint() const
00167 {
00168 return QSize( 100, 200 );
00169 }
00170
00171 KIO::PreviewJob * KImageFilePreview::createJob( const KUrl& url, int w, int h )
00172 {
00173 KUrl::List urls;
00174 urls.append( url );
00175 return KIO::filePreview( urls, w, h, 0, 0, true, false );
00176 }
00177
00178 void KImageFilePreview::gotPreview( const KFileItem& item, const QPixmap& pm )
00179 {
00180 if (item.url() == d->currentURL) {
00181 if (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) {
00182 if (d->m_timeLine->state() == QTimeLine::Running) {
00183 d->m_timeLine->setCurrentTime(0);
00184 }
00185
00186 d->m_pmTransition = pm;
00187 d->m_pmTransitionOpacity = 0;
00188 d->m_pmCurrentOpacity = 1;
00189 d->m_timeLine->setDirection(QTimeLine::Forward);
00190 d->m_timeLine->start();
00191 }
00192 else
00193 {
00194 d->imageLabel->setPixmap(pm);
00195 }
00196 }
00197 }
00198
00199 void KImageFilePreview::KImageFilePreviewPrivate::_k_slotFailed( const KFileItem& item )
00200 {
00201 if ( item.isDir() )
00202 imageLabel->clear();
00203 else if (item.url() == currentURL)
00204 imageLabel->setPixmap(SmallIcon( "image-missing", KIconLoader::SizeLarge,
00205 KIconLoader::DisabledState ));
00206 }
00207
00208 void KImageFilePreview::KImageFilePreviewPrivate::_k_slotResult( KJob *job )
00209 {
00210 if (job == m_job) {
00211 m_job = 0L;
00212 }
00213 }
00214
00215 void KImageFilePreview::KImageFilePreviewPrivate::_k_slotStepAnimation( int frame )
00216 {
00217 QPixmap pm(QSize(qMax(m_pmCurrent.size().width(), m_pmTransition.size().width()),
00218 qMax(m_pmCurrent.size().height(), m_pmTransition.size().height())));
00219 pm.fill(Qt::transparent);
00220
00221 QPainter p(&pm);
00222 p.setOpacity(m_pmCurrentOpacity);
00223
00224
00225 if (!m_pmCurrent.isNull())
00226 p.drawPixmap(QPoint(((float) pm.size().width() - m_pmCurrent.size().width()) / 2.0,
00227 ((float) pm.size().height() - m_pmCurrent.size().height()) / 2.0), m_pmCurrent);
00228 if (!m_pmTransition.isNull()) {
00229 p.setOpacity(m_pmTransitionOpacity);
00230 p.drawPixmap(QPoint(((float) pm.size().width() - m_pmTransition.size().width()) / 2.0,
00231 ((float) pm.size().height() - m_pmTransition.size().height()) / 2.0), m_pmTransition);
00232 }
00233 p.end();
00234
00235 imageLabel->setPixmap(pm);
00236
00237 m_pmCurrentOpacity = qMax(m_pmCurrentOpacity - 0.4, 0.0);
00238 m_pmTransitionOpacity = qMin(m_pmTransitionOpacity + 0.4, 1.0);
00239 }
00240
00241 void KImageFilePreview::KImageFilePreviewPrivate::_k_slotFinished()
00242 {
00243 m_pmCurrent = m_pmTransition;
00244 m_pmTransitionOpacity = 0;
00245 m_pmCurrentOpacity = 1;
00246 m_pmTransition = QPixmap();
00247
00248
00249 imageLabel->setPixmap(m_pmCurrent);
00250 clear = false;
00251 }
00252
00253 void KImageFilePreview::clearPreview()
00254 {
00255 if (d->m_job) {
00256 d->m_job->kill();
00257 d->m_job = 0L;
00258 }
00259
00260 if (d->clear || d->m_timeLine->state() == QTimeLine::Running) {
00261 return;
00262 }
00263
00264 if (KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects) {
00265 d->m_pmTransition = QPixmap();
00266
00267 if (!d->m_pmCurrent.isNull()) {
00268 d->m_timeLine->setCurrentTime(0);
00269 d->m_timeLine->setDirection(QTimeLine::Backward);
00270 d->m_timeLine->start();
00271 }
00272 d->currentURL = KUrl();
00273 d->clear = true;
00274 }
00275 else
00276 {
00277 d->imageLabel->clear();
00278 }
00279 }
00280
00281 #include "kimagefilepreview.moc"