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.
25 #include <kwindowsystem.h>
26 #include <kactioncollection.h>
29 #include "containment.h"
30 #include "wallpaper.h"
32 using namespace Plasma
;
40 ViewPrivate(View
*view
, int uniqueId
)
50 if (uniqueId
> s_maxViewId
) {
51 s_maxViewId
= uniqueId
;
56 // we didn't get a sane value assigned to us, so lets
57 // grab the next available id
58 viewId
= ++s_maxViewId
;
68 q
->setContainment(containment
);
72 void updateSceneRect()
74 if (!containment
|| !trackChanges
) {
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());
86 //kDebug() << "trying to show the containment nicely";
87 q
->ensureVisible(containment
->sceneBoundingRect());
88 //q->centerOn(containment);
90 emit q
->sceneRectChanged();
93 void containmentDestroyed()
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
;
121 Plasma::Containment
*containment
;
125 bool drawWallpaper
: 1;
126 bool trackChanges
: 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();
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();
152 setScene(containment
->scene());
153 d
->containment
= containment
;
154 QTimer::singleShot(0, this, SLOT(privateInit()));
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
166 void View::setScreen(int screen
, int desktop
)
169 Corona
*corona
= qobject_cast
<Corona
*>(scene());
175 // -1 == All desktops
176 if (desktop
< -1 || desktop
> KWindowSystem::numberOfDesktops() - 1) {
180 Containment
*containment
= corona
->containmentForScreen(screen
, desktop
);
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
) {
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);
228 Containment
*oldContainment
= d
->containment
;
232 if (oldContainment
) {
233 screen
= d
->containment
->screen();
234 desktop
= d
->containment
->desktop();
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();
248 d
->lastScreen
= screen
;
249 d
->lastDesktop
= desktop
;
250 containment
->setScreen(screen
, desktop
);
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
)
290 Containment
*old
= existing
;
291 Plasma::Corona
*corona
= old
->corona();
292 Plasma::Containment
*c
= corona
->addContainment(name
, args
);
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
308 // load the configuration of the old containment into the new one
309 c
->restore(newConfig
);
310 foreach (Applet
*applet
, c
->applets()) {
312 // We have to flush the applet constraints manually
313 applet
->flushPendingConstraintsEvents();
316 // destroy the old one
319 // and now save the config
321 corona
->requestConfigSync();
329 KConfigGroup
View::config() const
331 KConfigGroup
views(KGlobal::config(), "PlasmaViews");
332 return KConfigGroup(&views
, QString::number(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
);
364 Plasma::View
*v
= qobject_cast
<Plasma::View
*>(w
);
371 } // namespace Plasma