Merge branch 'mart/useActivities'
Conflicts: src/shell/shellcorona.cpp
This commit is contained in:
commit
92847333a0
@ -179,6 +179,7 @@ void Containment::restore(KConfigGroup &group)
|
|||||||
|
|
||||||
setLocation((Plasma::Types::Location)group.readEntry("location", (int)d->location));
|
setLocation((Plasma::Types::Location)group.readEntry("location", (int)d->location));
|
||||||
setFormFactor((Plasma::Types::FormFactor)group.readEntry("formfactor", (int)d->formFactor));
|
setFormFactor((Plasma::Types::FormFactor)group.readEntry("formfactor", (int)d->formFactor));
|
||||||
|
d->lastScreen = group.readEntry("lastScreen", d->lastScreen);
|
||||||
|
|
||||||
setWallpaper(group.readEntry("wallpaperplugin", ContainmentPrivate::defaultWallpaper));
|
setWallpaper(group.readEntry("wallpaperplugin", ContainmentPrivate::defaultWallpaper));
|
||||||
|
|
||||||
@ -245,6 +246,7 @@ void Containment::save(KConfigGroup &g) const
|
|||||||
}
|
}
|
||||||
|
|
||||||
group.writeEntry("screen", d->screen);
|
group.writeEntry("screen", d->screen);
|
||||||
|
group.writeEntry("lastScreen", d->lastScreen);
|
||||||
group.writeEntry("formfactor", (int)d->formFactor);
|
group.writeEntry("formfactor", (int)d->formFactor);
|
||||||
group.writeEntry("location", (int)d->location);
|
group.writeEntry("location", (int)d->location);
|
||||||
group.writeEntry("activityId", d->activityId);
|
group.writeEntry("activityId", d->activityId);
|
||||||
@ -452,6 +454,11 @@ int Containment::screen() const
|
|||||||
return d->screen;
|
return d->screen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int Containment::lastScreen() const
|
||||||
|
{
|
||||||
|
return d->lastScreen;
|
||||||
|
}
|
||||||
|
|
||||||
void Containment::setDrawWallpaper(bool drawWallpaper)
|
void Containment::setDrawWallpaper(bool drawWallpaper)
|
||||||
{
|
{
|
||||||
if (d->drawWallpaper == drawWallpaper) {
|
if (d->drawWallpaper == drawWallpaper) {
|
||||||
|
@ -148,6 +148,13 @@ class PLASMA_EXPORT Containment : public Applet
|
|||||||
*/
|
*/
|
||||||
int screen() const;
|
int screen() const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return the last screen number this containment had
|
||||||
|
* only returns -1 if it's never ever been on a screen
|
||||||
|
* @since 4.5
|
||||||
|
*/
|
||||||
|
int lastScreen() const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @reimp
|
* @reimp
|
||||||
* @sa Applet::save(KConfigGroup &)
|
* @sa Applet::save(KConfigGroup &)
|
||||||
|
@ -175,6 +175,22 @@ Containment *Corona::containmentForScreen(int screen) const
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Containment *Corona::containmentForScreen(int screen, const QString &defaultPluginIfNonExistent)
|
||||||
|
{
|
||||||
|
Containment *containment = containmentForScreen(screen);
|
||||||
|
if (!containment && !defaultPluginIfNonExistent.isEmpty()) {
|
||||||
|
// screen requests are allowed to bypass immutability
|
||||||
|
if (screen >= 0 && screen < numScreens()) {
|
||||||
|
containment = d->addContainment(defaultPluginIfNonExistent, QVariantList(), 0);
|
||||||
|
if (containment) {
|
||||||
|
containment->setScreen(screen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return containment;
|
||||||
|
}
|
||||||
|
|
||||||
QList<Containment*> Corona::containments() const
|
QList<Containment*> Corona::containments() const
|
||||||
{
|
{
|
||||||
return d->containments;
|
return d->containments;
|
||||||
|
@ -99,6 +99,17 @@ public:
|
|||||||
*/
|
*/
|
||||||
Containment *containmentForScreen(int screen) const;
|
Containment *containmentForScreen(int screen) const;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the Containment for a given physical screen and desktop, creating one
|
||||||
|
* if none exists
|
||||||
|
*
|
||||||
|
* @param screen number of the physical screen to locate
|
||||||
|
* @param defaultPluginIfNonExistent the plugin to load by default; "null" is an empty
|
||||||
|
* Containment and "default" creates the default plugin
|
||||||
|
* @since 4.6
|
||||||
|
*/
|
||||||
|
Containment *containmentForScreen(int screen, const QString &defaultPluginIfNonExistent);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the number of screens available to plasma.
|
* Returns the number of screens available to plasma.
|
||||||
* Subclasses should override this method as the default
|
* Subclasses should override this method as the default
|
||||||
|
@ -132,6 +132,10 @@ void ContainmentPrivate::setScreen(int newScreen)
|
|||||||
#endif
|
#endif
|
||||||
KConfigGroup c = q->config();
|
KConfigGroup c = q->config();
|
||||||
c.writeEntry("screen", screen);
|
c.writeEntry("screen", screen);
|
||||||
|
if (newScreen != -1) {
|
||||||
|
lastScreen = newScreen;
|
||||||
|
c.writeEntry("lastScreen", lastScreen);
|
||||||
|
}
|
||||||
emit q->configNeedsSaving();
|
emit q->configNeedsSaving();
|
||||||
emit q->screenChanged(oldScreen, newScreen, q);
|
emit q->screenChanged(oldScreen, newScreen, q);
|
||||||
}
|
}
|
||||||
|
@ -50,6 +50,7 @@ public:
|
|||||||
formFactor(Types::Planar),
|
formFactor(Types::Planar),
|
||||||
location(Types::Floating),
|
location(Types::Floating),
|
||||||
screen(-1), // no screen
|
screen(-1), // no screen
|
||||||
|
lastScreen(-1), // never had a screen
|
||||||
type(Plasma::Types::NoContainmentType),
|
type(Plasma::Types::NoContainmentType),
|
||||||
drawWallpaper(false)
|
drawWallpaper(false)
|
||||||
{
|
{
|
||||||
@ -103,6 +104,7 @@ public:
|
|||||||
QString wallpaper;
|
QString wallpaper;
|
||||||
QHash<QString, ContainmentActions*> localActionPlugins;
|
QHash<QString, ContainmentActions*> localActionPlugins;
|
||||||
int screen;
|
int screen;
|
||||||
|
int lastScreen;
|
||||||
QString activityId;
|
QString activityId;
|
||||||
Types::ContainmentType type;
|
Types::ContainmentType type;
|
||||||
bool drawWallpaper : 1;
|
bool drawWallpaper : 1;
|
||||||
|
@ -69,8 +69,10 @@ void PlasmaQuickViewPrivate::setContainment(Plasma::Containment *cont)
|
|||||||
QObject::disconnect(containment.data(), 0, q, 0);
|
QObject::disconnect(containment.data(), 0, q, 0);
|
||||||
QObject *oldGraphicObject = containment.data()->property("graphicObject").value<QObject *>();
|
QObject *oldGraphicObject = containment.data()->property("graphicObject").value<QObject *>();
|
||||||
if (oldGraphicObject) {
|
if (oldGraphicObject) {
|
||||||
|
qDebug() << "Old graphics Object:" << oldGraphicObject << "Old containment" << containment.data();
|
||||||
//make sure the graphic object won't die with us
|
//make sure the graphic object won't die with us
|
||||||
oldGraphicObject->setParent(cont);
|
//FIXME:we need a way to reparent to *NO* graphics item, but this makes Qt crash
|
||||||
|
oldGraphicObject->setParent(containment.data());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ find_package(Qt5Quick REQUIRED)
|
|||||||
find_package(Qt5Script REQUIRED)
|
find_package(Qt5Script REQUIRED)
|
||||||
find_package(KCoreAddons REQUIRED)
|
find_package(KCoreAddons REQUIRED)
|
||||||
find_package(Solid REQUIRED)
|
find_package(Solid REQUIRED)
|
||||||
|
find_package(KActivities REQUIRED)
|
||||||
|
|
||||||
set(scripting_SRC
|
set(scripting_SRC
|
||||||
scripting/appinterface.cpp
|
scripting/appinterface.cpp
|
||||||
@ -42,10 +43,12 @@ set(widgetexplorer_SRC
|
|||||||
)
|
)
|
||||||
|
|
||||||
add_executable(plasma-shell
|
add_executable(plasma-shell
|
||||||
|
activity.cpp
|
||||||
main.cpp
|
main.cpp
|
||||||
containmentconfigview.cpp
|
containmentconfigview.cpp
|
||||||
currentcontainmentactionsmodel.cpp
|
currentcontainmentactionsmodel.cpp
|
||||||
desktopview.cpp
|
desktopview.cpp
|
||||||
|
kidenticongenerator.cpp
|
||||||
panelview.cpp
|
panelview.cpp
|
||||||
panelconfigview.cpp
|
panelconfigview.cpp
|
||||||
panelshadows.cpp
|
panelshadows.cpp
|
||||||
@ -74,6 +77,8 @@ target_link_libraries(plasma-shell
|
|||||||
KF5::KDeclarative
|
KF5::KDeclarative
|
||||||
KF5::KI18n
|
KF5::KI18n
|
||||||
KF5::XmlGui
|
KF5::XmlGui
|
||||||
|
KF5::KIconThemes
|
||||||
|
KF5::KActivities
|
||||||
)
|
)
|
||||||
target_include_directories(plasma-shell PRIVATE "${CMAKE_BINARY_DIR}")
|
target_include_directories(plasma-shell PRIVATE "${CMAKE_BINARY_DIR}")
|
||||||
|
|
||||||
|
402
src/shell/activity.cpp
Normal file
402
src/shell/activity.cpp
Normal file
@ -0,0 +1,402 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Chani Armitage <chani@kde.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2,
|
||||||
|
* 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 "shellcorona.h"
|
||||||
|
#include "kidenticongenerator.h"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QString>
|
||||||
|
#include <QSize>
|
||||||
|
#include <QFile>
|
||||||
|
|
||||||
|
#include <kconfig.h>
|
||||||
|
#include <kicon.h>
|
||||||
|
#include <kstandarddirs.h>
|
||||||
|
#include <kwindowsystem.h>
|
||||||
|
|
||||||
|
#include <Plasma/Containment>
|
||||||
|
#include <Plasma/Corona>
|
||||||
|
|
||||||
|
#include <kactivities/controller.h>
|
||||||
|
#include <kactivities/consumer.h>
|
||||||
|
|
||||||
|
#include "activity.h"
|
||||||
|
|
||||||
|
Activity::Activity(const QString &id, Plasma::Corona *parent)
|
||||||
|
: QObject(parent),
|
||||||
|
m_id(id),
|
||||||
|
m_plugin("org.kde.desktopcontainment"),
|
||||||
|
m_info(new KActivities::Info(id, this)),
|
||||||
|
m_activityConsumer(new KActivities::Consumer(this)),
|
||||||
|
m_corona(parent),
|
||||||
|
m_current(false)
|
||||||
|
{
|
||||||
|
m_name = m_info->name();
|
||||||
|
m_icon = m_info->icon();
|
||||||
|
|
||||||
|
connect(m_info, SIGNAL(infoChanged()), this, SLOT(activityChanged()));
|
||||||
|
connect(m_info, SIGNAL(stateChanged(KActivities::Info::State)), this, SLOT(activityStateChanged(KActivities::Info::State)));
|
||||||
|
connect(m_info, SIGNAL(started()), this, SLOT(opened()));
|
||||||
|
connect(m_info, SIGNAL(stopped()), this, SLOT(closed()));
|
||||||
|
connect(m_info, SIGNAL(removed()), this, SLOT(removed()));
|
||||||
|
|
||||||
|
connect(m_activityConsumer, SIGNAL(currentActivityChanged(QString)), this, SLOT(checkIfCurrent()));
|
||||||
|
checkIfCurrent();
|
||||||
|
|
||||||
|
//find your containments
|
||||||
|
foreach (Plasma::Containment *cont, m_corona->containments()) {
|
||||||
|
if ((cont->containmentType() == Plasma::Types::DesktopContainment ||
|
||||||
|
cont->containmentType() == Plasma::Types::CustomContainment) &&
|
||||||
|
cont->activity() == id) {
|
||||||
|
insertContainment(cont);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//qDebug() << m_containments.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
Activity::~Activity()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::activityChanged()
|
||||||
|
{
|
||||||
|
setName(m_info->name());
|
||||||
|
setIcon(m_info->icon());
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::activityStateChanged(KActivities::Info::State state)
|
||||||
|
{
|
||||||
|
Q_UNUSED(state)
|
||||||
|
emit stateChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Activity::id()
|
||||||
|
{
|
||||||
|
return m_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
QString Activity::name()
|
||||||
|
{
|
||||||
|
return m_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap Activity::pixmap(const QSize &size)
|
||||||
|
{
|
||||||
|
if (m_info->isValid() && !m_info->icon().isEmpty()) {
|
||||||
|
return KIcon(m_info->icon()).pixmap(size);
|
||||||
|
} else {
|
||||||
|
return KIdenticonGenerator::self()->generatePixmap(size.width(), m_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Activity::isCurrent()
|
||||||
|
{
|
||||||
|
return m_current;
|
||||||
|
//TODO maybe plasmaapp should cache the current activity to reduce dbus calls?
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::checkIfCurrent()
|
||||||
|
{
|
||||||
|
const bool current = m_id == m_activityConsumer->currentActivity();
|
||||||
|
if (current != m_current) {
|
||||||
|
m_current = current;
|
||||||
|
emit currentStatusChanged();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
KActivities::Info::State Activity::state()
|
||||||
|
{
|
||||||
|
return m_info->state();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::remove()
|
||||||
|
{
|
||||||
|
KActivities::Controller().removeActivity(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::removed()
|
||||||
|
{
|
||||||
|
if (! m_containments.isEmpty()) {
|
||||||
|
//FIXME only m_corona has authority to remove properly
|
||||||
|
qDebug() << "!!!!! if your widgets are locked you've hit a BUG now";
|
||||||
|
foreach (Plasma::Containment *c, m_containments) {
|
||||||
|
c->destroy();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString name = "activities/" + m_id;
|
||||||
|
QFile::remove(KStandardDirs::locateLocal("appdata", name));
|
||||||
|
}
|
||||||
|
|
||||||
|
Plasma::Containment* Activity::containmentForScreen(int screen)
|
||||||
|
{
|
||||||
|
Plasma::Containment *containment = m_containments.value(screen);
|
||||||
|
|
||||||
|
if (!containment) {
|
||||||
|
qDebug() << "adding containment for" << screen;
|
||||||
|
// first look to see if there are any unnasigned containments that are candidates for
|
||||||
|
// being sucked into this Activity
|
||||||
|
foreach (Plasma::Containment *c, m_corona->containments()) {
|
||||||
|
if ((c->containmentType() == Plasma::Types::DesktopContainment ||
|
||||||
|
c->containmentType() == Plasma::Types::CustomContainment) &&
|
||||||
|
c->activity().isEmpty() &&
|
||||||
|
m_containments.key(c, -2) == -2) {
|
||||||
|
containment = c;
|
||||||
|
containment->setScreen(screen);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!containment) {
|
||||||
|
// we ask for the containment for the screen with a default plugin, because
|
||||||
|
// this allows the corona to either grab one for us that already exists matching
|
||||||
|
// screen, or create a new one. this also works regardless of immutability
|
||||||
|
containment = m_corona->containmentForScreen(screen, m_plugin);
|
||||||
|
|
||||||
|
if (!containment || !containment->activity().isEmpty()) {
|
||||||
|
// possibly a plugin failure, let's go for the default
|
||||||
|
containment = m_corona->containmentForScreen(screen, "org.kde.desktopcontainment");
|
||||||
|
}
|
||||||
|
|
||||||
|
//we don't want to steal contaiments from other activities
|
||||||
|
if (!containment) {
|
||||||
|
// we failed to even get the default; we're screwed.
|
||||||
|
Q_ASSERT(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!containment->activity().isEmpty() &&
|
||||||
|
containment->activity() != m_id) {
|
||||||
|
// we got a containment, but it belongs to some other activity; let's unassign it
|
||||||
|
// from a screen and grab a new one
|
||||||
|
containment->setScreen(-1);
|
||||||
|
containment = m_corona->containmentForScreen(screen, m_plugin);
|
||||||
|
|
||||||
|
if (!containment) {
|
||||||
|
// possibly a plugin failure, let's go for the default
|
||||||
|
containment = m_corona->containmentForScreen(screen, "org.kde.desktopcontainment");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containment) {
|
||||||
|
containment->setScreen(screen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (containment) {
|
||||||
|
insertContainment(containment, screen);
|
||||||
|
m_corona->requestConfigSync();
|
||||||
|
}
|
||||||
|
} else if (containment->screen() != screen) {
|
||||||
|
// ensure the containment _also_ knows which screen we think it is on;
|
||||||
|
// can happen when swapping between activities without stopping them first
|
||||||
|
containment->setScreen(screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
return containment;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::activate()
|
||||||
|
{
|
||||||
|
KActivities::Controller().setCurrentActivity(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::ensureActive()
|
||||||
|
{
|
||||||
|
if (m_containments.isEmpty()) {
|
||||||
|
opened();
|
||||||
|
}
|
||||||
|
|
||||||
|
checkScreens();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::checkScreens()
|
||||||
|
{
|
||||||
|
//ensure there's a containment for every screen & desktop.
|
||||||
|
int numScreens = m_corona->numScreens();
|
||||||
|
|
||||||
|
for (int screen = 0; screen < numScreens; ++screen) {
|
||||||
|
containmentForScreen(screen);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::setName(const QString &name)
|
||||||
|
{
|
||||||
|
if (m_name == name) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::setIcon(const QString &icon)
|
||||||
|
{
|
||||||
|
if (m_icon == icon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_icon = icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::save(KConfig &external)
|
||||||
|
{
|
||||||
|
foreach (const QString &group, external.groupList()) {
|
||||||
|
KConfigGroup cg(&external, group);
|
||||||
|
cg.deleteGroup();
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: multi-screen saving/restoring, where each screen can be
|
||||||
|
// independently restored: put each screen's containments into a
|
||||||
|
// different group, e.g. [Screens][0][Containments], [Screens][1][Containments], etc
|
||||||
|
KConfigGroup dest(&external, "Containments");
|
||||||
|
KConfigGroup dummy;
|
||||||
|
foreach (Plasma::Containment *c, m_containments) {
|
||||||
|
c->save(dummy);
|
||||||
|
KConfigGroup group(&dest, QString::number(c->id()));
|
||||||
|
c->config().copyTo(&group);
|
||||||
|
}
|
||||||
|
|
||||||
|
external.sync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::close()
|
||||||
|
{
|
||||||
|
KActivities::Controller().stopActivity(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::closed()
|
||||||
|
{
|
||||||
|
const QString name = "activities/" + m_id;
|
||||||
|
KConfig external(name, KConfig::SimpleConfig, QStandardPaths::GenericDataLocation);
|
||||||
|
|
||||||
|
//passing an empty string for the group name turns a kconfig into a kconfiggroup
|
||||||
|
KConfigGroup group = external.group(QString());
|
||||||
|
m_corona->exportLayout(group, m_containments.values());
|
||||||
|
|
||||||
|
//hrm, shouldn't the containments' deleted signals have done this for us?
|
||||||
|
if (!m_containments.isEmpty()) {
|
||||||
|
qDebug() << "isn't close supposed to *remove* containments??";
|
||||||
|
m_containments.clear();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::replaceContainment(Plasma::Containment* containment)
|
||||||
|
{
|
||||||
|
insertContainment(containment, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::insertContainment(Plasma::Containment* cont, bool force)
|
||||||
|
{
|
||||||
|
int screen = cont->lastScreen();
|
||||||
|
|
||||||
|
qDebug() << screen;
|
||||||
|
if (screen == -1) {
|
||||||
|
//the migration can't set lastScreen, so maybe we need to assign the containment here
|
||||||
|
qDebug() << "found a lost one";
|
||||||
|
screen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!force && m_containments.contains(screen)) {
|
||||||
|
//this almost certainly means someone has been meddling where they shouldn't
|
||||||
|
//but we should protect them from harm anyways
|
||||||
|
qDebug() << "@!@!@!@!@!@@@@rejecting containment!!!";
|
||||||
|
cont->setActivity(QString());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
insertContainment(cont, screen);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::insertContainment(Plasma::Containment* containment, int screen)
|
||||||
|
{
|
||||||
|
//ensure it's hooked up
|
||||||
|
containment->setActivity(m_id);
|
||||||
|
|
||||||
|
m_containments.insert(screen, containment);
|
||||||
|
connect(containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed(QObject*)));
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::containmentDestroyed(QObject *object)
|
||||||
|
{
|
||||||
|
//safe here because we are not accessing it
|
||||||
|
Plasma::Containment *deletedCont = static_cast<Plasma::Containment *>(object);
|
||||||
|
|
||||||
|
QHash<int, Plasma::Containment*>::iterator i;
|
||||||
|
for (i = m_containments.begin(); i != m_containments.end(); ++i) {
|
||||||
|
Plasma::Containment *cont = i.value();
|
||||||
|
if (cont == deletedCont) {
|
||||||
|
m_containments.remove(i.key());
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::open()
|
||||||
|
{
|
||||||
|
KActivities::Controller().startActivity(m_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::opened()
|
||||||
|
{
|
||||||
|
if (!m_containments.isEmpty()) {
|
||||||
|
qDebug() << "already open!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const QString fileName = QStandardPaths::writableLocation(QStandardPaths::GenericDataLocation) + QString("/activities/" + m_id);
|
||||||
|
qDebug() << "&&&&&&&&&&&&&&&" << fileName;
|
||||||
|
if (QFile::exists(fileName)) {
|
||||||
|
{
|
||||||
|
KConfig external(fileName, KConfig::SimpleConfig);
|
||||||
|
|
||||||
|
foreach (Plasma::Containment *newContainment, m_corona->importLayout(external.group(QByteArray()))) {
|
||||||
|
insertContainment(newContainment);
|
||||||
|
//ensure it's hooked up (if something odd happened we don't want orphan containments)
|
||||||
|
newContainment->setActivity(m_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QFile::remove(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (m_containments.isEmpty()) {
|
||||||
|
//TODO check if we need more for screens/desktops
|
||||||
|
qDebug() << "open failed (bad file?). creating new containment";
|
||||||
|
checkScreens();
|
||||||
|
}
|
||||||
|
|
||||||
|
m_corona->requireConfigSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
void Activity::setDefaultPlugin(const QString &plugin)
|
||||||
|
{
|
||||||
|
m_plugin = plugin;
|
||||||
|
//FIXME save&restore this setting
|
||||||
|
}
|
||||||
|
|
||||||
|
const KActivities::Info * Activity::info() const
|
||||||
|
{
|
||||||
|
return m_info;
|
||||||
|
}
|
||||||
|
|
||||||
|
#include "activity.moc"
|
||||||
|
|
||||||
|
// vim: sw=4 sts=4 et tw=100
|
170
src/shell/activity.h
Normal file
170
src/shell/activity.h
Normal file
@ -0,0 +1,170 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Chani Armitage <chani@kde.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as
|
||||||
|
* published by the Free Software Foundation; either version 2,
|
||||||
|
* 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 ACTIVITY_H
|
||||||
|
#define ACTIVITY_H
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
#include <QHash>
|
||||||
|
|
||||||
|
#include <kactivities/info.h>
|
||||||
|
|
||||||
|
class QSize;
|
||||||
|
class QString;
|
||||||
|
class QPixmap;
|
||||||
|
class KConfig;
|
||||||
|
|
||||||
|
namespace KActivities
|
||||||
|
{
|
||||||
|
class Consumer;
|
||||||
|
} // namespace KActivities
|
||||||
|
|
||||||
|
|
||||||
|
namespace Plasma
|
||||||
|
{
|
||||||
|
class Containment;
|
||||||
|
class Corona;
|
||||||
|
} // namespace Plasma
|
||||||
|
|
||||||
|
class DesktopCorona;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This class represents one activity.
|
||||||
|
* an activity has an ID and a name, from nepomuk.
|
||||||
|
* it also is associated with one or more containments.
|
||||||
|
*
|
||||||
|
* do NOT construct these yourself; use DesktopCorona::activity()
|
||||||
|
*/
|
||||||
|
class Activity : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
Activity(const QString &id, Plasma::Corona *parent = 0);
|
||||||
|
~Activity();
|
||||||
|
|
||||||
|
QString id();
|
||||||
|
QString name();
|
||||||
|
QPixmap pixmap(const QSize &size); //FIXME do we want diff. sizes? updates?
|
||||||
|
|
||||||
|
enum State {
|
||||||
|
Invalid = KActivities::Info::Invalid,
|
||||||
|
Running = KActivities::Info::Running,
|
||||||
|
Starting = KActivities::Info::Starting,
|
||||||
|
Stopped = KActivities::Info::Stopped,
|
||||||
|
Stopping = KActivities::Info::Stopping,
|
||||||
|
PreCreation = 32
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* whether this is the currently active activity
|
||||||
|
*/
|
||||||
|
bool isCurrent();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* state of the activity
|
||||||
|
*/
|
||||||
|
KActivities::Info::State state();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save (copy) the activity out to an @p external config
|
||||||
|
*/
|
||||||
|
void save(KConfig &external);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return the containment that belongs on @p screen and @p desktop
|
||||||
|
* or null if none exists
|
||||||
|
*/
|
||||||
|
Plasma::Containment* containmentForScreen(int screen);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make this activity's containments the active ones, loading them if necessary
|
||||||
|
*/
|
||||||
|
void ensureActive();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* set the plugin to use when creating new containments
|
||||||
|
*/
|
||||||
|
void setDefaultPlugin(const QString &plugin);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns the info object for this activity
|
||||||
|
*/
|
||||||
|
const KActivities::Info * info() const;
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void infoChanged();
|
||||||
|
void stateChanged();
|
||||||
|
void currentStatusChanged();
|
||||||
|
|
||||||
|
public Q_SLOTS:
|
||||||
|
void setName(const QString &name);
|
||||||
|
void setIcon(const QString &icon);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* delete the activity forever
|
||||||
|
*/
|
||||||
|
void remove();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* make this activity the current activity
|
||||||
|
*/
|
||||||
|
void activate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* save and remove all our containments
|
||||||
|
*/
|
||||||
|
void close();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* load the saved containment(s) for this activity
|
||||||
|
*/
|
||||||
|
void open();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* forcibly insert a containment, replacing the one on its screen/desktop
|
||||||
|
*/
|
||||||
|
void replaceContainment(Plasma::Containment* containment);
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void containmentDestroyed(QObject *object);
|
||||||
|
void activityChanged();
|
||||||
|
void activityStateChanged(KActivities::Info::State);
|
||||||
|
void checkIfCurrent();
|
||||||
|
|
||||||
|
void removed();
|
||||||
|
void opened();
|
||||||
|
void closed();
|
||||||
|
|
||||||
|
private:
|
||||||
|
void insertContainment(Plasma::Containment* cont, bool force=false);
|
||||||
|
void insertContainment(Plasma::Containment* containment, int screen);
|
||||||
|
void checkScreens();
|
||||||
|
|
||||||
|
QString m_id;
|
||||||
|
QString m_name;
|
||||||
|
QString m_icon;
|
||||||
|
QString m_plugin;
|
||||||
|
QHash<int, Plasma::Containment*> m_containments;
|
||||||
|
KActivities::Info *m_info;
|
||||||
|
KActivities::Consumer *m_activityConsumer;
|
||||||
|
Plasma::Corona *m_corona;
|
||||||
|
bool m_current;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif
|
302
src/shell/kidenticongenerator.cpp
Normal file
302
src/shell/kidenticongenerator.cpp
Normal file
@ -0,0 +1,302 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Ivan Cukic <ivan.cukic(at)kde.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library/Lesser General Public License
|
||||||
|
* version 2, or (at your option) any later version, 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/Lesser 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 "kidenticongenerator.h"
|
||||||
|
|
||||||
|
#include <QHash>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QDebug>
|
||||||
|
#include <QCryptographicHash>
|
||||||
|
|
||||||
|
#include <kiconeffect.h>
|
||||||
|
|
||||||
|
#include <Plasma/Svg>
|
||||||
|
#include <Plasma/Theme>
|
||||||
|
|
||||||
|
#define VALUE_LIMIT_UP 192
|
||||||
|
#define VALUE_LIMIT_DOWN 64
|
||||||
|
|
||||||
|
class KIdenticonGenerator::Private {
|
||||||
|
public:
|
||||||
|
QPixmap generatePattern(int size, quint32 hash, QIcon::Mode mode);
|
||||||
|
|
||||||
|
QString elementName(const QString & element, QIcon::Mode mode);
|
||||||
|
QColor colorForHash(quint32 hash) const;
|
||||||
|
quint32 hash(const QString & data);
|
||||||
|
|
||||||
|
static KIdenticonGenerator * instance;
|
||||||
|
|
||||||
|
Plasma::Theme *theme;
|
||||||
|
Plasma::Svg shapes;
|
||||||
|
Plasma::Svg svg;
|
||||||
|
};
|
||||||
|
|
||||||
|
QPixmap KIdenticonGenerator::Private::generatePattern(int size, quint32 hash, QIcon::Mode mode)
|
||||||
|
{
|
||||||
|
// We are dividing the pixmap into 9 blocks - 3 x 3
|
||||||
|
int blockSize = size / 3;
|
||||||
|
|
||||||
|
// pulling parts of the hash
|
||||||
|
quint32 tmp = hash;
|
||||||
|
|
||||||
|
quint8 block[4];
|
||||||
|
block[0] = tmp & 31; tmp >>= 5;
|
||||||
|
block[1] = tmp & 31; tmp >>= 5;
|
||||||
|
block[2] = tmp & 31; tmp >>= 5;
|
||||||
|
|
||||||
|
// Painting alpha channel
|
||||||
|
QPixmap pixmapAlpha(size, size);
|
||||||
|
pixmapAlpha.fill(Qt::black);
|
||||||
|
|
||||||
|
QPainter painterAlpha(& pixmapAlpha);
|
||||||
|
|
||||||
|
QRectF rect(0, 0, blockSize + 0.5, blockSize + 0.5);
|
||||||
|
|
||||||
|
for (int i = 0; i < 4; i++) {
|
||||||
|
// Painting the corner item
|
||||||
|
rect.moveTopLeft(QPoint(0, 0));
|
||||||
|
shapes.paint(& painterAlpha, rect, "shape" + QString::number(block[0] + 1));
|
||||||
|
|
||||||
|
// Painting side item
|
||||||
|
rect.moveTopLeft(QPoint(blockSize, 0));
|
||||||
|
shapes.paint(& painterAlpha, rect, "shape" + QString::number(block[1] + 1));
|
||||||
|
|
||||||
|
// Rotating the canvas to paint other edges
|
||||||
|
painterAlpha.translate(size, 0);
|
||||||
|
painterAlpha.rotate(90);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Painting center item
|
||||||
|
rect.moveTopLeft(QPoint(blockSize, blockSize));
|
||||||
|
shapes.paint(& painterAlpha, rect, "shape" + QString::number(block[2] + 1));
|
||||||
|
|
||||||
|
painterAlpha.end();
|
||||||
|
|
||||||
|
// Painting final pixmap
|
||||||
|
QPixmap pixmapResult(size, size);
|
||||||
|
|
||||||
|
|
||||||
|
pixmapResult.fill(Qt::transparent);
|
||||||
|
|
||||||
|
// QRadialGradient gradient(50, 50, 100);
|
||||||
|
// gradient.setColorAt(0, color.lighter());
|
||||||
|
// gradient.setColorAt(1, color.darker());
|
||||||
|
|
||||||
|
QPainter resultPainter(& pixmapResult);
|
||||||
|
// resultPainter.fillRect(0, 0, size, size, gradient);
|
||||||
|
svg.paint(& resultPainter, QRect(0, 0, size, size), elementName("content", mode));
|
||||||
|
|
||||||
|
resultPainter.end();
|
||||||
|
|
||||||
|
pixmapResult.setAlphaChannel(pixmapAlpha);
|
||||||
|
|
||||||
|
// QImage itmp = pixmapResult.toImage();
|
||||||
|
// KIconEffect::colorize(itmp, colorForHash(hash), 1.0);
|
||||||
|
// pixmapResult = pixmapResult.fromImage(itmp);
|
||||||
|
|
||||||
|
return pixmapResult;
|
||||||
|
}
|
||||||
|
|
||||||
|
QColor KIdenticonGenerator::Private::colorForHash(quint32 hash) const
|
||||||
|
{
|
||||||
|
// Color is chosen according to hash
|
||||||
|
QColor color;
|
||||||
|
|
||||||
|
// Getting the value from color svg, but we must restrain it to
|
||||||
|
// values in range from VALUE_LIMIT_DOWN to VALUE_LIMIT_UP
|
||||||
|
|
||||||
|
int value = theme->color(Plasma::Theme::TextColor).value();
|
||||||
|
if (value < VALUE_LIMIT_DOWN) {
|
||||||
|
value = VALUE_LIMIT_DOWN;
|
||||||
|
} else if (value > VALUE_LIMIT_UP) {
|
||||||
|
value = VALUE_LIMIT_UP;
|
||||||
|
}
|
||||||
|
|
||||||
|
color.setHsv(
|
||||||
|
hash % 359 + 1, // hue depending on hash
|
||||||
|
250, // high saturation level
|
||||||
|
value
|
||||||
|
);
|
||||||
|
|
||||||
|
return color;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QString KIdenticonGenerator::Private::elementName(const QString & element, QIcon::Mode mode)
|
||||||
|
{
|
||||||
|
QString prefix;
|
||||||
|
|
||||||
|
switch (mode) {
|
||||||
|
case QIcon::Normal:
|
||||||
|
prefix = "normal-";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QIcon::Disabled:
|
||||||
|
prefix = "disabled-";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QIcon::Selected:
|
||||||
|
prefix = "selected-";
|
||||||
|
break;
|
||||||
|
|
||||||
|
case QIcon::Active:
|
||||||
|
prefix = "active-";
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (svg.hasElement(prefix + element)) {
|
||||||
|
return prefix + element;
|
||||||
|
} else {
|
||||||
|
return element;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
quint32 KIdenticonGenerator::Private::hash(const QString & data)
|
||||||
|
{
|
||||||
|
// qHash function doesn't give random enough results
|
||||||
|
// and gives similar hashes for similar strings.
|
||||||
|
|
||||||
|
QByteArray bytes = QCryptographicHash::hash(data.toUtf8(), QCryptographicHash::Md5);
|
||||||
|
|
||||||
|
// Generating hash
|
||||||
|
quint32 hash = 0;
|
||||||
|
|
||||||
|
char * hashBytes = (char *) & hash;
|
||||||
|
for (int i = 0; i < bytes.size(); i++) {
|
||||||
|
// Using XOR for mixing the bytes because
|
||||||
|
// it is fast and cryptographically safe
|
||||||
|
// (more than enough for our use-case)
|
||||||
|
hashBytes[i % 4] ^= bytes.at(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
return hash;
|
||||||
|
}
|
||||||
|
|
||||||
|
KIdenticonGenerator * KIdenticonGenerator::Private::instance = NULL;
|
||||||
|
|
||||||
|
KIdenticonGenerator * KIdenticonGenerator::self()
|
||||||
|
{
|
||||||
|
if (!Private::instance) {
|
||||||
|
Private::instance = new KIdenticonGenerator();
|
||||||
|
}
|
||||||
|
|
||||||
|
return Private::instance;
|
||||||
|
}
|
||||||
|
|
||||||
|
KIdenticonGenerator::KIdenticonGenerator()
|
||||||
|
: d(new Private())
|
||||||
|
{
|
||||||
|
d->theme = new Plasma::Theme(0);
|
||||||
|
// loading SVGs
|
||||||
|
d->shapes.setImagePath("widgets/identiconshapes");
|
||||||
|
d->shapes.setContainsMultipleImages(true);
|
||||||
|
|
||||||
|
d->svg.setImagePath("widgets/identiconsvg");
|
||||||
|
d->svg.setContainsMultipleImages(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
KIdenticonGenerator::~KIdenticonGenerator()
|
||||||
|
{
|
||||||
|
delete d->theme;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define generateIconModes( PARAM ) \
|
||||||
|
for (int omode = QIcon::Normal; omode <= QIcon::Selected; omode++) { \
|
||||||
|
QIcon::Mode mode = (QIcon::Mode)omode; \
|
||||||
|
result.addPixmap(generatePixmap(size, PARAM, mode), mode); \
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon KIdenticonGenerator::generate(int size, quint32 hash)
|
||||||
|
{
|
||||||
|
QIcon result;
|
||||||
|
generateIconModes(hash);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon KIdenticonGenerator::generate(int size, const QString & data)
|
||||||
|
{
|
||||||
|
QIcon result;
|
||||||
|
generateIconModes(data);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QIcon KIdenticonGenerator::generate(int size, const QIcon & icon)
|
||||||
|
{
|
||||||
|
QIcon result;
|
||||||
|
generateIconModes(icon);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap KIdenticonGenerator::generatePixmap(int size, QString id, QIcon::Mode mode)
|
||||||
|
{
|
||||||
|
return generatePixmap(size, d->hash(id), mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap KIdenticonGenerator::generatePixmap(int size, quint32 hash, QIcon::Mode mode)
|
||||||
|
{
|
||||||
|
QPixmap pixmap(size, size);
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
// Painting background and the pattern
|
||||||
|
{
|
||||||
|
QPainter painter(& pixmap);
|
||||||
|
d->svg.paint(& painter, QRect(0, 0, size, size), d->elementName("background", mode));
|
||||||
|
painter.drawPixmap(0, 0, d->generatePattern(size, hash, mode));
|
||||||
|
painter.end();
|
||||||
|
}
|
||||||
|
|
||||||
|
// coloring the painted image
|
||||||
|
QImage itmp = pixmap.toImage();
|
||||||
|
KIconEffect::colorize(itmp, d->colorForHash(hash), 1.0);
|
||||||
|
if (mode == QIcon::Disabled) {
|
||||||
|
KIconEffect::toGray(itmp, 0.7);
|
||||||
|
}
|
||||||
|
pixmap = pixmap.fromImage(itmp);
|
||||||
|
|
||||||
|
// Drawing the overlay
|
||||||
|
{
|
||||||
|
QPainter painter(& pixmap);
|
||||||
|
d->svg.paint(& painter, QRect(0, 0, size, size), d->elementName("overlay", mode));
|
||||||
|
}
|
||||||
|
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
QPixmap KIdenticonGenerator::generatePixmap(int size, const QIcon & icon, QIcon::Mode mode)
|
||||||
|
{
|
||||||
|
QPixmap pixmap(size, size);
|
||||||
|
pixmap.fill(Qt::transparent);
|
||||||
|
|
||||||
|
QRect paintRect(0, 0, size, size);
|
||||||
|
|
||||||
|
// Painting background and the pattern
|
||||||
|
QPainter painter(& pixmap);
|
||||||
|
d->svg.paint(& painter, QRect(0, 0, size, size), d->elementName("background", mode));
|
||||||
|
|
||||||
|
icon.paint(& painter, paintRect, Qt::AlignCenter, mode);
|
||||||
|
|
||||||
|
painter.end();
|
||||||
|
|
||||||
|
return pixmap;
|
||||||
|
}
|
||||||
|
|
48
src/shell/kidenticongenerator.h
Normal file
48
src/shell/kidenticongenerator.h
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010 Ivan Cukic <ivan.cukic(at)kde.org>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Library/Lesser General Public License
|
||||||
|
* version 2, or (at your option) any later version, 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/Lesser 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 KIDENTICONGENERATOR_H
|
||||||
|
#define KIDENTICONGENERATOR_H
|
||||||
|
|
||||||
|
#include <QPixmap>
|
||||||
|
#include <QIcon>
|
||||||
|
|
||||||
|
#include <Plasma/Svg>
|
||||||
|
|
||||||
|
class KIdenticonGenerator {
|
||||||
|
public:
|
||||||
|
static KIdenticonGenerator * self();
|
||||||
|
~KIdenticonGenerator();
|
||||||
|
|
||||||
|
QPixmap generatePixmap(int size, QString id, QIcon::Mode mode = QIcon::Normal);
|
||||||
|
QPixmap generatePixmap(int size, quint32 hash, QIcon::Mode mode = QIcon::Normal);
|
||||||
|
QPixmap generatePixmap(int size, const QIcon & icon, QIcon::Mode mode = QIcon::Normal);
|
||||||
|
|
||||||
|
QIcon generate(int size, const QString & data);
|
||||||
|
QIcon generate(int size, quint32 hash);
|
||||||
|
QIcon generate(int size, const QIcon & icon);
|
||||||
|
|
||||||
|
private:
|
||||||
|
KIdenticonGenerator();
|
||||||
|
|
||||||
|
class Private;
|
||||||
|
Private * const d;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // KIDENTICONGENERATOR_H
|
@ -29,16 +29,88 @@ Rectangle {
|
|||||||
|
|
||||||
property Item containment
|
property Item containment
|
||||||
|
|
||||||
onContainmentChanged: {
|
function toggleActivityManager() {
|
||||||
print("New Containment: " + containment)
|
console.log("Activity manger toggled")
|
||||||
//containment.parent = root
|
|
||||||
containment.visible = true
|
|
||||||
containment.anchors.fill = root
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
onContainmentChanged: {
|
||||||
|
print("New Containment: " + containment);
|
||||||
|
print("Old Containment: " + internal.oldContainment);
|
||||||
|
//containment.parent = root;
|
||||||
|
containment.visible = true;
|
||||||
|
|
||||||
|
internal.newContainment = containment;
|
||||||
|
if (internal.oldContainment && internal.oldContainment != containment) {
|
||||||
|
switchAnim.running = true;
|
||||||
|
} else {
|
||||||
|
internal.oldContainment = containment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//some properties that shouldn't be accessible from elsewhere
|
||||||
|
QtObject {
|
||||||
|
id: internal;
|
||||||
|
|
||||||
|
property Item oldContainment;
|
||||||
|
property Item newContainment;
|
||||||
|
}
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: switchAnim
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
containment.anchors.left = undefined;
|
||||||
|
containment.anchors.top = undefined;
|
||||||
|
containment.anchors.right = undefined;
|
||||||
|
containment.anchors.bottom = undefined;
|
||||||
|
|
||||||
|
internal.oldContainment.anchors.left = undefined;
|
||||||
|
internal.oldContainment.anchors.top = undefined;
|
||||||
|
internal.oldContainment.anchors.right = undefined;
|
||||||
|
internal.oldContainment.anchors.bottom = undefined;
|
||||||
|
|
||||||
|
internal.oldContainment.z = 0;
|
||||||
|
internal.oldContainment.x = 0;
|
||||||
|
containment.z = 1;
|
||||||
|
containment.x = root.width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ParallelAnimation {
|
||||||
|
NumberAnimation {
|
||||||
|
target: internal.oldContainment
|
||||||
|
properties: "x"
|
||||||
|
to: -root.width
|
||||||
|
duration: 400
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
NumberAnimation {
|
||||||
|
target: internal.newContainment
|
||||||
|
properties: "x"
|
||||||
|
to: 0
|
||||||
|
duration: 250
|
||||||
|
easing.type: Easing.InOutQuad
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ScriptAction {
|
||||||
|
script: {
|
||||||
|
containment.anchors.left = root.left;
|
||||||
|
containment.anchors.top = root.top;
|
||||||
|
containment.anchors.right = root.right;
|
||||||
|
containment.anchors.bottom = root.bottom;
|
||||||
|
|
||||||
|
internal.oldContainment.visible = false;
|
||||||
|
internal.oldContainment = containment;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
|
//configure the view behavior
|
||||||
desktop.stayBehind = true;
|
desktop.stayBehind = true;
|
||||||
desktop.fillScreen = true;
|
desktop.fillScreen = true;
|
||||||
print("View QML loaded")
|
print("View QML loaded")
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,10 @@
|
|||||||
#include <klocalizedstring.h>
|
#include <klocalizedstring.h>
|
||||||
#include <Plasma/Package>
|
#include <Plasma/Package>
|
||||||
#include <Plasma/PluginLoader>
|
#include <Plasma/PluginLoader>
|
||||||
|
#include <kactivities/controller.h>
|
||||||
|
#include <kactivities/consumer.h>
|
||||||
|
|
||||||
|
#include "activity.h"
|
||||||
#include "desktopview.h"
|
#include "desktopview.h"
|
||||||
#include "panelview.h"
|
#include "panelview.h"
|
||||||
#include "scripting/desktopscriptengine.h"
|
#include "scripting/desktopscriptengine.h"
|
||||||
@ -40,9 +43,12 @@
|
|||||||
|
|
||||||
class ShellCorona::Private {
|
class ShellCorona::Private {
|
||||||
public:
|
public:
|
||||||
Private()
|
Private(ShellCorona *corona)
|
||||||
: desktopWidget(QApplication::desktop()),
|
: q(corona),
|
||||||
widgetExplorer(nullptr)
|
desktopWidget(QApplication::desktop()),
|
||||||
|
widgetExplorer(nullptr),
|
||||||
|
activityController(new KActivities::Controller(q)),
|
||||||
|
activityConsumer(new KActivities::Consumer(q))
|
||||||
{
|
{
|
||||||
appConfigSyncTimer.setSingleShot(true);
|
appConfigSyncTimer.setSingleShot(true);
|
||||||
// constant controlling how long between requesting a configuration sync
|
// constant controlling how long between requesting a configuration sync
|
||||||
@ -50,15 +56,19 @@ public:
|
|||||||
appConfigSyncTimer.setInterval(10000);
|
appConfigSyncTimer.setInterval(10000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ShellCorona *q;
|
||||||
QString shell;
|
QString shell;
|
||||||
QDesktopWidget * desktopWidget;
|
QDesktopWidget * desktopWidget;
|
||||||
QList <DesktopView *> views;
|
QList <DesktopView *> views;
|
||||||
QPointer<WidgetExplorer> widgetExplorer;
|
QPointer<WidgetExplorer> widgetExplorer;
|
||||||
|
KActivities::Controller *activityController;
|
||||||
|
KActivities::Consumer *activityConsumer;
|
||||||
QHash <Plasma::Containment *, PanelView *> panelViews;
|
QHash <Plasma::Containment *, PanelView *> panelViews;
|
||||||
KConfigGroup desktopDefaultsConfig;
|
KConfigGroup desktopDefaultsConfig;
|
||||||
WorkspaceScripting::DesktopScriptEngine * scriptEngine;
|
WorkspaceScripting::DesktopScriptEngine * scriptEngine;
|
||||||
QList<Plasma::Containment *> waitingPanels;
|
QList<Plasma::Containment *> waitingPanels;
|
||||||
QSet<Plasma::Containment *> loadingDesktops;
|
QSet<Plasma::Containment *> loadingDesktops;
|
||||||
|
QHash<QString, Activity*> activities;
|
||||||
|
|
||||||
QTimer appConfigSyncTimer;
|
QTimer appConfigSyncTimer;
|
||||||
};
|
};
|
||||||
@ -70,7 +80,8 @@ WorkspaceScripting::DesktopScriptEngine * ShellCorona::scriptEngine() const
|
|||||||
|
|
||||||
|
|
||||||
ShellCorona::ShellCorona(QObject *parent)
|
ShellCorona::ShellCorona(QObject *parent)
|
||||||
: Plasma::Corona(parent), d(new Private())
|
: Plasma::Corona(parent),
|
||||||
|
d(new Private(this))
|
||||||
{
|
{
|
||||||
d->desktopDefaultsConfig = KConfigGroup(KSharedConfig::openConfig(package().filePath("defaults")), "Desktop");
|
d->desktopDefaultsConfig = KConfigGroup(KSharedConfig::openConfig(package().filePath("defaults")), "Desktop");
|
||||||
|
|
||||||
@ -107,6 +118,23 @@ ShellCorona::ShellCorona(QObject *parent)
|
|||||||
dashboardAction->setShortcut(QKeySequence("ctrl+f12"));
|
dashboardAction->setShortcut(QKeySequence("ctrl+f12"));
|
||||||
dashboardAction->setShortcutContext(Qt::ApplicationShortcut);
|
dashboardAction->setShortcutContext(Qt::ApplicationShortcut);
|
||||||
|
|
||||||
|
//Activity stuff
|
||||||
|
|
||||||
|
QAction *activityAction = actions()->addAction("manage activities");
|
||||||
|
connect(activityAction, &QAction::triggered,
|
||||||
|
this, &ShellCorona::toggleActivityManager);
|
||||||
|
activityAction->setText(i18n("Activities..."));
|
||||||
|
activityAction->setIcon(QIcon::fromTheme("preferences-activities"));
|
||||||
|
activityAction->setData(Plasma::Types::ConfigureAction);
|
||||||
|
activityAction->setShortcut(QKeySequence("alt+d, alt+a"));
|
||||||
|
activityAction->setShortcutContext(Qt::ApplicationShortcut);
|
||||||
|
|
||||||
|
connect(this, SIGNAL(immutabilityChanged(Plasma::ImmutabilityType)),
|
||||||
|
this, SLOT(updateImmutability(Plasma::ImmutabilityType)));
|
||||||
|
|
||||||
|
connect(d->activityConsumer, SIGNAL(currentActivityChanged(QString)), this, SLOT(currentActivityChanged(QString)));
|
||||||
|
connect(d->activityConsumer, SIGNAL(activityAdded(QString)), this, SLOT(activityAdded(QString)));
|
||||||
|
connect(d->activityConsumer, SIGNAL(activityRemoved(QString)), this, SLOT(activityRemoved(QString)));
|
||||||
}
|
}
|
||||||
|
|
||||||
ShellCorona::~ShellCorona()
|
ShellCorona::~ShellCorona()
|
||||||
@ -146,6 +174,7 @@ void ShellCorona::load()
|
|||||||
}
|
}
|
||||||
|
|
||||||
processUpdateScripts();
|
processUpdateScripts();
|
||||||
|
checkActivities();
|
||||||
checkScreens();
|
checkScreens();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -186,6 +215,20 @@ void ShellCorona::processUpdateScripts()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Activity* ShellCorona::activity(const QString &id)
|
||||||
|
{
|
||||||
|
if (!d->activities.contains(id)) {
|
||||||
|
//the add signal comes late sometimes
|
||||||
|
activityAdded(id);
|
||||||
|
}
|
||||||
|
return d->activities.value(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
KActivities::Controller *ShellCorona::activityController()
|
||||||
|
{
|
||||||
|
return d->activityController;
|
||||||
|
}
|
||||||
|
|
||||||
void ShellCorona::checkScreens(bool signalWhenExists)
|
void ShellCorona::checkScreens(bool signalWhenExists)
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -213,9 +256,9 @@ void ShellCorona::checkScreen(int screen, bool signalWhenExists)
|
|||||||
//buggy (sometimes the containment thinks it's already on the screen, so no view is created)
|
//buggy (sometimes the containment thinks it's already on the screen, so no view is created)
|
||||||
|
|
||||||
//TODO: restore activities
|
//TODO: restore activities
|
||||||
//Activity *currentActivity = activity(d->activityController->currentActivity());
|
Activity *currentActivity = activity(d->activityController->currentActivity());
|
||||||
//ensure the desktop(s) have a containment and view
|
//ensure the desktop(s) have a containment and view
|
||||||
checkDesktop(/*currentActivity,*/ signalWhenExists, screen);
|
checkDesktop(currentActivity, signalWhenExists, screen);
|
||||||
|
|
||||||
|
|
||||||
//ensure the panels get views too
|
//ensure the panels get views too
|
||||||
@ -234,9 +277,9 @@ void ShellCorona::checkScreen(int screen, bool signalWhenExists)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void ShellCorona::checkDesktop(/*Activity *activity,*/ bool signalWhenExists, int screen)
|
void ShellCorona::checkDesktop(Activity *activity, bool signalWhenExists, int screen)
|
||||||
{
|
{
|
||||||
Plasma::Containment *c = /*activity->*/containmentForScreen(screen);
|
Plasma::Containment *c = activity->containmentForScreen(screen);
|
||||||
|
|
||||||
//TODO: remove following when activities are restored
|
//TODO: remove following when activities are restored
|
||||||
if (!c) {
|
if (!c) {
|
||||||
@ -422,6 +465,18 @@ void ShellCorona::showWidgetExplorer()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShellCorona::toggleActivityManager()
|
||||||
|
{
|
||||||
|
QPoint cursorPos = QCursor::pos();
|
||||||
|
foreach (DesktopView *view, d->views) {
|
||||||
|
if (view->screen()->geometry().contains(cursorPos)) {
|
||||||
|
//The view QML has to provide something to display the activity explorer
|
||||||
|
view->rootObject()->metaObject()->invokeMethod(view->rootObject(), "toggleActivityManager");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ShellCorona::syncAppConfig()
|
void ShellCorona::syncAppConfig()
|
||||||
{
|
{
|
||||||
qDebug() << "Syncing plasma-shellrc config";
|
qDebug() << "Syncing plasma-shellrc config";
|
||||||
@ -442,6 +497,131 @@ void ShellCorona::setDashboardShown(bool show)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ShellCorona::checkActivities()
|
||||||
|
{
|
||||||
|
qDebug() << "containments to start with" << containments().count();
|
||||||
|
|
||||||
|
KActivities::Consumer::ServiceStatus status = d->activityController->serviceStatus();
|
||||||
|
//qDebug() << "$%$%$#%$%$%Status:" << status;
|
||||||
|
if (status == KActivities::Consumer::NotRunning) {
|
||||||
|
//panic and give up - better than causing a mess
|
||||||
|
qDebug() << "No ActivityManager? Help, I've fallen and I can't get up!";
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList existingActivities = d->activityConsumer->activities();
|
||||||
|
foreach (const QString &id, existingActivities) {
|
||||||
|
activityAdded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList newActivities;
|
||||||
|
QString newCurrentActivity;
|
||||||
|
//migration checks:
|
||||||
|
//-containments with an invalid id are deleted.
|
||||||
|
//-containments that claim they were on a screen are kept together, and are preferred if we
|
||||||
|
//need to initialize the current activity.
|
||||||
|
//-containments that don't know where they were or who they were with just get made into their
|
||||||
|
//own activity.
|
||||||
|
foreach (Plasma::Containment *cont, containments()) {
|
||||||
|
if ((cont->containmentType() == Plasma::Types::DesktopContainment ||
|
||||||
|
cont->containmentType() == Plasma::Types::CustomContainment)) {
|
||||||
|
const QString oldId = cont->activity();
|
||||||
|
if (!oldId.isEmpty()) {
|
||||||
|
if (existingActivities.contains(oldId)) {
|
||||||
|
continue; //it's already claimed
|
||||||
|
}
|
||||||
|
qDebug() << "invalid id" << oldId;
|
||||||
|
//byebye
|
||||||
|
cont->destroy();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cont->screen() > -1 && !newCurrentActivity.isEmpty()) {
|
||||||
|
//it belongs on the new current activity
|
||||||
|
cont->setActivity(newCurrentActivity);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*//discourage blank names
|
||||||
|
if (context->currentActivity().isEmpty()) {
|
||||||
|
context->setCurrentActivity(i18nc("Default name for a new activity", "New Activity"));
|
||||||
|
}*/
|
||||||
|
|
||||||
|
//create a new activity for the containment
|
||||||
|
const QString id = d->activityController->addActivity(cont->activity());
|
||||||
|
cont->setActivity(id);
|
||||||
|
newActivities << id;
|
||||||
|
if (cont->screen() > -1) {
|
||||||
|
newCurrentActivity = id;
|
||||||
|
}
|
||||||
|
qDebug() << "migrated" << cont->id() << cont->activity();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
qDebug() << "migrated?" << !newActivities.isEmpty() << containments().count();
|
||||||
|
if (!newActivities.isEmpty()) {
|
||||||
|
requestConfigSync();
|
||||||
|
}
|
||||||
|
|
||||||
|
//init the newbies
|
||||||
|
foreach (const QString &id, newActivities) {
|
||||||
|
activityAdded(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
//ensure the current activity is initialized
|
||||||
|
if (d->activityController->currentActivity().isEmpty()) {
|
||||||
|
qDebug() << "guessing at current activity";
|
||||||
|
if (existingActivities.isEmpty()) {
|
||||||
|
if (newCurrentActivity.isEmpty()) {
|
||||||
|
if (newActivities.isEmpty()) {
|
||||||
|
qDebug() << "no activities!?! Bad activitymanager, no cookie!";
|
||||||
|
QString id = d->activityController->addActivity(i18nc("Default name for a new activity", "New Activity"));
|
||||||
|
activityAdded(id);
|
||||||
|
d->activityController->setCurrentActivity(id);
|
||||||
|
qDebug() << "created emergency activity" << id;
|
||||||
|
} else {
|
||||||
|
d->activityController->setCurrentActivity(newActivities.first());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
d->activityController->setCurrentActivity(newCurrentActivity);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
d->activityController->setCurrentActivity(existingActivities.first());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShellCorona::currentActivityChanged(const QString &newActivity)
|
||||||
|
{
|
||||||
|
Activity *act = activity(newActivity);
|
||||||
|
qDebug() << "Activity changed:" << newActivity << act;
|
||||||
|
|
||||||
|
if (act) {
|
||||||
|
act->ensureActive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShellCorona::activityAdded(const QString &id)
|
||||||
|
{
|
||||||
|
//TODO more sanity checks
|
||||||
|
if (d->activities.contains(id)) {
|
||||||
|
qDebug() << "you're late." << id;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Activity *a = new Activity(id, this);
|
||||||
|
if (a->isCurrent()) {
|
||||||
|
a->ensureActive();
|
||||||
|
}
|
||||||
|
d->activities.insert(id, a);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ShellCorona::activityRemoved(const QString &id)
|
||||||
|
{
|
||||||
|
Activity *a = d->activities.take(id);
|
||||||
|
a->deleteLater();
|
||||||
|
}
|
||||||
|
|
||||||
void ShellCorona::printScriptError(const QString &error)
|
void ShellCorona::printScriptError(const QString &error)
|
||||||
{
|
{
|
||||||
qWarning() << error;
|
qWarning() << error;
|
||||||
|
@ -28,11 +28,16 @@ namespace Plasma
|
|||||||
class Applet;
|
class Applet;
|
||||||
} // namespace Plasma
|
} // namespace Plasma
|
||||||
|
|
||||||
|
class Activity;
|
||||||
class PanelView;
|
class PanelView;
|
||||||
namespace WorkspaceScripting {
|
namespace WorkspaceScripting {
|
||||||
class DesktopScriptEngine;
|
class DesktopScriptEngine;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace KActivities {
|
||||||
|
class Controller;
|
||||||
|
}
|
||||||
|
|
||||||
class ShellCorona : public Plasma::Corona
|
class ShellCorona : public Plasma::Corona
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
@ -58,7 +63,7 @@ public:
|
|||||||
*/
|
*/
|
||||||
void checkScreen(int screen, bool signalWhenExists = false);
|
void checkScreen(int screen, bool signalWhenExists = false);
|
||||||
|
|
||||||
void checkDesktop(/*Activity *activity,*/ bool signalWhenExists, int screen);
|
void checkDesktop(Activity *activity, bool signalWhenExists, int screen);
|
||||||
|
|
||||||
int numScreens() const;
|
int numScreens() const;
|
||||||
QRect screenGeometry(int id) const;
|
QRect screenGeometry(int id) const;
|
||||||
@ -67,6 +72,10 @@ public:
|
|||||||
|
|
||||||
PanelView *panelView(Plasma::Containment *containment) const;
|
PanelView *panelView(Plasma::Containment *containment) const;
|
||||||
|
|
||||||
|
Activity* activity(const QString &id);
|
||||||
|
|
||||||
|
KActivities::Controller *activityController();
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
/**
|
/**
|
||||||
* Request saving applicationConfig on disk, it's event compressed, not immediate
|
* Request saving applicationConfig on disk, it's event compressed, not immediate
|
||||||
@ -114,13 +123,17 @@ protected Q_SLOTS:
|
|||||||
*/
|
*/
|
||||||
void processUpdateScripts();
|
void processUpdateScripts();
|
||||||
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
private Q_SLOTS:
|
||||||
void checkLoadingDesktopsComplete();
|
void checkLoadingDesktopsComplete();
|
||||||
void handleContainmentAdded(Plasma::Containment *c);
|
void handleContainmentAdded(Plasma::Containment *c);
|
||||||
void showWidgetExplorer();
|
void showWidgetExplorer();
|
||||||
|
void toggleActivityManager();
|
||||||
void syncAppConfig();
|
void syncAppConfig();
|
||||||
void setDashboardShown(bool show);
|
void setDashboardShown(bool show);
|
||||||
|
void checkActivities();
|
||||||
|
void currentActivityChanged(const QString &newActivity);
|
||||||
|
void activityAdded(const QString &id);
|
||||||
|
void activityRemoved(const QString &id);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
class Private;
|
class Private;
|
||||||
|
Loading…
Reference in New Issue
Block a user