You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
247 lines
9.6 KiB
247 lines
9.6 KiB
/* |
|
Copyright (c) 2010 Casey Link <unnamedrambler@gmail.com> |
|
Copyright (c) 2009-2010 Klaralvdalens Datakonsult AB, a KDAB Group company <info@kdab.net> |
|
Copyright (c) 2006-2008 Tobias Koenig <tokoe@kde.org> |
|
|
|
This library is free software; you can redistribute it and/or modify it |
|
under the terms of the GNU Library General Public License as published by |
|
the Free Software Foundation; either version 2 of the License, or (at your |
|
option) any later version. |
|
|
|
This library is distributed in the hope that it will be useful, but WITHOUT |
|
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or |
|
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public |
|
License for more details. |
|
|
|
You should have received a copy of the GNU Library General Public License |
|
along with this library; see the file COPYING.LIB. If not, write to the |
|
Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA |
|
02110-1301, USA. |
|
*/ |
|
|
|
#include "configagentdelegate.h" |
|
|
|
#include <AkonadiCore/AgentInstanceModel> |
|
#include <AkonadiCore/AgentInstance> |
|
|
|
#include <QIcon> |
|
#include <KLocalizedString> |
|
#include <KIconLoader> |
|
|
|
#include <QUrl> |
|
#include <QApplication> |
|
#include <QPainter> |
|
#include <QTextDocument> |
|
#include <QMouseEvent> |
|
|
|
using Akonadi::AgentInstanceModel; |
|
using Akonadi::AgentInstance; |
|
|
|
static const int s_delegatePaddingSize = 7; |
|
|
|
struct Icons { |
|
Icons() |
|
: readyPixmap(QIcon::fromTheme(QStringLiteral("user-online")).pixmap(QSize(16, 16))) |
|
, syncPixmap(QIcon::fromTheme(QStringLiteral("network-connect")).pixmap(QSize(16, 16))) |
|
, errorPixmap(QIcon::fromTheme(QStringLiteral("dialog-error")).pixmap(QSize(16, 16))) |
|
, offlinePixmap(QIcon::fromTheme(QStringLiteral("network-disconnect")).pixmap(QSize(16, 16))) |
|
, checkMailIcon(QIcon::fromTheme(QStringLiteral("mail-receive"))) |
|
{ |
|
} |
|
QPixmap readyPixmap, syncPixmap, errorPixmap, offlinePixmap; |
|
QIcon checkMailIcon; |
|
}; |
|
|
|
Q_GLOBAL_STATIC(Icons, s_icons) |
|
|
|
ConfigAgentDelegate::ConfigAgentDelegate(QObject *parent) |
|
: QStyledItemDelegate(parent) |
|
{ |
|
} |
|
|
|
QTextDocument *ConfigAgentDelegate::document(const QStyleOptionViewItem &option, const QModelIndex &index) const |
|
{ |
|
if (!index.isValid()) { |
|
return Q_NULLPTR; |
|
} |
|
|
|
const QString name = index.model()->data(index, Qt::DisplayRole).toString(); |
|
int status = index.model()->data(index, AgentInstanceModel::StatusRole).toInt(); |
|
uint progress = index.model()->data(index, AgentInstanceModel::ProgressRole).toUInt(); |
|
const QString statusMessage = index.model()->data(index, AgentInstanceModel::StatusMessageRole).toString(); |
|
|
|
QTextDocument *document = new QTextDocument(Q_NULLPTR); |
|
|
|
const QSize decorationSize(KIconLoader::global()->currentSize(KIconLoader::Desktop), KIconLoader::global()->currentSize(KIconLoader::Desktop)); |
|
const QVariant data = index.model()->data(index, Qt::DecorationRole); |
|
if (data.isValid() && data.type() == QVariant::Icon) { |
|
document->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("agent_icon")), |
|
qvariant_cast<QIcon> (data).pixmap(decorationSize)); |
|
} |
|
|
|
if (!index.data(AgentInstanceModel::OnlineRole).toBool()) { |
|
document->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("status_icon")), s_icons->offlinePixmap); |
|
} else if (status == AgentInstance::Idle) { |
|
document->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("status_icon")), s_icons->readyPixmap); |
|
} else if (status == AgentInstance::Running) { |
|
document->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("status_icon")), s_icons->syncPixmap); |
|
} else { |
|
document->addResource(QTextDocument::ImageResource, QUrl(QStringLiteral("status_icon")), s_icons->errorPixmap); |
|
} |
|
|
|
QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; |
|
if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) { |
|
cg = QPalette::Inactive; |
|
} |
|
|
|
QColor textColor; |
|
if (option.state & QStyle::State_Selected) { |
|
textColor = option.palette.color(cg, QPalette::HighlightedText); |
|
} else { |
|
textColor = option.palette.color(cg, QPalette::Text); |
|
} |
|
|
|
const QString content = QStringLiteral( |
|
"<html style=\"color:%1\">" |
|
"<body>" |
|
"<table>" |
|
"<tr>" |
|
"<td rowspan=\"2\"><img src=\"agent_icon\"> </td>" |
|
"<td><b>%2</b></td>" |
|
"</tr>").arg(textColor.name().toUpper()).arg(name) |
|
+ QStringLiteral( |
|
"<tr>" |
|
"<td><img src=\"status_icon\"/> %1 %2</td>" |
|
"</tr>").arg(statusMessage).arg(status == 1 ? QStringLiteral("(%1%)").arg(progress) : QLatin1String("")) |
|
+ QLatin1String("</table></body></html>"); |
|
|
|
document->setHtml(content); |
|
|
|
return document; |
|
} |
|
|
|
void ConfigAgentDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const |
|
{ |
|
if (!index.isValid()) { |
|
return; |
|
} |
|
|
|
QTextDocument *doc = document(option, index); |
|
if (!doc) { |
|
return; |
|
} |
|
|
|
QStyleOptionButton buttonOpt = buttonOption(option); |
|
|
|
doc->setTextWidth(option.rect.width() - buttonOpt.rect.width()); |
|
painter->setRenderHint(QPainter::Antialiasing); |
|
|
|
QPen pen = painter->pen(); |
|
|
|
QPalette::ColorGroup cg = option.state & QStyle::State_Enabled ? QPalette::Normal : QPalette::Disabled; |
|
if (cg == QPalette::Normal && !(option.state & QStyle::State_Active)) { |
|
cg = QPalette::Inactive; |
|
} |
|
|
|
QStyleOptionViewItemV4 opt(option); |
|
opt.showDecorationSelected = true; |
|
QApplication::style()->drawPrimitive(QStyle::PE_PanelItemViewItem, &opt, painter); |
|
painter->save(); |
|
painter->translate(option.rect.topLeft()); |
|
|
|
doc->drawContents(painter); |
|
|
|
QApplication::style()->drawControl(QStyle::CE_PushButton, &buttonOpt, painter); |
|
|
|
painter->restore(); |
|
painter->setPen(pen); |
|
|
|
drawFocus(painter, option, option.rect); |
|
delete doc; |
|
} |
|
|
|
QSize ConfigAgentDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &) const |
|
{ |
|
const int iconHeight = KIconLoader::global()->currentSize(KIconLoader::Desktop) + (s_delegatePaddingSize * 2); //icon height + padding either side |
|
const int textHeight = option.fontMetrics.height() + qMax(option.fontMetrics.height(), 16) + (s_delegatePaddingSize * 2); //height of text + icon/text + padding either side |
|
|
|
return QSize(1, qMax(iconHeight, textHeight)); //any width,the view will give us the whole thing in list mode |
|
} |
|
|
|
QWidget *ConfigAgentDelegate::createEditor(QWidget *, const QStyleOptionViewItem &, const QModelIndex &) const |
|
{ |
|
return Q_NULLPTR; |
|
} |
|
|
|
bool ConfigAgentDelegate::editorEvent(QEvent *event, QAbstractItemModel *model, const QStyleOptionViewItem &option, const QModelIndex &index) |
|
{ |
|
Q_UNUSED(model); |
|
if (!index.isValid()) { |
|
return false; |
|
} |
|
if (!((event->type() == QEvent::MouseButtonRelease) |
|
|| (event->type() == QEvent::MouseButtonPress) |
|
|| (event->type() == QEvent::MouseMove))) { |
|
return false; |
|
} |
|
|
|
QMouseEvent *me = static_cast<QMouseEvent *>(event); |
|
const QPoint mousePos = me->pos() - option.rect.topLeft(); |
|
|
|
QStyleOptionButton buttonOpt = buttonOption(option); |
|
|
|
if (buttonOpt.rect.contains(mousePos)) { |
|
|
|
switch (event->type()) { |
|
case QEvent::MouseButtonPress: |
|
return false; |
|
case QEvent::MouseButtonRelease: { |
|
QPoint pos = buttonOpt.rect.bottomLeft() + option.rect.topLeft(); |
|
const QString ident = index.data(Akonadi::AgentInstanceModel::InstanceIdentifierRole).toString(); |
|
Q_EMIT optionsClicked(ident, pos); |
|
return true; |
|
} |
|
default: |
|
return false; |
|
} |
|
} |
|
return false; |
|
} |
|
|
|
void ConfigAgentDelegate::drawFocus(QPainter *painter, const QStyleOptionViewItem &option, const QRect &rect) const |
|
{ |
|
if (option.state & QStyle::State_HasFocus) { |
|
QStyleOptionFocusRect o; |
|
o.QStyleOption::operator= (option); |
|
o.rect = rect; |
|
o.state |= QStyle::State_KeyboardFocusChange; |
|
QPalette::ColorGroup cg = (option.state & QStyle::State_Enabled) ? QPalette::Normal : QPalette::Disabled; |
|
o.backgroundColor = option.palette.color(cg, (option.state & QStyle::State_Selected) |
|
? QPalette::Highlight : QPalette::Background); |
|
QApplication::style()->drawPrimitive(QStyle::PE_FrameFocusRect, &o, painter); |
|
} |
|
} |
|
|
|
QStyleOptionButton ConfigAgentDelegate::buttonOption(const QStyleOptionViewItem &option) const |
|
{ |
|
const QString label = i18n("Retrieval Options"); |
|
QStyleOptionButton buttonOpt; |
|
QRect buttonRect = option.rect; |
|
int height = option.rect.height() / 2; |
|
int width = 22 + option.fontMetrics.width(label) + 40; // icon size + label size + arrow and padding |
|
buttonRect.setTop(0/*( option.rect.height() /2 ) - height / 2)*/); // center the button vertically |
|
buttonRect.setHeight(height); |
|
buttonRect.setLeft(option.rect.right() - width); |
|
buttonRect.setWidth(width); |
|
|
|
buttonOpt.rect = buttonRect; |
|
buttonOpt.state = option.state; |
|
buttonOpt.text = label; |
|
buttonOpt.palette = option.palette; |
|
buttonOpt.features = QStyleOptionButton::HasMenu; |
|
buttonOpt.icon = s_icons->checkMailIcon; |
|
buttonOpt.iconSize = QSize(22, 22); // FIXME don't hardcode this icon size |
|
|
|
return buttonOpt; |
|
} |
|
|
|
|