00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <QToolTip>
00031 #include <QLabel>
00032 #include <QPixmap>
00033 #include <QDateTime>
00034 #include <QPainter>
00035 #include <QApplication>
00036 #include <QVBoxLayout>
00037 #include <QTextDocument>
00038
00039
00040
00041 #include <kdebug.h>
00042 #include <klocale.h>
00043 #include <kfileitem.h>
00044 #include <kmimetype.h>
00045 #include <kglobalsettings.h>
00046 #include <kglobal.h>
00047 #include <kdeversion.h>
00048
00049
00050
00051 #include "dmetadata.h"
00052 #include "albumiconview.h"
00053 #include "albumiconitem.h"
00054 #include "albummanager.h"
00055 #include "albumsettings.h"
00056 #include "album.h"
00057 #include "albumfiletip.h"
00058
00059 namespace Digikam
00060 {
00061
00062 class AlbumFileTipPriv
00063 {
00064 public:
00065
00066 AlbumFileTipPriv() :
00067 maxStringLen(30), tipBorder(5)
00068 {
00069 corner = 0;
00070 label = 0;
00071 view = 0;
00072 iconItem = 0;
00073 }
00074
00075 const int maxStringLen;
00076 const uint tipBorder;
00077
00078 int corner;
00079
00080 QLabel *label;
00081
00082 QPixmap corners[4];
00083
00084 AlbumIconView *view;
00085
00086 AlbumIconItem *iconItem;
00087 };
00088
00089 AlbumFileTip::AlbumFileTip(AlbumIconView* view)
00090 : QFrame(0)
00091 {
00092 d = new AlbumFileTipPriv;
00093 d->view = view;
00094 hide();
00095
00096 setPalette(QToolTip::palette());
00097 setFrameStyle(QFrame::Plain | QFrame::Box);
00098 setLineWidth(1);
00099 setWindowFlags(Qt::ToolTip);
00100
00101 QVBoxLayout *layout = new QVBoxLayout(this);
00102
00103 d->label = new QLabel(this);
00104 d->label->setMargin(0);
00105 d->label->setAlignment(Qt::AlignHCenter | Qt::AlignVCenter);
00106
00107 layout->addWidget(d->label);
00108 layout->setSizeConstraint(QLayout::SetFixedSize);
00109 layout->setMargin(d->tipBorder+1);
00110 layout->setSpacing(0);
00111
00112 renderArrows();
00113 }
00114
00115 AlbumFileTip::~AlbumFileTip()
00116 {
00117 delete d;
00118 }
00119
00120 void AlbumFileTip::setIconItem(AlbumIconItem* iconItem)
00121 {
00122 d->iconItem = iconItem;
00123
00124 if (!d->iconItem ||
00125 !AlbumSettings::instance()->showToolTipsIsValid())
00126 {
00127 hide();
00128 }
00129 else
00130 {
00131 updateText();
00132 reposition();
00133 if (isHidden())
00134 show();
00135 }
00136 }
00137
00138 void AlbumFileTip::reposition()
00139 {
00140 if (!d->iconItem)
00141 return;
00142
00143 QRect rect = d->iconItem->clickToOpenRect();
00144 rect.moveTopLeft(d->view->contentsToViewport(rect.topLeft()));
00145 rect.moveTopLeft(d->view->viewport()->mapToGlobal(rect.topLeft()));
00146
00147 QPoint pos = rect.center();
00148
00149
00150
00151
00152
00153
00154 d->corner = 0;
00155
00156
00157 QRect desk = KGlobalSettings::desktopGeometry(rect.center());
00158
00159 if (rect.center().x() + width() > desk.right())
00160 {
00161
00162 if (pos.x() - width() < 0)
00163 {
00164 pos.setX(0);
00165 d->corner = 4;
00166 }
00167 else
00168 {
00169 pos.setX( pos.x() - width() );
00170 d->corner = 1;
00171 }
00172 }
00173
00174
00175 if (rect.bottom() + height() > desk.bottom())
00176 {
00177
00178 pos.setY( rect.top() - height() - 5);
00179 d->corner += 2;
00180 }
00181 else
00182 {
00183 pos.setY( rect.bottom() + 5 );
00184 }
00185
00186 move( pos );
00187 }
00188
00189 void AlbumFileTip::renderArrows()
00190 {
00191 int w = d->tipBorder;
00192
00193
00194
00195 QPixmap& pix0 = d->corners[0];
00196 pix0 = QPixmap(w, w);
00197 pix0.fill(palette().color(QPalette::Background));
00198
00199 QPainter p0(&pix0);
00200 p0.setPen(QPen(Qt::black, 1));
00201
00202 for (int j=0; j<w; j++)
00203 p0.drawLine(0, j, w-j-1, j);
00204
00205 p0.end();
00206
00207
00208
00209 QPixmap& pix1 = d->corners[1];
00210 pix1 = QPixmap(w, w);
00211 pix1.fill(palette().color(QPalette::Background));
00212
00213 QPainter p1(&pix1);
00214 p1.setPen(QPen(Qt::black, 1));
00215
00216 for (int j=0; j<w; j++)
00217 p1.drawLine(j, j, w-1, j);
00218
00219 p1.end();
00220
00221
00222
00223 QPixmap& pix2 = d->corners[2];
00224 pix2 = QPixmap(w, w);
00225 pix2.fill(palette().color(QPalette::Background));
00226
00227 QPainter p2(&pix2);
00228 p2.setPen(QPen(Qt::black, 1));
00229
00230 for (int j=0; j<w; j++)
00231 p2.drawLine(0, j, j, j);
00232
00233 p2.end();
00234
00235
00236
00237 QPixmap& pix3 = d->corners[3];
00238 pix3 = QPixmap(w, w);
00239 pix3.fill(palette().color(QPalette::Background));
00240
00241 QPainter p3(&pix3);
00242 p3.setPen(QPen(Qt::black, 1));
00243
00244 for (int j=0; j<w; j++)
00245 p3.drawLine(w-j-1, j, w-1, j);
00246
00247 p3.end();
00248 }
00249
00250 bool AlbumFileTip::event(QEvent *e)
00251 {
00252 switch ( e->type() )
00253 {
00254 case QEvent::Leave:
00255 case QEvent::MouseButtonPress:
00256 case QEvent::MouseButtonRelease:
00257 case QEvent::FocusIn:
00258 case QEvent::FocusOut:
00259 case QEvent::Wheel:
00260 hide();
00261 default:
00262 break;
00263 }
00264
00265 return QFrame::event(e);
00266 }
00267
00268 void AlbumFileTip::resizeEvent(QResizeEvent* e)
00269 {
00270 QFrame::resizeEvent(e);
00271 reposition();
00272 }
00273
00274 void AlbumFileTip::paintEvent(QPaintEvent *e)
00275 {
00276 QFrame::paintEvent(e);
00277
00278 if (d->corner >= 4)
00279 return;
00280
00281 QPainter p(this);
00282 QPixmap &pix = d->corners[d->corner];
00283
00284 switch (d->corner)
00285 {
00286 case 0:
00287 p.drawPixmap( 3, 3, pix );
00288 break;
00289 case 1:
00290 p.drawPixmap( width() - pix.width() - 3, 3, pix );
00291 break;
00292 case 2:
00293 p.drawPixmap( 3, height() - pix.height() - 3, pix );
00294 break;
00295 case 3:
00296 p.drawPixmap( width() - pix.width() - 3, height() - pix.height() - 3, pix );
00297 break;
00298 }
00299 }
00300
00301 void AlbumFileTip::updateText()
00302 {
00303 QString tip, str;
00304 QString unavailable(i18n("unavailable"));
00305
00306 QString headBeg("<tr bgcolor=\"#73CAE6\"><td colspan=\"2\">"
00307 "<nobr><font size=\"-1\" color=\"black\"><b>");
00308 QString headEnd("</b></font></nobr></td></tr>");
00309
00310 QString cellBeg("<tr><td><nobr><font size=\"-1\" color=\"black\">");
00311 QString cellMid("</font></nobr></td>"
00312 "<td><nobr><font size=\"-1\" color=\"black\">");
00313 QString cellEnd("</font></nobr></td></tr>");
00314
00315 QString cellSpecBeg("<tr><td><nobr><font size=\"-1\" color=\"black\">");
00316 QString cellSpecMid("</font></nobr></td>"
00317 "<td><nobr><font size=\"-1\" color=\"steelblue\"><i>");
00318 QString cellSpecEnd("</i></font></nobr></td></tr>");
00319
00320 tip = "<table cellspacing=\"0\" cellpadding=\"0\" width=\"250\" border=\"0\">";
00321
00322 AlbumSettings* settings = AlbumSettings::instance();
00323 const ImageInfo info = d->iconItem->imageInfo();
00324 ImageCommonContainer commonInfo = info.imageCommonContainer();
00325 ImageMetadataContainer photoInfo = info.imageMetadataContainer();
00326
00327
00328
00329 if (settings->getToolTipsShowFileName() ||
00330 settings->getToolTipsShowFileDate() ||
00331 settings->getToolTipsShowFileSize() ||
00332 settings->getToolTipsShowImageType() ||
00333 settings->getToolTipsShowImageDim())
00334 {
00335 tip += headBeg + i18n("File Properties") + headEnd;
00336
00337 if (settings->getToolTipsShowFileName())
00338 {
00339 tip += cellBeg + i18n("Name:") + cellMid;
00340 tip += commonInfo.fileName + cellEnd;
00341 }
00342
00343 if (settings->getToolTipsShowFileDate())
00344 {
00345 QDateTime modifiedDate = commonInfo.fileModificationDate;
00346 str = KGlobal::locale()->formatDateTime(modifiedDate, KLocale::ShortDate, true);
00347 tip += cellBeg + i18n("Modified:") + cellMid + str + cellEnd;
00348 }
00349
00350 if (settings->getToolTipsShowFileSize())
00351 {
00352 tip += cellBeg + i18n("Size:") + cellMid;
00353 str = i18n("%1 (%2)", KIO::convertSize(commonInfo.fileSize),
00354 KGlobal::locale()->formatNumber(commonInfo.fileSize, 0));
00355 tip += str + cellEnd;
00356 }
00357
00358 QSize dims;
00359
00360 if (settings->getToolTipsShowImageType())
00361 {
00362 tip += cellBeg + i18n("Type:") + cellMid + commonInfo.format + cellEnd;
00363 }
00364
00365 if (settings->getToolTipsShowImageDim())
00366 {
00367 if (commonInfo.width == 0 || commonInfo.height == 0)
00368 str = i18n("Unknown");
00369 else
00370 {
00371 QString mpixels;
00372 mpixels.setNum(commonInfo.width*commonInfo.height/1000000.0, 'f', 2);
00373 str = i18nc("width x height (megapixels Mpx)", "%1x%2 (%3Mpx)",
00374 commonInfo.width, commonInfo.height, mpixels);
00375 }
00376 tip += cellBeg + i18n("Dimensions:") + cellMid + str + cellEnd;
00377 }
00378 }
00379
00380
00381
00382 if (settings->getToolTipsShowPhotoMake() ||
00383 settings->getToolTipsShowPhotoDate() ||
00384 settings->getToolTipsShowPhotoFocal() ||
00385 settings->getToolTipsShowPhotoExpo() ||
00386 settings->getToolTipsShowPhotoMode() ||
00387 settings->getToolTipsShowPhotoFlash() ||
00388 settings->getToolTipsShowPhotoWB())
00389 {
00390 if (!photoInfo.allFieldsNull)
00391 {
00392 QString metaStr;
00393 tip += headBeg + i18n("Photograph Properties") + headEnd;
00394
00395 if (settings->getToolTipsShowPhotoMake())
00396 {
00397 str = QString("%1 / %2").arg(photoInfo.make.isEmpty() ? unavailable : photoInfo.make)
00398 .arg(photoInfo.model.isEmpty() ? unavailable : photoInfo.model);
00399 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00400 metaStr += cellBeg + i18n("Make/Model:") + cellMid + Qt::escape( str ) + cellEnd;
00401 }
00402
00403 if (settings->getToolTipsShowPhotoDate())
00404 {
00405 if (commonInfo.creationDate.isValid())
00406 {
00407 str = KGlobal::locale()->formatDateTime(commonInfo.creationDate, KLocale::ShortDate, true);
00408 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00409 metaStr += cellBeg + i18n("Created:") + cellMid + Qt::escape( str ) + cellEnd;
00410 }
00411 else
00412 metaStr += cellBeg + i18n("Created:") + cellMid + Qt::escape( unavailable ) + cellEnd;
00413 }
00414
00415 if (settings->getToolTipsShowPhotoFocal())
00416 {
00417 str = photoInfo.aperture.isEmpty() ? unavailable : photoInfo.aperture;
00418
00419 if (photoInfo.focalLength35.isEmpty())
00420 str += QString(" / %1").arg(photoInfo.focalLength.isEmpty() ? unavailable : photoInfo.focalLength);
00421 else
00422 str += QString(" / %1").arg(i18n("%1 (35mm: %2)",photoInfo.focalLength,photoInfo.focalLength35));
00423
00424 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00425 metaStr += cellBeg + i18n("Aperture/Focal:") + cellMid + Qt::escape( str ) + cellEnd;
00426 }
00427
00428 if (settings->getToolTipsShowPhotoExpo())
00429 {
00430 str = QString("%1 / %2").arg(photoInfo.exposureTime.isEmpty() ? unavailable : photoInfo.exposureTime)
00431 .arg(photoInfo.sensitivity.isEmpty() ? unavailable : i18n("%1 ISO",photoInfo.sensitivity));
00432 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00433 metaStr += cellBeg + i18n("Exposure/Sensitivity:") + cellMid + Qt::escape( str ) + cellEnd;
00434 }
00435
00436 if (settings->getToolTipsShowPhotoMode())
00437 {
00438
00439 if (photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
00440 str = unavailable;
00441 else if (!photoInfo.exposureMode.isEmpty() && photoInfo.exposureProgram.isEmpty())
00442 str = photoInfo.exposureMode;
00443 else if (photoInfo.exposureMode.isEmpty() && !photoInfo.exposureProgram.isEmpty())
00444 str = photoInfo.exposureProgram;
00445 else
00446 str = QString("%1 / %2").arg(photoInfo.exposureMode).arg(photoInfo.exposureProgram);
00447 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00448 metaStr += cellBeg + i18n("Mode/Program:") + cellMid + Qt::escape( str ) + cellEnd;
00449 }
00450
00451 if (settings->getToolTipsShowPhotoFlash())
00452 {
00453 str = photoInfo.flashMode.isEmpty() ? unavailable : photoInfo.flashMode;
00454 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00455 metaStr += cellBeg + i18n("Flash:") + cellMid + Qt::escape( str ) + cellEnd;
00456 }
00457
00458 if (settings->getToolTipsShowPhotoWB())
00459 {
00460 str = photoInfo.whiteBalance.isEmpty() ? unavailable : photoInfo.whiteBalance;
00461 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00462 metaStr += cellBeg + i18n("White Balance:") + cellMid + Qt::escape( str ) + cellEnd;
00463 }
00464
00465 tip += metaStr;
00466 }
00467 }
00468
00469
00470
00471 if (settings->getToolTipsShowAlbumName() ||
00472 settings->getToolTipsShowComments() ||
00473 settings->getToolTipsShowTags() ||
00474 settings->getToolTipsShowRating())
00475 {
00476 tip += headBeg + i18n("digiKam Properties") + headEnd;
00477
00478 if (settings->getToolTipsShowAlbumName())
00479 {
00480 PAlbum* album = AlbumManager::instance()->findPAlbum(info.albumId());
00481 if (album)
00482 tip += cellSpecBeg + i18n("Album:") + cellSpecMid + album->albumPath().remove(0, 1) + cellSpecEnd;
00483 }
00484
00485 if (settings->getToolTipsShowComments())
00486 {
00487 str = info.comment();
00488 if (str.isEmpty()) str = QString("---");
00489 tip += cellSpecBeg + i18n("Caption:") + cellSpecMid + breakString(str) + cellSpecEnd;
00490 }
00491
00492 if (settings->getToolTipsShowTags())
00493 {
00494 QStringList tagPaths = AlbumManager::instance()->tagPaths(info.tagIds(), false);
00495
00496 str = tagPaths.join(", ");
00497 if (str.isEmpty()) str = QString("---");
00498 if (str.length() > d->maxStringLen) str = str.left(d->maxStringLen-3) + "...";
00499 tip += cellSpecBeg + i18n("Tags:") + cellSpecMid + str + cellSpecEnd;
00500 }
00501
00502 if (settings->getToolTipsShowRating())
00503 {
00504 int rating = info.rating();
00505 if (rating <= 0)
00506 str = QString("---");
00507 else
00508 str.fill( 'X', info.rating() );
00509 tip += cellSpecBeg + i18n("Rating:") + cellSpecMid + str + cellSpecEnd;
00510 }
00511 }
00512
00513 tip += "</table>";
00514
00515 d->label->setText(tip);
00516 }
00517
00518 QString AlbumFileTip::breakString(const QString& input)
00519 {
00520 QString str = input.simplified();
00521 str = Qt::escape(str);
00522 int maxLen = d->maxStringLen;
00523
00524 if (str.length() <= maxLen)
00525 return str;
00526
00527 QString br;
00528
00529 int i = 0;
00530 int count = 0;
00531
00532 while (i < str.length())
00533 {
00534 if (count >= maxLen && str[i].isSpace())
00535 {
00536 count = 0;
00537 br.append("<br>");
00538 }
00539 else
00540 {
00541 br.append(str[i]);
00542 }
00543
00544 i++;
00545 count++;
00546 }
00547
00548 return br;
00549 }
00550
00551 }