2 * This file is part of the KDE project
3 * Copyright (C) 2007, 2006 Rafael Fernández López <ereslibre@kde.org>
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Library General Public
7 * License version 2 as published by the Free Software Foundation.
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Library General Public License for more details.
14 * You should have received a copy of the GNU Library General Public License
15 * along with this library; see the file COPYING.LIB. If not, write to
16 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17 * Boston, MA 02110-1301, USA.
20 #include "progresslistdelegate.h"
21 #include "progresslistdelegate_p.h"
22 #include "progresslistmodel.h"
24 #include <QApplication>
25 #include <QPushButton>
27 #include <QStyleOptionProgressBarV2>
29 #include <QFontMetrics>
31 #include <QHBoxLayout>
36 #include <kiconloader.h>
38 int ProgressListDelegate::Private::getJobId(const QModelIndex
&index
) const
40 return index
.model()->data(index
, JobId
).toInt();
43 QString
ProgressListDelegate::Private::getApplicationInternalName(const QModelIndex
&index
) const
45 return index
.model()->data(index
, ApplicationInternalName
).toString();
48 QString
ProgressListDelegate::Private::getApplicationName(const QModelIndex
&index
) const
50 return index
.model()->data(index
, ApplicationName
).toString();
53 QString
ProgressListDelegate::Private::getIcon(const QModelIndex
&index
) const
55 return index
.model()->data(index
, Icon
).toString();
58 qlonglong
ProgressListDelegate::Private::getFileTotals(const QModelIndex
&index
) const
60 return index
.model()->data(index
, FileTotals
).toLongLong();
63 qlonglong
ProgressListDelegate::Private::getFilesProcessed(const QModelIndex
&index
) const
65 return index
.model()->data(index
, FilesProcessed
).toLongLong();
68 qlonglong
ProgressListDelegate::Private::getDirTotals(const QModelIndex
&index
) const
70 return index
.model()->data(index
, DirTotals
).toLongLong();
73 qlonglong
ProgressListDelegate::Private::getDirsProcessed(const QModelIndex
&index
) const
75 return index
.model()->data(index
, DirsProcessed
).toLongLong();
78 QString
ProgressListDelegate::Private::getSizeTotals(const QModelIndex
&index
) const
80 return index
.model()->data(index
, SizeTotals
).toString();
83 QString
ProgressListDelegate::Private::getSizeProcessed(const QModelIndex
&index
) const
85 return index
.model()->data(index
, SizeProcessed
).toString();
88 qlonglong
ProgressListDelegate::Private::getTimeTotals(const QModelIndex
&index
) const
90 return index
.model()->data(index
, TimeTotals
).toLongLong();
93 qlonglong
ProgressListDelegate::Private::getTimeProcessed(const QModelIndex
&index
) const
95 return index
.model()->data(index
, TimeElapsed
).toLongLong();
98 QString
ProgressListDelegate::Private::getFromLabel(const QModelIndex
&index
) const
100 return index
.model()->data(index
, FromLabel
).toString();
103 QString
ProgressListDelegate::Private::getFrom(const QModelIndex
&index
) const
105 return index
.model()->data(index
, From
).toString();
108 QString
ProgressListDelegate::Private::getToLabel(const QModelIndex
&index
) const
110 return index
.model()->data(index
, ToLabel
).toString();
113 QString
ProgressListDelegate::Private::getTo(const QModelIndex
&index
) const
115 return index
.model()->data(index
, To
).toString();
118 QString
ProgressListDelegate::Private::getSpeed(const QModelIndex
&index
) const
120 return index
.model()->data(index
, Speed
).toString();
123 int ProgressListDelegate::Private::getPercent(const QModelIndex
&index
) const
125 return index
.model()->data(index
, Percent
).toInt();
128 QString
ProgressListDelegate::Private::getMessage(const QModelIndex
&index
) const
130 return index
.model()->data(index
, Message
).toString();
133 QString
ProgressListDelegate::Private::getProgressMessage(const QModelIndex
&index
) const
135 return index
.model()->data(index
, ProgressMessage
).toString();
138 const QList
<ActionInfo
> &ProgressListDelegate::Private::getActionList(const QModelIndex
&index
) const
140 const ProgressListModel
*progressListModel
= static_cast<const ProgressListModel
*>(index
.model());
142 return progressListModel
->actions(getJobId(index
));
145 QStyleOptionProgressBarV2
*ProgressListDelegate::Private::getProgressBar(const QModelIndex
&index
) const
147 const ProgressListModel
*progressListModel
= static_cast<const ProgressListModel
*>(index
.model());
149 return progressListModel
->progressBar(index
);
152 int ProgressListDelegate::Private::getCurrentLeftMargin(int fontHeight
) const
154 return leftMargin
+ separatorPixels
+ fontHeight
;
157 void ProgressListDelegate::Private::actionModified(const QModelIndex
&index
)
159 listView
->closePersistentEditor(index
);
160 listView
->openPersistentEditor(index
);
163 ProgressListDelegate::Private::QActionPushButton::QActionPushButton(int actionId
, int jobId
, const QString
&actionText
, QWidget
*parent
)
164 : QPushButton(actionText
, parent
)
166 this->actionId
= actionId
;
169 connect(this, SIGNAL(clicked(bool)), this,
170 SLOT(buttonPressed()));
173 void ProgressListDelegate::Private::QActionPushButton::buttonPressed()
175 emit
actionButtonPressed(actionId
, jobId
);
178 ProgressListDelegate::ProgressListDelegate(QObject
*parent
, QListView
*listView
)
179 : QItemDelegate(parent
)
180 , d(new Private(parent
, listView
))
184 ProgressListDelegate::~ProgressListDelegate()
189 QWidget
*ProgressListDelegate::createEditor(QWidget
*parent
, const QStyleOptionViewItem
&option
, const QModelIndex
&index
) const
193 const ProgressListModel
*progressListModel
= static_cast<const ProgressListModel
*>(index
.model());
195 int jobIdModel
= index
.model()->data(index
, JobId
).toInt();
197 QList
<ActionInfo
> actionsModel
= progressListModel
->actions(jobIdModel
);
199 if (actionsModel
.isEmpty())
202 QWidget
*returnWidget
= new QWidget(parent
);
203 QHBoxLayout
*layout
= new QHBoxLayout();
204 layout
->setMargin(0);
205 layout
->setSpacing(0);
206 returnWidget
->setLayout(layout
);
208 QPushButton
*newButton
;
210 foreach (const ActionInfo
&actionIt
, actionsModel
)
212 newButton
= new Private::QActionPushButton(actionIt
.actionId
, jobIdModel
, actionIt
.actionText
);
214 connect(newButton
, SIGNAL(actionButtonPressed(int,int)), this,
215 SIGNAL(actionPerformed(int,int)));
217 layout
->addWidget(newButton
);
219 if (i
< actionsModel
.count() - 1)
220 layout
->addSpacing(d
->separatorPixels
);
228 void ProgressListDelegate::paint(QPainter
*painter
, const QStyleOptionViewItem
&option
, const QModelIndex
&index
) const
230 painter
->setClipping(false); // workaround for qt bug
232 QFontMetrics fontMetrics
= painter
->fontMetrics();
233 int textHeight
= fontMetrics
.height();
235 int coordY
= d
->separatorPixels
+ option
.rect
.top();
237 KIconLoader
*iconLoader
= static_cast<KIconLoader
*>(index
.internalPointer());
238 KIcon
iconToShow(d
->getIcon(index
), iconLoader
);
240 QColor unselectedTextColor
= option
.palette
.text().color();
241 QColor selectedTextColor
= option
.palette
.highlightedText().color();
242 QPen currentPen
= painter
->pen();
243 QPen unselectedPen
= QPen(currentPen
);
244 QPen selectedPen
= QPen(currentPen
);
246 unselectedPen
.setColor(unselectedTextColor
);
247 selectedPen
.setColor(selectedTextColor
);
249 if (option
.state
& QStyle::State_Selected
)
251 painter
->fillRect(option
.rect
, option
.palette
.highlight());
252 painter
->setPen(selectedPen
);
256 painter
->setPen(unselectedPen
);
260 painter
->setRenderHint(QPainter::Antialiasing
, true);
262 QRect canvas
= option
.rect
;
263 int iconWidth
= canvas
.height() - d
->leftMargin
- d
->rightMargin
;
264 int iconHeight
= iconWidth
;
265 d
->iconWidth
= iconWidth
;
267 painter
->setOpacity(0.25);
269 painter
->drawPixmap(option
.rect
.right() - iconWidth
- d
->rightMargin
, coordY
, iconToShow
.pixmap(iconWidth
, iconHeight
));
271 painter
->translate(d
->leftMargin
, d
->separatorPixels
+ (fontMetrics
.width(d
->getApplicationName(index
)) / 2) + (iconHeight
/ 2) + canvas
.top());
272 painter
->rotate(270);
274 QRect
appNameRect(0, 0, fontMetrics
.width(d
->getApplicationName(index
)), textHeight
);
276 painter
->drawText(appNameRect
, Qt::AlignLeft
, d
->getApplicationName(index
));
278 painter
->resetMatrix();
280 painter
->setOpacity(1);
282 if (!d
->getMessage(index
).isEmpty())
284 QString textToShow
= fontMetrics
.elidedText(d
->getMessage(index
), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
286 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
288 painter
->drawText(d
->getCurrentLeftMargin(textHeight
), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
290 coordY
+= d
->separatorPixels
+ textHeight
;
293 if (!d
->getFrom(index
).isEmpty())
295 QString textToShow
= fontMetrics
.elidedText(i18n("%1: %2", d
->getFromLabel(index
), d
->getFrom(index
)), Qt::ElideMiddle
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
297 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
299 painter
->drawText(d
->getCurrentLeftMargin(textHeight
), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
301 coordY
+= d
->separatorPixels
+ textHeight
;
304 if (!d
->getTo(index
).isEmpty())
306 QString textToShow
= fontMetrics
.elidedText(i18n("%1: %2", d
->getToLabel(index
), d
->getTo(index
)), Qt::ElideMiddle
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
308 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
310 painter
->drawText(d
->getCurrentLeftMargin(textHeight
), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
312 coordY
+= d
->separatorPixels
+ textHeight
;
315 if (!d
->getProgressMessage(index
).isEmpty())
317 QString textToShow
= fontMetrics
.elidedText(d
->getProgressMessage(index
), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
319 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
321 painter
->drawText(d
->getCurrentLeftMargin(textHeight
), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
323 coordY
+= d
->separatorPixels
+ textHeight
;
326 if (d
->getFilesProcessed(index
) > 1)
329 if (d
->getFileTotals(index
))
330 textToShow
= fontMetrics
.elidedText(i18np("1 of %2 files processed", "%1 of %2 files processed", d
->getFilesProcessed(index
), d
->getFileTotals(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
332 textToShow
= fontMetrics
.elidedText(i18np("1 file processed", "%1 files processed", d
->getFilesProcessed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
334 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
336 painter
->drawText(d
->getCurrentLeftMargin(textHeight
), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
338 coordY
+= d
->separatorPixels
+ textHeight
;
341 if (!d
->getSizeProcessed(index
).isEmpty() || !d
->getSpeed(index
).isEmpty())
344 if (!d
->getSizeTotals(index
).isEmpty() && !d
->getSpeed(index
).isEmpty())
345 textToShow
= fontMetrics
.elidedText(i18n("%1 of %2 processed at %3", d
->getSizeProcessed(index
), d
->getSizeTotals(index
), d
->getSpeed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
346 else if (!d
->getSizeTotals(index
).isEmpty() && d
->getSpeed(index
).isEmpty())
347 textToShow
= fontMetrics
.elidedText(i18n("%1 of %2 processed", d
->getSizeProcessed(index
), d
->getSizeTotals(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
348 else if (d
->getSizeTotals(index
).isEmpty() && !d
->getSpeed(index
).isEmpty())
349 textToShow
= fontMetrics
.elidedText(i18n("%1 processed at %2", d
->getSizeProcessed(index
), d
->getSpeed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
351 textToShow
= fontMetrics
.elidedText(i18n("%1 processed", d
->getSizeProcessed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
353 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
355 painter
->drawText(d
->getCurrentLeftMargin(textHeight
), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
357 coordY
+= d
->separatorPixels
+ textHeight
;
360 if (d
->getPercent(index
) > -1)
362 QStyleOptionProgressBarV2
*progressBarModel
= d
->getProgressBar(index
);
364 progressBarModel
->rect
= QRect(d
->getCurrentLeftMargin(textHeight
), coordY
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
- iconWidth
- d
->separatorPixels
, d
->progressBarHeight
);
366 QApplication::style()->drawControl(QStyle::CE_ProgressBar
, progressBarModel
, painter
);
371 painter
->setClipping(true); // workaround for qt bug
374 QSize
ProgressListDelegate::sizeHint(const QStyleOptionViewItem
&option
, const QModelIndex
&index
) const
376 QFontMetrics fontMetrics
= option
.fontMetrics
;
378 int itemHeight
= d
->separatorPixels
;
379 int itemWidth
= qMax(option
.rect
.width(), d
->minimumContentWidth
);
381 int textSize
= fontMetrics
.height() + d
->separatorPixels
;
383 if (!d
->getMessage(index
).isEmpty())
385 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getMessage(index
)).height() + d
->separatorPixels
;
386 itemHeight
+= textSize
;
389 if (!d
->getProgressMessage(index
).isEmpty())
391 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getProgressMessage(index
)).height() + d
->separatorPixels
;
392 itemHeight
+= textSize
;
395 if (!d
->getFrom(index
).isEmpty())
397 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getFrom(index
)).height() + d
->separatorPixels
;
398 itemHeight
+= textSize
;
401 if (!d
->getTo(index
).isEmpty())
403 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getTo(index
)).height() + d
->separatorPixels
;
404 itemHeight
+= textSize
;
407 if (d
->getFilesProcessed(index
) > 1)
409 textSize
= fontMetrics
.size(Qt::TextSingleLine
, QString::number(d
->getFilesProcessed(index
))).height() + d
->separatorPixels
;
410 itemHeight
+= textSize
;
413 if (!d
->getSizeProcessed(index
).isEmpty())
415 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getSizeProcessed(index
)).height() + d
->separatorPixels
;
416 itemHeight
+= textSize
;
419 if (d
->getPercent(index
) > -1)
420 itemHeight
+= d
->progressBarHeight
+ d
->separatorPixels
;
422 if (d
->editorHeight
> 0)
423 itemHeight
+= d
->editorHeight
+ d
->separatorPixels
;
425 if (itemHeight
+ d
->separatorPixels
>= d
->minimumItemHeight
)
426 itemHeight
+= d
->separatorPixels
;
428 itemHeight
= d
->minimumItemHeight
;
430 return QSize(itemWidth
, itemHeight
);
433 void ProgressListDelegate::updateEditorGeometry(QWidget
*editor
, const QStyleOptionViewItem
&option
,
434 const QModelIndex
&index
) const
438 QRect
editorRect(d
->getCurrentLeftMargin(option
.fontMetrics
.height()), option
.rect
.height() - d
->separatorPixels
- d
->editorHeight
+ option
.rect
.top(), option
.rect
.width() - d
->getCurrentLeftMargin(option
.fontMetrics
.height()) - d
->rightMargin
- d
->separatorPixels
- d
->iconWidth
, d
->editorHeight
);
440 editor
->setGeometry(editorRect
);
443 void ProgressListDelegate::setSeparatorPixels(int separatorPixels
)
445 d
->separatorPixels
= separatorPixels
;
448 void ProgressListDelegate::setLeftMargin(int leftMargin
)
450 d
->leftMargin
= leftMargin
;
453 void ProgressListDelegate::setRightMargin(int rightMargin
)
455 d
->rightMargin
= rightMargin
;
458 void ProgressListDelegate::setProgressBarHeight(int progressBarHeight
)
460 d
->progressBarHeight
= progressBarHeight
;
463 void ProgressListDelegate::setMinimumItemHeight(int minimumItemHeight
)
465 d
->minimumItemHeight
= minimumItemHeight
;
468 void ProgressListDelegate::setMinimumContentWidth(int minimumContentWidth
)
470 d
->minimumContentWidth
= minimumContentWidth
;
473 void ProgressListDelegate::setEditorHeight(int editorHeight
)
475 d
->editorHeight
= editorHeight
;
478 #include "progresslistdelegate.moc"
479 #include "progresslistdelegate_p.moc"