mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-25 11:22:55 +00:00

that KIcon("kget").paint() in ProxyWidget::paint() looks expensive.. may have to cache the KIcon object aswell and update it when the system icon theme changes Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
402 lines
13 KiB
C++
402 lines
13 KiB
C++
/***************************************************************************
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
*
|
|
* Copyright (C) 2008 - 2009 by Lukas Appelhans <l.appelhans@gmx.de>
|
|
* *
|
|
* This program 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 General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA . *
|
|
***************************************************************************/
|
|
#include "kgetapplet.h"
|
|
#include "kget_interface.h"
|
|
#include "kgetappletutils.h"
|
|
#include "../../../core/transferhandler.h"
|
|
|
|
#include <plasma/dataengine.h>
|
|
#include <plasma/theme.h>
|
|
#include <plasma/widgets/iconwidget.h>
|
|
#include <plasma/widgets/meter.h>
|
|
|
|
#include <QtGui/qgraphicssceneevent.h>
|
|
#include <QGraphicsLinearLayout>
|
|
#include <QtGui/qstyleoption.h>
|
|
#include <QProgressBar>
|
|
#include <QGraphicsProxyWidget>
|
|
#include <QPainter>
|
|
#include <QProcess>
|
|
#include <QtDBus/QDBusConnectionInterface>
|
|
#include <KUrl>
|
|
#include <KLocale>
|
|
#include <KIcon>
|
|
|
|
const int ProxyWidget::MARGIN = 20;
|
|
const int ProxyWidget::TOP_MARGIN = 55;
|
|
const int ProxyWidget::LEFT_MARGIN = 15;
|
|
const int ProxyWidget::SPACING = 4;
|
|
|
|
const QString KGetApplet::KGET_DBUS_SERVICE = "org.kde.kget";
|
|
const QString KGetApplet::KGET_DBUS_PATH = "/KGet";
|
|
const int KGetApplet::POLL_INTERVAL = 1500;
|
|
|
|
ProxyWidget::ProxyWidget(QGraphicsWidget * parent)
|
|
: QGraphicsWidget(parent),
|
|
m_layout(0),
|
|
m_dataWidget(0)
|
|
{
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
m_layout->setSpacing(SPACING);
|
|
//m_layout->setContentsMargins(MARGIN, TOP_MARGIN, MARGIN, MARGIN);
|
|
|
|
themeChanged();
|
|
|
|
connect(Plasma::Theme::defaultTheme(), SIGNAL(themeChanged()), SLOT(themeChanged()));
|
|
}
|
|
|
|
ProxyWidget::~ProxyWidget()
|
|
{
|
|
}
|
|
|
|
void ProxyWidget::paint(QPainter * p, const QStyleOptionGraphicsItem * option, QWidget * widget)
|
|
{
|
|
const QRect rect = option->rect;
|
|
|
|
p->setRenderHint(QPainter::SmoothPixmapTransform);
|
|
|
|
p->setFont(m_font);
|
|
p->setPen(Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor));
|
|
|
|
QRect iconRect(QPoint(rect.x() + SPACING + 10, rect.y() + SPACING + 10), QSize(m_textHeight, m_textHeight));
|
|
|
|
KIcon("kget").paint(p, iconRect);
|
|
p->drawText(QRectF(rect.x() + SPACING * 2 + 10 + iconRect.width(), rect.y() + SPACING + 10,
|
|
m_textWidth, m_textHeight), i18n("KGet"));
|
|
p->drawLine(QPointF(rect.x() + SPACING + 10, rect.y() + SPACING * 2 + 10 + m_textHeight),
|
|
QPointF(rect.width() - SPACING - 10, rect.y() + SPACING * 2 + 10 + m_textHeight));
|
|
|
|
QGraphicsWidget::paint(p, option, widget);
|
|
}
|
|
|
|
void ProxyWidget::themeChanged()
|
|
{
|
|
m_font = Plasma::Theme::defaultTheme()->font(Plasma::Theme::DefaultFont);
|
|
m_font.setBold(true);
|
|
m_font.setPointSize(15);
|
|
|
|
QFontMetrics metrics(m_font);
|
|
m_textWidth = metrics.width(i18n("KGet"));
|
|
m_textHeight = metrics.height();
|
|
|
|
m_layout->setContentsMargins(MARGIN, MARGIN + m_textHeight + SPACING + 10, MARGIN, MARGIN);
|
|
}
|
|
|
|
void ProxyWidget::setDataWidget(QGraphicsWidget *widget)
|
|
{
|
|
if (m_layout->count())
|
|
m_layout->removeAt(0);
|
|
m_layout->addItem(widget);
|
|
m_dataWidget = widget;
|
|
}
|
|
|
|
QGraphicsWidget *ProxyWidget::dataWidget()
|
|
{
|
|
return m_dataWidget;
|
|
}
|
|
|
|
KGetApplet::KGetApplet(QObject *parent, const QVariantList &args)
|
|
: Plasma::PopupApplet(parent, args),
|
|
m_proxyWidget(0),
|
|
m_errorWidget(0),
|
|
m_dataWidget(0),
|
|
m_globalProgress(0),
|
|
m_icon(0),
|
|
m_engine(0),
|
|
m_totalSize(0),
|
|
m_downloadedSize(0)
|
|
{
|
|
setAspectRatioMode(Plasma::IgnoreAspectRatio);
|
|
setBackgroundHints(Applet::DefaultBackground);
|
|
setAcceptDrops(true);
|
|
m_proxyWidget = new ProxyWidget(this);
|
|
}
|
|
|
|
KGetApplet::~KGetApplet()
|
|
{
|
|
}
|
|
|
|
void KGetApplet::init()
|
|
{
|
|
KGlobal::locale()->insertCatalog("plasma_applet_kget");
|
|
|
|
setPopupIcon("kget");
|
|
m_engine = dataEngine("kget");
|
|
if (m_engine) {
|
|
m_engine->connectSource("KGet", this, POLL_INTERVAL);
|
|
} else {
|
|
kDebug(5001) << "KGet Engine could not be loaded";
|
|
}
|
|
m_globalProgress = new Plasma::Meter(this);
|
|
m_globalProgress->setMeterType(Plasma::Meter::BarMeterHorizontal);
|
|
m_globalProgress->setMinimumSize(QSize(0, 0));
|
|
setGraphicsWidget(m_proxyWidget);
|
|
}
|
|
|
|
void KGetApplet::slotKgetStarted()
|
|
{
|
|
m_engine->query("KGet");
|
|
}
|
|
|
|
void KGetApplet::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data)
|
|
{
|
|
Q_UNUSED(name)
|
|
kDebug() << layout()->count();
|
|
if (data["error"].toBool()) {
|
|
if (!m_errorWidget) {
|
|
m_errorWidget = new ErrorWidget(data["errorMessage"].toString(), this);
|
|
connect(m_errorWidget, SIGNAL(kgetStarted()), this, SLOT(slotKgetStarted()));
|
|
}
|
|
if (m_proxyWidget->dataWidget() != m_errorWidget) {
|
|
m_proxyWidget->setDataWidget(m_errorWidget);
|
|
m_errorWidget->show();
|
|
m_dataWidget->hide();
|
|
}
|
|
} else if (!data["error"].toBool()) {
|
|
if (m_errorWidget && m_errorWidget->isVisible())
|
|
m_errorWidget->hide();
|
|
if (m_proxyWidget->dataWidget() != m_dataWidget) {
|
|
m_proxyWidget->setDataWidget(m_dataWidget);
|
|
m_dataWidget->show();
|
|
}
|
|
if (m_transfers.isEmpty()) {
|
|
transferAdded(data["transfers"].toMap());
|
|
} else {
|
|
if (data.contains("transferAdded")) {
|
|
transferAdded(data["transferAdded"].toMap());
|
|
}
|
|
if (data.contains("transferRemoved")) {
|
|
transferRemoved(data["transferRemoved"].toMap());
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
void KGetApplet::transferAdded(const QVariantMap &transfer)
|
|
{
|
|
QList<OrgKdeKgetTransferInterface*> added;
|
|
QVariantMap::const_iterator it;
|
|
QVariantMap::const_iterator itEnd = transfer.constEnd();
|
|
for (it = transfer.constBegin(); it != itEnd; ++it) {
|
|
OrgKdeKgetTransferInterface *newTransfer = new OrgKdeKgetTransferInterface("org.kde.kget", it.value().toString(), QDBusConnection::sessionBus(), this);
|
|
connect(newTransfer, SIGNAL(transferChangedEvent(int)), this, SLOT(slotUpdateTransfer(int)));
|
|
|
|
added.append(newTransfer);
|
|
|
|
m_transfers[newTransfer].size = newTransfer->totalSize();
|
|
m_transfers[newTransfer].downloadedSize = newTransfer->downloadedSize();
|
|
m_transfers[newTransfer].source = newTransfer->source();
|
|
m_downloadedSize += m_transfers[newTransfer].downloadedSize;
|
|
m_totalSize += m_transfers[newTransfer].size;
|
|
}
|
|
|
|
if (!added.isEmpty()) {
|
|
emit transfersAdded(added);
|
|
emit update();
|
|
updateGlobalProgress();
|
|
}
|
|
}
|
|
|
|
void KGetApplet::transferRemoved(const QVariantMap &transfer)
|
|
{
|
|
QList<OrgKdeKgetTransferInterface*> removed;
|
|
|
|
foreach (const QVariant &it, transfer.keys()) {
|
|
foreach (const Data &it2, m_transfers.values()) {
|
|
OrgKdeKgetTransferInterface* iface = m_transfers.key(it2);
|
|
if (it.toString() == it2.source) {
|
|
removed.append(iface);
|
|
|
|
m_downloadedSize -= m_transfers[iface].downloadedSize;
|
|
m_totalSize -= m_transfers[iface].size;
|
|
|
|
m_transfers.remove(iface);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (!removed.isEmpty()) {
|
|
emit transfersRemoved(removed);
|
|
emit update();
|
|
updateGlobalProgress();
|
|
}
|
|
}
|
|
|
|
void KGetApplet::slotUpdateTransfer(int transferChange)
|
|
{
|
|
OrgKdeKgetTransferInterface *transfer = qobject_cast<OrgKdeKgetTransferInterface*>(QObject::sender());
|
|
|
|
if (transfer && m_transfers.contains(transfer)) {
|
|
if (transferChange & Transfer::Tc_TotalSize) {
|
|
m_totalSize -= m_transfers[transfer].size;
|
|
m_downloadedSize -= m_transfers[transfer].downloadedSize;
|
|
|
|
m_transfers[transfer].size = transfer->totalSize();
|
|
m_transfers[transfer].downloadedSize = transfer->downloadedSize();
|
|
m_transfers[transfer].source = transfer->source();
|
|
m_totalSize += m_transfers[transfer].size;
|
|
m_downloadedSize += m_transfers[transfer].downloadedSize;
|
|
|
|
updateGlobalProgress();
|
|
return;
|
|
}
|
|
if (transferChange & Transfer::Tc_DownloadedSize) {
|
|
m_downloadedSize -= m_transfers[transfer].downloadedSize;
|
|
|
|
m_transfers[transfer].downloadedSize = transfer->downloadedSize();
|
|
m_downloadedSize += m_transfers[transfer].downloadedSize;
|
|
|
|
updateGlobalProgress();
|
|
return;
|
|
}
|
|
}
|
|
}
|
|
|
|
void KGetApplet::updateGlobalProgress()
|
|
{
|
|
if (m_globalProgress && m_totalSize) {
|
|
m_globalProgress->setValue((m_downloadedSize * 100) / m_totalSize);
|
|
}
|
|
}
|
|
|
|
void KGetApplet::setDataWidget(QGraphicsWidget * widget)
|
|
{
|
|
m_dataWidget = widget;
|
|
if (m_proxyWidget->dataWidget() != m_errorWidget)
|
|
m_proxyWidget->setDataWidget(widget);
|
|
}
|
|
|
|
void KGetApplet::constraintsEvent(Plasma::Constraints constraints)
|
|
{
|
|
if (constraints & Plasma::SizeConstraint) {
|
|
QGraphicsLayoutItem *widget = layout()->itemAt(0);
|
|
Plasma::IconWidget *icon = 0;
|
|
if (!m_icon && (icon = dynamic_cast<Plasma::IconWidget*>(widget))) {
|
|
m_icon = icon;
|
|
}
|
|
if (widget == m_proxyWidget && m_globalProgress->isVisible()) {
|
|
kDebug() << "remove progressbar";
|
|
m_globalProgress->hide();
|
|
dynamic_cast<QGraphicsLinearLayout*>(layout())->removeItem(m_globalProgress);
|
|
} else if (m_icon && m_icon->isVisible()) {
|
|
QGraphicsLinearLayout *lay = dynamic_cast<QGraphicsLinearLayout*>(layout());
|
|
kDebug() << "switch to progressbar";
|
|
m_globalProgress->show();
|
|
m_icon->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
|
|
m_icon->setPreferredSize(size().height(), size().height());
|
|
m_globalProgress->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
for (int i = 0; i != 2; i++) {
|
|
if (lay->count())
|
|
lay->removeAt(0);
|
|
}
|
|
lay->addItem(m_icon);
|
|
lay->addItem(m_globalProgress);
|
|
}
|
|
/*if (layout()->count() && dynamic_cast<Plasma::IconWidget*>(layout()->itemAt(0)) && !m_progressProxy.isVisible()) {
|
|
qobject_cast<QGraphicsLinearLayout*>(layout())->addItem(m_progressProxy);
|
|
m_progressProxy->show();
|
|
} else if (m_progressProxy.isVisible() && layout->count() == 1) {
|
|
kDebug();
|
|
layout()->removeAt(0);
|
|
m_progressProxy->hide();
|
|
}*/
|
|
}
|
|
}
|
|
|
|
bool KGetApplet::sceneEventFilter(QGraphicsItem * watched, QEvent * event)
|
|
{
|
|
Q_UNUSED(watched)
|
|
switch (event->type())
|
|
{
|
|
case QEvent::GraphicsSceneDrop:
|
|
dropEvent(static_cast<QGraphicsSceneDragDropEvent*>(event));
|
|
break;
|
|
case QEvent::Drop:
|
|
dropEvent(static_cast<QDropEvent*>(event));
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
return Plasma::Applet::sceneEventFilter(watched, event);
|
|
//This is not 100% kosher, I think we should just return false, but otherwise the plasma resize buttons etc don't show u
|
|
}
|
|
|
|
void KGetApplet::dropEvent(QGraphicsSceneDragDropEvent * event)
|
|
{
|
|
kDebug(5001);
|
|
|
|
QStringList urls;
|
|
if (event->mimeData()->hasUrls())
|
|
{
|
|
foreach (const KUrl &url, event->mimeData()->urls())
|
|
urls.append(url.url());
|
|
}
|
|
else
|
|
{
|
|
event->ignore();
|
|
return;
|
|
}
|
|
|
|
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(KGET_DBUS_SERVICE))
|
|
{
|
|
OrgKdeKgetMainInterface kget_interface(KGET_DBUS_SERVICE, KGET_DBUS_PATH,
|
|
QDBusConnection::sessionBus());
|
|
|
|
kget_interface.showNewTransferDialog(urls);
|
|
}
|
|
else
|
|
{
|
|
QProcess::startDetached("kget", urls);
|
|
}
|
|
event->accept();
|
|
}
|
|
|
|
void KGetApplet::dropEvent(QDropEvent * event)
|
|
{
|
|
kDebug(5001);
|
|
|
|
QStringList urls;
|
|
if (event->mimeData()->hasUrls())
|
|
{
|
|
foreach (const KUrl &url, event->mimeData()->urls())
|
|
urls.append(url.url());
|
|
}
|
|
else
|
|
{
|
|
event->ignore();
|
|
return;
|
|
}
|
|
|
|
if (QDBusConnection::sessionBus().interface()->isServiceRegistered(KGET_DBUS_SERVICE))
|
|
{
|
|
OrgKdeKgetMainInterface kget_interface(KGET_DBUS_SERVICE, KGET_DBUS_PATH,
|
|
QDBusConnection::sessionBus());
|
|
|
|
kget_interface.showNewTransferDialog(urls);
|
|
event->accept();
|
|
}
|
|
else
|
|
{
|
|
QProcess::startDetached("kget", urls);
|
|
}
|
|
event->accept();
|
|
}
|
|
|
|
#include "moc_kgetapplet.cpp"
|