void BackgroundJobs::SearchForVideosWithoutVideoThumbnailsJob::execute()
{
    const DB::FileNameList images = DB::ImageDB::instance()->images();

    for( const DB::FileName& image : images ) {
        const DB::ImageInfoPtr info = image.info();
        if ( !info->isVideo() )
            continue;

        // silently ignore videos not (currently) on disk:
        if ( ! info->fileName().exists() )
            continue;

        const DB::FileName thumbnailName = BackgroundJobs::HandleVideoThumbnailRequestJob::frameName(info->fileName(),9);
        if ( thumbnailName.exists() )
            continue;

        BackgroundJobs::ReadVideoLengthJob* readVideoLengthJob = new BackgroundJobs::ReadVideoLengthJob(info->fileName(), BackgroundTaskManager::BackgroundVideoPreviewRequest);

        for (int i=0; i<10; ++i) {
            ExtractOneThumbnailJob* extractJob = new ExtractOneThumbnailJob( info->fileName(), i, BackgroundTaskManager::BackgroundVideoPreviewRequest );
            extractJob->addDependency(readVideoLengthJob);
        }

        BackgroundTaskManager::JobManager::instance()->addJob( readVideoLengthJob);
    }
    emit completed();
}
Utilities::StringSet MainWindow::ExternalPopup::mimeTypes( const DB::FileNameList& files )
{
    StringSet res;
    StringSet extensions;
    for( DB::FileNameList::ConstIterator fileIt = files.begin(); fileIt != files.end(); ++fileIt ) {
       const DB::FileName baseFileName = *fileIt;
       const int extStart = baseFileName.relative().lastIndexOf(QChar::fromLatin1('.'));
       const QString ext = baseFileName.relative().mid(extStart);
       if (! extensions.contains(ext)) {
           res.insert( mimeType( *fileIt ) );
           extensions.insert( ext );
       }
    }
    return res;
}
Exemplo n.º 3
0
void ToolTip::requestToolTip(const DB::FileName &fileName)
{
    if ( fileName.isNull() || fileName == m_currentFileName)
        return;
    m_currentFileName = fileName;
    requestImage( fileName );
}
void DB::FileInfo::parseKFileMetaInfo( const DB::FileName& fileName )
{
    KFileMetaInfo metainfo( fileName.absolute() );
    if ( !metainfo.isValid() )
        return;

    // Date.
    if ( metainfo.keys().contains( QString::fromLatin1( "CreationDate" ) ) ) {
        QDate date = metainfo.item( QString::fromLatin1( "CreationDate" )).value().toDate();
        if ( date.isValid() ) {
            m_date.setDate( date );

            if ( metainfo.keys().contains( QString::fromLatin1( "CreationTime" ) ) ) {
                QTime time = metainfo.item(QString::fromLatin1( "CreationTime" )).value().toTime();
                if ( time.isValid() )
                    m_date.setTime( time );
            }
        }
    }

    // Angle
    if ( metainfo.keys().contains( QString::fromLatin1( "Orientation" ) ) )
        m_angle = orientationToAngle( metainfo.item( QString::fromLatin1( "Orientation" ) ).value().toInt() );

    // Description
    if ( metainfo.keys().contains( QString::fromLatin1( "Comment" ) ) )
        m_description = metainfo.item( QString::fromLatin1( "Comment" ) ).value().toString();
}
void ThumbnailView::Delegate::paintCellText( QPainter* painter, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
    // Optimization based on result from KCacheGrind
    if ( !Settings::SettingsData::instance()->displayLabels() && !Settings::SettingsData::instance()->displayCategories() )
        return;

    DB::FileName fileName = model()->imageAt( index.row() );
    if ( fileName.isNull() )
        return;

    QString title = index.data( Qt::DisplayRole ).value<QString>();
    QRect rect = cellGeometryInfo()->cellTextGeometry();
    painter->setPen( Utilities::contrastColor( Settings::SettingsData::instance()->backgroundColor() ) );

    //Qt::TextWordWrap just in case, if the text's width is wider than the cell's width
    painter->drawText( rect.translated( option.rect.topLeft() ), Qt::AlignCenter | Qt::TextWordWrap, title );
}
bool RAWImageDecoder::_fileEndsWithExtensions( const DB::FileName& fileName,
                                               const QStringList& extensionList)
{
    for ( QStringList::ConstIterator it = extensionList.begin();
          it != extensionList.end(); ++it ) {
        if( fileName.relative().endsWith( *it, Qt::CaseInsensitive ) ) return true;
    }
    return false;
}
void ThumbnailView::ThumbnailDND::contentsDragMoveEvent( QDragMoveEvent* event )
{
    if ( event->provides( "text/uri-list" ) && widget()->m_selectionInteraction.isDragging() )
        event->accept();
    else {
        event->ignore();
        return;
    }

    const DB::FileName fileName = widget()->mediaIdUnderCursor();

    removeDropIndications();

    const QRect rect = widget()->visualRect( widget()->indexUnderCursor() );

    if ( ( event->pos().y() < 10 ) )
        widget()->scrollTo( widget()->indexUnderCursor(), QAbstractItemView::PositionAtCenter );
    if ( ( event->pos().y() > widget()->viewport()->visibleRegion().rects().first().height() - 10 ) )
        widget()->scrollTo( widget()->indexUnderCursor(), QAbstractItemView::PositionAtCenter );
    bool left = ( event->pos().x() - rect.x() < rect.width()/2 );
    if ( left ) {
        if ( fileName.isNull() ) {
            // We're dragging behind the last item
            model()->setRightDropItem(model()->imageAt( model()->imageCount() - 1));
        } else {
            model()->setLeftDropItem(fileName);
            const int index = model()->indexOf(fileName) - 1;
            if ( index != -1 )
                model()->setRightDropItem(model()->imageAt(index));
        }
    }

    else {
        model()->setRightDropItem(fileName);
        const int index = model()->indexOf(fileName) + 1;
        if (index != model()->imageCount())
            model()->setLeftDropItem(model()->imageAt(index));
    }

    model()->updateCell(model()->leftDropItem());
    model()->updateCell(model()->rightDropItem());
}
DB::FileInfo::FileInfo( const DB::FileName& fileName, DB::ExifMode mode )
    : m_angle(0)
{
#ifdef HAVE_EXIV2
    parseEXIV2( fileName );
#else
    parseKFileMetaInfo( fileName );
#endif


    if ( updateDataFromFileTimeStamp(fileName,mode))
        m_date = QFileInfo( fileName.absolute() ).lastModified();
}
bool RAWImageDecoder::_fileExistsWithExtensions( const DB::FileName& fileName,
                                                 const QStringList& extensionList) const
{
    QString baseFileName = fileName.absolute();
    int extStart = baseFileName.lastIndexOf(QChar::fromLatin1('.'));
    // We're interested in xxx.yyy, not .yyy
    if (extStart <= 1) return false;
    baseFileName.remove(extStart, baseFileName.length() - extStart);
    for ( QStringList::ConstIterator it = extensionList.begin();
          it != extensionList.end(); ++it ) {
        if (QFile::exists(baseFileName + *it)) return true;
    }
    return false;
}
Exemplo n.º 10
0
DB::FileName ImageDB::findFirstItemInRange(const DB::FileNameList& images,
                                           const ImageDate& range,
                                           bool includeRanges) const
{
    DB::FileName candidate;
    QDateTime candidateDateStart;
    for (const DB::FileName& fileName : images) {
        ImageInfoPtr iInfo = info(fileName);

        ImageDate::MatchType match = iInfo->date().isIncludedIn(range);
        if (match == DB::ImageDate::ExactMatch ||
            (includeRanges && match == DB::ImageDate::RangeMatch)) {
            if (candidate.isNull() ||
                iInfo->date().start() < candidateDateStart) {
                candidate = fileName;
                // Looking at this, can't this just be iInfo->date().start()?
                // Just in the middle of refactoring other stuff, so leaving
                // this alone now. TODO(hzeller): revisit.
                candidateDateStart = info(candidate)->date().start();
            }
        }
    }
    return candidate;
}
bool RAWImageDecoder::_fileIsKnownWithExtensions( const DB::FileNameSet& files,
                                                  const DB::FileName& fileName,
                                                  const QStringList& extensionList) const
{
    QString baseFileName = fileName.absolute();
    int extStart = baseFileName.lastIndexOf(QChar::fromLatin1('.'));
    if (extStart <= 1) return false;
    baseFileName.remove(extStart, baseFileName.length() - extStart);
    for ( QStringList::ConstIterator it = extensionList.begin();
          it != extensionList.end(); ++it ) {
        if (files.contains(DB::FileName::fromAbsolutePath(baseFileName + *it)) )
            return true;
    }
    return false;
}
ImageInfo::ImageInfo( const DB::FileName& fileName, MediaType type, bool readExifInfo )
    :  m_imageOnDisk( YesOnDisk ), m_null( false ), m_size( -1, -1 ), m_type( type )
      , m_rating(-1), m_stackId(0), m_stackOrder(0)
      , m_videoLength(-1)
      , m_locked(false), m_delaySaving( true )
{
    QFileInfo fi( fileName.absolute() );
    m_label = fi.completeBaseName();
    m_angle = 0;

    setFileName(fileName);

    // Read EXIF information
    if ( readExifInfo )
        readExif(fileName, EXIFMODE_INIT);

    m_dirty = false;
    m_delaySaving = false;
}
QString MainWindow::ExternalPopup::mimeType( const DB::FileName& file )
{
    return KMimeType::findByPath(file.absolute(), 0, true)->name();
}
bool ImageInfo::imageOnDisk( const DB::FileName& fileName )
{
    return fileName.exists();
}
static DB::StackID getStackId(const DB::FileName& fileName)
{
    return fileName.info()->stackId();
}
bool RAWImageDecoder::_decode( QImage *img, const DB::FileName& imageFile, QSize* fullSize, int dim)
{
    /* width and height seem to be only hints, ignore */
    Q_UNUSED( dim );

#ifdef HAVE_KDCRAW
#if KDCRAW_VERSION >= 0x020200
    if ( !KDcrawIface::KDcraw::loadRawPreview( *img, imageFile.absolute() ) )
#else
    if ( !KDcrawIface::KDcraw::loadDcrawPreview( *img, imageFile.absolute() ) )
#endif
        return false;

    // FIXME: The preview data for Canon's image is always returned in its non-rotated form by libkdcraw, ie. KPA should do the rotation.
    // FIXME: This will happen later on.
    if ( Settings::SettingsData::instance()->useRawThumbnail() &&
         img->width() >= Settings::SettingsData::instance()->useRawThumbnailSize().width() &&
         img->height() >= Settings::SettingsData::instance()->useRawThumbnailSize().height() )
        return true;

    KDcrawIface::DcrawInfoContainer metadata;
    if (!KDcrawIface::KDcraw::rawFileIdentify(metadata, imageFile.absolute()))
        return false;

    if ((img->width() < metadata.imageSize.width() * 0.8) ||
        (img->height() < metadata.imageSize.height() * 0.8)) {

        // let's try to get a better resolution
        KDcrawIface::KDcraw decoder;
        KDcrawIface::RawDecodingSettings rawDecodingSettings;

        if ( rawDecodingSettings.sixteenBitsImage ) {
            kDebug() << "16 bits per color channel is not supported yet";
            return false;
        } else {
            QByteArray imageData; /* 3 bytes for each pixel,  */
            int width, height, rgbmax;
            if ( !decoder.decodeRAWImage( imageFile.absolute(), rawDecodingSettings, imageData, width, height, rgbmax ) )
                return false;

            // Now the funny part, how to turn this fugly QByteArray into an QImage. Yay!
            *img = QImage(width, height, QImage::Format_RGB32);
            if (img->isNull())
                return false;

            uchar* data = img->bits();

            for ( int i = 0; i < imageData.size(); i += 3, data += 4 ) {
                data[0] = imageData[i + 2]; // blue
                data[1] = imageData[i + 1]; // green
                data[2] = imageData[i];     // red
                data[3] = 0xff;             // alpha
            }
        }
    }

    if ( fullSize )
        *fullSize = img->size();

    return true;
#else /* HAVE_KDCRAW */
    Q_UNUSED( img );
    Q_UNUSED( imageFile );
    Q_UNUSED( fullSize );
    return false;
#endif /* HAVE_KDCRAW */
}