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