2023-09-16 15:06:34 +03:00
|
|
|
/* This file is part of the KDE project
|
|
|
|
Copyright (C) 2023 Ivailo Monev <xakepa10@gmail.com>
|
|
|
|
|
|
|
|
This library 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 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 "jobswidget.h"
|
|
|
|
|
2024-04-07 23:36:44 +03:00
|
|
|
#include <QDBusConnection>
|
2023-09-17 10:28:33 +03:00
|
|
|
#include <QGraphicsGridLayout>
|
2023-09-18 14:17:05 +03:00
|
|
|
#include <Plasma/Animation>
|
2024-04-08 11:29:04 +03:00
|
|
|
#include <KLocale>
|
2023-09-17 14:32:10 +03:00
|
|
|
#include <KRun>
|
2023-09-17 10:28:33 +03:00
|
|
|
#include <KIconLoader>
|
|
|
|
#include <KIcon>
|
2024-03-20 01:14:01 +02:00
|
|
|
#include <KMimeType>
|
2023-09-16 15:06:34 +03:00
|
|
|
#include <KDebug>
|
|
|
|
|
2023-09-17 18:30:25 +03:00
|
|
|
JobFrame::JobFrame(const QString &_name, QGraphicsWidget *parent)
|
|
|
|
: Plasma::Frame(parent),
|
|
|
|
iconwidget(nullptr),
|
|
|
|
label(nullptr),
|
2023-09-18 20:04:35 +03:00
|
|
|
iconwidget0(nullptr),
|
|
|
|
iconwidget1(nullptr),
|
2023-09-17 18:30:25 +03:00
|
|
|
meter(nullptr),
|
|
|
|
name(_name)
|
2023-09-16 15:06:34 +03:00
|
|
|
{
|
2023-09-17 18:30:25 +03:00
|
|
|
JobsWidget* jobswidget = qobject_cast<JobsWidget*>(parent);
|
2023-09-16 15:06:34 +03:00
|
|
|
|
2023-09-18 11:16:10 +03:00
|
|
|
setFrameShadow(Plasma::Frame::Sunken);
|
2023-09-17 18:30:25 +03:00
|
|
|
setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
QGraphicsGridLayout* framelayout = new QGraphicsGridLayout(this);
|
2023-09-16 15:06:34 +03:00
|
|
|
|
2023-09-17 18:30:25 +03:00
|
|
|
iconwidget = new Plasma::IconWidget(this);
|
2023-09-17 10:28:33 +03:00
|
|
|
iconwidget->setAcceptHoverEvents(false);
|
|
|
|
iconwidget->setAcceptedMouseButtons(Qt::NoButton);
|
|
|
|
iconwidget->setIcon(KIcon("services"));
|
|
|
|
const int desktopiconsize = KIconLoader::global()->currentSize(KIconLoader::Desktop);
|
|
|
|
const QSizeF desktopiconsizef = QSizeF(desktopiconsize, desktopiconsize);
|
|
|
|
iconwidget->setPreferredIconSize(desktopiconsizef);
|
|
|
|
iconwidget->setMinimumSize(desktopiconsizef);
|
|
|
|
iconwidget->setMaximumSize(desktopiconsizef);
|
|
|
|
iconwidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
framelayout->addItem(iconwidget, 0, 0, 2, 1);
|
|
|
|
|
2023-09-17 18:30:25 +03:00
|
|
|
label = new Plasma::Label(this);
|
2023-09-17 13:45:48 +03:00
|
|
|
label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
|
|
|
label->setAlignment(Qt::AlignLeft | Qt::AlignTop);
|
2023-09-19 17:54:32 +03:00
|
|
|
label->nativeWidget()->setOpenExternalLinks(true);
|
2023-09-17 14:32:10 +03:00
|
|
|
framelayout->addItem(label, 0, 1, 3, 1);
|
2023-09-17 10:28:33 +03:00
|
|
|
|
|
|
|
const int smalliconsize = KIconLoader::global()->currentSize(KIconLoader::Small);
|
2023-09-18 20:04:35 +03:00
|
|
|
iconwidget0 = new Plasma::IconWidget(this);
|
|
|
|
iconwidget0->setMaximumIconSize(QSize(smalliconsize, smalliconsize));
|
|
|
|
iconwidget0->setIcon(KIcon("task-reject"));
|
|
|
|
iconwidget0->setToolTip(i18n("Click to stop the job."));
|
|
|
|
iconwidget0->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
iconwidget0->setVisible(false);
|
2023-09-17 10:28:33 +03:00
|
|
|
connect(
|
2023-09-18 20:04:35 +03:00
|
|
|
iconwidget0, SIGNAL(activated()),
|
|
|
|
jobswidget, SLOT(slotIcon0Activated())
|
2023-09-17 10:28:33 +03:00
|
|
|
);
|
2023-09-18 20:04:35 +03:00
|
|
|
framelayout->addItem(iconwidget0, 0, 2, 1, 1);
|
2023-09-17 10:28:33 +03:00
|
|
|
|
2023-09-18 20:04:35 +03:00
|
|
|
iconwidget1 = new Plasma::IconWidget(this);
|
|
|
|
iconwidget1->setMaximumIconSize(QSize(smalliconsize, smalliconsize));
|
|
|
|
iconwidget1->setIcon(KIcon("task-complete"));
|
|
|
|
iconwidget1->setToolTip(i18n("The job has completed."));
|
|
|
|
iconwidget1->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
|
|
|
iconwidget1->setVisible(false);
|
2023-09-17 14:32:10 +03:00
|
|
|
connect(
|
2023-09-18 20:04:35 +03:00
|
|
|
iconwidget1, SIGNAL(activated()),
|
|
|
|
jobswidget, SLOT(slotIcon1Activated())
|
2023-09-17 14:32:10 +03:00
|
|
|
);
|
2023-09-18 20:04:35 +03:00
|
|
|
framelayout->addItem(iconwidget1, 1, 2, 1, 1);
|
2023-09-17 14:32:10 +03:00
|
|
|
|
2023-09-17 18:30:25 +03:00
|
|
|
meter = new Plasma::Meter(this);
|
2023-09-17 10:28:33 +03:00
|
|
|
meter->setMeterType(Plasma::Meter::BarMeterHorizontal);
|
|
|
|
meter->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Minimum);
|
|
|
|
meter->setMinimum(0);
|
|
|
|
meter->setMaximum(100);
|
2023-09-17 14:32:10 +03:00
|
|
|
meter->setVisible(false);
|
|
|
|
framelayout->addItem(meter, 4, 0, 1, 3);
|
2023-09-17 10:28:33 +03:00
|
|
|
|
2023-09-17 18:30:25 +03:00
|
|
|
setLayout(framelayout);
|
|
|
|
}
|
|
|
|
|
2023-09-18 14:17:05 +03:00
|
|
|
void JobFrame::animateRemove()
|
|
|
|
{
|
|
|
|
Plasma::Animation *animation = Plasma::Animator::create(Plasma::Animator::FadeAnimation);
|
|
|
|
Q_ASSERT(animation != nullptr);
|
|
|
|
JobsWidget* jobswidget = qobject_cast<JobsWidget*>(parentObject());
|
2023-09-18 20:04:35 +03:00
|
|
|
disconnect(iconwidget0, 0, jobswidget, 0);
|
|
|
|
disconnect(iconwidget1, 0, jobswidget, 0);
|
2023-09-18 14:17:05 +03:00
|
|
|
|
2023-09-18 14:38:45 +03:00
|
|
|
connect(animation, SIGNAL(finished()), this, SLOT(deleteLater()));
|
2023-09-18 14:17:05 +03:00
|
|
|
animation->setTargetWidget(this);
|
|
|
|
animation->setProperty("startOpacity", 1.0);
|
|
|
|
animation->setProperty("targetOpacity", 0.0);
|
|
|
|
animation->start(QAbstractAnimation::DeleteWhenStopped);
|
|
|
|
}
|
|
|
|
|
2023-09-17 18:30:25 +03:00
|
|
|
|
|
|
|
JobsWidget::JobsWidget(QGraphicsItem *parent, NotificationsWidget *notificationswidget)
|
|
|
|
: QGraphicsWidget(parent),
|
|
|
|
m_notificationswidget(notificationswidget),
|
|
|
|
m_layout(nullptr),
|
|
|
|
m_label(nullptr),
|
2024-04-07 23:36:44 +03:00
|
|
|
m_adaptor(nullptr)
|
2023-09-17 18:30:25 +03:00
|
|
|
{
|
|
|
|
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout = new QGraphicsLinearLayout(Qt::Vertical, this);
|
|
|
|
m_layout->setContentsMargins(0, 0, 0, 0);
|
|
|
|
m_label = new Plasma::Label(this);
|
|
|
|
m_label->setText(i18n("No job notifications"));
|
|
|
|
m_label->setAlignment(Qt::AlignCenter);
|
|
|
|
m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
|
|
|
m_layout->addItem(m_label);
|
|
|
|
setLayout(m_layout);
|
|
|
|
|
2024-04-07 23:36:44 +03:00
|
|
|
m_adaptor = new JobTrackerAdaptor(this);
|
|
|
|
connect(
|
|
|
|
m_adaptor, SIGNAL(jobAdded(QString)),
|
|
|
|
this, SLOT(slotJobAdded(QString))
|
|
|
|
);
|
2023-09-17 18:30:25 +03:00
|
|
|
connect(
|
2024-04-07 23:36:44 +03:00
|
|
|
m_adaptor, SIGNAL(jobUpdated(QString,QVariantMap)),
|
|
|
|
this, SLOT(slotJobUpdated(QString,QVariantMap))
|
2023-09-17 18:30:25 +03:00
|
|
|
);
|
2024-04-07 23:36:44 +03:00
|
|
|
QDBusConnection session = QDBusConnection::sessionBus();
|
|
|
|
session.registerObject("/JobTracker", this);
|
2023-09-17 18:30:25 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
JobsWidget::~JobsWidget()
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
int JobsWidget::count() const
|
|
|
|
{
|
|
|
|
return m_frames.size();
|
|
|
|
}
|
|
|
|
|
2024-04-07 23:36:44 +03:00
|
|
|
void JobsWidget::slotJobAdded(const QString &name)
|
2023-09-17 18:30:25 +03:00
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
JobFrame* frame = new JobFrame(name, this);
|
2023-09-18 14:17:05 +03:00
|
|
|
connect(
|
|
|
|
frame, SIGNAL(destroyed()),
|
|
|
|
this, SLOT(slotFrameDestroyed())
|
|
|
|
);
|
2023-09-17 10:28:33 +03:00
|
|
|
m_frames.append(frame);
|
|
|
|
m_label->setVisible(false);
|
|
|
|
m_layout->insertItem(0, frame);
|
|
|
|
adjustSize();
|
|
|
|
|
|
|
|
emit countChanged();
|
2023-09-16 15:06:34 +03:00
|
|
|
}
|
|
|
|
|
2024-04-07 23:36:44 +03:00
|
|
|
void JobsWidget::slotJobUpdated(const QString &name, const QVariantMap &data)
|
2023-09-16 15:06:34 +03:00
|
|
|
{
|
2023-09-17 10:28:33 +03:00
|
|
|
QMutexLocker locker(&m_mutex);
|
2023-09-17 18:30:25 +03:00
|
|
|
foreach (JobFrame* frame, m_frames) {
|
2023-09-17 21:43:13 +03:00
|
|
|
if (frame->name == name) {
|
2023-09-17 11:57:36 +03:00
|
|
|
const QString infomessage = data.value("infoMessage").toString();
|
|
|
|
frame->setText(infomessage);
|
2023-09-17 10:28:33 +03:00
|
|
|
const QString appiconname = data.value("appIconName").toString();
|
|
|
|
if (!appiconname.isEmpty()) {
|
2023-09-17 18:30:25 +03:00
|
|
|
frame->iconwidget->setIcon(appiconname);
|
2023-09-17 10:28:33 +03:00
|
|
|
}
|
|
|
|
const QString labelname0 = data.value("labelName0").toString();
|
2023-09-17 13:45:48 +03:00
|
|
|
const QString labelname1 = data.value("labelName1").toString();
|
|
|
|
if (!labelname0.isEmpty() && !labelname1.isEmpty()) {
|
2023-09-17 18:30:25 +03:00
|
|
|
frame->label->setText(
|
2023-09-17 10:28:33 +03:00
|
|
|
i18n(
|
2023-09-17 13:45:48 +03:00
|
|
|
"<p><b>%1:</b> <i>%2</i></p><p><b>%3:</b> <i>%4</i></p>",
|
|
|
|
labelname0, data.value("label0").toString(),
|
|
|
|
labelname1, data.value("label1").toString()
|
2023-09-17 10:28:33 +03:00
|
|
|
)
|
|
|
|
);
|
2023-09-17 13:45:48 +03:00
|
|
|
} else if (!labelname0.isEmpty()) {
|
2023-09-17 18:30:25 +03:00
|
|
|
frame->label->setText(
|
2023-09-17 10:28:33 +03:00
|
|
|
i18n(
|
2023-09-17 13:45:48 +03:00
|
|
|
"<b>%1:</b> <i>%2</i>",
|
|
|
|
labelname0, data.value("label0").toString()
|
|
|
|
)
|
|
|
|
);
|
|
|
|
} else if (!labelname1.isEmpty()) {
|
2023-09-17 18:30:25 +03:00
|
|
|
frame->label->setText(
|
2023-09-17 13:45:48 +03:00
|
|
|
i18n(
|
|
|
|
"<b>%1:</b> <i>%2</i>",
|
|
|
|
labelname1, data.value("label1").toString()
|
2023-09-17 10:28:33 +03:00
|
|
|
)
|
|
|
|
);
|
|
|
|
}
|
2023-09-17 14:32:10 +03:00
|
|
|
const uint percentage = data.value("percentage").toUInt();
|
|
|
|
if (percentage > 0) {
|
2023-09-17 18:30:25 +03:00
|
|
|
frame->meter->setVisible(true);
|
|
|
|
frame->meter->setValue(percentage);
|
2023-09-17 14:32:10 +03:00
|
|
|
}
|
2023-09-17 10:43:06 +03:00
|
|
|
const QByteArray state = data.value("state").toByteArray();
|
2023-09-18 19:35:33 +03:00
|
|
|
const bool killable = data.value("killable").toBool();
|
2023-09-18 20:04:35 +03:00
|
|
|
if (killable) {
|
|
|
|
frame->iconwidget0->setVisible(true);
|
|
|
|
}
|
2023-09-17 10:43:06 +03:00
|
|
|
if (state == "stopped") {
|
2023-09-18 20:04:35 +03:00
|
|
|
frame->iconwidget0->setIcon(KIcon("dialog-close"));
|
|
|
|
frame->iconwidget0->setToolTip(i18n("Click to remove this job notification."));
|
|
|
|
frame->iconwidget0->setProperty("_k_stopped", true);
|
|
|
|
|
|
|
|
frame->iconwidget1->setVisible(true);
|
2023-09-17 14:32:10 +03:00
|
|
|
const QString desturl = data.value("destUrl").toString();
|
|
|
|
if (!desturl.isEmpty()) {
|
2023-09-18 20:04:35 +03:00
|
|
|
frame->iconwidget1->setProperty("_k_desturl", desturl);
|
|
|
|
frame->iconwidget1->setIcon(KIcon("system-file-manager"));
|
|
|
|
frame->iconwidget1->setToolTip(i18n("Click to open the destination of the job."));
|
2023-09-18 19:35:33 +03:00
|
|
|
} else {
|
2023-09-18 20:04:35 +03:00
|
|
|
frame->iconwidget1->setAcceptHoverEvents(false);
|
|
|
|
frame->iconwidget1->setAcceptedMouseButtons(Qt::NoButton);
|
2023-09-17 14:32:10 +03:00
|
|
|
}
|
2023-09-18 19:35:33 +03:00
|
|
|
}
|
2023-09-27 18:06:04 +03:00
|
|
|
// error overrides everything iconwidget1 does
|
2023-09-18 19:35:33 +03:00
|
|
|
const QString error = data.value("error").toString();
|
|
|
|
if (!error.isEmpty()) {
|
2023-09-18 20:04:35 +03:00
|
|
|
frame->iconwidget1->setVisible(false);
|
|
|
|
frame->iconwidget1->setAcceptHoverEvents(false);
|
|
|
|
frame->iconwidget1->setAcceptedMouseButtons(Qt::NoButton);
|
|
|
|
frame->iconwidget1->setIcon(KIcon("task-attention"));
|
|
|
|
frame->iconwidget1->setToolTip(error);
|
2023-09-17 10:28:33 +03:00
|
|
|
}
|
2023-09-17 15:31:02 +03:00
|
|
|
frame->adjustSize();
|
2023-09-18 11:39:02 +03:00
|
|
|
adjustSize();
|
2023-09-17 10:28:33 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2023-09-18 14:17:05 +03:00
|
|
|
void JobsWidget::slotFrameDestroyed()
|
|
|
|
{
|
|
|
|
m_label->setVisible(m_frames.size() <= 0);
|
|
|
|
adjustSize();
|
|
|
|
emit countChanged();
|
|
|
|
}
|
|
|
|
|
2023-09-18 20:04:35 +03:00
|
|
|
void JobsWidget::slotIcon0Activated()
|
2023-09-17 10:28:33 +03:00
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
2023-09-18 20:04:35 +03:00
|
|
|
const Plasma::IconWidget* iconwidget0 = qobject_cast<Plasma::IconWidget*>(sender());
|
|
|
|
const bool stopped = iconwidget0->property("_k_stopped").toBool();
|
|
|
|
JobFrame* jobframe = qobject_cast<JobFrame*>(iconwidget0->parentObject());
|
2023-09-17 18:30:25 +03:00
|
|
|
Q_ASSERT(jobframe != nullptr);
|
2023-09-18 20:04:35 +03:00
|
|
|
if (!stopped) {
|
2024-04-07 23:36:44 +03:00
|
|
|
m_adaptor->stopJob(jobframe->name);
|
2023-09-18 19:35:33 +03:00
|
|
|
} else {
|
2023-09-18 20:04:35 +03:00
|
|
|
QMutableListIterator<JobFrame*> iter(m_frames);
|
|
|
|
while (iter.hasNext()) {
|
|
|
|
JobFrame* frame = iter.next();
|
|
|
|
if (frame == jobframe) {
|
|
|
|
iter.remove();
|
2023-10-03 05:36:17 +03:00
|
|
|
frame->animateRemove();
|
2023-09-18 20:04:35 +03:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2023-09-18 19:35:33 +03:00
|
|
|
}
|
2023-09-17 13:45:48 +03:00
|
|
|
}
|
|
|
|
|
2023-09-18 20:04:35 +03:00
|
|
|
void JobsWidget::slotIcon1Activated()
|
|
|
|
{
|
|
|
|
QMutexLocker locker(&m_mutex);
|
|
|
|
const Plasma::IconWidget* iconwidget1 = qobject_cast<Plasma::IconWidget*>(sender());
|
2024-03-20 01:14:01 +02:00
|
|
|
const KUrl desturl = KUrl(iconwidget1->property("_k_desturl").toString());
|
2023-09-18 20:04:35 +03:00
|
|
|
locker.unlock();
|
2024-03-20 01:14:01 +02:00
|
|
|
const KMimeType::Ptr kmimetype = KMimeType::findByUrl(desturl);
|
|
|
|
Q_ASSERT(kmimetype);
|
|
|
|
KRun::runUrl(desturl, kmimetype->name(), nullptr);
|
2023-09-18 20:04:35 +03:00
|
|
|
}
|
|
|
|
|
2023-09-16 15:06:34 +03:00
|
|
|
#include "moc_jobswidget.cpp"
|