00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "kcategorizeditemsviewdelegate_p.h"
00021
00022 #include <cmath>
00023
00024 #include <QtCore/QtCore>
00025
00026 #include <KIconLoader>
00027
00028 #include "kcategorizeditemsview_p.h"
00029
00030 #define FAV_ICON_SIZE 24
00031 #define EMBLEM_ICON_SIZE 16
00032 #define UNIVERSAL_PADDING 6
00033 #define FADE_LENGTH 32
00034 #define MAIN_ICON_SIZE 48
00035 #define DROPDOWN_PADDING 2
00036 #define DROPDOWN_SEPARATOR_HEIGHT 32
00037
00038 KCategorizedItemsViewDelegate::KCategorizedItemsViewDelegate(QObject * parent)
00039 : QItemDelegate(parent), m_favoriteIcon("bookmarks"),
00040 m_favoriteAddIcon("list-add"), m_removeIcon("list-remove"),
00041 m_infoIcon("dialog-information"),
00042 m_onFavoriteIconItem(NULL)
00043 {
00044 m_parent = (KCategorizedItemsView *) parent;
00045 }
00046
00047 void KCategorizedItemsViewDelegate::paint(QPainter *painter,
00048 const QStyleOptionViewItem &option, const QModelIndex &index) const
00049 {
00050 KCategorizedItemsViewModels::AbstractItem * item = getItemByProxyIndex(index);
00051 if (!item) {
00052 return;
00053 }
00054
00055 QStyleOptionViewItemV4 opt(option);
00056 QStyle *style = opt.widget ? opt.widget->style() : QApplication::style();
00057 style->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter, opt.widget);
00058
00059 switch (index.column()) {
00060 case 0:
00061 paintColMain(painter, option, item);
00062 break;
00063 case 1:
00064 paintColFav(painter, option, item);
00065 break;
00066 case 2:
00067 paintColRemove(painter, option, item);
00068 break;
00069 case 3:
00070 paintColInfo(painter, option, item);
00071 break;
00072 default:
00073 kDebug() << "unexpected column";
00074 }
00075 }
00076
00077 int KCategorizedItemsViewDelegate::calcItemHeight(const QStyleOptionViewItem &option) const
00078 {
00079
00080 QFont titleFont = option.font;
00081 titleFont.setBold(true);
00082 titleFont.setPointSize(titleFont.pointSize() + 2);
00083
00084 int textHeight = QFontInfo(titleFont).pixelSize() + QFontInfo(option.font).pixelSize();
00085
00086 return qMax(textHeight, MAIN_ICON_SIZE) + 2 * UNIVERSAL_PADDING;
00087 }
00088
00089 void KCategorizedItemsViewDelegate::paintColMain(
00090 QPainter *painter, const QStyleOptionViewItem &option,
00091 const KCategorizedItemsViewModels::AbstractItem *item) const
00092 {
00093 const int left = option.rect.left();
00094 const int top = option.rect.top();
00095 const int width = option.rect.width();
00096 const int height = calcItemHeight(option);
00097
00098 bool leftToRight = (painter->layoutDirection() == Qt::LeftToRight);
00099 QIcon::Mode iconMode = QIcon::Normal;
00100
00101 QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
00102 option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
00103
00104
00105 QFont titleFont = option.font;
00106 titleFont.setBold(true);
00107 titleFont.setPointSize(titleFont.pointSize() + 2);
00108
00109 QPixmap pixmap(width, height);
00110 pixmap.fill(Qt::transparent);
00111 QPainter p(&pixmap);
00112 p.translate(-option.rect.topLeft());
00113
00114 QLinearGradient gradient;
00115
00116 QString title = item->name();
00117 QString description = item->description();
00118
00119
00120
00121
00122 int textInner = 2 * UNIVERSAL_PADDING + MAIN_ICON_SIZE;
00123
00124 p.setPen(foregroundColor);
00125 p.setFont(titleFont);
00126 p.drawText(left + (leftToRight ? textInner : 0),
00127 top, width - textInner, height / 2,
00128 Qt::AlignBottom | Qt::AlignLeft, title);
00129 p.setFont(option.font);
00130 p.drawText(left + (leftToRight ? textInner : 0),
00131 top + height / 2,
00132 width - textInner, height / 2,
00133 Qt::AlignTop | Qt::AlignLeft, description);
00134
00135
00136 item->icon().paint(
00137 &p,
00138 leftToRight ? left + UNIVERSAL_PADDING : left + width - UNIVERSAL_PADDING - MAIN_ICON_SIZE,
00139 top + UNIVERSAL_PADDING,
00140 MAIN_ICON_SIZE,
00141 MAIN_ICON_SIZE,
00142 Qt::AlignCenter, iconMode);
00143
00144
00145 int emblemCount = 0;
00146 QPair < Filter, QIcon > emblem;
00147 foreach (emblem, m_parent->m_emblems) {
00148 if (item->passesFiltering(emblem.first)) {
00149 ++emblemCount;
00150 }
00151 }
00152
00153
00154 if (leftToRight) {
00155 gradient = QLinearGradient(left + width - UNIVERSAL_PADDING - FADE_LENGTH, 0,
00156 left + width - UNIVERSAL_PADDING, 0);
00157 gradient.setColorAt(0, Qt::white);
00158 gradient.setColorAt(1, Qt::transparent);
00159 } else {
00160 gradient = QLinearGradient(left + UNIVERSAL_PADDING, 0,
00161 left + UNIVERSAL_PADDING + FADE_LENGTH, 0);
00162 gradient.setColorAt(0, Qt::transparent);
00163 gradient.setColorAt(1, Qt::white);
00164 }
00165
00166 QRect paintRect = option.rect;
00167 p.setCompositionMode(QPainter::CompositionMode_DestinationIn);
00168 p.fillRect(paintRect, gradient);
00169
00170 if (leftToRight) {
00171 gradient.setStart(
00172 left + width - emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) - FADE_LENGTH, 0);
00173 gradient.setFinalStop(
00174 left + width - emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
00175 } else {
00176 gradient.setStart(
00177 left + UNIVERSAL_PADDING + emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
00178 gradient.setFinalStop(
00179 left + UNIVERSAL_PADDING + emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) + FADE_LENGTH, 0);
00180 }
00181 paintRect.setHeight(UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2);
00182 p.fillRect(paintRect, gradient);
00183
00184
00185 p.setCompositionMode(QPainter::CompositionMode_SourceOver);
00186 int emblemLeft = leftToRight ? (left + width - EMBLEM_ICON_SIZE) : left;
00187 foreach (emblem, m_parent->m_emblems) {
00188 if (item->passesFiltering(emblem.first)) {
00189 emblem.second.paint(&p,
00190 emblemLeft, top + UNIVERSAL_PADDING + (FAV_ICON_SIZE - EMBLEM_ICON_SIZE)/2,
00191 EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
00192 if (leftToRight) {
00193 emblemLeft -= UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
00194 } else {
00195 emblemLeft += UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
00196 }
00197 }
00198 }
00199 p.end();
00200
00201 painter->drawPixmap(option.rect.topLeft(), pixmap);
00202 }
00203
00204 void KCategorizedItemsViewDelegate::paintColFav(
00205 QPainter *painter, const QStyleOptionViewItem &option,
00206 const KCategorizedItemsViewModels::AbstractItem *item) const
00207 {
00208 int left = option.rect.left();
00209 int top = option.rect.top();
00210 int width = option.rect.width();
00211
00212
00213
00214 if (! (option.state & QStyle::State_MouseOver) && m_onFavoriteIconItem == item) {
00215 m_onFavoriteIconItem = NULL;
00216 }
00217
00218 QIcon::Mode iconMode = QIcon::Normal;
00219 if (!item->isFavorite()) {
00220 iconMode = QIcon::Disabled;
00221 } else if (option.state & QStyle::State_MouseOver) {
00222 iconMode = QIcon::Active;
00223 }
00224
00225 m_favoriteIcon.paint(
00226 painter,
00227 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING,
00228 top + UNIVERSAL_PADDING,
00229 FAV_ICON_SIZE,
00230 FAV_ICON_SIZE,
00231 Qt::AlignCenter,
00232 iconMode);
00233
00234 const KIcon &icon = (item->isFavorite())? m_removeIcon : m_favoriteAddIcon;
00235
00236 if ((option.state & QStyle::State_MouseOver) && (m_onFavoriteIconItem != item)) {
00237 icon.paint(
00238 painter,
00239 left + width - EMBLEM_ICON_SIZE - UNIVERSAL_PADDING,
00240 top + UNIVERSAL_PADDING,
00241 EMBLEM_ICON_SIZE,
00242 EMBLEM_ICON_SIZE,
00243 Qt::AlignCenter,
00244 iconMode);
00245 }
00246 }
00247
00248 void KCategorizedItemsViewDelegate::paintColInfo(
00249 QPainter *painter, const QStyleOptionViewItem &option,
00250 const KCategorizedItemsViewModels::AbstractItem *item) const
00251 {
00252 QIcon::Mode infoMode = QIcon::Normal;
00253 if (!(option.state & QStyle::State_MouseOver)) {
00254 return;
00255 }
00256
00257 int left = option.rect.left();
00258 int top = option.rect.top();
00259 int width = option.rect.width();
00260
00261
00262
00263 m_infoIcon.paint(
00264 painter,
00265 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING,
00266 top + UNIVERSAL_PADDING,
00267 FAV_ICON_SIZE,
00268 FAV_ICON_SIZE,
00269 Qt::AlignCenter,
00270 infoMode);
00271 }
00272
00273 void KCategorizedItemsViewDelegate::paintColRemove(
00274 QPainter *painter, const QStyleOptionViewItem &option,
00275 const KCategorizedItemsViewModels::AbstractItem *item) const
00276 {
00277
00278 int running = item->running();
00279 if (!running) {
00280 return;
00281 }
00282
00283 int left = option.rect.left();
00284 int top = option.rect.top();
00285 int width = option.rect.width();
00286
00287 QIcon::Mode iconMode = QIcon::Normal;
00288 if (option.state & QStyle::State_MouseOver) {
00289 iconMode = QIcon::Active;
00290 }
00291
00292 m_removeIcon.paint(painter,
00293 left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
00294 FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
00295
00296 if (running == 1) {
00297 return;
00298 }
00299
00300 QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
00301 option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
00302 painter->setPen(foregroundColor);
00303 painter->setFont(option.font);
00304 painter->drawText(
00305 left + UNIVERSAL_PADDING,
00306 top + UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2,
00307 width - 2 * UNIVERSAL_PADDING, MAIN_ICON_SIZE / 2,
00308 Qt::AlignCenter, QString::number(running));
00309 }
00310
00311 bool KCategorizedItemsViewDelegate::editorEvent(
00312 QEvent *event, QAbstractItemModel *model,
00313 const QStyleOptionViewItem &option, const QModelIndex &index)
00314 {
00315 if (event->type() == QEvent::MouseButtonPress) {
00316 KCategorizedItemsViewModels::AbstractItem *item = getItemByProxyIndex(index);
00317 if (index.column() == 1) {
00318 m_onFavoriteIconItem = item;
00319 item->setFavorite(!item->isFavorite());
00320 return true;
00321 } else if (index.column() == 2 && item->running()) {
00322 item->setRunning(0);
00323 emit destroyApplets(item->name());
00324 return true;
00325 } else if (index.column() == 3) {
00326 emit infoAboutApplet(item->name());
00327 return true;
00328 }
00329 }
00330
00331 return QItemDelegate::editorEvent(event, model, option, index);
00332 }
00333
00334 QSize KCategorizedItemsViewDelegate::sizeHint(const QStyleOptionViewItem &option,
00335 const QModelIndex &index) const
00336 {
00337 int width = (index.column() == 0) ? 0 : FAV_ICON_SIZE;
00338 return QSize(width, calcItemHeight(option));
00339 }
00340
00341 int KCategorizedItemsViewDelegate::columnWidth (int column, int viewWidth) const {
00342 if (column != 0) {
00343 return FAV_ICON_SIZE + 3 * UNIVERSAL_PADDING;
00344 } else {
00345 return viewWidth - 3 * columnWidth(1, viewWidth);
00346 }
00347 }
00348
00349 KCategorizedItemsViewModels::AbstractItem *KCategorizedItemsViewDelegate::getItemByProxyIndex(
00350 const QModelIndex &index) const
00351 {
00352 return (AbstractItem *)m_parent->m_modelItems->itemFromIndex(m_parent->m_modelFilterItems->mapToSource(index));
00353 }
00354
00355
00356
00357 KCategorizedItemsViewFilterDelegate::KCategorizedItemsViewFilterDelegate(QObject *parent)
00358 : QItemDelegate(parent)
00359 {
00360 kDebug() << "KCategorizedItemsViewFilterDelegate(QObject *parent)\n";
00361
00362 }
00363
00364 void KCategorizedItemsViewFilterDelegate::paint(QPainter *painter,
00365 const QStyleOptionViewItem &option, const QModelIndex &index) const
00366 {
00367 if (index.flags() & Qt::ItemIsEnabled) {
00368 QItemDelegate::paint(painter, option, index);
00369 } else {
00370 QStyleOptionViewItem separatorOption(option);
00371 int height = QItemDelegate::sizeHint(option, index).height() + 2 * DROPDOWN_PADDING;
00372
00373 separatorOption.state &= ~(QStyle::State_Selected |
00374 QStyle::State_MouseOver |
00375 QStyle::State_HasFocus);
00376 separatorOption.rect.setTop(
00377 separatorOption.rect.top() + separatorOption.rect.height() - height);
00378 separatorOption.rect.setHeight(height);
00379 QItemDelegate::paint(painter, separatorOption, index);
00380
00381
00382
00383
00384
00385 }
00386 }
00387
00388 QSize KCategorizedItemsViewFilterDelegate::sizeHint(const QStyleOptionViewItem &option,
00389 const QModelIndex &index) const
00390 {
00391 QSize size = QItemDelegate::sizeHint(option, index);
00392 if (index.flags() & Qt::ItemIsEnabled) {
00393 size.setHeight(size.height() + 2 * DROPDOWN_PADDING);
00394 } else {
00395 size.setHeight(DROPDOWN_SEPARATOR_HEIGHT);
00396 }
00397 return size;
00398 }
00399
00400 #include "kcategorizeditemsviewdelegate_p.moc"
00401