|
|
|
/* ============================================================
|
|
|
|
*
|
|
|
|
* This file is a part of digiKam project
|
|
|
|
* http://www.digikam.org
|
|
|
|
*
|
|
|
|
* Date : 2004-11-22
|
|
|
|
* Description : a bar widget to display image thumbnails
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
|
|
* Copyright (C) 2005-2008 by Gilles Caulier <caulier dot gilles at gmail dot com>
|
|
|
|
*
|
|
|
|
* 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 <unistd.h>
|
|
|
|
}
|
|
|
|
|
|
|
|
// C++ includes.
|
|
|
|
|
|
|
|
#include <cmath>
|
|
|
|
|
|
|
|
// TQt includes.
|
|
|
|
|
|
|
|
#include <tqdir.h>
|
|
|
|
#include <tqpixmap.h>
|
|
|
|
#include <tqimage.h>
|
|
|
|
#include <tqtimer.h>
|
|
|
|
#include <tqpainter.h>
|
|
|
|
#include <tqdict.h>
|
|
|
|
#include <tqpoint.h>
|
|
|
|
#include <tqstylesheet.h>
|
|
|
|
#include <tqdatetime.h>
|
|
|
|
#include <tqguardedptr.h>
|
|
|
|
|
|
|
|
// KDE includes.
|
|
|
|
|
|
|
|
#include <kmdcodec.h>
|
|
|
|
#include <kfileitem.h>
|
|
|
|
#include <kapplication.h>
|
|
|
|
#include <kiconloader.h>
|
|
|
|
#include <klocale.h>
|
|
|
|
#include <kmimetype.h>
|
|
|
|
#include <kfileitem.h>
|
|
|
|
#include <kglobal.h>
|
|
|
|
|
|
|
|
// LibKDcraw includes.
|
|
|
|
|
|
|
|
#include <libkdcraw/version.h>
|
|
|
|
#include <libkdcraw/kdcraw.h>
|
|
|
|
|
|
|
|
#if KDCRAW_VERSION < 0x000106
|
|
|
|
#include <libkdcraw/dcrawbinary.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// Local includes.
|
|
|
|
|
|
|
|
#include "dmetadata.h"
|
|
|
|
#include "thumbnailjob.h"
|
|
|
|
#include "thumbnailsize.h"
|
|
|
|
#include "thumbbar.h"
|
|
|
|
#include "thumbbar.moc"
|
|
|
|
|
|
|
|
namespace Digikam
|
|
|
|
{
|
|
|
|
|
|
|
|
class ThumbBarViewPriv
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
ThumbBarViewPriv() :
|
|
|
|
margin(5)
|
|
|
|
{
|
|
|
|
dragging = false;
|
|
|
|
exifRotate = false;
|
|
|
|
clearing = false;
|
|
|
|
toolTip = 0;
|
|
|
|
firstItem = 0;
|
|
|
|
lastItem = 0;
|
|
|
|
currItem = 0;
|
|
|
|
count = 0;
|
|
|
|
thumbJob = 0;
|
|
|
|
tileSize = ThumbnailSize::Small;
|
|
|
|
|
|
|
|
itemDict.setAutoDelete(false);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool clearing;
|
|
|
|
bool exifRotate;
|
|
|
|
bool dragging;
|
|
|
|
|
|
|
|
const int margin;
|
|
|
|
int count;
|
|
|
|
int tileSize;
|
|
|
|
int orientation;
|
|
|
|
|
|
|
|
TQTimer *timer;
|
|
|
|
|
|
|
|
TQPoint dragStartPos;
|
|
|
|
|
|
|
|
ThumbBarItem *firstItem;
|
|
|
|
ThumbBarItem *lastItem;
|
|
|
|
ThumbBarItem *currItem;
|
|
|
|
|
|
|
|
TQDict<ThumbBarItem> itemDict;
|
|
|
|
TQGuardedPtr<ThumbnailJob> thumbJob;
|
|
|
|
|
|
|
|
ThumbBarToolTipSettings toolTipSettings;
|
|
|
|
|
|
|
|
ThumbBarToolTip *toolTip;
|
|
|
|
};
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
|
|
|
class ThumbBarItemPriv
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
|
|
|
|
ThumbBarItemPriv()
|
|
|
|
{
|
|
|
|
pos = 0;
|
|
|
|
pixmap = 0;
|
|
|
|
next = 0;
|
|
|
|
prev = 0;
|
|
|
|
view = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
int pos;
|
|
|
|
|
|
|
|
TQPixmap *pixmap;
|
|
|
|
|
|
|
|
KURL url;
|
|
|
|
|
|
|
|
ThumbBarItem *next;
|
|
|
|
ThumbBarItem *prev;
|
|
|
|
|
|
|
|
ThumbBarView *view;
|
|
|
|
};
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ThumbBarView::ThumbBarView(TQWidget* tqparent, int orientation, bool exifRotate,
|
|
|
|
ThumbBarToolTipSettings settings)
|
|
|
|
: TQScrollView(tqparent)
|
|
|
|
{
|
|
|
|
d = new ThumbBarViewPriv;
|
|
|
|
d->orientation = orientation;
|
|
|
|
d->exifRotate = exifRotate;
|
|
|
|
d->toolTipSettings = settings;
|
|
|
|
d->toolTip = new ThumbBarToolTip(this);
|
|
|
|
d->timer = new TQTimer(this);
|
|
|
|
|
|
|
|
connect(d->timer, TQT_SIGNAL(timeout()),
|
|
|
|
this, TQT_SLOT(slotUpdate()));
|
|
|
|
|
|
|
|
viewport()->setBackgroundMode(TQt::NoBackground);
|
|
|
|
viewport()->setMouseTracking(true);
|
|
|
|
viewport()->setAcceptDrops(true);
|
|
|
|
|
|
|
|
setFrameStyle(TQFrame::NoFrame);
|
|
|
|
setAcceptDrops(true);
|
|
|
|
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
{
|
|
|
|
setHScrollBarMode(TQScrollView::AlwaysOff);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
setVScrollBarMode(TQScrollView::AlwaysOff);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarView::~ThumbBarView()
|
|
|
|
{
|
|
|
|
if (!d->thumbJob.isNull())
|
|
|
|
{
|
|
|
|
d->thumbJob->kill();
|
|
|
|
d->thumbJob = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
clear(false);
|
|
|
|
|
|
|
|
delete d->timer;
|
|
|
|
delete d->toolTip;
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::resizeEvent(TQResizeEvent* e)
|
|
|
|
{
|
|
|
|
if (!e) return;
|
|
|
|
|
|
|
|
TQScrollView::resizeEvent(e);
|
|
|
|
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
{
|
|
|
|
d->tileSize = width() - 2*d->margin - verticalScrollBar()->tqsizeHint().width();
|
|
|
|
verticalScrollBar()->setLineStep(d->tileSize);
|
|
|
|
verticalScrollBar()->setPageStep(2*d->tileSize);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->tileSize = height() - 2*d->margin - horizontalScrollBar()->tqsizeHint().height();
|
|
|
|
horizontalScrollBar()->setLineStep(d->tileSize);
|
|
|
|
horizontalScrollBar()->setPageStep(2*d->tileSize);
|
|
|
|
}
|
|
|
|
|
|
|
|
rearrangeItems();
|
|
|
|
ensureItemVisible(currentItem());
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::setExifRotate(bool exifRotate)
|
|
|
|
{
|
|
|
|
if (d->exifRotate == exifRotate)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d->exifRotate = exifRotate;
|
|
|
|
TQString thumbCacheDir = TQDir::homeDirPath() + "/.thumbnails/";
|
|
|
|
|
|
|
|
for (ThumbBarItem *item = d->firstItem; item; item = item->d->next)
|
|
|
|
{
|
|
|
|
// Remove all current album item thumbs from disk cache.
|
|
|
|
|
|
|
|
TQString uri = "file://" + TQDir::cleanDirPath(item->url().path(-1));
|
|
|
|
KMD5 md5(TQFile::encodeName(uri).data());
|
|
|
|
uri = md5.hexDigest();
|
|
|
|
|
|
|
|
TQString smallThumbPath = thumbCacheDir + "normal/" + uri + ".png";
|
|
|
|
TQString bigThumbPath = thumbCacheDir + "large/" + uri + ".png";
|
|
|
|
|
|
|
|
::unlink(TQFile::encodeName(smallThumbPath));
|
|
|
|
::unlink(TQFile::encodeName(bigThumbPath));
|
|
|
|
|
|
|
|
invalidateThumb(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
triggerUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
bool ThumbBarView::getExifRotate()
|
|
|
|
{
|
|
|
|
return d->exifRotate;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ThumbBarView::getOrientation()
|
|
|
|
{
|
|
|
|
return d->orientation;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ThumbBarView::getTileSize()
|
|
|
|
{
|
|
|
|
return d->tileSize;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ThumbBarView::getMargin()
|
|
|
|
{
|
|
|
|
return d->margin;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::setToolTipSettings(const ThumbBarToolTipSettings &settings)
|
|
|
|
{
|
|
|
|
d->toolTipSettings = settings;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarToolTipSettings& ThumbBarView::getToolTipSettings()
|
|
|
|
{
|
|
|
|
return d->toolTipSettings;
|
|
|
|
}
|
|
|
|
|
|
|
|
int ThumbBarView::countItems()
|
|
|
|
{
|
|
|
|
return d->count;
|
|
|
|
}
|
|
|
|
|
|
|
|
KURL::List ThumbBarView::itemsURLs()
|
|
|
|
{
|
|
|
|
KURL::List urlList;
|
|
|
|
if (!countItems())
|
|
|
|
return urlList;
|
|
|
|
|
|
|
|
for (ThumbBarItem *item = firstItem(); item; item = item->next())
|
|
|
|
urlList.append(item->url());
|
|
|
|
|
|
|
|
return urlList;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::clear(bool updateView)
|
|
|
|
{
|
|
|
|
d->clearing = true;
|
|
|
|
|
|
|
|
ThumbBarItem *item = d->firstItem;
|
|
|
|
while (item)
|
|
|
|
{
|
|
|
|
ThumbBarItem *tmp = item->d->next;
|
|
|
|
delete item;
|
|
|
|
item = tmp;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->firstItem = 0;
|
|
|
|
d->lastItem = 0;
|
|
|
|
d->count = 0;
|
|
|
|
d->currItem = 0;
|
|
|
|
|
|
|
|
if (updateView)
|
|
|
|
slotUpdate();
|
|
|
|
|
|
|
|
d->clearing = false;
|
|
|
|
|
|
|
|
emit signalItemSelected(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::triggerUpdate()
|
|
|
|
{
|
|
|
|
d->timer->start(0, true);
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarView::currentItem() const
|
|
|
|
{
|
|
|
|
return d->currItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarView::firstItem() const
|
|
|
|
{
|
|
|
|
return d->firstItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarView::lastItem() const
|
|
|
|
{
|
|
|
|
return d->lastItem;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarView::findItem(const TQPoint& pos) const
|
|
|
|
{
|
|
|
|
int itemPos;
|
|
|
|
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
itemPos = pos.y();
|
|
|
|
else
|
|
|
|
itemPos = pos.x();
|
|
|
|
|
|
|
|
for (ThumbBarItem *item = d->firstItem; item; item = item->d->next)
|
|
|
|
{
|
|
|
|
if (itemPos >= item->d->pos && itemPos <= (item->d->pos+d->tileSize+2*d->margin))
|
|
|
|
{
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarView::findItemByURL(const KURL& url) const
|
|
|
|
{
|
|
|
|
for (ThumbBarItem *item = d->firstItem; item; item = item->d->next)
|
|
|
|
{
|
|
|
|
if (item->url().equals(url))
|
|
|
|
{
|
|
|
|
return item;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::setSelected(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
|
|
|
|
ensureItemVisible(item);
|
|
|
|
emit signalURLSelected(item->url());
|
|
|
|
emit signalItemSelected(item);
|
|
|
|
|
|
|
|
if (d->currItem == item) return;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
ThumbBarItem* item = d->currItem;
|
|
|
|
d->currItem = 0;
|
|
|
|
item->tqrepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
d->currItem = item;
|
|
|
|
if (d->currItem)
|
|
|
|
item->tqrepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::ensureItemVisible(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
// We want the complete thumb visible and the next one.
|
|
|
|
// find the middle of the image and give a margin of 1,5 image
|
|
|
|
// When changed, watch regression for bug 104031
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
ensureVisible(0, (int)(item->d->pos + d->margin + d->tileSize*.5),
|
|
|
|
0, (int)(d->tileSize*1.5 + 3*d->margin));
|
|
|
|
else
|
|
|
|
ensureVisible((int)(item->d->pos + d->margin + d->tileSize*.5), 0,
|
|
|
|
(int)(d->tileSize*1.5 + 3*d->margin), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::refreshThumbs(const KURL::List& urls)
|
|
|
|
{
|
|
|
|
for (KURL::List::const_iterator it = urls.begin() ; it != urls.end() ; ++it)
|
|
|
|
{
|
|
|
|
ThumbBarItem *item = findItemByURL(*it);
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
invalidateThumb(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::invalidateThumb(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
|
|
|
|
if (item->d->pixmap)
|
|
|
|
{
|
|
|
|
delete item->d->pixmap;
|
|
|
|
item->d->pixmap = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!d->thumbJob.isNull())
|
|
|
|
{
|
|
|
|
d->thumbJob->kill();
|
|
|
|
d->thumbJob = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->thumbJob = new ThumbnailJob(item->url(), ThumbnailSize::Huge, true, d->exifRotate);
|
|
|
|
|
|
|
|
connect(d->thumbJob, TQT_SIGNAL(signalThumbnail(const KURL&, const TQPixmap&)),
|
|
|
|
this, TQT_SLOT(slotGotThumbnail(const KURL&, const TQPixmap&)));
|
|
|
|
|
|
|
|
connect(d->thumbJob, TQT_SIGNAL(signalFailed(const KURL&)),
|
|
|
|
this, TQT_SLOT(slotFailedThumbnail(const KURL&)));
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::viewportPaintEvent(TQPaintEvent* e)
|
|
|
|
{
|
|
|
|
int cy, cx, ts, y1, y2, x1, x2;
|
|
|
|
TQPixmap bgPix, tile;
|
|
|
|
TQRect er(e->rect());
|
|
|
|
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
{
|
|
|
|
cy = viewportToContents(er.topLeft()).y();
|
|
|
|
|
|
|
|
bgPix.resize(contentsRect().width(), er.height());
|
|
|
|
|
|
|
|
ts = d->tileSize + 2*d->margin;
|
|
|
|
tile.resize(visibleWidth(), ts);
|
|
|
|
|
|
|
|
y1 = (cy/ts)*ts;
|
|
|
|
y2 = ((y1 + er.height())/ts +1)*ts;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cx = viewportToContents(er.topLeft()).x();
|
|
|
|
|
|
|
|
bgPix.resize(er.width(), contentsRect().height());
|
|
|
|
|
|
|
|
ts = d->tileSize + 2*d->margin;
|
|
|
|
tile.resize(ts, visibleHeight());
|
|
|
|
|
|
|
|
x1 = (cx/ts)*ts;
|
|
|
|
x2 = ((x1 + er.width())/ts +1)*ts;
|
|
|
|
}
|
|
|
|
|
|
|
|
bgPix.fill(tqcolorGroup().background());
|
|
|
|
|
|
|
|
for (ThumbBarItem *item = d->firstItem; item; item = item->d->next)
|
|
|
|
{
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
{
|
|
|
|
if (y1 <= item->d->pos && item->d->pos <= y2)
|
|
|
|
{
|
|
|
|
if (item == d->currItem)
|
|
|
|
tile.fill(tqcolorGroup().highlight());
|
|
|
|
else
|
|
|
|
tile.fill(tqcolorGroup().background());
|
|
|
|
|
|
|
|
TQPainter p(&tile);
|
|
|
|
p.setPen(TQt::white);
|
|
|
|
p.drawRect(0, 0, tile.width(), tile.height());
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
if (item->d->pixmap)
|
|
|
|
{
|
|
|
|
TQPixmap pix;
|
|
|
|
pix.convertFromImage(TQImage(item->d->pixmap->convertToImage()).
|
|
|
|
smoothScale(d->tileSize, d->tileSize, TQ_ScaleMin));
|
|
|
|
int x = (tile.width() - pix.width())/2;
|
|
|
|
int y = (tile.height() - pix.height())/2;
|
|
|
|
bitBlt(&tile, x, y, &pix);
|
|
|
|
}
|
|
|
|
|
|
|
|
bitBlt(&bgPix, 0, item->d->pos - cy, &tile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (x1 <= item->d->pos && item->d->pos <= x2)
|
|
|
|
{
|
|
|
|
if (item == d->currItem)
|
|
|
|
tile.fill(tqcolorGroup().highlight());
|
|
|
|
else
|
|
|
|
tile.fill(tqcolorGroup().background());
|
|
|
|
|
|
|
|
TQPainter p(&tile);
|
|
|
|
p.setPen(TQt::white);
|
|
|
|
p.drawRect(0, 0, tile.width(), tile.height());
|
|
|
|
p.end();
|
|
|
|
|
|
|
|
if (item->d->pixmap)
|
|
|
|
{
|
|
|
|
TQPixmap pix;
|
|
|
|
pix.convertFromImage(TQImage(item->d->pixmap->convertToImage()).
|
|
|
|
smoothScale(d->tileSize, d->tileSize, TQ_ScaleMin));
|
|
|
|
int x = (tile.width() - pix.width())/2;
|
|
|
|
int y = (tile.height()- pix.height())/2;
|
|
|
|
bitBlt(&tile, x, y, &pix);
|
|
|
|
}
|
|
|
|
|
|
|
|
bitBlt(&bgPix, item->d->pos - cx, 0, &tile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
bitBlt(viewport(), 0, er.y(), &bgPix);
|
|
|
|
else
|
|
|
|
bitBlt(viewport(), er.x(), 0, &bgPix);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::contentsMousePressEvent(TQMouseEvent* e)
|
|
|
|
{
|
|
|
|
ThumbBarItem* barItem = findItem(e->pos());
|
|
|
|
d->dragging = true;
|
|
|
|
d->dragStartPos = e->pos();
|
|
|
|
|
|
|
|
if (!barItem || barItem == d->currItem)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (d->currItem)
|
|
|
|
{
|
|
|
|
ThumbBarItem* item = d->currItem;
|
|
|
|
d->currItem = 0;
|
|
|
|
item->tqrepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
d->currItem = barItem;
|
|
|
|
barItem->tqrepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::contentsMouseMoveEvent(TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
if (!e) return;
|
|
|
|
|
|
|
|
if (d->dragging && (e->state() & Qt::LeftButton))
|
|
|
|
{
|
|
|
|
if ( findItem(d->dragStartPos) &&
|
|
|
|
(d->dragStartPos - e->pos()).manhattanLength() > TQApplication::startDragDistance() )
|
|
|
|
{
|
|
|
|
startDrag();
|
|
|
|
}
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::contentsMouseReleaseEvent(TQMouseEvent *e)
|
|
|
|
{
|
|
|
|
d->dragging = false;
|
|
|
|
ThumbBarItem *item = findItem(e->pos());
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
emit signalURLSelected(item->url());
|
|
|
|
emit signalItemSelected(item);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::contentsWheelEvent(TQWheelEvent *e)
|
|
|
|
{
|
|
|
|
e->accept();
|
|
|
|
|
|
|
|
if (e->delta() < 0)
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
scrollBy(0, verticalScrollBar()->pageStep());
|
|
|
|
else
|
|
|
|
scrollBy(horizontalScrollBar()->pageStep(), 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
scrollBy(0, verticalScrollBar()->lineStep());
|
|
|
|
else
|
|
|
|
scrollBy(horizontalScrollBar()->lineStep(), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (e->delta() > 0)
|
|
|
|
{
|
|
|
|
if (e->state() & TQt::ShiftButton)
|
|
|
|
{
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
scrollBy(0, (-1)*verticalScrollBar()->pageStep());
|
|
|
|
else
|
|
|
|
scrollBy((-1)*horizontalScrollBar()->pageStep(), 0);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
scrollBy(0, (-1)*verticalScrollBar()->lineStep());
|
|
|
|
else
|
|
|
|
scrollBy((-1)*horizontalScrollBar()->lineStep(), 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::startDrag()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::insertItem(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
|
|
|
|
if (!d->firstItem)
|
|
|
|
{
|
|
|
|
d->firstItem = item;
|
|
|
|
d->lastItem = item;
|
|
|
|
item->d->prev = 0;
|
|
|
|
item->d->next = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
d->lastItem->d->next = item;
|
|
|
|
item->d->prev = d->lastItem;
|
|
|
|
item->d->next = 0;
|
|
|
|
d->lastItem = item;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!d->currItem)
|
|
|
|
{
|
|
|
|
d->currItem = item;
|
|
|
|
emit signalURLSelected(item->url());
|
|
|
|
emit signalItemSelected(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
d->itemDict.insert(item->url().url(), item);
|
|
|
|
|
|
|
|
d->count++;
|
|
|
|
triggerUpdate();
|
|
|
|
emit signalItemAdded();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::removeItem(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
if (!item) return;
|
|
|
|
|
|
|
|
d->count--;
|
|
|
|
|
|
|
|
if (item == d->firstItem)
|
|
|
|
{
|
|
|
|
d->firstItem = d->currItem = d->firstItem->d->next;
|
|
|
|
if (d->firstItem)
|
|
|
|
d->firstItem->d->prev = 0;
|
|
|
|
else
|
|
|
|
d->firstItem = d->lastItem = d->currItem = 0;
|
|
|
|
}
|
|
|
|
else if (item == d->lastItem)
|
|
|
|
{
|
|
|
|
d->lastItem = d->currItem = d->lastItem->d->prev;
|
|
|
|
if ( d->lastItem )
|
|
|
|
d->lastItem->d->next = 0;
|
|
|
|
else
|
|
|
|
d->firstItem = d->lastItem = d->currItem = 0;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
ThumbBarItem *i = item;
|
|
|
|
if (i)
|
|
|
|
{
|
|
|
|
if (i->d->prev )
|
|
|
|
{
|
|
|
|
i->d->prev->d->next = d->currItem = i->d->next;
|
|
|
|
}
|
|
|
|
if ( i->d->next )
|
|
|
|
{
|
|
|
|
i->d->next->d->prev = d->currItem = i->d->prev;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
d->itemDict.remove(item->url().url());
|
|
|
|
|
|
|
|
if (!d->clearing)
|
|
|
|
{
|
|
|
|
triggerUpdate();
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d->count == 0)
|
|
|
|
emit signalItemSelected(0);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::rearrangeItems()
|
|
|
|
{
|
|
|
|
KURL::List urlList;
|
|
|
|
|
|
|
|
int pos = 0;
|
|
|
|
ThumbBarItem *item = d->firstItem;
|
|
|
|
|
|
|
|
while (item)
|
|
|
|
{
|
|
|
|
item->d->pos = pos;
|
|
|
|
pos += d->tileSize + 2*d->margin;
|
|
|
|
if (!(item->d->pixmap))
|
|
|
|
urlList.append(item->d->url);
|
|
|
|
item = item->d->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
resizeContents(visibleWidth(), d->count*(d->tileSize+2*d->margin));
|
|
|
|
else
|
|
|
|
resizeContents(d->count*(d->tileSize+2*d->margin), visibleHeight());
|
|
|
|
|
|
|
|
if (!urlList.isEmpty())
|
|
|
|
{
|
|
|
|
if (!d->thumbJob.isNull())
|
|
|
|
{
|
|
|
|
d->thumbJob->kill();
|
|
|
|
d->thumbJob = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
d->thumbJob = new ThumbnailJob(urlList, ThumbnailSize::Huge, true, d->exifRotate);
|
|
|
|
|
|
|
|
connect(d->thumbJob, TQT_SIGNAL(signalThumbnail(const KURL&, const TQPixmap&)),
|
|
|
|
this, TQT_SLOT(slotGotThumbnail(const KURL&, const TQPixmap&)));
|
|
|
|
|
|
|
|
connect(d->thumbJob, TQT_SIGNAL(signalFailed(const KURL&)),
|
|
|
|
this, TQT_SLOT(slotFailedThumbnail(const KURL&)));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::repaintItem(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
if (item)
|
|
|
|
{
|
|
|
|
if (d->orientation ==Qt::Vertical)
|
|
|
|
repaintContents(0, item->d->pos, visibleWidth(), d->tileSize+2*d->margin);
|
|
|
|
else
|
|
|
|
repaintContents(item->d->pos, 0, d->tileSize+2*d->margin, visibleHeight());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::slotUpdate()
|
|
|
|
{
|
|
|
|
rearrangeItems();
|
|
|
|
viewport()->update();
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::slotGotThumbnail(const KURL& url, const TQPixmap& pix)
|
|
|
|
{
|
|
|
|
if (!pix.isNull())
|
|
|
|
{
|
|
|
|
ThumbBarItem* item = d->itemDict.find(url.url());
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (item->d->pixmap)
|
|
|
|
{
|
|
|
|
delete item->d->pixmap;
|
|
|
|
item->d->pixmap = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->d->pixmap = new TQPixmap(pix);
|
|
|
|
item->tqrepaint();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarView::slotFailedThumbnail(const KURL& url)
|
|
|
|
{
|
|
|
|
ThumbBarItem* item = d->itemDict.find(url.url());
|
|
|
|
if (!item)
|
|
|
|
return;
|
|
|
|
|
|
|
|
KIconLoader* iconLoader = KApplication::kApplication()->iconLoader();
|
|
|
|
TQPixmap pix = iconLoader->loadIcon("image", KIcon::NoGroup, ThumbnailSize::Huge);
|
|
|
|
|
|
|
|
if (item->d->pixmap)
|
|
|
|
{
|
|
|
|
delete item->d->pixmap;
|
|
|
|
item->d->pixmap = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
item->d->pixmap = new TQPixmap(pix);
|
|
|
|
item->tqrepaint();
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ThumbBarItem::ThumbBarItem(ThumbBarView* view, const KURL& url)
|
|
|
|
{
|
|
|
|
d = new ThumbBarItemPriv;
|
|
|
|
d->url = url;
|
|
|
|
d->view = view;
|
|
|
|
d->view->insertItem(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem::~ThumbBarItem()
|
|
|
|
{
|
|
|
|
d->view->removeItem(this);
|
|
|
|
|
|
|
|
if (d->pixmap)
|
|
|
|
delete d->pixmap;
|
|
|
|
|
|
|
|
delete d;
|
|
|
|
}
|
|
|
|
|
|
|
|
KURL ThumbBarItem::url() const
|
|
|
|
{
|
|
|
|
return d->url;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarItem::next() const
|
|
|
|
{
|
|
|
|
return d->next;
|
|
|
|
}
|
|
|
|
|
|
|
|
ThumbBarItem* ThumbBarItem::prev() const
|
|
|
|
{
|
|
|
|
return d->prev;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQRect ThumbBarItem::rect() const
|
|
|
|
{
|
|
|
|
if (d->view->d->orientation == ThumbBarView::Vertical)
|
|
|
|
{
|
|
|
|
return TQRect(0, d->pos,
|
|
|
|
d->view->visibleWidth(),
|
|
|
|
d->view->d->tileSize + 2*d->view->d->margin);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return TQRect(d->pos, 0,
|
|
|
|
d->view->d->tileSize + 2*d->view->d->margin,
|
|
|
|
d->view->visibleHeight());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
int ThumbBarItem::position() const
|
|
|
|
{
|
|
|
|
return d->pos;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQPixmap* ThumbBarItem::pixmap() const
|
|
|
|
{
|
|
|
|
return d->pixmap;
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarItem::tqrepaint()
|
|
|
|
{
|
|
|
|
d->view->repaintItem(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
// -------------------------------------------------------------------------
|
|
|
|
|
|
|
|
ThumbBarToolTip::ThumbBarToolTip(ThumbBarView* tqparent)
|
|
|
|
: TQToolTip(tqparent->viewport()), m_maxStringLen(30), m_view(tqparent)
|
|
|
|
{
|
|
|
|
m_headBeg = TQString("<tr bgcolor=\"orange\"><td colspan=\"2\">"
|
|
|
|
"<nobr><font size=\"-1\" color=\"black\"><b>");
|
|
|
|
m_headEnd = TQString("</b></font></nobr></td></tr>");
|
|
|
|
|
|
|
|
m_cellBeg = TQString("<tr><td><nobr><font size=\"-1\" color=\"black\">");
|
|
|
|
m_cellMid = TQString("</font></nobr></td>"
|
|
|
|
"<td><nobr><font size=\"-1\" color=\"black\">");
|
|
|
|
m_cellEnd = TQString("</font></nobr></td></tr>");
|
|
|
|
|
|
|
|
m_cellSpecBeg = TQString("<tr><td><nobr><font size=\"-1\" color=\"black\">");
|
|
|
|
m_cellSpecMid = TQString("</font></nobr></td>"
|
|
|
|
"<td><nobr><font size=\"-1\" color=\"steelblue\"><i>");
|
|
|
|
m_cellSpecEnd = TQString("</i></font></nobr></td></tr>");
|
|
|
|
}
|
|
|
|
|
|
|
|
void ThumbBarToolTip::maybeTip(const TQPoint& pos)
|
|
|
|
{
|
|
|
|
if ( !parentWidget() || !m_view) return;
|
|
|
|
|
|
|
|
ThumbBarItem* item = m_view->findItem( m_view->viewportToContents(pos) );
|
|
|
|
if (!item) return;
|
|
|
|
|
|
|
|
if (!m_view->getToolTipSettings().showToolTips) return;
|
|
|
|
|
|
|
|
TQString tipText = tipContent(item);
|
|
|
|
tipText.append(tipContentExtraData(item));
|
|
|
|
tipText.append("</table>");
|
|
|
|
|
|
|
|
TQRect r(item->rect());
|
|
|
|
r = TQRect( m_view->contentsToViewport(r.topLeft()), r.size() );
|
|
|
|
|
|
|
|
tip(r, tipText);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ThumbBarToolTip::tipContent(ThumbBarItem* item)
|
|
|
|
{
|
|
|
|
ThumbBarToolTipSettings settings = m_view->getToolTipSettings();
|
|
|
|
|
|
|
|
TQString tipText, str;
|
|
|
|
TQString unavailable(i18n("unavailable"));
|
|
|
|
|
|
|
|
tipText = "<table cellspacing=\"0\" cellpadding=\"0\" width=\"250\" border=\"0\">";
|
|
|
|
|
|
|
|
TQFileInfo fileInfo(item->url().path());
|
|
|
|
|
|
|
|
KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, item->url());
|
|
|
|
DMetadata metaData(item->url().path());
|
|
|
|
|
|
|
|
// -- File properties ----------------------------------------------
|
|
|
|
|
|
|
|
if (settings.showFileName ||
|
|
|
|
settings.showFileDate ||
|
|
|
|
settings.showFileSize ||
|
|
|
|
settings.showImageType ||
|
|
|
|
settings.showImageDim)
|
|
|
|
{
|
|
|
|
tipText += m_headBeg + i18n("File Properties") + m_headEnd;
|
|
|
|
|
|
|
|
if (settings.showFileName)
|
|
|
|
{
|
|
|
|
tipText += m_cellBeg + i18n("Name:") + m_cellMid;
|
|
|
|
tipText += item->url().fileName() + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showFileDate)
|
|
|
|
{
|
|
|
|
TQDateTime modifiedDate = fileInfo.lastModified();
|
|
|
|
str = KGlobal::locale()->formatDateTime(modifiedDate, true, true);
|
|
|
|
tipText += m_cellBeg + i18n("Modified:") + m_cellMid + str + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showFileSize)
|
|
|
|
{
|
|
|
|
tipText += m_cellBeg + i18n("Size:") + m_cellMid;
|
|
|
|
str = i18n("%1 (%2)").tqarg(KIO::convertSize(fi.size()))
|
|
|
|
.tqarg(KGlobal::locale()->formatNumber(fi.size(), 0));
|
|
|
|
tipText += str + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize dims;
|
|
|
|
#if KDCRAW_VERSION < 0x000106
|
|
|
|
TQString rawFilesExt(KDcrawIface::DcrawBinary::instance()->rawFiles());
|
|
|
|
#else
|
|
|
|
TQString rawFilesExt(KDcrawIface::KDcraw::rawFiles());
|
|
|
|
#endif
|
|
|
|
TQString ext = fileInfo.extension(false).upper();
|
|
|
|
|
|
|
|
if (!ext.isEmpty() && rawFilesExt.upper().contains(ext))
|
|
|
|
{
|
|
|
|
str = i18n("RAW Image");
|
|
|
|
dims = metaData.getImageDimensions();
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
str = fi.mimeComment();
|
|
|
|
|
|
|
|
KFileMetaInfo meta = fi.metaInfo();
|
|
|
|
if (meta.isValid())
|
|
|
|
{
|
|
|
|
if (meta.containsGroup("Jpeg EXIF Data"))
|
|
|
|
dims = meta.group("Jpeg EXIF Data").item("Dimensions").value().toSize();
|
|
|
|
else if (meta.containsGroup("General"))
|
|
|
|
dims = meta.group("General").item("Dimensions").value().toSize();
|
|
|
|
else if (meta.containsGroup("Technical"))
|
|
|
|
dims = meta.group("Technical").item("Dimensions").value().toSize();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showImageType)
|
|
|
|
{
|
|
|
|
tipText += m_cellBeg + i18n("Type:") + m_cellMid + str + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showImageDim)
|
|
|
|
{
|
|
|
|
TQString mpixels;
|
|
|
|
mpixels.setNum(dims.width()*dims.height()/1000000.0, 'f', 2);
|
|
|
|
str = (!dims.isValid()) ? i18n("Unknown") : i18n("%1x%2 (%3Mpx)")
|
|
|
|
.tqarg(dims.width()).tqarg(dims.height()).tqarg(mpixels);
|
|
|
|
tipText += m_cellBeg + i18n("Dimensions:") + m_cellMid + str + m_cellEnd;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// -- Photograph Info ----------------------------------------------------
|
|
|
|
|
|
|
|
if (settings.showPhotoMake ||
|
|
|
|
settings.showPhotoDate ||
|
|
|
|
settings.showPhotoFocal ||
|
|
|
|
settings.showPhotoExpo ||
|
|
|
|
settings.showPhotoMode ||
|
|
|
|
settings.showPhotoFlash ||
|
|
|
|
settings.showPhotoWB)
|
|
|
|
{
|
|
|
|
PhotoInfoContainer photoInfo = metaData.getPhotographInformations();
|
|
|
|
|
|
|
|
if (!photoInfo.isEmpty())
|
|
|
|
{
|
|
|
|
TQString metaStr;
|
|
|
|
tipText += m_headBeg + i18n("Photograph Properties") + m_headEnd;
|
|
|
|
|
|
|
|
if (settings.showPhotoMake)
|
|
|
|
{
|
|
|
|
str = TQString("%1 / %2").tqarg(photoInfo.make.isEmpty() ? unavailable : photoInfo.make)
|
|
|
|
.tqarg(photoInfo.model.isEmpty() ? unavailable : photoInfo.model);
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("Make/Model:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showPhotoDate)
|
|
|
|
{
|
|
|
|
if (photoInfo.dateTime.isValid())
|
|
|
|
{
|
|
|
|
str = KGlobal::locale()->formatDateTime(photoInfo.dateTime, true, true);
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("Created:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
metaStr += m_cellBeg + i18n("Created:") + m_cellMid + TQStyleSheet::escape( unavailable ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showPhotoFocal)
|
|
|
|
{
|
|
|
|
str = photoInfo.aperture.isEmpty() ? unavailable : photoInfo.aperture;
|
|
|
|
|
|
|
|
if (photoInfo.focalLength35mm.isEmpty())
|
|
|
|
str += TQString(" / %1").tqarg(photoInfo.focalLength.isEmpty() ? unavailable : photoInfo.focalLength);
|
|
|
|
else
|
|
|
|
str += TQString(" / %1").tqarg(i18n("%1 (35mm: %2)").tqarg(photoInfo.focalLength).tqarg(photoInfo.focalLength35mm));
|
|
|
|
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("Aperture/Focal:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showPhotoExpo)
|
|
|
|
{
|
|
|
|
str = TQString("%1 / %2").tqarg(photoInfo.exposureTime.isEmpty() ? unavailable : photoInfo.exposureTime)
|
|
|
|
.tqarg(photoInfo.sensitivity.isEmpty() ? unavailable : i18n("%1 ISO").tqarg(photoInfo.sensitivity));
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("Exposure/Sensitivity:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showPhotoMode)
|
|
|
|
{
|
|
|
|
|
|
|
|
if (photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
|
|
|
|
str = unavailable;
|
|
|
|
else if (!photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
|
|
|
|
str = photoInfo.exposureMode;
|
|
|
|
else if (photoInfo.exposureMode.isEmpty() && !photoInfo.exposureProgram.isEmpty())
|
|
|
|
str = photoInfo.exposureProgram;
|
|
|
|
else
|
|
|
|
str = TQString("%1 / %2").tqarg(photoInfo.exposureMode).tqarg(photoInfo.exposureProgram);
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("Mode/Program:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showPhotoFlash)
|
|
|
|
{
|
|
|
|
str = photoInfo.flash.isEmpty() ? unavailable : photoInfo.flash;
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("Flash:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (settings.showPhotoWB)
|
|
|
|
{
|
|
|
|
str = photoInfo.whiteBalance.isEmpty() ? unavailable : photoInfo.whiteBalance;
|
|
|
|
if (str.length() > m_maxStringLen) str = str.left(m_maxStringLen-3) + "...";
|
|
|
|
metaStr += m_cellBeg + i18n("White Balance:") + m_cellMid + TQStyleSheet::escape( str ) + m_cellEnd;
|
|
|
|
}
|
|
|
|
|
|
|
|
tipText += metaStr;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return tipText;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString ThumbBarToolTip::breakString(const TQString& input)
|
|
|
|
{
|
|
|
|
TQString str = input.simplifyWhiteSpace();
|
|
|
|
str = TQStyleSheet::escape(str);
|
|
|
|
const uint maxLen = m_maxStringLen;
|
|
|
|
|
|
|
|
if (str.length() <= maxLen)
|
|
|
|
return str;
|
|
|
|
|
|
|
|
TQString br;
|
|
|
|
|
|
|
|
uint i = 0;
|
|
|
|
uint count = 0;
|
|
|
|
|
|
|
|
while (i < str.length())
|
|
|
|
{
|
|
|
|
if (count >= maxLen && str[i].isSpace())
|
|
|
|
{
|
|
|
|
count = 0;
|
|
|
|
br.append("<br>");
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
br.append(str[i]);
|
|
|
|
}
|
|
|
|
|
|
|
|
i++;
|
|
|
|
count++;
|
|
|
|
}
|
|
|
|
|
|
|
|
return br;
|
|
|
|
}
|
|
|
|
|
|
|
|
} // NameSpace Digikam
|