mirror of
https://bitbucket.org/smil3y/kde-workspace.git
synced 2025-02-24 02:42:50 +00:00
plasma: semi-working notifications applet reimplementation
the application notifications works and is nearly complete, the jobs notification is yet to be done. so far it looks like this: https://ibb.co/GTGMKtQ Signed-off-by: Ivailo Monev <xakepa10@gmail.com>
This commit is contained in:
parent
5ce20a5331
commit
f4d40c28e9
46 changed files with 656 additions and 3961 deletions
|
@ -1,6 +1,5 @@
|
|||
project(batterymonitor)
|
||||
|
||||
|
||||
set(batterymonitor_SRCS
|
||||
batterymonitor.cpp
|
||||
)
|
||||
|
|
|
@ -1,2 +1,23 @@
|
|||
installPackage(. org.kde.notifications)
|
||||
project(plasma-applet-notifications)
|
||||
|
||||
set(notifications_SRCS
|
||||
notifications.cpp
|
||||
jobswidget.cpp
|
||||
applicationswidget.cpp
|
||||
)
|
||||
|
||||
kde4_add_plugin(plasma_applet_notifications ${notifications_SRCS})
|
||||
target_link_libraries(plasma_applet_notifications
|
||||
KDE4::plasma
|
||||
KDE4::kio
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS plasma_applet_notifications
|
||||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
||||
)
|
||||
|
||||
install(
|
||||
FILES plasma-applet-notifications.desktop
|
||||
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
|
||||
)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
#!/bin/bash
|
||||
$EXTRACTRC `find . -name \*.rc -o -name \*.ui -o -name \*.kcfg` >> rc.cpp
|
||||
$XGETTEXT `find . -name \*.qml` -L Java -o $podir/plasma_applet_org.kde.notifications.pot
|
||||
$XGETTEXT rc.cpp -jo $podir/plasma_applet_org.kde.notifications.pot
|
||||
$XGETTEXT `find . -name \*.js -o -name \*.qml -o -name \*.cpp` -o $podir/plasma_applet_notifications.pot
|
||||
rm -f rc.cpp
|
||||
|
|
278
plasma/applets/notifications/applicationswidget.cpp
Normal file
278
plasma/applets/notifications/applicationswidget.cpp
Normal file
|
@ -0,0 +1,278 @@
|
|||
/* 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 "applicationswidget.h"
|
||||
|
||||
#include <QGraphicsGridLayout>
|
||||
#include <Plasma/DataEngineManager>
|
||||
#include <Plasma/IconWidget>
|
||||
#include <Plasma/ToolButton>
|
||||
#include <KIcon>
|
||||
#include <KNotificationConfigWidget>
|
||||
#include <KDebug>
|
||||
|
||||
Q_DECLARE_METATYPE(Plasma::IconWidget*)
|
||||
Q_DECLARE_METATYPE(Plasma::Label*)
|
||||
|
||||
ApplicationsWidget::ApplicationsWidget(QGraphicsItem *parent, NotificationsWidget *notificationswidget)
|
||||
: QGraphicsWidget(parent),
|
||||
m_notificationswidget(notificationswidget),
|
||||
m_layout(nullptr),
|
||||
m_label(nullptr),
|
||||
m_dataengine(nullptr)
|
||||
{
|
||||
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 application notifications"));
|
||||
m_label->setAlignment(Qt::AlignCenter);
|
||||
m_label->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
m_layout->addItem(m_label);
|
||||
m_layout->addStretch();
|
||||
setLayout(m_layout);
|
||||
|
||||
m_dataengine = Plasma::DataEngineManager::self()->loadEngine("notifications");
|
||||
if (!m_dataengine) {
|
||||
kWarning() << "Could not load notifications data engine";
|
||||
return;
|
||||
}
|
||||
connect(
|
||||
m_dataengine, SIGNAL(sourceAdded(QString)),
|
||||
this, SLOT(sourceAdded(QString))
|
||||
);
|
||||
}
|
||||
|
||||
ApplicationsWidget::~ApplicationsWidget()
|
||||
{
|
||||
if (m_dataengine) {
|
||||
Plasma::DataEngineManager::self()->unloadEngine("notifications");
|
||||
}
|
||||
}
|
||||
|
||||
int ApplicationsWidget::count() const
|
||||
{
|
||||
return m_frames.size();
|
||||
}
|
||||
|
||||
void ApplicationsWidget::sourceAdded(const QString &name)
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << name;
|
||||
QMutexLocker locker(&m_mutex);
|
||||
Plasma::Frame* frame = new Plasma::Frame(this);
|
||||
frame->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
frame->setProperty("_k_name", name);
|
||||
|
||||
QGraphicsGridLayout* framelayout = new QGraphicsGridLayout(frame);
|
||||
|
||||
Plasma::IconWidget* iconwidget = new Plasma::IconWidget(frame);
|
||||
iconwidget->setAcceptHoverEvents(false);
|
||||
iconwidget->setAcceptedMouseButtons(Qt::NoButton);
|
||||
iconwidget->setIcon(KIcon("dialog-information"));
|
||||
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);
|
||||
frame->setProperty("_k_iconwidget", QVariant::fromValue(iconwidget));
|
||||
|
||||
Plasma::Label* bodylabel = new Plasma::Label(frame);
|
||||
bodylabel->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Minimum);
|
||||
bodylabel->setAlignment(Qt::AlignTop | Qt::AlignHCenter);
|
||||
framelayout->addItem(bodylabel, 0, 1, 3, 1);
|
||||
frame->setProperty("_k_bodylabel", QVariant::fromValue(bodylabel));
|
||||
|
||||
const int smalliconsize = KIconLoader::global()->currentSize(KIconLoader::Small);
|
||||
Plasma::IconWidget* removewidget = new Plasma::IconWidget(frame);
|
||||
removewidget->setMaximumIconSize(QSize(smalliconsize, smalliconsize));
|
||||
removewidget->setIcon(KIcon("dialog-close"));
|
||||
removewidget->setToolTip(i18n("Click to remove this notification."));
|
||||
removewidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
connect(
|
||||
removewidget, SIGNAL(activated()),
|
||||
this, SLOT(slotRemoveActivated())
|
||||
);
|
||||
framelayout->addItem(removewidget, 0, 2, 1, 1);
|
||||
frame->setProperty("_k_removewidget", QVariant::fromValue(removewidget));
|
||||
|
||||
Plasma::IconWidget* configurewidget = new Plasma::IconWidget(frame);
|
||||
configurewidget->setMaximumIconSize(QSize(smalliconsize, smalliconsize));
|
||||
configurewidget->setIcon(KIcon("configure"));
|
||||
configurewidget->setToolTip(i18n("Click to configure this notification."));
|
||||
configurewidget->setSizePolicy(QSizePolicy::Minimum, QSizePolicy::Minimum);
|
||||
configurewidget->setVisible(false);
|
||||
connect(
|
||||
configurewidget, SIGNAL(activated()),
|
||||
this, SLOT(slotConfigureActivated())
|
||||
);
|
||||
framelayout->addItem(configurewidget, 1, 2, 1, 1);
|
||||
frame->setProperty("_k_configurewidget", QVariant::fromValue(configurewidget));
|
||||
|
||||
frame->setLayout(framelayout);
|
||||
m_frames.append(frame);
|
||||
m_label->setVisible(false);
|
||||
m_layout->insertItem(0, frame);
|
||||
adjustSize();
|
||||
|
||||
emit countChanged();
|
||||
locker.unlock();
|
||||
m_dataengine->connectSource(name, this);
|
||||
}
|
||||
|
||||
void ApplicationsWidget::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data)
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << name << data;
|
||||
#if 0
|
||||
// sample data
|
||||
"notification 1" QHash(
|
||||
("appName", QVariant(QString, "Изтегляне на файлове (KGet)") )
|
||||
( "body" , QVariant(QString, "<p>Изтеглянето на следният файл завърши:</p><p style="font-size: small;">index.html</p>") )
|
||||
( "appIcon" , QVariant(QString, "kget") )
|
||||
( "appRealName" , QVariant(QString, "kget") )
|
||||
( "image" , QVariant(QImage, ) )
|
||||
( "actions" , QVariant(QStringList, () ) )
|
||||
( "summary" , QVariant(QString, "Изтеглянето завърши") )
|
||||
( "expireTimeout" , QVariant(int, 6240) )
|
||||
( "id" , QVariant(QString, "1") )
|
||||
( "configurable" , QVariant(bool, true) )
|
||||
)
|
||||
#endif
|
||||
QMutexLocker locker(&m_mutex);
|
||||
foreach (Plasma::Frame* frame, m_frames) {
|
||||
const QString framename = frame->property("_k_name").toString();
|
||||
if (framename == name) {
|
||||
Plasma::IconWidget* iconwidget = qvariant_cast<Plasma::IconWidget*>(frame->property("_k_iconwidget"));
|
||||
const QString appicon = data.value("appIcon").toString();
|
||||
if (!appicon.isEmpty()) {
|
||||
iconwidget->setIcon(appicon);
|
||||
}
|
||||
const QStringList actions = data.value("actions").toStringList();
|
||||
// qDebug() << Q_FUNC_INFO << actions;
|
||||
QGraphicsGridLayout* framelayout = static_cast<QGraphicsGridLayout*>(frame->layout());
|
||||
Q_ASSERT(framelayout != nullptr);
|
||||
QGraphicsLinearLayout* buttonslayout = nullptr;
|
||||
// row insertation starts at 0, count is +1
|
||||
if (framelayout->rowCount() >= 4) {
|
||||
buttonslayout = static_cast<QGraphicsLinearLayout*>(framelayout->itemAt(3, 0));
|
||||
}
|
||||
if (buttonslayout) {
|
||||
// remove buttons in case of notification update
|
||||
QList<Plasma::ToolButton*> actionbuttons;
|
||||
for (int i = 0; i < buttonslayout->count(); i++) {
|
||||
Plasma::ToolButton* actionbutton = static_cast<Plasma::ToolButton*>(buttonslayout->itemAt(i));
|
||||
actionbuttons.append(actionbutton);
|
||||
buttonslayout->removeAt(i);
|
||||
}
|
||||
qDeleteAll(actionbuttons);
|
||||
actionbuttons.clear();
|
||||
}
|
||||
for (int i = 0; i < actions.size(); i++) {
|
||||
const QString actionid = actions[i];
|
||||
i++;
|
||||
const QString actionname = actions[i];
|
||||
if (actionid.isEmpty() || actionname.isEmpty()) {
|
||||
kWarning() << "Empty action ID or name" << actionid << actionname;
|
||||
continue;
|
||||
}
|
||||
|
||||
Plasma::ToolButton* actionbutton = new Plasma::ToolButton(frame);
|
||||
actionbutton->setProperty("_k_name", framename);
|
||||
actionbutton->setProperty("_k_actionid", actionid);
|
||||
actionbutton->setText(actionname);
|
||||
connect(
|
||||
actionbutton, SIGNAL(clicked()),
|
||||
this, SLOT(slotActionClicked())
|
||||
);
|
||||
if (!buttonslayout) {
|
||||
buttonslayout = new QGraphicsLinearLayout(Qt::Horizontal, framelayout);
|
||||
}
|
||||
buttonslayout->addItem(actionbutton);
|
||||
}
|
||||
if (buttonslayout) {
|
||||
framelayout->addItem(buttonslayout, 3, 0, 1, 3);
|
||||
framelayout->setAlignment(buttonslayout, Qt::AlignCenter);
|
||||
}
|
||||
Plasma::Label* label = qvariant_cast<Plasma::Label*>(frame->property("_k_bodylabel"));
|
||||
label->setText(data.value("body").toString());
|
||||
Plasma::IconWidget* configurewidget = qvariant_cast<Plasma::IconWidget*>(frame->property("_k_configurewidget"));
|
||||
const bool configurable = data.value("configurable").toBool();
|
||||
configurewidget->setVisible(configurable);
|
||||
if (configurable) {
|
||||
configurewidget->setProperty("_k_apprealname", data.value("appRealName"));
|
||||
}
|
||||
frame->adjustSize();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ApplicationsWidget::slotRemoveActivated()
|
||||
{
|
||||
QMutexLocker locker(&m_mutex);
|
||||
const Plasma::IconWidget* removewidget = qobject_cast<Plasma::IconWidget*>(sender());
|
||||
Plasma::Frame* removeframe = qobject_cast<Plasma::Frame*>(removewidget->parentObject());
|
||||
Q_ASSERT(removeframe != nullptr);
|
||||
QMutableListIterator<Plasma::Frame*> iter(m_frames);
|
||||
while (iter.hasNext()) {
|
||||
Plasma::Frame* frame = iter.next();
|
||||
if (frame == removeframe) {
|
||||
const QString framename = removeframe->property("_k_name").toString();
|
||||
Plasma::Service* plasmaservice = m_dataengine->serviceForSource(framename);
|
||||
if (!plasmaservice) {
|
||||
kWarning() << "Could not get service for" << framename;
|
||||
} else {
|
||||
const QVariantMap plasmaserviceargs = plasmaservice->operationParameters("userClosed");
|
||||
(void)plasmaservice->startOperationCall("userClosed", plasmaserviceargs);
|
||||
}
|
||||
m_layout->removeItem(frame);
|
||||
frame->deleteLater();
|
||||
iter.remove();
|
||||
break;
|
||||
}
|
||||
}
|
||||
m_label->setVisible(m_frames.size() <= 0);
|
||||
adjustSize();
|
||||
emit countChanged();
|
||||
}
|
||||
|
||||
void ApplicationsWidget::slotConfigureActivated()
|
||||
{
|
||||
const Plasma::IconWidget* configurewidget = qobject_cast<Plasma::IconWidget*>(sender());
|
||||
const QString frameapprealname = configurewidget->property("_k_apprealname").toString();
|
||||
KNotificationConfigWidget::configure(frameapprealname, nullptr);
|
||||
}
|
||||
|
||||
void ApplicationsWidget::slotActionClicked()
|
||||
{
|
||||
const Plasma::ToolButton* actionbutton = qobject_cast<Plasma::ToolButton*>(sender());
|
||||
const QString framename = actionbutton->property("_k_name").toString();
|
||||
const QString actionid = actionbutton->property("_k_actionid").toString();
|
||||
Plasma::Service* plasmaservice = m_dataengine->serviceForSource(framename);
|
||||
if (!plasmaservice) {
|
||||
kWarning() << "Could not get service for" << framename;
|
||||
} else {
|
||||
QVariantMap plasmaserviceargs = plasmaservice->operationParameters("invokeAction");
|
||||
plasmaserviceargs["actionId"] = actionid;
|
||||
(void)plasmaservice->startOperationCall("invokeAction", plasmaserviceargs);
|
||||
}
|
||||
// TODO: remove notification too
|
||||
}
|
||||
|
||||
#include "moc_applicationswidget.cpp"
|
60
plasma/applets/notifications/applicationswidget.h
Normal file
60
plasma/applets/notifications/applicationswidget.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef APPLICATIONSWIDGET_H
|
||||
#define APPLICATIONSWIDGET_H
|
||||
|
||||
#include <QMutex>
|
||||
#include <QGraphicsWidget>
|
||||
#include <QGraphicsLinearLayout>
|
||||
#include <Plasma/Label>
|
||||
#include <Plasma/Frame>
|
||||
#include <Plasma/DataEngine>
|
||||
#include <KIconLoader>
|
||||
|
||||
class NotificationsWidget;
|
||||
|
||||
class ApplicationsWidget : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
ApplicationsWidget(QGraphicsItem *parent, NotificationsWidget *notificationswidget);
|
||||
~ApplicationsWidget();
|
||||
|
||||
int count() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
int countChanged();
|
||||
|
||||
private Q_SLOTS:
|
||||
void sourceAdded(const QString &name);
|
||||
void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data);
|
||||
void slotRemoveActivated();
|
||||
void slotConfigureActivated();
|
||||
void slotActionClicked();
|
||||
|
||||
private:
|
||||
QMutex m_mutex;
|
||||
NotificationsWidget *m_notificationswidget;
|
||||
QGraphicsLinearLayout* m_layout;
|
||||
Plasma::Label* m_label;
|
||||
QList<Plasma::Frame*> m_frames;
|
||||
Plasma::DataEngine *m_dataengine;
|
||||
};
|
||||
|
||||
#endif // APPLICATIONSWIDGET_H
|
|
@ -1,23 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<kcfg xmlns="http://www.kde.org/standards/kcfg/1.0"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://www.kde.org/standards/kcfg/1.0
|
||||
http://www.kde.org/standards/kcfg/1.0/kcfg.xsd" >
|
||||
<kcfgfile name=""/>
|
||||
|
||||
<group name="General">
|
||||
<entry name="CustomPosition" type="Point">
|
||||
<label>where the notification popup will be</label>
|
||||
<default>-1,-1</default>
|
||||
</entry>
|
||||
<entry name="ShowNotifications" type="Bool">
|
||||
<label>Show the notifications</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
<entry name="ShowJobs" type="Bool">
|
||||
<label>Show the jobs progress</label>
|
||||
<default>true</default>
|
||||
</entry>
|
||||
</group>
|
||||
|
||||
</kcfg>
|
|
@ -1,310 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
import org.kde.plasma.graphicswidgets 0.1 as PlasmaWidgets
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
PlasmaComponents.ListItem {
|
||||
id: notificationItem
|
||||
width: popupFlickable.width
|
||||
|
||||
property int toolIconSize: theme.smallMediumIconSize
|
||||
property int layoutSpacing: 4
|
||||
|
||||
function getData(data, name, defaultValue) {
|
||||
return data[modelData] ? (data[modelData][name] ? data[modelData][name] : defaultValue) : defaultValue;
|
||||
}
|
||||
|
||||
property string labelName0: getData(jobsSource.data, "labelName0", '')
|
||||
property string label0: getData(jobsSource.data, "label0", '')
|
||||
property string labelName1: getData(jobsSource.data, "labelName1", '')
|
||||
property string label1: getData(jobsSource.data, "label1", '')
|
||||
property string jobstate: getData(jobsSource.data, "state", '')
|
||||
property int eta: getData(jobsSource.data, "eta", 0)
|
||||
property string speed: getData(jobsSource.data, "speed", '')
|
||||
|
||||
Column {
|
||||
spacing: notificationItem.layoutSpacing
|
||||
width: parent.width
|
||||
PlasmaComponents.Label {
|
||||
text: getData(jobsSource.data, "infoMessage", '')
|
||||
font.bold: true
|
||||
color: theme.textColor
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
Grid {
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
rightMargin: notificationItem.layoutSpacing
|
||||
}
|
||||
spacing: notificationItem.layoutSpacing
|
||||
rows: 4
|
||||
columns: 2
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: labelName0Text
|
||||
text: labelName0 ? i18n("%1:", labelName0) : ''
|
||||
width: Math.max(paintedWidth, labelName1Text.paintedWidth)
|
||||
horizontalAlignment: Text.AlignRight
|
||||
visible: labelName0 != ''
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: label0Text
|
||||
text: label0 ? label0 : ''
|
||||
width: parent.width - labelName0Text.width
|
||||
elide: Text.ElideMiddle
|
||||
visible: label0 != ''
|
||||
|
||||
PlasmaCore.ToolTip {
|
||||
target: label0Text
|
||||
subText: label0Text.truncated ? label0 : ""
|
||||
}
|
||||
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: labelName1Text
|
||||
text: labelName1 ? i18n("%1:", labelName1) : ''
|
||||
width: Math.max(paintedWidth, labelName0Text.paintedWidth)
|
||||
horizontalAlignment: Text.AlignRight
|
||||
visible: labelName1 != ''
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: label1Text
|
||||
text: label1 ? label1 : ''
|
||||
width: parent.width - labelName0Text.width
|
||||
elide: Text.ElideMiddle
|
||||
visible: label1 != ''
|
||||
|
||||
PlasmaCore.ToolTip {
|
||||
target: label1Text
|
||||
subText: label1Text.truncated ? label1 : ""
|
||||
}
|
||||
}
|
||||
QIconItem {
|
||||
icon: getData(jobsSource.data, "appIconName", '')
|
||||
width: notificationItem.toolIconSize
|
||||
height: width
|
||||
anchors {
|
||||
verticalCenter: progressItem.verticalCenter
|
||||
right: progressItem.left
|
||||
rightMargin: notificationItem.layoutSpacing
|
||||
}
|
||||
}
|
||||
Item {
|
||||
id: progressItem
|
||||
width: parent.width - labelName0Text.width
|
||||
height: childrenRect.height
|
||||
PlasmaComponents.ProgressBar {
|
||||
width: parent.width - pauseButton.width*2 - theme.largeIconSize - notificationItem.layoutSpacing*3
|
||||
height: 16
|
||||
orientation: Qt.Horizontal
|
||||
minimumValue: 0
|
||||
maximumValue: 100
|
||||
//percentage doesn't always exist, so doesn't get in the model
|
||||
value: getData(jobsSource.data, "percentage", 0)
|
||||
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: buttonsRow.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
rightMargin: notificationItem.layoutSpacing
|
||||
}
|
||||
}
|
||||
Row {
|
||||
id: buttonsRow
|
||||
spacing: notificationItem.layoutSpacing
|
||||
anchors.right: parent.right
|
||||
PlasmaComponents.ToolButton {
|
||||
id: pauseButton
|
||||
width: notificationItem.toolIconSize
|
||||
height: width
|
||||
iconSource: jobstate == "suspended" ? "media-playback-start" : "media-playback-pause"
|
||||
flat: false
|
||||
onClicked: {
|
||||
var operationName = "suspend"
|
||||
if (jobstate == "suspended") {
|
||||
operationName = "resume"
|
||||
}
|
||||
var service = jobsSource.serviceForSource(modelData)
|
||||
var operation = service.operationParameters(operationName)
|
||||
service.startOperationCall(operationName, operation)
|
||||
}
|
||||
}
|
||||
PlasmaComponents.ToolButton {
|
||||
id: stopButton
|
||||
width: notificationItem.toolIconSize
|
||||
height: width
|
||||
iconSource: "media-playback-stop"
|
||||
flat: false
|
||||
onClicked: {
|
||||
var service = jobsSource.serviceForSource(modelData)
|
||||
var operation = service.operationParameters("stop")
|
||||
service.startOperationCall("stop", operation)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaComponents.ToolButton {
|
||||
id: expandButton
|
||||
width: notificationItem.toolIconSize
|
||||
height: width
|
||||
flat: false
|
||||
iconSource: checked ? "list-remove" : "list-add"
|
||||
checkable: true
|
||||
anchors {
|
||||
right: speedLabel.left
|
||||
rightMargin: notificationItem.layoutSpacing
|
||||
verticalCenter: speedLabel.verticalCenter
|
||||
}
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: speedLabel
|
||||
text: eta > 0 ? i18nc("Speed and estimated time to completition", "%1 (%2 remaining)", speed, locale.formatDuration(eta)) : speed
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Item {
|
||||
id: detailsItem
|
||||
state: expandButton.checked ? "expanded" : "collapsed"
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: speedLabel.x
|
||||
}
|
||||
property Item contentsItem
|
||||
Component {
|
||||
id: detailsComponent
|
||||
Column {
|
||||
id: detailsColumn
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
function localizeProcessedAmount(id) {
|
||||
//if bytes localise the unit
|
||||
if (jobsSource.data[modelData]["processedUnit"+id] == "bytes") {
|
||||
return i18nc("How much many bytes (or whether unit in the locale has been copied over total", "%1 of %2",
|
||||
locale.formatByteSize(jobsSource.data[modelData]["processedAmount"+id]),
|
||||
locale.formatByteSize(jobsSource.data[modelData]["totalAmount"+id]))
|
||||
//else print something only if is interesting data (ie more than one file/directory etc to copy
|
||||
} else if (jobsSource.data[modelData]["totalAmount"+id] > 1) {
|
||||
return i18n( "%1 of %2 %3",
|
||||
jobsSource.data[modelData]["processedAmount"+id],
|
||||
jobsSource.data[modelData]["totalAmount"+id],
|
||||
jobsSource.data[modelData]["processedUnit"+id])
|
||||
} else {
|
||||
return ""
|
||||
}
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
text: jobsSource.data[modelData] ? detailsColumn.localizeProcessedAmount(0) : ""
|
||||
anchors.left: parent.left
|
||||
visible: text != ""
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
text: jobsSource.data[modelData] ? detailsColumn.localizeProcessedAmount(1) : ""
|
||||
anchors.left: parent.left
|
||||
visible: text != ""
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
text: jobsSource.data[modelData] ? detailsColumn.localizeProcessedAmount(2) : ""
|
||||
anchors.left: parent.left
|
||||
visible: text != ""
|
||||
}
|
||||
PlasmaWidgets.SignalPlotter {
|
||||
id: plotter
|
||||
width: parent.width
|
||||
useAutoRange: true
|
||||
showVerticalLines: false
|
||||
unit: i18n("KiB/s")
|
||||
height: theme.defaultFont.mSize.height * 5
|
||||
Component.onCompleted: plotter.addPlot(theme.highlightColor)
|
||||
}
|
||||
Connections {
|
||||
target: jobsSource
|
||||
onDataChanged: {
|
||||
plotter.addSample([jobsSource.data[modelData]["numericSpeed"]/1000])
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "expanded"
|
||||
PropertyChanges {
|
||||
target: detailsItem
|
||||
height: detailsItem.childrenRect.height
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "collapsed"
|
||||
PropertyChanges {
|
||||
target: detailsItem
|
||||
height: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions : [
|
||||
Transition {
|
||||
from: "collapsed"
|
||||
to: "expanded"
|
||||
SequentialAnimation {
|
||||
ScriptAction {
|
||||
script: {
|
||||
detailsItem.visible = true
|
||||
detailsItem.clip = true
|
||||
//create the contents if they don't exist yet
|
||||
if (!detailsItem.contentsItem) {
|
||||
detailsItem.contentsItem = detailsComponent.createObject(detailsItem)
|
||||
}
|
||||
}
|
||||
}
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
properties: "height"
|
||||
easing: PropertyAnimation.EaseInOut
|
||||
}
|
||||
ScriptAction {script: detailsItem.clip = false}
|
||||
}
|
||||
},
|
||||
Transition {
|
||||
from: "expanded"
|
||||
to: "collapsed"
|
||||
SequentialAnimation {
|
||||
ScriptAction {script: detailsItem.clip = true}
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
properties: "height"
|
||||
easing: PropertyAnimation.EaseInOut
|
||||
}
|
||||
//TODO: delete the details?
|
||||
ScriptAction {script: detailsItem.visible = false}
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
Column {
|
||||
id: jobsRoot
|
||||
property alias count: jobsRepeater.count
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
PlasmaCore.DataSource {
|
||||
id: jobsSource
|
||||
engine: "applicationjobs"
|
||||
interval: 0
|
||||
|
||||
onSourceAdded: {
|
||||
connectSource(source);
|
||||
}
|
||||
property variant runningJobs
|
||||
|
||||
onSourceRemoved: {
|
||||
if (!notifications) {
|
||||
return
|
||||
}
|
||||
var message = runningJobs[source]["label1"] ? runningJobs[source]["label1"] : runningJobs[source]["label0"]
|
||||
notifications.addJobNotification(
|
||||
source,
|
||||
runningJobs[source]["appIconName"],
|
||||
runningJobs[source]["appName"],
|
||||
i18n("%1 [Finished]", runningJobs[source]["infoMessage"]),
|
||||
message,
|
||||
0,
|
||||
0,
|
||||
runningJobs[source]["destUrl"] ? [{"id": message, "text": i18n("Open")}] : [])
|
||||
delete runningJobs[source]
|
||||
}
|
||||
Component.onCompleted: {
|
||||
jobsSource.runningJobs = new Object
|
||||
connectedSources = sources
|
||||
}
|
||||
onNewData: {
|
||||
var jobs = runningJobs
|
||||
jobs[sourceName] = data
|
||||
runningJobs = jobs
|
||||
}
|
||||
onDataChanged: {
|
||||
var total = 0
|
||||
for (var i = 0; i < sources.length; ++i) {
|
||||
if (jobsSource.data[sources[i]]["percentage"]) {
|
||||
total += jobsSource.data[sources[i]]["percentage"]
|
||||
}
|
||||
}
|
||||
|
||||
total /= sources.length
|
||||
notificationsApplet.globalProgress = total/100
|
||||
}
|
||||
}
|
||||
|
||||
Title {
|
||||
visible: jobsRepeater.count > 0 && notifications && notifications.count > 0
|
||||
text: i18n("Transfers")
|
||||
}
|
||||
PlasmaComponents.ListItem {
|
||||
visible: jobsRepeater.count > 1
|
||||
PlasmaComponents.ProgressBar {
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
minimumValue: 0
|
||||
maximumValue: 100
|
||||
value: notificationsApplet.globalProgress * 100
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
id: jobsRepeater
|
||||
model: jobsSource.sources
|
||||
delegate: JobDelegate {
|
||||
toolIconSize: notificationsApplet.toolIconSize
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,414 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2011 Davide Bettio <davide.bettio@kdemail.net> *
|
||||
* Copyright 2011 Marco Martin <mart@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Library General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* 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 Library 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 . *
|
||||
***************************************************************************/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
|
||||
PlasmaCore.Dialog {
|
||||
id: lastNotificationPopup
|
||||
|
||||
property variant savedPos
|
||||
property bool customPosition: false
|
||||
|
||||
onHeightChanged: setCustomPosition(lastNotificationPopup.savedPos, false)
|
||||
onWidthChanged: setCustomPosition(lastNotificationPopup.savedPos, false)
|
||||
|
||||
function popup(notification)
|
||||
{
|
||||
if (!lastNotificationPopup.visible) {
|
||||
lastNotificationsModel.clear()
|
||||
}
|
||||
lastNotificationsModel.append(notification)
|
||||
|
||||
setCustomPosition(lastNotificationPopup.savedPos, false)
|
||||
|
||||
lastNotificationPopup.visible = true
|
||||
lastNotificationTimer.interval = Math.max(4000, Math.min(60*1000, notificationsModel.get(0).expireTimeout))
|
||||
notificationsView.currentIndex = lastNotificationsModel.count - 1
|
||||
lastNotificationTimer.restart()
|
||||
mainItem.buttonPressed = false
|
||||
}
|
||||
|
||||
function setCustomPosition(pos, writeConfig)
|
||||
{
|
||||
var popupPos = lastNotificationPopup.popupPosition(notificationIcon, Qt.AlignCenter)
|
||||
var finalPos
|
||||
|
||||
//custom
|
||||
if ((pos.x >= 0 || pos.y >= 0) &&
|
||||
(Math.abs(popupPos.x - pos.x) > 40 ||
|
||||
Math.abs(popupPos.y - pos.y) > 40)) {
|
||||
finalPos = pos
|
||||
if (writeConfig) {
|
||||
plasmoid.writeConfig("CustomPosition", pos)
|
||||
lastNotificationPopup.savedPos = pos
|
||||
lastNotificationPopup.customPosition = true
|
||||
}
|
||||
} else {
|
||||
finalPos = popupPos
|
||||
if (writeConfig) {
|
||||
plasmoid.writeConfig("CustomPosition", QPoint(-1,-1))
|
||||
lastNotificationPopup.savedPos = QPoint(-1,-1)
|
||||
lastNotificationPopup.customPosition = false
|
||||
}
|
||||
}
|
||||
lastNotificationPopup.x = finalPos.x
|
||||
lastNotificationPopup.y = finalPos.y
|
||||
}
|
||||
|
||||
location: customPosition ? Floating : plasmoid.location
|
||||
windowFlags: Qt.WindowStaysOnTopHint
|
||||
Component.onCompleted: {
|
||||
setAttribute(Qt.WA_X11NetWmWindowTypeDock, true)
|
||||
|
||||
lastNotificationPopup.savedPos = plasmoid.readConfig("CustomPosition")
|
||||
setCustomPosition(lastNotificationPopup.savedPos, true)
|
||||
plasmoid.popupEvent.connect(lastNotificationPopup.popupEvent)
|
||||
}
|
||||
|
||||
function popupEvent(popupShowing)
|
||||
{
|
||||
if(popupShowing) {
|
||||
lastNotificationPopup.visible = false
|
||||
}
|
||||
}
|
||||
|
||||
mainItem: MouseEventListener {
|
||||
id: mainItem
|
||||
width: maximumWidth
|
||||
height: maximumHeight
|
||||
property int maximumWidth: theme.defaultFont.mSize.width * 35
|
||||
property int maximumHeight: theme.defaultFont.mSize.width * 10
|
||||
property int minimumWidth: maximumWidth
|
||||
property int minimumHeight: maximumHeight
|
||||
|
||||
property int startX: 0
|
||||
property int startY: 0
|
||||
property int startScreenX: 0
|
||||
property int startScreenY: 0
|
||||
hoverEnabled: true
|
||||
property bool buttonPressed: false
|
||||
|
||||
state: "controlsHidden"
|
||||
onContainsMouseChanged: {
|
||||
if (containsMouse) {
|
||||
mainItem.state = "controlsShown"
|
||||
lastNotificationTimer.running = false
|
||||
} else {
|
||||
mainItem.state = "controlsHidden"
|
||||
lastNotificationTimer.restart()
|
||||
}
|
||||
}
|
||||
onPressed: {
|
||||
startX = mouse.x + lastNotificationPopup.margins.left
|
||||
startY = mouse.y + lastNotificationPopup.margins.top
|
||||
startScreenX = mouse.screenX
|
||||
startScreenY = mouse.screenY
|
||||
lastNotificationTimer.running = false
|
||||
}
|
||||
onReleased: {
|
||||
//FIXME: bind startdragdistance
|
||||
if ((navigationButtonsColumn.visible && mouse.x < navigationButtonsColumn.width) ||
|
||||
buttonPressed ||
|
||||
Math.sqrt(Math.pow(startScreenX - mouse.screenX, 2) + Math.pow(startScreenY - mouse.screenY, 2)) > 4) {
|
||||
} else {
|
||||
lastNotificationPopup.visible = false
|
||||
}
|
||||
|
||||
setCustomPosition(QPoint(Math.max(0, mouse.screenX - startX), Math.max(mouse.screenY - startY)), true)
|
||||
}
|
||||
onPositionChanged: {
|
||||
lastNotificationPopup.x = Math.max(0, mouse.screenX - startX)
|
||||
lastNotificationPopup.y = Math.max(0, mouse.screenY - startY)
|
||||
}
|
||||
onWheelMoved: {
|
||||
if (notificationsView.moving) {
|
||||
return
|
||||
}
|
||||
|
||||
if (wheel.delta > 0) {
|
||||
notificationsView.currentIndex = Math.max(0, notificationsView.currentIndex-1)
|
||||
} else {
|
||||
notificationsView.currentIndex = Math.min(notificationsView.count-1, notificationsView.currentIndex+1)
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: lastNotificationTimer
|
||||
interval: 4000
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: lastNotificationPopup.visible = false
|
||||
}
|
||||
|
||||
ListView {
|
||||
id: notificationsView
|
||||
clip: true
|
||||
snapMode: ListView.SnapOneItem
|
||||
orientation: ListView.Horizontal
|
||||
anchors.fill: parent
|
||||
model: ListModel {
|
||||
id: lastNotificationsModel
|
||||
}
|
||||
interactive: false
|
||||
delegate: Item {
|
||||
height: notificationsView.height
|
||||
width: notificationsView.width
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: titleLabel
|
||||
text: model.summary
|
||||
//font.weight: Font.Bold
|
||||
visible: model.summary.length > 0
|
||||
height: model.summary.length > 0 ? paintedHeight : 0
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
color: theme.textColor
|
||||
elide: Text.ElideRight
|
||||
anchors {
|
||||
left: appIconItem.y > y + height ? parent.left : appIconItem.right
|
||||
right: parent.right
|
||||
rightMargin: settingsButton.visible ? settingsButton.width + closeButton.width : closeButton.width
|
||||
top: parent.top
|
||||
topMargin: 6
|
||||
leftMargin: 6
|
||||
}
|
||||
onLinkActivated: plasmoid.openUrl(link)
|
||||
}
|
||||
|
||||
QIconItem {
|
||||
id: appIconItem
|
||||
icon: model.appIcon
|
||||
width: (model.appIcon.length > 0 || imageItem.visible) ? theme.largeIconSize : 0
|
||||
height: theme.largeIconSize
|
||||
visible: !imageItem.visible
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: navigationButtonsColumn.width
|
||||
}
|
||||
}
|
||||
QImageItem {
|
||||
id: imageItem
|
||||
anchors.fill: appIconItem
|
||||
image: model.image
|
||||
smooth: true
|
||||
fillMode: Image.PreserveAspectFit
|
||||
visible: nativeWidth > 0
|
||||
}
|
||||
/*
|
||||
* this extra item is for clip the overflowed body text
|
||||
* maximumLineCount cannot control the behavior of rich text,
|
||||
* so manual clip is required.
|
||||
*/
|
||||
Item {
|
||||
id: bodyLabel
|
||||
clip: true
|
||||
height: Math.min(parent.height - (titleLabel.height+titleLabel.y), lastNotificationText.height)
|
||||
property bool tallText: bodyLabel.height >= (bodyLabel.parent.height - (titleLabel.height+titleLabel.y)*2)
|
||||
anchors {
|
||||
top: tallText ? titleLabel.bottom : undefined
|
||||
verticalCenter: tallText ? undefined : parent.verticalCenter
|
||||
left: appIconItem.right
|
||||
right: actionsColumn.left
|
||||
leftMargin: 6
|
||||
rightMargin: 6
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
id: lastNotificationText
|
||||
text: model.body
|
||||
width: parent.width
|
||||
//textFormat: Text.PlainText
|
||||
color: theme.textColor
|
||||
wrapMode: Text.Wrap
|
||||
elide: Text.ElideRight
|
||||
maximumLineCount: 4
|
||||
onLinkActivated: plasmoid.openUrl(link)
|
||||
}
|
||||
}
|
||||
Column {
|
||||
id: actionsColumn
|
||||
spacing: 6
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 6
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Repeater {
|
||||
model: actions
|
||||
PlasmaComponents.Button {
|
||||
text: model.text
|
||||
width: theme.defaultFont.mSize.width * 8
|
||||
height: theme.defaultFont.mSize.width * 2
|
||||
onPressedChanged: {
|
||||
if (pressed) {
|
||||
mainItem.buttonPressed = true
|
||||
} else {
|
||||
mainItem.buttonPressed = false
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
executeAction(source, model.id)
|
||||
actionsColumn.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Column {
|
||||
id: navigationButtonsColumn
|
||||
opacity: 0
|
||||
visible: backButton.enabled || nextButton.enabled
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: nextButton
|
||||
iconSource: "go-next"
|
||||
width: theme.smallMediumIconSize
|
||||
height: mainItem.height/2 - 4
|
||||
enabled: notificationsView.currentIndex < notificationsView.count-1
|
||||
onPressedChanged: {
|
||||
if (pressed) {
|
||||
mainItem.buttonPressed = true
|
||||
} else {
|
||||
mainItem.buttonPressed = false
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
notificationsView.currentIndex = Math.min(notificationsView.count-1, notificationsView.currentIndex+1)
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: backButton
|
||||
iconSource: "go-previous"
|
||||
width: theme.smallMediumIconSize
|
||||
height: mainItem.height/2 - 4
|
||||
enabled: notificationsView.currentIndex > 0
|
||||
onPressedChanged: {
|
||||
if (pressed) {
|
||||
mainItem.buttonPressed = true
|
||||
} else {
|
||||
mainItem.buttonPressed = false
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
notificationsView.currentIndex = Math.max(0, notificationsView.currentIndex-1)
|
||||
}
|
||||
}
|
||||
}
|
||||
PlasmaComponents.ToolButton {
|
||||
id: closeButton
|
||||
opacity: 0
|
||||
iconSource: "window-close"
|
||||
width: theme.smallMediumIconSize
|
||||
height: width
|
||||
anchors {
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
onPressedChanged: {
|
||||
if (pressed) {
|
||||
mainItem.buttonPressed = true
|
||||
} else {
|
||||
mainItem.buttonPressed = false
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
lastNotificationPopup.visible = false
|
||||
lastNotificationTimer.running = false
|
||||
closeNotification(notificationsModel.get((notificationsView.count-1)-notificationsView.currentIndex).source)
|
||||
notificationsModel.remove((notificationsView.count-1)-notificationsView.currentIndex)
|
||||
}
|
||||
}
|
||||
PlasmaComponents.ToolButton {
|
||||
id: settingsButton
|
||||
opacity: 0
|
||||
iconSource: "configure"
|
||||
width: theme.smallMediumIconSize
|
||||
height: width
|
||||
visible: notificationsModel.get((notificationsView.count-1)-notificationsView.currentIndex).configurable
|
||||
anchors {
|
||||
right: closeButton.left
|
||||
top: parent.top
|
||||
rightMargin: 5
|
||||
}
|
||||
onPressedChanged: {
|
||||
if (pressed) {
|
||||
mainItem.buttonPressed = true
|
||||
} else {
|
||||
mainItem.buttonPressed = false
|
||||
}
|
||||
}
|
||||
onClicked: {
|
||||
lastNotificationPopup.visible = false
|
||||
configureNotification(notificationsModel.get((notificationsView.count-1)-notificationsView.currentIndex).appRealName)
|
||||
}
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
name: "controlsShown"
|
||||
PropertyChanges {
|
||||
target: navigationButtonsColumn
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 1
|
||||
}
|
||||
PropertyChanges {
|
||||
target: settingsButton
|
||||
opacity: 1
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "controlsHidden"
|
||||
PropertyChanges {
|
||||
target: navigationButtonsColumn
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: closeButton
|
||||
opacity: 0
|
||||
}
|
||||
PropertyChanges {
|
||||
target: settingsButton
|
||||
opacity: 0
|
||||
}
|
||||
}
|
||||
]
|
||||
transitions: [
|
||||
Transition {
|
||||
NumberAnimation {
|
||||
properties: "opacity"
|
||||
easing.type: Easing.InOutQuad
|
||||
duration: 250
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
PlasmaComponents.ListItem {
|
||||
id: notificationItem
|
||||
opacity: 1-Math.abs(x)/width
|
||||
width: popupFlickable.width
|
||||
property int toolIconSize: theme.smallMediumIconSize
|
||||
property int layoutSpacing: 4
|
||||
|
||||
visible: appTabBar.currentTab == allAppsTab || appTabBar.currentTab.text == appName
|
||||
|
||||
Component.onCompleted: {
|
||||
allApplicationsModel.addApplication(appIcon, appName)
|
||||
mainScrollArea.height = mainScrollArea.implicitHeight
|
||||
}
|
||||
Component.onDestruction: {
|
||||
allApplicationsModel.removeApplication(model.appName)
|
||||
mainScrollArea.height = mainScrollArea.implicitHeight
|
||||
}
|
||||
Timer {
|
||||
interval: 10*60*1000
|
||||
repeat: false
|
||||
running: !idleTimeSource.idle
|
||||
onTriggered: {
|
||||
if (!notificationsModel.inserting)
|
||||
notificationsModel.remove(index)
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
width: parent.width
|
||||
height: childrenRect.height
|
||||
drag {
|
||||
target: notificationItem
|
||||
axis: Drag.XAxis
|
||||
//kind of an hack over Column being too smart
|
||||
minimumX: -parent.width + 1
|
||||
maximumX: parent.width - 1
|
||||
}
|
||||
onReleased: {
|
||||
if (notificationItem.x < -notificationItem.width/2) {
|
||||
removeAnimation.exitFromRight = false
|
||||
removeAnimation.running = true
|
||||
} else if (notificationItem.x > notificationItem.width/2 ) {
|
||||
removeAnimation.exitFromRight = true
|
||||
removeAnimation.running = true
|
||||
} else {
|
||||
resetAnimation.running = true
|
||||
}
|
||||
}
|
||||
SequentialAnimation {
|
||||
id: removeAnimation
|
||||
property bool exitFromRight: true
|
||||
NumberAnimation {
|
||||
target: notificationItem
|
||||
properties: "x"
|
||||
to: removeAnimation.exitFromRight ? notificationItem.width-1 : 1-notificationItem.width
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
NumberAnimation {
|
||||
target: notificationItem
|
||||
properties: "height"
|
||||
to: 0
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
ScriptAction {
|
||||
script: notificationsModel.remove(index)
|
||||
}
|
||||
}
|
||||
SequentialAnimation {
|
||||
id: resetAnimation
|
||||
NumberAnimation {
|
||||
target: notificationItem
|
||||
properties: "x"
|
||||
to: 0
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
Column {
|
||||
spacing: notificationItem.layoutSpacing
|
||||
width: parent.width
|
||||
Item {
|
||||
width: parent.width
|
||||
height: summaryLabel.height
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: summaryLabel
|
||||
text: summary
|
||||
height: paintedHeight
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
leftMargin: closeButton.width
|
||||
rightMargin: settingsButton.visible ? settingsButton.width + closeButton.width : closeButton.width
|
||||
}
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
onLinkActivated: plasmoid.openUrl(link)
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: closeButton
|
||||
iconSource: "window-close"
|
||||
width: notificationItem.toolIconSize
|
||||
height: width
|
||||
onClicked: {
|
||||
if (notificationsModel.count > 1) {
|
||||
removeAnimation.running = true
|
||||
} else {
|
||||
closeNotification(model.source)
|
||||
notificationsModel.remove(index)
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaComponents.ToolButton {
|
||||
id: settingsButton
|
||||
iconSource: "configure"
|
||||
width: notificationItem.toolIconSize
|
||||
height: width
|
||||
visible: model.configurable
|
||||
onClicked: {
|
||||
plasmoid.hidePopup()
|
||||
configureNotification(model.appRealName)
|
||||
}
|
||||
anchors {
|
||||
top: parent.top
|
||||
right: closeButton.left
|
||||
rightMargin: 5
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Item {
|
||||
height: childrenRect.height
|
||||
width: parent.width
|
||||
QIconItem {
|
||||
id: appIconItem
|
||||
icon: QIcon(appIcon)
|
||||
width: theme.largeIconSize
|
||||
height: theme.largeIconSize
|
||||
visible: !imageItem.visible
|
||||
anchors {
|
||||
left: parent.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
}
|
||||
QImageItem {
|
||||
id: imageItem
|
||||
anchors.fill: appIconItem
|
||||
image: model.image
|
||||
smooth: true
|
||||
visible: nativeWidth > 0
|
||||
}
|
||||
PlasmaComponents.ContextMenu {
|
||||
id: contextMenu
|
||||
visualParent: contextMouseArea
|
||||
PlasmaComponents.MenuItem {
|
||||
text: i18n("Copy")
|
||||
onClicked: bodyText.copy()
|
||||
}
|
||||
PlasmaComponents.MenuItem {
|
||||
text: i18n("Select All")
|
||||
onClicked: bodyText.selectAll()
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
id: contextMouseArea
|
||||
anchors {
|
||||
left: appIconItem.right
|
||||
right: actionsColumn.left
|
||||
verticalCenter: parent.verticalCenter
|
||||
leftMargin: 6
|
||||
rightMargin: 6
|
||||
}
|
||||
acceptedButtons: Qt.RightButton
|
||||
height: bodyText.paintedHeight
|
||||
preventStealing: true
|
||||
onPressed: contextMenu.open(mouse.x, mouse.y)
|
||||
TextEdit {
|
||||
id: bodyText
|
||||
anchors.fill: parent
|
||||
text: body
|
||||
color: theme.textColor
|
||||
font.family: theme.defaultFont.family
|
||||
font.italic: theme.defaultFont.italic
|
||||
font.pointSize: theme.defaultFont.pointSize
|
||||
font.strikeout: theme.defaultFont.strikeout
|
||||
font.underline: theme.defaultFont.underline
|
||||
font.weight: theme.defaultFont.weight
|
||||
selectByMouse: true
|
||||
readOnly: true
|
||||
wrapMode: Text.Wrap
|
||||
textFormat: TextEdit.RichText
|
||||
onLinkActivated: plasmoid.openUrl(link)
|
||||
}
|
||||
}
|
||||
Column {
|
||||
id: actionsColumn
|
||||
spacing: notificationItem.layoutSpacing
|
||||
anchors {
|
||||
right: parent.right
|
||||
rightMargin: 6
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
Repeater {
|
||||
model: actions
|
||||
PlasmaComponents.Button {
|
||||
text: model.text
|
||||
width: theme.defaultFont.mSize.width * 8
|
||||
height: theme.defaultFont.mSize.width * 2
|
||||
onClicked: {
|
||||
executeAction(source, model.id)
|
||||
actionsColumn.visible = false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
NotificationDelegate 0.1 NotificationDelegate.qml
|
|
@ -1,187 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2011 Davide Bettio <davide.bettio@kdemail.net> *
|
||||
* Copyright 2011 Marco Martin <mart@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Library General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* 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 Library 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 . *
|
||||
***************************************************************************/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
|
||||
Item {
|
||||
PlasmaCore.SvgItem {
|
||||
id: notificationSvgItem
|
||||
svg: notificationSvg
|
||||
elementId: "notification-disabled"
|
||||
anchors.centerIn: parent
|
||||
width: Math.min(parent.width, parent.height)
|
||||
height: width
|
||||
state: notificationsApplet.state
|
||||
|
||||
PlasmaCore.Svg {
|
||||
id: notificationSvg
|
||||
imagePath: "icons/notification"
|
||||
}
|
||||
|
||||
Item {
|
||||
id: jobProgressItem
|
||||
width: notificationSvgItem.width * globalProgress
|
||||
clip: true
|
||||
visible: jobs.count > 0
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
PlasmaCore.SvgItem {
|
||||
svg: notificationSvg
|
||||
elementId: "notification-progress-active"
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
}
|
||||
width: notificationSvgItem.width
|
||||
}
|
||||
}
|
||||
PlasmaComponents.BusyIndicator {
|
||||
anchors.fill: parent
|
||||
visible: jobs ? jobs.count > 0 : false
|
||||
running: visible
|
||||
}
|
||||
|
||||
Column {
|
||||
id: countColumn
|
||||
visible: false
|
||||
anchors.centerIn: parent
|
||||
PlasmaCore.SvgItem {
|
||||
svg: notificationSvg
|
||||
elementId: {
|
||||
switch (plasmoid.location) {
|
||||
case TopEdge:
|
||||
return "expander-top"
|
||||
case LeftEdge:
|
||||
return "expander-left"
|
||||
case RightEdge:
|
||||
return "expander-right"
|
||||
default:
|
||||
return "expander-bottom"
|
||||
}
|
||||
}
|
||||
width: naturalSize.width
|
||||
height: naturalSize.height
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
}
|
||||
PlasmaComponents.Label {
|
||||
property int totalCount: notificationsApplet.totalCount
|
||||
text: totalCount
|
||||
|
||||
property int oldTotalCount: 0
|
||||
font.pointSize: theme.smallestFont.pointSize
|
||||
height: paintedHeight - 3
|
||||
onTotalCountChanged: {
|
||||
if (totalCount > oldTotalCount) {
|
||||
notificationAnimation.running = true
|
||||
}
|
||||
oldTotalCount = totalCount
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: notificationAnimatedItem
|
||||
anchors.fill: parent
|
||||
svg: notificationSvg
|
||||
elementId: "notification-active"
|
||||
opacity: 0
|
||||
scale: 2
|
||||
|
||||
SequentialAnimation {
|
||||
id: notificationAnimation
|
||||
NumberAnimation {
|
||||
target: notificationAnimatedItem
|
||||
duration: 250
|
||||
properties: "opacity, scale"
|
||||
to: 1
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
PauseAnimation { duration: 500 }
|
||||
ParallelAnimation {
|
||||
NumberAnimation {
|
||||
target: notificationAnimatedItem
|
||||
duration: 250
|
||||
properties: "opacity"
|
||||
to: 0
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
NumberAnimation {
|
||||
target: notificationAnimatedItem
|
||||
duration: 250
|
||||
properties: "scale"
|
||||
to: 2
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
MouseArea {
|
||||
anchors.fill: parent
|
||||
onClicked: {
|
||||
if (notificationsApplet.totalCount > 0) {
|
||||
plasmoid.togglePopup()
|
||||
} else {
|
||||
plasmoid.hidePopup()
|
||||
}
|
||||
}
|
||||
}
|
||||
states: [
|
||||
State {
|
||||
name: "default"
|
||||
PropertyChanges {
|
||||
target: notificationSvgItem
|
||||
elementId: "notification-disabled"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: countColumn
|
||||
visible: false
|
||||
}
|
||||
PropertyChanges {
|
||||
target: plasmoid
|
||||
status: PassiveStatus
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: "new-notifications"
|
||||
PropertyChanges {
|
||||
target: notificationSvgItem
|
||||
elementId: jobs.count > 0 ? "notification-progress-inactive" : "notification-empty"
|
||||
}
|
||||
PropertyChanges {
|
||||
target: countColumn
|
||||
visible: true
|
||||
}
|
||||
PropertyChanges {
|
||||
target: plasmoid
|
||||
status: ActiveStatus
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
|
|
@ -1,236 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
import "NotificationDelegate"
|
||||
|
||||
Column {
|
||||
id: notificationsRoot
|
||||
property alias count: notificationsRepeater.count
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
|
||||
function addNotification(source, appIcon, image, appName, summary, body, expireTimeout, urgency, appRealName, configurable, actions) {
|
||||
// Do not show duplicated notifications
|
||||
for (var i = 0; i < notificationsModel.count; ++i) {
|
||||
if (notificationsModel.get(i).source == source &&
|
||||
notificationsModel.get(i).appName == appName &&
|
||||
notificationsModel.get(i).summary == summary &&
|
||||
notificationsModel.get(i).body == body) {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
for (var i = 0; i < notificationsModel.count; ++i) {
|
||||
if (notificationsModel.get(i).source == source) {
|
||||
notificationsModel.remove(i)
|
||||
break
|
||||
}
|
||||
}
|
||||
if (notificationsModel.count > 20) {
|
||||
notificationsModel.remove(notificationsModel.count-1)
|
||||
}
|
||||
var notification = {
|
||||
"source" : source,
|
||||
"appIcon" : appIcon,
|
||||
"image" : image,
|
||||
"appName" : appName,
|
||||
"summary" : summary,
|
||||
"body" : body,
|
||||
"expireTimeout": expireTimeout,
|
||||
"urgency" : urgency,
|
||||
"configurable": configurable,
|
||||
"appRealName": appRealName,
|
||||
"actions" : actions
|
||||
}
|
||||
notificationsModel.inserting = true;
|
||||
notificationsModel.insert(0, notification);
|
||||
notificationsModel.inserting = false;
|
||||
if (plasmoid.popupShowing) {
|
||||
return
|
||||
}
|
||||
if (!lastNotificationPopup) {
|
||||
lastNotificationPopup = lastNotificationPopupComponent.createObject(notificationsRoot)
|
||||
}
|
||||
lastNotificationPopup.popup(notification)
|
||||
}
|
||||
|
||||
function addJobNotification(source, appIcon, appName, summary, body, expireTimeout, urgency, actions) {
|
||||
addNotification(source, appIcon, new QImage, appName, summary, body, expireTimeout, urgency, appName, false, actions)
|
||||
}
|
||||
|
||||
function executeAction(source, id) {
|
||||
//try to use the service
|
||||
if (source.indexOf("notification") !== -1) {
|
||||
var service = notificationsSource.serviceForSource(source)
|
||||
var op = service.operationParameters("invokeAction")
|
||||
op["actionId"] = id
|
||||
|
||||
service.startOperationCall("invokeAction", op)
|
||||
//try to open the id as url
|
||||
} else if (source.indexOf("Job") !== -1) {
|
||||
plasmoid.openUrl(id)
|
||||
}
|
||||
}
|
||||
|
||||
function configureNotification(appRealName) {
|
||||
var service = notificationsSource.serviceForSource("notification")
|
||||
var op = service.operationParameters("configureNotification")
|
||||
op["appRealName"] = appRealName;
|
||||
service.startOperationCall("configureNotification", op)
|
||||
}
|
||||
|
||||
function closeNotification(source) {
|
||||
var service = notificationsSource.serviceForSource(source)
|
||||
var op = service.operationParameters("userClosed")
|
||||
service.startOperationCall("userClosed", op)
|
||||
}
|
||||
|
||||
property QtObject lastNotificationPopup
|
||||
Component {
|
||||
id: lastNotificationPopupComponent
|
||||
LastNotificationPopup {
|
||||
}
|
||||
}
|
||||
|
||||
ListModel {
|
||||
id: notificationsModel
|
||||
property bool inserting: false;
|
||||
}
|
||||
ListModel {
|
||||
id: allApplicationsModel
|
||||
function addApplication(icon, name)
|
||||
{
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var item = get(i)
|
||||
if (item.name == name) {
|
||||
setProperty(i, "count", item.count + 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
append({"icon": icon, "name": name, "count": 1})
|
||||
}
|
||||
function removeApplication(name)
|
||||
{
|
||||
for (var i = 0; i < count; ++i) {
|
||||
var item = get(i)
|
||||
if (item.name == name) {
|
||||
if (item.count <= 1) {
|
||||
remove(i)
|
||||
appTabBar.currentTab = allAppsTab
|
||||
return
|
||||
}
|
||||
setProperty(i, "count", item.count - 1)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.DataSource {
|
||||
id: idleTimeSource
|
||||
engine: "powermanagement"
|
||||
interval: 30000
|
||||
connectedSources: ["UserActivity"]
|
||||
//Idle whith more than 5 minutes of user inactivity
|
||||
property bool idle: data["UserActivity"]["IdleTime"] > 300000
|
||||
}
|
||||
|
||||
PlasmaCore.DataSource {
|
||||
id: notificationsSource
|
||||
engine: "notifications"
|
||||
interval: 0
|
||||
|
||||
onSourceAdded: {
|
||||
connectSource(source);
|
||||
}
|
||||
|
||||
onNewData: {
|
||||
var actions = new Array()
|
||||
if (data["actions"] && data["actions"].length % 2 == 0) {
|
||||
for (var i = 0; i < data["actions"].length; i += 2) {
|
||||
var action = new Object()
|
||||
action["id"] = data["actions"][i]
|
||||
action["text"] = data["actions"][i+1]
|
||||
actions.push(action)
|
||||
}
|
||||
}
|
||||
notificationsRoot.addNotification(
|
||||
sourceName,
|
||||
data["appIcon"],
|
||||
data["image"],
|
||||
data["appName"],
|
||||
data["summary"],
|
||||
data["body"],
|
||||
data["expireTimeout"],
|
||||
data["urgency"],
|
||||
data["appRealName"],
|
||||
data["configurable"],
|
||||
actions)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Title {
|
||||
visible: notificationsRepeater.count > 1 || (jobs && jobs.count > 0 && notificationsRepeater.count > 0)
|
||||
text: i18n("Notifications")
|
||||
PlasmaComponents.ToolButton {
|
||||
iconSource: "window-close"
|
||||
width: notificationsApplet.toolIconSize
|
||||
height: width
|
||||
anchors {
|
||||
right: parent.right
|
||||
verticalCenter: parent.verticalCenter
|
||||
}
|
||||
onClicked: notificationsModel.clear()
|
||||
}
|
||||
}
|
||||
PlasmaComponents.ListItem {
|
||||
visible: allApplicationsModel.count > 1
|
||||
PlasmaComponents.TabBar {
|
||||
id: appTabBar
|
||||
anchors.horizontalCenter: parent.horizontalCenter
|
||||
width: Math.min(implicitWidth, parent.width-8)
|
||||
PlasmaComponents.TabButton {
|
||||
id: allAppsTab
|
||||
text: i18n("All")
|
||||
iconSource: "dialog-information"
|
||||
}
|
||||
Repeater {
|
||||
model: allApplicationsModel
|
||||
PlasmaComponents.TabButton {
|
||||
text: name
|
||||
iconSource: icon
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Repeater {
|
||||
id: notificationsRepeater
|
||||
model: notificationsModel
|
||||
delegate: NotificationDelegate {
|
||||
toolIconSize: notificationsApplet.toolIconSize
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,43 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
|
||||
PlasmaComponents.ListItem {
|
||||
id: root
|
||||
property alias text: titleLabel.text
|
||||
|
||||
|
||||
sectionDelegate: true
|
||||
|
||||
width: parent.width
|
||||
|
||||
PlasmaComponents.Label {
|
||||
id: titleLabel
|
||||
horizontalAlignment: Text.AlignHCenter
|
||||
elide: Text.ElideRight
|
||||
anchors {
|
||||
verticalCenter: parent.verticalCenter
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,68 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>feedsConfig</class>
|
||||
<widget class="QWidget" name="feedsConfig">
|
||||
<property name="geometry">
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>337</width>
|
||||
<height>181</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>&Application notifications:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>kcfg_ShowNotifications</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ShowNotifications">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>&File transfers and jobs:</string>
|
||||
</property>
|
||||
<property name="buddy">
|
||||
<cstring>kcfg_ShowJobs</cstring>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QCheckBox" name="kcfg_ShowJobs">
|
||||
<property name="text">
|
||||
<string/>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" colspan="2">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="font">
|
||||
<font>
|
||||
<weight>75</weight>
|
||||
<bold>true</bold>
|
||||
</font>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Choose which information to show</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>kcfg_ShowNotifications</tabstop>
|
||||
<tabstop>kcfg_ShowJobs</tabstop>
|
||||
</tabstops>
|
||||
<connections/>
|
||||
</ui>
|
|
@ -1,170 +0,0 @@
|
|||
/***************************************************************************
|
||||
* Copyright 2011 Davide Bettio <davide.bettio@kdemail.net> *
|
||||
* Copyright 2011 Marco Martin <mart@kde.org> *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU Library General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* 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 Library 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 . *
|
||||
***************************************************************************/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
import org.kde.qtextracomponents 0.1
|
||||
import org.kde.locale 0.1 as KLocale
|
||||
|
||||
import "uiproperties.js" as UiProperties
|
||||
|
||||
|
||||
MouseEventListener {
|
||||
id: notificationsApplet
|
||||
state: "default"
|
||||
width: 32
|
||||
height: 32
|
||||
property int minimumWidth: mainScrollArea.implicitWidth
|
||||
property int minimumHeight: mainScrollArea.implicitHeight
|
||||
property int maximumWidth: -1
|
||||
property int maximumHeight: mainScrollArea.implicitHeight
|
||||
|
||||
property int toolIconSize: UiProperties.toolIconSize
|
||||
property int layoutSpacing: UiProperties.layoutSpacing
|
||||
|
||||
property real globalProgress: 0
|
||||
|
||||
property bool showNotifications: false
|
||||
property bool showJobs: false
|
||||
|
||||
property Item notifications: notificationsLoader.item
|
||||
property Item jobs: jobsLoader.item
|
||||
|
||||
//notifications + jobs
|
||||
property int totalCount: (notifications ? notifications.count : 0) + (jobs ? jobs.count : 0)
|
||||
onTotalCountChanged: {
|
||||
if (totalCount > 0) {
|
||||
state = "new-notifications"
|
||||
} else {
|
||||
state = "default"
|
||||
plasmoid.hidePopup()
|
||||
}
|
||||
|
||||
var data = new Object
|
||||
data["image"] = "preferences-desktop-notification"
|
||||
data["mainText"] = i18n("Notifications and Jobs")
|
||||
if (totalCount == 0) {
|
||||
data["subText"] = i18n("No notifications or jobs")
|
||||
} else if (!notifications.count) {
|
||||
data["subText"] = i18np("%1 running job", "%1 running jobs", jobs.count)
|
||||
} else if (!jobs.count) {
|
||||
data["subText"] = i18np("%1 notification", "%1 notifications", notifications.count)
|
||||
} else {
|
||||
data["subText"] = i18np("%1 running job", "%1 running jobs", jobs.count) + "<br/>" + i18np("%1 notification", "%1 notifications", notifications.count)
|
||||
}
|
||||
plasmoid.popupIconToolTip = data
|
||||
plasmoid.passivePopup = jobs.count != 0
|
||||
}
|
||||
|
||||
property Item notificationIcon
|
||||
|
||||
Component.onCompleted: {
|
||||
//plasmoid.popupIcon = QIcon("preferences-desktop-notification")
|
||||
plasmoid.aspectRatioMode = "ConstrainedSquare"
|
||||
plasmoid.status = PassiveStatus
|
||||
allApplications = new Object
|
||||
plasmoid.addEventListener('ConfigChanged', configChanged);
|
||||
configChanged()
|
||||
}
|
||||
|
||||
function configChanged()
|
||||
{
|
||||
showNotifications = plasmoid.readConfig("ShowNotifications")
|
||||
showJobs = plasmoid.readConfig("ShowJobs")
|
||||
}
|
||||
|
||||
KLocale.Locale {
|
||||
id: locale
|
||||
}
|
||||
|
||||
PlasmaCore.Svg {
|
||||
id: configIconsSvg
|
||||
imagePath: "widgets/configuration-icons"
|
||||
}
|
||||
|
||||
property Component compactRepresentation: Component {
|
||||
NotificationIcon {
|
||||
id: notificationIcon
|
||||
Component.onCompleted: notificationsApplet.notificationIcon = notificationIcon
|
||||
}
|
||||
}
|
||||
|
||||
hoverEnabled: !UiProperties.touchInput
|
||||
|
||||
PlasmaComponents.ScrollArea {
|
||||
id: mainScrollArea
|
||||
anchors.fill: parent
|
||||
implicitWidth: theme.defaultFont.mSize.width * 40
|
||||
implicitHeight: Math.min(theme.defaultFont.mSize.height * 40, Math.max(theme.defaultFont.mSize.height * 6, contentsColumn.height))
|
||||
state: ""
|
||||
|
||||
states: [
|
||||
State {
|
||||
name: "underMouse"
|
||||
when: notificationsApplet.containsMouse
|
||||
PropertyChanges {
|
||||
target: mainScrollArea
|
||||
implicitHeight: implicitHeight
|
||||
}
|
||||
},
|
||||
State {
|
||||
name: ""
|
||||
when: !notificationsApplet.containsMouse
|
||||
PropertyChanges {
|
||||
target: mainScrollArea
|
||||
implicitHeight: Math.min(theme.defaultFont.mSize.height * 40, Math.max(theme.defaultFont.mSize.height * 6, contentsColumn.height))
|
||||
}
|
||||
}
|
||||
]
|
||||
|
||||
Flickable {
|
||||
id: popupFlickable
|
||||
anchors.fill:parent
|
||||
|
||||
contentWidth: width
|
||||
contentHeight: contentsColumn.height
|
||||
clip: true
|
||||
|
||||
Column {
|
||||
id: contentsColumn
|
||||
width: popupFlickable.width
|
||||
|
||||
//TODO: load those on demand based on configuration
|
||||
Loader {
|
||||
id: jobsLoader
|
||||
source: showJobs ? "Jobs.qml" : ""
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
Loader {
|
||||
id: notificationsLoader
|
||||
source: showNotifications ? "Notifications.qml" : ""
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,23 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
|
||||
var toolIconSize = theme.smallMediumIconSize
|
||||
var layoutSpacing = 4
|
||||
var touchInput = false
|
75
plasma/applets/notifications/jobswidget.cpp
Normal file
75
plasma/applets/notifications/jobswidget.cpp
Normal file
|
@ -0,0 +1,75 @@
|
|||
/* 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"
|
||||
|
||||
#include <Plasma/DataEngineManager>
|
||||
#include <KDebug>
|
||||
|
||||
JobsWidget::JobsWidget(QGraphicsItem *parent, NotificationsWidget *notificationswidget)
|
||||
: QGraphicsWidget(parent),
|
||||
m_notificationswidget(notificationswidget),
|
||||
m_layout(nullptr),
|
||||
m_label(nullptr),
|
||||
m_dataengine(nullptr)
|
||||
{
|
||||
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);
|
||||
|
||||
m_dataengine = Plasma::DataEngineManager::self()->loadEngine("applicationjobs");
|
||||
if (!m_dataengine) {
|
||||
kWarning() << "Could not load applicationjobs data engine";
|
||||
return;
|
||||
}
|
||||
connect(
|
||||
m_dataengine, SIGNAL(sourceAdded(QString)),
|
||||
this, SLOT(sourceAdded(QString))
|
||||
);
|
||||
}
|
||||
|
||||
JobsWidget::~JobsWidget()
|
||||
{
|
||||
if (m_dataengine) {
|
||||
Plasma::DataEngineManager::self()->unloadEngine("applicationjobs");
|
||||
}
|
||||
}
|
||||
|
||||
int JobsWidget::count() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
void JobsWidget::sourceAdded(const QString &name)
|
||||
{
|
||||
qDebug() << Q_FUNC_INFO << name;
|
||||
m_dataengine->connectSource(name, this);
|
||||
}
|
||||
|
||||
void JobsWidget::dataUpdated(const QString &name, const Plasma::DataEngine::Data &data)
|
||||
{
|
||||
// qDebug() << Q_FUNC_INFO << name << data;
|
||||
}
|
||||
|
||||
#include "moc_jobswidget.cpp"
|
53
plasma/applets/notifications/jobswidget.h
Normal file
53
plasma/applets/notifications/jobswidget.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef JOBSWIDGET_H
|
||||
#define JOBSWIDGET_H
|
||||
|
||||
#include <QGraphicsWidget>
|
||||
#include <QGraphicsLinearLayout>
|
||||
#include <Plasma/Label>
|
||||
#include <Plasma/DataEngine>
|
||||
|
||||
class NotificationsWidget;
|
||||
|
||||
class JobsWidget : public QGraphicsWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
JobsWidget(QGraphicsItem *parent, NotificationsWidget *notificationswidget);
|
||||
~JobsWidget();
|
||||
|
||||
int count() const;
|
||||
|
||||
Q_SIGNALS:
|
||||
int countChanged();
|
||||
|
||||
|
||||
private Q_SLOTS:
|
||||
void sourceAdded(const QString &name);
|
||||
void dataUpdated(const QString &name, const Plasma::DataEngine::Data &data);
|
||||
|
||||
private:
|
||||
NotificationsWidget *m_notificationswidget;
|
||||
QGraphicsLinearLayout* m_layout;
|
||||
Plasma::Label* m_label;
|
||||
Plasma::DataEngine *m_dataengine;
|
||||
};
|
||||
|
||||
#endif // JOBSWIDGET_H
|
119
plasma/applets/notifications/notifications.cpp
Normal file
119
plasma/applets/notifications/notifications.cpp
Normal file
|
@ -0,0 +1,119 @@
|
|||
/* 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 "notifications.h"
|
||||
#include "jobswidget.h"
|
||||
#include "applicationswidget.h"
|
||||
|
||||
#include <Plasma/TabBar>
|
||||
#include <Plasma/ScrollWidget>
|
||||
#include <KIcon>
|
||||
#include <KDebug>
|
||||
|
||||
static const QSizeF s_minimumsize = QSizeF(290, 140);
|
||||
|
||||
class NotificationsWidget : public Plasma::TabBar
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotificationsWidget(NotificationsApplet* notifications);
|
||||
~NotificationsWidget();
|
||||
|
||||
private Q_SLOTS:
|
||||
void slotCountChanged();
|
||||
|
||||
private:
|
||||
NotificationsApplet* m_notifications;
|
||||
Plasma::ScrollWidget* m_jobsscrollwidget;
|
||||
JobsWidget* m_jobswidget;
|
||||
Plasma::ScrollWidget* m_applicationsscrollwidget;
|
||||
ApplicationsWidget* m_applicationswidget;
|
||||
Plasma::Label* m_notificationslabel;
|
||||
};
|
||||
|
||||
NotificationsWidget::NotificationsWidget(NotificationsApplet* notifications)
|
||||
: Plasma::TabBar(notifications),
|
||||
m_notifications(notifications),
|
||||
m_jobswidget(nullptr),
|
||||
m_applicationswidget(nullptr)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
|
||||
setMinimumSize(s_minimumsize);
|
||||
|
||||
m_jobsscrollwidget = new Plasma::ScrollWidget(this);
|
||||
m_jobsscrollwidget->setMinimumSize(s_minimumsize);
|
||||
m_jobswidget = new JobsWidget(m_jobsscrollwidget, this);
|
||||
connect(
|
||||
m_jobswidget, SIGNAL(countChanged()),
|
||||
this, SLOT(slotCountChanged())
|
||||
);
|
||||
m_jobsscrollwidget->setWidget(m_jobswidget);
|
||||
addTab(KIcon("services"), i18n("Jobs"), m_jobsscrollwidget);
|
||||
|
||||
m_applicationsscrollwidget = new Plasma::ScrollWidget(this);
|
||||
m_applicationsscrollwidget->setMinimumSize(s_minimumsize);
|
||||
m_applicationswidget = new ApplicationsWidget(m_applicationsscrollwidget, this);
|
||||
connect(
|
||||
m_applicationswidget, SIGNAL(countChanged()),
|
||||
this, SLOT(slotCountChanged())
|
||||
);
|
||||
m_applicationsscrollwidget->setWidget(m_applicationswidget);
|
||||
addTab(KIcon("dialog-information"), i18n("Notifications"), m_applicationsscrollwidget);
|
||||
|
||||
m_notifications->setStatus(Plasma::ItemStatus::PassiveStatus);
|
||||
}
|
||||
|
||||
NotificationsWidget::~NotificationsWidget()
|
||||
{
|
||||
}
|
||||
|
||||
void NotificationsWidget::slotCountChanged()
|
||||
{
|
||||
const int totalcount = (m_jobswidget->count() + m_applicationswidget->count());
|
||||
if (totalcount > 0) {
|
||||
m_notifications->setStatus(Plasma::ItemStatus::ActiveStatus);
|
||||
} else {
|
||||
m_notifications->setStatus(Plasma::ItemStatus::PassiveStatus);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
NotificationsApplet::NotificationsApplet(QObject *parent, const QVariantList &args)
|
||||
: Plasma::PopupApplet(parent, args),
|
||||
m_notificationswidget(nullptr)
|
||||
{
|
||||
KGlobal::locale()->insertCatalog("plasma_applet_notifications");
|
||||
setAspectRatioMode(Plasma::AspectRatioMode::IgnoreAspectRatio);
|
||||
m_notificationswidget = new NotificationsWidget(this);
|
||||
setPopupIcon("preferences-desktop-notification");
|
||||
}
|
||||
|
||||
NotificationsApplet::~NotificationsApplet()
|
||||
{
|
||||
delete m_notificationswidget;
|
||||
}
|
||||
|
||||
QGraphicsWidget* NotificationsApplet::graphicsWidget()
|
||||
{
|
||||
return m_notificationswidget;
|
||||
}
|
||||
|
||||
K_EXPORT_PLASMA_APPLET(notifications, NotificationsApplet)
|
||||
|
||||
#include "moc_notifications.cpp"
|
||||
#include "notifications.moc"
|
41
plasma/applets/notifications/notifications.h
Normal file
41
plasma/applets/notifications/notifications.h
Normal file
|
@ -0,0 +1,41 @@
|
|||
/* 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.
|
||||
*/
|
||||
|
||||
#ifndef NOTIFICATIONS_H
|
||||
#define NOTIFICATIONS_H
|
||||
|
||||
#include <Plasma/PopupApplet>
|
||||
|
||||
class NotificationsWidget;
|
||||
|
||||
class NotificationsApplet : public Plasma::PopupApplet
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
NotificationsApplet(QObject *parent, const QVariantList &args);
|
||||
~NotificationsApplet();
|
||||
|
||||
// Plasma::PopupApplet reimplementation
|
||||
QGraphicsWidget* graphicsWidget() final;
|
||||
|
||||
private:
|
||||
friend NotificationsWidget;
|
||||
NotificationsWidget *m_notificationswidget;
|
||||
};
|
||||
|
||||
#endif // NOTIFICATIONS_H
|
|
@ -153,12 +153,11 @@ X-KDE-PluginInfo-Author=Davide Bettio
|
|||
X-KDE-PluginInfo-Category=Tasks
|
||||
X-KDE-PluginInfo-Email=davide.bettio@kdemail.net
|
||||
X-KDE-PluginInfo-License=GPL
|
||||
X-KDE-PluginInfo-Name=org.kde.notifications
|
||||
X-KDE-PluginInfo-Version=0.1
|
||||
X-KDE-PluginInfo-Name=notifications
|
||||
X-KDE-PluginInfo-Version=1.0
|
||||
X-KDE-PluginInfo-Website=
|
||||
X-KDE-ServiceTypes=Plasma/PopupApplet,Plasma/Applet
|
||||
X-Plasma-API=declarativeappletscript
|
||||
X-KDE-Library=plasma_applet_notifications
|
||||
X-Plasma-DefaultSize=100,100
|
||||
X-Plasma-MainScript=ui/main.qml
|
||||
X-Plasma-RequiredExtensions=LaunchApp
|
||||
X-Plasma-NotificationArea=true
|
|
@ -28,7 +28,7 @@ var ICONS_SIZE = 24 // Size of icons, icons are square i.e. width == height
|
|||
var MINIMUM_SIZE = 8 // minimum size of widget
|
||||
var ARROW_MARGINS = 5 // margins for an arrow
|
||||
var BLINK_INTERVAL = 750 // time interval of blinking
|
||||
var TASK_NOTIFICATIONS_TYPEID = "org.kde.notifications"
|
||||
var TASK_NOTIFICATIONS_TYPEID = "notifications"
|
||||
var USE_GRID_IN_POPUP = false // true if in popup icons should be placed like a grid without names
|
||||
|
||||
|
||||
|
|
|
@ -683,8 +683,8 @@ void Applet::checkDefaultApplets()
|
|||
s_manager->addApplet("devicenotifier", this);
|
||||
}
|
||||
|
||||
if (!applets.contains("org.kde.notifications")) {
|
||||
s_manager->addApplet("org.kde.notifications", this);
|
||||
if (!applets.contains("notifications")) {
|
||||
s_manager->addApplet("notifications", this);
|
||||
}
|
||||
|
||||
if (!applets.contains("keyboard")) {
|
||||
|
|
|
@ -3,7 +3,6 @@ add_subdirectory(apps)
|
|||
add_subdirectory(dict)
|
||||
add_subdirectory(geolocation)
|
||||
add_subdirectory(notifications)
|
||||
add_subdirectory(powermanagement)
|
||||
add_subdirectory(soliddevice)
|
||||
add_subdirectory(time)
|
||||
add_subdirectory(weather)
|
||||
|
|
|
@ -1,27 +0,0 @@
|
|||
|
||||
set(powermanagement_engine_SRCS
|
||||
powermanagementengine.cpp
|
||||
powermanagementjob.cpp
|
||||
powermanagementservice.cpp
|
||||
)
|
||||
|
||||
set(krunner_xml ${CMAKE_SOURCE_DIR}/krunner/dbus/org.kde.krunner.App.xml)
|
||||
QT4_ADD_DBUS_INTERFACE(powermanagement_engine_SRCS ${krunner_xml} krunner_interface)
|
||||
|
||||
kde4_add_plugin(plasma_engine_powermanagement ${powermanagement_engine_SRCS})
|
||||
target_link_libraries(plasma_engine_powermanagement
|
||||
KDE4::kdecore
|
||||
KDE4::solid
|
||||
KDE4::plasma
|
||||
KDE4::kidletime
|
||||
kworkspace
|
||||
)
|
||||
|
||||
install(
|
||||
TARGETS plasma_engine_powermanagement
|
||||
DESTINATION ${KDE4_PLUGIN_INSTALL_DIR}
|
||||
)
|
||||
install(
|
||||
FILES plasma-dataengine-powermanagement.desktop
|
||||
DESTINATION ${KDE4_SERVICES_INSTALL_DIR}
|
||||
)
|
|
@ -1,147 +0,0 @@
|
|||
[Desktop Entry]
|
||||
# ctxt: plasma data engine
|
||||
Name=Power Management
|
||||
Name[ar]=إدارة الطاقة
|
||||
Name[ast]=Xestión d'enerxía
|
||||
Name[bg]=Управление на захранването
|
||||
Name[bn]=শক্তি ব্যবস্থাপনা
|
||||
Name[bs]=upravljanje napajanjem
|
||||
Name[ca]=Gestió d'energia
|
||||
Name[ca@valencia]=Gestió d'energia
|
||||
Name[cs]=Správa napájení
|
||||
Name[csb]=Sprôwianié mòcą
|
||||
Name[da]=Strømstyring
|
||||
Name[de]=Energieverwaltung
|
||||
Name[el]=Διαχείριση ενέργειας
|
||||
Name[en_GB]=Power Management
|
||||
Name[eo]=Energia administrado
|
||||
Name[es]=Gestión de energía
|
||||
Name[et]=Toitehaldus
|
||||
Name[eu]=Energia-kudeaketa
|
||||
Name[fi]=Virranhallinta
|
||||
Name[fr]=Gestion de l'énergie
|
||||
Name[fy]=Enerzjybehear
|
||||
Name[ga]=Bainisteoireacht Cumhachta
|
||||
Name[gl]=Xestión da enerxía
|
||||
Name[gu]=પાવર વ્યવસ્થાપક
|
||||
Name[he]=ניהול צריכת חשמל
|
||||
Name[hi]=बिज़ली प्रबंधन
|
||||
Name[hr]=Upravljanje potrošnjom energije
|
||||
Name[hu]=Energiakezelő
|
||||
Name[ia]=Gestion de energia
|
||||
Name[id]=Manajemen Daya
|
||||
Name[is]=Orkustýring
|
||||
Name[it]=Gestione energetica
|
||||
Name[ja]=電源管理
|
||||
Name[kk]=Қуаттандыруды басқару
|
||||
Name[km]=ការគ្រប់គ្រងថាមពល
|
||||
Name[kn]=ವಿದ್ಯುಚ್ಚಕ್ತಿಯ ನಿರ್ವಹಣೆ
|
||||
Name[ko]=전원 관리
|
||||
Name[lt]=Energijos valdymas
|
||||
Name[lv]=Energokontrole
|
||||
Name[mk]=Менаџмент на енергија
|
||||
Name[ml]=വൈദ്യുതി നടത്തിപ്പു്
|
||||
Name[mr]=वीज व्यवस्थापन
|
||||
Name[nb]=Strømstyring
|
||||
Name[nds]=Stroomkuntrull
|
||||
Name[nl]=Energiebeheer
|
||||
Name[nn]=Straumstyring
|
||||
Name[pa]=ਪਾਵਰ ਮੈਨਿਜਮੈਂਟ
|
||||
Name[pl]=Zarządzanie energią
|
||||
Name[pt]=Gestão de Energia
|
||||
Name[pt_BR]=Gerenciamento de energia
|
||||
Name[ro]=Gestiunea alimentării
|
||||
Name[ru]=Управление питанием
|
||||
Name[si]=බල පරිපාලනය
|
||||
Name[sk]=Správa napájania
|
||||
Name[sl]=Upravljanje z energijo
|
||||
Name[sr]=управљање напајањем
|
||||
Name[sr@ijekavian]=управљање напајањем
|
||||
Name[sr@ijekavianlatin]=upravljanje napajanjem
|
||||
Name[sr@latin]=upravljanje napajanjem
|
||||
Name[sv]=Strömsparhantering
|
||||
Name[tg]=Идоракунии барқ
|
||||
Name[th]=การจัดการพลังงาน
|
||||
Name[tr]=Güç Yönetimi
|
||||
Name[ug]=توك مەنبەسىنى باشقۇرۇش
|
||||
Name[uk]=Керування живленням
|
||||
Name[wa]=Manaedjmint di l' enerdjeye
|
||||
Name[x-test]=xxPower Managementxx
|
||||
Name[zh_CN]=电源管理
|
||||
Name[zh_TW]=電源管理
|
||||
Comment=Battery, AC, sleep and PowerDevil information.
|
||||
Comment[ar]=معلومات البطارية والتيار المتناوب والنوم وعفريت الطاقة.
|
||||
Comment[ast]=Información de batería, CA, hibernación y PowerDevil.
|
||||
Comment[bg]=Данни за батерия, AC, приспиване и PowerDevil
|
||||
Comment[bs]=Podaci iz Strujnog đavola o bateriji, AC‑u, i spavanju.
|
||||
Comment[ca]=Informació de la bateria, AC, suspensió i del PowerDevil.
|
||||
Comment[ca@valencia]=Informació de la bateria, AC, suspensió i del PowerDevil.
|
||||
Comment[cs]=Informace o baterii, AC a uspání.
|
||||
Comment[da]=Information om batteri, strømforsyning, dvale og PowerDevil.
|
||||
Comment[de]=Informationen zu Akku, Netzanschluss, Ruhezustand und PowerDevil.
|
||||
Comment[el]=Πληροφορίες μπαταρίας, AC, αδράνειας και PowerDevil
|
||||
Comment[en_GB]=Battery, AC, sleep and PowerDevil information.
|
||||
Comment[es]=Información de batería, CA, hibernación y PowerDevil.
|
||||
Comment[et]=Aku, voolutoite, puhkeseisundi ja PowerDevili teave.
|
||||
Comment[eu]=Bateria, korronte alternoa, loa eta PowerDevil-i buruzko informazioa.
|
||||
Comment[fi]=Akku, vaihtovirta, nukkumis- ja PowerDevil-tiedot.
|
||||
Comment[fr]=Batterie, chargeur, veille et informations sur PowerDevil
|
||||
Comment[fy]=Batterij, AC, sliepe en PowerDevil ynformaasje
|
||||
Comment[ga]=Faisnéis a bhaineann leis an gcadhnra, ceangal SA, codladh agus PowerDevil.
|
||||
Comment[gl]=Información da batería, corrente, hibernación e PowerDevil.
|
||||
Comment[he]=מידע אודות סוללה, צריכת חשמל, מצב שינה ו־PowerDevil.
|
||||
Comment[hr]=Informacije o bateriji, adapteru, spavanju i PowerDevilu.
|
||||
Comment[hu]=A telepek, a tápellátás és a PowerDevil energiakezelő jellemzői.
|
||||
Comment[ia]=Batteria, AC, reposo e information de PowerDevil.
|
||||
Comment[id]=Informasi Baterai, AC, tidur dan PowerDevil.
|
||||
Comment[is]=Upplýsingar um raflöður, AC-straum, svæfingu og PowerDevil orkustýringarpúkann.
|
||||
Comment[it]=Informazioni su batteria, alimentazione, sospensione e PowerDevil
|
||||
Comment[ja]=バッテリ、商用電源、スリープ、PowerDevil の情報。
|
||||
Comment[kk]=Батарея, тоқ, ұйықтау күйі және PowerDevil мәліметі.
|
||||
Comment[km]=ព័ត៌មាន ថ្ម AC ដេក និង PowerDevil ។
|
||||
Comment[kn]=ವಿದ್ಯುತ್ಕೋಶ, AC, ಜಡ ಹಾಗು PowerDevil ಮಾಹಿತಿ.
|
||||
Comment[ko]=배터리, AC, 절전 모드 및 PowerDevil 정보입니다.
|
||||
Comment[lt]=Akumuliatoriaus, AC, miego ir PowerDevil informacija.
|
||||
Comment[lv]=Baterija, barošana, gulēšanas un PowerDevil informācija.
|
||||
Comment[ml]=ബാറ്ററി, എസി, നിദ്ര പിന്നെ പവര്ഡെവിള് എന്നീ വിവരങ്ങള്.
|
||||
Comment[mr]=बॅटरी, AC, व पॉवरडेव्हिल माहिती.
|
||||
Comment[nb]=Informasjon om batteri, nettstrøm, hvilemodus og PowerDevil.
|
||||
Comment[nds]=Batterie-, Stroom-, Utsett- un Stroomdüvel-Infos
|
||||
Comment[nl]=Accu-, stroomvoorziening-, slaapstand- en PowerDevil-informatie.
|
||||
Comment[nn]=Informasjon om batteristatus, lading og liknande.
|
||||
Comment[pa]=ਬੈਟਰੀ, ਏਸੀ, ਸਲੀਪ ਅਤੇ ਪਾਵਰਡਿਵੈਲ ਜਾਣਕਾਰੀ ਹੈ।
|
||||
Comment[pl]=Bateria, zasilacz, usypianie i informacje PowerDevil.
|
||||
Comment[pt]=Informação sobre a bateria, corrente eléctrica e o PowerDevil.
|
||||
Comment[pt_BR]=Bateria, adaptador de energia, dormir e informação do PowerDevil.
|
||||
Comment[ro]=Informații despre acumulator, priză, adormire și PowerDevil.
|
||||
Comment[ru]=Информация о батарее, электрической сети и PowerDevil.
|
||||
Comment[si]=බැටරි, AC, නිද්රා හා PowerDevil තොරතුරු
|
||||
Comment[sk]=Informácie o batérii, AC a uspaní.
|
||||
Comment[sl]=Podatki o baterijah, omrežnem napajanju, pripravljenosti in PowerDevilu.
|
||||
Comment[sr]=Подаци из Струјног ђавола о батерији, АЦ‑у, и спавању.
|
||||
Comment[sr@ijekavian]=Подаци из Струјног ђавола о батерији, АЦ‑у, и спавању.
|
||||
Comment[sr@ijekavianlatin]=Podaci iz Strujnog đavola o bateriji, AC‑u, i spavanju.
|
||||
Comment[sr@latin]=Podaci iz Strujnog đavola o bateriji, AC‑u, i spavanju.
|
||||
Comment[sv]=Information om batteri, nätspänning, viloläge och Powerdevil.
|
||||
Comment[tg]=Батарея, AC, захираи барқ ва иттилооти PowerDevil.
|
||||
Comment[th]=แบตเตอรี่, การเสียบปลั๊กไฟ, การพักเครื่อง และข้อมูลของ PowerDevil
|
||||
Comment[tr]=Pil, Adaptör, uyku kipi ve PowerDevil bilgileri.
|
||||
Comment[ug]=توكدان، ئۆزگىرىشچان توك مەنبەسى، سىستېما ئۇخلات ۋە PowerDevil ئۇچۇرىنى تەمىنلەيدۇ.
|
||||
Comment[uk]=Акумулятор, мережеве живлення, відомості щодо присипляння і PowerDevil.
|
||||
Comment[vi]=Thông tin pin, AC, chế độ ngủ và PowerDevil
|
||||
Comment[wa]=Pondants et djondants sol batreye, l' AC, l' edoirmaedje eyet l' Diâle d' Enerdjeye.
|
||||
Comment[x-test]=xxBattery, AC, sleep and PowerDevil information.xx
|
||||
Comment[zh_CN]=提供电池、交流适配器、系统睡眠及 PowerDevil 信息。
|
||||
Comment[zh_TW]=電池、市電電源、睡眠模式與 PowerDevil 資訊。
|
||||
X-KDE-ServiceTypes=Plasma/DataEngine
|
||||
Type=Service
|
||||
Icon=preferences-system-power-management
|
||||
X-KDE-Library=plasma_engine_powermanagement
|
||||
|
||||
X-KDE-PluginInfo-Author=
|
||||
X-KDE-PluginInfo-Email=
|
||||
X-KDE-PluginInfo-Name=powermanagement
|
||||
X-KDE-PluginInfo-Version=
|
||||
X-KDE-PluginInfo-Website=
|
||||
X-KDE-PluginInfo-Category=
|
||||
X-KDE-PluginInfo-Depends=
|
|
@ -1,109 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 Aaron Seigo <aseigo@kde.org>
|
||||
* Copyright 2007-2008 Sebastian Kuegler <sebas@kde.org>
|
||||
* CopyRight 2007 Maor Vanmak <mvanmak1@gmail.com>
|
||||
* Copyright 2008 Dario Freddi <drf54321@gmail.com>
|
||||
*
|
||||
* 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 "powermanagementengine.h"
|
||||
#include "powermanagementservice.h"
|
||||
|
||||
#include <QDBusConnectionInterface>
|
||||
#include <QDBusConnection>
|
||||
#include <QDBusMetaType>
|
||||
|
||||
#include <KDebug>
|
||||
#include <KLocale>
|
||||
#include <KStandardDirs>
|
||||
#include <KIdleTime>
|
||||
#include <Solid/PowerManagement>
|
||||
#include <Plasma/DataContainer>
|
||||
|
||||
typedef QMap< QString, QString > StringStringMap;
|
||||
Q_DECLARE_METATYPE(StringStringMap)
|
||||
|
||||
PowermanagementEngine::PowermanagementEngine(QObject* parent, const QVariantList& args)
|
||||
: Plasma::DataEngine(parent, args)
|
||||
{
|
||||
qDBusRegisterMetaType<StringStringMap>();
|
||||
|
||||
m_sources << "Sleep States" << "PowerDevil";
|
||||
}
|
||||
|
||||
void PowermanagementEngine::init()
|
||||
{
|
||||
if (QDBusConnection::sessionBus().interface()->isServiceRegistered("org.freedesktop.PowerManagement")) {
|
||||
sourceRequestEvent("PowerDevil");
|
||||
}
|
||||
}
|
||||
|
||||
QStringList PowermanagementEngine::sources() const
|
||||
{
|
||||
return m_sources;
|
||||
}
|
||||
|
||||
bool PowermanagementEngine::sourceRequestEvent(const QString &name)
|
||||
{
|
||||
if (name == "Sleep States") {
|
||||
const QSet<Solid::PowerManagement::SleepState> sleepstates = Solid::PowerManagement::supportedSleepStates();
|
||||
// We first set all possible sleepstates to false, then enable the ones that are available
|
||||
setData("Sleep States", "Suspend", false);
|
||||
setData("Sleep States", "Hibernate", false);
|
||||
setData("Sleep States", "Hybrid Suspend", false);
|
||||
|
||||
foreach (const Solid::PowerManagement::SleepState &sleepstate, sleepstates) {
|
||||
if (sleepstate == Solid::PowerManagement::SuspendState) {
|
||||
setData("Sleep States", "Suspend", true);
|
||||
} else if (sleepstate == Solid::PowerManagement::HibernateState) {
|
||||
setData("Sleep States", "Hibernate", true);
|
||||
} else if (sleepstate == Solid::PowerManagement::HybridSuspendState) {
|
||||
setData("Sleep States", "Hybrid Suspend", true);
|
||||
}
|
||||
//kDebug() << "Sleepstate \"" << sleepstate << "\" supported.";
|
||||
}
|
||||
} else if (name == "PowerDevil") {
|
||||
;
|
||||
//any info concerning lock screen/screensaver goes here
|
||||
} else if (name == "UserActivity") {
|
||||
setData("UserActivity", "IdleTime", KIdleTime::instance()->idleTime());
|
||||
} else {
|
||||
kDebug() << "Data for '" << name << "' not found";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PowermanagementEngine::updateSourceEvent(const QString &source)
|
||||
{
|
||||
if (source == "UserActivity") {
|
||||
setData("UserActivity", "IdleTime", KIdleTime::instance()->idleTime());
|
||||
return true;
|
||||
}
|
||||
return Plasma::DataEngine::updateSourceEvent(source);
|
||||
}
|
||||
|
||||
Plasma::Service* PowermanagementEngine::serviceForSource(const QString &source)
|
||||
{
|
||||
if (source == "PowerDevil") {
|
||||
return new PowerManagementService(this);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
K_EXPORT_PLASMA_DATAENGINE(powermanagement, PowermanagementEngine)
|
||||
|
||||
#include "moc_powermanagementengine.cpp"
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright 2007 Aaron Seigo <aseigo@kde.org>
|
||||
* Copyright 2007-2008 Sebastian Kuegler <sebas@kde.org>
|
||||
* Copyright 2008 Dario Freddi <drf54321@gmail.com>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef POWERMANAGEMENTENGINE_H
|
||||
#define POWERMANAGEMENTENGINE_H
|
||||
|
||||
#include <Plasma/DataEngine>
|
||||
|
||||
/**
|
||||
* This class provides power management in Plasma applets.
|
||||
*/
|
||||
class PowermanagementEngine : public Plasma::DataEngine
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PowermanagementEngine(QObject *parent, const QVariantList &args);
|
||||
|
||||
QStringList sources() const;
|
||||
Plasma::Service* serviceForSource(const QString &source);
|
||||
|
||||
protected:
|
||||
bool sourceRequestEvent(const QString &name);
|
||||
bool updateSourceEvent(const QString &source);
|
||||
void init();
|
||||
|
||||
private:
|
||||
QStringList m_sources;
|
||||
};
|
||||
|
||||
#endif // POWERMANAGEMENTENGINE_H
|
|
@ -1,115 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* 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 <QDBusConnection>
|
||||
#include <QDBusInterface>
|
||||
#include <QDBusMessage>
|
||||
#include <QDBusPendingReply>
|
||||
|
||||
// kde-workspace/libs
|
||||
#include <kworkspace/kworkspace.h>
|
||||
|
||||
#include <krunner_interface.h>
|
||||
|
||||
#include "powermanagementjob.h"
|
||||
|
||||
#include <kdebug.h>
|
||||
|
||||
#include <Solid/PowerManagement>
|
||||
|
||||
PowerManagementJob::PowerManagementJob(const QString &operation, const QMap<QString, QVariant> ¶meters, QObject *parent) :
|
||||
ServiceJob(parent->objectName(), operation, parameters, parent)
|
||||
{
|
||||
}
|
||||
|
||||
PowerManagementJob::~PowerManagementJob()
|
||||
{
|
||||
}
|
||||
|
||||
void PowerManagementJob::start()
|
||||
{
|
||||
const QString operation = operationName();
|
||||
//kDebug() << "starting operation ... " << operation;
|
||||
|
||||
if (operation == "lockScreen") {
|
||||
static const QString interface("org.freedesktop.ScreenSaver");
|
||||
QDBusInterface screensaver(interface, "/ScreenSaver");
|
||||
QDBusPendingReply<void> reply = screensaver.asyncCall("Lock");
|
||||
if (reply.isError()) {
|
||||
setResult(false);
|
||||
return;
|
||||
}
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operation == "suspendToRam") {
|
||||
if (!Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::SuspendState)) {
|
||||
setResult(false);
|
||||
return;
|
||||
}
|
||||
Solid::PowerManagement::requestSleep(Solid::PowerManagement::SuspendState);
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operation == "suspendToDisk") {
|
||||
if (!Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HibernateState)) {
|
||||
setResult(false);
|
||||
return;
|
||||
}
|
||||
Solid::PowerManagement::requestSleep(Solid::PowerManagement::HibernateState);
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operation == "suspendHybrid") {
|
||||
if (!Solid::PowerManagement::supportedSleepStates().contains(Solid::PowerManagement::HybridSuspendState)) {
|
||||
setResult(false);
|
||||
return;
|
||||
}
|
||||
Solid::PowerManagement::requestSleep(Solid::PowerManagement::HybridSuspendState);
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operation == "requestShutDown") {
|
||||
if (!KWorkSpace::canShutDown()) {
|
||||
setResult(false);
|
||||
return;
|
||||
}
|
||||
KWorkSpace::requestShutDown();
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operation == "switchUser") {
|
||||
// Taken from kickoff/core/itemhandlers.cpp
|
||||
org::kde::krunner::App krunner("org.kde.krunner", "/App", QDBusConnection::sessionBus());
|
||||
krunner.switchUser();
|
||||
setResult(true);
|
||||
return;
|
||||
} else if (operation == "beginSuppressingSleep") {
|
||||
setResult(Solid::PowerManagement::beginSuppressingSleep(parameters().value("reason").toString()));
|
||||
return;
|
||||
} else if (operation == "stopSuppressingSleep") {
|
||||
setResult(Solid::PowerManagement::stopSuppressingSleep(parameters().value("cookie").toUInt()));
|
||||
return;
|
||||
} else if (operation == "beginSuppressingScreenPowerManagement") {
|
||||
setResult(Solid::PowerManagement::beginSuppressingScreenPowerManagement(parameters().value("reason").toString()));
|
||||
return;
|
||||
} else if (operation == "stopSuppressingScreenPowerManagement") {
|
||||
setResult(Solid::PowerManagement::stopSuppressingScreenPowerManagement(parameters().value("cookie").toUInt()));
|
||||
return;
|
||||
}
|
||||
|
||||
kDebug() << "don't know what to do with " << operation;
|
||||
setResult(false);
|
||||
}
|
||||
|
||||
#include "moc_powermanagementjob.cpp"
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef POWERMANAGEMENTJOB_H
|
||||
#define POWERMANAGEMENTJOB_H
|
||||
|
||||
// plasma
|
||||
#include <Plasma/ServiceJob>
|
||||
|
||||
class PowerManagementJob : public Plasma::ServiceJob
|
||||
{
|
||||
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PowerManagementJob(const QString &operation, const QMap<QString, QVariant> ¶meters,
|
||||
QObject *parent = 0);
|
||||
~PowerManagementJob();
|
||||
|
||||
protected:
|
||||
void start();
|
||||
};
|
||||
|
||||
#endif // POWERMANAGEMENTJOB_H
|
|
@ -1,48 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 "powermanagementservice.h"
|
||||
#include "powermanagementjob.h"
|
||||
|
||||
PowerManagementService::PowerManagementService(QObject *parent)
|
||||
: Plasma::Service(parent)
|
||||
{
|
||||
setName("powermanagementservice");
|
||||
setOperationNames(
|
||||
QStringList()
|
||||
<< "lockScreen"
|
||||
<< "suspendToRam"
|
||||
<< "suspendToDisk"
|
||||
<< "suspendHybrid"
|
||||
<< "requestShutDown"
|
||||
<< "switchUser"
|
||||
<< "beginSuppressingSleep"
|
||||
<< "stopSuppressingSleep"
|
||||
<< "beginSuppressingScreenPowerManagement"
|
||||
<< "stopSuppressingScreenPowerManagement"
|
||||
);
|
||||
}
|
||||
|
||||
ServiceJob *PowerManagementService::createJob(const QString &operation,
|
||||
const QMap<QString, QVariant> ¶meters)
|
||||
{
|
||||
return new PowerManagementJob(operation, parameters, this);
|
||||
}
|
||||
|
||||
#include "moc_powermanagementservice.cpp"
|
|
@ -1,39 +0,0 @@
|
|||
/*
|
||||
* Copyright 2011 Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2 or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
#ifndef POWERMANAGEMENTSERVICE_H
|
||||
#define POWERMANAGEMENTSERVICE_H
|
||||
|
||||
|
||||
#include <Plasma/Service>
|
||||
#include <Plasma/ServiceJob>
|
||||
|
||||
using namespace Plasma;
|
||||
|
||||
|
||||
class PowerManagementService : public Plasma::Service
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
PowerManagementService(QObject *parent = 0);
|
||||
ServiceJob *createJob(const QString &operation, const QMap<QString, QVariant> ¶meters);
|
||||
};
|
||||
|
||||
#endif // POWERMANAGEMENTSERVICE_H
|
|
@ -1,53 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Components project.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.components 0.1
|
||||
|
||||
/**
|
||||
* Provides a component with list of options that the user can choose from.
|
||||
*
|
||||
* All elements of this component are defined in Menu, its base component.
|
||||
*/
|
||||
Menu {
|
||||
id: root
|
||||
}
|
|
@ -1,135 +0,0 @@
|
|||
/*
|
||||
* Copyright 2010 Marco Martin <notmart@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import "private/Config.js" as Config
|
||||
|
||||
/**
|
||||
* An item delegate for the primitive ListView component.
|
||||
*
|
||||
* It's intended to make all listviews look coherent.
|
||||
*/
|
||||
Item {
|
||||
id: listItem
|
||||
default property alias content: paddingItem.data
|
||||
|
||||
/**
|
||||
* type:bool Holds if the item emits signals related to mouse interaction.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
property alias enabled: itemMouse.enabled
|
||||
//item has been clicked or pressed+hold
|
||||
|
||||
/**
|
||||
* This signal is emitted when there is a click.
|
||||
*
|
||||
* This is disabled by default, set enabled to true to use it.
|
||||
* @see enabled
|
||||
*/
|
||||
signal clicked
|
||||
|
||||
|
||||
/**
|
||||
* The user pressed the item with the mouse and didn't release it for a
|
||||
* certain amount of time.
|
||||
*
|
||||
* This is disabled by default, set enabled to true to use it.
|
||||
* @see enabled
|
||||
*/
|
||||
signal pressAndHold
|
||||
|
||||
/**
|
||||
* If true makes the list item look as checked or pressed. It has to be set
|
||||
* from the code, it won't change by itself.
|
||||
*/
|
||||
//plasma extension
|
||||
//always look pressed?
|
||||
property bool checked: false
|
||||
|
||||
/**
|
||||
* If true the item will be a delegate for a section, so will look like a
|
||||
* "title" for the otems under it.
|
||||
*/
|
||||
//is this to be used as section delegate?
|
||||
property bool sectionDelegate: false
|
||||
|
||||
width: parent ? parent.width : childrenRect.width
|
||||
height: paddingItem.childrenRect.height + background.margins.top + background.margins.bottom
|
||||
|
||||
property int implicitHeight: paddingItem.childrenRect.height + background.margins.top + background.margins.bottom
|
||||
|
||||
|
||||
Connections {
|
||||
target: listItem
|
||||
onCheckedChanged: background.prefix = (listItem.checked ? "pressed" : "normal")
|
||||
onSectionDelegateChanged: background.prefix = (listItem.sectionDelegate ? "section" : "normal")
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id : background
|
||||
imagePath: "widgets/listitem"
|
||||
prefix: "normal"
|
||||
|
||||
anchors.fill: parent
|
||||
visible: listItem.ListView.view ? listItem.ListView.view.highlight === null : true
|
||||
opacity: itemMouse.containsMouse && !itemMouse.pressed ? 0.5 : 1
|
||||
Component.onCompleted: {
|
||||
prefix = (listItem.sectionDelegate ? "section" : (listItem.checked ? "pressed" : "normal"))
|
||||
}
|
||||
Behavior on opacity { NumberAnimation { duration: 200 } }
|
||||
}
|
||||
PlasmaCore.SvgItem {
|
||||
svg: PlasmaCore.Svg {imagePath: "widgets/listitem"}
|
||||
elementId: "separator"
|
||||
anchors {
|
||||
left: parent.left
|
||||
right: parent.right
|
||||
top: parent.top
|
||||
}
|
||||
height: naturalSize.height
|
||||
visible: listItem.sectionDelegate || (typeof(index) != "undefined" && index > 0 && !listItem.checked && !itemMouse.pressed)
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: itemMouse
|
||||
property bool changeBackgroundOnPress: !listItem.checked && !listItem.sectionDelegate
|
||||
anchors.fill: background
|
||||
enabled: false
|
||||
hoverEnabled: Config.mouseOverEnabled
|
||||
|
||||
onClicked: listItem.clicked()
|
||||
onPressAndHold: listItem.pressAndHold()
|
||||
onPressed: if (changeBackgroundOnPress) background.prefix = "pressed"
|
||||
onReleased: if (changeBackgroundOnPress) background.prefix = "normal"
|
||||
onCanceled: if (changeBackgroundOnPress) background.prefix = "normal"
|
||||
}
|
||||
|
||||
Item {
|
||||
id: paddingItem
|
||||
anchors {
|
||||
fill: background
|
||||
leftMargin: background.margins.left
|
||||
topMargin: background.margins.top
|
||||
rightMargin: background.margins.right
|
||||
bottomMargin: background.margins.bottom
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,175 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.0
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import org.kde.qtextracomponents 0.1
|
||||
|
||||
/**
|
||||
* Simple progressBar using the plasma theme.
|
||||
*
|
||||
* Some operations take a period of time to be performed and the user needs a
|
||||
* confirmation that the operation is still ongoing. If the user does not get
|
||||
* any confirmation, they might suspect that they did something wrong or that
|
||||
* the device has broken. A progress bar is one of the available mechanisms for
|
||||
* providing this reassurance to the user.
|
||||
*/
|
||||
Item {
|
||||
id: progressBar
|
||||
|
||||
// Common API
|
||||
/** type:real Minimum value for the progressBar */
|
||||
property alias minimumValue: range.minimumValue
|
||||
/** type:real Maximum value for the progressBar */
|
||||
property alias maximumValue: range.maximumValue
|
||||
/** type:real Current value of the progressBar */
|
||||
property alias value: range.value
|
||||
/**
|
||||
* type:bool
|
||||
* Indicates whether the operation's duration is known or not. The property
|
||||
* can have the following values:
|
||||
*
|
||||
* - true: the operation's duration is unknown, so the progress bar is
|
||||
* animated. The value, minimum, and maximum properties are ignored.
|
||||
* - false: the operation's duration is known, so the progress bar is drawn
|
||||
* to indicate progress between the minimum and maximum values.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
property alias indeterminate: indeterminateAnimation.running
|
||||
|
||||
// Plasma API
|
||||
/**
|
||||
* Orientation of the progressBar: Qt.Horizontal or Qt.Vertical
|
||||
*/
|
||||
property int orientation: Qt.Horizontal
|
||||
|
||||
width: 100
|
||||
height: 20
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
|
||||
RangeModel {
|
||||
id: range
|
||||
|
||||
// default values
|
||||
minimumValue: 0.0
|
||||
maximumValue: 1.0
|
||||
value: 0
|
||||
|
||||
positionAtMinimum: 0
|
||||
positionAtMaximum: backgroundPixmapItem.width
|
||||
}
|
||||
|
||||
Item {
|
||||
id: contents
|
||||
|
||||
property bool _isVertical: orientation == Qt.Vertical
|
||||
property int _tileWidth: width
|
||||
|
||||
width: _isVertical ? progressBar.height : progressBar.width
|
||||
height: _isVertical ? progressBar.width : progressBar.height
|
||||
rotation: _isVertical ? 90 : 0
|
||||
anchors.centerIn: parent
|
||||
|
||||
Timer {
|
||||
id: resizeTimer
|
||||
repeat: false
|
||||
interval: 0
|
||||
running: false
|
||||
onTriggered: {
|
||||
contents._tileWidth = Math.floor(contents.width/(Math.floor(contents.width/(contents.height/1.6))))
|
||||
|
||||
|
||||
if (barFrameSvg.hasElement("hint-bar-stretch")) {
|
||||
barFrameSvg.resizeFrame(Qt.size(barPixmapItem.width, barPixmapItem.height))
|
||||
} else {
|
||||
barFrameSvg.resizeFrame(Qt.size(contents._tileWidth, contents.height))
|
||||
}
|
||||
barPixmapItem.pixmap = barFrameSvg.framePixmap()
|
||||
|
||||
if (backgroundFrameSvg.hasElement("hint-bar-stretch")) {
|
||||
backgroundFrameSvg.resizeFrame(Qt.size(backgroundPixmapItem.width, backgroundPixmapItem.height))
|
||||
} else {
|
||||
backgroundFrameSvg.resizeFrame(Qt.size(contents._tileWidth, contents.height))
|
||||
}
|
||||
backgroundPixmapItem.pixmap = backgroundFrameSvg.framePixmap()
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvg {
|
||||
id: barFrameSvg
|
||||
Component.onCompleted: {
|
||||
barFrameSvg.setImagePath("widgets/bar_meter_horizontal")
|
||||
barFrameSvg.setElementPrefix("bar-active")
|
||||
resizeTimer.restart()
|
||||
}
|
||||
}
|
||||
PlasmaCore.FrameSvg {
|
||||
id: backgroundFrameSvg
|
||||
Component.onCompleted: {
|
||||
backgroundFrameSvg.setImagePath("widgets/bar_meter_horizontal")
|
||||
backgroundFrameSvg.setElementPrefix("bar-inactive")
|
||||
resizeTimer.restart()
|
||||
}
|
||||
}
|
||||
QPixmapItem {
|
||||
id: backgroundPixmapItem
|
||||
anchors.fill: parent
|
||||
fillMode: QPixmapItem.TileHorizontally
|
||||
onWidthChanged: resizeTimer.restart()
|
||||
onHeightChanged: resizeTimer.restart()
|
||||
}
|
||||
|
||||
|
||||
QPixmapItem {
|
||||
id: barPixmapItem
|
||||
fillMode: QPixmapItem.TileHorizontally
|
||||
width: indeterminate ? contents._tileWidth*2 : range.position
|
||||
height: contents.height
|
||||
|
||||
visible: indeterminate || value > 0
|
||||
onWidthChanged: resizeTimer.restart()
|
||||
onHeightChanged: resizeTimer.restart()
|
||||
|
||||
SequentialAnimation {
|
||||
id: indeterminateAnimation
|
||||
|
||||
loops: Animation.Infinite
|
||||
|
||||
onRunningChanged: {
|
||||
if (!running) {
|
||||
barPixmapItem.x = 0
|
||||
}
|
||||
}
|
||||
|
||||
PropertyAnimation {
|
||||
target: barPixmapItem
|
||||
property: "x"
|
||||
duration: 800
|
||||
to: 0
|
||||
}
|
||||
PropertyAnimation {
|
||||
target: barPixmapItem
|
||||
property: "x"
|
||||
duration: 800
|
||||
to: backgroundPixmapItem.width - barPixmapItem.width
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,258 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
|
||||
/**
|
||||
* This item takes a Flickable and automatically puts scrollbars in adjusting
|
||||
* the layout if needed. The scrollbars will be interactive or not, depending
|
||||
* on the platform. If flickableItem is a categorized ListView the vertical
|
||||
* scrollbar will be a SectionScroller.
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* The Flickable of this area: it can be either a Flickable or a subclass,
|
||||
* ListView or GridView
|
||||
*/
|
||||
property Flickable flickableItem
|
||||
//FIXME: this alias seems necessary for it to correctly parse
|
||||
default property alias flickableItemDefault: root.flickableItem
|
||||
|
||||
Connections {
|
||||
target: root
|
||||
onFlickableItemChanged: {
|
||||
root.flickableItem.parent = root
|
||||
root.flickableItem.anchors.fill = root
|
||||
root.flickableItem.clip = true
|
||||
internal.checkVerticalScrollBar()
|
||||
internal.checkHorizontalScrollBar()
|
||||
}
|
||||
}
|
||||
Component.onCompleted: {
|
||||
root.flickableItem.parent = root
|
||||
root.flickableItem.anchors.fill = root
|
||||
root.flickableItem.clip = true
|
||||
internal.checkVerticalScrollBar()
|
||||
internal.checkHorizontalScrollBar()
|
||||
}
|
||||
Connections {
|
||||
target: flickableItem
|
||||
onContentHeightChanged: internal.checkVerticalScrollBar()
|
||||
onHeightChanged: internal.checkVerticalScrollBar()
|
||||
onContentWidthChanged: internal.checkHorizontalScrollBar()
|
||||
onWidthChanged: internal.checkHorizontalScrollBar()
|
||||
}
|
||||
QtObject {
|
||||
id: internal
|
||||
property Item verticalScrollBar
|
||||
property Item horizontalScrollBar
|
||||
|
||||
function checkVerticalScrollBar() {
|
||||
if (!flickableItem) {
|
||||
return
|
||||
}
|
||||
|
||||
if (flickableItem.contentHeight > flickableItem.height) {
|
||||
//Do we have to change the type?
|
||||
//from section to normal
|
||||
if ((!flickableItem.model || flickableItem.model.get === undefined || !flickableItem.section || !flickableItem.section.property) &&
|
||||
(!verticalScrollBar || verticalScrollBar.orientation === undefined)) {
|
||||
if (verticalScrollBar) verticalScrollBar.destroy()
|
||||
verticalScrollBar = verticalScrollBarComponent.createObject(root)
|
||||
//from normal to section
|
||||
} else if (flickableItem.section && flickableItem.section.property &&
|
||||
flickableItem.model.get !== undefined &&
|
||||
(!verticalScrollBar || verticalScrollBar.orientation !== undefined)) {
|
||||
if (verticalScrollBar) verticalScrollBar.destroy()
|
||||
verticalScrollBar = sectionScrollerComponent.createObject(root)
|
||||
}
|
||||
}
|
||||
checkVerticalScrollBarMargins()
|
||||
}
|
||||
|
||||
function checkVerticalScrollBarMargins() {
|
||||
//undefined in case of SectionScroller
|
||||
if ((flickableItem.contentHeight > flickableItem.height) && verticalScrollBar &&
|
||||
((verticalScrollBar.interactive && verticalScrollBar.visible) || (verticalScrollBar.orientation === undefined &&
|
||||
//FIXME: heuristic on width to distinguish the touch sectionscroller
|
||||
verticalScrollBar.width < 30))) {
|
||||
flickableItem.anchors.rightMargin = verticalScrollBar.width
|
||||
} else {
|
||||
flickableItem.anchors.rightMargin = 0
|
||||
}
|
||||
}
|
||||
|
||||
function checkHorizontalScrollBar() {
|
||||
if (!flickableItem || horizontalScrollBar) {
|
||||
return
|
||||
}
|
||||
|
||||
if (flickableItem.contentWidth > flickableItem.width) {
|
||||
if (!horizontalScrollBar) {
|
||||
horizontalScrollBar = horizontalScrollBarComponent.createObject(root)
|
||||
}
|
||||
}
|
||||
checkHorizontalScrollBarMargins()
|
||||
}
|
||||
|
||||
function checkHorizontalScrollBarMargins() {
|
||||
if ((flickableItem.contentWidth > flickableItem.width) &&
|
||||
horizontalScrollBar && horizontalScrollBar.interactive && horizontalScrollBar.visible) {
|
||||
flickableItem.anchors.bottomMargin = horizontalScrollBar.height
|
||||
} else {
|
||||
flickableItem.anchors.bottomMargin = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: verticalScrollBarComponent
|
||||
ScrollBar {
|
||||
flickableItem: root.flickableItem
|
||||
orientation: Qt.Vertical
|
||||
property bool isScrollBar: true
|
||||
z: root.flickableItem.z + 1
|
||||
anchors {
|
||||
left: undefined
|
||||
top: root.top
|
||||
right: root.right
|
||||
bottom: root.bottom
|
||||
bottomMargin: root.height - root.flickableItem.height
|
||||
}
|
||||
onVisibleChanged: internal.checkVerticalScrollBarMargins()
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: horizontalScrollBarComponent
|
||||
ScrollBar {
|
||||
flickableItem: root.flickableItem
|
||||
orientation: Qt.Horizontal
|
||||
z: root.flickableItem.z + 1
|
||||
anchors {
|
||||
left: root.left
|
||||
top: undefined
|
||||
right: root.right
|
||||
bottom: root.bottom
|
||||
rightMargin: root.width - root.flickableItem.width
|
||||
}
|
||||
onVisibleChanged: internal.checkHorizontalScrollBarMargins()
|
||||
}
|
||||
}
|
||||
Component {
|
||||
id: sectionScrollerComponent
|
||||
SectionScroller {
|
||||
listView: root.flickableItem
|
||||
property bool isScrollBar: false
|
||||
z: root.flickableItem.z + 1
|
||||
anchors {
|
||||
left: undefined
|
||||
top: root.top
|
||||
right: root.right
|
||||
bottom: root.bottom
|
||||
bottomMargin: root.height - root.flickableItem.height
|
||||
}
|
||||
onVisibleChanged: internal.checkVerticalScrollBarMargins()
|
||||
}
|
||||
}
|
||||
//FIXME: create all this stuff only on demand, like scrollbars?
|
||||
PlasmaCore.Svg {
|
||||
id: borderSvg
|
||||
imagePath: "widgets/scrollwidget"
|
||||
}
|
||||
PlasmaCore.SvgItem {
|
||||
svg: borderSvg
|
||||
z: 1000
|
||||
elementId: "border-top"
|
||||
width: 100
|
||||
height: naturalSize.height
|
||||
opacity: flickableItem.atYBeginning ? 0 : 1
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
right: parent.right
|
||||
topMargin: flickableItem.anchors.topMargin
|
||||
}
|
||||
}
|
||||
PlasmaCore.SvgItem {
|
||||
svg: borderSvg
|
||||
z: 1000
|
||||
elementId: "border-bottom"
|
||||
width: 100
|
||||
height: naturalSize.height
|
||||
opacity: flickableItem.atYEnd ? 0 : 1
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
left: parent.left
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
bottomMargin: flickableItem.anchors.bottomMargin
|
||||
}
|
||||
}
|
||||
PlasmaCore.SvgItem {
|
||||
svg: borderSvg
|
||||
z: 1000
|
||||
elementId: "border-left"
|
||||
width: naturalSize.width
|
||||
opacity: flickableItem.atXBeginning ? 0 : 1
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
left: parent.left
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
leftMargin: flickableItem.anchors.leftMargin
|
||||
}
|
||||
}
|
||||
PlasmaCore.SvgItem {
|
||||
svg: borderSvg
|
||||
z: 1000
|
||||
elementId: "border-right"
|
||||
width: naturalSize.width
|
||||
opacity: flickableItem.atXEnd ? 0 : 1
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.InOutQuad
|
||||
}
|
||||
}
|
||||
anchors {
|
||||
top: parent.top
|
||||
bottom: parent.bottom
|
||||
right: parent.right
|
||||
rightMargin: flickableItem.anchors.rightMargin
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,218 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
import "private" as Private
|
||||
|
||||
/**
|
||||
* A simple Scroll Bar using the plasma theme.
|
||||
*
|
||||
* This component does not belong to the QtComponents API specification but it
|
||||
* was based on the ScrollDecorator component. You should not use it for touch
|
||||
* interfaces, use a flickable and a ScrollDecorator instead.
|
||||
*
|
||||
* By default, this component looks and behaves like a scroll decorator
|
||||
* on touchscreens.
|
||||
*/
|
||||
// TODO: add support mouse wheel events
|
||||
Item {
|
||||
id: scrollbar
|
||||
|
||||
// Common API
|
||||
/**
|
||||
* The Flickable component which the ScrollBar will interact with.
|
||||
*/
|
||||
property Flickable flickableItem: null
|
||||
/**
|
||||
* The orientation where the ScrollBar will scroll.
|
||||
* The orientation * can be either Qt.Horizontal or Qt.Vertical.
|
||||
*
|
||||
* The default value is Qt.Vertical.
|
||||
*/
|
||||
property int orientation: Qt.Vertical
|
||||
|
||||
/**
|
||||
* Whether the ScrollBar is interactive.
|
||||
*
|
||||
* The default value is true.
|
||||
*/
|
||||
property bool interactive: true
|
||||
|
||||
// Plasma API
|
||||
/**
|
||||
* Whether the ScrollBar will increase the Flickable content in the normal
|
||||
* direction (Left to Right or Top to Bottom) or if this will be inverted.
|
||||
*
|
||||
* The default value is false.
|
||||
*/
|
||||
property bool inverted: false
|
||||
|
||||
/**
|
||||
* type:real
|
||||
* How many steps exist while moving the handler. If you want the
|
||||
* ScrollBar buttons to appear you must set this property to a value
|
||||
* bigger than 0.
|
||||
*
|
||||
* The default value is 0.
|
||||
*/
|
||||
property alias stepSize: range.stepSize
|
||||
|
||||
/**
|
||||
* Indicates if the ScrollBar is pressed.
|
||||
*/
|
||||
property bool pressed: internalLoader.item.mouseArea?internalLoader.item.mouseArea.pressed:false
|
||||
|
||||
/**
|
||||
* The interval time used by the ScrollBar button to increase or decrease
|
||||
* steps.
|
||||
*/
|
||||
property real scrollButtonInterval: 50
|
||||
|
||||
implicitWidth: internalLoader.isVertical ? (internalLoader.item ? internalLoader.item.implicitWidth : 12) : 200
|
||||
implicitHeight: internalLoader.isVertical ? 200 : (internalLoader.item ? internalLoader.item.implicitHeight : 12)
|
||||
// TODO: needs to define if there will be specific graphics for
|
||||
// disabled scroll bars
|
||||
opacity: enabled ? 1.0 : 0.5
|
||||
|
||||
visible: flickableItem && internalLoader.handleEnabled
|
||||
|
||||
anchors {
|
||||
right: internalLoader.anchorableWithFlickable ? flickableItem.right : undefined
|
||||
left: (orientation == Qt.Vertical) ? undefined : (internalLoader.anchorableWithFlickable ? flickableItem.left : undefined)
|
||||
top: (orientation == Qt.Vertical) ? (internalLoader.anchorableWithFlickable ? flickableItem.top : undefined) : undefined
|
||||
bottom: internalLoader.anchorableWithFlickable ? flickableItem.bottom : undefined
|
||||
}
|
||||
|
||||
Loader {
|
||||
id: internalLoader
|
||||
anchors.fill: parent
|
||||
//property bool handleEnabled: internalLoader.isVertical ? item.handle.height < item.contents.height : item.handle.width < item.contents.width
|
||||
property bool handleEnabled: internalLoader.isVertical ? flickableItem.contentHeight > flickableItem.height : flickableItem.contentWidth > flickableItem.width
|
||||
property bool isVertical: orientation == Qt.Vertical
|
||||
property bool anchorableWithFlickable: scrollbar.parent == flickableItem || scrollbar.parent == flickableItem.parent
|
||||
|
||||
function incrementValue(increment)
|
||||
{
|
||||
if (!flickableItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
flickableItem.contentY = Math.max(0, Math.min(flickableItem.contentHeight - flickableItem.height,
|
||||
flickableItem.contentY + increment));
|
||||
} else {
|
||||
flickableItem.contentX = Math.max(0, Math.min(flickableItem.contentWidth - flickableItem.width,
|
||||
flickableItem.contentX + increment));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
onContentHeightChanged: {
|
||||
range.value = flickableItem.contentY;
|
||||
}
|
||||
onContentYChanged: {
|
||||
if (internalLoader.isVertical) {
|
||||
range.value = flickableItem.contentY;
|
||||
}
|
||||
}
|
||||
onContentXChanged: {
|
||||
if (!internalLoader.isVertical) {
|
||||
range.value = flickableItem.contentX;
|
||||
}
|
||||
}
|
||||
}
|
||||
Connections {
|
||||
target: internalLoader.item.handle
|
||||
onYChanged: updateFromHandleTimer.running = true
|
||||
onXChanged: updateFromHandleTimer.running = true
|
||||
}
|
||||
RangeModel {
|
||||
id: range
|
||||
|
||||
minimumValue: 0
|
||||
maximumValue: {
|
||||
var diff;
|
||||
if (internalLoader.isVertical) {
|
||||
diff = flickableItem.contentHeight - flickableItem.height;
|
||||
} else {
|
||||
diff = flickableItem.contentWidth - flickableItem.width;
|
||||
}
|
||||
|
||||
return Math.max(0, diff);
|
||||
}
|
||||
|
||||
stepSize: 10
|
||||
inverted: scrollbar.inverted
|
||||
positionAtMinimum: 0
|
||||
positionAtMaximum: {
|
||||
if (internalLoader.isVertical) {
|
||||
internalLoader.item.contents.height - internalLoader.item.handle.height;
|
||||
} else {
|
||||
internalLoader.item.contents.width - internalLoader.item.handle.width;
|
||||
}
|
||||
}
|
||||
|
||||
onValueChanged: {
|
||||
if (flickableItem.moving) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
flickableItem.contentY = value;
|
||||
} else {
|
||||
flickableItem.contentX = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
onPositionChanged: {
|
||||
if (internalLoader.item.mouseArea && internalLoader.item.mouseArea.pressed) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
internalLoader.item.handle.y = position;
|
||||
} else {
|
||||
internalLoader.item.handle.x = position; }
|
||||
}
|
||||
}
|
||||
|
||||
Timer {
|
||||
id: updateFromHandleTimer
|
||||
interval: 10
|
||||
onTriggered: {
|
||||
if (!enabled || !interactive) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
range.position = internalLoader.item.handle.y;
|
||||
} else {
|
||||
range.position = internalLoader.item.handle.x;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
source: interactive ? "private/ScrollBarDelegate.qml" : "private/ScrollDecoratorDelegate.qml"
|
||||
}
|
||||
}
|
|
@ -1,176 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Components project.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
import QtQuick 1.1
|
||||
import "private/SectionScroller.js" as Sections
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
|
||||
/**
|
||||
* Similar to a ScrollBar or a ScrollDecorator.
|
||||
*
|
||||
* It's interactive and works on ListViews that have section.property set, so
|
||||
* its contents are categorized.
|
||||
*
|
||||
* An indicator will say to what category the user scrolled to. Useful for
|
||||
* things like address books or things sorted by date. Don't use with models
|
||||
* too big (thousands of items) because it implies loading all the items to
|
||||
* memory, as well loses precision.
|
||||
*/
|
||||
Item {
|
||||
id: root
|
||||
|
||||
/**
|
||||
* The listview the sectionScroller will operate on. This component doesn't
|
||||
* work with Flickable or GridView.
|
||||
*/
|
||||
property ListView listView
|
||||
|
||||
onListViewChanged: {
|
||||
if (listView && listView.model)
|
||||
internal.initDirtyObserver();
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: listView
|
||||
onModelChanged: {
|
||||
if (listView && listView.model) {
|
||||
internal.initDirtyObserver()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
implicitWidth: scrollBar.implicitWidth
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
}
|
||||
}
|
||||
|
||||
anchors {
|
||||
right: listView.right
|
||||
top: listView.top
|
||||
bottom: listView.bottom
|
||||
}
|
||||
|
||||
|
||||
RangeModel {
|
||||
id: range
|
||||
|
||||
minimumValue: 0
|
||||
maximumValue: Math.max(0, listView.contentHeight - listView.height)
|
||||
stepSize: 0
|
||||
//inverted: true
|
||||
positionAtMinimum: root.width*2
|
||||
positionAtMaximum: root.height - root.width*2
|
||||
value: listView.contentY
|
||||
onPositionChanged: sectionLabel.text = Sections.closestSection(position/listView.height)
|
||||
|
||||
}
|
||||
|
||||
ScrollBar {
|
||||
id: scrollBar
|
||||
flickableItem: listView
|
||||
anchors.fill: parent
|
||||
interactive: true
|
||||
}
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: tooltip
|
||||
imagePath: "widgets/tooltip"
|
||||
width: sectionLabel.width + margins.left + margins.right
|
||||
height: sectionLabel.height + margins.top + margins.bottom
|
||||
Label {
|
||||
id: sectionLabel
|
||||
x: parent.margins.left
|
||||
y: parent.margins.top
|
||||
}
|
||||
y: Math.min(root.height-height-scrollBar.width, Math.max(scrollBar.width, range.position - height/2))
|
||||
anchors {
|
||||
//verticalCenter: handle.verticalCenter
|
||||
right: parent.left
|
||||
}
|
||||
opacity: sectionLabel.text && scrollBar.pressed ? 1 : 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Timer {
|
||||
id: dirtyTimer
|
||||
interval: 250
|
||||
onTriggered: {
|
||||
Sections.initSectionData(listView);
|
||||
internal.modelDirty = false;
|
||||
tooltip.visible = Sections._sections.length > 1
|
||||
}
|
||||
}
|
||||
QtObject {
|
||||
id: internal
|
||||
|
||||
property bool modelDirty: false
|
||||
function initDirtyObserver() {
|
||||
Sections.initSectionData(listView);
|
||||
tooltip.visible = Sections._sections.length > 1
|
||||
function dirtyObserver() {
|
||||
if (!internal.modelDirty) {
|
||||
internal.modelDirty = true;
|
||||
dirtyTimer.running = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (listView.model.countChanged)
|
||||
listView.model.countChanged.connect(dirtyObserver);
|
||||
|
||||
if (listView.model.itemsChanged)
|
||||
listView.model.itemsChanged.connect(dirtyObserver);
|
||||
|
||||
if (listView.model.itemsInserted)
|
||||
listView.model.itemsInserted.connect(dirtyObserver);
|
||||
|
||||
if (listView.model.itemsMoved)
|
||||
listView.model.itemsMoved.connect(dirtyObserver);
|
||||
|
||||
if (listView.model.itemsRemoved)
|
||||
listView.model.itemsRemoved.connect(dirtyObserver);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,44 +0,0 @@
|
|||
/*
|
||||
* Copyright 2012 by Sebastian Kügler <sebas@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
|
||||
/**
|
||||
* This is a title label which uses the plasma theme. The characteristics of
|
||||
* the text will be automatically set according to the plasma theme. Use this
|
||||
* components for titles in your UI, for example page or section titles.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* import org.kde.plasma.components 0.1 as PlasmaComponents
|
||||
* [...]
|
||||
* Column {
|
||||
* PlasmaComponents.Title { text: "Fruit sweetness on the rise" }
|
||||
* [...]
|
||||
* }
|
||||
* @endcode
|
||||
*
|
||||
* See PlasmaComponents Label and primitive QML Text element API for additional
|
||||
* properties, methods and signals.
|
||||
*/
|
||||
Label {
|
||||
id: root
|
||||
|
||||
font.pointSize: theme.defaultFont.pointSize*2
|
||||
}
|
|
@ -1,20 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2012 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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 Library 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.
|
||||
*/
|
||||
|
||||
var mouseOverEnabled = true
|
|
@ -1,267 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
imagePath:"widgets/scrollbar"
|
||||
prefix: internalLoader.isVertical ? "background-vertical" : "background-horizontal"
|
||||
|
||||
property int implicitWidth: scrollbarSvg.hasElement("hint-scrollbar-size") ? scrollbarSvg.elementSize("hint-scrollbar-size").width : scrollbarSvg.elementSize("arrow-up").width
|
||||
property int implicitHeight: scrollbarSvg.hasElement("hint-scrollbar-size") ? scrollbarSvg.elementSize("hint-scrollbar-size").height : scrollbarSvg.elementSize("arrow-left").height
|
||||
|
||||
Keys.onUpPressed: {
|
||||
if (!enabled || !internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
}
|
||||
|
||||
Keys.onDownPressed: {
|
||||
if (!enabled || !internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(stepSize);
|
||||
}
|
||||
|
||||
Keys.onLeftPressed: {
|
||||
if (!enabled || internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
}
|
||||
|
||||
Keys.onRightPressed: {
|
||||
if (!enabled || internalLoader.isVertical)
|
||||
return;
|
||||
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(stepSize);
|
||||
}
|
||||
|
||||
property Item handle: handle
|
||||
|
||||
property Item contents: contents
|
||||
Item {
|
||||
id: contents
|
||||
anchors {
|
||||
fill: parent
|
||||
leftMargin: (!internalLoader.isVertical && leftButton.visible) ? leftButton.width : 0
|
||||
rightMargin: (!internalLoader.isVertical && rightButton.visible) ? rightButton.width : 0
|
||||
topMargin: (internalLoader.isVertical && leftButton.visible) ? leftButton.height : 0
|
||||
bottomMargin: (internalLoader.isVertical && rightButton.visible) ? rightButton.height : 0
|
||||
}
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: handle
|
||||
imagePath:"widgets/scrollbar"
|
||||
prefix: {
|
||||
if (mouseArea.pressed) {
|
||||
return "sunken-slider"
|
||||
}
|
||||
|
||||
if (scrollbar.activeFocus || mouseArea.containsMouse) {
|
||||
return "mouseover-slider"
|
||||
} else {
|
||||
return "slider"
|
||||
}
|
||||
}
|
||||
|
||||
property int length: internalLoader.isVertical? flickableItem.visibleArea.heightRatio * parent.height : flickableItem.visibleArea.widthRatio * parent.width
|
||||
|
||||
width: internalLoader.isVertical ? parent.width : length
|
||||
height: internalLoader.isVertical ? length : parent.height
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.Svg {
|
||||
id: scrollbarSvg
|
||||
imagePath: "widgets/scrollbar"
|
||||
property bool arrowPresent: scrollbarSvg.hasElement("arrow-up")
|
||||
//new theme may be different
|
||||
onRepaintNeeded: arrowPresent = scrollbarSvg.hasElement("arrow-up")
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: leftButton
|
||||
visible: stepSize > 0 && scrollbarSvg.arrowPresent
|
||||
|
||||
anchors {
|
||||
left: internalLoader.isVertical ? undefined : parent.left
|
||||
verticalCenter: internalLoader.isVertical ? undefined : parent.verticalCenter
|
||||
top: internalLoader.isVertical ? parent.top : undefined
|
||||
horizontalCenter: internalLoader.isVertical ? parent.horizontalCenter : undefined
|
||||
}
|
||||
width: 18
|
||||
height: 18
|
||||
svg: scrollbarSvg
|
||||
elementId: {
|
||||
if (leftMouseArea.pressed) {
|
||||
return internalLoader.isVertical ? "sunken-arrow-up" : "sunken-arrow-left"
|
||||
}
|
||||
|
||||
if (scrollbar.activeFocus || leftMouseArea.containsMouse) {
|
||||
return internalLoader.isVertical ? "mouseover-arrow-up" : "mouseover-arrow-left"
|
||||
} else {
|
||||
return internalLoader.isVertical ? "arrow-up" : "arrow-left"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: leftMouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
enabled: scrollbar.enabled
|
||||
hoverEnabled: true
|
||||
|
||||
Timer {
|
||||
id: leftTimer
|
||||
interval: scrollbar.scrollButtonInterval;
|
||||
running: parent.pressed
|
||||
repeat: true
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
background.forceActiveFocus()
|
||||
if (inverted) {
|
||||
internalLoader.incrementValue(stepSize);
|
||||
} else {
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.SvgItem {
|
||||
id: rightButton
|
||||
visible: leftButton.visible
|
||||
|
||||
anchors {
|
||||
right: internalLoader.isVertical ? undefined : parent.right
|
||||
verticalCenter: internalLoader.isVertical ? undefined : parent.verticalCenter
|
||||
bottom: internalLoader.isVertical ? parent.bottom : undefined
|
||||
horizontalCenter: internalLoader.isVertical ? parent.horizontalCenter : undefined
|
||||
}
|
||||
width: 18
|
||||
height: 18
|
||||
svg: scrollbarSvg
|
||||
elementId: {
|
||||
if (rightMouseArea.pressed) {
|
||||
return internalLoader.isVertical ? "sunken-arrow-down" : "sunken-arrow-right"
|
||||
}
|
||||
|
||||
if (scrollbar.activeFocus || rightMouseArea.containsMouse) {
|
||||
return internalLoader.isVertical ? "mouseover-arrow-down" : "mouseover-arrow-right"
|
||||
} else {
|
||||
return internalLoader.isVertical ? "arrow-down" : "arrow-right"
|
||||
}
|
||||
}
|
||||
|
||||
MouseArea {
|
||||
id: rightMouseArea
|
||||
|
||||
anchors.fill: parent
|
||||
enabled: scrollbar.enabled
|
||||
hoverEnabled: true
|
||||
|
||||
Timer {
|
||||
id: rightTimer
|
||||
interval: scrollbar.scrollButtonInterval;
|
||||
running: parent.pressed;
|
||||
repeat: true
|
||||
triggeredOnStart: true
|
||||
onTriggered: {
|
||||
background.forceActiveFocus();
|
||||
if (inverted)
|
||||
internalLoader.incrementValue(-stepSize);
|
||||
else
|
||||
internalLoader.incrementValue(stepSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
property MouseArea mouseArea: mouseArea
|
||||
MouseArea {
|
||||
id: mouseArea
|
||||
|
||||
anchors.fill: contents
|
||||
enabled: scrollbar.enabled
|
||||
hoverEnabled: true
|
||||
drag {
|
||||
target: handle
|
||||
axis: internalLoader.isVertical ? Drag.YAxis : Drag.XAxis
|
||||
minimumX: range.positionAtMinimum
|
||||
maximumX: range.positionAtMaximum
|
||||
minimumY: range.positionAtMinimum
|
||||
maximumY: range.positionAtMaximum
|
||||
}
|
||||
|
||||
onPressed: {
|
||||
if (internalLoader.isVertical) {
|
||||
// Clamp the value
|
||||
var newY = Math.max(mouse.y, drag.minimumY);
|
||||
newY = Math.min(newY, drag.maximumY);
|
||||
|
||||
// Debounce the press: a press event inside the handler will not
|
||||
// change its position, the user needs to drag it.
|
||||
if (newY > handle.y + handle.height) {
|
||||
handle.y = mouse.y - handle.height
|
||||
} else if (newY < handle.y) {
|
||||
handle.y = mouse.y
|
||||
}
|
||||
} else {
|
||||
// Clamp the value
|
||||
var newX = Math.max(mouse.x, drag.minimumX);
|
||||
newX = Math.min(newX, drag.maximumX);
|
||||
|
||||
// Debounce the press: a press event inside the handler will not
|
||||
// change its position, the user needs to drag it.
|
||||
if (newX > handle.x + handle.width) {
|
||||
handle.x = mouse.x - handle.width
|
||||
} else if (newX < handle.x) {
|
||||
handle.x = mouse.x
|
||||
}
|
||||
}
|
||||
|
||||
background.forceActiveFocus();
|
||||
}
|
||||
|
||||
Component.onCompleted: {
|
||||
acceptedButtons |= Qt.MiddleButton
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,122 +0,0 @@
|
|||
/*
|
||||
* Copyright (C) 2011 by Daker Fernandes Pinheiro <dakerfp@gmail.com>
|
||||
* Copyright (C) 2011 Marco Martin <mart@kde.org>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Library General Public License as
|
||||
* published by the Free Software Foundation; either version 2, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import QtQuick 1.1
|
||||
import org.kde.plasma.core 0.1 as PlasmaCore
|
||||
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: background
|
||||
anchors.fill: parent
|
||||
imagePath:"widgets/scrollbar"
|
||||
prefix: internalLoader.isVertical ? "background-vertical" : "background-horizontal"
|
||||
|
||||
property int implicitWidth: scrollbarSvg.hasElement("hint-scrollbar-size") ? scrollbarSvg.elementSize("hint-scrollbar-size").width : 12
|
||||
property int implicitHeight: scrollbarSvg.hasElement("hint-scrollbar-size") ? scrollbarSvg.elementSize("hint-scrollbar-size").height : 12
|
||||
|
||||
opacity: 0
|
||||
Behavior on opacity {
|
||||
NumberAnimation {
|
||||
duration: 250
|
||||
easing.type: Easing.OutQuad
|
||||
}
|
||||
}
|
||||
|
||||
PlasmaCore.Svg {
|
||||
id: scrollbarSvg
|
||||
imagePath: "widgets/scrollbar"
|
||||
}
|
||||
|
||||
property Item handle: handle
|
||||
|
||||
property Item contents: contents
|
||||
Item {
|
||||
id: contents
|
||||
anchors.fill: parent
|
||||
|
||||
PlasmaCore.FrameSvgItem {
|
||||
id: handle
|
||||
imagePath:"widgets/scrollbar"
|
||||
prefix: "slider"
|
||||
|
||||
function length()
|
||||
{
|
||||
var nh, ny;
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
nh = flickableItem.visibleArea.heightRatio * internalLoader.height
|
||||
} else {
|
||||
nh = flickableItem.visibleArea.widthRatio * internalLoader.width
|
||||
}
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
ny = flickableItem.visibleArea.yPosition * internalLoader.height
|
||||
} else {
|
||||
ny = flickableItem.visibleArea.xPosition * internalLoader.width
|
||||
}
|
||||
|
||||
if (ny > 3) {
|
||||
var t
|
||||
|
||||
if (internalLoader.isVertical) {
|
||||
t = Math.ceil(internalLoader.height - 3 - ny)
|
||||
} else {
|
||||
t = Math.ceil(internalLoader.width - 3 - ny)
|
||||
}
|
||||
|
||||
if (nh > t) {
|
||||
return t
|
||||
} else {
|
||||
return nh
|
||||
}
|
||||
} else {
|
||||
return nh + ny
|
||||
}
|
||||
}
|
||||
|
||||
width: internalLoader.isVertical ? parent.width : length()
|
||||
height: internalLoader.isVertical ? length() : parent.height
|
||||
}
|
||||
}
|
||||
|
||||
property MouseArea mouseArea: null
|
||||
|
||||
Connections {
|
||||
target: flickableItem
|
||||
onMovingChanged: {
|
||||
if (flickableItem.moving) {
|
||||
opacityTimer.running = false
|
||||
background.opacity = 1
|
||||
} else {
|
||||
opacityTimer.restart()
|
||||
}
|
||||
}
|
||||
}
|
||||
Timer {
|
||||
id: opacityTimer
|
||||
interval: 500
|
||||
repeat: false
|
||||
running: false
|
||||
onTriggered: {
|
||||
background.opacity = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,71 +0,0 @@
|
|||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
|
||||
** All rights reserved.
|
||||
** Contact: Nokia Corporation (qt-info@nokia.com)
|
||||
**
|
||||
** This file is part of the Qt Components project.
|
||||
**
|
||||
** $QT_BEGIN_LICENSE:BSD$
|
||||
** You may use this file under the terms of the BSD license as follows:
|
||||
**
|
||||
** "Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions are
|
||||
** met:
|
||||
** * Redistributions of source code must retain the above copyright
|
||||
** notice, this list of conditions and the following disclaimer.
|
||||
** * Redistributions in binary form must reproduce the above copyright
|
||||
** notice, this list of conditions and the following disclaimer in
|
||||
** the documentation and/or other materials provided with the
|
||||
** distribution.
|
||||
** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
|
||||
** the names of its contributors may be used to endorse or promote
|
||||
** products derived from this software without specific prior written
|
||||
** permission.
|
||||
**
|
||||
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
|
||||
** $QT_END_LICENSE$
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
var _sectionData = [];
|
||||
var _sections = [];
|
||||
|
||||
function initSectionData(list) {
|
||||
if (!list || !list.model) return;
|
||||
_sectionData = [];
|
||||
_sections = [];
|
||||
var current = "";
|
||||
var prop = list.section.property;
|
||||
|
||||
for (var i = 0, count = list.model.count; i < count; i++) {
|
||||
var item = list.model.get(i);
|
||||
if (item[prop] !== current) {
|
||||
current = item[prop];
|
||||
_sections.push(current);
|
||||
_sectionData.push({ index: i, header: current });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function closestSection(pos) {
|
||||
var tmp = (_sections.length) * pos;
|
||||
var val = Math.ceil(tmp) // TODO: better algorithm
|
||||
val = val < 2 ? 1 : val;
|
||||
return _sections[val-1];
|
||||
}
|
||||
|
||||
function indexOf(sectionName) {
|
||||
var val = _sectionData[_sections.indexOf(sectionName)].index;
|
||||
return val === 0 || val > 0 ? val : -1;
|
||||
}
|
|
@ -3,16 +3,9 @@ plugin plasmacomponentsplugin
|
|||
BusyIndicator 0.1 BusyIndicator.qml
|
||||
Button 0.1 Button.qml
|
||||
ButtonGroup 0.1 ButtonGroup.js
|
||||
ContextMenu 0.1 ContextMenu.qml
|
||||
Highlight 0.1 Highlight.qml
|
||||
Label 0.1 Label.qml
|
||||
ListItem 0.1 ListItem.qml
|
||||
ProgressBar 0.1 ProgressBar.qml
|
||||
ScrollBar 0.1 ScrollBar.qml
|
||||
SectionScroller 0.1 SectionScroller.qml
|
||||
TabBar 0.1 TabBar.qml
|
||||
TabButton 0.1 TabButton.qml
|
||||
TabGroup 0.1 TabGroup.qml
|
||||
ToolButton 0.1 ToolButton.qml
|
||||
ScrollArea 0.1 ScrollArea.qml
|
||||
Title 0.1 Title.qml
|
||||
|
|
|
@ -79,7 +79,7 @@ DialogWidth=302
|
|||
[Containments][1][Applets][5][Configuration][Applets][9]
|
||||
geometry=0,0,24,24
|
||||
immutability=1
|
||||
plugin=org.kde.notifications
|
||||
plugin=notifications
|
||||
zvalue=0
|
||||
|
||||
[Containments][1][Applets][5][Configuration][Applets][9][PopupApplet]
|
||||
|
|
Loading…
Add table
Reference in a new issue