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; either
9 version 2 of the License, or (at your option) any later version.
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
),
47 void GroupStatusButton::checkStateSet()
49 // kDebug(5001) << "GroupStatusButton::checkStateSet";
51 QToolButton::checkStateSet();
63 m_status
= Deselecting
;
66 setMouseTracking(!isChecked());
69 m_timerId
= startTimer(25);
72 void GroupStatusButton::enterEvent(QEvent
* event
)
81 m_timerId
= startTimer(25);
83 if(m_status
== !BlinkingExiting
)
89 void GroupStatusButton::leaveEvent(QEvent
* event
)
92 if(m_status
== Blinking
)
93 m_status
= BlinkingExiting
;
96 void GroupStatusButton::paintEvent(QPaintEvent
* event
)
102 int offset
= (event
->rect().width() - m_iconSize
) / 2;
104 if(m_gradientId
== 0)
105 m_gradientId
= isChecked() ? 1 : 0.7;
107 QRadialGradient
gradient(event
->rect().topLeft() + QPoint(event
->rect().width() / 2, event
->rect().height() / 2), event
->rect().width() / 2);
111 if(KGet::selectionModel()->isSelected(m_index
))
113 gradient
.setColorAt(0, palette().color(QPalette::AlternateBase
));
114 gradient
.setColorAt(m_gradientId
, palette().color(QPalette::Highlight
));
115 gradient
.setColorAt(1, palette().color(QPalette::Highlight
));
116 pen
.setColor(palette().color(QPalette::AlternateBase
));
120 gradient
.setColorAt(0, palette().color(QPalette::Highlight
));
121 gradient
.setColorAt(m_gradientId
, Qt::transparent
);
122 gradient
.setColorAt(1, Qt::transparent
);
123 pen
.setColor(palette().color(QPalette::Highlight
));
126 QRect r
= event
->rect();
129 p
.fillRect(r
, gradient
);
131 p
.setRenderHint(QPainter::Antialiasing
);
137 p
.drawEllipse(event
->rect().x()+5, event
->rect().y()+5, event
->rect().width()-10, event
->rect().width()-10);
140 p
.drawPixmap(event
->rect().topLeft() + QPoint(offset
, offset
),
141 icon().pixmap(m_iconSize
, isChecked() || m_status
== Blinking
?
142 QIcon::Normal
: QIcon::Disabled
));
145 void GroupStatusButton::timerEvent(QTimerEvent
*event
)
149 if(m_status
== Selecting
)
153 if(m_gradientId
>= 1)
157 killTimer(m_timerId
);
161 else if(m_status
== Deselecting
)
165 if(m_gradientId
<= 0.7)
169 killTimer(m_timerId
);
173 else if(m_status
== Blinking
)
177 if(m_gradientId
<= 0.7)
182 else if(m_status
== BlinkingExiting
)
186 if(m_gradientId
<= 0.7)
190 killTimer(m_timerId
);
198 GroupStatusEditor::GroupStatusEditor(const QModelIndex
& index
, const TransfersViewDelegate
* delegate
, QWidget
* parent
)
200 m_delegate(delegate
),
205 m_layout
= new QHBoxLayout();
206 m_layout
->addStretch();
209 m_btGroup
= new QButtonGroup(this);
210 m_btGroup
->setExclusive(true);
212 m_startBt
= new GroupStatusButton(m_index
, this);
213 m_startBt
->setCheckable(true);
214 m_startBt
->setAutoRaise(true);
215 m_startBt
->setIcon(KIcon("media-playback-start"));
216 m_startBt
->setFixedSize(36, 36);
217 m_startBt
->setIconSize(QSize(22, 22));
218 m_startBt
->installEventFilter(const_cast<TransfersViewDelegate
*>(delegate
));
219 m_layout
->addWidget(m_startBt
);
220 m_btGroup
->addButton(m_startBt
);
222 m_stopBt
= new GroupStatusButton(m_index
, this);
223 m_stopBt
->setCheckable(true);
224 m_stopBt
->setAutoRaise(true);
225 m_stopBt
->setIcon(KIcon("media-playback-pause"));
226 m_stopBt
->setFixedSize(36, 36);
227 m_stopBt
->setIconSize(QSize(22, 22));
228 m_stopBt
->installEventFilter(const_cast<TransfersViewDelegate
*>(delegate
));
229 m_layout
->addWidget(m_stopBt
);
230 m_btGroup
->addButton(m_stopBt
);
232 m_stopBt
->setChecked(true);
234 m_layout
->addStretch();
235 m_layout
->setMargin(1);
237 connect(m_startBt
, SIGNAL(toggled(bool)),
238 this, SLOT(slotStatusChanged(bool)));
241 void GroupStatusEditor::setRunning(bool running
)
244 m_startBt
->setChecked(true);
246 m_stopBt
->setChecked(true);
249 bool GroupStatusEditor::isRunning()
251 return m_startBt
->isChecked();
254 void GroupStatusEditor::slotStatusChanged(bool running
)
258 emit
const_cast<TransfersViewDelegate
*>(m_delegate
)->commitData(this);
261 TransfersViewDelegate::TransfersViewDelegate(QAbstractItemView
*parent
)
262 : KExtendableItemDelegate(parent
), m_popup(0)
264 Q_ASSERT(qobject_cast
<QAbstractItemView
*>(parent
));
265 setExtendIcon(SmallIcon("arrow-right"));
266 setContractIcon(SmallIcon("arrow-down"));
267 connect(parent
, SIGNAL(clicked(QModelIndex
)), this, SLOT(itemActivated(QModelIndex
)));
270 void TransfersViewDelegate::paint(QPainter
* painter
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
272 const TransferTreeModel
* transferTreeModel
= static_cast<const TransferTreeModel
*>(index
.model());
274 if(transferTreeModel
->isTransferGroup(index
))
278 if (option
.state
& QStyle::State_Selected
)
283 QLinearGradient
gradient(option
.rect
.x(), option
.rect
.y(),
284 option
.rect
.x(), (option
.rect
.y() + option
.rect
.height()));
285 gradient
.setColorAt(0, QApplication::palette().color(QPalette::Base
));
286 gradient
.setColorAt(0.5, QApplication::palette().color(QPalette::AlternateBase
).darker(110));
287 gradient
.setColorAt(1, QApplication::palette().color(QPalette::Base
));
289 painter
->fillRect(option
.rect
, gradient
);
292 QItemDelegate::paint(painter
, option
, index
);
297 if (KGet::selectionModel()->isSelected(index
))
298 painter
->fillRect(option
.rect
, QApplication::palette().color(option
.state
& QStyle::State_Active
?
299 QPalette::Active
: QPalette::Inactive
,
300 QPalette::Highlight
));
302 KExtendableItemDelegate::paint(painter
, option
, index
);
304 if (index
.column() == 3 && !isExtended(transferTreeModel
->index(index
.row(), 0, index
.parent()))) { // the percent column
305 TransferHandler
*transferHandler
= static_cast<TransferHandler
*>(index
.internalPointer());
307 // following progressbar code has mostly been taken from Qt4 examples/network/torrent/mainview.cpp
308 // Set up a QStyleOptionProgressBar to precisely mimic the
309 // environment of a progress bar.
310 QStyleOptionProgressBar progressBarOption
;
311 progressBarOption
.state
= QStyle::State_Enabled
;
312 progressBarOption
.direction
= QApplication::layoutDirection();
313 progressBarOption
.rect
= option
.rect
;
314 progressBarOption
.fontMetrics
= QApplication::fontMetrics();
315 progressBarOption
.minimum
= 0;
316 progressBarOption
.maximum
= 100;
317 progressBarOption
.textAlignment
= Qt::AlignCenter
;
318 progressBarOption
.textVisible
= true;
320 // Set the progress and text values of the style option.
321 int progress
= transferHandler
->percent();
322 if (progress
>= 0 && progress
<= 100) {
323 progressBarOption
.progress
= progress
;
324 progressBarOption
.text
= QString().sprintf("%d%%", progressBarOption
.progress
);
326 progressBarOption
.text
= i18nc("not available", "n/a");
329 progressBarOption
.rect
.setY(progressBarOption
.rect
.y() +
330 (option
.rect
.height() - QApplication::fontMetrics().height()) / 2);
331 progressBarOption
.rect
.setHeight(QApplication::fontMetrics().height());
333 // Draw the progress bar onto the view.
334 QApplication::style()->drawControl(QStyle::CE_ProgressBar
, &progressBarOption
, painter
);
339 void TransfersViewDelegate::drawFocus(QPainter
* painter
, const QStyleOptionViewItem
& option
, const
347 QSize
TransfersViewDelegate::sizeHint(const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
351 const TransferTreeModel
* transferTreeModel
= static_cast<const TransferTreeModel
*>(index
.model());
353 if(transferTreeModel
->isTransferGroup(index
))
358 QSize
ret(KExtendableItemDelegate::sizeHint(option
, index
));
364 QWidget
* TransfersViewDelegate::createEditor(QWidget
*parent
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
) const
369 GroupStatusEditor
* groupsStatusEditor
= new GroupStatusEditor(index
, this, parent
);
371 return groupsStatusEditor
;
374 bool TransfersViewDelegate::editorEvent(QEvent
* event
, QAbstractItemModel
* model
, const QStyleOptionViewItem
& option
, const QModelIndex
& index
)
378 QMouseEvent
* mouseEvent
= dynamic_cast<QMouseEvent
*>(event
);
382 if(mouseEvent
->button() == Qt::RightButton
)
384 // kDebug(5001) << "TransfersViewDelegate::editorEvent() -> rightClick";
392 TransferTreeModel
* transferTreeModel
= static_cast<TransferTreeModel
*>(model
);
394 if(transferTreeModel
->isTransferGroup(index
))
396 // kDebug(5001) << "isTransferGroup = true";
397 TransferGroupHandler
* transferGroupHandler
= static_cast<TransferGroupHandler
*>(index
.internalPointer());
399 m_popup
= transferGroupHandler
->popupMenu();
404 // kDebug(5001) << "isTransferGroup = false";
406 TransferHandler
* transferHandler
= static_cast<TransferHandler
*>(index
.internalPointer());
408 m_popup
= transferHandler
->popupMenu(KGet::selectedTransfers());
412 m_popup
->popup( mouseEvent
->globalPos() );
419 void TransfersViewDelegate::setEditorData(QWidget
* editor
, const QModelIndex
& index
) const
421 GroupStatusEditor
* groupEditor
= static_cast<GroupStatusEditor
*>(editor
);
423 groupEditor
->setRunning((static_cast<TransferGroupHandler
*>(index
.internalPointer())->status()) == JobQueue::Running
);
426 void TransfersViewDelegate::setModelData(QWidget
* editor
, QAbstractItemModel
* model
, const QModelIndex
& index
) const
430 GroupStatusEditor
* groupEditor
= static_cast<GroupStatusEditor
*>(editor
);
432 TransferGroupHandler
* groupHandler
= static_cast<TransferGroupHandler
*>(index
.internalPointer());
434 if (groupEditor
->isRunning())
435 groupHandler
->start();
437 groupHandler
->stop();
439 bool downloading
= false;
440 foreach (TransferHandler
*transfer
, groupHandler
->transfers())
442 if (transfer
->status() == Job::Running
)
446 KGet::setTrayDownloading(true);
449 void TransfersViewDelegate::closeExpandableDetails(const QModelIndex
&transferIndex
)
451 if(transferIndex
.isValid()) {
452 contractItem(transferIndex
);
453 m_editingIndexes
.removeAll(transferIndex
);
456 foreach(const QModelIndex
&index
, m_editingIndexes
) {
460 m_editingIndexes
.clear();
464 QWidget
*TransfersViewDelegate::getDetailsWidgetForTransfer(TransferHandler
*handler
)
466 QGroupBox
*groupBox
= new QGroupBox();
468 QVBoxLayout
*layout
= new QVBoxLayout(groupBox
);
469 QLabel
*title
= new QLabel(i18n("Transfer details"));
471 layout
->addWidget(title
);
472 layout
->addWidget(new TransferDetails(handler
));
473 groupBox
->setAutoFillBackground(false);
474 title
->setStyleSheet(EXPANDABLE_TRANSFER_DETAILS_TITLE_STYLE
.arg(QApplication::palette().color(QPalette::Foreground
).name()));
475 title
->setAlignment(Qt::AlignHCenter
);
476 groupBox
->setStyleSheet(EXPANDABLE_TRANSFER_DETAILS_STYLE
.arg(QApplication::palette().color(QPalette::Background
).lighter(200).name(), QApplication::palette().color(QPalette::Background
).name()));
481 void TransfersViewDelegate::itemActivated(QModelIndex index
)
483 const TransferTreeModel
* transferTreeModel
= static_cast <const TransferTreeModel
*> (index
.model());
485 if(!transferTreeModel
->isTransferGroup(index
) && Settings::showExpandableTransferDetails() && index
.column() == 0) {
486 if(!isExtended(index
)) {
487 TransferHandler
*handler
= static_cast <TransferHandler
*> (index
.internalPointer());
488 QWidget
*widget
= getDetailsWidgetForTransfer(handler
);
490 m_editingIndexes
.append(index
);
491 extendItem(widget
, index
);
494 m_editingIndexes
.removeAll(index
);
500 #include "transfersviewdelegate.moc"