add more spacing
[personal-kdebase.git] / runtime / kuiserver / progresslistdelegate.cpp
blob0f52a23895abd20f382cd8b0e627057f7602abac
1 /**
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>
26 #include <QPainter>
27 #include <QHash>
28 #include <QFontMetrics>
29 #include <QListView>
30 #include <QHBoxLayout>
31 #include <QProgressBar>
33 #include <kdebug.h>
34 #include <kicon.h>
35 #include <klocale.h>
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()
98 delete d;
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()) {
106 return;
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);
130 else
132 painter->setPen(unselectedPen);
135 painter->save();
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())
171 QString textToShow;
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);
178 else
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;
188 painter->restore();
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;
225 else
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;
279 return widgetList;
282 void ProgressListDelegate::updateItemWidgets(const QList<QWidget*> widgets,
283 const QStyleOptionViewItem &option,
284 const QPersistentModelIndex &index) const
286 if (!index.isValid()) {
287 return;
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();
299 switch (state) {
300 case JobInfo::Running:
301 pauseResumeButton->setText(i18n("Pause"));
302 pauseResumeButton->setIcon(KIcon("media-playback-pause"));
303 break;
304 case JobInfo::Suspended:
305 pauseResumeButton->setText(i18n("Resume"));
306 pauseResumeButton->setIcon(KIcon("media-playback-start"));
307 break;
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();
331 if (jobView) {
332 switch (state) {
333 case JobInfo::Running:
334 emit jobView->suspendRequested();
335 break;
336 case JobInfo::Suspended:
337 emit jobView->resumeRequested();
338 break;
339 default:
340 Q_ASSERT(0); // this point should have never been reached
341 break;
346 void ProgressListDelegate::slotCancelClicked()
348 const QModelIndex index = focusedIndex();
349 UIServer::JobView *jobView = index.model()->data(index, ProgressListModel::JobViewRole).value<UIServer::JobView*>();
350 if (jobView) {
351 emit jobView->cancelRequested();
355 #include "progresslistdelegate.moc"