You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
digikam/digikam/libs/thumbbar/thumbbar.cpp

1139 lines
30 KiB

/* ============================================================
*
* 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 <tdefileitem.h>
#include <kapplication.h>
#include <kiconloader.h>
#include <klocale.h>
#include <kmimetype.h>
#include <tdefileitem.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* parent, int orientation, bool exifRotate,
ThumbBarToolTipSettings settings)
: TQScrollView(parent)
{
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()->sizeHint().width();
verticalScrollBar()->setLineStep(d->tileSize);
verticalScrollBar()->setPageStep(2*d->tileSize);
}
else
{
d->tileSize = height() - 2*d->margin - horizontalScrollBar()->sizeHint().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->repaint();
}
d->currItem = item;
if (d->currItem)
item->repaint();
}
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(colorGroup().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(colorGroup().highlight());
else
tile.fill(colorGroup().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(colorGroup().highlight());
else
tile.fill(colorGroup().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->repaint();
}
d->currItem = barItem;
barItem->repaint();
}
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->repaint();
}
}
void ThumbBarView::slotFailedThumbnail(const KURL& url)
{
ThumbBarItem* item = d->itemDict.find(url.url());
if (!item)
return;
KIconLoader* iconLoader = TDEApplication::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->repaint();
}
// -------------------------------------------------------------------------
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::repaint()
{
d->view->repaintItem(this);
}
// -------------------------------------------------------------------------
ThumbBarToolTip::ThumbBarToolTip(ThumbBarView* parent)
: TQToolTip(parent->viewport()), m_maxStringLen(30), m_view(parent)
{
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 = TDEGlobal::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)").arg(TDEIO::convertSize(fi.size()))
.arg(TDEGlobal::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)")
.arg(dims.width()).arg(dims.height()).arg(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").arg(photoInfo.make.isEmpty() ? unavailable : photoInfo.make)
.arg(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 = TDEGlobal::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").arg(photoInfo.focalLength.isEmpty() ? unavailable : photoInfo.focalLength);
else
str += TQString(" / %1").arg(i18n("%1 (35mm: %2)").arg(photoInfo.focalLength).arg(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").arg(photoInfo.exposureTime.isEmpty() ? unavailable : photoInfo.exposureTime)
.arg(photoInfo.sensitivity.isEmpty() ? unavailable : i18n("%1 ISO").arg(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").arg(photoInfo.exposureMode).arg(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