Show invite menu in wlm chat window immediately
[kdenetwork.git] / kget / ui / transfersviewdelegate.cpp
blob463784a7a21a06a00428ea9053c0e7e68de721c5
1 /* This file is part of the KDE project
3 Copyright (C) 2006 Dario Massarin <nekkar@libero.it>
4 Copyright (C) 2007 by Javier Goday <jgoday@gmail.com>
5 Copyright (C) 2008 Lukas Appelhans <l.appelhans@gmx.de>
7 This program is free software; you can redistribute it and/or
8 modify it under the terms of the GNU General Public
9 License as published by the Free Software Foundation; either
10 version 2 of the License, or (at your option) any later version.
13 #include "ui/transfersviewdelegate.h"
15 #include "transferdetails.h"
16 #include "ui/contextmenu.h"
17 #include "core/kget.h"
18 #include "core/observer.h"
19 #include "core/transferhandler.h"
20 #include "core/transfergrouphandler.h"
21 #include "core/transfertreemodel.h"
22 #include "core/transfertreeselectionmodel.h"
23 #include "settings.h"
25 #include <kdebug.h>
26 #include <klocale.h>
27 #include <kmenu.h>
28 #include <kicon.h>
30 #include <QApplication>
31 #include <QPainter>
32 #include <QMouseEvent>
33 #include <QModelIndex>
34 #include <QButtonGroup>
35 #include <QHBoxLayout>
36 #include <QGroupBox>
37 #include <QLabel>
38 #include <QAbstractItemView>
40 GroupStatusButton::GroupStatusButton(const QModelIndex & index, QWidget * parent)
41 : QToolButton(parent),
42 m_status(None),
43 m_index(index),
44 m_timerId(-1),
45 m_iconSize(22),
46 m_gradientId(0)
48 setAttribute(Qt::WA_NoSystemBackground);
51 void GroupStatusButton::checkStateSet()
53 // kDebug(5001) << "GroupStatusButton::checkStateSet";
55 QToolButton::checkStateSet();
57 if(isChecked())
59 if(m_status == None)
60 m_gradientId = 0.9;
61 m_status = Selecting;
63 else
65 if(m_status == None)
66 m_gradientId = 1;
67 m_status = Deselecting;
70 setMouseTracking(!isChecked());
72 if(m_timerId == -1)
73 m_timerId = startTimer(100);
76 void GroupStatusButton::enterEvent(QEvent * event)
78 Q_UNUSED(event);
79 if(!isChecked())
81 m_status = Blinking;
83 if(m_timerId == -1)
85 m_timerId = startTimer(100);
87 if(m_status == !BlinkingExiting)
88 m_gradientId = 1;
93 void GroupStatusButton::leaveEvent(QEvent * event)
95 Q_UNUSED(event);
96 if(m_status == Blinking)
97 m_status = BlinkingExiting;
100 void GroupStatusButton::paintEvent(QPaintEvent * event)
102 Q_UNUSED(event);
104 QPainter p(this);
106 int offset = (event->rect().width() - m_iconSize) / 2;
108 if(m_gradientId == 0)
109 m_gradientId = isChecked() ? 1 : 0.7;
111 QRadialGradient gradient(event->rect().topLeft() + QPoint(event->rect().width() / 2, event->rect().height() / 2), event->rect().width() / 2);
113 QPen pen;
115 if(KGet::selectionModel()->isSelected(m_index))
117 gradient.setColorAt(0, palette().color(QPalette::AlternateBase));
118 gradient.setColorAt(m_gradientId, Qt::transparent);
119 gradient.setColorAt(1, Qt::transparent);
120 pen.setColor(palette().color(QPalette::AlternateBase));
122 else
124 gradient.setColorAt(0, palette().color(QPalette::Highlight));
125 gradient.setColorAt(m_gradientId, Qt::transparent);
126 gradient.setColorAt(1, Qt::transparent);
127 pen.setColor(palette().color(QPalette::Highlight));
130 QRect r = event->rect().adjusted(0,0,0,1);
132 p.fillRect(r, gradient);
134 p.setRenderHint(QPainter::Antialiasing);
136 if(isChecked())
138 pen.setWidth(1);
139 p.setPen(pen);
140 p.drawEllipse(event->rect().x()+5, event->rect().y()+4, event->rect().width()-10, event->rect().width()-10);
143 p.drawPixmap(event->rect().topLeft() + QPoint(offset, offset-1),
144 icon().pixmap(m_iconSize, isChecked() || m_status == Blinking ?
145 QIcon::Normal : QIcon::Disabled));
148 void GroupStatusButton::timerEvent(QTimerEvent *event)
150 Q_UNUSED(event);
152 if(m_status == Selecting)
154 m_gradientId+=0.04;
156 if(m_gradientId >= 1)
158 m_status = None;
159 m_gradientId = 1;
160 killTimer(m_timerId);
161 m_timerId = -1;
164 else if(m_status == Deselecting)
166 m_gradientId-=0.04;
168 if(m_gradientId <= 0.7)
170 m_status = None;
171 m_gradientId = 0.7;
172 killTimer(m_timerId);
173 m_timerId = -1;
176 else if(m_status == Blinking)
178 if(isChecked())
180 m_status = Selecting;
181 m_gradientId = 0.9;
182 return;
185 m_gradientId-=0.04;
187 if(m_gradientId <= 0.7)
189 m_gradientId = 1;
192 else if(m_status == BlinkingExiting)
194 m_gradientId-=0.04;
196 if(m_gradientId <= 0.7)
198 m_status = None;
199 m_gradientId = 0.7;
200 killTimer(m_timerId);
201 m_timerId = -1;
205 update();
208 GroupStatusEditor::GroupStatusEditor(const QModelIndex & index, const TransfersViewDelegate * delegate, QWidget * parent)
209 : QWidget(parent),
210 m_delegate(delegate),
211 m_index(index)
213 setMinimumWidth(80);
215 m_layout = new QHBoxLayout();
216 m_layout->addStretch();
217 setLayout(m_layout);
219 m_btGroup = new QButtonGroup(this);
220 m_btGroup->setExclusive(true);
222 m_startBt = new GroupStatusButton(m_index, this);
223 m_startBt->setCheckable(true);
224 m_startBt->setAutoRaise(true);
225 m_startBt->setIcon(KIcon("media-playback-start"));
226 m_startBt->setFixedSize(36, 36);
227 m_startBt->setIconSize(QSize(22, 22));
228 m_startBt->installEventFilter(const_cast<TransfersViewDelegate *>(delegate));
229 m_layout->addWidget(m_startBt);
230 m_btGroup->addButton(m_startBt);
232 m_stopBt = new GroupStatusButton(m_index, this);
233 m_stopBt->setCheckable(true);
234 m_stopBt->setAutoRaise(true);
235 m_stopBt->setIcon(KIcon("media-playback-pause"));
236 m_stopBt->setFixedSize(36, 36);
237 m_stopBt->setIconSize(QSize(22, 22));
238 m_stopBt->installEventFilter(const_cast<TransfersViewDelegate *>(delegate));
239 m_layout->addWidget(m_stopBt);
240 m_btGroup->addButton(m_stopBt);
242 m_stopBt->setChecked(true);
244 m_layout->addStretch();
245 m_layout->setMargin(1);
247 connect(m_startBt, SIGNAL(toggled(bool)),
248 this, SLOT(slotStatusChanged(bool)));
251 void GroupStatusEditor::setRunning(bool running)
253 if(running == m_startBt->isChecked())
254 return;
256 if(running)
257 m_startBt->setChecked(true);
258 else
259 m_stopBt->setChecked(true);
262 bool GroupStatusEditor::isRunning()
264 return m_startBt->isChecked();
267 void GroupStatusEditor::slotStatusChanged(bool running)
269 Q_UNUSED(running);
271 emit const_cast<TransfersViewDelegate *>(m_delegate)->commitData(this);
274 TransfersViewDelegate::TransfersViewDelegate(QAbstractItemView *parent)
275 : KExtendableItemDelegate(parent)
277 Q_ASSERT(qobject_cast<QAbstractItemView *>(parent));
278 setExtendPixmap(SmallIcon("arrow-right"));
279 setContractPixmap(SmallIcon("arrow-down"));
280 connect(parent, SIGNAL(activated(QModelIndex)), this, SLOT(itemActivated(QModelIndex)));
283 void TransfersViewDelegate::paint(QPainter * painter, const QStyleOptionViewItem & option, const QModelIndex & index) const
285 const TransferTreeModel * transferTreeModel = static_cast<const TransferTreeModel *>(index.model());
287 if(transferTreeModel->isTransferGroup(index))
289 painter->save();
291 if (option.state & QStyle::State_Selected)
294 else
296 static bool backgroundInitialized = false;
297 static QPixmap groupBackground(64, 35);
298 static QPalette palette(QApplication::palette());
300 if(!backgroundInitialized || palette!= QApplication::palette())
302 const QRect rect = groupBackground.rect();
303 QPainter p(&groupBackground);
305 QLinearGradient gradient(rect.x(), rect.y(),
306 rect.x(), (rect.y() + rect.height()));
308 gradient.setColorAt(0, QApplication::palette().color(QPalette::Base));
309 gradient.setColorAt(0.5, QApplication::palette().color(QPalette::AlternateBase).darker(110));
310 gradient.setColorAt(1, QApplication::palette().color(QPalette::Base));
312 p.fillRect(rect, gradient);
313 backgroundInitialized = true;
316 painter->drawTiledPixmap(option.rect, groupBackground);
319 KExtendableItemDelegate::paint(painter, option, index);
321 painter->restore();
323 else {
324 if (KGet::selectionModel()->isSelected(index))
325 painter->fillRect(option.rect, QApplication::palette().color(option.state & QStyle::State_Active ?
326 QPalette::Active : QPalette::Inactive,
327 QPalette::Highlight));
329 KExtendableItemDelegate::paint(painter, option, index);
331 if (index.column() == 3 && !isExtended(transferTreeModel->index(index.row(), 0, index.parent()))) { // the percent column
332 TransferHandler *transferHandler = static_cast<TransferHandler *>(index.internalPointer());
334 // following progressbar code has mostly been taken from Qt4 examples/network/torrent/mainview.cpp
335 // Set up a QStyleOptionProgressBar to precisely mimic the
336 // environment of a progress bar.
337 QStyleOptionProgressBar progressBarOption;
338 progressBarOption.state = QStyle::State_Enabled;
339 progressBarOption.direction = QApplication::layoutDirection();
340 progressBarOption.rect = option.rect;
341 progressBarOption.fontMetrics = QApplication::fontMetrics();
342 progressBarOption.minimum = 0;
343 progressBarOption.maximum = 100;
344 progressBarOption.textAlignment = Qt::AlignCenter;
345 progressBarOption.textVisible = true;
347 // Set the progress and text values of the style option.
348 int progress = transferHandler->percent();
349 if (progress >= 0 && progress <= 100) {
350 progressBarOption.progress = progress;
351 progressBarOption.text = QString().sprintf("%d%%", progressBarOption.progress);
352 } else {
353 progressBarOption.text = i18nc("not available", "n/a");
356 progressBarOption.rect.setY(progressBarOption.rect.y() +
357 (option.rect.height() - QApplication::fontMetrics().height()) / 2);
358 progressBarOption.rect.setHeight(QApplication::fontMetrics().height());
360 // Draw the progress bar onto the view.
361 QApplication::style()->drawControl(QStyle::CE_ProgressBar, &progressBarOption, painter);
365 /// These lines are just for testing purposes. Uncomment them to show on the view the repaint events.
366 // static int i=0;
367 // kDebug(5001) << "paint!!! " << i++ << " " << index.internalPointer() << " " << index.column();
369 // painter->drawRect(option.rect);
370 // painter->drawText(option.rect.topLeft(), QString::number(i));
373 void TransfersViewDelegate::drawFocus(QPainter * painter, const QStyleOptionViewItem & option, const
374 QRect & rect) const
376 Q_UNUSED(painter);
377 Q_UNUSED(option);
378 Q_UNUSED(rect);
381 QSize TransfersViewDelegate::sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const
383 Q_UNUSED(option);
385 const TransferTreeModel * transferTreeModel = static_cast<const TransferTreeModel *>(index.model());
387 if(transferTreeModel->isTransferGroup(index))
389 return QSize(0, 35);
391 else {
392 QSize ret(KExtendableItemDelegate::sizeHint(option, index));
393 ret.rheight() += 8;
394 return ret;
398 QWidget * TransfersViewDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem & option , const QModelIndex & index) const
400 Q_UNUSED(option);
401 Q_UNUSED(index);
403 GroupStatusEditor * groupsStatusEditor = new GroupStatusEditor(index, this, parent);
405 return groupsStatusEditor;
408 bool TransfersViewDelegate::editorEvent(QEvent * event, QAbstractItemModel * model, const QStyleOptionViewItem & option, const QModelIndex & index)
410 Q_UNUSED(option);
412 QMouseEvent * mouseEvent = dynamic_cast<QMouseEvent *>(event);
414 if(mouseEvent)
416 if(mouseEvent->button() == Qt::RightButton)
418 // kDebug(5001) << "TransfersViewDelegate::editorEvent() -> rightClick";
420 KMenu *popup = 0;
422 TransferTreeModel * transferTreeModel = static_cast<TransferTreeModel *>(model);
424 if(transferTreeModel->isTransferGroup(index))
426 // kDebug(5001) << "isTransferGroup = true";
427 TransferGroupHandler * transferGroupHandler = static_cast<TransferGroupHandler *>(index.internalPointer());
429 popup = ContextMenu::createTransferGroupContextMenu(transferGroupHandler, qobject_cast<QWidget*>(this));
432 else
434 // kDebug(5001) << "isTransferGroup = false";
436 TransferHandler * transferHandler = static_cast<TransferHandler *>(index.internalPointer());
438 popup = ContextMenu::createTransferContextMenu(transferHandler, qobject_cast<QWidget*>(this));
441 if(popup) {
442 popup->exec(QCursor::pos());
443 popup->deleteLater();
448 return false;
451 void TransfersViewDelegate::setEditorData(QWidget * editor, const QModelIndex & index) const
453 GroupStatusEditor * groupEditor = static_cast<GroupStatusEditor *>(editor);
455 groupEditor->setRunning((static_cast<TransferGroupHandler *>(index.internalPointer())->status()) == JobQueue::Running);
458 void TransfersViewDelegate::setModelData(QWidget * editor, QAbstractItemModel * model, const QModelIndex & index) const
460 Q_UNUSED(model);
462 GroupStatusEditor * groupEditor = static_cast<GroupStatusEditor *>(editor);
464 TransferGroupHandler * groupHandler = static_cast<TransferGroupHandler *>(index.internalPointer());
466 if (groupEditor->isRunning())
467 groupHandler->start();
468 else
469 groupHandler->stop();
472 void TransfersViewDelegate::closeExpandableDetails(const QModelIndex &transferIndex)
474 if(transferIndex.isValid()) {
475 removeTransferObserver(transferIndex);
476 contractItem(transferIndex);
477 m_editingIndexes.removeAll(transferIndex);
479 else {
480 foreach(const QModelIndex &index, m_editingIndexes) {
481 removeTransferObserver(index);
482 contractItem(index);
485 m_editingIndexes.clear();
489 QWidget *TransfersViewDelegate::getDetailsWidgetForTransfer(TransferHandler *handler)
491 QGroupBox *groupBox = new QGroupBox(i18n("Transfer details"));
493 QVBoxLayout *layout = new QVBoxLayout(groupBox);
494 QWidget *detailsWidget = TransferDetails::detailsWidget(handler);
495 layout->addWidget(detailsWidget);
497 // if the details widget is a transfer observer
498 // we add into the transfers_map to delete it when
499 // the extendableitem is closed before the widget or the transfer
500 TransferObserver *observer = dynamic_cast <TransferObserver *> (detailsWidget);
501 if (observer) {
502 m_transfersMap.insert(handler, observer);
505 return groupBox;
508 void TransfersViewDelegate::itemActivated(const QModelIndex &index)
510 const TransferTreeModel * transferTreeModel = static_cast <const TransferTreeModel *> (index.model());
512 if(!transferTreeModel->isTransferGroup(index) && Settings::showExpandableTransferDetails() && index.column() == 0) {
513 if(!isExtended(index)) {
514 TransferHandler *handler = static_cast <TransferHandler *> (index.internalPointer());
515 QWidget *widget = getDetailsWidgetForTransfer(handler);
517 m_editingIndexes.append(index);
518 extendItem(widget, index);
520 else {
521 removeTransferObserver(index);
523 m_editingIndexes.removeAll(index);
524 contractItem(index);
529 void TransfersViewDelegate::removeTransferObserver(const QModelIndex &index)
531 TransferHandler *handler = static_cast <TransferHandler *> (index.internalPointer());
533 // remove the observer from the handler
534 if (m_transfersMap.contains(handler)) {
535 TransferObserver *observer = m_transfersMap.value(handler);
536 m_transfersMap.remove(handler);
537 handler->delObserver(observer);
542 #include "transfersviewdelegate.moc"