• Skip to content
  • Skip to link menu
KDE 4.6 API Reference
  • KDE API Reference
  • kdelibs
  • KDE Home
  • Contact Us
 

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 "wallpaper.h"
00032 
00033 using namespace Plasma;
00034 
00035 namespace Plasma
00036 {
00037 
00038 class ViewPrivate
00039 {
00040 public:
00041     ViewPrivate(View *view, int uniqueId)
00042         : q(view),
00043           containment(0),
00044           viewId(0),
00045           lastScreen(-1),
00046           lastDesktop(-2),
00047           drawWallpaper(true),
00048           trackChanges(true),
00049           init(false)
00050     {
00051         if (uniqueId > 0 && !viewIds.contains(uniqueId)) {
00052             s_maxViewId = uniqueId;
00053             viewId = uniqueId;
00054         }
00055 
00056         if (viewId == 0) {
00057             // we didn't get a sane value assigned to us, so lets
00058             // grab the next available id
00059             viewId = ++s_maxViewId;
00060         }
00061         viewIds.insert(viewId);
00062     }
00063 
00064     ~ViewPrivate()
00065     {
00066     }
00067 
00068     void privateInit()
00069     {
00070         q->setContainment(containment);
00071         init = true;
00072     }
00073 
00074     void updateSceneRect()
00075     {
00076         if (!containment || !trackChanges) {
00077             return;
00078         }
00079 
00080         kDebug() << "!!!!!!!!!!!!!!!!! setting the scene rect to"
00081                  << containment->sceneBoundingRect()
00082                  << "associated screen is" << containment->screen();
00083 
00084         emit q->sceneRectAboutToChange();
00085         if (q->transform().isIdentity()) { //we're not zoomed out
00086             q->setSceneRect(containment->sceneBoundingRect());
00087         } else {
00088             //kDebug() << "trying to show the containment nicely";
00089             q->ensureVisible(containment->sceneBoundingRect());
00090             //q->centerOn(containment);
00091         }
00092         emit q->sceneRectChanged();
00093     }
00094 
00095     void containmentDestroyed()
00096     {
00097         containment = 0;
00098         emit q->lostContainment();
00099     }
00100 
00101     void containmentScreenChanged(int wasScreen, int newScreen, Plasma::Containment *containment)
00102     {
00103         Q_UNUSED(wasScreen)
00104         lastScreen = newScreen;
00105         lastDesktop = containment->desktop();
00106     }
00107 
00108     void initGraphicsView()
00109     {
00110         q->setFrameShape(QFrame::NoFrame);
00111         q->setAttribute(Qt::WA_TranslucentBackground);
00112         q->setAutoFillBackground(true);
00113         q->setDragMode(QGraphicsView::NoDrag);
00114         //setCacheMode(QGraphicsView::CacheBackground);
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->type() == Containment::PanelContainment ||
00191          d->containment->type() == 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->flushPendingConstraintsEvents();
00343         emit corona->containmentAdded(c);
00344         foreach (Applet *applet, c->applets()) {
00345             applet->init();
00346             // We have to flush the applet constraints manually
00347             applet->flushPendingConstraintsEvents();
00348         }
00349 
00350         // destroy the old one
00351         old->destroy(false);
00352 
00353         // and now save the config
00354         c->save(newConfig);
00355         corona->requestConfigSync();
00356 
00357         return c;
00358     }
00359 
00360     return old;
00361 }
00362 
00363 KConfigGroup View::config() const
00364 {
00365     KConfigGroup views(KGlobal::config(), "PlasmaViews");
00366     return KConfigGroup(&views, QString::number(d->viewId));
00367 }
00368 
00369 void View::configNeedsSaving() const
00370 {
00371     Plasma::Corona *corona = qobject_cast<Plasma::Corona*>(scene());
00372     if (corona) {
00373         corona->requestConfigSync();
00374     } else {
00375         KGlobal::config()->sync();
00376     }
00377 }
00378 
00379 
00380 int View::id() const
00381 {
00382     return d->viewId;
00383 }
00384 
00385 void View::setWallpaperEnabled(bool draw)
00386 {
00387     d->drawWallpaper = draw;
00388 }
00389 
00390 bool View::isWallpaperEnabled() const
00391 {
00392     return d->drawWallpaper;
00393 }
00394 
00395 void View::setTrackContainmentChanges(bool trackChanges)
00396 {
00397     d->trackChanges = trackChanges;
00398 }
00399 
00400 bool View::trackContainmentChanges()
00401 {
00402     return d->trackChanges;
00403 }
00404 
00405 View * View::topLevelViewAt(const QPoint & pos)
00406 {
00407     QWidget *w = QApplication::topLevelAt(pos);
00408     if (w) {
00409         Plasma::View *v = qobject_cast<Plasma::View *>(w);
00410         return v;
00411     } else {
00412         return 0;
00413     }
00414 }
00415 
00416 } // namespace Plasma
00417 
00418 #include "view.moc"
00419 

Plasma

Skip menu "Plasma"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDEWebKit
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUnitConversion
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.7.3
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal