1 /* This file is part of the KDE project
3 Copyright (C) 2006 Dario Massarin <nekkar@libero.it>
4 Adapt the kshortcutdialog use of the kextendableitemdelegate in kdelibs/kdeui/dialogs/
6 This program is free software; you can redistribute it and/or
7 modify it under the terms of the GNU General Public
8 License as published by the Free Software Foundation; version 2
12 #include "ui/transfersviewdelegate.h"
14 #include "transferdetails.h"
15 #include "core/kget.h"
16 #include "core/transferhandler.h"
17 #include "core/transfergrouphandler.h"
18 #include "core/transfertreemodel.h"
19 #include "core/transfertreeselectionmodel.h"
27 #include <QApplication>
29 #include <QMouseEvent>
30 #include <QModelIndex>
31 #include <QButtonGroup>
32 #include <QHBoxLayout>
35 #include <QAbstractItemView>
37 GroupStatusButton::GroupStatusButton(const QModelIndex
& index
, QWidget
* parent
)
38 : QToolButton(parent
),
46 void GroupStatusButton::checkStateSet()
48 // kDebug(5001) << "GroupStatusButton::checkStateSet";
50 QToolButton::checkStateSet();
62 m_status
= Deselecting
;
65 setMouseTracking(!isChecked());
68 m_timerId
= startTimer(25);
71 void GroupStatusButton::enterEvent(QEvent
* event
)
80 m_timerId
= startTimer(25);
82 if(m_status
== !BlinkingExiting
)
88 void GroupStatusButton::leaveEvent(QEvent
* event
)
91 if(m_status
== Blinking
)
92 m_status
= BlinkingExiting
;
95 void GroupStatusButton::paintEvent(QPaintEvent
* event
)
101 int offset
= (event
->rect().width() - m_iconSize
) / 2;
103 if(m_gradientId
== 0)
104 m_gradientId
= isChecked() ? 1 : 0.7;
106 QRadialGradient
gradient(event
->rect().topLeft() + QPoint(event
->rect().width() / 2, event
->rect().height() / 2), event
->rect().width() / 2);
110 if(KGet::selectionModel()->isSelected(m_index
))
112 gradient
.setColorAt(0, palette().color(QPalette::AlternateBase
));
113 gradient
.setColorAt(m_gradientId
, palette().color(QPalette::Highlight
));
114 gradient
.setColorAt(1, palette().color(QPalette::Highlight
));
115 pen
.setColor(palette().color(QPalette::AlternateBase
));
119 gradient
.setColorAt(0, palette().color(QPalette::Highlight
));
120 gradient
.setColorAt(m_gradientId
, Qt::transparent
);
121 gradient
.setColorAt(1, Qt::transparent
);
122 pen
.setColor(palette().color(QPalette::Highlight
));
125 QRect r
= event
->rect();
128 p
.fillRect(r
, gradient
);
130 p
.setRenderHint(QPainter::Antialiasing
);
136 p
.drawEllipse(event
->rect().x()+5, event
->rect().y()+5, event
->rect().width()-10, event
->rect().width()-10);
139 p
.drawPixmap(event
->rect().topLeft() + QPoint(offset
, offset
),
140 icon().pixmap(m_iconSize
, isChecked() || m_status
== Blinking
?
141 QIcon::Normal
: QIcon::Disabled
));
144 void GroupStatusButton::timerEvent(QTimerEvent
*event
)
148 if(m_status
== Selecting
)
152 if(m_gradientId
>= 1)
156 killTimer(m_timerId
);
160 else if(m_status
== Deselecting
)
164 if(m_gradientId
<= 0.7)
168 killTimer(m_timerId
);
172 else if(m_status
== Blinking
)
176 if(m_gradientId
<= 0.7)
181 else if(m_status
== BlinkingExiting
)
185 if(m_gradientId
<= 0.7)
189 killTimer(m_timerId
);
197 GroupStatusEditor::GroupStatusEditor(const QModelIndex
& index
, const TransfersViewDelegate
* delegate
, QWidget
* parent
)
199 m_delegate(delegate
),
204 m_layout
= new QHBoxLayout();
205 m_layout
->addStretch();
208 m_btGroup
= new QButtonGroup(this);
209 m_btGroup
->setExclusive(true);
211 m_startBt
= new GroupStatusButton(m_index
, this);
212 m_startBt
->setCheckable(true);
213 m_startBt
->setAutoRaise(true);
214 m_startBt
->setIcon(KIcon("media-playback-start"));
215 m_startBt
->setFixedSize(36, 36);
216 m_startBt
->setIconSize(QSize(22, 22));
217 m_startBt
->installEventFilter(const_cast<TransfersViewDelegate
*>(delegate
));
218 m_layout
->addWidget(m_startBt
);
219 m_btGroup
->addButton(m_startBt
);
221 m_stopBt
= new GroupStatusButton(m_index
, this);
222 m_stopBt
->setCheckable(true);
223 m_stopBt
->setAutoRaise(true);
224 m_stopBt
->setIcon(KIcon("media-playback-pause"));
225 m_stopBt
->setFixedSize(36, 36);
226 m_stopBt
->setIconSize(QSize(22, 22));
227 m_stopBt
->installEventFilter(const_cast<TransfersViewDelegate
*>(delegate
));
228 m_layout
->addWidget(m_stopBt
);
229 m_btGroup
->addButton(m_stopBt
);
231 m_stopBt
->setChecked(true);
233 m_layout
->addStretch();
234 m_layout
->setMargin(1);
236 connect(m_startBt
, SIGNAL(toggled(bool)),
237 this, SLOT(slotStatusChanged(bool)));
240 void GroupStatusEditor::setRunning(bool running
)
243 m_startBt
->setChecked(true);
245 m_stopBt
->setChecked(true);
248 bool GroupStatusEditor::isRunning()
250 return m_startBt
->isChecked();
253 void GroupStatusEditor::slotStatusChanged(bool running
)
257 emit
const_cast<TransfersViewDelegate
*>(m_delegate
)->commitData(this);
260 TransfersViewDelegate::TransfersViewDelegate(QAbstractItemView
*parent
)
261 : KExtendableItemDelegate(parent
), m_popup(0)
263 Q_ASSERT(qobject_cast
<QAbstractItemView
*>(parent
));
264 setExtendIcon(SmallIcon("arrow-right"));
265 setContractIcon(SmallIcon("arrow-down"));
266 connect(parent
, SIGNAL(clicked(QModelIndex
)), this, SLOT(itemActivated(QModelIndex
)));
269 void TransfersViewDelegate::paint(QPainter
* painter
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
271 const TransferTreeModel
* transferTreeModel
= static_cast<const TransferTreeModel
*>(index
.model());
273 if(transferTreeModel
->isTransferGroup(index
))
277 if (option
.state
& QStyle::State_Selected
)
282 QLinearGradient
gradient(option
.rect
.x(), option
.rect
.y(),
283 option
.rect
.x(), (option
.rect
.y() + option
.rect
.height()));
284 gradient
.setColorAt(0, QApplication::palette().color(QPalette::Base
));
285 gradient
.setColorAt(0.5, QApplication::palette().color(QPalette::AlternateBase
).darker(110));
286 gradient
.setColorAt(1, QApplication::palette().color(QPalette::Base
));
288 painter
->fillRect(option
.rect
, gradient
);
291 QItemDelegate::paint(painter
, option
, index
);
296 if (KGet::selectionModel()->isSelected(index
))
297 painter
->fillRect(option
.rect
, QApplication::palette().color(option
.state
& QStyle::State_Active
?
298 QPalette::Active
: QPalette::Inactive
,
299 QPalette::Highlight
));
301 KExtendableItemDelegate::paint(painter
, option
, index
);
303 if (index
.column() == 3 && !isExtended(index
)) { // the percent column
304 TransferHandler
*transferHandler
= static_cast<TransferHandler
*>(index
.internalPointer());
306 // following progressbar code has mostly been taken from Qt4 examples/network/torrent/mainview.cpp
307 // Set up a QStyleOptionProgressBar to precisely mimic the
308 // environment of a progress bar.
309 QStyleOptionProgressBar progressBarOption
;
310 progressBarOption
.state
= QStyle::State_Enabled
;
311 progressBarOption
.direction
= QApplication::layoutDirection();
312 progressBarOption
.rect
= option
.rect
;
313 progressBarOption
.fontMetrics
= QApplication::fontMetrics();
314 progressBarOption
.minimum
= 0;
315 progressBarOption
.maximum
= 100;
316 progressBarOption
.textAlignment
= Qt::AlignCenter
;
317 progressBarOption
.textVisible
= true;
319 // Set the progress and text values of the style option.
320 int progress
= transferHandler
->percent();
321 if (progress
>= 0 && progress
<= 100) {
322 progressBarOption
.progress
= progress
;
323 progressBarOption
.text
= QString().sprintf("%d%%", progressBarOption
.progress
);
325 progressBarOption
.text
= i18nc("not available", "n/a");
328 progressBarOption
.rect
.setY(progressBarOption
.rect
.y() +
329 (option
.rect
.height() - QApplication::fontMetrics().height()) / 2);
330 progressBarOption
.rect
.setHeight(QApplication::fontMetrics().height());
332 // Draw the progress bar onto the view.
333 QApplication::style()->drawControl(QStyle::CE_ProgressBar
, &progressBarOption
, painter
);
338 void TransfersViewDelegate::drawFocus(QPainter
* painter
, const QStyleOptionViewItem
& option
, const
346 QSize
TransfersViewDelegate::sizeHint(const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
350 const TransferTreeModel
* transferTreeModel
= static_cast<const TransferTreeModel
*>(index
.model());
352 if(transferTreeModel
->isTransferGroup(index
))
357 QSize
ret(KExtendableItemDelegate::sizeHint(option
, index
));
363 QWidget
* TransfersViewDelegate::createEditor(QWidget
*parent
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
368 GroupStatusEditor
* groupsStatusEditor
= new GroupStatusEditor(index
, this, parent
);
370 return groupsStatusEditor
;
373 bool TransfersViewDelegate::editorEvent(QEvent
* event
, QAbstractItemModel
* model
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
)
377 QMouseEvent
* mouseEvent
= dynamic_cast<QMouseEvent
*>(event
);
381 if(mouseEvent
->button() == Qt::RightButton
)
383 // kDebug(5001) << "TransfersViewDelegate::editorEvent() -> rightClick";
391 TransferTreeModel
* transferTreeModel
= static_cast<TransferTreeModel
*>(model
);
393 if(transferTreeModel
->isTransferGroup(index
))
395 // kDebug(5001) << "isTransferGroup = true";
396 TransferGroupHandler
* transferGroupHandler
= static_cast<TransferGroupHandler
*>(index
.internalPointer());
398 m_popup
= transferGroupHandler
->popupMenu();
403 // kDebug(5001) << "isTransferGroup = false";
405 TransferHandler
* transferHandler
= static_cast<TransferHandler
*>(index
.internalPointer());
407 m_popup
= transferHandler
->popupMenu(KGet::selectedTransfers());
411 m_popup
->popup( mouseEvent
->globalPos() );
418 void TransfersViewDelegate::setEditorData(QWidget
* editor
, const QModelIndex
& index
) const
420 GroupStatusEditor
* groupEditor
= static_cast<GroupStatusEditor
*>(editor
);
422 groupEditor
->setRunning((static_cast<TransferGroupHandler
*>(index
.internalPointer())->status()) == JobQueue::Running
);
425 void TransfersViewDelegate::setModelData(QWidget
* editor
, QAbstractItemModel
* model
, const QModelIndex
& index
) const
429 GroupStatusEditor
* groupEditor
= static_cast<GroupStatusEditor
*>(editor
);
431 TransferGroupHandler
* groupHandler
= static_cast<TransferGroupHandler
*>(index
.internalPointer());
433 if(groupEditor
->isRunning())
434 groupHandler
->start();
436 groupHandler
->stop();
439 void TransfersViewDelegate::closeExpandableDetails(const QModelIndex
&transferIndex
)
441 if(transferIndex
.isValid()) {
442 contractItem(transferIndex
);
443 m_editingIndexes
.removeAll(transferIndex
);
446 foreach(const QModelIndex
&index
, m_editingIndexes
) {
450 m_editingIndexes
.clear();
454 QWidget
*TransfersViewDelegate::getDetailsWidgetForTransfer(TransferHandler
*handler
)
456 QGroupBox
*groupBox
= new QGroupBox();
458 QVBoxLayout
*layout
= new QVBoxLayout(groupBox
);
459 QLabel
*title
= new QLabel(i18n("Transfer details"));
461 layout
->addWidget(title
);
462 layout
->addWidget(new TransferDetails(handler
));
463 groupBox
->setAutoFillBackground(false);
464 title
->setStyleSheet(EXPANDABLE_TRANSFER_DETAILS_TITLE_STYLE
);
465 title
->setAlignment(Qt::AlignHCenter
);
466 groupBox
->setStyleSheet(EXPANDABLE_TRANSFER_DETAILS_STYLE
);
471 void TransfersViewDelegate::itemActivated(QModelIndex index
)
473 const TransferTreeModel
* transferTreeModel
= static_cast <const TransferTreeModel
*> (index
.model());
475 if(!transferTreeModel
->isTransferGroup(index
) && Settings::showExpandableTransferDetails()) {
476 if(!isExtended(index
)) {
477 TransferHandler
*handler
= static_cast <TransferHandler
*> (index
.internalPointer());
478 QWidget
*widget
= getDetailsWidgetForTransfer(handler
);
480 m_editingIndexes
.append(index
);
481 extendItem(widget
, index
);
484 m_editingIndexes
.removeAll(index
);
489 closeExpandableDetails(QModelIndex());
493 #include "transfersviewdelegate.moc"