00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "corona.h"
00023
00024 #include <QApplication>
00025 #include <QGraphicsSceneDragDropEvent>
00026 #include <QMimeData>
00027 #include <QPainter>
00028 #include <QTimer>
00029
00030 #include <KDebug>
00031 #include <KGlobal>
00032 #include <KLocale>
00033 #include <KMimeType>
00034
00035 #include "containment.h"
00036
00037 using namespace Plasma;
00038
00039 namespace Plasma
00040 {
00041
00042
00043
00044 const int CONFIG_SYNC_TIMEOUT = 30000;
00045
00046 class CoronaPrivate
00047 {
00048 public:
00049 CoronaPrivate(Corona *corona)
00050 : q(corona),
00051 immutability(Mutable),
00052 mimetype("text/x-plasmoidservicename"),
00053 config(0)
00054 {
00055 if (KGlobal::hasMainComponent()) {
00056 configName = KGlobal::mainComponent().componentName() + "-appletsrc";
00057 } else {
00058 configName = "plasma-appletsrc";
00059 }
00060 }
00061
00062 ~CoronaPrivate()
00063 {
00064 qDeleteAll(containments);
00065 }
00066
00067 void init()
00068 {
00069 configSyncTimer.setSingleShot(true);
00070 QObject::connect(&configSyncTimer, SIGNAL(timeout()), q, SLOT(syncConfig()));
00071 }
00072
00073 void saveLayout(KSharedConfigPtr cg) const
00074 {
00075 KConfigGroup containmentsGroup(cg, "Containments");
00076 foreach (const Containment *containment, containments) {
00077 QString cid = QString::number(containment->id());
00078 KConfigGroup containmentConfig(&containmentsGroup, cid);
00079 containment->save(containmentConfig);
00080 }
00081 }
00082
00083 void updateContainmentImmutability()
00084 {
00085 foreach (Containment *c, containments) {
00086
00087 c->updateConstraints(ImmutableConstraint);
00088 }
00089 }
00090
00091 void containmentDestroyed(QObject* obj)
00092 {
00093
00094
00095
00096
00097 Containment* containment = static_cast<Plasma::Containment*>(obj);
00098 int index = containments.indexOf(containment);
00099
00100 if (index > -1) {
00101 containments.removeAt(index);
00102 q->requestConfigSync();
00103 }
00104 }
00105
00106 void syncConfig()
00107 {
00108 q->config()->sync();
00109 emit q->configSynced();
00110 }
00111
00112 Containment* addContainment(const QString& name, const QVariantList& args, uint id, bool delayedInit)
00113 {
00114 QString pluginName = name;
00115 Containment* containment = 0;
00116 Applet* applet = 0;
00117
00118
00119
00120 if (pluginName.isEmpty()) {
00121
00122 pluginName = "desktop";
00123 }
00124
00125 if (pluginName != "null") {
00126 applet = Applet::load(pluginName, id, args);
00127 containment = dynamic_cast<Containment*>(applet);
00128 }
00129
00130 if (!containment) {
00131 kDebug() << "loading of containment" << name << "failed.";
00132
00133
00134 delete applet;
00135 containment = new Containment(0, 0, id);
00136
00137
00138 containment->setFailedToLaunch(false);
00139 containment->setFormFactor(Plasma::Planar);
00140 }
00141
00142 containment->setIsContainment(true);
00143 q->addItem(containment);
00144
00145 if (!delayedInit) {
00146 containment->init();
00147 containment->updateConstraints(Plasma::StartupCompletedConstraint);
00148 KConfigGroup cg = containment->config();
00149 containment->save(cg);
00150 q->requestConfigSync();
00151 }
00152
00153 containments.append(containment);
00154 QObject::connect(containment, SIGNAL(destroyed(QObject*)), q, SLOT(containmentDestroyed(QObject*)));
00155 QObject::connect(containment, SIGNAL(configNeedsSaving()), q, SLOT(requestConfigSync()));
00156 QObject::connect(containment, SIGNAL(releaseVisualFocus()), q, SIGNAL(releaseVisualFocus()));
00157 QObject::connect(containment, SIGNAL(screenChanged(int,int,Plasma::Containment*)),
00158 q, SIGNAL(screenOwnerChanged(int,int,Plasma::Containment*)));
00159
00160 if (!delayedInit) {
00161 emit q->containmentAdded(containment);
00162 }
00163
00164 return containment;
00165 }
00166
00167 Corona *q;
00168 ImmutabilityType immutability;
00169 QString mimetype;
00170 QString configName;
00171 KSharedConfigPtr config;
00172 QTimer configSyncTimer;
00173 QList<Containment*> containments;
00174 };
00175
00176 Corona::Corona(QObject *parent)
00177 : QGraphicsScene(parent),
00178 d(new CoronaPrivate(this))
00179 {
00180 d->init();
00181
00182 }
00183
00184 Corona::~Corona()
00185 {
00186 KConfigGroup cg(config(), "General");
00187
00188
00189
00190 cg.writeEntry("immutability", (int)d->immutability);
00191 delete d;
00192 }
00193
00194 void Corona::setAppletMimeType(const QString& type)
00195 {
00196 d->mimetype = type;
00197 }
00198
00199 QString Corona::appletMimeType()
00200 {
00201 return d->mimetype;
00202 }
00203
00204 void Corona::saveLayout(const QString &configName) const
00205 {
00206 KSharedConfigPtr c;
00207
00208 if (configName.isEmpty() || configName == d->configName) {
00209 c = config();
00210 } else {
00211 c = KSharedConfig::openConfig(configName);
00212 }
00213
00214 d->saveLayout(c);
00215 }
00216
00217 void Corona::requestConfigSync()
00218 {
00219
00220
00221
00222
00223
00224
00225
00226 if (!d->configSyncTimer.isActive()) {
00227 d->configSyncTimer.start(CONFIG_SYNC_TIMEOUT);
00228 }
00229 }
00230
00231 void Corona::initializeLayout(const QString &configName)
00232 {
00233 clearContainments();
00234 loadLayout(configName);
00235
00236 if (d->containments.isEmpty()) {
00237 loadDefaultLayout();
00238 if (!d->containments.isEmpty()) {
00239 requestConfigSync();
00240 }
00241 }
00242
00243 if (config()->isImmutable()) {
00244 d->updateContainmentImmutability();
00245 }
00246
00247 KConfigGroup coronaConfig(config(), "General");
00248 setImmutability((ImmutabilityType)coronaConfig.readEntry("immutability", (int)Mutable));
00249 }
00250
00251 void Corona::loadLayout(const QString& configName)
00252 {
00253 KSharedConfigPtr c;
00254
00255 if (configName.isEmpty() || configName == d->configName) {
00256 c = config();
00257 } else {
00258 c = KSharedConfig::openConfig(configName);
00259 }
00260
00261 KConfigGroup containments(config(), "Containments");
00262
00263 foreach (const QString& group, containments.groupList()) {
00264 KConfigGroup containmentConfig(&containments, group);
00265
00266 if (containmentConfig.entryMap().isEmpty()) {
00267 continue;
00268 }
00269
00270 int cid = group.toUInt();
00271
00272 Containment *c = d->addContainment(containmentConfig.readEntry("plugin", QString()), QVariantList(),
00273 cid, true);
00274 if (!c) {
00275 continue;
00276 }
00277
00278
00279 c->init();
00280 c->restore(containmentConfig);
00281 }
00282
00283 foreach (Containment* containment, d->containments) {
00284 QString cid = QString::number(containment->id());
00285 KConfigGroup containmentConfig(&containments, cid);
00286
00287 foreach(Applet* applet, containment->applets()) {
00288 applet->init();
00289 }
00290
00291 containment->updateConstraints(Plasma::StartupCompletedConstraint);
00292 containment->flushPendingConstraintsEvents();
00293 emit containmentAdded(containment);
00294 }
00295 }
00296
00297 Containment* Corona::containmentForScreen(int screen) const
00298 {
00299 foreach (Containment* containment, d->containments) {
00300 if (containment->screen() == screen &&
00301 (containment->containmentType() == Containment::DesktopContainment ||
00302 containment->containmentType() >= Containment::CustomContainment)) {
00303 return containment;
00304 }
00305 }
00306
00307 return 0;
00308 }
00309
00310 QList<Containment*> Corona::containments() const
00311 {
00312 return d->containments;
00313 }
00314
00315 void Corona::clearContainments()
00316 {
00317 foreach (Containment* containment, d->containments) {
00318 containment->clearApplets();
00319 }
00320 }
00321
00322 KSharedConfigPtr Corona::config() const
00323 {
00324 if (!d->config) {
00325 d->config = KSharedConfig::openConfig(d->configName);
00326 }
00327
00328 return d->config;
00329 }
00330
00331 Containment* Corona::addContainment(const QString& name, const QVariantList& args)
00332 {
00333 return d->addContainment(name, args, 0, false);
00334 }
00335
00336 Containment* Corona::addContainmentDelayed(const QString& name, const QVariantList& args)
00337 {
00338 return d->addContainment(name, args, 0, true);
00339 }
00340
00341 void Corona::loadDefaultLayout()
00342 {
00343 }
00344
00345 void Corona::dragEnterEvent(QGraphicsSceneDragDropEvent *event)
00346 {
00347 QGraphicsScene::dragEnterEvent(event);
00348 }
00349
00350 void Corona::dragLeaveEvent(QGraphicsSceneDragDropEvent *event)
00351 {
00352 QGraphicsScene::dragLeaveEvent(event);
00353 }
00354
00355 void Corona::dragMoveEvent(QGraphicsSceneDragDropEvent *event)
00356 {
00357 QGraphicsScene::dragMoveEvent(event);
00358 }
00359
00360 ImmutabilityType Corona::immutability() const
00361 {
00362 return d->immutability;
00363 }
00364
00365 void Corona::setImmutability(const ImmutabilityType immutable)
00366 {
00367 if (d->immutability == immutable ||
00368 d->immutability == SystemImmutable) {
00369 return;
00370 }
00371
00372 kDebug() << "setting immutability to" << immutable;
00373 d->immutability = immutable;
00374 d->updateContainmentImmutability();
00375 }
00376
00377 }
00378
00379 #include "corona.moc"
00380