- add Contaiment to the build
- put applets in the center of the screen not the top left (i really wish people wouldn't commit obvious regressions like that? the code was ifdef 0'd out!) - create a Containment per-screen (in the xinerama sense) - new loading/saving code; not overly comfortable with it yet but it works and maintains the single-pass semantics as well as the option for us to delay calling init() if we decide to do so in the future - misc fixes here and there svn path=/trunk/KDE/kdebase/workspace/libs/plasma/; revision=714175
This commit is contained in:
parent
2c63daad12
commit
f0cb7e662c
@ -18,6 +18,7 @@ set(plasma_LIB_SRCS
|
||||
animator.cpp
|
||||
applet.cpp
|
||||
configxml.cpp
|
||||
containment.cpp
|
||||
corona.cpp
|
||||
datacontainer.cpp
|
||||
dataengine.cpp
|
||||
@ -52,6 +53,10 @@ set(plasma_LIB_SRCS
|
||||
widgets/signalplotter.cpp
|
||||
)
|
||||
|
||||
set(krunner_xml ${KDEBASE_WORKSPACE_SOURCE_DIR}/krunner/org.kde.krunner.Interface.xml)
|
||||
QT4_ADD_DBUS_INTERFACE(plasma_LIB_SRCS ${krunner_xml} krunner_interface)
|
||||
|
||||
|
||||
if(QT_QTOPENGL_FOUND AND OPENGL_FOUND)
|
||||
MESSAGE(STATUS "Adding support for OpenGL applets to libplasma")
|
||||
set(plasma_LIB_SRCS
|
||||
@ -82,6 +87,7 @@ set(plasma_LIB_INCLUDES
|
||||
animator.h
|
||||
applet.h
|
||||
configxml.h
|
||||
containment.h
|
||||
corona.h
|
||||
datacontainer.h
|
||||
dataengine.h
|
||||
|
276
corona.cpp
276
corona.cpp
@ -34,7 +34,7 @@
|
||||
#include <KMimeType>
|
||||
#include <KWindowSystem>
|
||||
|
||||
#include "applet.h"
|
||||
#include "containment.h"
|
||||
#include "dataengine.h"
|
||||
#include "karambamanager.h"
|
||||
#include "phase.h"
|
||||
@ -52,31 +52,24 @@ class Corona::Private
|
||||
public:
|
||||
Private()
|
||||
: immutable(false),
|
||||
formFactor(Planar),
|
||||
location(Floating),
|
||||
layout(new FreeLayout),
|
||||
mimetype("text/x-plasmoidservicename")
|
||||
{
|
||||
}
|
||||
|
||||
~Private()
|
||||
{
|
||||
qDeleteAll(applets);
|
||||
delete layout;
|
||||
}
|
||||
|
||||
bool immutable;
|
||||
Applet::List applets;
|
||||
FormFactor formFactor;
|
||||
Location location;
|
||||
Layout* layout;
|
||||
QString mimetype;
|
||||
QList<Containment*> containments;
|
||||
};
|
||||
|
||||
Corona::Corona(QObject *parent)
|
||||
: QGraphicsScene(parent),
|
||||
d(new Private)
|
||||
{
|
||||
//d->init(this);
|
||||
//setViewport(new QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel)));
|
||||
}
|
||||
|
||||
@ -84,6 +77,7 @@ Corona::Corona(const QRectF & sceneRect, QObject * parent )
|
||||
: QGraphicsScene(sceneRect, parent),
|
||||
d(new Private)
|
||||
{
|
||||
//d->init(this);
|
||||
//setViewport(new QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel)));
|
||||
}
|
||||
|
||||
@ -91,6 +85,7 @@ Corona::Corona(qreal x, qreal y, qreal width, qreal height, QObject * parent)
|
||||
: QGraphicsScene(x, y, width, height, parent),
|
||||
d(new Private)
|
||||
{
|
||||
//d->init(this);
|
||||
//setViewport(new QGLWidget(QGLFormat(QGL::StencilBuffer | QGL::AlphaChannel)));
|
||||
}
|
||||
|
||||
@ -99,62 +94,6 @@ Corona::~Corona()
|
||||
delete d;
|
||||
}
|
||||
|
||||
Location Corona::location() const
|
||||
{
|
||||
return d->location;
|
||||
}
|
||||
|
||||
void Corona::setLocation(Location location)
|
||||
{
|
||||
if (d->location == location) {
|
||||
return;
|
||||
}
|
||||
|
||||
d->location = location;
|
||||
|
||||
foreach (Applet* applet, d->applets) {
|
||||
applet->updateConstraints();
|
||||
}
|
||||
}
|
||||
|
||||
FormFactor Corona::formFactor() const
|
||||
{
|
||||
return d->formFactor;
|
||||
}
|
||||
|
||||
void Corona::setFormFactor(FormFactor formFactor)
|
||||
{
|
||||
if (d->formFactor == formFactor) {
|
||||
return;
|
||||
}
|
||||
|
||||
//kDebug() << "switching FF to " << formFactor;
|
||||
d->formFactor = formFactor;
|
||||
delete d->layout;
|
||||
d->layout = 0;
|
||||
|
||||
switch (d->formFactor) {
|
||||
case Planar:
|
||||
d->layout = new FreeLayout;
|
||||
break;
|
||||
case Horizontal:
|
||||
d->layout = new BoxLayout(BoxLayout::LeftToRight);
|
||||
break;
|
||||
case Vertical:
|
||||
d->layout = new BoxLayout(BoxLayout::TopToBottom);
|
||||
break;
|
||||
case MediaCenter:
|
||||
break;
|
||||
default:
|
||||
kDebug() << "This can't be happening!";
|
||||
break;
|
||||
}
|
||||
|
||||
foreach (Applet* applet, d->applets) {
|
||||
applet->updateConstraints();
|
||||
}
|
||||
}
|
||||
|
||||
QRectF Corona::maxSizeHint() const
|
||||
{
|
||||
//FIXME: this is a bit of a naive implementation, do you think? =)
|
||||
@ -174,16 +113,21 @@ QString Corona::appletMimeType()
|
||||
|
||||
void Corona::saveApplets(const QString &config) const
|
||||
{
|
||||
KConfig appletConfig(config);
|
||||
foreach (const QString& group, appletConfig.groupList()) {
|
||||
appletConfig.deleteGroup(group);
|
||||
KConfig cg(config);
|
||||
foreach (const QString& group, cg.groupList()) {
|
||||
cg.deleteGroup(group);
|
||||
}
|
||||
|
||||
foreach (Applet *applet, d->applets) {
|
||||
KConfigGroup cg(&appletConfig, QString::number(applet->id()));
|
||||
//kDebug() << "saving applet " << applet->name();
|
||||
cg.writeEntry("plugin", applet->pluginName());
|
||||
cg.writeEntry("geometry", QRect(applet->pos().toPoint(), applet->boundingRect().size().toSize()));
|
||||
QStringList containmentIds;
|
||||
foreach (const Containment *containment, d->containments) {
|
||||
QString cid = QString::number(containment->id());
|
||||
KConfigGroup containmentConfig(&cg, cid.append("-containment"));
|
||||
containment->saveConstraints(&containmentConfig);
|
||||
containment->save(&containmentConfig);
|
||||
foreach (const Applet* applet, containment->applets()) {
|
||||
KConfigGroup appletConfig(&cg, QString::number(applet->id()).append("-applet"));
|
||||
applet->save(&appletConfig);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -196,85 +140,151 @@ void Corona::loadApplets(const QString& config)
|
||||
{
|
||||
clearApplets();
|
||||
|
||||
KConfig appletConfig(config, KConfig::OnlyLocal);
|
||||
foreach (const QString& group, appletConfig.groupList()) {
|
||||
KConfigGroup cg(&appletConfig, group);
|
||||
addApplet(cg.readEntry("plugin", QString()), QVariantList(),
|
||||
group.toUInt(), cg.readEntry("geometry", QRectF()), true);
|
||||
KConfig cg(config, KConfig::OnlyLocal);
|
||||
|
||||
QList<KConfigGroup> applets;
|
||||
QHash<int, Containment*> containments;
|
||||
foreach (const QString& group, cg.groupList()) {
|
||||
KConfigGroup appletConfig(&cg, group);
|
||||
if (group.contains("containment")) {
|
||||
int cid = group.left(group.indexOf('-')).toUInt();
|
||||
Containment *c = addContainment(appletConfig.readEntry("plugin", QString()), QVariantList(),
|
||||
cid, true);
|
||||
if (c) {
|
||||
containments.insert(c->id(), c);
|
||||
c->initConstraints(&appletConfig);
|
||||
}
|
||||
} else {
|
||||
// it's an applet, let's grab the containment association
|
||||
kDebug() << "insert multi " << group;
|
||||
applets.append(appletConfig);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (Applet* applet, d->applets) {
|
||||
//int maxContainment = containments.size();
|
||||
//kDebug() << "number of applets?" << applets.count();
|
||||
foreach (KConfigGroup cg, applets) {
|
||||
int cid = cg.readEntry("containment", 0);
|
||||
kDebug() << "trying to load applet" << cg.group() << cid;
|
||||
|
||||
Containment* c = containments.value(cid, 0);
|
||||
|
||||
if (!c) {
|
||||
continue;
|
||||
}
|
||||
|
||||
kDebug() << "loading containment " << cid;
|
||||
|
||||
kDebug() << "creating applet " << cg.group();
|
||||
int appId = cg.group().left(cg.group().indexOf('-')).toUInt();
|
||||
c->addApplet(cg.readEntry("plugin", QString()), QVariantList(),
|
||||
appId, cg.readEntry("geometry", QRectF()), true);
|
||||
}
|
||||
|
||||
foreach (Containment* c, containments) {
|
||||
QString cid = QString::number(c->id());
|
||||
KConfigGroup containmentConfig(&cg, cid.append("-containment"));
|
||||
c->setImmutable(containmentConfig.isImmutable());
|
||||
}
|
||||
|
||||
if (d->containments.count() < 1) {
|
||||
loadDefaultSetup();
|
||||
}
|
||||
|
||||
foreach (Containment* containment, d->containments) {
|
||||
containment->init();
|
||||
|
||||
foreach(Applet* applet, containment->applets()) {
|
||||
applet->init();
|
||||
}
|
||||
}
|
||||
|
||||
setImmutable(cg.isImmutable());
|
||||
}
|
||||
|
||||
void Corona::loadApplets()
|
||||
{
|
||||
loadApplets("plasma-appletsrc");
|
||||
}
|
||||
|
||||
void Corona::loadDefaultSetup()
|
||||
{
|
||||
//FIXME: implement support for system-wide defaults
|
||||
QDesktopWidget desktop;
|
||||
int numScreens = desktop.numScreens();
|
||||
// create a containment for each screen
|
||||
for (int i = 0; i < numScreens; ++i) {
|
||||
Containment* c = addContainment("default");
|
||||
c->setScreen(i);
|
||||
c->setFormFactor(Plasma::Planar);
|
||||
}
|
||||
}
|
||||
|
||||
Containment* Corona::containmentForScreen(int screen) const
|
||||
{
|
||||
foreach (Containment* containment, d->containments) {
|
||||
if (containment->screen() == screen) {
|
||||
return containment;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void Corona::clearApplets()
|
||||
{
|
||||
qDeleteAll(d->applets);
|
||||
d->applets.clear();
|
||||
foreach (Containment* containment, d->containments) {
|
||||
containment->clearApplets();
|
||||
}
|
||||
}
|
||||
|
||||
Applet* Corona::addApplet(const QString& name, const QVariantList& args, uint id, const QRectF& geometry, bool delayInit)
|
||||
Containment* Corona::addContainment(const QString& name, const QVariantList& args, uint id, bool delayedInit)
|
||||
{
|
||||
Applet* applet = Applet::loadApplet(name, id, args);
|
||||
if (!applet) {
|
||||
kDebug() << "Applet " << name << " could not be loaded.";
|
||||
applet = new Applet;
|
||||
applet->setFailedToLaunch(true);
|
||||
Containment* containment = 0;
|
||||
Applet* applet = 0;
|
||||
|
||||
if (!name.isEmpty()) {
|
||||
applet = Applet::loadApplet(name, id, args);
|
||||
containment = dynamic_cast<Containment*>(applet);
|
||||
}
|
||||
|
||||
//qreal appWidth = applet->boundingRect().width();
|
||||
//qreal appHeight = applet->boundingRect().height();
|
||||
|
||||
if (geometry.isValid()) {
|
||||
applet->setGeometry(geometry);
|
||||
} else {
|
||||
applet->setGeometry( QRectF(geometry.topLeft(),applet->sizeHint()) );
|
||||
if (!containment) {
|
||||
delete applet; // in case we got a non-Containment from Applet::loadApplet
|
||||
containment = new Containment;
|
||||
containment->setFailedToLaunch(false); // we want to provide something and don't care about the failure to launch
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (!geometry.size().isValid()) {
|
||||
addItem(containment);
|
||||
|
||||
if (!delayedInit) {
|
||||
containment->init();
|
||||
}
|
||||
|
||||
if (geometry.isValid()) {
|
||||
applet->setGeometry(geometry);
|
||||
} else if (geometry.x() != -1 && geometry.y() != -1) {
|
||||
// yes, this means we can't have items start -1, -1
|
||||
applet->setPos(geometry.topLeft() - QPointF(applet->boundingRect().width()/2,
|
||||
applet->boundingRect().height()/2));
|
||||
} else {
|
||||
//TODO: Make sure new applets don't overlap with existing ones
|
||||
// Center exactly:
|
||||
applet->setPos((width() / 2) - (appWidth / 2), (height() / 2) - (appHeight / 2));
|
||||
}
|
||||
#endif
|
||||
// in case it was set in the Containment (or Applet), we don't want this
|
||||
containment->setDrawStandardBackground(false);
|
||||
|
||||
if ( d->layout )
|
||||
d->layout->addItem(applet);
|
||||
addItem(applet);
|
||||
applet->updateConstraints();
|
||||
d->containments.append(containment);
|
||||
connect(containment, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(containmentDestroyed(QObject*)));
|
||||
|
||||
if (!delayInit) {
|
||||
applet->init();
|
||||
return containment;
|
||||
}
|
||||
|
||||
//applet->constraintsUpdated();
|
||||
d->applets << applet;
|
||||
connect(applet, SIGNAL(destroyed(QObject*)),
|
||||
this, SLOT(appletDestroyed(QObject*)));
|
||||
Phase::self()->animateItem(applet, Phase::Appear);
|
||||
Applet* Corona::addApplet(const QString& name, const QVariantList& args, uint id, const QRectF& geometry)
|
||||
{
|
||||
if (d->containments.size() < 1) {
|
||||
kDebug() << "No containments to add an applet to!" << endl;
|
||||
//FIXME create a containment if one doesn't exist ... ?
|
||||
return 0;
|
||||
}
|
||||
|
||||
return applet;
|
||||
return d->containments[0]->addApplet(name, args, id, geometry);
|
||||
}
|
||||
|
||||
void Corona::addKaramba(const KUrl& path)
|
||||
{
|
||||
//FIXME: i think this is slightly broken now that we have containments?
|
||||
// it should go into a containment...
|
||||
QGraphicsItemGroup* karamba = KarambaManager::loadKaramba(path, this);
|
||||
if (karamba) {
|
||||
addItem(karamba);
|
||||
@ -286,7 +296,7 @@ void Corona::addKaramba(const KUrl& path)
|
||||
|
||||
void Corona::dragEnterEvent( QGraphicsSceneDragDropEvent *event)
|
||||
{
|
||||
kDebug() << "Corona::dragEnterEvent(QGraphicsSceneDragDropEvent* event)";
|
||||
// kDebug() << "Corona::dragEnterEvent(QGraphicsSceneDragDropEvent* event)";
|
||||
if (event->mimeData()->hasFormat(d->mimetype) ||
|
||||
KUrl::List::canDecode(event->mimeData())) {
|
||||
event->acceptProposedAction();
|
||||
@ -358,21 +368,17 @@ void Corona::dropEvent(QGraphicsSceneDragDropEvent *event)
|
||||
}
|
||||
}
|
||||
|
||||
// void Corona::contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent)
|
||||
// {
|
||||
// }
|
||||
|
||||
void Corona::appletDestroyed(QObject* object)
|
||||
void Corona::containmentDestroyed(QObject* obj)
|
||||
{
|
||||
// we do a static_cast here since it really isn't an Applet by this
|
||||
// we do a static_cast here since it really isn't an Containment by this
|
||||
// point anymore since we are in the qobject dtor. we don't actually
|
||||
// try and do anything with it, we just need the value of the pointer
|
||||
// so this unsafe looking code is actually just fine.
|
||||
Applet* applet = static_cast<Plasma::Applet*>(object);
|
||||
int index = d->applets.indexOf(applet);
|
||||
Containment* containment = static_cast<Plasma::Containment*>(obj);
|
||||
int index = d->containments.indexOf(containment);
|
||||
|
||||
if (index > -1) {
|
||||
d->applets.removeAt(index);
|
||||
d->containments.removeAt(index);
|
||||
}
|
||||
}
|
||||
|
||||
@ -389,13 +395,7 @@ void Corona::setImmutable(bool immutable)
|
||||
|
||||
d->immutable = immutable;
|
||||
foreach (QGraphicsItem* item, items()) {
|
||||
QGraphicsItem::GraphicsItemFlags flags = item->flags();
|
||||
if (immutable) {
|
||||
flags ^= QGraphicsItem::ItemIsMovable;
|
||||
} else {
|
||||
flags |= QGraphicsItem::ItemIsMovable;
|
||||
}
|
||||
item->setFlags(flags);
|
||||
item->setFlag(QGraphicsItem::ItemIsMovable, immutable);
|
||||
}
|
||||
}
|
||||
|
||||
|
61
corona.h
61
corona.h
@ -29,6 +29,7 @@
|
||||
namespace Plasma
|
||||
{
|
||||
|
||||
class Containment;
|
||||
|
||||
/**
|
||||
* @short A QGraphicsScene for Plasma::Applets
|
||||
@ -50,16 +51,6 @@ public:
|
||||
**/
|
||||
bool isImmutable() const;
|
||||
|
||||
/**
|
||||
* The location of the Corona. @see Plasma::Location
|
||||
*/
|
||||
Plasma::Location location() const;
|
||||
|
||||
/**
|
||||
* The current form factor for this Corona. @see Plasma::FormFactor
|
||||
**/
|
||||
Plasma::FormFactor formFactor() const;
|
||||
|
||||
/**
|
||||
* A rect containing the maximum size a plasmoid on this corona should
|
||||
* consider being.
|
||||
@ -91,6 +82,11 @@ public:
|
||||
*/
|
||||
void loadApplets(const QString &config);
|
||||
|
||||
/**
|
||||
* Loads the default (system wide) layout for this user
|
||||
**/
|
||||
virtual void loadDefaultSetup();
|
||||
|
||||
/**
|
||||
* Clear the Corona from all applets.
|
||||
*/
|
||||
@ -108,23 +104,7 @@ public Q_SLOTS:
|
||||
void saveApplets() const;
|
||||
|
||||
/**
|
||||
* Informs the Corona as to what position it is in. This is informational
|
||||
* only, as the Corona doesn't change it's actual location. This is,
|
||||
* however, passed on to Applets that may be managed by this Corona.
|
||||
*
|
||||
* @param location the new location of this Corona
|
||||
*/
|
||||
void setLocation(Plasma::Location location);
|
||||
|
||||
/**
|
||||
* Sets the form factor for this Corona. This may cause changes in both
|
||||
* the arrangement of Applets as well as the display choices of individual
|
||||
* Applets.
|
||||
*/
|
||||
void setFormFactor(Plasma::FormFactor formFactor);
|
||||
|
||||
/**
|
||||
* Adds an applet to the Corona
|
||||
* Adds an applet to the default Containment
|
||||
*
|
||||
* @param name the plugin name for the applet, as given by
|
||||
* KPluginInfo::pluginName()
|
||||
@ -136,8 +116,29 @@ public Q_SLOTS:
|
||||
* @return a pointer to the applet on success, or 0 on failure
|
||||
*/
|
||||
Applet* addApplet(const QString& name, const QVariantList& args = QVariantList(),
|
||||
uint id = 0, const QRectF &geometry = QRectF(-1, -1, -1, -1),
|
||||
bool delayInit = false);
|
||||
uint id = 0, const QRectF &geometry = QRectF(-1, -1, -1, -1));
|
||||
|
||||
/**
|
||||
* Adds a Containment to the Corona
|
||||
*
|
||||
* @param name the plugin name for the containment, as given by
|
||||
* KPluginInfo::pluginName()
|
||||
* @param args argument list to pass to the containment
|
||||
* @param id to assign to this containment, or 0 to auto-assign it a new id
|
||||
* @param geometry where to place the containment, or to auto-place it if an invalid
|
||||
* is provided
|
||||
*
|
||||
* @return a pointer to the containment on success, or 0 on failure
|
||||
*/
|
||||
Containment* addContainment(const QString& name, const QVariantList& args = QVariantList(),
|
||||
uint id = 0, bool delayInit = false);
|
||||
|
||||
/**
|
||||
* Returns the Containment, if any, for a given physical screen
|
||||
*
|
||||
* @param screen number of the physical screen to locate
|
||||
*/
|
||||
Containment* containmentForScreen(int screen) const;
|
||||
|
||||
/**
|
||||
* Adds a SuperKaramba theme to the scene
|
||||
@ -159,7 +160,7 @@ protected:
|
||||
//void contextMenuEvent(QGraphicsSceneContextMenuEvent *contextMenuEvent);
|
||||
|
||||
protected Q_SLOTS:
|
||||
void appletDestroyed(QObject*);
|
||||
void containmentDestroyed(QObject*);
|
||||
|
||||
private:
|
||||
class Private;
|
||||
|
Loading…
Reference in New Issue
Block a user