Plasma
view.cpp
Go to the documentation of this file.
00001 /* 00002 * Copyright 2007 Aaron Seigo <aseigo@kde.org> 00003 * 00004 * This program is free software; you can redistribute it and/or modify 00005 * it under the terms of the GNU Library General Public License as 00006 * published by the Free Software Foundation; either version 2, or 00007 * (at your option) any later version. 00008 * 00009 * This program is distributed in the hope that it will be useful, 00010 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00012 * GNU General Public License for more details 00013 * 00014 * You should have received a copy of the GNU Library General Public 00015 * License along with this program; if not, write to the 00016 * Free Software Foundation, Inc., 00017 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00018 */ 00019 00020 #include "view.h" 00021 00022 #include <QTimer> 00023 00024 #include <kdebug.h> 00025 #include <kglobal.h> 00026 #include <kwindowsystem.h> 00027 #include <kactioncollection.h> 00028 00029 #include "corona.h" 00030 #include "containment.h" 00031 #include "private/containment_p.h" 00032 #include "wallpaper.h" 00033 00034 using namespace Plasma; 00035 00036 namespace Plasma 00037 { 00038 00039 class ViewPrivate 00040 { 00041 public: 00042 ViewPrivate(View *view, int uniqueId) 00043 : q(view), 00044 containment(0), 00045 viewId(0), 00046 lastScreen(-1), 00047 lastDesktop(-2), 00048 drawWallpaper(true), 00049 trackChanges(true), 00050 init(false) 00051 { 00052 if (uniqueId > 0 && !viewIds.contains(uniqueId)) { 00053 s_maxViewId = uniqueId; 00054 viewId = uniqueId; 00055 } 00056 00057 if (viewId == 0) { 00058 // we didn't get a sane value assigned to us, so lets 00059 // grab the next available id 00060 viewId = ++s_maxViewId; 00061 } 00062 viewIds.insert(viewId); 00063 } 00064 00065 ~ViewPrivate() 00066 { 00067 } 00068 00069 void privateInit() 00070 { 00071 q->setContainment(containment); 00072 init = true; 00073 } 00074 00075 void updateSceneRect() 00076 { 00077 if (!containment || !trackChanges) { 00078 return; 00079 } 00080 00081 kDebug() << "!!!!!!!!!!!!!!!!! setting the scene rect to" 00082 << containment->sceneBoundingRect() 00083 << "associated screen is" << containment->screen(); 00084 00085 emit q->sceneRectAboutToChange(); 00086 if (q->transform().isIdentity()) { //we're not zoomed out 00087 q->setSceneRect(containment->sceneBoundingRect()); 00088 } else { 00089 //kDebug() << "trying to show the containment nicely"; 00090 q->ensureVisible(containment->sceneBoundingRect()); 00091 //q->centerOn(containment); 00092 } 00093 emit q->sceneRectChanged(); 00094 } 00095 00096 void containmentDestroyed() 00097 { 00098 containment = 0; 00099 emit q->lostContainment(); 00100 } 00101 00102 void containmentScreenChanged(int wasScreen, int newScreen, Plasma::Containment *containment) 00103 { 00104 Q_UNUSED(wasScreen) 00105 lastScreen = newScreen; 00106 lastDesktop = containment->desktop(); 00107 } 00108 00109 void initGraphicsView() 00110 { 00111 q->setFrameShape(QFrame::NoFrame); 00112 q->setAttribute(Qt::WA_TranslucentBackground); 00113 q->setAutoFillBackground(true); 00114 q->setDragMode(QGraphicsView::NoDrag); 00115 q->setInteractive(true); 00116 q->setAcceptDrops(true); 00117 q->setAlignment(Qt::AlignLeft | Qt::AlignTop); 00118 q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 00119 q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); 00120 } 00121 00122 static int s_maxViewId; 00123 //ugly but the only reliable way to do collision detection of ids 00124 static QSet<int> viewIds; 00125 00126 Plasma::View *q; 00127 Plasma::Containment *containment; 00128 int viewId; 00129 int lastScreen; 00130 int lastDesktop; 00131 bool drawWallpaper : 1; 00132 bool trackChanges : 1; 00133 bool init : 1; 00134 }; 00135 00136 int ViewPrivate::s_maxViewId(0); 00137 QSet<int> ViewPrivate::viewIds; 00138 00139 View::View(Containment *containment, QWidget *parent) 00140 : QGraphicsView(parent), 00141 d(new ViewPrivate(this, 0)) 00142 { 00143 d->initGraphicsView(); 00144 00145 if (containment) { 00146 setScene(containment->scene()); 00147 d->containment = containment; 00148 QTimer::singleShot(0, this, SLOT(privateInit())); 00149 } 00150 } 00151 00152 View::View(Containment *containment, int viewId, QWidget *parent) 00153 : QGraphicsView(parent), 00154 d(new ViewPrivate(this, viewId)) 00155 { 00156 d->initGraphicsView(); 00157 00158 if (containment) { 00159 setScene(containment->scene()); 00160 d->containment = containment; 00161 QTimer::singleShot(0, this, SLOT(privateInit())); 00162 } 00163 } 00164 00165 View::~View() 00166 { 00167 delete d; 00168 // FIXME FIX a focus crash but i wasn't able to reproduce in a simple test case for Qt guys 00169 // NB: this is also done in Corona 00170 clearFocus(); 00171 } 00172 00173 void View::setScreen(int screen, int desktop) 00174 { 00175 if (screen < 0) { 00176 return; 00177 } 00178 00179 // handle desktop views 00180 // -1 == All desktops 00181 if (desktop < -1 || desktop > KWindowSystem::numberOfDesktops() - 1) { 00182 desktop = -1; 00183 } 00184 00185 d->lastScreen = screen; 00186 d->lastDesktop = desktop; 00187 00188 // handle views that are working with panel containment types 00189 if (d->containment && 00190 (d->containment->containmentType() == Containment::PanelContainment || 00191 d->containment->containmentType() == Containment::CustomPanelContainment)) { 00192 d->containment->setScreen(screen, desktop); 00193 return; 00194 } 00195 00196 Plasma::Corona *corona = qobject_cast<Plasma::Corona*>(scene()); 00197 if (corona) { 00198 Containment *containment = corona->containmentForScreen(screen, desktop); 00199 00200 if (containment) { 00201 d->containment = 0; //so that we don't end up on the old containment's screen 00202 setContainment(containment); 00203 } 00204 } 00205 } 00206 00207 int View::screen() const 00208 { 00209 return d->lastScreen; 00210 } 00211 00212 int View::desktop() const 00213 { 00214 if (d->containment) { 00215 return d->containment->desktop(); 00216 } 00217 00218 return d->lastDesktop; 00219 } 00220 00221 int View::effectiveDesktop() const 00222 { 00223 int desk = desktop(); 00224 return desk > -1 ? desk : KWindowSystem::currentDesktop(); 00225 } 00226 00227 void View::setContainment(Plasma::Containment *containment) 00228 { 00229 if (d->init && containment == d->containment) { 00230 return; 00231 } 00232 00233 if (d->containment) { 00234 disconnect(d->containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed())); 00235 disconnect(d->containment, SIGNAL(geometryChanged()), this, SLOT(updateSceneRect())); 00236 disconnect(d->containment, SIGNAL(screenChanged(int,int,Plasma::Containment*)), this, SLOT(containmentScreenChanged(int,int,Plasma::Containment*))); 00237 d->containment->removeAssociatedWidget(this); 00238 } 00239 00240 if (!containment) { 00241 d->containment = 0; 00242 return; 00243 } 00244 00245 Containment *oldContainment = d->containment; 00246 00247 int screen = d->lastScreen; 00248 int desktop = d->lastDesktop; 00249 if (oldContainment && oldContainment != containment) { 00250 screen = oldContainment->screen(); 00251 desktop = oldContainment->desktop(); 00252 } 00253 00254 if (scene() != containment->scene()) { 00255 setScene(containment->scene()); 00256 } 00257 00258 d->containment = containment; 00259 00260 //add keyboard-shortcut actions 00261 d->containment->addAssociatedWidget(this); 00262 00263 int otherScreen = containment->screen(); 00264 int otherDesktop = containment->desktop(); 00265 00266 if (screen > -1) { 00267 d->lastScreen = screen; 00268 d->lastDesktop = desktop; 00269 //kDebug() << "set screen from setContainment due to old containment"; 00270 if (oldContainment && oldContainment != containment) { 00271 oldContainment->setScreen(-1, -1); 00272 } 00273 00274 if (screen != containment->screen() || desktop != containment->desktop()) { 00275 containment->setScreen(screen, desktop); 00276 } 00277 } else { 00278 d->lastScreen = otherScreen; 00279 d->lastDesktop = otherDesktop; 00280 } 00281 00282 if (oldContainment && oldContainment != containment && otherScreen > -1 && 00283 (!containment || otherScreen != containment->screen() || otherDesktop != containment->desktop())) { 00284 // assign the old containment the old screen/desktop 00285 //kDebug() << "set screen from setContainment" << screen << otherScreen << desktop << otherDesktop; 00286 oldContainment->setScreen(otherScreen, otherDesktop); 00287 } 00288 00289 00290 /* 00291 if (oldContainment) { 00292 kDebug() << "old" << (QObject*)oldContainment << screen << oldContainment->screen() 00293 << "new" << (QObject*)containment << otherScreen << containment->screen(); 00294 } 00295 */ 00296 00297 d->updateSceneRect(); 00298 connect(containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed())); 00299 connect(containment, SIGNAL(geometryChanged()), this, SLOT(updateSceneRect())); 00300 connect(containment, SIGNAL(screenChanged(int,int,Plasma::Containment*)), this, SLOT(containmentScreenChanged(int,int,Plasma::Containment*))); 00301 } 00302 00303 Containment *View::containment() const 00304 { 00305 return d->containment; 00306 } 00307 00308 Containment *View::swapContainment(const QString &name, const QVariantList &args) 00309 { 00310 return swapContainment(d->containment, name, args); 00311 } 00312 00313 Containment *View::swapContainment(Plasma::Containment *existing, const QString &name, const QVariantList &args) 00314 { 00315 if (!existing) { 00316 return 0; 00317 } 00318 00319 Containment *old = existing; 00320 Plasma::Corona *corona = old->corona(); 00321 Plasma::Containment *c = corona->addContainmentDelayed(name, args); 00322 if (c) { 00323 c->init(); 00324 00325 KConfigGroup oldConfig = old->config(); 00326 KConfigGroup newConfig = c->config(); 00327 00328 // ensure that the old containments configuration is up to date 00329 old->save(oldConfig); 00330 00331 // Copy configuration to new containment 00332 oldConfig.copyTo(&newConfig); 00333 00334 if (old == d->containment) { 00335 // set our containment to the new one, if the the old containment was us 00336 setContainment(c); 00337 } 00338 00339 // load the configuration of the old containment into the new one 00340 c->restore(newConfig); 00341 c->updateConstraints(Plasma::StartupCompletedConstraint); 00342 c->d->initApplets(); 00343 emit corona->containmentAdded(c); 00344 00345 // destroy the old one 00346 old->destroy(false); 00347 00348 // and now save the config 00349 c->save(newConfig); 00350 corona->requestConfigSync(); 00351 00352 return c; 00353 } 00354 00355 return old; 00356 } 00357 00358 KConfigGroup View::config() const 00359 { 00360 KConfigGroup views(KGlobal::config(), "PlasmaViews"); 00361 return KConfigGroup(&views, QString::number(d->viewId)); 00362 } 00363 00364 void View::configNeedsSaving() const 00365 { 00366 Plasma::Corona *corona = qobject_cast<Plasma::Corona*>(scene()); 00367 if (corona) { 00368 corona->requestConfigSync(); 00369 } else { 00370 KGlobal::config()->sync(); 00371 } 00372 } 00373 00374 00375 int View::id() const 00376 { 00377 return d->viewId; 00378 } 00379 00380 void View::setWallpaperEnabled(bool draw) 00381 { 00382 d->drawWallpaper = draw; 00383 } 00384 00385 bool View::isWallpaperEnabled() const 00386 { 00387 return d->drawWallpaper; 00388 } 00389 00390 void View::setTrackContainmentChanges(bool trackChanges) 00391 { 00392 d->trackChanges = trackChanges; 00393 } 00394 00395 bool View::trackContainmentChanges() 00396 { 00397 return d->trackChanges; 00398 } 00399 00400 View * View::topLevelViewAt(const QPoint & pos) 00401 { 00402 QWidget *w = QApplication::topLevelAt(pos); 00403 if (w) { 00404 Plasma::View *v = qobject_cast<Plasma::View *>(w); 00405 return v; 00406 } else { 00407 return 0; 00408 } 00409 } 00410 00411 } // namespace Plasma 00412 00413 #include "view.moc" 00414
This file is part of the KDE documentation.
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:36:23 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
Documentation copyright © 1996-2012 The KDE developers.
Generated on Wed May 2 2012 17:36:23 by doxygen 1.8.0 written by Dimitri van Heesch, © 1997-2006
KDE's Doxygen guidelines are available online.