mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-25 19:32:52 +00:00
380 lines
9.8 KiB
C++
380 lines
9.8 KiB
C++
/*
|
|
* Copyright © 2008 Rob Scheepmaker <r.scheepmaker@student.utwente.nl>
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU Library General Public License version 2 as
|
|
* published by the Free Software Foundation
|
|
*
|
|
* 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 Library 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 "jobviewadaptor.h"
|
|
#include "jobviewserveradaptor.h"
|
|
#include "kuiserverengine.h"
|
|
#include "jobcontrol.h"
|
|
|
|
#include <QDBusConnection>
|
|
|
|
#include <KJob>
|
|
|
|
#include <Plasma/DataEngine>
|
|
|
|
|
|
uint JobView::s_jobId = 0;
|
|
|
|
static const int UPDATE_INTERVAL = 100;
|
|
|
|
JobView::JobView(QObject* parent)
|
|
: Plasma::DataContainer(parent),
|
|
m_capabilities(-1),
|
|
m_percent(0),
|
|
m_speed(0),
|
|
m_totalBytes(0),
|
|
m_processedBytes(0),
|
|
m_state(UnknownState),
|
|
m_bytesUnitId(-1),
|
|
m_unitId(0)
|
|
{
|
|
m_jobId = ++s_jobId;
|
|
setObjectName(QString("Job %1").arg(s_jobId));
|
|
|
|
new JobViewV2Adaptor(this);
|
|
|
|
m_objectPath.setPath(QString("/DataEngine/applicationjobs/JobView_%1").arg(m_jobId));
|
|
QDBusConnection::sessionBus().registerObject(m_objectPath.path(), this);
|
|
|
|
setSuspended(false);
|
|
}
|
|
|
|
JobView::~JobView()
|
|
{
|
|
QDBusConnection::sessionBus().unregisterObject(m_objectPath.path(), QDBusConnection::UnregisterTree);
|
|
}
|
|
|
|
uint JobView::jobId() const
|
|
{
|
|
return m_jobId;
|
|
}
|
|
|
|
void JobView::scheduleUpdate()
|
|
{
|
|
if (!m_updateTimer.isActive()) {
|
|
m_updateTimer.start(UPDATE_INTERVAL, this);
|
|
}
|
|
}
|
|
|
|
void JobView::timerEvent(QTimerEvent *event)
|
|
{
|
|
if (event->timerId() == m_updateTimer.timerId()) {
|
|
m_updateTimer.stop();
|
|
checkForUpdate();
|
|
|
|
if (m_state == Stopped) {
|
|
emit becameUnused(objectName());
|
|
}
|
|
} else {
|
|
Plasma::DataContainer::timerEvent(event);
|
|
}
|
|
}
|
|
|
|
void JobView::terminate(const QString &errorMessage)
|
|
{
|
|
setData("error", errorMessage);
|
|
QTimer::singleShot(0, this, SLOT(finished()));
|
|
}
|
|
|
|
void JobView::finished()
|
|
{
|
|
if (m_state != Stopped) {
|
|
m_state = Stopped;
|
|
setData("state", "stopped");
|
|
setData("speed", QVariant());
|
|
setData("numericSpeed", QVariant());
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
JobView::State JobView::state()
|
|
{
|
|
return m_state;
|
|
}
|
|
|
|
void JobView::setSuspended(bool suspended)
|
|
{
|
|
if (suspended) {
|
|
if (m_state != Suspended) {
|
|
m_state = Suspended;
|
|
setData("state", "suspended");
|
|
setData("speed", QVariant());
|
|
setData("numericSpeed", QVariant());
|
|
scheduleUpdate();
|
|
}
|
|
} else if (m_state != Running) {
|
|
m_state = Running;
|
|
setData("state", "running");
|
|
setData("speed", speedString());
|
|
setData("numericSpeed", m_speed);
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
int JobView::unitId(const QString &unit)
|
|
{
|
|
int id = 0;
|
|
if (m_unitMap.contains(unit)) {
|
|
id = m_unitMap.value(unit);
|
|
} else {
|
|
id = m_unitId;
|
|
setData(QString("totalUnit%1").arg(id), unit);
|
|
setData(QString("totalAmount%1").arg(id), 0);
|
|
setData(QString("processedUnit%1").arg(id), unit);
|
|
setData(QString("processedAmount%1").arg(id), 0);
|
|
m_unitMap.insert(unit, m_unitId);
|
|
|
|
if (unit == "bytes") {
|
|
m_bytesUnitId = id;
|
|
}
|
|
|
|
++m_unitId;
|
|
scheduleUpdate();
|
|
}
|
|
|
|
return id;
|
|
}
|
|
|
|
void JobView::updateEta()
|
|
{
|
|
if (m_speed < 1) {
|
|
setData("eta", 0);
|
|
return;
|
|
}
|
|
|
|
if (m_totalBytes < 1) {
|
|
setData("eta", 0);
|
|
return;
|
|
}
|
|
|
|
const qlonglong remaining = 1000 * (m_totalBytes - m_processedBytes);
|
|
setData("eta", remaining / m_speed);
|
|
}
|
|
|
|
void JobView::setTotalAmount(qlonglong amount, const QString &unit)
|
|
{
|
|
const int id = unitId(unit);
|
|
const QString amountString = QString("totalAmount%1").arg(id);
|
|
const qlonglong prevTotal = data().value(amountString).toLongLong();
|
|
if (prevTotal != amount) {
|
|
if (id == m_bytesUnitId) {
|
|
m_totalBytes = amount;
|
|
updateEta();
|
|
}
|
|
|
|
setData(amountString, amount);
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
void JobView::setProcessedAmount(qlonglong amount, const QString &unit)
|
|
{
|
|
const int id = unitId(unit);
|
|
const QString processedString = QString("processedAmount%1").arg(id);
|
|
const qlonglong prevTotal = data().value(processedString).toLongLong();
|
|
if (prevTotal != amount) {
|
|
if (id == m_bytesUnitId) {
|
|
m_processedBytes = amount;
|
|
updateEta();
|
|
}
|
|
|
|
setData(processedString, amount);
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
void JobView::setDestUrl(const QDBusVariant & destUrl)
|
|
{
|
|
Q_UNUSED(destUrl);
|
|
}
|
|
|
|
void JobView::setPercent(uint percent)
|
|
{
|
|
if (m_percent != percent) {
|
|
m_percent = percent;
|
|
setData("percentage", m_percent);
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
void JobView::setSpeed(qlonglong bytesPerSecond)
|
|
{
|
|
if (m_speed != bytesPerSecond) {
|
|
m_speed = bytesPerSecond;
|
|
setData("speed", speedString());
|
|
setData("numericSpeed", m_speed);
|
|
|
|
if (m_bytesUnitId > -1) {
|
|
updateEta();
|
|
}
|
|
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
QString JobView::speedString() const
|
|
{
|
|
return i18nc("Byes per second", "%1/s", KGlobal::locale()->formatByteSize(m_speed));
|
|
}
|
|
|
|
void JobView::setInfoMessage(const QString &infoMessage)
|
|
{
|
|
if (data().value("infoMessage") != infoMessage) {
|
|
setData("infoMessage", infoMessage);
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
bool JobView::setDescriptionField(uint number, const QString &name, const QString &value)
|
|
{
|
|
const QString labelString = QString("label%1").arg(number);
|
|
const QString labelNameString = QString("labelName%1").arg(number);
|
|
|
|
if (!data().contains(labelNameString) || data().value(labelString) != value) {
|
|
setData(labelNameString, name);
|
|
setData(labelString, value);
|
|
scheduleUpdate();
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void JobView::clearDescriptionField(uint number)
|
|
{
|
|
const QString labelString = QString("label%1").arg(number);
|
|
const QString labelNameString = QString("labelName%1").arg(number);
|
|
|
|
setData(labelNameString, QVariant());
|
|
setData(labelString, QVariant());
|
|
scheduleUpdate();
|
|
}
|
|
|
|
void JobView::setAppName(const QString &appName)
|
|
{
|
|
// don't need to update, this is only set once at creation
|
|
setData("appName", appName);
|
|
}
|
|
|
|
void JobView::setAppIconName(const QString &appIconName)
|
|
{
|
|
// don't need to update, this is only set once at creation
|
|
setData("appIconName", appIconName);
|
|
}
|
|
|
|
void JobView::setCapabilities(int capabilities)
|
|
{
|
|
if (m_capabilities != uint(capabilities)) {
|
|
m_capabilities = capabilities;
|
|
setData("suspendable", m_capabilities & KJob::Suspendable);
|
|
setData("killable", m_capabilities & KJob::Killable);
|
|
scheduleUpdate();
|
|
}
|
|
}
|
|
|
|
QDBusObjectPath JobView::objectPath() const
|
|
{
|
|
return m_objectPath;
|
|
}
|
|
|
|
void JobView::requestStateChange(State state)
|
|
{
|
|
switch (state) {
|
|
case Running:
|
|
emit resumeRequested();
|
|
break;
|
|
case Suspended:
|
|
emit suspendRequested();
|
|
break;
|
|
case Stopped:
|
|
emit cancelRequested();
|
|
break;
|
|
default:
|
|
break;
|
|
}
|
|
}
|
|
|
|
KuiserverEngine::KuiserverEngine(QObject* parent, const QVariantList& args)
|
|
: Plasma::DataEngine(parent, args)
|
|
{
|
|
new JobViewServerAdaptor(this);
|
|
|
|
QDBusConnection bus = QDBusConnection::sessionBus();
|
|
bus.registerObject(QLatin1String("/DataEngine/applicationjobs/JobWatcher"), this);
|
|
|
|
setMinimumPollingInterval(500);
|
|
|
|
m_pendingJobsTimer.setSingleShot(true);
|
|
m_pendingJobsTimer.setInterval(500);
|
|
connect(&m_pendingJobsTimer, SIGNAL(timeout()), this, SLOT(processPendingJobs()));
|
|
}
|
|
|
|
KuiserverEngine::~KuiserverEngine()
|
|
{
|
|
QDBusConnection::sessionBus()
|
|
.unregisterObject(QLatin1String("/DataEngine/applicationjobs/JobWatcher"), QDBusConnection::UnregisterTree);
|
|
qDeleteAll(m_pendingJobs);
|
|
}
|
|
|
|
QDBusObjectPath KuiserverEngine::requestView(const QString &appName,
|
|
const QString &appIconName, int capabilities)
|
|
{
|
|
JobView *jobView = new JobView(this);
|
|
jobView->setAppName(appName);
|
|
jobView->setAppIconName(appIconName);
|
|
jobView->setCapabilities(capabilities);
|
|
connect(jobView, SIGNAL(becameUnused(QString)), this, SLOT(removeSource(QString)));
|
|
|
|
m_pendingJobs << jobView;
|
|
m_pendingJobsTimer.start();
|
|
|
|
return jobView->objectPath();
|
|
}
|
|
|
|
void KuiserverEngine::processPendingJobs()
|
|
{
|
|
foreach (JobView *jobView, m_pendingJobs) {
|
|
if (jobView->state() == JobView::Stopped) {
|
|
delete jobView;
|
|
} else {
|
|
addSource(jobView);
|
|
}
|
|
}
|
|
|
|
m_pendingJobs.clear();
|
|
}
|
|
|
|
Plasma::Service* KuiserverEngine::serviceForSource(const QString& source)
|
|
{
|
|
JobView *jobView = qobject_cast<JobView *>(containerForSource(source));
|
|
if (jobView) {
|
|
return new JobControl(this, jobView);
|
|
} else {
|
|
return DataEngine::serviceForSource(source);
|
|
}
|
|
}
|
|
|
|
void KuiserverEngine::init()
|
|
{
|
|
// register with the Job UI Serer to receive notifications of jobs becoming available
|
|
QDBusInterface interface("org.kde.kuiserver", "/JobViewServer"/* object to connect to */,
|
|
""/* use the default interface */, QDBusConnection::sessionBus(), this);
|
|
interface.asyncCall(QLatin1String("registerService"), QDBusConnection::sessionBus().baseService(), "/DataEngine/applicationjobs/JobWatcher");
|
|
}
|
|
|
|
K_EXPORT_PLASMA_DATAENGINE(kuiserver, KuiserverEngine)
|
|
|
|
#include "moc_kuiserverengine.cpp"
|