• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • API Reference
  • Sitemap
  • Contact Us
 

Plasma

desktop.cpp

Go to the documentation of this file.
00001 /*
00002 *   Copyright 2007 by Aaron Seigo <aseigo@kde.org>
00003 *   Copyright 2008 by Alexis Ménard <darktears31@gmail.com>
00004 *
00005 *
00006 *   This program is free software; you can redistribute it and/or modify
00007 *   it under the terms of the GNU Library General Public License version 2,
00008 *   or (at your option) any later version.
00009 *
00010 *   This program is distributed in the hope that it will be useful,
00011 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 *   GNU General Public License for more details
00014 *
00015 *   You should have received a copy of the GNU Library General Public
00016 *   License along with this program; if not, write to the
00017 *   Free Software Foundation, Inc.,
00018 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
00019 */
00020 
00021 #include "desktop.h"
00022 
00023 #include <limits>
00024 
00025 #include <QAction>
00026 #include <QGraphicsProxyWidget>
00027 #include <QFile>
00028 #include <QFileInfo>
00029 #include <QGraphicsScene>
00030 #include <QGraphicsView>
00031 #include <QPainter>
00032 #include <QTimeLine>
00033 
00034 #include <KAuthorized>
00035 #include <KComboBox>
00036 #include <KDebug>
00037 #include <KFileDialog>
00038 #include <KImageFilePreview>
00039 #include <KRun>
00040 #include <KStandardDirs>
00041 #include <KWindowSystem>
00042 
00043 #include <Plasma/Corona>
00044 #include <Plasma/Animator>
00045 #include <Plasma/Theme>
00046 #include "kworkspace/kworkspace.h"
00047 #include "knewstuff2/engine.h"
00048 
00049 #include "krunner_interface.h"
00050 #include "screensaver_interface.h"
00051 
00052 #ifdef Q_OS_WIN
00053 #define _WIN32_WINNT 0x0500 // require NT 5.0 (win 2k pro)
00054 #include <windows.h>
00055 #endif // Q_OS_WIN
00056 
00057 using namespace Plasma;
00058 
00059 DefaultDesktop::DefaultDesktop(QObject *parent, const QVariantList &args)
00060     : Containment(parent, args),
00061       m_lockDesktopAction(0),
00062       m_appletBrowserAction(0),
00063       m_addPanelAction(0),
00064       m_runCommandAction(0),
00065       m_lockScreenAction(0),
00066       m_logoutAction(0),
00067       dropping(false)
00068 {
00069     qRegisterMetaType<QImage>("QImage");
00070     qRegisterMetaType<QPersistentModelIndex>("QPersistentModelIndex");
00071     connect(this, SIGNAL(appletAdded(Plasma::Applet *, const QPointF &)),
00072             this, SLOT(onAppletAdded(Plasma::Applet *, const QPointF &)));
00073     connect(this, SIGNAL(appletRemoved(Plasma::Applet *)),
00074             this, SLOT(onAppletRemoved(Plasma::Applet *)));
00075 
00076     m_layout = new DesktopLayout;
00077     m_layout->setAutoWorkingArea(false);
00078     m_layout->setAlignment(Qt::AlignTop|Qt::AlignLeft);
00079     m_layout->setPlacementSpacing(20);
00080     m_layout->setScreenSpacing(5);
00081     m_layout->setShiftingSpacing(0);
00082     m_layout->setTemporaryPlacement(true);
00083     m_layout->setVisibilityTolerance(0.5);
00084     setLayout(m_layout);
00085 
00086     resize(800, 600);
00087     //kDebug() << "!!! loading desktop";
00088 }
00089 
00090 void DefaultDesktop::constraintsEvent(Plasma::Constraints constraints)
00091 {
00092     if (constraints & Plasma::ImmutableConstraint && m_appletBrowserAction) {
00093         // we need to update the menu items that have already been created
00094         bool locked = immutability() != Mutable;
00095         m_addPanelAction->setVisible(!locked);
00096     }
00097 
00098     if (constraints & Plasma::StartupCompletedConstraint) {
00099         connect(corona(), SIGNAL(availableScreenRegionChanged()),
00100                 this, SLOT(refreshWorkingArea()));
00101         refreshWorkingArea();
00102     }
00103 }
00104 
00105 void DefaultDesktop::addPanel()
00106 {
00107     if (corona()) {
00108         // make a panel at the top
00109         Containment* panel = corona()->addContainment("panel");
00110         panel->showConfigurationInterface();
00111 
00112         panel->setScreen(screen());
00113 
00114         QList<Plasma::Location> freeEdges = corona()->freeEdges(screen());
00115         kDebug() << freeEdges;
00116         Plasma::Location destination;
00117         if (freeEdges.contains(Plasma::TopEdge)) {
00118             destination = Plasma::TopEdge;
00119         } else if (freeEdges.contains(Plasma::BottomEdge)) {
00120             destination = Plasma::BottomEdge;
00121         } else if (freeEdges.contains(Plasma::LeftEdge)) {
00122             destination = Plasma::LeftEdge;
00123         } else if (freeEdges.contains(Plasma::RightEdge)) {
00124             destination = Plasma::RightEdge;
00125         } else destination = Plasma::TopEdge;
00126 
00127         panel->setLocation(destination);
00128 
00129         // trigger an instant layout so we immediately have a proper geometry
00130         // rather than waiting around for the event loop
00131         panel->updateConstraints(Plasma::StartupCompletedConstraint);
00132         panel->flushPendingConstraintsEvents();
00133 
00134         if (destination == Plasma::LeftEdge || destination == Plasma::RightEdge) {
00135             panel->setMinimumSize(10, 35);
00136             panel->setMaximumSize(35, corona()->screenGeometry(screen()).height());
00137             panel->resize(QSize(35, corona()->screenGeometry(screen()).height()));
00138         }
00139 
00140     }
00141 }
00142 
00143 void DefaultDesktop::runCommand()
00144 {
00145     if (!KAuthorized::authorizeKAction("run_command")) {
00146         return;
00147     }
00148 
00149     QString interface("org.kde.krunner");
00150     org::kde::krunner::App krunner(interface, "/App", QDBusConnection::sessionBus());
00151     krunner.display();
00152 }
00153 
00154 void DefaultDesktop::lockScreen()
00155 {
00156     if (!KAuthorized::authorizeKAction("lock_screen")) {
00157         return;
00158     }
00159 
00160 #ifndef Q_OS_WIN
00161     QString interface("org.freedesktop.ScreenSaver");
00162     org::freedesktop::ScreenSaver screensaver(interface, "/ScreenSaver",
00163                                               QDBusConnection::sessionBus());
00164     if (screensaver.isValid()) {
00165         screensaver.Lock();
00166     }
00167 #else
00168     LockWorkStation();
00169 #endif // !Q_OS_WIN
00170 }
00171 
00172 QList<QAction*> DefaultDesktop::contextualActions()
00173 {
00174     //TODO: should we offer "Switch User" here?
00175 
00176     if (!m_appletBrowserAction) {
00177         m_appletBrowserAction = action("add widgets");
00178 
00179         m_addPanelAction = new QAction(i18n("Add Panel"), this);
00180         connect(m_addPanelAction, SIGNAL(triggered(bool)), this, SLOT(addPanel()));
00181         m_addPanelAction->setIcon(KIcon("list-add"));
00182 
00183         m_runCommandAction = new QAction(i18n("Run Command..."), this);
00184         connect(m_runCommandAction, SIGNAL(triggered(bool)), this, SLOT(runCommand()));
00185         m_runCommandAction->setIcon(KIcon("system-run"));
00186 
00187         m_setupDesktopAction = action("activity settings");
00188         m_lockDesktopAction = action("lock widgets");
00189 
00190         m_lockScreenAction = new QAction(i18n("Lock Screen"), this);
00191         m_lockScreenAction->setIcon(KIcon("system-lock-screen"));
00192         connect(m_lockScreenAction, SIGNAL(triggered(bool)), this, SLOT(lockScreen()));
00193 
00194         m_logoutAction = new QAction(i18n("Leave..."), this);
00195         m_logoutAction->setIcon(KIcon("system-shutdown"));
00196         connect(m_logoutAction, SIGNAL(triggered(bool)), this, SLOT(logout()));
00197         constraintsEvent(Plasma::ImmutableConstraint);
00198 
00199         m_separator = new QAction(this);
00200         m_separator->setSeparator(true);
00201     }
00202 
00203     QList<QAction*> actions;
00204 
00205     if (KAuthorized::authorizeKAction("run_command")) {
00206         actions.append(m_runCommandAction);
00207     }
00208 
00209     actions.append(m_appletBrowserAction);
00210     actions.append(m_addPanelAction);
00211     actions.append(m_setupDesktopAction);
00212     if (screen() == -1) {
00213         actions.append(action("remove"));
00214     }
00215 
00216     actions.append(m_lockDesktopAction);
00217 
00218     actions.append(m_separator);
00219 
00220     if (KAuthorized::authorizeKAction("lock_screen")) {
00221         actions.append(m_lockScreenAction);
00222     }
00223 
00224     if (KAuthorized::authorizeKAction("logout")) {
00225         actions.append(m_logoutAction);
00226     }
00227 
00228     return actions;
00229 }
00230 
00231 void DefaultDesktop::logout()
00232 {
00233     if (!KAuthorized::authorizeKAction("logout")) {
00234         return;
00235     }
00236 #ifndef Q_WS_WIN
00237     KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault,
00238                                 KWorkSpace::ShutdownTypeDefault,
00239                                 KWorkSpace::ShutdownModeDefault);
00240 #endif
00241 }
00242 
00243 void DefaultDesktop::onAppletAdded(Plasma::Applet *applet, const QPointF &pos)
00244 {
00245     if (dropping || pos != QPointF(-1,-1) || applet->geometry().topLeft() != QPointF(0,0)) {
00246         // add item to the layout using the current position
00247         m_layout->addItem(applet, true, applet->geometry());
00248     } else {
00249         /*
00250             There seems to be no uniform way to get the applet's preferred size.
00251             Regular applets properly set their current size when created, but report useless size hints.
00252             Proxy widget applets don't set their size properly, but report valid size hints. However, they
00253             will obtain proper size if we just re-set the geometry to the current value.
00254         */
00255         applet->setGeometry(applet->geometry());
00256         m_layout->addItem(applet, true, applet->geometry().size());
00257     }
00258 
00259     connect(applet, SIGNAL(geometryChanged()), this, SLOT(onAppletGeometryChanged()));
00260 }
00261 
00262 void DefaultDesktop::onAppletRemoved(Plasma::Applet *applet)
00263 {
00264     for (int i=0; i < m_layout->count(); i++) {
00265         if (applet == m_layout->itemAt(i)) {
00266             m_layout->removeAt(i);
00267             return;
00268         }
00269     }
00270 }
00271 
00272 void DefaultDesktop::onAppletGeometryChanged()
00273 {
00274     m_layout->itemGeometryChanged((Applet *)sender());
00275 }
00276 
00277 void DefaultDesktop::refreshWorkingArea()
00278 {
00279     Corona *c = corona();
00280     if (!c) {
00281         //kDebug() << "no corona?!";
00282         return;
00283     }
00284 
00285     QRectF workingGeom;
00286     if (screen() != -1) {
00287         // we are associated with a screen, make sure not to overlap panels
00288         workingGeom = c->availableScreenRegion(screen()).boundingRect();
00289         //kDebug() << "got" << workingGeom;
00290         // From screen coordinates to containment coordinates
00291         workingGeom.translate(-c->screenGeometry(screen()).topLeft());
00292     } else {
00293         workingGeom = geometry();
00294         workingGeom = mapFromScene(workingGeom).boundingRect();
00295         //kDebug() << "defaults due to no screen; got:" << workingGeom;
00296     }
00297 
00298     if (workingGeom != QRectF()) {
00299         //kDebug() << "!!!!!!!!!!!!! workingGeom is" << workingGeom;
00300         m_layout->setWorkingArea(workingGeom);
00301     }
00302 }
00303 
00304 void DefaultDesktop::dropEvent(QGraphicsSceneDragDropEvent *event)
00305 {
00306     dropping = true;
00307     Containment::dropEvent(event);
00308     dropping = false;
00309 }
00310 
00311 K_EXPORT_PLASMA_APPLET(desktop, DefaultDesktop)
00312 
00313 #include "desktop.moc"

Plasma

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

API Reference

Skip menu "API Reference"
  • KWin
  •   KWin Libraries
  • Libraries
  •   libkworkspace
  •   libsolidcontrol
  •   libtaskmanager
  • Plasma
  •   Animators
  •   Applets
  •   Engines
  • Solid Modules
Generated for API Reference by doxygen 1.5.7
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