Make a branch to make krunner Good Enough For Aaron™.
[kdebase/uwolfer.git] / runtime / kuiserver / progresslistdelegate.cpp
blobf6913d80bda06634d0d2d86093ce7b6a9ad84758
1 /**
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>
26 #include <QPainter>
27 #include <QStyleOptionProgressBarV2>
28 #include <QHash>
29 #include <QFontMetrics>
30 #include <QListView>
31 #include <QHBoxLayout>
33 #include <kdebug.h>
34 #include <kicon.h>
35 #include <klocale.h>
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;
167 this->jobId = jobId;
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()
186 delete d;
189 QWidget *ProgressListDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const
191 Q_UNUSED(option);
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())
200 return 0;
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;
209 int i = 0;
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);
222 i++;
225 return returnWidget;
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);
254 else
256 painter->setPen(unselectedPen);
259 painter->save();
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)
328 QString textToShow;
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);
331 else
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())
343 QString textToShow;
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);
350 else
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);
369 painter->restore();
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;
427 else
428 itemHeight = d->minimumItemHeight;
430 return QSize(itemWidth, itemHeight);
433 void ProgressListDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option,
434 const QModelIndex &index) const
436 Q_UNUSED(index);
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"