2 * This file is part of the KDE project
3 * Copyright (C) 2006-2008 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>
28 #include <QFontMetrics>
30 #include <QHBoxLayout>
31 #include <QProgressBar>
36 #include <kpushbutton.h>
38 #define MIN_CONTENT_PIXELS 50
40 QString
ProgressListDelegate::Private::getApplicationName(const QModelIndex
&index
) const
42 return index
.model()->data(index
, ProgressListModel::ApplicationName
).toString();
45 QString
ProgressListDelegate::Private::getIcon(const QModelIndex
&index
) const
47 return index
.model()->data(index
, ProgressListModel::Icon
).toString();
50 QString
ProgressListDelegate::Private::getSizeTotals(const QModelIndex
&index
) const
52 return index
.model()->data(index
, ProgressListModel::SizeTotals
).toString();
55 QString
ProgressListDelegate::Private::getSizeProcessed(const QModelIndex
&index
) const
57 return index
.model()->data(index
, ProgressListModel::SizeProcessed
).toString();
60 qlonglong
ProgressListDelegate::Private::getTimeTotals(const QModelIndex
&index
) const
62 return index
.model()->data(index
, ProgressListModel::TimeTotals
).toLongLong();
65 qlonglong
ProgressListDelegate::Private::getTimeProcessed(const QModelIndex
&index
) const
67 return index
.model()->data(index
, ProgressListModel::TimeElapsed
).toLongLong();
70 QString
ProgressListDelegate::Private::getSpeed(const QModelIndex
&index
) const
72 return index
.model()->data(index
, ProgressListModel::Speed
).toString();
75 int ProgressListDelegate::Private::getPercent(const QModelIndex
&index
) const
77 return index
.model()->data(index
, ProgressListModel::Percent
).toInt();
80 QString
ProgressListDelegate::Private::getMessage(const QModelIndex
&index
) const
82 return index
.model()->data(index
, ProgressListModel::Message
).toString();
85 int ProgressListDelegate::Private::getCurrentLeftMargin(int fontHeight
) const
87 return leftMargin
+ separatorPixels
+ fontHeight
;
90 ProgressListDelegate::ProgressListDelegate(QObject
*parent
, QListView
*listView
)
91 : KWidgetItemDelegate(listView
, parent
)
92 , d(new Private(listView
))
96 ProgressListDelegate::~ProgressListDelegate()
101 void ProgressListDelegate::paint(QPainter
*painter
, const QStyleOptionViewItem
&option
, const QModelIndex
&index
) const
103 QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem
, &option
, painter
, 0);
105 if (!index
.isValid()) {
109 QFontMetrics fontMetrics
= painter
->fontMetrics();
110 int textHeight
= fontMetrics
.height();
112 int coordY
= d
->separatorPixels
+ option
.rect
.top();
114 KIcon
iconToShow(d
->getIcon(index
));
116 QColor unselectedTextColor
= option
.palette
.text().color();
117 QColor selectedTextColor
= option
.palette
.highlightedText().color();
118 QPen currentPen
= painter
->pen();
119 QPen unselectedPen
= QPen(currentPen
);
120 QPen selectedPen
= QPen(currentPen
);
122 unselectedPen
.setColor(unselectedTextColor
);
123 selectedPen
.setColor(selectedTextColor
);
125 if (option
.state
& QStyle::State_Selected
)
127 painter
->fillRect(option
.rect
, option
.palette
.highlight());
128 painter
->setPen(selectedPen
);
132 painter
->setPen(unselectedPen
);
136 painter
->setRenderHint(QPainter::Antialiasing
, true);
138 QRect canvas
= option
.rect
;
139 int iconWidth
= canvas
.height() - d
->leftMargin
- d
->rightMargin
;
140 int iconHeight
= iconWidth
;
141 d
->iconWidth
= iconWidth
;
143 painter
->setOpacity(0.25);
145 painter
->drawPixmap(option
.rect
.right() - iconWidth
- d
->rightMargin
, coordY
, iconToShow
.pixmap(iconWidth
, iconHeight
));
147 painter
->translate(d
->leftMargin
+ option
.rect
.left(), d
->separatorPixels
+ qMin(fontMetrics
.width(d
->getApplicationName(index
)) / 2, (option
.rect
.height() / 2) - d
->separatorPixels
) + (iconHeight
/ 2) + canvas
.top());
148 painter
->rotate(270);
150 QRect
appNameRect(0, 0, qMin(fontMetrics
.width(d
->getApplicationName(index
)), option
.rect
.height() - d
->separatorPixels
* 2), textHeight
);
152 painter
->drawText(appNameRect
, Qt::AlignLeft
, fontMetrics
.elidedText(d
->getApplicationName(index
), Qt::ElideRight
, option
.rect
.height() - d
->separatorPixels
* 2));
154 painter
->resetMatrix();
156 painter
->setOpacity(1);
158 if (!d
->getMessage(index
).isEmpty())
160 QString textToShow
= fontMetrics
.elidedText(d
->getMessage(index
), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
162 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
164 painter
->drawText(d
->getCurrentLeftMargin(textHeight
) + option
.rect
.left(), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
166 coordY
+= textHeight
;
169 if (!d
->getSizeProcessed(index
).isEmpty() || !d
->getSizeTotals(index
).isEmpty() || !d
->getSpeed(index
).isEmpty())
172 if (!d
->getSizeTotals(index
).isEmpty() && !d
->getSpeed(index
).isEmpty())
173 textToShow
= fontMetrics
.elidedText(i18n("%1 of %2 processed at %3/s", d
->getSizeProcessed(index
), d
->getSizeTotals(index
), d
->getSpeed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
174 else if (!d
->getSizeTotals(index
).isEmpty() && d
->getSpeed(index
).isEmpty())
175 textToShow
= fontMetrics
.elidedText(i18n("%1 of %2 processed", d
->getSizeProcessed(index
), d
->getSizeTotals(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
176 else if (d
->getSizeTotals(index
).isEmpty() && !d
->getSpeed(index
).isEmpty())
177 textToShow
= fontMetrics
.elidedText(i18n("%1 processed at %2/s", d
->getSizeProcessed(index
), d
->getSpeed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
179 textToShow
= fontMetrics
.elidedText(i18n("%1 processed", d
->getSizeProcessed(index
)), Qt::ElideRight
, canvas
.width() - d
->getCurrentLeftMargin(textHeight
) - d
->rightMargin
);
181 textHeight
= fontMetrics
.size(Qt::TextSingleLine
, textToShow
).height();
183 painter
->drawText(d
->getCurrentLeftMargin(textHeight
) + option
.rect
.left(), coordY
, fontMetrics
.width(textToShow
), textHeight
, Qt::AlignLeft
, textToShow
);
185 coordY
+= textHeight
;
190 KWidgetItemDelegate::paintWidgets(painter
, option
, index
);
193 QSize
ProgressListDelegate::sizeHint(const QStyleOptionViewItem
&option
, const QModelIndex
&index
) const
195 QFontMetrics fontMetrics
= option
.fontMetrics
;
197 int itemHeight
= d
->separatorPixels
;
198 int itemWidth
= d
->leftMargin
+ d
->rightMargin
+ d
->iconWidth
+ d
->separatorPixels
* 2 +
199 fontMetrics
.height();
201 int textSize
= fontMetrics
.height();
203 if (!d
->getMessage(index
).isEmpty())
205 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getMessage(index
)).height();
206 itemHeight
+= textSize
;
209 if (!d
->getSizeProcessed(index
).isEmpty() || !d
->getSpeed(index
).isEmpty() ||
210 !d
->getSizeTotals(index
).isEmpty())
212 textSize
= fontMetrics
.size(Qt::TextSingleLine
, d
->getSizeProcessed(index
)).height();
213 itemHeight
+= textSize
;
216 if (d
->getPercent(index
)) {
217 itemHeight
+= d
->progressBar
->sizeHint().height();
220 if (d
->editorHeight
> 0)
221 itemHeight
+= d
->editorHeight
;
223 if (itemHeight
+ d
->separatorPixels
>= d
->minimumItemHeight
)
224 itemHeight
+= d
->separatorPixels
;
226 itemHeight
= d
->minimumItemHeight
;
228 return QSize(itemWidth
+ MIN_CONTENT_PIXELS
, itemHeight
);
231 void ProgressListDelegate::setSeparatorPixels(int separatorPixels
)
233 d
->separatorPixels
= separatorPixels
;
236 void ProgressListDelegate::setLeftMargin(int leftMargin
)
238 d
->leftMargin
= leftMargin
;
241 void ProgressListDelegate::setRightMargin(int rightMargin
)
243 d
->rightMargin
= rightMargin
;
246 void ProgressListDelegate::setMinimumItemHeight(int minimumItemHeight
)
248 d
->minimumItemHeight
= minimumItemHeight
;
251 void ProgressListDelegate::setMinimumContentWidth(int minimumContentWidth
)
253 d
->minimumContentWidth
= minimumContentWidth
;
256 void ProgressListDelegate::setEditorHeight(int editorHeight
)
258 d
->editorHeight
= editorHeight
;
261 QList
<QWidget
*> ProgressListDelegate::createItemWidgets() const
263 QList
<QWidget
*> widgetList
;
265 KPushButton
*pauseResumeButton
= new KPushButton(KIcon("media-playback-pause"), i18n("Pause"));
266 KPushButton
*cancelButton
= new KPushButton(KIcon("media-playback-stop"), i18n("Cancel"));
267 QProgressBar
*progressBar
= new QProgressBar();
269 connect(pauseResumeButton
, SIGNAL(clicked(bool)), this, SLOT(slotPauseResumeClicked()));
270 connect(cancelButton
, SIGNAL(clicked(bool)), this, SLOT(slotCancelClicked()));
272 setBlockedEventTypes(pauseResumeButton
, QList
<QEvent::Type
>() << QEvent::MouseButtonPress
273 << QEvent::MouseButtonRelease
<< QEvent::MouseButtonDblClick
);
274 setBlockedEventTypes(cancelButton
, QList
<QEvent::Type
>() << QEvent::MouseButtonPress
275 << QEvent::MouseButtonRelease
<< QEvent::MouseButtonDblClick
);
277 widgetList
<< pauseResumeButton
<< cancelButton
<< progressBar
;
282 void ProgressListDelegate::updateItemWidgets(const QList
<QWidget
*> widgets
,
283 const QStyleOptionViewItem
&option
,
284 const QPersistentModelIndex
&index
) const
286 if (!index
.isValid()) {
290 KPushButton
*cancelButton
= static_cast<KPushButton
*>(widgets
[1]);
291 KPushButton
*pauseResumeButton
= static_cast<KPushButton
*>(widgets
[0]);
292 QProgressBar
*progressBar
= static_cast<QProgressBar
*>(widgets
[2]);
294 KJob::Capabilities capabilities
= (KJob::Capabilities
) index
.model()->data(index
, ProgressListModel::Capabilities
).toInt();
295 cancelButton
->setEnabled(capabilities
& KJob::Killable
);
296 pauseResumeButton
->setEnabled(capabilities
& KJob::Suspendable
);
298 JobInfo::State state
= (JobInfo::State
) index
.model()->data(index
, ProgressListModel::State
).toInt();
300 case JobInfo::Running
:
301 pauseResumeButton
->setText(i18n("Pause"));
302 pauseResumeButton
->setIcon(KIcon("media-playback-pause"));
304 case JobInfo::Suspended
:
305 pauseResumeButton
->setText(i18n("Resume"));
306 pauseResumeButton
->setIcon(KIcon("media-playback-start"));
310 progressBar
->setValue(d
->getPercent(index
));
312 QSize cancelButtonSizeHint
= cancelButton
->sizeHint();
313 cancelButton
->resize(cancelButtonSizeHint
);
314 cancelButton
->move(option
.rect
.width() - d
->separatorPixels
- cancelButtonSizeHint
.width(), option
.rect
.height() - d
->separatorPixels
- cancelButtonSizeHint
.height());
316 QSize pauseResumeButtonSizeHint
= pauseResumeButton
->sizeHint();
317 pauseResumeButton
->resize(pauseResumeButtonSizeHint
);
318 pauseResumeButton
->move(option
.rect
.width() - d
->separatorPixels
* 2 - pauseResumeButtonSizeHint
.width() - cancelButtonSizeHint
.width(), option
.rect
.height() - d
->separatorPixels
- pauseResumeButtonSizeHint
.height());
320 QFontMetrics
fm(QApplication::font());
321 QSize progressBarSizeHint
= progressBar
->sizeHint();
322 progressBar
->resize(QSize(option
.rect
.width() - d
->getCurrentLeftMargin(fm
.height()) - d
->rightMargin
, progressBarSizeHint
.height()));
323 progressBar
->move(d
->getCurrentLeftMargin(fm
.height()), option
.rect
.height() - d
->separatorPixels
* 2 - pauseResumeButtonSizeHint
.height() - progressBarSizeHint
.height());
326 void ProgressListDelegate::slotPauseResumeClicked()
328 const QModelIndex index
= focusedIndex();
329 UIServer::JobView
*jobView
= index
.model()->data(index
, ProgressListModel::JobViewRole
).value
<UIServer::JobView
*>();
330 JobInfo::State state
= (JobInfo::State
) index
.model()->data(index
, ProgressListModel::State
).toInt();
333 case JobInfo::Running
:
334 emit jobView
->suspendRequested();
336 case JobInfo::Suspended
:
337 emit jobView
->resumeRequested();
340 Q_ASSERT(0); // this point should have never been reached
346 void ProgressListDelegate::slotCancelClicked()
348 const QModelIndex index
= focusedIndex();
349 UIServer::JobView
*jobView
= index
.model()->data(index
, ProgressListModel::JobViewRole
).value
<UIServer::JobView
*>();
351 emit jobView
->cancelRequested();
355 #include "progresslistdelegate.moc"