/*************************************************************************** * * * 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 * * * 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 #include #include #include #include #include #include #include #include #include #include #include #include #include #include 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 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 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(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(widget))) { m_icon = icon; } if (widget == m_proxyWidget && m_globalProgress->isVisible()) { kDebug() << "remove progressbar"; m_globalProgress->hide(); dynamic_cast(layout())->removeItem(m_globalProgress); } else if (m_icon && m_icon->isVisible()) { QGraphicsLinearLayout *lay = dynamic_cast(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(layout()->itemAt(0)) && !m_progressProxy.isVisible()) { qobject_cast(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(event)); break; case QEvent::Drop: dropEvent(static_cast(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"