00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "desktop.h"
00022
00023 #include <QAction>
00024 #include <QApplication>
00025 #include <QDesktopWidget>
00026 #include <QFile>
00027 #include <QFileInfo>
00028 #include <QGraphicsScene>
00029 #include <QGraphicsView>
00030 #include <QPainter>
00031 #include <QTimeLine>
00032
00033 #include <KAuthorized>
00034 #include <KComboBox>
00035 #include <KDebug>
00036 #include <KFileDialog>
00037 #include <KImageFilePreview>
00038 #include <KRun>
00039 #include <KStandardDirs>
00040 #include <KWindowSystem>
00041
00042 #include "plasma/corona.h"
00043 #include "plasma/appletbrowser.h"
00044 #include "plasma/animator.h"
00045 #include "plasma/theme.h"
00046 #include "kworkspace/kworkspace.h"
00047 #include "knewstuff2/engine.h"
00048
00049 #include "krunner_interface.h"
00050 #include "screensaver_interface.h"
00051 #include "ksmserver_interface.h"
00052
00053 #include "backgrounddialog.h"
00054
00055 using namespace Plasma;
00056
00057 DefaultDesktop::DefaultDesktop(QObject *parent, const QVariantList &args)
00058 : Containment(parent, args),
00059 m_lockDesktopAction(0),
00060 m_appletBrowserAction(0),
00061 m_addPanelAction(0),
00062 m_runCommandAction(0),
00063 m_lockScreenAction(0),
00064 m_logoutAction(0),
00065 m_configDialog(0),
00066 m_wallpaperPath(0),
00067 m_wallpaperPosition(0),
00068 m_renderer(resolution(), 1.0),
00069 m_rendererToken(-1)
00070 {
00071 qRegisterMetaType<QImage>("QImage");
00072 qRegisterMetaType<QPersistentModelIndex>("QPersistentModelIndex");
00073 connect(&m_renderer, SIGNAL(done(int, QImage)),
00074 this, SLOT(updateBackground(int, QImage)));
00075 connect(&m_slideshowTimer, SIGNAL(timeout()),
00076 this, SLOT(nextSlide()));
00077
00078 }
00079
00080 DefaultDesktop::~DefaultDesktop()
00081 {
00082 delete m_configDialog;
00083 }
00084
00085 void DefaultDesktop::nextSlide(bool skipUpdates)
00086 {
00087 if (++m_currentSlide >= m_slideFiles.size()) {
00088 m_currentSlide = 0;
00089 }
00090
00091 if (m_slideFiles.size() > 0) {
00092
00093
00094 if (m_slideFiles.size() > 1 && m_wallpaperPath == m_slideFiles[m_currentSlide]) {
00095
00096 if (++m_currentSlide >= m_slideFiles.size()) {
00097 m_currentSlide = 0;
00098 }
00099 }
00100
00101 m_wallpaperPath = m_slideFiles[m_currentSlide];
00102 if (!skipUpdates) {
00103 updateBackground();
00104 }
00105 }
00106 }
00107
00108 QSize DefaultDesktop::resolution() const
00109 {
00110 return QApplication::desktop()->screenGeometry(screen()).size();
00111 }
00112
00113 void DefaultDesktop::constraintsEvent(Plasma::Constraints constraints)
00114 {
00115 if (constraints & Plasma::StartupCompletedConstraint) {
00116 qsrand(QTime(0,0,0).secsTo(QTime::currentTime()));
00117 reloadConfig();
00118 }
00119
00120 if (constraints & Plasma::SizeConstraint) {
00121 m_renderer.setSize(size().toSize());
00122
00123 if (m_rendererToken != -1) {
00124
00125
00126 updateBackground();
00127 }
00128 }
00129
00130 if (constraints & Plasma::ImmutableConstraint && m_appletBrowserAction) {
00131
00132 bool locked = immutability() != Mutable;
00133 m_addPanelAction->setVisible(!locked);
00134 }
00135 }
00136
00137 void DefaultDesktop::configure()
00138 {
00139 KConfigGroup cg = config();
00140 KConfigGroup gcg = globalConfig();
00141 if (m_configDialog == 0) {
00142 const QSize resolution =
00143 QApplication::desktop()->screenGeometry(screen()).size();
00144 m_configDialog = new BackgroundDialog(resolution, cg, gcg, 0);
00145 connect(m_configDialog, SIGNAL(okClicked()),
00146 this, SLOT(applyConfig()));
00147 connect(m_configDialog, SIGNAL(applyClicked()),
00148 this, SLOT(applyConfig()));
00149 }
00150 else {
00151 m_configDialog->reloadConfig(cg, gcg);
00152 }
00153
00154 m_configDialog->show();
00155 KWindowSystem::setOnDesktop(m_configDialog->winId(), KWindowSystem::currentDesktop());
00156 KWindowSystem::activateWindow(m_configDialog->winId());
00157 }
00158
00159 void DefaultDesktop::applyConfig()
00160 {
00161 Q_ASSERT(m_configDialog);
00162 m_configDialog->saveConfig(config(), globalConfig());
00163 emit configNeedsSaving();
00164
00165 reloadConfig();
00166 }
00167
00168 void DefaultDesktop::reloadConfig()
00169 {
00170 KConfigGroup cg = config();
00171
00172
00173
00174 QString oldWallpaperPath(m_wallpaperPath);
00175 QColor old_wallpaperColor = m_wallpaperColor;
00176 int old_wallPaperPosition = m_wallpaperPosition;
00177
00178
00179
00180 m_wallpaperPath = cg.readEntry("wallpaper", QString());
00181 m_backgroundMode = cg.readEntry("backgroundmode", int(BackgroundDialog::kStaticBackground));
00182
00183 if (m_backgroundMode != BackgroundDialog::kNoBackground &&
00184 (m_wallpaperPath.isEmpty() || !KStandardDirs::exists(m_wallpaperPath))) {
00185 m_wallpaperPath = Plasma::Theme::defaultTheme()->wallpaperPath(size().toSize());
00186 cg.writeEntry("wallpaper", m_wallpaperPath);
00187 }
00188
00189 if (!m_wallpaperPath.isEmpty()) {
00190 kDebug() << "Using configured wallpaper" << m_wallpaperPath;
00191 }
00192
00193
00194 m_wallpaperPosition = cg.readEntry("wallpaperposition", int(Background::ScaleCrop));
00195 m_wallpaperColor = cg.readEntry("wallpapercolor", QColor(Qt::black));
00196
00197 if (m_backgroundMode == BackgroundDialog::kStaticBackground ||
00198 m_backgroundMode == BackgroundDialog::kNoBackground) {
00199 m_slideshowTimer.stop();
00200
00201
00202 if (oldWallpaperPath != m_wallpaperPath ||
00203 m_wallpaperPosition != old_wallPaperPosition ||
00204 m_wallpaperColor != old_wallpaperColor) {
00205 updateBackground();
00206 }
00207 } else {
00208 QStringList dirs = cg.readEntry("slidepaths", QStringList());
00209 QStringList filters;
00210 filters << "*.png" << "*.jpeg" << "*.jpg" << "*.svg" << "*.svgz";
00211
00212 m_slideFiles.clear();
00213
00214 for (int i = 0; i < dirs.size(); ++i) {
00215 QString path = dirs[i];
00216
00217 QDir dir(path);
00218 dir.setNameFilters(filters);
00219 dir.setFilter(QDir::Files | QDir::Hidden);
00220
00221 QFileInfoList files = dir.entryInfoList();
00222 foreach (const QFileInfo &wp, files) {
00223 int position = m_slideFiles.size() == 0 ? 0 : qrand() % m_slideFiles.size();
00224 m_slideFiles.insert(position, wp.filePath());
00225 }
00226
00227
00228 dir.setFilter(QDir::AllDirs | QDir::NoDotAndDotDot);
00229 QFileInfoList subdirs = dir.entryInfoList();
00230 foreach (const QFileInfo &wp, subdirs) {
00231 dirs.append(wp.filePath());
00232 }
00233 }
00234
00235 int delay = cg.readEntry("slideTimer", 60);
00236 m_slideshowTimer.setInterval(delay * 1000);
00237 if (!m_slideshowTimer.isActive()) {
00238 m_slideshowTimer.start();
00239 }
00240 m_currentSlide = -1;
00241 nextSlide(false);
00242 }
00243 }
00244
00245 void DefaultDesktop::updateBackground()
00246 {
00247 if (m_wallpaperPath.isEmpty() && m_backgroundMode != BackgroundDialog::kNoBackground) {
00248 m_wallpaperPath = Plasma::Theme::defaultTheme()->wallpaperPath(size().toSize());
00249 kDebug() << "Setting wallpaper to default" << m_wallpaperPath;
00250 emit configNeedsSaving();
00251 }
00252
00253 m_rendererToken =
00254 m_renderer.render(m_wallpaperPath,
00255 m_wallpaperColor,
00256 (Background::ResizeMethod)m_wallpaperPosition,
00257 Qt::SmoothTransformation);
00258 suspendStartup( true );
00259 }
00260
00261 void DefaultDesktop::updateBackground(int token, const QImage &img)
00262 {
00263 if (m_rendererToken == token) {
00264 m_bitmapBackground = QPixmap::fromImage(img);
00265 update();
00266 suspendStartup( false );
00267 }
00268 }
00269
00270 void DefaultDesktop::addPanel()
00271 {
00272 if (corona()) {
00273
00274 Containment* panel = corona()->addContainment("panel");
00275 panel->showConfigurationInterface();
00276
00277 panel->setScreen(screen());
00278 panel->setLocation(Plasma::TopEdge);
00279
00280
00281
00282 panel->updateConstraints(Plasma::StartupCompletedConstraint);
00283 panel->flushPendingConstraintsEvents();
00284 }
00285 }
00286
00287 void DefaultDesktop::runCommand()
00288 {
00289 if (!KAuthorized::authorizeKAction("run_command")) {
00290 return;
00291 }
00292
00293 QString interface("org.kde.krunner");
00294 org::kde::krunner::Interface krunner(interface, "/Interface",
00295 QDBusConnection::sessionBus());
00296 if (krunner.isValid()) {
00297 krunner.display();
00298 }
00299 }
00300
00301 void DefaultDesktop::suspendStartup(bool suspend)
00302 {
00303 org::kde::KSMServerInterface ksmserver("org.kde.ksmserver", "/KSMServer", QDBusConnection::sessionBus());
00304 const QString startupID("desktop wallaper");
00305 if (suspend) {
00306 ksmserver.suspendStartup(startupID);
00307 } else {
00308 ksmserver.resumeStartup(startupID);
00309 }
00310 }
00311
00312 void DefaultDesktop::lockScreen()
00313 {
00314 if (!KAuthorized::authorizeKAction("lock_screen")) {
00315 return;
00316 }
00317
00318 QString interface("org.freedesktop.ScreenSaver");
00319 org::freedesktop::ScreenSaver screensaver(interface, "/ScreenSaver",
00320 QDBusConnection::sessionBus());
00321 if (screensaver.isValid()) {
00322 screensaver.Lock();
00323 }
00324 }
00325
00326 QList<QAction*> DefaultDesktop::contextualActions()
00327 {
00328
00329
00330 if (!m_appletBrowserAction) {
00331 m_appletBrowserAction = action("add widgets");
00332
00333 m_addPanelAction = new QAction(i18n("Add Panel"), this);
00334 connect(m_addPanelAction, SIGNAL(triggered(bool)), this, SLOT(addPanel()));
00335 m_addPanelAction->setIcon(KIcon("list-add"));
00336
00337 m_runCommandAction = new QAction(i18n("Run Command..."), this);
00338 connect(m_runCommandAction, SIGNAL(triggered(bool)), this, SLOT(runCommand()));
00339 m_runCommandAction->setIcon(KIcon("system-run"));
00340
00341 m_setupDesktopAction = new QAction(i18n("Desktop Settings..."), this);
00342 m_setupDesktopAction->setIcon(KIcon("configure"));
00343 connect(m_setupDesktopAction, SIGNAL(triggered()), this, SLOT(configure()));
00344
00345 m_lockDesktopAction = action("lock widgets");
00346
00347 m_lockScreenAction = new QAction(i18n("Lock Screen"), this);
00348 m_lockScreenAction->setIcon(KIcon("system-lock-screen"));
00349 connect(m_lockScreenAction, SIGNAL(triggered(bool)), this, SLOT(lockScreen()));
00350
00351 m_logoutAction = new QAction(i18n("Leave..."), this);
00352 m_logoutAction->setIcon(KIcon("system-shutdown"));
00353 connect(m_logoutAction, SIGNAL(triggered(bool)), this, SLOT(logout()));
00354 constraintsEvent(Plasma::ImmutableConstraint);
00355
00356 m_separator = new QAction(this);
00357 m_separator->setSeparator(true);
00358
00359 m_separator2 = new QAction(this);
00360 m_separator2->setSeparator(true);
00361 }
00362
00363 QList<QAction*> actions;
00364
00365 if (KAuthorized::authorizeKAction("run_command")) {
00366 actions.append(m_runCommandAction);
00367 }
00368
00369 actions.append(m_appletBrowserAction);
00370 actions.append(m_addPanelAction);
00371 actions.append(m_setupDesktopAction);
00372 if (screen() == -1) {
00373 actions.append(action("remove"));
00374 }
00375
00376 actions.append(m_lockDesktopAction);
00377
00378 actions.append(m_separator);
00379
00380 if (KAuthorized::authorizeKAction("lock_screen")) {
00381 actions.append(m_lockScreenAction);
00382 }
00383
00384 if (KAuthorized::authorizeKAction("logout")) {
00385 actions.append(m_logoutAction);
00386 }
00387
00388 return actions;
00389 }
00390
00391 void DefaultDesktop::logout()
00392 {
00393 if (!KAuthorized::authorizeKAction("logout")) {
00394 return;
00395 }
00396 KWorkSpace::requestShutDown(KWorkSpace::ShutdownConfirmDefault,
00397 KWorkSpace::ShutdownTypeDefault,
00398 KWorkSpace::ShutdownModeDefault);
00399 }
00400
00401 void DefaultDesktop::paintInterface(QPainter *painter,
00402 const QStyleOptionGraphicsItem *option,
00403 const QRect& contentsRect)
00404 {
00405
00406 if (m_bitmapBackground.isNull()) {
00407 Containment::paintInterface(painter, option, contentsRect);
00408 return;
00409 }
00410
00411 painter->save();
00412
00413 if (painter->worldMatrix() == QMatrix()) {
00414
00415 painter->resetTransform();
00416 }
00417
00418
00419 painter->setCompositionMode(QPainter::CompositionMode_Source);
00420
00421
00422
00423 painter->drawPixmap(option->exposedRect, m_bitmapBackground, option->exposedRect);
00424
00425
00426
00427 painter->restore();
00428 }
00429
00430 K_EXPORT_PLASMA_APPLET(desktop, DefaultDesktop)
00431
00432 #include "desktop.moc"