|
|
|
/* ============================================================
|
|
|
|
*
|
|
|
|
* This file is a part of digiKam project
|
|
|
|
* http://www.digikam.org
|
|
|
|
*
|
|
|
|
* Date : 2004-06-26
|
|
|
|
* Description : Albums lister.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
|
|
* Copyright (C) 2007-2009 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
|
|
* Copyright (C) 2007 by Arnd Baecker <arnd dot baecker at web dot de>
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it
|
|
|
|
* and/or modify it under the terms of the GNU General
|
|
|
|
* Public License as published by the Free Software Foundation;
|
|
|
|
* either version 2, or (at your option)
|
|
|
|
* any later version.
|
|
|
|
*
|
|
|
|
* This program is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* ============================================================ */
|
|
|
|
|
|
|
|
// C Ansi includes.
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
#include <sys/time.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
// C++ includes.
|
|
|
|
|
|
|
|
#include <cstdio>
|
|
|
|
#include <ctime>
|
|
|
|
|
|
|
|
// TQt includes.
|
|
|
|
|
|
|
|
#include <tqstring.h>
|
|
|
|
#include <tqcstring.h>
|
|
|
|
#include <tqdatastream.h>
|
|
|
|
#include <tqfileinfo.h>
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqmap.h>
|
|
|
|
#include <tqpair.h>
|
|
|
|
#include <tqvaluelist.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
|
|
|
|
// KDE includes.
|
|
|
|
|
|
|
|
#include <tdeapplication.h>
|
|
|
|
#include <kcursor.h>
|
|
|
|
#include <tdeio/job.h>
|
|
|
|
#include <kurl.h>
|
|
|
|
|
|
|
|
// Local includes.
|
|
|
|
|
|
|
|
#include "ddebug.h"
|
|
|
|
#include "mimefilter.h"
|
|
|
|
#include "album.h"
|
|
|
|
#include "albummanager.h"
|
|
|
|
#include "albumsettings.h"
|
|
|
|
#include "albumlister.h"
|
|
|
|
#include "albumlister.moc"
|
|
|
|
|
|
|
|
namespace Digikam
|
|
|
|
{
|
|
|
|
|
|
|
|
class AlbumListerPriv
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
AlbumListerPriv()
|
|
|
|
{
|
|
|
|
untaggedFilter = false;
|
|
|
|
ratingFilter = 0;
|
|
|
|
filterTimer = 0;
|
|
|
|
job = 0;
|
|
|
|
currAlbum = 0;
|
|
|
|
namesFilter = "*";
|
|
|
|
mimeTypeFilter = MimeFilter::AllFiles;
|
|
|
|
ratingCond = AlbumLister::GreaterEqualCondition;
|
|
|
|
matchingCond = AlbumLister::OrCondition;
|
|
|
|
recurseAlbums = false;
|
|
|
|
recurseTags = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool untaggedFilter;
|
|
|
|
|
|
|
|
int ratingFilter;
|
|
|
|
int recurseAlbums;
|
|
|
|
int recurseTags;
|
|
|
|
|
|
|
|
TQString namesFilter;
|
|
|
|
TQString textFilter;
|
|
|
|
|
|
|
|
TQMap<TQ_LLONG, ImageInfo*> itemMap;
|
|
|
|
TQMap<int, int> invalidatedItems;
|
|
|
|
TQMap<TQDateTime, bool> dayFilter;
|
|
|
|
|
|
|
|
TQValueList<int> tagFilter;
|
|
|
|
|
|
|
|
TQTimer *filterTimer;
|
|
|
|
|
|
|
|
TDEIO::TransferJob *job;
|
|
|
|
|
|
|
|
ImageInfoList itemList;
|
|
|
|
|
|
|
|
Album *currAlbum;
|
|
|
|
|
|
|
|
MimeFilter::TypeMimeFilter mimeTypeFilter;
|
|
|
|
|
|
|
|
AlbumLister::MatchingCondition matchingCond;
|
|
|
|
|
|
|
|
AlbumLister::RatingCondition ratingCond;
|
|
|
|
};
|
|
|
|
|
|
|
|
AlbumLister* AlbumLister::m_instance = 0;
|
|
|
|
|
|
|
|
AlbumLister* AlbumLister::instance()
|
|
|
|
{
|
|
|
|
if (!m_instance)
|
|
|
|
new AlbumLister();
|
|
|
|
|
|
|
|
return m_instance;
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumLister::AlbumLister()
|
|
|
|
{
|
|
|
|
m_instance = this;
|
|
|
|
|
|
|
|
d = new AlbumListerPriv;
|
|
|
|
d->itemList.setAutoDelete(true);
|
|
|
|
d->filterTimer = new TQTimer(this);
|
|
|
|
|
|
|
|
connect(d->filterTimer, TQT_SIGNAL(timeout()),
|
|
|
|
this, TQT_SLOT(slotFilterItems()));
|
|
|
|
}
|
|
|
|
|
|
|
|
AlbumLister::~AlbumLister()
|
|
|
|
{
|
|
|
|
delete d->filterTimer;
|
|
|
|
delete d;
|
|
|
|
m_instance = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::openAlbum(Album *album)
|
|
|
|
{
|
|
|
|
d->currAlbum = album;
|
|
|
|
d->filterTimer->stop();
|
|
|
|
emit signalClear();
|
|
|
|
d->itemList.clear();
|
|
|
|
d->itemMap.clear();
|
|
|
|
|
|
|
|
if (d->job)
|
|
|
|
{
|
|
|
|
d->job->kill();
|
|
|
|
d->job = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!album)
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQByteArray ba;
|
|
|
|
TQDataStream ds(ba, IO_WriteOnly);
|
|
|
|
ds << AlbumManager::instance()->getLibraryPath();
|
|
|
|
ds << album->kurl();
|
|
|
|
ds << d->namesFilter;
|
|
|
|
ds << AlbumSettings::instance()->getIconShowResolution();
|
|
|
|
ds << d->recurseAlbums;
|
|
|
|
ds << d->recurseTags;
|
|
|
|
|
|
|
|
// Protocol = digikamalbums -> tdeio_digikamalbums
|
|
|
|
d->job = new TDEIO::TransferJob(album->kurl(), TDEIO::CMD_SPECIAL,
|
|
|
|
ba, TQByteArray(), false);
|
|
|
|
|
|
|
|
connect(d->job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotResult(TDEIO::Job*)));
|
|
|
|
|
|
|
|
connect(d->job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
|
|
|
|
this, TQT_SLOT(slotData(TDEIO::Job*, const TQByteArray&)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::refresh()
|
|
|
|
{
|
|
|
|
if (!d->currAlbum)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->filterTimer->stop();
|
|
|
|
|
|
|
|
if (d->job)
|
|
|
|
{
|
|
|
|
d->job->kill();
|
|
|
|
d->job = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->itemMap.clear();
|
|
|
|
ImageInfo* item;
|
|
|
|
for (ImageInfoListIterator it(d->itemList); (item = it.current()); ++it)
|
|
|
|
{
|
|
|
|
d->itemMap.insert(item->id(), item);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQByteArray ba;
|
|
|
|
TQDataStream ds(ba, IO_WriteOnly);
|
|
|
|
ds << AlbumManager::instance()->getLibraryPath();
|
|
|
|
ds << d->currAlbum->kurl();
|
|
|
|
ds << d->namesFilter;
|
|
|
|
ds << AlbumSettings::instance()->getIconShowResolution();
|
|
|
|
ds << d->recurseAlbums;
|
|
|
|
ds << d->recurseTags;
|
|
|
|
|
|
|
|
d->job = new TDEIO::TransferJob(d->currAlbum->kurl(), TDEIO::CMD_SPECIAL,
|
|
|
|
ba, TQByteArray(), false);
|
|
|
|
|
|
|
|
connect(d->job, TQT_SIGNAL(result(TDEIO::Job*)),
|
|
|
|
this, TQT_SLOT(slotResult(TDEIO::Job*)));
|
|
|
|
|
|
|
|
connect(d->job, TQT_SIGNAL(data(TDEIO::Job*, const TQByteArray&)),
|
|
|
|
this, TQT_SLOT(slotData(TDEIO::Job*, const TQByteArray&)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setDayFilter(const TQValueList<TQDateTime>& days)
|
|
|
|
{
|
|
|
|
d->dayFilter.clear();
|
|
|
|
|
|
|
|
for (TQValueList<TQDateTime>::const_iterator it = days.begin(); it != days.end(); ++it)
|
|
|
|
d->dayFilter.insert(*it, true);
|
|
|
|
|
|
|
|
d->filterTimer->start(100, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AlbumLister::tagFiltersIsActive()
|
|
|
|
{
|
|
|
|
if (!d->tagFilter.isEmpty() || d->untaggedFilter)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setTagFilter(const TQValueList<int>& tags, const MatchingCondition& matchingCond,
|
|
|
|
bool showUnTagged)
|
|
|
|
{
|
|
|
|
d->tagFilter = tags;
|
|
|
|
d->matchingCond = matchingCond;
|
|
|
|
d->untaggedFilter = showUnTagged;
|
|
|
|
d->filterTimer->start(100, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setRatingFilter(int rating, const RatingCondition& ratingCond)
|
|
|
|
{
|
|
|
|
d->ratingFilter = rating;
|
|
|
|
d->ratingCond = ratingCond;
|
|
|
|
d->filterTimer->start(100, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setMimeTypeFilter(int mimeTypeFilter)
|
|
|
|
{
|
|
|
|
d->mimeTypeFilter = (MimeFilter::TypeMimeFilter)mimeTypeFilter;
|
|
|
|
d->filterTimer->start(100, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setTextFilter(const TQString& text)
|
|
|
|
{
|
|
|
|
d->textFilter = text;
|
|
|
|
d->filterTimer->start(100, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setRecurseAlbums(bool recursive)
|
|
|
|
{
|
|
|
|
d->recurseAlbums = recursive;
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setRecurseTags(bool recursive)
|
|
|
|
{
|
|
|
|
d->recurseTags = recursive;
|
|
|
|
refresh();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool AlbumLister::matchesFilter(const ImageInfo* info, bool &foundText)
|
|
|
|
{
|
|
|
|
if (d->dayFilter.isEmpty() && d->tagFilter.isEmpty() && d->textFilter.isEmpty() &&
|
|
|
|
!d->untaggedFilter && d->ratingFilter==-1)
|
|
|
|
return true;
|
|
|
|
|
|
|
|
bool match = false;
|
|
|
|
|
|
|
|
if (!d->tagFilter.isEmpty())
|
|
|
|
{
|
|
|
|
TQValueList<int> tagIDs = info->tagIDs();
|
|
|
|
TQValueList<int>::iterator it;
|
|
|
|
|
|
|
|
if (d->matchingCond == OrCondition)
|
|
|
|
{
|
|
|
|
for (it = d->tagFilter.begin(); it != d->tagFilter.end(); ++it)
|
|
|
|
{
|
|
|
|
if (tagIDs.contains(*it))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// AND matching condition...
|
|
|
|
|
|
|
|
for (it = d->tagFilter.begin(); it != d->tagFilter.end(); ++it)
|
|
|
|
{
|
|
|
|
if (!tagIDs.contains(*it))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (it == d->tagFilter.end())
|
|
|
|
match = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
match |= (d->untaggedFilter && tagIDs.isEmpty());
|
|
|
|
}
|
|
|
|
else if (d->untaggedFilter)
|
|
|
|
{
|
|
|
|
match = info->tagIDs().isEmpty();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!d->dayFilter.isEmpty())
|
|
|
|
{
|
|
|
|
match &= d->dayFilter.contains(TQDateTime(info->dateTime().date(), TQTime()));
|
|
|
|
}
|
|
|
|
|
|
|
|
//-- Filter by rating ---------------------------------------------------------
|
|
|
|
|
|
|
|
if (d->ratingFilter >= 0)
|
|
|
|
{
|
|
|
|
if (d->ratingCond == GreaterEqualCondition)
|
|
|
|
{
|
|
|
|
// If the rating is not >=, i.e it is <, then it does not match.
|
|
|
|
if (info->rating() < d->ratingFilter)
|
|
|
|
{
|
|
|
|
match = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (d->ratingCond == EqualCondition)
|
|
|
|
{
|
|
|
|
// If the rating is not =, i.e it is !=, then it does not match.
|
|
|
|
if (info->rating() != d->ratingFilter)
|
|
|
|
{
|
|
|
|
match = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// If the rating is not <=, i.e it is >, then it does not match.
|
|
|
|
if (info->rating() > d->ratingFilter)
|
|
|
|
{
|
|
|
|
match = false;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- Filter by mime type -----------------------------------------------------
|
|
|
|
|
|
|
|
TQFileInfo fi(info->filePath());
|
|
|
|
TQString mimeType = fi.extension(false).upper();
|
|
|
|
|
|
|
|
switch(d->mimeTypeFilter)
|
|
|
|
{
|
|
|
|
case MimeFilter::ImageFiles:
|
|
|
|
{
|
|
|
|
TQString imageFilesExt(AlbumSettings::instance()->getImageFileFilter());
|
|
|
|
imageFilesExt.append(AlbumSettings::instance()->getRawFileFilter());
|
|
|
|
if (!imageFilesExt.upper().contains(mimeType))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::JPGFiles:
|
|
|
|
{
|
|
|
|
if (mimeType != TQString("JPG") && mimeType != TQString("JPE") &&
|
|
|
|
mimeType != TQString("JPEG"))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::PNGFiles:
|
|
|
|
{
|
|
|
|
if (mimeType != TQString("PNG"))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::TIFFiles:
|
|
|
|
{
|
|
|
|
if (mimeType != TQString("TIF") && mimeType != TQString("TIFF"))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::NoRAWFiles:
|
|
|
|
{
|
|
|
|
TQString rawFilesExt(AlbumSettings::instance()->getRawFileFilter());
|
|
|
|
if (rawFilesExt.upper().contains(mimeType))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::RAWFiles:
|
|
|
|
{
|
|
|
|
TQString rawFilesExt(AlbumSettings::instance()->getRawFileFilter());
|
|
|
|
if (!rawFilesExt.upper().contains(mimeType))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::MoviesFiles:
|
|
|
|
{
|
|
|
|
TQString moviesFilesExt(AlbumSettings::instance()->getMovieFileFilter());
|
|
|
|
if (!moviesFilesExt.upper().contains(mimeType))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case MimeFilter::AudioFiles:
|
|
|
|
{
|
|
|
|
TQString audioFilesExt(AlbumSettings::instance()->getAudioFileFilter());
|
|
|
|
if (!audioFilesExt.upper().contains(mimeType))
|
|
|
|
match = false;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default: // All Files: do nothing...
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
//-- Filter by text -----------------------------------------------------------
|
|
|
|
|
|
|
|
if (!d->textFilter.isEmpty())
|
|
|
|
{
|
|
|
|
foundText = false;
|
|
|
|
if (info->name().lower().contains(d->textFilter.lower()))
|
|
|
|
{
|
|
|
|
foundText = true;
|
|
|
|
}
|
|
|
|
if (info->caption().lower().contains(d->textFilter.lower()))
|
|
|
|
foundText = true;
|
|
|
|
TQStringList tags = info->tagNames();
|
|
|
|
for (TQStringList::const_iterator it = tags.constBegin() ; it != tags.constEnd() ; ++it)
|
|
|
|
{
|
|
|
|
if ((*it).lower().contains(d->textFilter.lower()))
|
|
|
|
foundText = true;
|
|
|
|
}
|
|
|
|
// check for folder names
|
|
|
|
PAlbum* palbum = AlbumManager::instance()->findPAlbum(info->albumID());
|
|
|
|
if ((palbum && palbum->title().lower().contains(d->textFilter.lower())))
|
|
|
|
{
|
|
|
|
foundText = true;
|
|
|
|
}
|
|
|
|
match &= foundText;
|
|
|
|
}
|
|
|
|
|
|
|
|
return match;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::stop()
|
|
|
|
{
|
|
|
|
d->currAlbum = 0;
|
|
|
|
d->filterTimer->stop();
|
|
|
|
emit signalClear();
|
|
|
|
|
|
|
|
d->itemList.clear();
|
|
|
|
d->itemMap.clear();
|
|
|
|
|
|
|
|
if (d->job)
|
|
|
|
{
|
|
|
|
d->job->kill();
|
|
|
|
d->job = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::setNamesFilter(const TQString& namesFilter)
|
|
|
|
{
|
|
|
|
d->namesFilter = namesFilter;
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::invalidateItem(const ImageInfo *item)
|
|
|
|
{
|
|
|
|
d->invalidatedItems.insert(item->id(), item->id());
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::slotFilterItems()
|
|
|
|
{
|
|
|
|
if (d->job)
|
|
|
|
{
|
|
|
|
d->filterTimer->start(100, true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPtrList<ImageInfo> newFilteredItemsList;
|
|
|
|
TQPtrList<ImageInfo> deleteFilteredItemsList;
|
|
|
|
ImageInfo *item = 0;
|
|
|
|
bool matchForText = false;
|
|
|
|
bool match = false;
|
|
|
|
|
|
|
|
for (ImageInfoListIterator it(d->itemList);
|
|
|
|
(item = it.current()); ++it)
|
|
|
|
{
|
|
|
|
bool foundText = false;
|
|
|
|
if (matchesFilter(item, foundText))
|
|
|
|
{
|
|
|
|
match = true;
|
|
|
|
if (!item->getViewItem())
|
|
|
|
newFilteredItemsList.append(item);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (item->getViewItem())
|
|
|
|
deleteFilteredItemsList.append(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (foundText)
|
|
|
|
matchForText = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This takes linear time - and deleting seems to take longer. Set wait cursor for large numbers.
|
|
|
|
bool setCursor = (3*deleteFilteredItemsList.count() + newFilteredItemsList.count()) > 1500;
|
|
|
|
if (setCursor)
|
|
|
|
kapp->setOverrideCursor(KCursor::waitCursor());
|
|
|
|
|
|
|
|
emit signalItemsTextFilterMatch(matchForText);
|
|
|
|
emit signalItemsFilterMatch(match);
|
|
|
|
|
|
|
|
if (!deleteFilteredItemsList.isEmpty())
|
|
|
|
{
|
|
|
|
for (ImageInfo *info=deleteFilteredItemsList.first(); info; info = deleteFilteredItemsList.next())
|
|
|
|
emit signalDeleteFilteredItem(info);
|
|
|
|
}
|
|
|
|
if (!newFilteredItemsList.isEmpty())
|
|
|
|
{
|
|
|
|
emit signalNewFilteredItems(newFilteredItemsList);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (setCursor)
|
|
|
|
kapp->restoreOverrideCursor();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::slotResult(TDEIO::Job* job)
|
|
|
|
{
|
|
|
|
d->job = 0;
|
|
|
|
|
|
|
|
if (job->error())
|
|
|
|
{
|
|
|
|
DWarning() << "Failed to list url: " << job->errorString() << endl;
|
|
|
|
d->itemMap.clear();
|
|
|
|
d->invalidatedItems.clear();
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
typedef TQMap<TQ_LLONG, ImageInfo*> ImMap;
|
|
|
|
|
|
|
|
for (ImMap::iterator it = d->itemMap.begin();
|
|
|
|
it != d->itemMap.end(); ++it)
|
|
|
|
{
|
|
|
|
emit signalDeleteItem(it.data());
|
|
|
|
emit signalDeleteFilteredItem(it.data());
|
|
|
|
d->itemList.remove(it.data());
|
|
|
|
}
|
|
|
|
|
|
|
|
d->itemMap.clear();
|
|
|
|
d->invalidatedItems.clear();
|
|
|
|
|
|
|
|
emit signalCompleted();
|
|
|
|
}
|
|
|
|
|
|
|
|
void AlbumLister::slotData(TDEIO::Job*, const TQByteArray& data)
|
|
|
|
{
|
|
|
|
if (data.isEmpty())
|
|
|
|
return;
|
|
|
|
|
|
|
|
TQ_LLONG imageID;
|
|
|
|
int albumID;
|
|
|
|
TQString name;
|
|
|
|
TQString date;
|
|
|
|
size_t size;
|
|
|
|
TQSize dims;
|
|
|
|
|
|
|
|
ImageInfoList newItemsList;
|
|
|
|
ImageInfoList newFilteredItemsList;
|
|
|
|
|
|
|
|
TQDataStream ds(data, IO_ReadOnly);
|
|
|
|
|
|
|
|
while (!ds.atEnd())
|
|
|
|
{
|
|
|
|
bool foundText = false;
|
|
|
|
|
|
|
|
ds >> imageID;
|
|
|
|
ds >> albumID;
|
|
|
|
ds >> name;
|
|
|
|
ds >> date;
|
|
|
|
ds >> size;
|
|
|
|
ds >> dims;
|
|
|
|
|
|
|
|
if (d->itemMap.contains(imageID))
|
|
|
|
{
|
|
|
|
ImageInfo* info = d->itemMap[imageID];
|
|
|
|
d->itemMap.remove(imageID);
|
|
|
|
|
|
|
|
if (d->invalidatedItems.contains(imageID))
|
|
|
|
{
|
|
|
|
emit signalDeleteItem(info);
|
|
|
|
emit signalDeleteFilteredItem(info);
|
|
|
|
d->itemList.remove(info);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!matchesFilter(info, foundText))
|
|
|
|
{
|
|
|
|
emit signalDeleteFilteredItem(info);
|
|
|
|
}
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ImageInfo* info = new ImageInfo(imageID, albumID, name,
|
|
|
|
TQDateTime::fromString(date, TQt::ISODate),
|
|
|
|
size, dims);
|
|
|
|
|
|
|
|
if (matchesFilter(info, foundText))
|
|
|
|
newFilteredItemsList.append(info);
|
|
|
|
|
|
|
|
newItemsList.append(info);
|
|
|
|
d->itemList.append(info);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!newFilteredItemsList.isEmpty())
|
|
|
|
emit signalNewFilteredItems(newFilteredItemsList);
|
|
|
|
|
|
|
|
if (!newItemsList.isEmpty())
|
|
|
|
emit signalNewItems(newItemsList);
|
|
|
|
|
|
|
|
slotFilterItems();
|
|
|
|
}
|
|
|
|
|
|
|
|
} // namespace Digikam
|