• Skip to content
  • Skip to link menu
KDE 4.7 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         q->setInteractive(true);
00115         q->setAcceptDrops(true);
00116         q->setAlignment(Qt::AlignLeft | Qt::AlignTop);
00117         q->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00118         q->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
00119     }
00120 
00121     static int s_maxViewId;
00122     //ugly but the only reliable way to do collision detection of ids
00123     static QSet<int> viewIds;
00124 
00125     Plasma::View *q;
00126     Plasma::Containment *containment;
00127     int viewId;
00128     int lastScreen;
00129     int lastDesktop;
00130     bool drawWallpaper : 1;
00131     bool trackChanges : 1;
00132     bool init : 1;
00133 };
00134 
00135 int ViewPrivate::s_maxViewId(0);
00136 QSet<int> ViewPrivate::viewIds;
00137 
00138 View::View(Containment *containment, QWidget *parent)
00139     : QGraphicsView(parent),
00140       d(new ViewPrivate(this, 0))
00141 {
00142     d->initGraphicsView();
00143 
00144     if (containment) {
00145         setScene(containment->scene());
00146         d->containment = containment;
00147         QTimer::singleShot(0, this, SLOT(privateInit()));
00148     }
00149 }
00150 
00151 View::View(Containment *containment, int viewId, QWidget *parent)
00152     : QGraphicsView(parent),
00153       d(new ViewPrivate(this, viewId))
00154 {
00155     d->initGraphicsView();
00156 
00157     if (containment) {
00158         setScene(containment->scene());
00159         d->containment = containment;
00160         QTimer::singleShot(0, this, SLOT(privateInit()));
00161     }
00162 }
00163 
00164 View::~View()
00165 {
00166     delete d;
00167     // FIXME FIX a focus crash but i wasn't able to reproduce in a simple test case for Qt guys
00168     //       NB: this is also done in Corona
00169     clearFocus();
00170 }
00171 
00172 void View::setScreen(int screen, int desktop)
00173 {
00174     if (screen < 0) {
00175         return;
00176     }
00177 
00178     // handle desktop views
00179     // -1 == All desktops
00180     if (desktop < -1 || desktop > KWindowSystem::numberOfDesktops() - 1) {
00181         desktop = -1;
00182     }
00183 
00184     d->lastScreen = screen;
00185     d->lastDesktop = desktop;
00186 
00187     // handle views that are working with panel containment types
00188     if (d->containment &&
00189         (d->containment->type() == Containment::PanelContainment ||
00190          d->containment->type() == Containment::CustomPanelContainment)) {
00191         d->containment->setScreen(screen, desktop);
00192         return;
00193     }
00194 
00195     Plasma::Corona *corona = qobject_cast<Plasma::Corona*>(scene());
00196     if (corona) {
00197         Containment *containment = corona->containmentForScreen(screen, desktop);
00198 
00199         if (containment) {
00200             d->containment = 0; //so that we don't end up on the old containment's screen
00201             setContainment(containment);
00202         }
00203     }
00204 }
00205 
00206 int View::screen() const
00207 {
00208     return d->lastScreen;
00209 }
00210 
00211 int View::desktop() const
00212 {
00213     if (d->containment) {
00214         return d->containment->desktop();
00215     }
00216 
00217     return d->lastDesktop;
00218 }
00219 
00220 int View::effectiveDesktop() const
00221 {
00222     int desk = desktop();
00223     return desk > -1 ? desk : KWindowSystem::currentDesktop();
00224 }
00225 
00226 void View::setContainment(Plasma::Containment *containment)
00227 {
00228     if (d->init && containment == d->containment) {
00229         return;
00230     }
00231 
00232     if (d->containment) {
00233         disconnect(d->containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed()));
00234         disconnect(d->containment, SIGNAL(geometryChanged()), this, SLOT(updateSceneRect()));
00235         disconnect(d->containment, SIGNAL(screenChanged(int, int, Plasma::Containment *)), this, SLOT(containmentScreenChanged(int, int, Plasma::Containment *)));
00236         d->containment->removeAssociatedWidget(this);
00237     }
00238 
00239     if (!containment) {
00240         d->containment = 0;
00241         return;
00242     }
00243 
00244     Containment *oldContainment = d->containment;
00245 
00246     int screen = d->lastScreen;
00247     int desktop = d->lastDesktop;
00248     if (oldContainment && oldContainment != containment) {
00249         screen = oldContainment->screen();
00250         desktop = oldContainment->desktop();
00251     } 
00252 
00253     if (scene() != containment->scene()) {
00254         setScene(containment->scene());
00255     }
00256 
00257     d->containment = containment;
00258 
00259     //add keyboard-shortcut actions
00260     d->containment->addAssociatedWidget(this);
00261 
00262     int otherScreen = containment->screen();
00263     int otherDesktop = containment->desktop();
00264 
00265     if (screen > -1) {
00266         d->lastScreen = screen;
00267         d->lastDesktop = desktop;
00268         //kDebug() << "set screen from setContainment due to old containment";
00269         if (oldContainment && oldContainment != containment) {
00270             oldContainment->setScreen(-1, -1);
00271         }
00272 
00273         if (screen != containment->screen() || desktop != containment->desktop()) {
00274             containment->setScreen(screen, desktop);
00275         }
00276     } else {
00277         d->lastScreen = otherScreen;
00278         d->lastDesktop = otherDesktop;
00279     }
00280 
00281     if (oldContainment && oldContainment != containment && otherScreen > -1 &&
00282         (!containment || otherScreen != containment->screen() || otherDesktop != containment->desktop())) {
00283         // assign the old containment the old screen/desktop
00284         //kDebug() << "set screen from setContainment" << screen << otherScreen << desktop << otherDesktop;
00285         oldContainment->setScreen(otherScreen, otherDesktop);
00286     }
00287 
00288 
00289     /*
00290     if (oldContainment) {
00291         kDebug() << "old" << (QObject*)oldContainment << screen << oldContainment->screen()
00292                  << "new" << (QObject*)containment << otherScreen << containment->screen();
00293     }
00294     */
00295 
00296     d->updateSceneRect();
00297     connect(containment, SIGNAL(destroyed(QObject*)), this, SLOT(containmentDestroyed()));
00298     connect(containment, SIGNAL(geometryChanged()), this, SLOT(updateSceneRect()));
00299     connect(containment, SIGNAL(screenChanged(int, int, Plasma::Containment *)), this, SLOT(containmentScreenChanged(int, int, Plasma::Containment *)));
00300 }
00301 
00302 Containment *View::containment() const
00303 {
00304     return d->containment;
00305 }
00306 
00307 Containment *View::swapContainment(const QString &name, const QVariantList &args)
00308 {
00309     return swapContainment(d->containment, name, args);
00310 }
00311 
00312 Containment *View::swapContainment(Plasma::Containment *existing, const QString &name, const QVariantList &args)
00313 {
00314     if (!existing) {
00315         return 0;
00316     }
00317 
00318     Containment *old = existing;
00319     Plasma::Corona *corona = old->corona();
00320     Plasma::Containment *c = corona->addContainmentDelayed(name, args);
00321     if (c) {
00322         c->init();
00323 
00324         KConfigGroup oldConfig = old->config();
00325         KConfigGroup newConfig = c->config();
00326 
00327         // ensure that the old containments configuration is up to date
00328         old->save(oldConfig);
00329 
00330         // Copy configuration to new containment
00331         oldConfig.copyTo(&newConfig);
00332 
00333         if (old == d->containment) {
00334             // set our containment to the new one, if the the old containment was us
00335             setContainment(c);
00336         }
00337 
00338         // load the configuration of the old containment into the new one
00339         c->restore(newConfig);
00340         c->updateConstraints(Plasma::StartupCompletedConstraint);
00341         c->flushPendingConstraintsEvents();
00342         emit corona->containmentAdded(c);
00343         foreach (Applet *applet, c->applets()) {
00344             applet->init();
00345             // We have to flush the applet constraints manually
00346             applet->flushPendingConstraintsEvents();
00347         }
00348 
00349         // destroy the old one
00350         old->destroy(false);
00351 
00352         // and now save the config
00353         c->save(newConfig);
00354         corona->requestConfigSync();
00355 
00356         return c;
00357     }
00358 
00359     return old;
00360 }
00361 
00362 KConfigGroup View::config() const
00363 {
00364     KConfigGroup views(KGlobal::config(), "PlasmaViews");
00365     return KConfigGroup(&views, QString::number(d->viewId));
00366 }
00367 
00368 void View::configNeedsSaving() const
00369 {
00370     Plasma::Corona *corona = qobject_cast<Plasma::Corona*>(scene());
00371     if (corona) {
00372         corona->requestConfigSync();
00373     } else {
00374         KGlobal::config()->sync();
00375     }
00376 }
00377 
00378 
00379 int View::id() const
00380 {
00381     return d->viewId;
00382 }
00383 
00384 void View::setWallpaperEnabled(bool draw)
00385 {
00386     d->drawWallpaper = draw;
00387 }
00388 
00389 bool View::isWallpaperEnabled() const
00390 {
00391     return d->drawWallpaper;
00392 }
00393 
00394 void View::setTrackContainmentChanges(bool trackChanges)
00395 {
00396     d->trackChanges = trackChanges;
00397 }
00398 
00399 bool View::trackContainmentChanges()
00400 {
00401     return d->trackChanges;
00402 }
00403 
00404 View * View::topLevelViewAt(const QPoint & pos)
00405 {
00406     QWidget *w = QApplication::topLevelAt(pos);
00407     if (w) {
00408         Plasma::View *v = qobject_cast<Plasma::View *>(w);
00409         return v;
00410     } else {
00411         return 0;
00412     }
00413 }
00414 
00415 } // namespace Plasma
00416 
00417 #include "view.moc"
00418 

Plasma

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

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • 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.5
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