KIO
previewjob.cpp
Go to the documentation of this file.
00001 // -*- c++ -*- 00002 // vim: ts=4 sw=4 et 00003 /* This file is part of the KDE libraries 00004 Copyright (C) 2000 David Faure <faure@kde.org> 00005 2000 Carsten Pfeiffer <pfeiffer@kde.org> 00006 2001 Malte Starostik <malte.starostik@t-online.de> 00007 00008 This library is free software; you can redistribute it and/or 00009 modify it under the terms of the GNU Library General Public 00010 License as published by the Free Software Foundation; either 00011 version 2 of the License, or (at your option) any later version. 00012 00013 This library is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00016 Library General Public License for more details. 00017 00018 You should have received a copy of the GNU Library General Public License 00019 along with this library; see the file COPYING.LIB. If not, write to 00020 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00021 Boston, MA 02110-1301, USA. 00022 */ 00023 00024 #include "previewjob.h" 00025 #include <kdebug.h> 00026 00027 #include <sys/stat.h> 00028 #ifdef __FreeBSD__ 00029 #include <machine/param.h> 00030 #endif 00031 #include <sys/types.h> 00032 00033 #ifdef Q_OS_UNIX 00034 #include <sys/ipc.h> 00035 #include <sys/shm.h> 00036 #endif 00037 00038 #include <QtCore/QDir> 00039 #include <QtCore/QFile> 00040 #include <QtGui/QImage> 00041 #include <QtCore/QTimer> 00042 #include <QtCore/QRegExp> 00043 00044 #include <kfileitem.h> 00045 #include <kapplication.h> 00046 #include <kde_file.h> 00047 #include <ktemporaryfile.h> 00048 #include <kservicetypetrader.h> 00049 #include <kcodecs.h> 00050 #include <kglobal.h> 00051 #include <kstandarddirs.h> 00052 #include <kservice.h> 00053 #include <QtCore/QLinkedList> 00054 #include <kconfiggroup.h> 00055 #include <kprotocolinfo.h> 00056 00057 #include "jobuidelegate.h" 00058 #include "job_p.h" 00059 00060 namespace KIO { struct PreviewItem; } 00061 using namespace KIO; 00062 00063 struct KIO::PreviewItem 00064 { 00065 KFileItem item; 00066 KService::Ptr plugin; 00067 }; 00068 00069 class KIO::PreviewJobPrivate: public KIO::JobPrivate 00070 { 00071 public: 00072 enum { STATE_STATORIG, // if the thumbnail exists 00073 STATE_GETORIG, // if we create it 00074 STATE_CREATETHUMB // thumbnail:/ slave 00075 } state; 00076 PreviewJob *q; 00077 00078 KFileItemList initialItems; 00079 QStringList enabledPlugins; 00080 // Our todo list :) 00081 // We remove the first item at every step, so use QLinkedList 00082 QLinkedList<PreviewItem> items; 00083 // The current item 00084 PreviewItem currentItem; 00085 // The modification time of that URL 00086 time_t tOrig; 00087 // Path to thumbnail cache for the current size 00088 QString thumbPath; 00089 // Original URL of current item in TMS format 00090 // (file:///path/to/file instead of file:/path/to/file) 00091 QString origName; 00092 // Thumbnail file name for current item 00093 QString thumbName; 00094 // Size of thumbnail 00095 int width; 00096 int height; 00097 // Unscaled size of thumbnail (128 or 256 if cache is enabled) 00098 int cacheWidth; 00099 int cacheHeight; 00100 // Whether the thumbnail should be scaled 00101 bool bScale; 00102 // Whether we should save the thumbnail 00103 bool bSave; 00104 bool ignoreMaximumSize; 00105 int sequenceIndex; 00106 bool succeeded; 00107 // If the file to create a thumb for was a temp file, this is its name 00108 QString tempName; 00109 KIO::filesize_t maximumLocalSize; 00110 KIO::filesize_t maximumRemoteSize; 00111 // the size for the icon overlay 00112 int iconSize; 00113 // the transparency of the blended mimetype icon 00114 int iconAlpha; 00115 // Shared memory segment Id. The segment is allocated to a size 00116 // of extent x extent x 4 (32 bit image) on first need. 00117 int shmid; 00118 // And the data area 00119 uchar *shmaddr; 00120 // Root of thumbnail cache 00121 QString thumbRoot; 00122 00123 void getOrCreateThumbnail(); 00124 bool statResultThumbnail(); 00125 void createThumbnail( const QString& ); 00126 void determineNextFile(); 00127 void emitPreview(const QImage &thumb); 00128 00129 void startPreview(); 00130 void slotThumbData(KIO::Job *, const QByteArray &); 00131 00132 Q_DECLARE_PUBLIC(PreviewJob) 00133 }; 00134 00135 PreviewJob::PreviewJob( const KFileItemList &items, int width, int height, 00136 int iconSize, int iconAlpha, bool scale, bool save, 00137 const QStringList *enabledPlugins ) 00138 : KIO::Job(*new PreviewJobPrivate) 00139 { 00140 Q_D(PreviewJob); 00141 d->tOrig = 0; 00142 d->shmid = -1; 00143 d->shmaddr = 0; 00144 d->initialItems = items; 00145 d->enabledPlugins = enabledPlugins ? *enabledPlugins : QStringList(); 00146 d->width = width; 00147 d->height = height ? height : width; 00148 d->cacheWidth = d->width; 00149 d->cacheHeight = d->height; 00150 d->iconSize = iconSize; 00151 d->iconAlpha = iconAlpha; 00152 d->bScale = scale; 00153 d->bSave = save && scale; 00154 d->succeeded = false; 00155 d->thumbRoot = QDir::homePath() + "/.thumbnails/"; 00156 d->ignoreMaximumSize = false; 00157 d->sequenceIndex = 0; 00158 d->maximumLocalSize = 0; 00159 d->maximumRemoteSize = 0; 00160 00161 // Return to event loop first, determineNextFile() might delete this; 00162 QTimer::singleShot(0, this, SLOT(startPreview())); 00163 } 00164 00165 PreviewJob::~PreviewJob() 00166 { 00167 #ifdef Q_OS_UNIX 00168 Q_D(PreviewJob); 00169 if (d->shmaddr) { 00170 shmdt((char*)d->shmaddr); 00171 shmctl(d->shmid, IPC_RMID, 0); 00172 } 00173 #endif 00174 } 00175 00176 void PreviewJobPrivate::startPreview() 00177 { 00178 Q_Q(PreviewJob); 00179 // Load the list of plugins to determine which mimetypes are supported 00180 const KService::List plugins = KServiceTypeTrader::self()->query("ThumbCreator"); 00181 QMap<QString, KService::Ptr> mimeMap; 00182 00183 for (KService::List::ConstIterator it = plugins.constBegin(); it != plugins.constEnd(); ++it) { 00184 if (enabledPlugins.isEmpty() || enabledPlugins.contains((*it)->desktopEntryName())) { 00185 const QStringList mimeTypes = (*it)->serviceTypes(); 00186 for (QStringList::ConstIterator mt = mimeTypes.constBegin(); mt != mimeTypes.constEnd(); ++mt) 00187 mimeMap.insert(*mt, *it); 00188 } 00189 } 00190 00191 // Look for images and store the items in our todo list :) 00192 bool bNeedCache = false; 00193 KFileItemList::const_iterator kit = initialItems.constBegin(); 00194 const KFileItemList::const_iterator kend = initialItems.constEnd(); 00195 for ( ; kit != kend; ++kit ) 00196 { 00197 PreviewItem item; 00198 item.item = *kit; 00199 const QString mimeType = item.item.mimetype(); 00200 QMap<QString, KService::Ptr>::ConstIterator plugin = mimeMap.constFind(mimeType); 00201 if (plugin == mimeMap.constEnd()) 00202 00203 { 00204 QString groupMimeType = mimeType; 00205 groupMimeType.replace(QRegExp("/.*"), "/*"); 00206 plugin = mimeMap.constFind(groupMimeType); 00207 00208 if (plugin == mimeMap.constEnd()) 00209 { 00210 // check mime type inheritance, resolve aliases 00211 const KMimeType::Ptr mimeInfo = KMimeType::mimeType(mimeType, KMimeType::ResolveAliases); 00212 if (mimeInfo) { 00213 const QStringList parentMimeTypes = mimeInfo->allParentMimeTypes(); 00214 Q_FOREACH(const QString& parentMimeType, parentMimeTypes) { 00215 plugin = mimeMap.constFind(parentMimeType); 00216 if (plugin != mimeMap.constEnd()) break; 00217 } 00218 } 00219 } 00220 #if 0 // KDE4: should be covered by inheritance above, all text mimetypes inherit from text/plain 00221 // if that's not enough, we need to invent something else 00222 if (plugin == mimeMap.end()) 00223 { 00224 // check X-KDE-Text property 00225 KMimeType::Ptr mimeInfo = KMimeType::mimeType(mimeType); 00226 QVariant textProperty = mimeInfo->property("X-KDE-text"); 00227 if (textProperty.isValid() && textProperty.type() == QVariant::Bool) 00228 { 00229 if (textProperty.toBool()) 00230 { 00231 plugin = mimeMap.find("text/plain"); 00232 if (plugin == mimeMap.end()) 00233 { 00234 plugin = mimeMap.find( "text/*" ); 00235 } 00236 } 00237 } 00238 } 00239 #endif 00240 } 00241 00242 if (plugin != mimeMap.constEnd()) 00243 { 00244 item.plugin = *plugin; 00245 items.append(item); 00246 if (!bNeedCache && bSave && 00247 ((*kit).url().protocol() != "file" || 00248 !(*kit).url().directory( KUrl::AppendTrailingSlash ).startsWith(thumbRoot)) && 00249 (*plugin)->property("CacheThumbnail").toBool()) 00250 bNeedCache = true; 00251 } 00252 else 00253 { 00254 emit q->failed( *kit ); 00255 } 00256 } 00257 00258 KConfigGroup cg( KGlobal::config(), "PreviewSettings" ); 00259 maximumLocalSize = cg.readEntry( "MaximumSize", 5*1024*1024LL /* 5MB */ ); 00260 maximumRemoteSize = cg.readEntry( "MaximumRemoteSize", 0 ); 00261 00262 if (bNeedCache) 00263 { 00264 if (width <= 128 && height <= 128) cacheWidth = cacheHeight = 128; 00265 else cacheWidth = cacheHeight = 256; 00266 thumbPath = thumbRoot + (cacheWidth == 128 ? "normal/" : "large/"); 00267 KStandardDirs::makeDir(thumbPath, 0700); 00268 } 00269 else 00270 bSave = false; 00271 00272 initialItems.clear(); 00273 determineNextFile(); 00274 } 00275 00276 void PreviewJob::removeItem( const KUrl& url ) 00277 { 00278 Q_D(PreviewJob); 00279 for (QLinkedList<PreviewItem>::Iterator it = d->items.begin(); it != d->items.end(); ++it) 00280 if ((*it).item.url() == url) 00281 { 00282 d->items.erase(it); 00283 break; 00284 } 00285 00286 if (d->currentItem.item.url() == url) 00287 { 00288 KJob* job = subjobs().first(); 00289 job->kill(); 00290 removeSubjob( job ); 00291 d->determineNextFile(); 00292 } 00293 } 00294 00295 void KIO::PreviewJob::setSequenceIndex(int index) { 00296 d_func()->sequenceIndex = index; 00297 } 00298 00299 int KIO::PreviewJob::sequenceIndex() const { 00300 return d_func()->sequenceIndex; 00301 } 00302 00303 void PreviewJob::setIgnoreMaximumSize(bool ignoreSize) 00304 { 00305 d_func()->ignoreMaximumSize = ignoreSize; 00306 } 00307 00308 void PreviewJobPrivate::determineNextFile() 00309 { 00310 Q_Q(PreviewJob); 00311 if (!currentItem.item.isNull()) 00312 { 00313 if (!succeeded) 00314 emit q->failed( currentItem.item ); 00315 } 00316 // No more items ? 00317 if ( items.isEmpty() ) 00318 { 00319 q->emitResult(); 00320 return; 00321 } 00322 else 00323 { 00324 // First, stat the orig file 00325 state = PreviewJobPrivate::STATE_STATORIG; 00326 currentItem = items.first(); 00327 succeeded = false; 00328 items.removeFirst(); 00329 KIO::Job *job = KIO::stat( currentItem.item.url(), KIO::HideProgressInfo ); 00330 job->addMetaData( "no-auth-prompt", "true" ); 00331 q->addSubjob(job); 00332 } 00333 } 00334 00335 void PreviewJob::slotResult( KJob *job ) 00336 { 00337 Q_D(PreviewJob); 00338 00339 removeSubjob(job); 00340 Q_ASSERT ( !hasSubjobs() ); // We should have only one job at a time ... 00341 switch ( d->state ) 00342 { 00343 case PreviewJobPrivate::STATE_STATORIG: 00344 { 00345 if (job->error()) // that's no good news... 00346 { 00347 // Drop this one and move on to the next one 00348 d->determineNextFile(); 00349 return; 00350 } 00351 const KIO::UDSEntry entry = static_cast<KIO::StatJob*>(job)->statResult(); 00352 d->tOrig = entry.numberValue( KIO::UDSEntry::UDS_MODIFICATION_TIME, 0 ); 00353 00354 bool skipCurrentItem = false; 00355 const KIO::filesize_t size = (KIO::filesize_t)entry.numberValue( KIO::UDSEntry::UDS_SIZE, 0 ); 00356 const KUrl itemUrl = d->currentItem.item.mostLocalUrl(); 00357 if (itemUrl.isLocalFile() || KProtocolInfo::protocolClass(itemUrl.protocol()) == QLatin1String(":local")) 00358 { 00359 skipCurrentItem = !d->ignoreMaximumSize && size > d->maximumLocalSize 00360 && !d->currentItem.plugin->property("IgnoreMaximumSize").toBool(); 00361 } 00362 else 00363 { 00364 // For remote items the "IgnoreMaximumSize" plugin property is not respected 00365 skipCurrentItem = !d->ignoreMaximumSize && size > d->maximumRemoteSize; 00366 00367 // Remote directories are not supported, don't try to do a file_copy on them 00368 if (!skipCurrentItem) { 00369 // TODO update item.mimeType from the UDS entry, in case it wasn't set initially 00370 KMimeType::Ptr mime = d->currentItem.item.mimeTypePtr(); 00371 if (mime && mime->is("inode/directory")) { 00372 skipCurrentItem = true; 00373 } 00374 } 00375 } 00376 if (skipCurrentItem) 00377 { 00378 d->determineNextFile(); 00379 return; 00380 } 00381 00382 bool pluginHandlesSequences = d->currentItem.plugin->property("HandleSequences", QVariant::Bool).toBool(); 00383 00384 if ( !d->currentItem.plugin->property( "CacheThumbnail" ).toBool() || (d->sequenceIndex && pluginHandlesSequences) ) 00385 { 00386 // This preview will not be cached, no need to look for a saved thumbnail 00387 // Just create it, and be done 00388 d->getOrCreateThumbnail(); 00389 return; 00390 } 00391 00392 if ( d->statResultThumbnail() ) 00393 return; 00394 00395 d->getOrCreateThumbnail(); 00396 return; 00397 } 00398 case PreviewJobPrivate::STATE_GETORIG: 00399 { 00400 if (job->error()) 00401 { 00402 d->determineNextFile(); 00403 return; 00404 } 00405 00406 d->createThumbnail( static_cast<KIO::FileCopyJob*>(job)->destUrl().toLocalFile() ); 00407 return; 00408 } 00409 case PreviewJobPrivate::STATE_CREATETHUMB: 00410 { 00411 if (!d->tempName.isEmpty()) 00412 { 00413 QFile::remove(d->tempName); 00414 d->tempName.clear(); 00415 } 00416 d->determineNextFile(); 00417 return; 00418 } 00419 } 00420 } 00421 00422 bool PreviewJobPrivate::statResultThumbnail() 00423 { 00424 if ( thumbPath.isEmpty() ) 00425 return false; 00426 00427 KUrl url = currentItem.item.mostLocalUrl(); 00428 // Don't include the password if any 00429 url.setPass(QString()); 00430 origName = url.url(); 00431 00432 KMD5 md5( QFile::encodeName( origName ) ); 00433 thumbName = QFile::encodeName( md5.hexDigest() ) + ".png"; 00434 00435 QImage thumb; 00436 if ( !thumb.load( thumbPath + thumbName ) ) return false; 00437 00438 if ( thumb.text( "Thumb::URI", 0 ) != origName || 00439 thumb.text( "Thumb::MTime", 0 ).toInt() != tOrig ) return false; 00440 00441 QString thumbnailerVersion = currentItem.plugin->property("ThumbnailerVersion", QVariant::String).toString(); 00442 00443 if (!thumbnailerVersion.isEmpty() && thumb.text("Software", 0).startsWith("KDE Thumbnail Generator")) { 00444 //Check if the version matches 00445 //The software string should read "KDE Thumbnail Generator pluginName (vX)" 00446 QString softwareString = thumb.text("Software", 0).remove("KDE Thumbnail Generator").trimmed(); 00447 if (softwareString.isEmpty()) { 00448 // The thumbnail has been created with an older version, recreating 00449 return false; 00450 } 00451 int versionIndex = softwareString.lastIndexOf("(v"); 00452 if (versionIndex < 0) { 00453 return false; 00454 } 00455 00456 QString cachedVersion = softwareString.remove(0, versionIndex+2); 00457 cachedVersion.chop(1); 00458 uint thumbnailerMajor = thumbnailerVersion.toInt(); 00459 uint cachedMajor = cachedVersion.toInt(); 00460 if (thumbnailerMajor > cachedMajor) { 00461 return false; 00462 } 00463 } 00464 00465 // Found it, use it 00466 emitPreview( thumb ); 00467 succeeded = true; 00468 determineNextFile(); 00469 return true; 00470 } 00471 00472 00473 void PreviewJobPrivate::getOrCreateThumbnail() 00474 { 00475 Q_Q(PreviewJob); 00476 // We still need to load the orig file ! (This is getting tedious) :) 00477 const KFileItem& item = currentItem.item; 00478 const QString localPath = item.localPath(); 00479 if ( !localPath.isEmpty() ) 00480 createThumbnail( localPath ); 00481 else 00482 { 00483 state = PreviewJobPrivate::STATE_GETORIG; 00484 KTemporaryFile localFile; 00485 localFile.setAutoRemove(false); 00486 localFile.open(); 00487 KUrl localURL; 00488 localURL.setPath( tempName = localFile.fileName() ); 00489 const KUrl currentURL = item.mostLocalUrl(); 00490 KIO::Job * job = KIO::file_copy( currentURL, localURL, -1, KIO::Overwrite | KIO::HideProgressInfo /* No GUI */ ); 00491 job->addMetaData("thumbnail","1"); 00492 q->addSubjob(job); 00493 } 00494 } 00495 00496 void PreviewJobPrivate::createThumbnail( const QString &pixPath ) 00497 { 00498 Q_Q(PreviewJob); 00499 state = PreviewJobPrivate::STATE_CREATETHUMB; 00500 KUrl thumbURL; 00501 thumbURL.setProtocol("thumbnail"); 00502 thumbURL.setPath(pixPath); 00503 KIO::TransferJob *job = KIO::get(thumbURL, NoReload, HideProgressInfo); 00504 q->addSubjob(job); 00505 q->connect(job, SIGNAL(data(KIO::Job *, const QByteArray &)), SLOT(slotThumbData(KIO::Job *, const QByteArray &))); 00506 bool save = bSave && currentItem.plugin->property("CacheThumbnail").toBool() && !sequenceIndex; 00507 job->addMetaData("mimeType", currentItem.item.mimetype()); 00508 job->addMetaData("width", QString().setNum(save ? cacheWidth : width)); 00509 job->addMetaData("height", QString().setNum(save ? cacheHeight : height)); 00510 job->addMetaData("iconSize", QString().setNum(save ? 64 : iconSize)); 00511 job->addMetaData("iconAlpha", QString().setNum(iconAlpha)); 00512 job->addMetaData("plugin", currentItem.plugin->library()); 00513 if(sequenceIndex) 00514 job->addMetaData("sequence-index", QString().setNum(sequenceIndex)); 00515 00516 #ifdef Q_OS_UNIX 00517 if (shmid == -1) 00518 { 00519 if (shmaddr) { 00520 shmdt((char*)shmaddr); 00521 shmctl(shmid, IPC_RMID, 0); 00522 } 00523 shmid = shmget(IPC_PRIVATE, cacheWidth * cacheHeight * 4, IPC_CREAT|0600); 00524 if (shmid != -1) 00525 { 00526 shmaddr = (uchar *)(shmat(shmid, 0, SHM_RDONLY)); 00527 if (shmaddr == (uchar *)-1) 00528 { 00529 shmctl(shmid, IPC_RMID, 0); 00530 shmaddr = 0; 00531 shmid = -1; 00532 } 00533 } 00534 else 00535 shmaddr = 0; 00536 } 00537 if (shmid != -1) 00538 job->addMetaData("shmid", QString().setNum(shmid)); 00539 #endif 00540 } 00541 00542 void PreviewJobPrivate::slotThumbData(KIO::Job *, const QByteArray &data) 00543 { 00544 bool save = bSave && 00545 currentItem.plugin->property("CacheThumbnail").toBool() && 00546 (currentItem.item.url().protocol() != "file" || 00547 !currentItem.item.url().directory( KUrl::AppendTrailingSlash ).startsWith(thumbRoot)) && !sequenceIndex; 00548 QImage thumb; 00549 #ifdef Q_OS_UNIX 00550 if (shmaddr) 00551 { 00552 // Keep this in sync with kdebase/kioslave/thumbnail.cpp 00553 QDataStream str(data); 00554 int width, height; 00555 quint8 iFormat; 00556 str >> width >> height >> iFormat; 00557 QImage::Format format = static_cast<QImage::Format>( iFormat ); 00558 thumb = QImage(shmaddr, width, height, format ).copy(); 00559 } 00560 else 00561 #endif 00562 thumb.loadFromData(data); 00563 00564 if (thumb.isNull()) { 00565 QDataStream s(data); 00566 s >> thumb; 00567 } 00568 00569 QString tempFileName; 00570 bool savedCorrectly = false; 00571 if (save) 00572 { 00573 thumb.setText("Thumb::URI", origName); 00574 thumb.setText("Thumb::MTime", QString::number(tOrig)); 00575 thumb.setText("Thumb::Size", number(currentItem.item.size())); 00576 thumb.setText("Thumb::Mimetype", currentItem.item.mimetype()); 00577 QString thumbnailerVersion = currentItem.plugin->property("ThumbnailerVersion", QVariant::String).toString(); 00578 QString signature = QString("KDE Thumbnail Generator "+currentItem.plugin->name()); 00579 if (!thumbnailerVersion.isEmpty()) { 00580 signature.append(" (v"+thumbnailerVersion+')'); 00581 } 00582 thumb.setText("Software", signature); 00583 KTemporaryFile temp; 00584 temp.setPrefix(thumbPath + "kde-tmp-"); 00585 temp.setSuffix(".png"); 00586 temp.setAutoRemove(false); 00587 if (temp.open()) //Only try to write out the thumbnail if we 00588 { //actually created the temp file. 00589 tempFileName = temp.fileName(); 00590 savedCorrectly = thumb.save(tempFileName, "PNG"); 00591 } 00592 } 00593 if(savedCorrectly) 00594 { 00595 Q_ASSERT(!tempFileName.isEmpty()); 00596 KDE::rename(tempFileName, thumbPath + thumbName); 00597 } 00598 emitPreview( thumb ); 00599 succeeded = true; 00600 } 00601 00602 void PreviewJobPrivate::emitPreview(const QImage &thumb) 00603 { 00604 Q_Q(PreviewJob); 00605 QPixmap pix; 00606 if (thumb.width() > width || thumb.height() > height) 00607 pix = QPixmap::fromImage( thumb.scaled(QSize(width, height), Qt::KeepAspectRatio, Qt::SmoothTransformation) ); 00608 else 00609 pix = QPixmap::fromImage( thumb ); 00610 emit q->gotPreview(currentItem.item, pix); 00611 } 00612 00613 QStringList PreviewJob::availablePlugins() 00614 { 00615 QStringList result; 00616 const KService::List plugins = KServiceTypeTrader::self()->query("ThumbCreator"); 00617 for (KService::List::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) 00618 if (!result.contains((*it)->desktopEntryName())) 00619 result.append((*it)->desktopEntryName()); 00620 return result; 00621 } 00622 00623 QStringList PreviewJob::supportedMimeTypes() 00624 { 00625 QStringList result; 00626 const KService::List plugins = KServiceTypeTrader::self()->query("ThumbCreator"); 00627 for (KService::List::ConstIterator it = plugins.begin(); it != plugins.end(); ++it) 00628 result += (*it)->serviceTypes(); 00629 return result; 00630 } 00631 00632 PreviewJob *KIO::filePreview( const KFileItemList &items, int width, int height, 00633 int iconSize, int iconAlpha, bool scale, bool save, 00634 const QStringList *enabledPlugins ) 00635 { 00636 return new PreviewJob(items, width, height, iconSize, iconAlpha, 00637 scale, save, enabledPlugins); 00638 } 00639 00640 PreviewJob *KIO::filePreview( const KUrl::List &items, int width, int height, 00641 int iconSize, int iconAlpha, bool scale, bool save, 00642 const QStringList *enabledPlugins ) 00643 { 00644 KFileItemList fileItems; 00645 for (KUrl::List::ConstIterator it = items.begin(); it != items.end(); ++it) { 00646 Q_ASSERT( (*it).isValid() ); // please call us with valid urls only 00647 fileItems.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, *it, true)); 00648 } 00649 return new PreviewJob(fileItems, width, height, iconSize, iconAlpha, 00650 scale, save, enabledPlugins); 00651 } 00652 00653 #ifndef KDE_NO_DEPRECATED 00654 KIO::filesize_t PreviewJob::maximumFileSize() 00655 { 00656 KConfigGroup cg( KGlobal::config(), "PreviewSettings" ); 00657 return cg.readEntry( "MaximumSize", 5*1024*1024LL /* 5MB */ ); 00658 } 00659 #endif 00660 00661 #include "previewjob.moc"
KDE 4.6 API Reference