some more win32'fication to fix non-ascii filename handling
[kdelibs.git] / plasma / view.cpp
blob2e4c78bef726fb8b4258c00886b858ae37a1affb
1 /*
2 * Copyright 2007 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 "view.h"
22 #include <QTimer>
24 #include <kglobal.h>
25 #include <kwindowsystem.h>
26 #include <kactioncollection.h>
28 #include "corona.h"
29 #include "containment.h"
30 #include "wallpaper.h"
32 using namespace Plasma;
34 namespace Plasma
37 class ViewPrivate
39 public:
40 ViewPrivate(View *view, int uniqueId)
41 : q(view),
42 containment(0),
43 viewId(0),
44 lastScreen(-1),
45 lastDesktop(-2),
46 drawWallpaper(true),
47 trackChanges(true),
48 init(false)
50 if (uniqueId > s_maxViewId) {
51 s_maxViewId = uniqueId;
52 viewId = uniqueId;
55 if (viewId == 0) {
56 // we didn't get a sane value assigned to us, so lets
57 // grab the next available id
58 viewId = ++s_maxViewId;
62 ~ViewPrivate()
66 void privateInit()
68 q->setContainment(containment);
69 init = true;
72 void updateSceneRect()
74 if (!containment || !trackChanges) {
75 return;
78 kDebug() << "!!!!!!!!!!!!!!!!! setting the scene rect to"
79 << containment->sceneBoundingRect()
80 << "associated screen is" << containment->screen();
82 emit q->sceneRectAboutToChange();
83 if (q->transform().isIdentity()) { //we're not zoomed out
84 q->setSceneRect(containment->sceneBoundingRect());
85 } else {
86 //kDebug() << "trying to show the containment nicely";
87 q->ensureVisible(containment->sceneBoundingRect());
88 //q->centerOn(containment);
90 emit q->sceneRectChanged();
93 void containmentDestroyed()
95 containment = 0;
98 void containmentScreenChanged(int wasScreen, int newScreen, Plasma::Containment *containment)
100 lastScreen = newScreen;
101 lastDesktop = this->containment->desktop();
104 void initGraphicsView()
106 q->setFrameShape(QFrame::NoFrame);
107 q->setAttribute(Qt::WA_TranslucentBackground);
108 q->setAutoFillBackground(true);
109 q->setDragMode(QGraphicsView::NoDrag);
110 //setCacheMode(QGraphicsView::CacheBackground);
111 q->setInteractive(true);
112 q->setAcceptDrops(true);
113 q->setAlignment(Qt::AlignLeft | Qt::AlignTop);
114 q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
115 q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
118 static int s_maxViewId;
120 Plasma::View *q;
121 Plasma::Containment *containment;
122 int viewId;
123 int lastScreen;
124 int lastDesktop;
125 bool drawWallpaper : 1;
126 bool trackChanges : 1;
127 bool init : 1;
130 int ViewPrivate::s_maxViewId(0);
132 View::View(Containment *containment, QWidget *parent)
133 : QGraphicsView(parent),
134 d(new ViewPrivate(this, 0))
136 d->initGraphicsView();
138 if (containment) {
139 setScene(containment->scene());
140 d->containment = containment;
141 QTimer::singleShot(0, this, SLOT(privateInit()));
145 View::View(Containment *containment, int viewId, QWidget *parent)
146 : QGraphicsView(parent),
147 d(new ViewPrivate(this, viewId))
149 d->initGraphicsView();
151 if (containment) {
152 setScene(containment->scene());
153 d->containment = containment;
154 QTimer::singleShot(0, this, SLOT(privateInit()));
158 View::~View()
160 delete d;
161 // FIXME FIX a focus crash but i wasn't able to reproduce in a simple test case for Qt guys
162 // NB: this is also done in Corona
163 clearFocus();
166 void View::setScreen(int screen, int desktop)
168 if (screen > -1) {
169 Corona *corona = qobject_cast<Corona*>(scene());
171 if (!corona) {
172 return;
175 // -1 == All desktops
176 if (desktop < -1 || desktop > KWindowSystem::numberOfDesktops() - 1) {
177 desktop = -1;
180 Containment *containment = corona->containmentForScreen(screen, desktop);
181 if (containment) {
182 d->containment = 0; //so that we don't end up on the old containment's screen
183 d->lastScreen = screen;
184 d->lastDesktop = desktop;
185 setContainment(containment);
190 int View::screen() const
192 return d->lastScreen;
195 int View::desktop() const
197 if (d->containment) {
198 return d->containment->desktop();
201 return d->lastDesktop;
204 int View::effectiveDesktop() const
206 int desk = desktop();
207 return desk > -1 ? desk : KWindowSystem::currentDesktop();
210 void View::setContainment(Plasma::Containment *containment)
212 if (d->init && containment == d->containment) {
213 return;
216 if (d->containment) {
217 disconnect(d->containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed()));
218 disconnect(d->containment, SIGNAL(geometryChanged()), this, SLOT(updateSceneRect()));
219 disconnect(d->containment, SIGNAL(screenChanged(int, int, Plasma::Containment *)), this, SLOT(containmentScreenChanged(int, int, Plasma::Containment *)));
220 d->containment->removeAssociatedWidget(this);
223 if (!containment) {
224 d->containment = 0;
225 return;
228 Containment *oldContainment = d->containment;
230 int screen = -1;
231 int desktop = -1;
232 if (oldContainment) {
233 screen = d->containment->screen();
234 desktop = d->containment->desktop();
235 } else {
236 setScene(containment->scene());
239 d->containment = containment;
241 //add keyboard-shortcut actions
242 d->containment->addAssociatedWidget(this);
244 int otherScreen = containment->screen();
245 int otherDesktop = containment->desktop();
247 if (screen > -1) {
248 d->lastScreen = screen;
249 d->lastDesktop = desktop;
250 containment->setScreen(screen, desktop);
251 } else {
252 d->lastScreen = otherScreen;
253 d->lastDesktop = otherDesktop;
256 if (oldContainment && otherScreen > -1) {
257 // assign the old containment the old screen/desktop
258 oldContainment->setScreen(otherScreen, otherDesktop);
262 if (oldContainment) {
263 kDebug() << "old" << (QObject*)oldContainment << screen << oldContainment->screen()
264 << "new" << (QObject*)containment << otherScreen << containment->screen();
268 d->updateSceneRect();
269 connect(containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed()));
270 connect(containment, SIGNAL(geometryChanged()), this, SLOT(updateSceneRect()));
271 connect(containment, SIGNAL(screenChanged(int, int, Plasma::Containment *)), this, SLOT(containmentScreenChanged(int, int, Plasma::Containment *)));
274 Containment *View::containment() const
276 return d->containment;
279 Containment *View::swapContainment(const QString &name, const QVariantList &args)
281 return swapContainment(d->containment, name, args);
284 Containment *View::swapContainment(Plasma::Containment *existing, const QString &name, const QVariantList &args)
286 if (!existing) {
287 return 0;
290 Containment *old = existing;
291 Plasma::Corona *corona = old->corona();
292 Plasma::Containment *c = corona->addContainment(name, args);
293 if (c) {
294 KConfigGroup oldConfig = old->config();
295 KConfigGroup newConfig = c->config();
297 // ensure that the old containments configuration is up to date
298 old->save(oldConfig);
300 // Copy configuration to new containment
301 oldConfig.copyTo(&newConfig);
303 if (old == d->containment) {
304 // set our containment to the new one, if the the old containment was us
305 setContainment(c);
308 // load the configuration of the old containment into the new one
309 c->restore(newConfig);
310 foreach (Applet *applet, c->applets()) {
311 applet->init();
312 // We have to flush the applet constraints manually
313 applet->flushPendingConstraintsEvents();
316 // destroy the old one
317 old->destroy(false);
319 // and now save the config
320 c->save(newConfig);
321 corona->requestConfigSync();
323 return c;
326 return old;
329 KConfigGroup View::config() const
331 KConfigGroup views(KGlobal::config(), "PlasmaViews");
332 return KConfigGroup(&views, QString::number(d->viewId));
335 int View::id() const
337 return d->viewId;
340 void View::setWallpaperEnabled(bool draw)
342 d->drawWallpaper = draw;
345 bool View::isWallpaperEnabled() const
347 return d->drawWallpaper;
350 void View::setTrackContainmentChanges(bool trackChanges)
352 d->trackChanges = trackChanges;
355 bool View::trackContainmentChanges()
357 return d->trackChanges;
360 View * View::topLevelViewAt(const QPoint & pos)
362 QWidget *w = QApplication::topLevelAt(pos);
363 if (w) {
364 Plasma::View *v = qobject_cast<Plasma::View *>(w);
365 return v;
366 } else {
367 return 0;
371 } // namespace Plasma
373 #include "view.moc"