00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "kfileitemdelegate.h"
00023 #include "imagefilter_p.h"
00024
00025 #include <config.h>
00026
00027 #include <QApplication>
00028 #include <QStyle>
00029 #include <QModelIndex>
00030 #include <QPainter>
00031 #include <QCache>
00032 #include <QImage>
00033 #include <QPainterPath>
00034 #include <QTextLayout>
00035 #include <QListView>
00036 #include <QPaintEngine>
00037 #include <qmath.h>
00038
00039 #include <kglobal.h>
00040 #include <klocale.h>
00041 #include <kiconloader.h>
00042 #include <kiconeffect.h>
00043 #include <kdirmodel.h>
00044 #include <kfileitem.h>
00045 #include <kcolorscheme.h>
00046 #include <kglobalsettings.h>
00047 #include <ktextedit.h>
00048
00049 #include "delegateanimationhandler_p.h"
00050
00051 #if defined(Q_WS_X11) && defined(HAVE_XRENDER)
00052 # include <X11/Xlib.h>
00053 # include <X11/extensions/Xrender.h>
00054 # include <QX11Info>
00055 # undef KeyPress
00056 # undef FocusOut
00057 #endif
00058
00059
00060 struct Margin
00061 {
00062 int left, right, top, bottom;
00063 };
00064
00065
00066 class KFileItemDelegate::Private
00067 {
00068 public:
00069 enum MarginType { ItemMargin = 0, TextMargin, IconMargin, NMargins };
00070
00071 Private(KFileItemDelegate *parent);
00072 ~Private() {}
00073
00074 QSize decorationSizeHint(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
00075 QSize displaySizeHint(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
00076 QString replaceNewlines(const QString &string) const;
00077 inline KFileItem fileItem(const QModelIndex &index) const;
00078 QString elidedText(QTextLayout &layout, const QStyleOptionViewItemV4 &option, const QSize &maxSize) const;
00079 QSize layoutText(QTextLayout &layout, const QStyleOptionViewItemV4 &option,
00080 const QString &text, const QSize &constraints) const;
00081 QSize layoutText(QTextLayout &layout, const QString &text, int maxWidth) const;
00082 inline void setLayoutOptions(QTextLayout &layout, const QStyleOptionViewItemV4 &options) const;
00083 inline bool verticalLayout(const QStyleOptionViewItemV4 &option) const;
00084 inline QBrush brush(const QVariant &value, const QStyleOptionViewItemV4 &option) const;
00085 QBrush foregroundBrush(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
00086 inline void setActiveMargins(Qt::Orientation layout);
00087 void setVerticalMargin(MarginType type, int left, int right, int top, int bottom);
00088 void setHorizontalMargin(MarginType type, int left, int right, int top, int bottom);
00089 inline void setVerticalMargin(MarginType type, int hor, int ver);
00090 inline void setHorizontalMargin(MarginType type, int hor, int ver);
00091 inline QRect addMargin(const QRect &rect, MarginType type) const;
00092 inline QRect subtractMargin(const QRect &rect, MarginType type) const;
00093 inline QSize addMargin(const QSize &size, MarginType type) const;
00094 inline QSize subtractMargin(const QSize &size, MarginType type) const;
00095 QString itemSize(const QModelIndex &index, const KFileItem &item) const;
00096 QString information(const QStyleOptionViewItemV4 &option, const QModelIndex &index, const KFileItem &item) const;
00097 bool isListView(const QStyleOptionViewItemV4 &option) const;
00098 QString display(const QModelIndex &index) const;
00099 QIcon decoration(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const;
00100 QPoint iconPosition(const QStyleOptionViewItemV4 &option) const;
00101 QRect labelRectangle(const QStyleOptionViewItemV4 &option) const;
00102 void layoutTextItems(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
00103 QTextLayout *labelLayout, QTextLayout *infoLayout, QRect *textBoundingRect) const;
00104 void drawTextItems(QPainter *painter, const QTextLayout &labelLayout, const QTextLayout &infoLayout,
00105 const QRect &textBoundingRect) const;
00106 KIO::AnimationState *animationState(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
00107 const QAbstractItemView *view) const;
00108 void restartAnimation(KIO::AnimationState* state);
00109 QPixmap applyHoverEffect(const QPixmap &icon) const;
00110 QPixmap transition(const QPixmap &from, const QPixmap &to, qreal amount) const;
00111 void initStyleOption(QStyleOptionViewItemV4 *option, const QModelIndex &index) const;
00112 void drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option, const QRect &rect) const;
00113
00114 void gotNewIcon(const QModelIndex& index);
00115
00116 public:
00117 KFileItemDelegate::InformationList informationList;
00118 QColor shadowColor;
00119 QPointF shadowOffset;
00120 qreal shadowBlur;
00121 QSize maximumSize;
00122 bool showToolTipWhenElided;
00123
00124 private:
00125 KFileItemDelegate * const q;
00126 KIO::DelegateAnimationHandler *animationHandler;
00127 Margin verticalMargin[NMargins];
00128 Margin horizontalMargin[NMargins];
00129 Margin *activeMargins;
00130 };
00131
00132
00133 KFileItemDelegate::Private::Private(KFileItemDelegate *parent)
00134 : shadowColor(Qt::transparent), shadowOffset(1, 1), shadowBlur(2), maximumSize(0, 0),
00135 showToolTipWhenElided(true), q(parent),
00136 animationHandler(new KIO::DelegateAnimationHandler(parent)), activeMargins(0)
00137 {
00138 }
00139
00140
00141 void KFileItemDelegate::Private::setActiveMargins(Qt::Orientation layout)
00142 {
00143 activeMargins = (layout == Qt::Horizontal ?
00144 horizontalMargin : verticalMargin);
00145 }
00146
00147
00148 void KFileItemDelegate::Private::setVerticalMargin(MarginType type, int left, int top, int right, int bottom)
00149 {
00150 verticalMargin[type].left = left;
00151 verticalMargin[type].right = right;
00152 verticalMargin[type].top = top;
00153 verticalMargin[type].bottom = bottom;
00154 }
00155
00156
00157 void KFileItemDelegate::Private::setHorizontalMargin(MarginType type, int left, int top, int right, int bottom)
00158 {
00159 horizontalMargin[type].left = left;
00160 horizontalMargin[type].right = right;
00161 horizontalMargin[type].top = top;
00162 horizontalMargin[type].bottom = bottom;
00163 }
00164
00165
00166 void KFileItemDelegate::Private::setVerticalMargin(MarginType type, int horizontal, int vertical)
00167 {
00168 setVerticalMargin(type, horizontal, vertical, horizontal, vertical);
00169 }
00170
00171
00172 void KFileItemDelegate::Private::setHorizontalMargin(MarginType type, int horizontal, int vertical)
00173 {
00174 setHorizontalMargin(type, horizontal, vertical, horizontal, vertical);
00175 }
00176
00177
00178 QRect KFileItemDelegate::Private::addMargin(const QRect &rect, MarginType type) const
00179 {
00180 Q_ASSERT(activeMargins != 0);
00181 const Margin &m = activeMargins[type];
00182 return rect.adjusted(-m.left, -m.top, m.right, m.bottom);
00183 }
00184
00185
00186 QRect KFileItemDelegate::Private::subtractMargin(const QRect &rect, MarginType type) const
00187 {
00188 Q_ASSERT(activeMargins != 0);
00189 const Margin &m = activeMargins[type];
00190 return rect.adjusted(m.left, m.top, -m.right, -m.bottom);
00191 }
00192
00193
00194 QSize KFileItemDelegate::Private::addMargin(const QSize &size, MarginType type) const
00195 {
00196 Q_ASSERT(activeMargins != 0);
00197 const Margin &m = activeMargins[type];
00198 return QSize(size.width() + m.left + m.right, size.height() + m.top + m.bottom);
00199 }
00200
00201
00202 QSize KFileItemDelegate::Private::subtractMargin(const QSize &size, MarginType type) const
00203 {
00204 Q_ASSERT(activeMargins != 0);
00205 const Margin &m = activeMargins[type];
00206 return QSize(size.width() - m.left - m.right, size.height() - m.top - m.bottom);
00207 }
00208
00209
00210
00211 QString KFileItemDelegate::Private::itemSize(const QModelIndex &index, const KFileItem &item) const
00212 {
00213
00214 if (item.isFile())
00215 return KGlobal::locale()->formatByteSize(item.size());
00216
00217
00218 const QVariant value = index.data(KDirModel::ChildCountRole);
00219 const int count = value.type() == QVariant::Int ? value.toInt() : KDirModel::ChildCountUnknown;
00220
00221 if (count == KDirModel::ChildCountUnknown) {
00222
00223
00224
00225 return QString();
00226 }
00227
00228 return i18ncp("Items in a folder", "1 item", "%1 items", count);
00229 }
00230
00231
00232
00233 QString KFileItemDelegate::Private::information(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
00234 const KFileItem &item) const
00235 {
00236 QString string;
00237
00238 if (informationList.isEmpty() || item.isNull() || !isListView(option))
00239 return string;
00240
00241 foreach (KFileItemDelegate::Information info, informationList)
00242 {
00243 if (info == KFileItemDelegate::NoInformation)
00244 continue;
00245
00246 if (!string.isEmpty())
00247 string += QChar::LineSeparator;
00248
00249 switch (info)
00250 {
00251 case KFileItemDelegate::Size:
00252 string += itemSize(index, item);
00253 break;
00254
00255 case KFileItemDelegate::Permissions:
00256 string += item.permissionsString();
00257 break;
00258
00259 case KFileItemDelegate::OctalPermissions:
00260 string += QString('0') + QString::number(item.permissions(), 8);
00261 break;
00262
00263 case KFileItemDelegate::Owner:
00264 string += item.user();
00265 break;
00266
00267 case KFileItemDelegate::OwnerAndGroup:
00268 string += item.user() + ':' + item.group();
00269 break;
00270
00271 case KFileItemDelegate::CreationTime:
00272 string += item.timeString(KFileItem::CreationTime);
00273 break;
00274
00275 case KFileItemDelegate::ModificationTime:
00276 string += item.timeString(KFileItem::ModificationTime);
00277 break;
00278
00279 case KFileItemDelegate::AccessTime:
00280 string += item.timeString(KFileItem::AccessTime);
00281 break;
00282
00283 case KFileItemDelegate::MimeType:
00284 string += item.isMimeTypeKnown() ? item.mimetype() : i18nc("@info mimetype","Unknown");
00285 break;
00286
00287 case KFileItemDelegate::FriendlyMimeType:
00288 string += item.isMimeTypeKnown() ? item.mimeComment() : i18nc("@info mimetype","Unknown");
00289 break;
00290
00291 default:
00292 break;
00293 }
00294 }
00295
00296 return string;
00297 }
00298
00299
00300
00301 KFileItem KFileItemDelegate::Private::fileItem(const QModelIndex &index) const
00302 {
00303 const QVariant value = index.data(KDirModel::FileItemRole);
00304 return qvariant_cast<KFileItem>(value);
00305 }
00306
00307
00308
00309 QString KFileItemDelegate::Private::replaceNewlines(const QString &text) const
00310 {
00311 QString string = text;
00312 const QChar newline = QLatin1Char('\n');
00313
00314 for (int i = 0; i < string.length(); i++)
00315 if (string[i] == newline)
00316 string[i] = QChar::LineSeparator;
00317
00318 return string;
00319 }
00320
00321
00322
00323 QSize KFileItemDelegate::Private::layoutText(QTextLayout &layout, const QStyleOptionViewItemV4 &option,
00324 const QString &text, const QSize &constraints) const
00325 {
00326 const QSize size = layoutText(layout, text, constraints.width());
00327
00328 if (size.width() > constraints.width() || size.height() > constraints.height())
00329 {
00330 const QString elided = elidedText(layout, option, constraints);
00331 return layoutText(layout, elided, constraints.width());
00332 }
00333
00334 return size;
00335 }
00336
00337
00338
00339 QSize KFileItemDelegate::Private::layoutText(QTextLayout &layout, const QString &text, int maxWidth) const
00340 {
00341 QFontMetrics metrics(layout.font());
00342 int leading = metrics.leading();
00343 int height = 0;
00344 qreal widthUsed = 0;
00345 QTextLine line;
00346
00347 layout.setText(text);
00348
00349 layout.beginLayout();
00350 while ((line = layout.createLine()).isValid())
00351 {
00352 line.setLineWidth(int(maxWidth));
00353 height += leading;
00354 line.setPosition(QPoint(0, height));
00355 height += int(line.height());
00356 widthUsed = qMax(widthUsed, line.naturalTextWidth());
00357 }
00358 layout.endLayout();
00359
00360 return QSize(int(widthUsed), height);
00361 }
00362
00363
00364
00365
00366
00367
00368 QString KFileItemDelegate::Private::elidedText(QTextLayout &layout, const QStyleOptionViewItemV4 &option,
00369 const QSize &size) const
00370 {
00371 const QString text = layout.text();
00372 int maxWidth = size.width();
00373 int maxHeight = size.height();
00374 qreal height = 0;
00375 bool wrapText = (option.features & QStyleOptionViewItemV2::WrapText);
00376
00377
00378 if (!wrapText && text.indexOf(QChar::LineSeparator) == -1)
00379 return option.fontMetrics.elidedText(text, option.textElideMode, maxWidth);
00380
00381
00382 QString elided;
00383 elided.reserve(text.length());
00384
00385 for (int i = 0; i < layout.lineCount(); i++)
00386 {
00387 QTextLine line = layout.lineAt(i);
00388 int start = line.textStart();
00389 int length = line.textLength();
00390
00391 height += option.fontMetrics.leading();
00392 if (height + line.height() + option.fontMetrics.lineSpacing() > maxHeight)
00393 {
00394
00395
00396 if (line.naturalTextWidth() < maxWidth && text[start + length - 1] == QChar::LineSeparator)
00397 elided += text.mid(start, length - 1);
00398 else
00399 elided += option.fontMetrics.elidedText(text.mid(start), option.textElideMode, maxWidth);
00400 break;
00401 }
00402 else if (line.naturalTextWidth() > maxWidth)
00403 {
00404 elided += option.fontMetrics.elidedText(text.mid(start, length), option.textElideMode, maxWidth);
00405 if (!elided.endsWith(QChar::LineSeparator))
00406 elided += QChar::LineSeparator;
00407 }
00408 else
00409 elided += text.mid(start, length);
00410
00411 height += line.height();
00412 }
00413
00414 return elided;
00415 }
00416
00417
00418 void KFileItemDelegate::Private::setLayoutOptions(QTextLayout &layout, const QStyleOptionViewItemV4 &option) const
00419 {
00420 QTextOption textoption;
00421 textoption.setTextDirection(option.direction);
00422 textoption.setAlignment(QStyle::visualAlignment(option.direction, option.displayAlignment));
00423 textoption.setWrapMode((option.features & QStyleOptionViewItemV2::WrapText) ?
00424 QTextOption::WrapAtWordBoundaryOrAnywhere : QTextOption::NoWrap);
00425
00426 layout.setFont(option.font);
00427 layout.setTextOption(textoption);
00428 }
00429
00430
00431 QSize KFileItemDelegate::Private::displaySizeHint(const QStyleOptionViewItemV4 &option,
00432 const QModelIndex &index) const
00433 {
00434 QString label = option.text;
00435 int maxWidth = 0;
00436 if (maximumSize.isEmpty()) {
00437 maxWidth = verticalLayout(option) && (option.features & QStyleOptionViewItemV2::WrapText)
00438 ? option.decorationSize.width() + 10 : 32757;
00439 }
00440 else {
00441 const Margin &itemMargin = activeMargins[ItemMargin];
00442 const Margin &textMargin = activeMargins[TextMargin];
00443 maxWidth = maximumSize.width() -
00444 (itemMargin.left + itemMargin.right) -
00445 (textMargin.left + textMargin.right);
00446 }
00447
00448 KFileItem item = fileItem(index);
00449
00450
00451
00452 const QString info = information(option, index, item);
00453 if (!info.isEmpty())
00454 label += QString(QChar::LineSeparator) + info;
00455
00456 QTextLayout layout;
00457 setLayoutOptions(layout, option);
00458
00459 QSize size = layoutText(layout, label, maxWidth);
00460 return addMargin(size, TextMargin);
00461 }
00462
00463
00464 QSize KFileItemDelegate::Private::decorationSizeHint(const QStyleOptionViewItemV4 &option,
00465 const QModelIndex &index) const
00466 {
00467 Q_UNUSED(index)
00468
00469 QSize iconSize = option.icon.actualSize(option.decorationSize);
00470 if (!verticalLayout(option))
00471 iconSize.rwidth() = option.decorationSize.width();
00472 else if (iconSize.width() < option.decorationSize.width())
00473 iconSize.rwidth() = qMin(iconSize.width() + 10, option.decorationSize.width());
00474 if (iconSize.height() < option.decorationSize.height())
00475 iconSize.rheight() = option.decorationSize.height();
00476
00477 return addMargin(iconSize, IconMargin);
00478 }
00479
00480
00481 bool KFileItemDelegate::Private::verticalLayout(const QStyleOptionViewItemV4 &option) const
00482 {
00483 return (option.decorationPosition == QStyleOptionViewItem::Top ||
00484 option.decorationPosition == QStyleOptionViewItem::Bottom);
00485 }
00486
00487
00488
00489 QBrush KFileItemDelegate::Private::brush(const QVariant &value, const QStyleOptionViewItemV4 &option) const
00490 {
00491 if (value.userType() == qMetaTypeId<KStatefulBrush>())
00492 return qvariant_cast<KStatefulBrush>(value).brush(option.palette);
00493 switch (value.type())
00494 {
00495 case QVariant::Color:
00496 return QBrush(qvariant_cast<QColor>(value));
00497
00498 case QVariant::Brush:
00499 return qvariant_cast<QBrush>(value);
00500
00501 default:
00502 return QBrush(Qt::NoBrush);
00503 }
00504 }
00505
00506
00507 QBrush KFileItemDelegate::Private::foregroundBrush(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const
00508 {
00509
00510 if (option.state & QStyle::State_Selected)
00511 return option.palette.brush(QPalette::HighlightedText);
00512
00513
00514 const QVariant value = index.data(Qt::ForegroundRole);
00515 if (value.isValid())
00516 return brush(value, option);
00517
00518 return option.palette.brush(QPalette::Text);
00519 }
00520
00521
00522 bool KFileItemDelegate::Private::isListView(const QStyleOptionViewItemV4 &option) const
00523 {
00524 if (qobject_cast<const QListView*>(option.widget) || verticalLayout(option))
00525 return true;
00526
00527 return false;
00528 }
00529
00530
00531 QPixmap KFileItemDelegate::Private::applyHoverEffect(const QPixmap &icon) const
00532 {
00533 KIconEffect *effect = KIconLoader::global()->iconEffect();
00534
00535
00536
00537
00538 if (effect->hasEffect(KIconLoader::Desktop, KIconLoader::ActiveState))
00539 return effect->apply(icon, KIconLoader::Desktop, KIconLoader::ActiveState);
00540
00541 return icon;
00542 }
00543
00544 void KFileItemDelegate::Private::gotNewIcon(const QModelIndex& index) {
00545 animationHandler->gotNewIcon(index);
00546 }
00547
00548 void KFileItemDelegate::Private::restartAnimation(KIO::AnimationState* state) {
00549 animationHandler->restartAnimation(state);
00550 }
00551
00552 KIO::AnimationState *KFileItemDelegate::Private::animationState(const QStyleOptionViewItemV4 &option,
00553 const QModelIndex &index,
00554 const QAbstractItemView *view) const
00555 {
00556 if (!(KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects)) {
00557 return NULL;
00558 }
00559
00560 if (index.column() == KDirModel::Name)
00561 return animationHandler->animationState(option, index, view);
00562
00563 return NULL;
00564 }
00565
00566
00567 QPixmap KFileItemDelegate::Private::transition(const QPixmap &from, const QPixmap &to, qreal amount) const
00568 {
00569 int value = int(0xff * amount);
00570
00571 if (value == 0)
00572 return from;
00573
00574 if (value == 1)
00575 return to;
00576
00577 QColor color;
00578 color.setAlphaF(amount);
00579
00580
00581 if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff) &&
00582 from.paintEngine()->hasFeature(QPaintEngine::BlendModes))
00583 {
00584 QPixmap under = from;
00585 QPixmap over = to;
00586
00587 QPainter p;
00588 p.begin(&over);
00589 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00590 p.fillRect(over.rect(), color);
00591 p.end();
00592
00593 p.begin(&under);
00594 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00595 p.fillRect(under.rect(), color);
00596 p.setCompositionMode(QPainter::CompositionMode_Plus);
00597 p.drawPixmap(0, 0, over);
00598 p.end();
00599
00600 return under;
00601 }
00602 #if defined(Q_WS_X11) && defined(HAVE_XRENDER)
00603 else if (from.paintEngine()->hasFeature(QPaintEngine::PorterDuff))
00604 {
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 QPixmap source(to), destination(from);
00617
00618 source.detach();
00619 destination.detach();
00620
00621 Display *dpy = QX11Info::display();
00622
00623 XRenderPictFormat *format = XRenderFindStandardFormat(dpy, PictStandardA8);
00624 XRenderPictureAttributes pa;
00625 pa.repeat = 1;
00626
00627
00628 Pixmap pixmap = XCreatePixmap(dpy, destination.handle(), 1, 1, 8);
00629 Picture alpha = XRenderCreatePicture(dpy, pixmap, format, CPRepeat, &pa);
00630 XFreePixmap(dpy, pixmap);
00631
00632
00633 XRenderColor xcolor;
00634 xcolor.alpha = quint16(0xffff * amount);
00635 XRenderFillRectangle(dpy, PictOpSrc, alpha, &xcolor, 0, 0, 1, 1);
00636
00637
00638 XRenderComposite(dpy, PictOpOutReverse, alpha, None, destination.x11PictureHandle(),
00639 0, 0, 0, 0, 0, 0, destination.width(), destination.height());
00640
00641
00642 XRenderComposite(dpy, PictOpAdd, source.x11PictureHandle(), alpha,
00643 destination.x11PictureHandle(),
00644 0, 0, 0, 0, 0, 0, destination.width(), destination.height());
00645
00646 XRenderFreePicture(dpy, alpha);
00647 return destination;
00648 }
00649 #endif
00650 else
00651 {
00652
00653 QImage under = from.toImage();
00654 QImage over = to.toImage();
00655
00656 QPainter p;
00657 p.begin(&over);
00658 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00659 p.fillRect(over.rect(), color);
00660 p.end();
00661
00662 p.begin(&under);
00663 p.setCompositionMode(QPainter::CompositionMode_DestinationOut);
00664 p.fillRect(under.rect(), color);
00665 p.setCompositionMode(QPainter::CompositionMode_Plus);
00666 p.drawImage(0, 0, over);
00667 p.end();
00668
00669 return QPixmap::fromImage(under);
00670 }
00671 }
00672
00673
00674 void KFileItemDelegate::Private::layoutTextItems(const QStyleOptionViewItemV4 &option, const QModelIndex &index,
00675 QTextLayout *labelLayout, QTextLayout *infoLayout,
00676 QRect *textBoundingRect) const
00677 {
00678 KFileItem item = fileItem(index);
00679 const QString info = information(option, index, item);
00680 bool showInformation = false;
00681
00682 setLayoutOptions(*labelLayout, option);
00683
00684 const QRect textArea = labelRectangle(option);
00685 QRect textRect = subtractMargin(textArea, Private::TextMargin);
00686
00687
00688 QSize maxLabelSize = textRect.size();
00689 QSize maxInfoSize = textRect.size();
00690 QSize labelSize;
00691 QSize infoSize;
00692
00693
00694
00695 if (!info.isEmpty() && textRect.height() >= option.fontMetrics.lineSpacing() * 2)
00696 {
00697 infoLayout->setFont(labelLayout->font());
00698 infoLayout->setTextOption(labelLayout->textOption());
00699
00700 maxLabelSize.rheight() -= option.fontMetrics.lineSpacing();
00701 showInformation = true;
00702 }
00703
00704
00705 labelSize = layoutText(*labelLayout, option, option.text, maxLabelSize);
00706 maxInfoSize.rheight() -= labelSize.height();
00707
00708
00709 if (showInformation)
00710 infoSize = layoutText(*infoLayout, option, info, maxInfoSize);
00711 else
00712 infoSize = QSize(0, 0);
00713
00714
00715 const QSize size(qMax(labelSize.width(), infoSize.width()), labelSize.height() + infoSize.height());
00716 *textBoundingRect = QStyle::alignedRect(option.direction, option.displayAlignment, size, textRect);
00717
00718
00719 labelLayout->setPosition(QPointF(textRect.x(), textBoundingRect->y()));
00720 infoLayout->setPosition(QPointF(textRect.x(), textBoundingRect->y() + labelSize.height()));
00721 }
00722
00723
00724 void KFileItemDelegate::Private::drawTextItems(QPainter *painter, const QTextLayout &labelLayout,
00725 const QTextLayout &infoLayout, const QRect &boundingRect) const
00726 {
00727 if (shadowColor.alpha() > 0)
00728 {
00729 QPixmap pixmap(boundingRect.size());
00730 pixmap.fill(Qt::transparent);
00731
00732 QPainter p(&pixmap);
00733 p.translate(-boundingRect.topLeft());
00734 p.setPen(painter->pen());
00735 labelLayout.draw(&p, QPoint());
00736
00737 if (!infoLayout.text().isEmpty())
00738 {
00739 QColor color = p.pen().color();
00740 color.setAlphaF(0.6);
00741
00742 p.setPen(color);
00743 infoLayout.draw(&p, QPoint());
00744 }
00745 p.end();
00746
00747 int padding = qCeil(shadowBlur);
00748 int blurFactor = qRound(shadowBlur);
00749
00750 QImage image(boundingRect.size() + QSize(padding * 2, padding * 2), QImage::Format_ARGB32_Premultiplied);
00751 image.fill(0);
00752 p.begin(&image);
00753 p.drawImage(padding, padding, pixmap.toImage());
00754 p.end();
00755
00756 KIO::ImageFilter::shadowBlur(image, blurFactor, shadowColor);
00757
00758 painter->drawImage(boundingRect.topLeft() - QPoint(padding, padding) + shadowOffset.toPoint(), image);
00759 painter->drawPixmap(boundingRect.topLeft(), pixmap);
00760 return;
00761 }
00762
00763 labelLayout.draw(painter, QPoint());
00764
00765 if (!infoLayout.text().isEmpty())
00766 {
00767
00768
00769
00770 QColor color = painter->pen().color();
00771 color.setAlphaF(0.6);
00772
00773 painter->setPen(color);
00774 infoLayout.draw(painter, QPoint());
00775 }
00776 }
00777
00778
00779 void KFileItemDelegate::Private::initStyleOption(QStyleOptionViewItemV4 *option,
00780 const QModelIndex &index) const
00781 {
00782 const KFileItem item = fileItem(index);
00783 bool updateFontMetrics = false;
00784
00785
00786 QVariant value = index.data(Qt::FontRole);
00787 if (value.isValid()) {
00788 option->font = qvariant_cast<QFont>(value).resolve(option->font);
00789 updateFontMetrics = true;
00790 }
00791
00792
00793 if (!item.isNull() && item.isLink()) {
00794 option->font.setItalic(true);
00795 updateFontMetrics = true;
00796 }
00797
00798 if (updateFontMetrics)
00799 option->fontMetrics = QFontMetrics(option->font);
00800
00801
00802 value = index.data(Qt::TextAlignmentRole);
00803 if (value.isValid())
00804 option->displayAlignment = Qt::Alignment(value.toInt());
00805
00806 value = index.data(Qt::BackgroundRole);
00807 if (value.isValid())
00808 option->backgroundBrush = brush(value, *option);
00809
00810 option->text = display(index);
00811 if (!option->text.isEmpty())
00812 option->features |= QStyleOptionViewItemV2::HasDisplay;
00813
00814 option->icon = decoration(*option, index);
00815 if (!option->icon.isNull())
00816 option->features |= QStyleOptionViewItemV2::HasDecoration;
00817
00818
00819 option->showDecorationSelected = true;
00820 }
00821
00822
00823
00824
00825
00826
00827
00828
00829
00830 KFileItemDelegate::KFileItemDelegate(QObject *parent)
00831 : QAbstractItemDelegate(parent), d(new Private(this))
00832 {
00833 int focusHMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameHMargin);
00834 int focusVMargin = QApplication::style()->pixelMetric(QStyle::PM_FocusFrameVMargin);
00835
00836
00837 const int textMargin = focusHMargin * 4;
00838 if (QApplication::isRightToLeft())
00839 d->setHorizontalMargin(Private::TextMargin, textMargin, focusVMargin, focusHMargin, focusVMargin);
00840 else
00841 d->setHorizontalMargin(Private::TextMargin, focusHMargin, focusVMargin, textMargin, focusVMargin);
00842
00843 d->setHorizontalMargin(Private::IconMargin, focusHMargin, focusVMargin);
00844 d->setHorizontalMargin(Private::ItemMargin, 0, 0);
00845
00846
00847 d->setVerticalMargin(Private::TextMargin, 6, 2);
00848 d->setVerticalMargin(Private::IconMargin, focusHMargin, focusVMargin);
00849 d->setVerticalMargin(Private::ItemMargin, 0, 0);
00850
00851 setShowInformation(NoInformation);
00852 }
00853
00854
00855 KFileItemDelegate::~KFileItemDelegate()
00856 {
00857 delete d;
00858 }
00859
00860
00861 QSize KFileItemDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
00862 {
00863
00864 const QVariant value = index.data(Qt::SizeHintRole);
00865 if (value.isValid())
00866 return qvariant_cast<QSize>(value);
00867
00868 QStyleOptionViewItemV4 opt(option);
00869 d->initStyleOption(&opt, index);
00870 d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
00871
00872 const QSize displaySize = d->displaySizeHint(opt, index);
00873 const QSize decorationSize = d->decorationSizeHint(opt, index);
00874
00875 QSize size;
00876
00877 if (d->verticalLayout(opt))
00878 {
00879 size.rwidth() = qMax(displaySize.width(), decorationSize.width());
00880 size.rheight() = decorationSize.height() + displaySize.height() + 1;
00881 }
00882 else
00883 {
00884 size.rwidth() = decorationSize.width() + displaySize.width() + 1;
00885 size.rheight() = qMax(decorationSize.height(), displaySize.height());
00886 }
00887
00888 size = d->addMargin(size, Private::ItemMargin);
00889 if (!d->maximumSize.isEmpty())
00890 {
00891 size = size.boundedTo(d->maximumSize);
00892 }
00893
00894 return size;
00895 }
00896
00897
00898 QString KFileItemDelegate::Private::display(const QModelIndex &index) const
00899 {
00900 const QVariant value = index.data(Qt::DisplayRole);
00901
00902 switch (value.type())
00903 {
00904 case QVariant::String:
00905 {
00906 if (index.column() == KDirModel::Size)
00907 return itemSize(index, fileItem(index));
00908 else
00909 return replaceNewlines(value.toString());
00910 }
00911
00912 case QVariant::Double:
00913 return KGlobal::locale()->formatNumber(value.toDouble());
00914
00915 case QVariant::Int:
00916 case QVariant::UInt:
00917 return KGlobal::locale()->formatLong(value.toInt());
00918
00919 default:
00920 return QString();
00921 }
00922 }
00923
00924
00925 void KFileItemDelegate::setShowInformation(const InformationList &list)
00926 {
00927 d->informationList = list;
00928 }
00929
00930
00931 void KFileItemDelegate::setShowInformation(Information value)
00932 {
00933 if (value != NoInformation)
00934 d->informationList = InformationList() << value;
00935 else
00936 d->informationList = InformationList();
00937 }
00938
00939
00940 KFileItemDelegate::InformationList KFileItemDelegate::showInformation() const
00941 {
00942 return d->informationList;
00943 }
00944
00945
00946 void KFileItemDelegate::setShadowColor(const QColor &color)
00947 {
00948 d->shadowColor = color;
00949 }
00950
00951
00952 QColor KFileItemDelegate::shadowColor() const
00953 {
00954 return d->shadowColor;
00955 }
00956
00957
00958 void KFileItemDelegate::setShadowOffset(const QPointF &offset)
00959 {
00960 d->shadowOffset = offset;
00961 }
00962
00963
00964 QPointF KFileItemDelegate::shadowOffset() const
00965 {
00966 return d->shadowOffset;
00967 }
00968
00969
00970 void KFileItemDelegate::setShadowBlur(qreal factor)
00971 {
00972 d->shadowBlur = factor;
00973 }
00974
00975
00976 qreal KFileItemDelegate::shadowBlur() const
00977 {
00978 return d->shadowBlur;
00979 }
00980
00981
00982 void KFileItemDelegate::setMaximumSize(const QSize &size)
00983 {
00984 d->maximumSize = size;
00985 }
00986
00987
00988 QSize KFileItemDelegate::maximumSize() const
00989 {
00990 return d->maximumSize;
00991 }
00992
00993
00994 void KFileItemDelegate::setShowToolTipWhenElided(bool showToolTip)
00995 {
00996 d->showToolTipWhenElided = showToolTip;
00997 }
00998
00999
01000 bool KFileItemDelegate::showToolTipWhenElided() const
01001 {
01002 return d->showToolTipWhenElided;
01003 }
01004
01005
01006 QIcon KFileItemDelegate::Private::decoration(const QStyleOptionViewItemV4 &option, const QModelIndex &index) const
01007 {
01008 const QVariant value = index.data(Qt::DecorationRole);
01009 QIcon icon;
01010
01011 switch (value.type())
01012 {
01013 case QVariant::Icon:
01014 icon = qvariant_cast<QIcon>(value);
01015 break;
01016
01017 case QVariant::Pixmap:
01018 icon.addPixmap(qvariant_cast<QPixmap>(value));
01019 break;
01020
01021 case QVariant::Color: {
01022 QPixmap pixmap(option.decorationSize);
01023 pixmap.fill(qvariant_cast<QColor>(value));
01024 icon.addPixmap(pixmap);
01025 break;
01026 }
01027
01028 default:
01029 break;
01030 }
01031
01032 return icon;
01033 }
01034
01035
01036 QRect KFileItemDelegate::Private::labelRectangle(const QStyleOptionViewItemV4 &option) const
01037 {
01038 if (option.icon.isNull())
01039 return subtractMargin(option.rect, Private::ItemMargin);
01040
01041 const QSize decoSize = addMargin(option.decorationSize, Private::IconMargin);
01042 const QRect itemRect = subtractMargin(option.rect, Private::ItemMargin);
01043 QRect textArea(QPoint(0, 0), itemRect.size());
01044
01045 switch (option.decorationPosition)
01046 {
01047 case QStyleOptionViewItem::Top:
01048 textArea.setTop(decoSize.height() + 1);
01049 break;
01050
01051 case QStyleOptionViewItem::Bottom:
01052 textArea.setBottom(itemRect.height() - decoSize.height() - 1);
01053 break;
01054
01055 case QStyleOptionViewItem::Left:
01056 textArea.setLeft(decoSize.width() + 1);
01057 break;
01058
01059 case QStyleOptionViewItem::Right:
01060 textArea.setRight(itemRect.width() - decoSize.width() - 1);
01061 break;
01062 }
01063
01064 textArea.translate(itemRect.topLeft());
01065 return QStyle::visualRect(option.direction, option.rect, textArea);
01066 }
01067
01068
01069 QPoint KFileItemDelegate::Private::iconPosition(const QStyleOptionViewItemV4 &option) const
01070 {
01071 const QRect itemRect = subtractMargin(option.rect, Private::ItemMargin);
01072 Qt::Alignment alignment;
01073
01074
01075 switch (option.decorationPosition)
01076 {
01077 case QStyleOptionViewItem::Top:
01078 alignment = Qt::AlignHCenter | Qt::AlignTop;
01079 break;
01080
01081 case QStyleOptionViewItem::Bottom:
01082 alignment = Qt::AlignHCenter | Qt::AlignBottom;
01083 break;
01084
01085 case QStyleOptionViewItem::Left:
01086 alignment = Qt::AlignVCenter | Qt::AlignLeft;
01087 break;
01088
01089 case QStyleOptionViewItem::Right:
01090 alignment = Qt::AlignVCenter | Qt::AlignRight;
01091 break;
01092 }
01093
01094
01095 const QSize size = addMargin(option.decorationSize, Private::IconMargin);
01096 const QRect rect = QStyle::alignedRect(option.direction, alignment, size, itemRect);
01097
01098
01099 QRect iconRect = QRect(QPoint(), option.icon.actualSize(option.decorationSize));
01100 iconRect.moveCenter(rect.center());
01101
01102 return iconRect.topLeft();
01103 }
01104
01105
01106 void KFileItemDelegate::Private::drawFocusRect(QPainter *painter, const QStyleOptionViewItemV4 &option,
01107 const QRect &rect) const
01108 {
01109 if (!(option.state & QStyle::State_HasFocus))
01110 return;
01111
01112 QStyleOptionFocusRect opt;
01113 opt.direction = option.direction;
01114 opt.fontMetrics = option.fontMetrics;
01115 opt.palette = option.palette;
01116 opt.rect = rect;
01117 opt.state = option.state | QStyle::State_KeyboardFocusChange | QStyle::State_Item;
01118 opt.backgroundColor = option.palette.color(option.state & QStyle::State_Selected ?
01119 QPalette::Highlight : QPalette::Base);
01120
01121
01122 painter->setRenderHint(QPainter::Antialiasing, false);
01123
01124 QStyle *style = option.widget ? option.widget->style() : QApplication::style();
01125 style->drawPrimitive(QStyle::PE_FrameFocusRect, &opt, painter, option.widget);
01126
01127 painter->setRenderHint(QPainter::Antialiasing);
01128 }
01129
01130
01131 void KFileItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option,
01132 const QModelIndex &index) const
01133 {
01134 if (!index.isValid())
01135 return;
01136
01137 QStyleOptionViewItemV4 opt(option);
01138 d->initStyleOption(&opt, index);
01139
01140
01141 if (index.column() > 0)
01142 opt.state &= ~QStyle::State_MouseOver;
01143 else
01144 opt.viewItemPosition = QStyleOptionViewItemV4::OnlyOne;
01145
01146 const QAbstractItemView *view = qobject_cast<const QAbstractItemView*>(opt.widget);
01147
01148
01149
01150
01151 KIO::AnimationState *state = d->animationState(opt, index, view);
01152 KIO::CachedRendering *cache = 0;
01153 qreal progress = ((opt.state & QStyle::State_MouseOver) &&
01154 index.column() == KDirModel::Name) ? 1.0 : 0.0;
01155 if (state)
01156 {
01157 cache = state->cachedRendering();
01158 progress = state->hoverProgress();
01159
01160 opt.state &= ~QStyle::State_MouseOver;
01161
01162
01163 if (cache)
01164 {
01165 if (cache->checkValidity(opt.state) && cache->regular.size() == opt.rect.size())
01166 {
01167 QPixmap pixmap = d->transition(cache->regular, cache->hover, progress);
01168
01169 if (state->cachedRenderingFadeFrom() && state->fadeProgress() != 1.0)
01170 {
01171
01172 KIO::CachedRendering* fadeFromCache = state->cachedRenderingFadeFrom();
01173 const QPixmap fadeFromPixmap = d->transition(fadeFromCache->regular, fadeFromCache->hover, progress);
01174
01175 pixmap = d->transition(fadeFromPixmap, pixmap, state->fadeProgress());
01176 }
01177 painter->drawPixmap(option.rect.topLeft(), pixmap);
01178 return;
01179 }
01180
01181 if (!cache->checkValidity(opt.state))
01182 {
01183 if ((KGlobalSettings::graphicEffectsLevel() & KGlobalSettings::SimpleAnimationEffects))
01184 {
01185
01186
01187
01188 if (state->fadeProgress() == 1)
01189 state->setCachedRenderingFadeFrom(state->takeCachedRendering());
01190 }
01191 d->gotNewIcon(index);
01192 }
01193
01194 state->setCachedRendering(0);
01195 }
01196 else
01197 {
01198
01199 d->gotNewIcon(index);
01200 }
01201 }
01202
01203 d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
01204
01205
01206
01207
01208 const QPoint iconPos = d->iconPosition(opt);
01209 QIcon::Mode iconMode = option.state & QStyle::State_Enabled ? QIcon::Normal : QIcon::Disabled;
01210 QIcon::State iconState = option.state & QStyle::State_Open ? QIcon::On : QIcon::Off;
01211 QPixmap icon = opt.icon.pixmap(opt.decorationSize, iconMode, iconState);
01212 const QPen pen = QPen(d->foregroundBrush(opt, index), 0);
01213
01215
01216
01217 QTextLayout labelLayout, infoLayout;
01218 QRect textBoundingRect;
01219
01220 d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect);
01221
01222 QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
01223
01224 int focusHMargin = style->pixelMetric(QStyle::PM_FocusFrameHMargin);
01225 int focusVMargin = style->pixelMetric(QStyle::PM_FocusFrameVMargin);
01226 QRect focusRect = textBoundingRect.adjusted(-focusHMargin, -focusVMargin,
01227 +focusHMargin, +focusVMargin);
01228
01229
01230
01231
01232
01233 if (state && (state->hoverProgress() < 1 || state->fadeProgress() < 1))
01234 {
01235 cache = new KIO::CachedRendering(opt.state, option.rect.size(), index);
01236
01237 QPainter p;
01238 p.begin(&cache->regular);
01239 p.translate(-option.rect.topLeft());
01240 p.setRenderHint(QPainter::Antialiasing);
01241 p.setPen(pen);
01242 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget);
01243 p.drawPixmap(iconPos, icon);
01244 d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect);
01245 d->drawFocusRect(&p, opt, focusRect);
01246 p.end();
01247
01248 opt.state |= QStyle::State_MouseOver;
01249 icon = d->applyHoverEffect(icon);
01250
01251 p.begin(&cache->hover);
01252 p.translate(-option.rect.topLeft());
01253 p.setRenderHint(QPainter::Antialiasing);
01254 p.setPen(pen);
01255 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, &p, opt.widget);
01256 p.drawPixmap(iconPos, icon);
01257 d->drawTextItems(&p, labelLayout, infoLayout, textBoundingRect);
01258 d->drawFocusRect(&p, opt, focusRect);
01259 p.end();
01260
01261 state->setCachedRendering(cache);
01262
01263 QPixmap pixmap = d->transition(cache->regular, cache->hover, progress);
01264
01265 if (state->cachedRenderingFadeFrom() && state->fadeProgress() == 0)
01266 {
01267
01268 KIO::CachedRendering* fadeFromCache = state->cachedRenderingFadeFrom();
01269 const QPixmap fadeFromPixmap = d->transition(fadeFromCache->regular, fadeFromCache->hover, progress);
01270
01271 pixmap = d->transition(fadeFromPixmap, pixmap, state->fadeProgress());
01272
01273 d->restartAnimation(state);
01274 }
01275
01276 painter->drawPixmap(option.rect.topLeft(), pixmap);
01277 return;
01278 }
01279
01280
01281
01282
01283 painter->save();
01284 painter->setRenderHint(QPainter::Antialiasing);
01285 painter->setPen(pen);
01286
01287 if (progress > 0 && !(opt.state & QStyle::State_MouseOver))
01288 {
01289 opt.state |= QStyle::State_MouseOver;
01290 icon = d->applyHoverEffect(icon);
01291 }
01292
01293 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
01294 painter->drawPixmap(iconPos, icon);
01295 d->drawTextItems(painter, labelLayout, infoLayout, textBoundingRect);
01296 d->drawFocusRect(painter, opt, focusRect);
01297
01298 painter->restore();
01299 }
01300
01301
01302 QWidget *KFileItemDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option,
01303 const QModelIndex &index) const
01304 {
01305 QStyleOptionViewItemV4 opt(option);
01306 d->initStyleOption(&opt, index);
01307
01308 KTextEdit *edit = new KTextEdit(parent);
01309 edit->setAcceptRichText(false);
01310 edit->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
01311 edit->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
01312 edit->setAlignment(opt.displayAlignment);
01313 edit->setEnabled(false);
01314 return edit;
01315 }
01316
01317
01318 bool KFileItemDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option,
01319 const QModelIndex &index)
01320 {
01321 Q_UNUSED(event)
01322 Q_UNUSED(model)
01323 Q_UNUSED(option)
01324 Q_UNUSED(index)
01325
01326 return false;
01327 }
01328
01329
01330 void KFileItemDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const
01331 {
01332 KTextEdit *textedit = qobject_cast<KTextEdit*>(editor);
01333 Q_ASSERT(textedit != 0);
01334
01335
01336
01337
01338 if(textedit->isEnabled()) {
01339 return;
01340 }
01341 textedit->setEnabled(true);
01342
01343 const QVariant value = index.data(Qt::EditRole);
01344 const QString text = value.toString();
01345 textedit->insertPlainText(text);
01346 textedit->selectAll();
01347
01348 const QString extension = KMimeType::extractKnownExtension(text);
01349 if (!extension.isEmpty()) {
01350
01351
01352 const int selectionLength = text.length() - extension.length() - 1;
01353 QTextCursor cursor = textedit->textCursor();
01354 cursor.movePosition(QTextCursor::StartOfBlock);
01355 cursor.movePosition(QTextCursor::NextCharacter, QTextCursor::KeepAnchor, selectionLength);
01356 textedit->setTextCursor(cursor);
01357 }
01358 }
01359
01360
01361 void KFileItemDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const
01362 {
01363 KTextEdit *textedit = qobject_cast<KTextEdit*>(editor);
01364 Q_ASSERT(textedit != 0);
01365
01366 model->setData(index, textedit->toPlainText(), Qt::EditRole);
01367 }
01368
01369
01370 void KFileItemDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
01371 const QModelIndex &index) const
01372 {
01373 QStyleOptionViewItemV4 opt(option);
01374 d->initStyleOption(&opt, index);
01375 d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
01376
01377 QRect r = d->labelRectangle(opt);
01378
01379
01380 if (d->verticalLayout(option) && !d->maximumSize.isEmpty()) {
01381 int diff = qMax(r.width(), d->maximumSize.width()) - r.width();
01382 if (diff > 1)
01383 r.adjust(-(diff / 2), 0, diff / 2, 0);
01384 }
01385
01386 KTextEdit *textedit = qobject_cast<KTextEdit*>(editor);
01387 Q_ASSERT(textedit != 0);
01388 const int frame = textedit->frameWidth();
01389 r.adjust(-frame, -frame, frame, frame);
01390
01391 editor->setGeometry(r);
01392 }
01393
01394
01395 bool KFileItemDelegate::helpEvent(QHelpEvent *event, QAbstractItemView *view, const QStyleOptionViewItem &option,
01396 const QModelIndex &index)
01397 {
01398 Q_UNUSED(event)
01399 Q_UNUSED(view)
01400
01401
01402
01403 const QVariant toolTip = index.data(Qt::ToolTipRole);
01404
01405 if (!toolTip.isValid()) {
01406 return false;
01407 }
01408
01409 if (index.data() != toolTip) {
01410 return QAbstractItemDelegate::helpEvent(event, view, option, index);
01411 }
01412
01413 if (!d->showToolTipWhenElided) {
01414 return false;
01415 }
01416
01417
01418
01419 QStyleOptionViewItemV4 opt(option);
01420 d->initStyleOption(&opt, index);
01421 d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
01422
01423 QTextLayout labelLayout;
01424 QTextLayout infoLayout;
01425 QRect textBoundingRect;
01426 d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect);
01427 const QString elidedText = d->elidedText(labelLayout, opt, textBoundingRect.size());
01428
01429 if (elidedText != d->display(index)) {
01430 return QAbstractItemDelegate::helpEvent(event, view, option, index);
01431 }
01432
01433 return false;
01434 }
01435
01436 QRegion KFileItemDelegate::shape(const QStyleOptionViewItem &option, const QModelIndex &index)
01437 {
01438 QStyleOptionViewItemV4 opt(option);
01439 d->initStyleOption(&opt, index);
01440 d->setActiveMargins(d->verticalLayout(opt) ? Qt::Vertical : Qt::Horizontal);
01441
01442 QTextLayout labelLayout;
01443 QTextLayout infoLayout;
01444 QRect textBoundingRect;
01445 d->layoutTextItems(opt, index, &labelLayout, &infoLayout, &textBoundingRect);
01446
01447 const QPoint pos = d->iconPosition(opt);
01448 QRect iconRect = QRect(pos, opt.icon.actualSize(opt.decorationSize));
01449
01450
01451 switch (opt.decorationPosition)
01452 {
01453 case QStyleOptionViewItem::Top:
01454 if (iconRect.width() < textBoundingRect.width())
01455 iconRect.setBottom(textBoundingRect.top());
01456 else
01457 textBoundingRect.setTop(iconRect.bottom());
01458 break;
01459 case QStyleOptionViewItem::Bottom:
01460 if (iconRect.width() < textBoundingRect.width())
01461 iconRect.setTop(textBoundingRect.bottom());
01462 else
01463 textBoundingRect.setBottom(iconRect.top());
01464 break;
01465 case QStyleOptionViewItem::Left:
01466 iconRect.setRight(textBoundingRect.left());
01467 break;
01468 case QStyleOptionViewItem::Right:
01469 iconRect.setLeft(textBoundingRect.right());
01470 break;
01471 }
01472
01473 QRegion region;
01474 region += iconRect;
01475 region += textBoundingRect;
01476 return region;
01477 }
01478
01479 bool KFileItemDelegate::eventFilter(QObject *object, QEvent *event)
01480 {
01481 KTextEdit *editor = qobject_cast<KTextEdit*>(object);
01482 if (!editor)
01483 return false;
01484
01485 switch (event->type())
01486 {
01487 case QEvent::KeyPress:
01488 {
01489 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
01490 switch (keyEvent->key())
01491 {
01492 case Qt::Key_Tab:
01493 case Qt::Key_Backtab:
01494 emit commitData(editor);
01495 emit closeEditor(editor, NoHint);
01496 return true;
01497
01498 case Qt::Key_Enter:
01499 case Qt::Key_Return:
01500 if (editor->toPlainText().isEmpty())
01501 return true;
01502
01503 emit commitData(editor);
01504 emit closeEditor(editor, SubmitModelCache);
01505 return true;
01506
01507 case Qt::Key_Escape:
01508 emit closeEditor(editor, RevertModelCache);
01509 return true;
01510
01511 default:
01512 return false;
01513 }
01514 }
01515
01516 case QEvent::FocusOut:
01517 {
01518 emit commitData(editor);
01519 emit closeEditor(editor, NoHint);
01520 return true;
01521 }
01522
01523 default:
01524 return false;
01525 }
01526 }
01527
01528
01529 #include "kfileitemdelegate.moc"
01530
01531
01532