Example #1
0
void DirModel::delayedPreview()
{
    QHash<QUrl, QPersistentModelIndex>::const_iterator i = m_filesToPreview.constBegin();

    KFileItemList list;

    while (i != m_filesToPreview.constEnd()) {
        QUrl file = i.key();
        QPersistentModelIndex index = i.value();


        if (!m_previewJobs.contains(file) && file.isValid()) {
            list.append(KFileItem(file, QString(), 0));
            m_previewJobs.insert(file, QPersistentModelIndex(index));
        }

        ++i;
    }

    if (list.size() > 0) {
        KIO::PreviewJob* job = KIO::filePreview(list, m_screenshotSize);
        job->setIgnoreMaximumSize(true);
        // qDebug() << "Created job" << job;
        connect(job, &KIO::PreviewJob::gotPreview,
                this, &DirModel::showPreview);
        connect(job, &KIO::PreviewJob::failed,
                this, &DirModel::previewFailed);
    }

    m_filesToPreview.clear();
}
void BatchProcessImagesDialog::slotImageSelected(QTreeWidgetItem * item)
{
    if (!item || m_listFiles->topLevelItemCount() == 0)
    {
        m_ui->m_imageLabel->clear();
        return;
    }

    BatchProcessImagesItem *pitem = static_cast<BatchProcessImagesItem*>(item);

    m_ui->m_imageLabel->clear();

    QString IdemIndexed = "file:" + pitem->pathSrc();

    KUrl url(IdemIndexed);

    if ( !url.isValid() )
        return;

#if KDE_IS_VERSION(4,7,0)
    KFileItemList items;
    items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true));
    KIO::PreviewJob* m_thumbJob = KIO::filePreview(items, QSize(m_ui->m_imageLabel->height(), m_ui->m_imageLabel->height()));
#else
    KIO::PreviewJob* m_thumbJob = KIO::filePreview(url, m_ui->m_imageLabel->height());
#endif

    connect(m_thumbJob, SIGNAL(gotPreview(KFileItem,QPixmap)),
            this, SLOT(slotGotPreview(KFileItem,QPixmap)));
}
Example #3
0
void ThumbView::slImageChanged( KFileItem *kfit )
{
   if( ! kfit ) return;
   // kdDebug(28000) << "changes to one thumbnail!" << endl;

   KURL thumbDir = currentDir();
   KURL itemUrl = kfit->url();

   /* delete filename */
   itemUrl.setFileName( QString());
   if( !itemUrl.equals( thumbDir, true ))
   {
      // kdDebug(28000) << "returning, because directory does not match: " << itemUrl.prettyURL() << endl;
      // kdDebug(28000) << "and my URL: " << thumbDir.prettyURL() << endl;
      return;
   }

   if( deleteImage( kfit ))
   {
      kdDebug(28000) << "was changed, deleted first!" << endl;
   }
   /* Trigger a new reading */
   KFileItemList li;
   li.append( kfit );
   slNewFileItems( li );
}
Example #4
0
void KrPreviewJob::slotStartJob()
{
    ASSERT(_job == 0);
    ASSERT(!_scheduled.isEmpty());

    _hash.clear();
    sort();

    int size = _parent->_view->fileIconSize();

    KFileItemList list;
    for(int i = 0; i < _scheduled.count() && i < MAX_CHUNK_SIZE; i++) {
        KFileItem fi(_scheduled[i]->getVfile()->vfile_getUrl(), 0, 0);
        list.append(fi);
        _hash.insert(fi, _scheduled[i]);
    }
    QStringList allPlugins = KIO::PreviewJob::availablePlugins();
    _job = new KIO::PreviewJob(list, QSize(size, size), &allPlugins);
    _job->setOverlayIconAlpha(0);
    _job->setOverlayIconSize(0);
    _job->setScaleType(KIO::PreviewJob::ScaledAndCached);
    connect(_job, SIGNAL(gotPreview(const KFileItem&, const QPixmap&)), SLOT(slotGotPreview(const KFileItem&, const QPixmap&)));
    connect(_job, SIGNAL(failed(const KFileItem&)), SLOT(slotFailed(const KFileItem&)));
    connect(_job, SIGNAL(result(KJob*)), SLOT(slotJobResult(KJob*)));
}
Example #5
0
void  ThumbView::slCheckForUpdate( KFileItem *kfit )
{
   if( ! kfit ) return;

   kdDebug(28000) << "Checking for update of thumbview!" << endl;

   KURL searchUrl = kfit->url();
   bool haveItem = false;

   /* iterate over all icon items and compare urls.
    * TODO: Check the parent url to avoid iteration over all */
   for ( QIconViewItem *item = m_iconView->firstItem(); item && !haveItem;
	 item = item->nextItem() )
   {
      if( searchUrl == static_cast<ThumbViewItem*>(item)->itemUrl() )
      {
	 haveItem = true;
      }
   }

   /* if we still do not have the item, it is not in the thumbview. */
   if( ! haveItem )
   {
      KFileItemList kfiList;

      kfiList.append( kfit );
      slNewFileItems( kfiList );
   }

}
Example #6
0
void UploadDialog::imageSelected(QTreeWidgetItem* item)
{
    if( !item || m_transferring )
    {
        m_imagePreview->clear();
        return;
    }

    ImageListItem* pitem = static_cast<ImageListItem*>( item );
    if ( !pitem ) return;

    m_imagePreview->clear();

    QString IdemIndexed = "file:" + pitem->pathSrc();

    KUrl url( IdemIndexed );

    if ( !url.isValid() )
        return;

#if KDE_IS_VERSION(4,7,0)
    KFileItemList items;
    items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true));
    KIO::PreviewJob* m_thumbJob = KIO::filePreview(items, QSize(m_imagePreview->height(), m_imagePreview->height()));
#else
    KIO::PreviewJob* m_thumbJob = KIO::filePreview(url, m_imagePreview->height());
#endif

    connect(m_thumbJob, SIGNAL(gotPreview(const KFileItem*,QPixmap)),
            this,   SLOT(gotImagePreview(const KFileItem*,QPixmap)) );
}
Example #7
0
bool TrashImpl::synchronousDel( const TQString& path, bool setLastErrorCode, bool isDir )
{
    const int oldErrorCode = m_lastErrorCode;
    const TQString oldErrorMsg = m_lastErrorMessage;
    KURL url;
    url.setPath( path );

    // First ensure that all dirs have u+w permissions,
    // otherwise we won't be able to delete files in them (#130780).
    if ( isDir ) {
        kdDebug() << k_funcinfo << "chmod'ing " << url << endl;
        KFileItem fileItem( url, "inode/directory", KFileItem::Unknown );
        KFileItemList fileItemList;
        fileItemList.append( &fileItem );
        TDEIO::ChmodJob* chmodJob = TDEIO::chmod( fileItemList, 0200, 0200, TQString::null, TQString::null, true /*recursive*/, false /*showProgressInfo*/ );
        connect( chmodJob, TQT_SIGNAL( result(TDEIO::Job *) ),
                 this, TQT_SLOT( jobFinished(TDEIO::Job *) ) );
        tqApp->eventLoop()->enterLoop();
    }

    kdDebug() << k_funcinfo << "deleting " << url << endl;
    TDEIO::DeleteJob *job = TDEIO::del( url, false, false );
    connect( job, TQT_SIGNAL( result(TDEIO::Job *) ),
             this, TQT_SLOT( jobFinished(TDEIO::Job *) ) );
    tqApp->eventLoop()->enterLoop();
    bool ok = m_lastErrorCode == 0;
    if ( !setLastErrorCode ) {
        m_lastErrorCode = oldErrorCode;
        m_lastErrorMessage = oldErrorMsg;
    }
    return ok;
}
Example #8
0
// caller needs to delete the returned list!
static KFileItemList * fileItemList( const TDECmdLineArgs *args )
{
    KFileItemList * items = new KFileItemList();
    items->setAutoDelete( true );
    for ( int i = 0; i < args->count(); i++ )
        items->append( new KFileItem( KFileItem::Unknown,
                                     KFileItem::Unknown,
                                     args->url( i ) ));
    return items;
}
Example #9
0
void PreviewTest::slotGenerate()
{
    KFileItemList items;
    items.append(KFileItem(QUrl::fromUserInput(m_url->text())));

    KIO::PreviewJob *job = KIO::filePreview(items, QSize(m_preview->width(), m_preview->height()));
    connect(job, SIGNAL(result(KJob*)), SLOT(slotResult(KJob*)));
    connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)), SLOT(slotPreview(KFileItem,QPixmap)));
    connect(job, SIGNAL(failed(KFileItem)), SLOT(slotFailed()));
}
Example #10
0
void KSysinfoPart::slotResult( KIO::Job *job )
{
    KIO::StatJob *sjob = dynamic_cast<KIO::StatJob*>( job );
    if (!job)
        return;

    KFileItem item(sjob->statResult(), sjob->url());
    KFileItemList list;
    list.append(&item);
    emit browserExtension()->popupMenu( 0, QCursor::pos(), list );
}
Example #11
0
void IconView::contextMenuEvent( QContextMenuEvent* event )
{
    QModelIndex index = indexAt( event->pos() );
    if ( !index.isValid() || m_selectionModel->selectedIndexes().isEmpty() ) {
        QMenu* menu = new QMenu;
        menu->addAction( m_actionCollection.action( "new_menu" ) );
        menu->addSeparator();
        menu->addAction( m_actionCollection.action( "undo" ) );
        menu->addAction( m_actionCollection.action( "paste" ) );
        menu->addSeparator();
        menu->addAction( m_actionCollection.action( "refresh" ) );
        menu->addSeparator();
        menu->addAction( m_actionCollection.action( "wallpaper" ) );
        if ( event->reason() == QContextMenuEvent::Keyboard )
            menu->exec( QPoint( 0, 0 ) );
        else
            menu->exec( event->pos() );
        delete menu;
        return;
    }

    KFileItemList items;
    foreach ( const QModelIndex &index, m_selectionModel->selectedIndexes() ) {
        KFileItem item = m_model->itemForIndex( m_proxyModel->mapToSource( index ) );
        if ( !item.isNull() )
            items.append( item );
    }

    QAction* pasteTo = m_actionCollection.action( "pasteto" );
    if ( pasteTo ) {
        pasteTo->setEnabled( m_actionCollection.action( "paste" )->isEnabled() );
        pasteTo->setText( m_actionCollection.action( "paste" )->text() );
    }

    QList<QAction*> editActions;
    editActions.append( m_actionCollection.action( "rename" ) );
    editActions.append( m_actionCollection.action( "trash" ) );
    KConfigGroup configGroup( KGlobal::config(), "KDE" );
    bool showDeleteCommand = configGroup.readEntry( "ShowDeleteCommand", false );
    if ( showDeleteCommand )
        editActions.append( m_actionCollection.action( "del" ) );
    KParts::BrowserExtension::ActionGroupMap actionGroups;
    actionGroups.insert( "editactions", editActions );
    KParts::BrowserExtension::PopupFlags flags = KParts::BrowserExtension::ShowProperties;
    flags |= KParts::BrowserExtension::ShowUrlOperations;
    KonqPopupMenu* contextMenu = new KonqPopupMenu( items, KUrl(QDir::homePath()), m_actionCollection, m_newMenu,
                                                    KonqPopupMenu::ShowNewWindow, flags,
                                                    QApplication::desktop(),
                                                    KBookmarkManager::userBookmarksManager(),
                                                    actionGroups );
    contextMenu->exec( event->pos() );
    delete contextMenu;
}
Example #12
0
void CFontFileListView::properties()
{
    QList<QTreeWidgetItem *> items(selectedItems());
    QTreeWidgetItem          *item;
    KFileItemList            files;

    foreach(item, items)
        if(item->parent())
            files.append(KFileItem(KUrl::fromPath(item->text(0)),
                                   KMimeType::findByPath(item->text(0))->name(),
                                   item->text(COL_LINK).isEmpty() ? S_IFREG : S_IFLNK));

    if(files.count())
    {
        KPropertiesDialog dlg(files, this);
        dlg.exec();
    }
}
Example #13
0
void IconManager::updatePreviews()
{
    if (!m_showPreview) {
        return;
    }

    killPreviewJobs();
    m_pendingItems.clear();
    m_dispatchedItems.clear();

    KFileItemList itemList;
    const int rowCount = m_model->rowCount();
    for (int row = 0; row < rowCount; ++row) {
        const QModelIndex index = m_model->index(row, 0);
        KFileItem item = m_model->itemForIndex(index);
        itemList.append(item);
    }

    generatePreviews(itemList);
}
Example #14
0
void Interface::thumbnails(const KUrl::List& list, int size)
{
    PrintWarningMessageFeature("HostSupportsThumbnails");

#if KDE_IS_VERSION(4,7,0)
    KFileItemList items;
    for (KUrl::List::ConstIterator it = list.begin() ; it != list.end() ; ++it)
    {
        if ((*it).isValid())
            items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, *it, true));
    }
    KIO::PreviewJob* job = KIO::filePreview(items, QSize(size, size));
#else
    KIO::PreviewJob *job = KIO::filePreview(list, size);
#endif

    connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)),
            this, SLOT(gotKDEPreview(KFileItem,QPixmap)));

    connect(job, SIGNAL(failed(KFileItem)),
            this, SLOT(failedKDEPreview(KFileItem)));
}
Example #15
0
void KuickShow::performDeleteCurrentImage(QWidget *parent)
{
    assert(fileWidget != 0L);

    KFileItemList list;
    KFileItem *item = fileWidget->getCurrentItem(false);
    list.append (item);

    if (KMessageBox::warningContinueCancel(
            parent,
            i18n("<qt>Do you really want to delete\n <b>'%1'</b>?</qt>").arg(item->url().pathOrURL()),
            i18n("Delete File"),
            KStdGuiItem::del(),
            "Kuick_delete_current_image")
        != KMessageBox::Continue)
    {
        return;
    }

    tryShowNextImage();
    fileWidget->del(list, false, false);
}
Example #16
0
void KipiInterface::slotRawThumb(const KUrl& url, const QImage& img)
{
    if (img.isNull())
    {
#if KDE_IS_VERSION(4,7,0)
        KFileItemList items;
        items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, url, true));
        KIO::PreviewJob* job = KIO::filePreview(items, QSize(256, 256));
#else
        KIO::PreviewJob *job = KIO::filePreview(KUrl::List() << url, 256);
#endif

        connect(job, SIGNAL(gotPreview(KFileItem, QPixmap)),
                this, SLOT(slotGotKDEPreview(KFileItem, QPixmap)));

        connect(job, SIGNAL(failed(KFileItem)),
                this, SLOT(slotFailedKDEPreview(KFileItem)));
    }
    else
    {
        emit gotThumbnail(url, QPixmap::fromImage(img));
    }
}
Example #17
0
void KuickShow::performTrashCurrentImage(QWidget *parent)
{
    assert(fileWidget != 0L);

    KFileItemList list;
    KFileItem *item = fileWidget->getCurrentItem(false);
    if (!item) return;

    list.append (item);

    if (KMessageBox::warningContinueCancel(
            parent,
            i18n("<qt>Do you really want to trash\n <b>'%1'</b>?</qt>").arg(item->url().pathOrURL()),
            i18n("Trash File"),
            KGuiItem(i18n("to trash", "&Trash"),"edittrash"),
            "Kuick_trash_current_image")
        != KMessageBox::Continue)
    {
        return;
    }

    tryShowNextImage();
    fileWidget->trash(list, parent, false, false);
}
Example #18
0
void PopupView::showContextMenu(QWidget *widget, const QPoint &screenPos, const QList<QModelIndex> &indexes)
{
    Q_UNUSED(widget)
    // contextMenuRequest is only called from the icon view, which is created in init()
    // which mean m_model should always be initialized
    Q_ASSERT(m_model);

    if (indexes.isEmpty()) {
        return;
    }

    if (m_actionCollection.isEmpty()) {
        createActions();
    }

    KFileItemList items;
    bool hasRemoteFiles = false;
    bool isTrashLink = false;

    foreach (const QModelIndex &index, m_selectionModel->selectedIndexes()) {
        KFileItem item = m_model->itemForIndex(index);
        if (!item.isNull()) {
            hasRemoteFiles |= item.localPath().isEmpty();
            items.append(item);
        }
    }

    // Check if we're showing the menu for the trash link
    if (items.count() == 1 && items.at(0).isDesktopFile()) {
        KDesktopFile file(items.at(0).localPath());
        if (file.readType() == "Link" && file.readUrl() == "trash:/") {
            isTrashLink = true;
        }
    }

    QAction *pasteTo = m_actionCollection.action("pasteto");
    if (pasteTo) {
        if (QAction *paste = m_actionCollection.action("paste")) {
            pasteTo->setEnabled(paste->isEnabled());
            pasteTo->setText(paste->text());
        }
    }

    QList<QAction*> editActions;
    editActions.append(m_actionCollection.action("rename"));

    KConfigGroup configGroup(KGlobal::config(), "KDE");
    bool showDeleteCommand = configGroup.readEntry("ShowDeleteCommand", false);

    // Don't add the "Move to Trash" action if we're showing the menu for the trash link
    if (!isTrashLink) {
        if (!hasRemoteFiles) {
            editActions.append(m_actionCollection.action("trash"));
        } else {
            showDeleteCommand = true;
        }
    }
    if (showDeleteCommand) {
        editActions.append(m_actionCollection.action("del"));
    }

    KParts::BrowserExtension::ActionGroupMap actionGroups;
    actionGroups.insert("editactions", editActions);

    KParts::BrowserExtension::PopupFlags flags = KParts::BrowserExtension::ShowProperties;
    flags |= KParts::BrowserExtension::ShowUrlOperations;

    // m_newMenu can be NULL here but KonqPopupMenu does handle this.
    KonqPopupMenu *contextMenu = new KonqPopupMenu(items, m_url, m_actionCollection, m_newMenu,
                                                   KonqPopupMenu::ShowNewWindow, flags,
                                                   QApplication::desktop(),
                                                   KBookmarkManager::userBookmarksManager(),
                                                   actionGroups);

    connect(contextMenu->fileItemActions(), SIGNAL(openWithDialogAboutToBeShown()), this, SLOT(openWithDialogAboutToShow()));

    m_showingMenu = true;
    contextMenu->exec(screenPos);
    delete contextMenu;
    m_showingMenu = false;

    if (pasteTo) {
        pasteTo->setEnabled(false);
    }

    if (m_delayedClose) {
        m_delayedClose = false;
        closeThisAndParentPopup();
    }
}
Example #19
0
bool KuickShow::eventFilter( QObject *o, QEvent *e )
{
    if ( m_delayedRepeatItem ) // we probably need to install an eventFilter over
	{
        return true;    // kapp, to make it really safe
	}

    bool ret = false;
    int eventType = e->type();
    QKeyEvent *k = 0L;
    if ( eventType == QEvent::KeyPress )
        k = static_cast<QKeyEvent *>( e );

    if ( k ) {
        if ( KStdAccel::quit().contains( KKey( k ) ) ) {
            saveSettings();
            deleteAllViewers();
            FileCache::shutdown();
            ::exit(0);
        }
        else if ( KStdAccel::help().contains( KKey( k ) ) ) {
            appHelpActivated();
            return true;
        }
    }


    ImageWindow *window = dynamic_cast<ImageWindow*>( o );

    if ( window ) {
        // The XWindow used to display Imlib's image is being resized when
        // switching images, causing enter- and leaveevents for this
        // ImageWindow, leading to the cursor being unhidden. So we simply
        // don't pass those events to KCursor to prevent that.
        if ( eventType != QEvent::Leave && eventType != QEvent::Enter )
            KCursor::autoHideEventFilter( o, e );

        m_viewer = window;
        QString img;
        KFileItem *item = 0L;      // the image to be shown
        KFileItem *item_next = 0L; // the image to be cached

        if ( k ) { // keypress
            ret = true;
            int key = k->key();

            // Key_Shift shouldn't load the browser in nobrowser mode, it
            // is used for zooming in the imagewindow
            // Key_Alt shouldn't either - otherwise Alt+F4 doesn't work, the
            // F4 gets eaten (by NetAccess' modal dialog maybe?)

            if ( !fileWidget )
            {
                if ( key != Key_Escape && key != Key_Shift && key != Key_Alt )
                {
                    KuickFile *file = m_viewer->currentFile();
//                    QFileInfo fi( m_viewer->filename() );
//                    start.setPath( fi.dirPath( true ) );
                    initGUI( file->url().upURL() );

                    // the fileBrowser will list the start-directory
                    // asynchronously so we can't immediately continue. There
                    // is no current-item and no next-item (actually no item
                    // at all). So we tell the browser the initial
                    // current-item and wait for it to tell us when it's ready.
                    // Then we will replay this KeyEvent.
                    delayedRepeatEvent( m_viewer, k );

                    // OK, once again, we have a problem with the now async and
                    // sync KDirLister :( If the startDir is already cached by
                    // KDirLister, we won't ever get that finished() signal
                    // because it is emitted before we can connect(). So if
                    // our dirlister has a rootFileItem, we assume the
                    // directory is read already and simply call
                    // slotReplayEvent() without the need for the finished()
                    // signal.

                    // see slotAdvanceImage() for similar code
                    if ( fileWidget->dirLister()->isFinished() )
                    {
                        if ( fileWidget->dirLister()->rootItem() )
                        {
                            fileWidget->setCurrentItem( file->url().fileName() );
                            QTimer::singleShot( 0, this, SLOT( slotReplayEvent()));
                        }
                        else // finished, but no root-item -- probably an error, kill repeat-item!
                        {
                            abortDelayedEvent();
                        }
                    }
                    else // not finished yet
                    {
                        fileWidget->setInitialItem( file->url().fileName() );
                        connect( fileWidget, SIGNAL( finished() ),
                                 SLOT( slotReplayEvent() ));
                    }

                    return true;
                }

                return KMainWindow::eventFilter( o, e );
            }

            // we definitely have a fileWidget here!

            KKey kkey( k );
            if ( key == Key_Home || KStdAccel::home().contains( kkey ) )
            {
                item = fileWidget->gotoFirstImage();
                item_next = fileWidget->getNext( false );
            }

            else if ( key == Key_End || KStdAccel::end().contains( kkey ) )
            {
                item = fileWidget->gotoLastImage();
                item_next = fileWidget->getPrevious( false );
            }

            else if ( fileWidget->actionCollection()->action("delete")->shortcut().contains( key ))
            {
                kdDebug() << "WOW, deletion happens here!" << endl;
//      KFileItem *cur = fileWidget->getCurrentItem( false );
                (void) fileWidget->getCurrentItem( false );
                item = fileWidget->getNext( false ); // don't move
                if ( !item )
                    item = fileWidget->getPrevious( false );
                KFileItem it( KFileItem::Unknown, KFileItem::Unknown,
                              m_viewer->url() );
                KFileItemList list;
                list.append( &it );
                if ( fileWidget->del(list, window,
                                     (k->state() & ShiftButton) == 0) == 0L )
                    return true; // aborted deletion

                // ### check failure asynchronously and restore old item?
                fileWidget->setCurrentItem( item );
            }

            else if ( m_toggleBrowserAction->shortcut().contains( key ) )
            {
                toggleBrowser();
                return true; // don't pass keyEvent
            }

            else
                ret = false;


            if ( FileWidget::isImage( item ) ) {
//                QString filename;
//                KIO::NetAccess::download(item->url(), filename, this);
                m_viewer->showNextImage( item->url() );

                if ( kdata->preloadImage && item_next ) { // preload next image
                    if ( FileWidget::isImage( item_next ) )
                        m_viewer->cacheImage( item_next->url() );
                }

                ret = true; // don't pass keyEvent
            }
        } // keyPressEvent on ImageWindow


        // doubleclick closes image window
        // and shows browser when last window closed via doubleclick
        else if ( eventType == QEvent::MouseButtonDblClick )
        {
            QMouseEvent *ev = static_cast<QMouseEvent*>( e );
            if ( ev->button() == LeftButton )
            {
                if ( s_viewers.count() == 1 )
                {
                    if ( !fileWidget )
                    {
//                        KURL start;
//                        QFileInfo fi( window->filename() );
//                        start.setPath( fi.dirPath( true ) );
                        initGUI( window->currentFile()->url().fileName() );
                    }
                    show();
                    raise();
                }

                window->close( true );

                ev->accept();
                ret = true;
            }
        }

    } // isA ImageWindow


    if ( ret )
        return true;

    return KMainWindow::eventFilter( o, e );
}
void KPImageDialogPreview::showPreview(const KUrl& url)
{
    if (!url.isValid())
    {
        clearPreview();
        return;
    }

    if (url != d->currentUrl)
    {
        QString make, model, dateTime, aperture, focalLength, exposureTime, sensitivity;
        QString unavailable(i18n("<i>unavailable</i>"));
        clearPreview();
        d->currentUrl = url;
        if (d->iface)
        {
            d->iface->thumbnail(d->currentUrl, 256);
        }
        else
        {
            if ( !d->currentUrl.isValid() )
                return;

#if KDE_IS_VERSION(4,7,0)
            KFileItemList items;
            items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, d->currentUrl, true));
            KIO::PreviewJob* job = KIO::filePreview(items, QSize(256, 256));
#else
            KIO::PreviewJob* job = KIO::filePreview(d->currentUrl, 256);
#endif

            connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)),
                    this, SLOT(slotKDEPreview(KFileItem,QPixmap)));

            connect(job, SIGNAL(failed(KFileItem)),
                    this, SLOT(slotKDEPreviewFailed(KFileItem)));
        }

        // Try to use libkexiv2 to identify image.

        if (d->metaIface.load(d->currentUrl.path()) &&
            (d->metaIface.hasExif() || d->metaIface.hasXmp()))
        {
            make = d->metaIface.getExifTagString("Exif.Image.Make");
            if (make.isEmpty())
                make = d->metaIface.getXmpTagString("Xmp.tiff.Make");

            model = d->metaIface.getExifTagString("Exif.Image.Model");
            if (model.isEmpty())
                model = d->metaIface.getXmpTagString("Xmp.tiff.Model");

            if (d->metaIface.getImageDateTime().isValid())
                dateTime = KGlobal::locale()->formatDateTime(d->metaIface.getImageDateTime(),
                                                             KLocale::ShortDate, true);

            aperture = d->metaIface.getExifTagString("Exif.Photo.FNumber");
            if (aperture.isEmpty())
            {
                aperture = d->metaIface.getExifTagString("Exif.Photo.ApertureValue");
                if (aperture.isEmpty())
                {
                    aperture = d->metaIface.getXmpTagString("Xmp.exif.FNumber");
                    if (aperture.isEmpty())
                        aperture = d->metaIface.getXmpTagString("Xmp.exif.ApertureValue");
                }
            }

            focalLength = d->metaIface.getExifTagString("Exif.Photo.FocalLength");
            if (focalLength.isEmpty())
                focalLength = d->metaIface.getXmpTagString("Xmp.exif.FocalLength");

            exposureTime = d->metaIface.getExifTagString("Exif.Photo.ExposureTime");
            if (exposureTime.isEmpty())
            {
                exposureTime = d->metaIface.getExifTagString("Exif.Photo.ShutterSpeedValue");
                if (exposureTime.isEmpty())
                {
                    exposureTime = d->metaIface.getXmpTagString("Xmp.exif.ExposureTime");
                    if (exposureTime.isEmpty())
                        exposureTime = d->metaIface.getXmpTagString("Xmp.exif.ShutterSpeedValue");
                }
            }

            sensitivity = d->metaIface.getExifTagString("Exif.Photo.ISOSpeedRatings");
            if (sensitivity.isEmpty())
            {
                sensitivity = d->metaIface.getExifTagString("Exif.Photo.ExposureIndex");
                if (sensitivity.isEmpty())
                {
                    sensitivity = d->metaIface.getXmpTagString("Xmp.exif.ISOSpeedRatings");
                    if (sensitivity.isEmpty())
                        sensitivity = d->metaIface.getXmpTagString("Xmp.exif.ExposureIndex");
                }
            }
        }
        else
        {
            // Try to use libkdcraw interface to identify image.

            DcrawInfoContainer info;
            KDcraw             dcrawIface;
            dcrawIface.rawFileIdentify(info, d->currentUrl.path());
            if (info.isDecodable)
            {
                if (!info.make.isEmpty())
                    make = info.make;

                if (!info.model.isEmpty())
                    model = info.model;

                if (info.dateTime.isValid())
                    dateTime = KGlobal::locale()->formatDateTime(info.dateTime, KLocale::ShortDate, true);

                if (info.aperture != -1.0)
                    aperture = QString::number(info.aperture);

                if (info.focalLength != -1.0)
                    focalLength = QString::number(info.focalLength);

                if (info.exposureTime != -1.0)
                    exposureTime = QString::number(info.exposureTime);

                if (info.sensitivity != -1)
                    sensitivity = QString::number(info.sensitivity);
            }
            else
            {
                d->infoLabel->clear();
                return;
            }
        }

        if (make.isEmpty())         make         = unavailable;
        if (model.isEmpty())        model        = unavailable;
        if (dateTime.isEmpty())     dateTime     = unavailable;
        if (aperture.isEmpty())     aperture     = unavailable;
        if (focalLength.isEmpty())  focalLength  = unavailable;
        if (exposureTime.isEmpty()) exposureTime = unavailable;

        if (sensitivity.isEmpty()) sensitivity = unavailable;
        else sensitivity = i18n("%1 ISO", sensitivity);

        QString identify("<qt><center>");
        QString cellBeg("<tr><td><nobr><font size=-1>");
        QString cellMid("</font></nobr></td><td><nobr><font size=-1>");
        QString cellEnd("</font></nobr></td></tr>");

        identify += "<table cellspacing=0 cellpadding=0>";
        identify += cellBeg + i18n("<i>Make:</i>")        + cellMid + make         + cellEnd;
        identify += cellBeg + i18n("<i>Model:</i>")       + cellMid + model        + cellEnd;
        identify += cellBeg + i18n("<i>Created:</i>")     + cellMid + dateTime     + cellEnd;
        identify += cellBeg + i18n("<i>Aperture:</i>")    + cellMid + aperture     + cellEnd;
        identify += cellBeg + i18n("<i>Focal:</i>")       + cellMid + focalLength  + cellEnd;
        identify += cellBeg + i18n("<i>Exposure:</i>")    + cellMid + exposureTime + cellEnd;
        identify += cellBeg + i18n("<i>Sensitivity:</i>") + cellMid + sensitivity  + cellEnd;
        identify += "</table></center></qt>";

        d->infoLabel->setText(identify);
    }
}
void BracketStackList::addItems(const KUrl::List& list)
{
    if (list.count() == 0)
        return;

    KUrl::List urls;

    for ( KUrl::List::ConstIterator it = list.constBegin(); it != list.constEnd(); ++it )
    {
        KUrl imageUrl = *it;

        // Check if the new item already exist in the list.
        bool found = false;

        QTreeWidgetItemIterator iter(this);
        while (*iter)
        {
            BracketStackItem* item = dynamic_cast<BracketStackItem*>(*iter);

            if (item->url() == imageUrl)
                found = true;

            ++iter;
        }

        if (!found)
        {
            BracketStackItem* item = new BracketStackItem(this);
            item->setUrl(imageUrl);
            item->setOn(true);
            urls.append(imageUrl);
        }
    }

    if (d->iface)
    {
        d->iface->thumbnails(urls, iconSize().width());
    }
    else
    {
#if KDE_IS_VERSION(4,7,0)
        KFileItemList items;
        for (KUrl::List::ConstIterator it = urls.begin() ; it != urls.end() ; ++it)
        {
            if ((*it).isValid())
                items.append(KFileItem(KFileItem::Unknown, KFileItem::Unknown, *it, true));
        }
        KIO::PreviewJob* job = KIO::filePreview(items, iconSize());
#else
        KIO::PreviewJob *job = KIO::filePreview(urls, iconSize().width());
#endif

        connect(job, SIGNAL(gotPreview(KFileItem,QPixmap)),
                this, SLOT(slotKDEPreview(KFileItem,QPixmap)));

        connect(job, SIGNAL(failed(KFileItem)),
                this, SLOT(slotKDEPreviewFailed(KFileItem)));
    }

    emit signalAddItems(urls);
}