dtor first
[personal-kdebase.git] / workspace / plasma / shells / desktop / desktopcorona.cpp
blobed07149577599651fb7ada841a981a481ef8a4d7
1 /*
2 * Copyright 2008 Aaron Seigo <aseigo@kde.org>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Library General Public License as
6 * published by the Free Software Foundation; either version 2, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details
14 * You should have received a copy of the GNU Library General Public
15 * License along with this program; if not, write to the
16 * Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "desktopcorona.h"
22 #include <QApplication>
23 #include <QDir>
24 #include <QGraphicsLayout>
25 #include <QTimer>
27 #include <KDebug>
28 #include <KDialog>
29 #include <KGlobalSettings>
30 #include <KStandardDirs>
31 #include <KWindowSystem>
33 #include <Plasma/Containment>
34 #include <Plasma/DataEngineManager>
36 #include <kephal/screens.h>
38 #include "panelview.h"
39 #include "plasmaapp.h"
40 #include "plasma-shell-desktop.h"
42 DesktopCorona::DesktopCorona(QObject *parent)
43 : Plasma::Corona(parent)
45 init();
48 void DesktopCorona::init()
50 Kephal::Screens *screens = Kephal::Screens::self();
51 connect(screens, SIGNAL(screenAdded(Kephal::Screen *)), SLOT(screenAdded(Kephal::Screen *)));
52 connect(KWindowSystem::self(), SIGNAL(workAreaChanged()), this, SIGNAL(availableScreenRegionChanged()));
55 void DesktopCorona::checkScreens()
57 // quick sanity check to ensure we have containments for each screen
58 int numScreens = Kephal::ScreenUtils::numScreens();
59 for (int i = 0; i < numScreens; ++i) {
60 checkScreen(i);
64 void DesktopCorona::checkScreen(int screen, bool signalWhenExists)
66 if (AppSettings::perVirtualDesktopViews()) {
67 int numDesktops = KWindowSystem::numberOfDesktops();
69 for (int j = 0; j < numDesktops; ++j) {
70 Plasma::Containment *c = containmentForScreen(screen, j);
72 if (!c) {
73 addDesktopContainment(screen, j);
74 } else if (signalWhenExists) {
75 emit containmentAdded(c);
78 } else {
79 Plasma::Containment *c = containmentForScreen(screen);
80 if (!containmentForScreen(screen)) {
81 addDesktopContainment(screen);
82 } else if (signalWhenExists) {
83 emit containmentAdded(c);
88 void DesktopCorona::addDesktopContainment(int screen, int desktop)
90 kDebug() << screen << desktop;
91 Plasma::Containment* c = addContainment("desktop");
92 c->setScreen(screen, desktop);
93 c->setFormFactor(Plasma::Planar);
94 c->flushPendingConstraintsEvents();
95 c->setActivity(i18n("Desktop"));
96 emit containmentAdded(c);
99 int DesktopCorona::numScreens() const
101 return Kephal::ScreenUtils::numScreens();
104 QRect DesktopCorona::screenGeometry(int id) const
106 return Kephal::ScreenUtils::screenGeometry(id);
109 QRegion DesktopCorona::availableScreenRegion(int id) const
111 QRegion r(screenGeometry(id));
112 foreach (PanelView *view, PlasmaApp::self()->panelViews()) {
113 if (view->screen() == id && view->visibilityMode() == PanelView::NormalPanel) {
114 r = r.subtracted(view->geometry());
118 return r;
121 void DesktopCorona::loadDefaultLayout()
123 QString defaultConfig = KStandardDirs::locate("appdata", "plasma-default-layoutrc");
124 if (!defaultConfig.isEmpty()) {
125 kDebug() << "attempting to load the default layout from:" << defaultConfig;
126 loadLayout(defaultConfig);
127 return;
130 kDebug() << "number of screens is" << Kephal::ScreenUtils::numScreens();
131 int topLeftScreen = 0;
132 QPoint topLeftCorner = Kephal::ScreenUtils::screenGeometry(0).topLeft();
134 // find our "top left" screen, use it as the primary
135 for (int i = 0; i < Kephal::ScreenUtils::numScreens(); ++i) {
136 QRect g = Kephal::ScreenUtils::screenGeometry(i);
137 kDebug() << " screen " << i << "geometry is" << g;
139 if (g.x() <= topLeftCorner.x() && g.y() >= topLeftCorner.y()) {
140 topLeftCorner = g.topLeft();
141 topLeftScreen = i;
145 // create a containment for each screen
146 for (int i = 0; i < Kephal::ScreenUtils::numScreens(); ++i) {
147 // passing in an empty string will get us whatever the default
148 // containment type is!
149 Plasma::Containment* c = addContainmentDelayed(QString());
151 if (!c) {
152 continue;
155 c->init();
156 c->setScreen(i, 0);
157 c->setWallpaper("image", "SingleImage");
158 c->setFormFactor(Plasma::Planar);
159 c->updateConstraints(Plasma::StartupCompletedConstraint);
160 c->flushPendingConstraintsEvents();
162 // put a folder view on the first screen
163 if (i == topLeftScreen) {
164 QString desktopPath = KGlobalSettings::desktopPath();
165 QDir desktopFolder(desktopPath);
166 if (desktopPath != QDir::homePath() && desktopFolder.exists()) {
167 Plasma::Applet *folderView = Plasma::Applet::load("folderview", c->id() + 1);
168 if (folderView) {
169 c->addApplet(folderView, QPointF(KDialog::spacingHint(), KDialog::spacingHint()), true);
170 KConfigGroup config = folderView->config();
171 config.writeEntry("url", "desktop:/");
176 emit containmentAdded(c);
179 // make a panel at the bottom
180 Plasma::Containment *panel = addContainmentDelayed("panel");
182 if (!panel) {
183 return;
186 panel->init();
187 panel->setScreen(topLeftScreen);
188 panel->setLocation(Plasma::BottomEdge);
189 panel->updateConstraints(Plasma::StartupCompletedConstraint);
190 panel->flushPendingConstraintsEvents();
192 // some default applets to get a usable UI
193 Plasma::Applet *applet = loadDefaultApplet("launcher", panel);
194 if (applet) {
195 applet->setGlobalShortcut(KShortcut("Alt+F1"));
198 loadDefaultApplet("notifier", panel);
199 loadDefaultApplet("pager", panel);
200 loadDefaultApplet("tasks", panel);
201 loadDefaultApplet("systemtray", panel);
203 Plasma::DataEngineManager *engines = Plasma::DataEngineManager::self();
204 Plasma::DataEngine *power = engines->loadEngine("powermanagement");
205 if (power) {
206 const QStringList &batteries = power->query("Battery")["sources"].toStringList();
207 if (!batteries.isEmpty()) {
208 loadDefaultApplet("battery", panel);
211 engines->unloadEngine("powermanagement");
213 loadDefaultApplet("digital-clock", panel);
214 emit containmentAdded(panel);
216 QTimer::singleShot(1000, this, SLOT(saveDefaultSetup()));
219 void DesktopCorona::saveDefaultSetup()
221 // a "null" KConfigGroup is used to force a save into the config file
222 KConfigGroup invalidConfig;
224 foreach (Plasma::Containment *containment, containments()) {
225 containment->save(invalidConfig);
227 foreach (Plasma::Applet* applet, containment->applets()) {
228 applet->init();
229 applet->flushPendingConstraintsEvents();
230 applet->save(invalidConfig);
234 requestConfigSync();
237 Plasma::Applet *DesktopCorona::loadDefaultApplet(const QString &pluginName, Plasma::Containment *c)
239 QVariantList args;
240 Plasma::Applet *applet = Plasma::Applet::load(pluginName, 0, args);
242 if (applet) {
243 c->addApplet(applet);
246 return applet;
249 void DesktopCorona::screenAdded(Kephal::Screen *s)
251 kDebug() << s->id();
252 checkScreen(s->id(), true);
255 #include "desktopcorona.moc"