appletbrowser gets a remove icon and a filter for running applets
svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=746735
This commit is contained in:
parent
5db83950c4
commit
950cc1c149
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include "plasma/corona.h"
|
#include "plasma/corona.h"
|
||||||
#include "plasma/containment.h"
|
#include "plasma/containment.h"
|
||||||
|
#include "plasma/applet.h"
|
||||||
#include "plasma/appletbrowser/plasmaappletitemmodel_p.h"
|
#include "plasma/appletbrowser/plasmaappletitemmodel_p.h"
|
||||||
#include "plasma/appletbrowser/kcategorizeditemsview_p.h"
|
#include "plasma/appletbrowser/kcategorizeditemsview_p.h"
|
||||||
|
|
||||||
@ -48,11 +49,16 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void initFilters();
|
void initFilters();
|
||||||
|
//update the itemModel on our running applets
|
||||||
|
void updateRunningApplets();
|
||||||
|
|
||||||
QString application;
|
QString application;
|
||||||
Plasma::Corona *corona;
|
Plasma::Corona *corona;
|
||||||
Plasma::Containment *containment;
|
Plasma::Containment *containment;
|
||||||
KCategorizedItemsView *appletList;
|
KCategorizedItemsView *appletList;
|
||||||
|
QMultiHash<QString,Plasma::Applet*> runningApplets;
|
||||||
|
//extra hash so we can look up the names of deleted applets
|
||||||
|
QHash<Plasma::Applet*,QString> appletNames;
|
||||||
|
|
||||||
KConfig config;
|
KConfig config;
|
||||||
KConfigGroup configGroup;
|
KConfigGroup configGroup;
|
||||||
@ -96,6 +102,9 @@ void AppletBrowserWidget::Private::initFilters()
|
|||||||
filterModel.addFilter(i18n("Widgets I Have Used Before"),
|
filterModel.addFilter(i18n("Widgets I Have Used Before"),
|
||||||
KCategorizedItemsViewModels::Filter("used", true),
|
KCategorizedItemsViewModels::Filter("used", true),
|
||||||
new KIcon("history"));
|
new KIcon("history"));
|
||||||
|
filterModel.addFilter(i18n("Currently Running Widgets"),
|
||||||
|
KCategorizedItemsViewModels::Filter("running", true),
|
||||||
|
new KIcon("history"));
|
||||||
|
|
||||||
filterModel.addSeparator(i18n("Categories:"));
|
filterModel.addSeparator(i18n("Categories:"));
|
||||||
|
|
||||||
@ -105,6 +114,16 @@ void AppletBrowserWidget::Private::initFilters()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppletBrowserWidget::Private::updateRunningApplets()
|
||||||
|
{
|
||||||
|
QHash<QString,int> appCount;
|
||||||
|
foreach (QString key, runningApplets.uniqueKeys()) {
|
||||||
|
appCount[key]=runningApplets.count(key);
|
||||||
|
}
|
||||||
|
kDebug() << appCount;
|
||||||
|
itemModel.setRunningApplets(appCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
AppletBrowserWidget::AppletBrowserWidget(Plasma::Corona * corona, bool showButtons, QWidget * parent, Qt::WindowFlags f)
|
AppletBrowserWidget::AppletBrowserWidget(Plasma::Corona * corona, bool showButtons, QWidget * parent, Qt::WindowFlags f)
|
||||||
: QWidget(parent, f),
|
: QWidget(parent, f),
|
||||||
@ -161,6 +180,38 @@ void AppletBrowserWidget::init()
|
|||||||
|
|
||||||
// Other models
|
// Other models
|
||||||
d->appletList->setItemModel(&d->itemModel);
|
d->appletList->setItemModel(&d->itemModel);
|
||||||
|
initRunningApplets();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletBrowserWidget::initRunningApplets()
|
||||||
|
{
|
||||||
|
//get applets from corona, count them, send results to model
|
||||||
|
kDebug() << d->runningApplets.count();
|
||||||
|
QHash<QString,int> appCount;
|
||||||
|
Plasma::Corona *c=d->corona;
|
||||||
|
if (!c && d->containment) {
|
||||||
|
c=d->containment->corona();
|
||||||
|
}
|
||||||
|
//we've tried our best to get a corona
|
||||||
|
//we don't want just one containment, we want them all
|
||||||
|
if (!c) {
|
||||||
|
kDebug() << "can't happen";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
QList<Containment*>containments=c->containments();
|
||||||
|
foreach (Containment * containment,containments) {
|
||||||
|
connect(containment, SIGNAL(appletAdded(Plasma::Applet*)), this, SLOT(appletAdded(Plasma::Applet*)));
|
||||||
|
//TODO track containments too?
|
||||||
|
QList<Applet*>applets=containment->applets();
|
||||||
|
foreach (Applet *applet,applets) {
|
||||||
|
d->runningApplets.insert(applet->name(), applet);
|
||||||
|
d->appletNames.insert(applet, applet->name());
|
||||||
|
connect(applet, SIGNAL(destroyed(QObject*)), this, SLOT(appletDestroyed(QObject*)));
|
||||||
|
appCount[applet->name()]++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
kDebug() << appCount;
|
||||||
|
d->itemModel.setRunningApplets(appCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void AppletBrowserWidget::setApplication(const QString& app)
|
void AppletBrowserWidget::setApplication(const QString& app)
|
||||||
@ -173,6 +224,8 @@ void AppletBrowserWidget::setApplication(const QString& app)
|
|||||||
//FIXME: AFAIK this shouldn't be necessary ... but here it is. need to find out what in that
|
//FIXME: AFAIK this shouldn't be necessary ... but here it is. need to find out what in that
|
||||||
// maze of models and views is screwing up
|
// maze of models and views is screwing up
|
||||||
d->appletList->setItemModel(&d->itemModel);
|
d->appletList->setItemModel(&d->itemModel);
|
||||||
|
|
||||||
|
d->updateRunningApplets();
|
||||||
}
|
}
|
||||||
|
|
||||||
QString AppletBrowserWidget::application()
|
QString AppletBrowserWidget::application()
|
||||||
@ -199,6 +252,37 @@ void AppletBrowserWidget::addApplet()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void AppletBrowserWidget::appletAdded(Plasma::Applet* applet)
|
||||||
|
{
|
||||||
|
QString name = applet->name();
|
||||||
|
kDebug() << name;
|
||||||
|
d->runningApplets.insert(name, applet);
|
||||||
|
d->appletNames.insert(applet, name);
|
||||||
|
connect(applet, SIGNAL(destroyed(QObject*)), this, SLOT(appletDestroyed(QObject*)));
|
||||||
|
d->itemModel.setRunningApplets(name, d->runningApplets.count(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletBrowserWidget::appletDestroyed(QObject* applet)
|
||||||
|
{
|
||||||
|
kDebug() << applet;
|
||||||
|
Plasma::Applet* a = (Plasma::Applet*)applet; //don't care if it's valid, just need the address
|
||||||
|
QString name = d->appletNames.take(a);
|
||||||
|
//if !name, was the applet not found or was the name actually ""?
|
||||||
|
d->runningApplets.remove(name, a);
|
||||||
|
d->itemModel.setRunningApplets(name, d->runningApplets.count(name));
|
||||||
|
}
|
||||||
|
|
||||||
|
void AppletBrowserWidget::destroyApplets(QString name)
|
||||||
|
{
|
||||||
|
foreach (Plasma::Applet* app, d->runningApplets.values(name)) {
|
||||||
|
//FIXME I have a hard time believing this is safe without QPointer
|
||||||
|
app->disconnect(this); //don't need to be told it's being destroyed
|
||||||
|
app->destroy();
|
||||||
|
d->appletNames.remove(app);
|
||||||
|
}
|
||||||
|
d->runningApplets.remove(name);
|
||||||
|
}
|
||||||
|
|
||||||
void AppletBrowserWidget::downloadApplets()
|
void AppletBrowserWidget::downloadApplets()
|
||||||
{
|
{
|
||||||
//TODO: implement
|
//TODO: implement
|
||||||
|
@ -29,6 +29,7 @@ namespace Plasma
|
|||||||
|
|
||||||
class Corona;
|
class Corona;
|
||||||
class Containment;
|
class Containment;
|
||||||
|
class Applet;
|
||||||
|
|
||||||
class PLASMA_EXPORT AppletBrowserWidget : public QWidget
|
class PLASMA_EXPORT AppletBrowserWidget : public QWidget
|
||||||
{
|
{
|
||||||
@ -47,6 +48,21 @@ protected Q_SLOTS:
|
|||||||
*/
|
*/
|
||||||
void addApplet();
|
void addApplet();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Tracks a new running applet
|
||||||
|
*/
|
||||||
|
void appletAdded(Plasma::Applet* applet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A running applet is no more
|
||||||
|
*/
|
||||||
|
void appletDestroyed(QObject* applet);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Destroy all applets with this name
|
||||||
|
*/
|
||||||
|
void destroyApplets(const QString name);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Launches a download dialog to retrieve new applets from the Internet
|
* Launches a download dialog to retrieve new applets from the Internet
|
||||||
*/
|
*/
|
||||||
@ -54,6 +70,7 @@ protected Q_SLOTS:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
void init();
|
void init();
|
||||||
|
void initRunningApplets();
|
||||||
class Private;
|
class Private;
|
||||||
Private * const d;
|
Private * const d;
|
||||||
bool m_showButtons;
|
bool m_showButtons;
|
||||||
|
@ -56,7 +56,7 @@ void CustomDragTreeView::startDrag ( Qt::DropActions supportedActions )
|
|||||||
QRect rect(0, 0, PIX_SIZE, PIX_SIZE);
|
QRect rect(0, 0, PIX_SIZE, PIX_SIZE);
|
||||||
|
|
||||||
foreach (QModelIndex index, indexes) {
|
foreach (QModelIndex index, indexes) {
|
||||||
if (index.column() == 1) continue;
|
if (index.column() != 0) continue;
|
||||||
|
|
||||||
KCategorizedItemsViewModels::AbstractItem * item =
|
KCategorizedItemsViewModels::AbstractItem * item =
|
||||||
m_view->getItemByProxyIndex(index);
|
m_view->getItemByProxyIndex(index);
|
||||||
|
@ -55,6 +55,9 @@ KCategorizedItemsView::KCategorizedItemsView(QWidget * parent, Qt::WindowFlags f
|
|||||||
itemsView->setItemDelegate(m_delegate = new KCategorizedItemsViewDelegate(this));
|
itemsView->setItemDelegate(m_delegate = new KCategorizedItemsViewDelegate(this));
|
||||||
itemsView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
itemsView->setVerticalScrollMode(QAbstractItemView::ScrollPerPixel);
|
||||||
|
|
||||||
|
connect (m_delegate, SIGNAL(destroyApplets(const QString)),
|
||||||
|
parent, SLOT(destroyApplets(const QString)));
|
||||||
|
|
||||||
comboFilters->setItemDelegate(new KCategorizedItemsViewFilterDelegate(this));
|
comboFilters->setItemDelegate(new KCategorizedItemsViewFilterDelegate(this));
|
||||||
|
|
||||||
itemsView->viewport()->setAttribute(Qt::WA_Hover);
|
itemsView->viewport()->setAttribute(Qt::WA_Hover);
|
||||||
@ -80,6 +83,7 @@ void KCategorizedItemsView::resizeEvent ( QResizeEvent * event ) {
|
|||||||
m_viewWidth = itemsView->viewport()->width();
|
m_viewWidth = itemsView->viewport()->width();
|
||||||
itemsView->setColumnWidth(0, m_delegate->columnWidth(0, m_viewWidth));
|
itemsView->setColumnWidth(0, m_delegate->columnWidth(0, m_viewWidth));
|
||||||
itemsView->setColumnWidth(1, m_delegate->columnWidth(1, m_viewWidth));
|
itemsView->setColumnWidth(1, m_delegate->columnWidth(1, m_viewWidth));
|
||||||
|
itemsView->setColumnWidth(2, m_delegate->columnWidth(2, m_viewWidth));
|
||||||
}
|
}
|
||||||
|
|
||||||
void KCategorizedItemsView::setFilterModel(QStandardItemModel * model)
|
void KCategorizedItemsView::setFilterModel(QStandardItemModel * model)
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
|
|
||||||
KCategorizedItemsViewDelegate::KCategorizedItemsViewDelegate(QObject * parent)
|
KCategorizedItemsViewDelegate::KCategorizedItemsViewDelegate(QObject * parent)
|
||||||
: QItemDelegate(parent), m_favoriteIcon("bookmark"),
|
: QItemDelegate(parent), m_favoriteIcon("bookmark"),
|
||||||
m_favoriteAddIcon("edit-add"), m_favoriteRemoveIcon("edit-delete"),
|
m_favoriteAddIcon("edit-add"), m_removeIcon("edit-delete"),
|
||||||
m_onFavoriteIconItem(NULL)
|
m_onFavoriteIconItem(NULL)
|
||||||
{
|
{
|
||||||
m_parent = (KCategorizedItemsView *) parent;
|
m_parent = (KCategorizedItemsView *) parent;
|
||||||
@ -47,148 +47,34 @@ void KCategorizedItemsViewDelegate::paint(QPainter *painter,
|
|||||||
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
const QStyleOptionViewItem &option, const QModelIndex &index) const
|
||||||
{
|
{
|
||||||
|
|
||||||
|
KCategorizedItemsViewModels::AbstractItem * item =
|
||||||
|
getItemByProxyIndex(index);
|
||||||
|
if (!item) return;
|
||||||
|
|
||||||
// Preparing needed data for painting
|
// Preparing needed data for painting
|
||||||
int left = option.rect.left();
|
int left = option.rect.left();
|
||||||
int top = option.rect.top();
|
int top = option.rect.top();
|
||||||
int width = option.rect.width();
|
int width = option.rect.width();
|
||||||
int height = option.rect.height();
|
int height = option.rect.height();
|
||||||
bool leftToRight = (painter->layoutDirection() == Qt::LeftToRight);
|
|
||||||
|
|
||||||
QIcon::Mode iconMode = QIcon::Normal;
|
|
||||||
|
|
||||||
QColor backgroundColor = (option.state.testFlag(QStyle::State_Selected))?
|
QColor backgroundColor = (option.state.testFlag(QStyle::State_Selected))?
|
||||||
option.palette.color(QPalette::Highlight):option.palette.color(QPalette::Base);
|
option.palette.color(QPalette::Highlight):option.palette.color(QPalette::Base);
|
||||||
QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
|
|
||||||
option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
|
|
||||||
|
|
||||||
KCategorizedItemsViewModels::AbstractItem * item =
|
|
||||||
getItemByProxyIndex(index);
|
|
||||||
if (!item) return;
|
|
||||||
|
|
||||||
// Base Background
|
// Base Background
|
||||||
painter->fillRect(option.rect, QBrush(backgroundColor));
|
painter->fillRect(option.rect, QBrush(backgroundColor));
|
||||||
|
|
||||||
if (index.column() == 0) {
|
switch (index.column()) {
|
||||||
// Painting main column
|
case 0:
|
||||||
QStyleOptionViewItem local_option_title(option);
|
paintColMain(painter, option, item);
|
||||||
QStyleOptionViewItem local_option_normal(option);
|
break;
|
||||||
|
case 1:
|
||||||
local_option_title.font.setBold(true);
|
paintColFav(painter, option, item);
|
||||||
local_option_title.font.setPointSize(local_option_title.font.pointSize() + 2);
|
break;
|
||||||
|
case 2:
|
||||||
QLinearGradient gradient;
|
paintColRemove(painter, option, item);
|
||||||
|
break;
|
||||||
QString title = item->name();
|
default:
|
||||||
QString description = item->description();
|
kDebug() << "unexpected column";
|
||||||
|
|
||||||
// Painting
|
|
||||||
|
|
||||||
// Text
|
|
||||||
int textInner = 2 * UNIVERSAL_PADDING + MAIN_ICON_SIZE;
|
|
||||||
|
|
||||||
painter->setPen(foregroundColor);
|
|
||||||
painter->setFont(local_option_title.font);
|
|
||||||
painter->drawText(
|
|
||||||
left + (leftToRight ? textInner : 0),
|
|
||||||
top + UNIVERSAL_PADDING,
|
|
||||||
width - textInner, MAIN_ICON_SIZE / 2,
|
|
||||||
Qt::AlignBottom | Qt::AlignLeft, title);
|
|
||||||
painter->setFont(local_option_normal.font);
|
|
||||||
painter->drawText(
|
|
||||||
left + (leftToRight ? textInner : 0),
|
|
||||||
top + UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2,
|
|
||||||
width - textInner, MAIN_ICON_SIZE / 2,
|
|
||||||
Qt::AlignTop | Qt::AlignLeft, description);
|
|
||||||
|
|
||||||
// Main icon
|
|
||||||
item->icon().paint(painter,
|
|
||||||
leftToRight ? left + UNIVERSAL_PADDING : left + width - UNIVERSAL_PADDING - MAIN_ICON_SIZE,
|
|
||||||
top + UNIVERSAL_PADDING,
|
|
||||||
MAIN_ICON_SIZE, MAIN_ICON_SIZE, Qt::AlignCenter, iconMode);
|
|
||||||
|
|
||||||
// Counting the number of emblems for this item
|
|
||||||
int emblemCount = 0;
|
|
||||||
QPair < Filter, QIcon * > emblem;
|
|
||||||
foreach (emblem, m_parent->m_emblems) {
|
|
||||||
if (item->passesFiltering(emblem.first)) ++emblemCount;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Gradient part of the background - fading of the text at the end
|
|
||||||
if (leftToRight) {
|
|
||||||
gradient = QLinearGradient(left + width - UNIVERSAL_PADDING - FADE_LENGTH, 0,
|
|
||||||
left + width - UNIVERSAL_PADDING, 0);
|
|
||||||
gradient.setColorAt(1, backgroundColor);
|
|
||||||
backgroundColor.setAlpha(0);
|
|
||||||
gradient.setColorAt(0, backgroundColor);
|
|
||||||
} else {
|
|
||||||
gradient = QLinearGradient(left + UNIVERSAL_PADDING, 0,
|
|
||||||
left + UNIVERSAL_PADDING + FADE_LENGTH, 0);
|
|
||||||
gradient.setColorAt(0, backgroundColor);
|
|
||||||
backgroundColor.setAlpha(0);
|
|
||||||
gradient.setColorAt(1, backgroundColor);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
QRect paintRect = option.rect;
|
|
||||||
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
|
|
||||||
painter->fillRect(paintRect, gradient);
|
|
||||||
|
|
||||||
if (leftToRight) {
|
|
||||||
gradient.setStart(left + width
|
|
||||||
- emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) - FADE_LENGTH, 0);
|
|
||||||
gradient.setFinalStop(left + width
|
|
||||||
- emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
|
|
||||||
} else {
|
|
||||||
gradient.setStart(left + UNIVERSAL_PADDING
|
|
||||||
+ emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
|
|
||||||
gradient.setFinalStop(left + UNIVERSAL_PADDING
|
|
||||||
+ emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) + FADE_LENGTH, 0);
|
|
||||||
}
|
|
||||||
paintRect.setHeight(UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2);
|
|
||||||
painter->fillRect(paintRect, gradient);
|
|
||||||
|
|
||||||
// Emblems icons
|
|
||||||
int emblemLeft = leftToRight ? (left + width - EMBLEM_ICON_SIZE) : left; // - FAV_ICON_SIZE - 2 * UNIVERSAL_PADDING
|
|
||||||
foreach (emblem, m_parent->m_emblems) {
|
|
||||||
if (item->passesFiltering(emblem.first)) {
|
|
||||||
emblem.second->paint(painter,
|
|
||||||
emblemLeft, top + UNIVERSAL_PADDING,
|
|
||||||
EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
|
|
||||||
if (leftToRight) {
|
|
||||||
emblemLeft -= UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
|
|
||||||
} else {
|
|
||||||
emblemLeft += UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// Painting favorite icon column
|
|
||||||
|
|
||||||
KCategorizedItemsViewModels::AbstractItem * item =
|
|
||||||
getItemByProxyIndex(index);
|
|
||||||
|
|
||||||
if (! (option.state & QStyle::State_MouseOver) && m_onFavoriteIconItem == item)
|
|
||||||
m_onFavoriteIconItem = NULL;
|
|
||||||
|
|
||||||
QIcon::Mode iconMode = QIcon::Normal;
|
|
||||||
if (!item->isFavorite()) {
|
|
||||||
iconMode = QIcon::Disabled;
|
|
||||||
} else if (option.state & QStyle::State_MouseOver) {
|
|
||||||
iconMode = QIcon::Active;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_favoriteIcon.paint(painter,
|
|
||||||
left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
|
|
||||||
FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
|
|
||||||
|
|
||||||
const KIcon * icon = (item->isFavorite())? & m_favoriteRemoveIcon : & m_favoriteAddIcon;
|
|
||||||
|
|
||||||
if ((option.state & QStyle::State_MouseOver) && (m_onFavoriteIconItem != item))
|
|
||||||
icon->paint(painter,
|
|
||||||
left + width - EMBLEM_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
|
|
||||||
EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Dividing line
|
// Dividing line
|
||||||
@ -199,16 +85,199 @@ void KCategorizedItemsViewDelegate::paint(QPainter *painter,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void KCategorizedItemsViewDelegate::paintColMain(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const
|
||||||
|
{
|
||||||
|
int left = option.rect.left();
|
||||||
|
int top = option.rect.top();
|
||||||
|
int width = option.rect.width();
|
||||||
|
|
||||||
|
bool leftToRight = (painter->layoutDirection() == Qt::LeftToRight);
|
||||||
|
QIcon::Mode iconMode = QIcon::Normal;
|
||||||
|
|
||||||
|
QColor backgroundColor = (option.state.testFlag(QStyle::State_Selected))?
|
||||||
|
option.palette.color(QPalette::Highlight):option.palette.color(QPalette::Base);
|
||||||
|
QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
|
||||||
|
option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
|
||||||
|
|
||||||
|
// Painting main column
|
||||||
|
QStyleOptionViewItem local_option_title(option);
|
||||||
|
QStyleOptionViewItem local_option_normal(option);
|
||||||
|
|
||||||
|
local_option_title.font.setBold(true);
|
||||||
|
local_option_title.font.setPointSize(local_option_title.font.pointSize() + 2);
|
||||||
|
|
||||||
|
QLinearGradient gradient;
|
||||||
|
|
||||||
|
QString title = item->name();
|
||||||
|
QString description = item->description();
|
||||||
|
|
||||||
|
// Painting
|
||||||
|
|
||||||
|
// Text
|
||||||
|
int textInner = 2 * UNIVERSAL_PADDING + MAIN_ICON_SIZE;
|
||||||
|
|
||||||
|
painter->setPen(foregroundColor);
|
||||||
|
painter->setFont(local_option_title.font);
|
||||||
|
painter->drawText(
|
||||||
|
left + (leftToRight ? textInner : 0),
|
||||||
|
top + UNIVERSAL_PADDING,
|
||||||
|
width - textInner, MAIN_ICON_SIZE / 2,
|
||||||
|
Qt::AlignBottom | Qt::AlignLeft, title);
|
||||||
|
painter->setFont(local_option_normal.font);
|
||||||
|
painter->drawText(
|
||||||
|
left + (leftToRight ? textInner : 0),
|
||||||
|
top + UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2,
|
||||||
|
width - textInner, MAIN_ICON_SIZE / 2,
|
||||||
|
Qt::AlignTop | Qt::AlignLeft, description);
|
||||||
|
|
||||||
|
// Main icon
|
||||||
|
item->icon().paint(painter,
|
||||||
|
leftToRight ? left + UNIVERSAL_PADDING : left + width - UNIVERSAL_PADDING - MAIN_ICON_SIZE,
|
||||||
|
top + UNIVERSAL_PADDING,
|
||||||
|
MAIN_ICON_SIZE, MAIN_ICON_SIZE, Qt::AlignCenter, iconMode);
|
||||||
|
|
||||||
|
// Counting the number of emblems for this item
|
||||||
|
int emblemCount = 0;
|
||||||
|
QPair < Filter, QIcon * > emblem;
|
||||||
|
foreach (emblem, m_parent->m_emblems) {
|
||||||
|
if (item->passesFiltering(emblem.first)) ++emblemCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Gradient part of the background - fading of the text at the end
|
||||||
|
if (leftToRight) {
|
||||||
|
gradient = QLinearGradient(left + width - UNIVERSAL_PADDING - FADE_LENGTH, 0,
|
||||||
|
left + width - UNIVERSAL_PADDING, 0);
|
||||||
|
gradient.setColorAt(1, backgroundColor);
|
||||||
|
backgroundColor.setAlpha(0);
|
||||||
|
gradient.setColorAt(0, backgroundColor);
|
||||||
|
} else {
|
||||||
|
gradient = QLinearGradient(left + UNIVERSAL_PADDING, 0,
|
||||||
|
left + UNIVERSAL_PADDING + FADE_LENGTH, 0);
|
||||||
|
gradient.setColorAt(0, backgroundColor);
|
||||||
|
backgroundColor.setAlpha(0);
|
||||||
|
gradient.setColorAt(1, backgroundColor);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QRect paintRect = option.rect;
|
||||||
|
painter->setCompositionMode(QPainter::CompositionMode_SourceOver);
|
||||||
|
painter->fillRect(paintRect, gradient);
|
||||||
|
|
||||||
|
if (leftToRight) {
|
||||||
|
gradient.setStart(left + width
|
||||||
|
- emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) - FADE_LENGTH, 0);
|
||||||
|
gradient.setFinalStop(left + width
|
||||||
|
- emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
|
||||||
|
} else {
|
||||||
|
gradient.setStart(left + UNIVERSAL_PADDING
|
||||||
|
+ emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE), 0);
|
||||||
|
gradient.setFinalStop(left + UNIVERSAL_PADDING
|
||||||
|
+ emblemCount * (UNIVERSAL_PADDING + EMBLEM_ICON_SIZE) + FADE_LENGTH, 0);
|
||||||
|
}
|
||||||
|
paintRect.setHeight(UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2);
|
||||||
|
painter->fillRect(paintRect, gradient);
|
||||||
|
|
||||||
|
// Emblems icons
|
||||||
|
int emblemLeft = leftToRight ? (left + width - EMBLEM_ICON_SIZE) : left; // - FAV_ICON_SIZE - 2 * UNIVERSAL_PADDING
|
||||||
|
foreach (emblem, m_parent->m_emblems) {
|
||||||
|
if (item->passesFiltering(emblem.first)) {
|
||||||
|
emblem.second->paint(painter,
|
||||||
|
emblemLeft, top + UNIVERSAL_PADDING,
|
||||||
|
EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
|
||||||
|
if (leftToRight) {
|
||||||
|
emblemLeft -= UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
|
||||||
|
} else {
|
||||||
|
emblemLeft += UNIVERSAL_PADDING + EMBLEM_ICON_SIZE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCategorizedItemsViewDelegate::paintColFav(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const
|
||||||
|
{
|
||||||
|
int left = option.rect.left();
|
||||||
|
int top = option.rect.top();
|
||||||
|
int width = option.rect.width();
|
||||||
|
|
||||||
|
// Painting favorite icon column
|
||||||
|
|
||||||
|
if (! (option.state & QStyle::State_MouseOver) && m_onFavoriteIconItem == item)
|
||||||
|
m_onFavoriteIconItem = NULL;
|
||||||
|
|
||||||
|
QIcon::Mode iconMode = QIcon::Normal;
|
||||||
|
if (!item->isFavorite()) {
|
||||||
|
iconMode = QIcon::Disabled;
|
||||||
|
} else if (option.state & QStyle::State_MouseOver) {
|
||||||
|
iconMode = QIcon::Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_favoriteIcon.paint(painter,
|
||||||
|
left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
|
||||||
|
FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
|
||||||
|
|
||||||
|
const KIcon * icon = (item->isFavorite())? & m_removeIcon : & m_favoriteAddIcon;
|
||||||
|
|
||||||
|
if ((option.state & QStyle::State_MouseOver) && (m_onFavoriteIconItem != item))
|
||||||
|
icon->paint(painter,
|
||||||
|
left + width - EMBLEM_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
|
||||||
|
EMBLEM_ICON_SIZE, EMBLEM_ICON_SIZE, Qt::AlignCenter, iconMode);
|
||||||
|
}
|
||||||
|
|
||||||
|
void KCategorizedItemsViewDelegate::paintColRemove(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const
|
||||||
|
{
|
||||||
|
// Painting remove icon column
|
||||||
|
int running = item->running();
|
||||||
|
if (!running) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
int left = option.rect.left();
|
||||||
|
int top = option.rect.top();
|
||||||
|
int width = option.rect.width();
|
||||||
|
|
||||||
|
QIcon::Mode iconMode = QIcon::Normal;
|
||||||
|
if (option.state & QStyle::State_MouseOver) {
|
||||||
|
iconMode = QIcon::Active;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_removeIcon.paint(painter,
|
||||||
|
left + width - FAV_ICON_SIZE - UNIVERSAL_PADDING, top + UNIVERSAL_PADDING,
|
||||||
|
FAV_ICON_SIZE, FAV_ICON_SIZE, Qt::AlignCenter, iconMode);
|
||||||
|
|
||||||
|
if (running == 1) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
//paint number
|
||||||
|
QColor foregroundColor = (option.state.testFlag(QStyle::State_Selected))?
|
||||||
|
option.palette.color(QPalette::HighlightedText):option.palette.color(QPalette::Text);
|
||||||
|
painter->setPen(foregroundColor);
|
||||||
|
painter->setFont(option.font);
|
||||||
|
painter->drawText(
|
||||||
|
left + UNIVERSAL_PADDING, //FIXME might be wrong
|
||||||
|
top + UNIVERSAL_PADDING + MAIN_ICON_SIZE / 2,
|
||||||
|
width - 2 * UNIVERSAL_PADDING, MAIN_ICON_SIZE / 2,
|
||||||
|
Qt::AlignCenter, QString::number(running));
|
||||||
|
}
|
||||||
|
|
||||||
bool KCategorizedItemsViewDelegate::editorEvent(QEvent *event,
|
bool KCategorizedItemsViewDelegate::editorEvent(QEvent *event,
|
||||||
QAbstractItemModel *model,
|
QAbstractItemModel *model,
|
||||||
const QStyleOptionViewItem &option,
|
const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index)
|
const QModelIndex &index)
|
||||||
{
|
{
|
||||||
if (index.column() == 1 && event->type() == QEvent::MouseButtonPress) {
|
if (event->type() == QEvent::MouseButtonPress) {
|
||||||
(m_onFavoriteIconItem = getItemByProxyIndex(index))
|
KCategorizedItemsViewModels::AbstractItem * item = getItemByProxyIndex(index);
|
||||||
->setFavorite(!getItemByProxyIndex(index)->isFavorite());
|
if (index.column() == 1) {
|
||||||
|
(m_onFavoriteIconItem = item)
|
||||||
return true;
|
->setFavorite(!item->isFavorite());
|
||||||
|
return true;
|
||||||
|
} else if (index.column() == 2 && item->running()) {
|
||||||
|
item->setRunning(0);
|
||||||
|
emit destroyApplets(item->name());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return QItemDelegate::editorEvent(event, model, option, index);
|
return QItemDelegate::editorEvent(event, model, option, index);
|
||||||
@ -220,15 +289,14 @@ QSize KCategorizedItemsViewDelegate::sizeHint(const QStyleOptionViewItem &option
|
|||||||
Q_UNUSED(option);
|
Q_UNUSED(option);
|
||||||
|
|
||||||
//Q_UNUSED(index);
|
//Q_UNUSED(index);
|
||||||
//option.
|
|
||||||
int width = (index.column() == 0) ? 0 : FAV_ICON_SIZE;
|
int width = (index.column() == 0) ? 0 : FAV_ICON_SIZE;
|
||||||
return QSize(width, MAIN_ICON_SIZE + 2 * UNIVERSAL_PADDING);
|
return QSize(width, MAIN_ICON_SIZE + 2 * UNIVERSAL_PADDING);
|
||||||
}
|
}
|
||||||
|
|
||||||
int KCategorizedItemsViewDelegate::columnWidth (int column, int viewWidth) const {
|
int KCategorizedItemsViewDelegate::columnWidth (int column, int viewWidth) const {
|
||||||
if (column == 1) {
|
if (column != 0) {
|
||||||
return FAV_ICON_SIZE + 2 * UNIVERSAL_PADDING;
|
return FAV_ICON_SIZE + 2 * UNIVERSAL_PADDING;
|
||||||
} else return viewWidth - columnWidth(1, viewWidth);
|
} else return viewWidth - 2 * columnWidth(1, viewWidth);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -52,17 +52,25 @@ public:
|
|||||||
const QStyleOptionViewItem &option,
|
const QStyleOptionViewItem &option,
|
||||||
const QModelIndex &index);
|
const QModelIndex &index);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void destroyApplets(const QString name);
|
||||||
private:
|
private:
|
||||||
|
|
||||||
KCategorizedItemsView * m_parent;
|
KCategorizedItemsView * m_parent;
|
||||||
KIcon m_favoriteIcon;
|
KIcon m_favoriteIcon;
|
||||||
KIcon m_favoriteAddIcon;
|
KIcon m_favoriteAddIcon;
|
||||||
KIcon m_favoriteRemoveIcon;
|
KIcon m_removeIcon;
|
||||||
|
|
||||||
mutable KCategorizedItemsViewModels::AbstractItem * m_onFavoriteIconItem;
|
mutable KCategorizedItemsViewModels::AbstractItem * m_onFavoriteIconItem;
|
||||||
|
|
||||||
|
|
||||||
KCategorizedItemsViewModels::AbstractItem * getItemByProxyIndex(const QModelIndex & index) const;
|
KCategorizedItemsViewModels::AbstractItem * getItemByProxyIndex(const QModelIndex & index) const;
|
||||||
|
void paintColMain(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const;
|
||||||
|
void paintColFav(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const;
|
||||||
|
void paintColRemove(QPainter *painter,
|
||||||
|
const QStyleOptionViewItem &option, const KCategorizedItemsViewModels::AbstractItem * item) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -38,6 +38,11 @@ bool AbstractItem::isFavorite() const
|
|||||||
return passesFiltering(Filter("favorite", true));
|
return passesFiltering(Filter("favorite", true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int AbstractItem::running() const
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
bool AbstractItem::matches(const QString & pattern) const
|
bool AbstractItem::matches(const QString & pattern) const
|
||||||
{
|
{
|
||||||
return name().contains(pattern, Qt::CaseInsensitive) || description().contains(pattern, Qt::CaseInsensitive);
|
return name().contains(pattern, Qt::CaseInsensitive) || description().contains(pattern, Qt::CaseInsensitive);
|
||||||
@ -101,7 +106,7 @@ QStandardItemModel * DefaultItemFilterProxyModel::sourceModel() const
|
|||||||
int DefaultItemFilterProxyModel::columnCount(const QModelIndex& index) const
|
int DefaultItemFilterProxyModel::columnCount(const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
return 2;
|
return 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
QVariant DefaultItemFilterProxyModel::data(const QModelIndex & index, int role) const
|
QVariant DefaultItemFilterProxyModel::data(const QModelIndex & index, int role) const
|
||||||
@ -234,7 +239,7 @@ int DefaultItemFilterProxyModel::InnerProxyModel::columnCount(
|
|||||||
const QModelIndex& index) const
|
const QModelIndex& index) const
|
||||||
{
|
{
|
||||||
Q_UNUSED(index);
|
Q_UNUSED(index);
|
||||||
return 2;
|
return 3; //FIXME: a hardcoded magic number that appears in two places CANNOT be good
|
||||||
}
|
}
|
||||||
|
|
||||||
void DefaultItemFilterProxyModel::InnerProxyModel::setSourceModel(
|
void DefaultItemFilterProxyModel::InnerProxyModel::setSourceModel(
|
||||||
|
@ -50,6 +50,12 @@ public:
|
|||||||
*/
|
*/
|
||||||
virtual bool isFavorite() const;
|
virtual bool isFavorite() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the item's number of running applets
|
||||||
|
* Default implementation just returns 0
|
||||||
|
*/
|
||||||
|
virtual int running() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the item contains string specified by pattern.
|
* Returns if the item contains string specified by pattern.
|
||||||
* Default implementation checks whether name or description contain the
|
* Default implementation checks whether name or description contain the
|
||||||
@ -61,6 +67,10 @@ public:
|
|||||||
* sets the favorite flag for the item
|
* sets the favorite flag for the item
|
||||||
*/
|
*/
|
||||||
virtual void setFavorite(bool favorite) = 0;
|
virtual void setFavorite(bool favorite) = 0;
|
||||||
|
/**
|
||||||
|
* sets the number of running applets for the item
|
||||||
|
*/
|
||||||
|
virtual void setRunning(int count) = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the item passes the filter specified
|
* Returns if the item passes the filter specified
|
||||||
|
@ -49,6 +49,11 @@ QString PlasmaAppletItem::description() const
|
|||||||
return data().toMap()["description"].toString();
|
return data().toMap()["description"].toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int PlasmaAppletItem::running() const
|
||||||
|
{
|
||||||
|
return data().toMap()["runningCount"].toInt();
|
||||||
|
}
|
||||||
|
|
||||||
void PlasmaAppletItem::setFavorite(bool favorite)
|
void PlasmaAppletItem::setFavorite(bool favorite)
|
||||||
{
|
{
|
||||||
QMap<QString, QVariant> attrs = data().toMap();
|
QMap<QString, QVariant> attrs = data().toMap();
|
||||||
@ -69,6 +74,14 @@ void PlasmaAppletItem::setFavorite(bool favorite)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlasmaAppletItem::setRunning(int count)
|
||||||
|
{
|
||||||
|
QMap<QString, QVariant> attrs = data().toMap();
|
||||||
|
attrs.insert("running", count > 0); //bool for the filter
|
||||||
|
attrs.insert("runningCount", count);
|
||||||
|
setData(QVariant(attrs));
|
||||||
|
}
|
||||||
|
|
||||||
bool PlasmaAppletItem::passesFiltering(
|
bool PlasmaAppletItem::passesFiltering(
|
||||||
const KCategorizedItemsViewModels::Filter & filter) const
|
const KCategorizedItemsViewModels::Filter & filter) const
|
||||||
{
|
{
|
||||||
@ -138,6 +151,29 @@ void PlasmaAppletItemModel::populateModel()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PlasmaAppletItemModel::setRunningApplets(const QHash<QString, int> apps)
|
||||||
|
{
|
||||||
|
//foreach item, find that string and set the count
|
||||||
|
for (int r=0; r<rowCount(); ++r) {
|
||||||
|
QStandardItem *i = item(r);
|
||||||
|
PlasmaAppletItem *p = (PlasmaAppletItem *)i;
|
||||||
|
if (p) {
|
||||||
|
p->setRunning(apps.value(p->name()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PlasmaAppletItemModel::setRunningApplets(const QString name, int count)
|
||||||
|
{
|
||||||
|
for (int r=0; r<rowCount(); ++r) {
|
||||||
|
QStandardItem *i = item(r);
|
||||||
|
PlasmaAppletItem *p = (PlasmaAppletItem *)i;
|
||||||
|
if (p && p->name() == name) {
|
||||||
|
p->setRunning(count);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
QStringList PlasmaAppletItemModel::mimeTypes() const
|
QStringList PlasmaAppletItemModel::mimeTypes() const
|
||||||
{
|
{
|
||||||
QStringList types;
|
QStringList types;
|
||||||
|
@ -47,7 +47,10 @@ public:
|
|||||||
virtual QString name() const;
|
virtual QString name() const;
|
||||||
QString pluginName() const;
|
QString pluginName() const;
|
||||||
virtual QString description() const;
|
virtual QString description() const;
|
||||||
|
virtual int running() const;
|
||||||
virtual void setFavorite(bool favorite);
|
virtual void setFavorite(bool favorite);
|
||||||
|
//set how many instances of this applet are running
|
||||||
|
virtual void setRunning(int count);
|
||||||
virtual bool passesFiltering(
|
virtual bool passesFiltering(
|
||||||
const KCategorizedItemsViewModels::Filter & filter) const;
|
const KCategorizedItemsViewModels::Filter & filter) const;
|
||||||
virtual QVariantList arguments() const;
|
virtual QVariantList arguments() const;
|
||||||
@ -68,6 +71,8 @@ public:
|
|||||||
|
|
||||||
void setFavorite(QString plugin, bool favorite);
|
void setFavorite(QString plugin, bool favorite);
|
||||||
void setApplication(const QString& app);
|
void setApplication(const QString& app);
|
||||||
|
void setRunningApplets(const QHash<QString, int> apps);
|
||||||
|
void setRunningApplets(const QString name, int count);
|
||||||
|
|
||||||
QString& Application();
|
QString& Application();
|
||||||
private:
|
private:
|
||||||
|
Loading…
Reference in New Issue
Block a user