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 #include "qxtscheduleitemdelegate.h"
00026 #include <QModelIndex>
00027 #include <QPixmap>
00028 #include <QPainter>
00029 #include <QApplication>
00030 #include <QSize>
00031 #include <QFontMetrics>
00032 #include <QIcon>
00033 #include <QVariant>
00034 #include <QDateTime>
00035 #include "qxtnamespace.h"
00036
00037 QxtScheduleItemDelegate::QxtScheduleItemDelegate(QObject *parent)
00038 : QAbstractItemDelegate(parent)
00039 {
00040 }
00041
00042
00043 QxtScheduleItemDelegate::~QxtScheduleItemDelegate()
00044 {
00045 }
00046
00047
00056 void QxtScheduleItemDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
00057 {
00058
00059 const QxtStyleOptionScheduleViewItem *agendaOption = qstyleoption_cast<const QxtStyleOptionScheduleViewItem *>(&option);
00060 if (!agendaOption)
00061 return;
00062
00063 QStringList rowsData = index.data(Qt::EditRole).toStringList();
00064
00065 QRect currRect;
00066
00067 painter->save();
00068
00069 if (agendaOption->itemPaintCache->size() != agendaOption->itemGeometries.size())
00070 (*agendaOption->itemPaintCache) = QVector<QPixmap>(agendaOption->itemGeometries.size(), QPixmap());
00071
00072 int lastPart = agendaOption->itemGeometries.size() - 1;
00073 int paintedSubItems = 0;
00074
00075 for (int iLoop = 0; iLoop < agendaOption->itemGeometries.size();iLoop++)
00076 {
00077 if ((*agendaOption->itemPaintCache)[iLoop].width() != agendaOption->itemGeometries[iLoop].width()
00078 || (*agendaOption->itemPaintCache)[iLoop].height() != agendaOption->itemGeometries[iLoop].height())
00079 {
00080
00081
00082 (*agendaOption->itemPaintCache)[iLoop] = QPixmap(agendaOption->itemGeometries[iLoop].size());
00083 (*agendaOption->itemPaintCache)[iLoop].fill(Qt::transparent);
00084
00085 QPainter cachePainter(&(*agendaOption->itemPaintCache)[iLoop]);
00086 QRect rect = QRect(QPoint(0, 0), agendaOption->itemGeometries[iLoop].size());
00087
00088
00089 ItemPart part = iLoop == 0 ? Top : (iLoop == lastPart ? Bottom : Middle);
00090
00091
00092 if (lastPart == 0)
00093 part = Single;
00094
00095
00096 cachePainter.save();
00097 paintItemBody(&cachePainter, rect, *agendaOption, part, index);
00098 cachePainter.restore();
00099
00100 int remainingHeight = rect.height();
00101
00102
00103 if (iLoop == 0 && agendaOption->itemHeaderHeight > 0 && agendaOption->itemHeaderHeight < remainingHeight)
00104 {
00105 QRect headerRect(0, 0, rect.width(), agendaOption->itemHeaderHeight);
00106 paintItemHeader(&cachePainter, headerRect, *agendaOption, index);
00107 remainingHeight -= agendaOption->itemHeaderHeight;
00108 }
00109
00110
00111 int subItems = index.model()->rowCount(index);
00112 for (int items = paintedSubItems; items < subItems; items++)
00113 {
00114 QModelIndex currSubItem = index.model()->index(items, 0, index);
00115 QSize size = sizeHint(option, currSubItem);
00116
00117 if (currSubItem.isValid()){
00118 paintSubItem(&cachePainter, QRect(), *agendaOption, currSubItem);
00119 }
00120
00121 paintedSubItems++;
00122 }
00123
00124 cachePainter.end();
00125
00126 }
00127 currRect = agendaOption->itemGeometries[iLoop];
00128 currRect.translate(agendaOption->translate);
00129 painter->drawPixmap(currRect, (*agendaOption->itemPaintCache)[iLoop]);
00130 }
00131 painter->restore();
00132 }
00133
00142 void QxtScheduleItemDelegate::paintItemBody(QPainter *painter, const QRect rect , const QxtStyleOptionScheduleViewItem & option , const ItemPart part, const QModelIndex & index) const
00143 {
00144 int iCurrRoundTop, iCurrRoundBottom;
00145 iCurrRoundTop = iCurrRoundBottom = 0;
00146
00147 QColor fillColor = index.data(Qt::BackgroundRole).value<QColor>();
00148 fillColor.setAlpha(120);
00149 QColor outLineColor = index.data(Qt::ForegroundRole).value<QColor>();
00150
00151 painter->setFont(option.font);
00152 painter->setRenderHint(QPainter::Antialiasing);
00153
00154 if (part == Top || part == Single)
00155 iCurrRoundTop = option.roundCornersRadius;
00156 if (part == Bottom || part == Single)
00157 iCurrRoundBottom = option.roundCornersRadius;
00158
00159 QPainterPath cachePath;
00160 QRect cacheRect = QRect(QPoint(1, 1), rect.size() - QSize(1, 1));
00161
00162 painter->setBrush(fillColor);
00163 painter->setPen(outLineColor);
00164
00165 createPainterPath(cachePath, cacheRect, iCurrRoundTop, iCurrRoundBottom);
00166 painter->drawPath(cachePath);
00167 }
00168
00176 void QxtScheduleItemDelegate::paintItemHeader(QPainter *painter, const QRect rect , const QxtStyleOptionScheduleViewItem & option, const QModelIndex &index) const
00177 {
00178 bool converted = false;
00179 int startUnixTime = index.data(Qxt::ItemStartTimeRole).toInt(&converted);
00180 if (!converted)
00181 return;
00182
00183 int duration = index.data(Qxt::ItemDurationRole).toInt(&converted);
00184 if (!converted)
00185 return;
00186
00187 QDateTime startTime = QDateTime::fromTime_t(startUnixTime);
00188 QDateTime endTime = QDateTime::fromTime_t(startUnixTime + duration);
00189
00190 if (!startTime.isValid() || !endTime.isValid())
00191 return;
00192
00193 QFont font;
00194 QVariant vfont = index.data(Qt::FontRole);
00195
00196 if (vfont.isValid())
00197 font = vfont.value<QFont>();
00198 else
00199 font = option.font;
00200
00201 QString text = startTime.toString("hh:mm") + ' ' + endTime.toString("hh:mm");
00202 QFontMetrics metr(font);
00203 text = metr.elidedText(text, Qt::ElideRight, rect.width());
00204 painter->drawText(rect, Qt::AlignCenter, text);
00205 }
00206
00214 void QxtScheduleItemDelegate::paintSubItem(QPainter * , const QRect , const QxtStyleOptionScheduleViewItem & , const QModelIndex & ) const
00215 {
00216
00217 }
00218
00222 QSize QxtScheduleItemDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
00223 {
00224
00225
00226 if (index.parent().isValid())
00227 {
00228 QSize size = index.data(Qt::SizeHintRole).toSize();
00229
00230 if (!size.isValid())
00231 {
00232 QFont font;
00233 QVariant vfont = index.data(Qt::FontRole);
00234
00235 if (vfont.isValid())
00236 font = vfont.value<QFont>();
00237 else
00238 font = option.font;
00239
00240 int height = 0;
00241 QFontMetrics metr(font);
00242 height = metr.height() + 2;
00243
00244 return QSize(0, height);
00245 }
00246 }
00247 return QSize();
00248 }
00249
00250 void QxtScheduleItemDelegate::createPainterPath(QPainterPath & emptyPath, const QRect & fullItemRect, const int iRoundTop, const int iRoundBottom) const
00251 {
00252 emptyPath = QPainterPath();
00253 bool bRoundTop = iRoundTop > 0;
00254 bool bRountBottom = iRoundBottom > 0;
00255
00256 if (bRoundTop)
00257 {
00258 emptyPath.moveTo(fullItemRect.topLeft() + QPoint(0, iRoundTop));
00259 emptyPath.quadTo(fullItemRect.topLeft(), fullItemRect.topLeft() + QPoint(iRoundTop, 0));
00260 }
00261 else
00262 emptyPath.moveTo(fullItemRect.topLeft());
00263
00264 emptyPath.lineTo(fullItemRect.topRight() - QPoint(iRoundTop, 0));
00265
00266 if (bRoundTop)
00267 emptyPath.quadTo(fullItemRect.topRight(), fullItemRect.topRight() + QPoint(0, iRoundTop));
00268
00269 emptyPath.lineTo(fullItemRect.bottomRight() - QPoint(0, iRoundBottom));
00270
00271 if (bRountBottom)
00272 emptyPath.quadTo(fullItemRect.bottomRight(), fullItemRect.bottomRight() - QPoint(iRoundBottom, 0));
00273
00274 emptyPath.lineTo(fullItemRect.bottomLeft() + QPoint(iRoundBottom, 0));
00275
00276 if (bRountBottom)
00277 emptyPath.quadTo(fullItemRect.bottomLeft(), fullItemRect.bottomLeft() - QPoint(0, iRoundBottom));
00278
00279 emptyPath.closeSubpath();
00280 }
00281
00282