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.
589 lines
18 KiB
589 lines
18 KiB
/* ============================================================
|
|
*
|
|
* This file is a part of digiKam project
|
|
* http://www.digikam.org
|
|
*
|
|
* Date : 2004-08-19
|
|
* Description : Album item file tip adapted from tdefiletip
|
|
* (konqueror - konq_iconviewwidget.cc)
|
|
*
|
|
* Copyright (C) 1998-1999 by Torben Weis <weis@kde.org>
|
|
* Copyright (C) 2000-2002 by David Faure <david@mandrakesoft.com>
|
|
* Copyright (C) 2004-2005 by Renchi Raju <renchi@pooh.tam.uiuc.edu>
|
|
* Copyright (C) 2006-2007 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.
|
|
*
|
|
* ============================================================ */
|
|
|
|
// TQt includes.
|
|
|
|
#include <tqtooltip.h>
|
|
#include <tqfileinfo.h>
|
|
#include <tqlabel.h>
|
|
#include <tqlayout.h>
|
|
#include <tqpixmap.h>
|
|
#include <tqdatetime.h>
|
|
#include <tqstylesheet.h>
|
|
#include <tqpainter.h>
|
|
#include <tqapplication.h>
|
|
|
|
// KDE includes.
|
|
|
|
#include <tdelocale.h>
|
|
#include <tdefileitem.h>
|
|
#include <kmimetype.h>
|
|
#include <tdeglobalsettings.h>
|
|
#include <tdeglobal.h>
|
|
#include <tdeversion.h>
|
|
|
|
// LibKDcraw includes.
|
|
|
|
#include <libkdcraw/version.h>
|
|
#include <libkdcraw/kdcraw.h>
|
|
|
|
#if KDCRAW_VERSION < 0x000106
|
|
#include <libkdcraw/dcrawbinary.h>
|
|
#endif
|
|
|
|
// Local includes.
|
|
|
|
#include "ddebug.h"
|
|
#include "dmetadata.h"
|
|
#include "albumiconview.h"
|
|
#include "albumiconitem.h"
|
|
#include "albumsettings.h"
|
|
#include "album.h"
|
|
#include "albumfiletip.h"
|
|
|
|
namespace Digikam
|
|
{
|
|
|
|
class AlbumFileTipPriv
|
|
{
|
|
public:
|
|
|
|
AlbumFileTipPriv() :
|
|
maxStringLen(30), tipBorder(5)
|
|
{
|
|
corner = 0;
|
|
label = 0;
|
|
view = 0;
|
|
iconItem = 0;
|
|
}
|
|
|
|
const uint maxStringLen;
|
|
const uint tipBorder;
|
|
|
|
int corner;
|
|
|
|
TQLabel *label;
|
|
|
|
TQPixmap corners[4];
|
|
|
|
AlbumIconView *view;
|
|
|
|
AlbumIconItem *iconItem;
|
|
};
|
|
|
|
AlbumFileTip::AlbumFileTip(AlbumIconView* view)
|
|
: TQFrame(0, 0, WStyle_Customize | WStyle_NoBorder | WStyle_Tool |
|
|
WStyle_StaysOnTop | WX11BypassWM)
|
|
{
|
|
d = new AlbumFileTipPriv;
|
|
d->view = view;
|
|
hide();
|
|
|
|
setPalette(TQToolTip::palette());
|
|
setFrameStyle(TQFrame::Plain | TQFrame::Box);
|
|
setLineWidth(1);
|
|
|
|
TQVBoxLayout *layout = new TQVBoxLayout(this, d->tipBorder+1, 0);
|
|
|
|
d->label = new TQLabel(this);
|
|
d->label->setMargin(0);
|
|
d->label->setAlignment(TQt::AlignHCenter | TQt::AlignVCenter);
|
|
|
|
layout->addWidget(d->label);
|
|
layout->setResizeMode(TQLayout::Fixed);
|
|
|
|
renderArrows();
|
|
}
|
|
|
|
AlbumFileTip::~AlbumFileTip()
|
|
{
|
|
delete d;
|
|
}
|
|
|
|
void AlbumFileTip::setIconItem(AlbumIconItem* iconItem)
|
|
{
|
|
d->iconItem = iconItem;
|
|
|
|
if (!d->iconItem ||
|
|
!AlbumSettings::instance()->showToolTipsIsValid())
|
|
{
|
|
hide();
|
|
}
|
|
else
|
|
{
|
|
updateText();
|
|
reposition();
|
|
if (isHidden())
|
|
show();
|
|
}
|
|
}
|
|
|
|
void AlbumFileTip::reposition()
|
|
{
|
|
if (!d->iconItem)
|
|
return;
|
|
|
|
TQRect rect = d->iconItem->clickToOpenRect();
|
|
rect.moveTopLeft(d->view->contentsToViewport(rect.topLeft()));
|
|
rect.moveTopLeft(d->view->viewport()->mapToGlobal(rect.topLeft()));
|
|
|
|
TQPoint pos = rect.center();
|
|
// d->corner:
|
|
// 0: upperleft
|
|
// 1: upperright
|
|
// 2: lowerleft
|
|
// 3: lowerright
|
|
|
|
d->corner = 0;
|
|
// should the tooltip be shown to the left or to the right of the ivi ?
|
|
|
|
#if KDE_IS_VERSION(3,2,0)
|
|
TQRect desk = TDEGlobalSettings::desktopGeometry(rect.center());
|
|
#else
|
|
TQRect desk = TQApplication::desktop()->screenGeometry(
|
|
TQApplication::desktop()->screenNumber(rect.center()) );
|
|
#endif
|
|
|
|
if (rect.center().x() + width() > desk.right())
|
|
{
|
|
// to the left
|
|
if (pos.x() - width() < 0)
|
|
{
|
|
pos.setX(0);
|
|
d->corner = 4;
|
|
}
|
|
else
|
|
{
|
|
pos.setX( pos.x() - width() );
|
|
d->corner = 1;
|
|
}
|
|
}
|
|
|
|
// should the tooltip be shown above or below the ivi ?
|
|
if (rect.bottom() + height() > desk.bottom())
|
|
{
|
|
// above
|
|
pos.setY( rect.top() - height() - 5);
|
|
d->corner += 2;
|
|
}
|
|
else
|
|
{
|
|
pos.setY( rect.bottom() + 5 );
|
|
}
|
|
|
|
move( pos );
|
|
}
|
|
|
|
void AlbumFileTip::renderArrows()
|
|
{
|
|
int w = d->tipBorder;
|
|
|
|
// -- left top arrow -------------------------------------
|
|
|
|
TQPixmap& pix0 = d->corners[0];
|
|
pix0.resize(w, w);
|
|
pix0.fill(colorGroup().background());
|
|
|
|
TQPainter p0(&pix0);
|
|
p0.setPen(TQPen(TQt::black, 1));
|
|
|
|
for (int j=0; j<w; j++)
|
|
p0.drawLine(0, j, w-j-1, j);
|
|
|
|
p0.end();
|
|
|
|
// -- right top arrow ------------------------------------
|
|
|
|
TQPixmap& pix1 = d->corners[1];
|
|
pix1.resize(w, w);
|
|
pix1.fill(colorGroup().background());
|
|
|
|
TQPainter p1(&pix1);
|
|
p1.setPen(TQPen(TQt::black, 1));
|
|
|
|
for (int j=0; j<w; j++)
|
|
p1.drawLine(j, j, w-1, j);
|
|
|
|
p1.end();
|
|
|
|
// -- left bottom arrow ----------------------------------
|
|
|
|
TQPixmap& pix2 = d->corners[2];
|
|
pix2.resize(w, w);
|
|
pix2.fill(colorGroup().background());
|
|
|
|
TQPainter p2(&pix2);
|
|
p2.setPen(TQPen(TQt::black, 1));
|
|
|
|
for (int j=0; j<w; j++)
|
|
p2.drawLine(0, j, j, j);
|
|
|
|
p2.end();
|
|
|
|
// -- right bottom arrow ---------------------------------
|
|
|
|
TQPixmap& pix3 = d->corners[3];
|
|
pix3.resize(w, w);
|
|
pix3.fill(colorGroup().background());
|
|
|
|
TQPainter p3(&pix3);
|
|
p3.setPen(TQPen(TQt::black, 1));
|
|
|
|
for (int j=0; j<w; j++)
|
|
p3.drawLine(w-j-1, j, w-1, j);
|
|
|
|
p3.end();
|
|
}
|
|
|
|
bool AlbumFileTip::event(TQEvent *e)
|
|
{
|
|
switch ( e->type() )
|
|
{
|
|
case TQEvent::Leave:
|
|
case TQEvent::MouseButtonPress:
|
|
case TQEvent::MouseButtonRelease:
|
|
case TQEvent::FocusIn:
|
|
case TQEvent::FocusOut:
|
|
case TQEvent::Wheel:
|
|
hide();
|
|
default:
|
|
break;
|
|
}
|
|
|
|
return TQFrame::event(e);
|
|
}
|
|
|
|
void AlbumFileTip::resizeEvent(TQResizeEvent* e)
|
|
{
|
|
TQFrame::resizeEvent(e);
|
|
reposition();
|
|
}
|
|
|
|
void AlbumFileTip::drawContents(TQPainter *p)
|
|
{
|
|
if (d->corner >= 4)
|
|
{
|
|
TQFrame::drawContents( p );
|
|
return;
|
|
}
|
|
|
|
TQPixmap &pix = d->corners[d->corner];
|
|
|
|
switch ( d->corner )
|
|
{
|
|
case 0:
|
|
p->drawPixmap( 3, 3, pix );
|
|
break;
|
|
case 1:
|
|
p->drawPixmap( width() - pix.width() - 3, 3, pix );
|
|
break;
|
|
case 2:
|
|
p->drawPixmap( 3, height() - pix.height() - 3, pix );
|
|
break;
|
|
case 3:
|
|
p->drawPixmap( width() - pix.width() - 3, height() - pix.height() - 3, pix );
|
|
break;
|
|
}
|
|
|
|
TQFrame::drawContents(p);
|
|
}
|
|
|
|
void AlbumFileTip::updateText()
|
|
{
|
|
TQString tip, str;
|
|
TQString unavailable(i18n("unavailable"));
|
|
|
|
TQString headBeg("<tr bgcolor=\"orange\"><td colspan=\"2\">"
|
|
"<nobr><font size=\"-1\" color=\"black\"><b>");
|
|
TQString headEnd("</b></font></nobr></td></tr>");
|
|
|
|
TQString cellBeg("<tr><td><nobr><font size=\"-1\" color=\"black\">");
|
|
TQString cellMid("</font></nobr></td>"
|
|
"<td><nobr><font size=\"-1\" color=\"black\">");
|
|
TQString cellEnd("</font></nobr></td></tr>");
|
|
|
|
TQString cellSpecBeg("<tr><td><nobr><font size=\"-1\" color=\"black\">");
|
|
TQString cellSpecMid("</font></nobr></td>"
|
|
"<td><nobr><font size=\"-1\" color=\"steelblue\"><i>");
|
|
TQString cellSpecEnd("</i></font></nobr></td></tr>");
|
|
|
|
tip = "<table cellspacing=\"0\" cellpadding=\"0\" width=\"250\" border=\"0\">";
|
|
|
|
AlbumSettings* settings = AlbumSettings::instance();
|
|
const ImageInfo* info = d->iconItem->imageInfo();
|
|
TQFileInfo fileInfo(info->kurl().path());
|
|
KFileItem fi(KFileItem::Unknown, KFileItem::Unknown, info->kurl());
|
|
DMetadata metaData(info->kurl().path());
|
|
|
|
// -- File properties ----------------------------------------------
|
|
|
|
if (settings->getToolTipsShowFileName() ||
|
|
settings->getToolTipsShowFileDate() ||
|
|
settings->getToolTipsShowFileSize() ||
|
|
settings->getToolTipsShowImageType() ||
|
|
settings->getToolTipsShowImageDim())
|
|
{
|
|
tip += headBeg + i18n("File Properties") + headEnd;
|
|
|
|
if (settings->getToolTipsShowFileName())
|
|
{
|
|
tip += cellBeg + i18n("Name:") + cellMid;
|
|
tip += info->kurl().fileName() + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowFileDate())
|
|
{
|
|
TQDateTime modifiedDate = fileInfo.lastModified();
|
|
str = TDEGlobal::locale()->formatDateTime(modifiedDate, true, true);
|
|
tip += cellBeg + i18n("Modified:") + cellMid + str + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowFileSize())
|
|
{
|
|
tip += cellBeg + i18n("Size:") + cellMid;
|
|
str = i18n("%1 (%2)").arg(TDEIO::convertSize(fi.size()))
|
|
.arg(TDEGlobal::locale()->formatNumber(fi.size(), 0));
|
|
tip += str + 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->getToolTipsShowImageType())
|
|
{
|
|
tip += cellBeg + i18n("Type:") + cellMid + str + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowImageDim())
|
|
{
|
|
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);
|
|
tip += cellBeg + i18n("Dimensions:") + cellMid + str + cellEnd;
|
|
}
|
|
}
|
|
|
|
// -- Photograph Info ----------------------------------------------------
|
|
// NOTE: If something is changed here, please updated imageproperties section too.
|
|
|
|
if (settings->getToolTipsShowPhotoMake() ||
|
|
settings->getToolTipsShowPhotoDate() ||
|
|
settings->getToolTipsShowPhotoFocal() ||
|
|
settings->getToolTipsShowPhotoExpo() ||
|
|
settings->getToolTipsShowPhotoMode() ||
|
|
settings->getToolTipsShowPhotoFlash() ||
|
|
settings->getToolTipsShowPhotoWB())
|
|
{
|
|
PhotoInfoContainer photoInfo = metaData.getPhotographInformations();
|
|
|
|
if (!photoInfo.isEmpty())
|
|
{
|
|
TQString metaStr;
|
|
tip += headBeg + i18n("Photograph Properties") + headEnd;
|
|
|
|
if (settings->getToolTipsShowPhotoMake())
|
|
{
|
|
str = TQString("%1 / %2").arg(photoInfo.make.isEmpty() ? unavailable : photoInfo.make)
|
|
.arg(photoInfo.model.isEmpty() ? unavailable : photoInfo.model);
|
|
if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("Make/Model:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowPhotoDate())
|
|
{
|
|
if (photoInfo.dateTime.isValid())
|
|
{
|
|
str = TDEGlobal::locale()->formatDateTime(photoInfo.dateTime, true, true);
|
|
if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("Created:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
else
|
|
metaStr += cellBeg + i18n("Created:") + cellMid + TQStyleSheet::escape( unavailable ) + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowPhotoFocal())
|
|
{
|
|
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() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("Aperture/Focal:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowPhotoExpo())
|
|
{
|
|
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() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("Exposure/Sensitivity:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowPhotoMode())
|
|
{
|
|
|
|
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() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("Mode/Program:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowPhotoFlash())
|
|
{
|
|
str = photoInfo.flash.isEmpty() ? unavailable : photoInfo.flash;
|
|
if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("Flash:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowPhotoWB())
|
|
{
|
|
str = photoInfo.whiteBalance.isEmpty() ? unavailable : photoInfo.whiteBalance;
|
|
if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
metaStr += cellBeg + i18n("White Balance:") + cellMid + TQStyleSheet::escape( str ) + cellEnd;
|
|
}
|
|
|
|
tip += metaStr;
|
|
}
|
|
}
|
|
|
|
// -- digiKam properties ------------------------------------------
|
|
|
|
if (settings->getToolTipsShowAlbumName() ||
|
|
settings->getToolTipsShowComments() ||
|
|
settings->getToolTipsShowTags() ||
|
|
settings->getToolTipsShowRating())
|
|
{
|
|
tip += headBeg + i18n("digiKam Properties") + headEnd;
|
|
|
|
if (settings->getToolTipsShowAlbumName())
|
|
{
|
|
PAlbum* album = info->album();
|
|
if (album)
|
|
tip += cellSpecBeg + i18n("Album:") + cellSpecMid + album->url().remove(0, 1) + cellSpecEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowComments())
|
|
{
|
|
str = info->caption();
|
|
if (str.isEmpty()) str = TQString("---");
|
|
tip += cellSpecBeg + i18n("Caption:") + cellSpecMid + breakString(str) + cellSpecEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowTags())
|
|
{
|
|
TQStringList tagPaths = info->tagPaths(false);
|
|
|
|
str = tagPaths.join(", ");
|
|
if (str.isEmpty()) str = TQString("---");
|
|
if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
|
|
tip += cellSpecBeg + i18n("Tags:") + cellSpecMid + str + cellSpecEnd;
|
|
}
|
|
|
|
if (settings->getToolTipsShowRating())
|
|
{
|
|
str.fill( 'X', info->rating() );
|
|
if (str.isEmpty()) str = TQString("---");
|
|
tip += cellSpecBeg + i18n("Rating:") + cellSpecMid + str + cellSpecEnd;
|
|
}
|
|
}
|
|
|
|
tip += "</table>";
|
|
|
|
d->label->setText(tip);
|
|
}
|
|
|
|
TQString AlbumFileTip::breakString(const TQString& input)
|
|
{
|
|
TQString str = input.simplifyWhiteSpace();
|
|
str = TQStyleSheet::escape(str);
|
|
uint maxLen = d->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
|