diff --git a/ksmserver/CMakeLists.txt b/ksmserver/CMakeLists.txt
index 295b96e..4bdb5ae 100644
--- a/ksmserver/CMakeLists.txt
+++ b/ksmserver/CMakeLists.txt
@@ -54,6 +54,7 @@ kde4_add_kdeinit_executable( ksmserver ${ksmserver_KDEINIT_SRCS})
 
 target_link_libraries(kdeinit_ksmserver ${KDE4_PLASMA_LIBS} kworkspace
    ${KDE4_KDEUI_LIBS} ${KDE4_KIO_LIBS} ${QIMAGEBLITZ_LIBRARIES} ${KDE4_SOLID_LIBS} ${X11_LIBRARIES} ${X11_Xrender_LIB}
+   ${QT_QTDECLARATIVE_LIBRARY} kdeclarative
 )
 
 install(TARGETS kdeinit_ksmserver ${INSTALL_TARGETS_DEFAULT_ARGS})
@@ -76,3 +77,4 @@ install(TARGETS kcheckrunning ${INSTALL_TARGETS_DEFAULT_ARGS})
 install( FILES ksmserver.upd ksmserver_shortcuts.upd DESTINATION  ${KCONF_UPDATE_INSTALL_DIR} )
 install( PROGRAMS move_session_config.sh DESTINATION  ${KCONF_UPDATE_INSTALL_DIR} )
 install( FILES org.kde.KSMServerInterface.xml DESTINATION ${DBUS_INTERFACES_INSTALL_DIR})
+install( DIRECTORY qml/ DESTINATION ${DATA_INSTALL_DIR}/ksmserver/qml )
diff --git a/ksmserver/qml/ContextMenu.qml b/ksmserver/qml/ContextMenu.qml
new file mode 100644
index 0000000..839afdf
--- /dev/null
+++ b/ksmserver/qml/ContextMenu.qml
@@ -0,0 +1,112 @@
+/*
+*   Copyright (C) 2011 by Marco Martin <mart@kde.org>
+*   Copyright (C) 2011 by Lamarque V. Souza <lamarque@kde.org>
+*
+*   This program is free software; you can redistribute it and/or modify
+*   it under the terms of the GNU Library General Public License as
+*   published by the Free Software Foundation; either version 2, or
+*   (at your option) any later version.
+*
+*   This program is distributed in the hope that it will be useful,
+*   but WITHOUT ANY WARRANTY; without even the implied warranty of
+*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*   GNU Library General Public License for more details
+*
+*   You should have received a copy of the GNU Library General Public
+*   License along with this program; if not, write to the
+*   Free Software Foundation, Inc.,
+*   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+*/
+
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.plasma.components 0.1 as PlasmaComponents
+
+Item {
+    id: root
+
+    property Item visualParent
+    property int status: PlasmaComponents.DialogStatus.Closed
+    signal clicked(int index)
+
+    function append(dict)
+    {
+        listModel.append(dict)
+    }
+
+    function open()
+    {
+        var parent = root.visualParent ? root.visualParent : root.parent
+        var pos = dialog.popupPosition(parent, Qt.alignCenter)
+        dialog.x = pos.x
+        dialog.y = pos.y
+
+        dialog.visible = true
+        dialog.activateWindow()
+    }
+
+    function close()
+    {
+        dialog.visible = false
+    }
+
+    visible: false
+
+    ListModel {
+         id: listModel
+    }
+
+    PlasmaCore.Dialog {
+        id: dialog
+        visible: false
+        windowFlags: Qt.Popup
+        onVisibleChanged: {
+            if (visible) {
+                status = PlasmaComponents.DialogStatus.Open
+            } else {
+                status = PlasmaComponents.DialogStatus.Closed
+            }
+        }
+
+        mainItem: Item {
+            id: contentItem
+
+            width: listView.width
+            height: Math.min(listView.contentHeight, theme.defaultFont.mSize.height * 25)
+
+            ListView {
+                id: listView
+                anchors.fill: parent
+
+                currentIndex : -1
+                clip: true
+
+                model: listModel
+                delegate: MenuItem {
+                    text: itemText
+                    index: itemIndex
+                    Component.onCompleted: {
+                        contentItem.width = Math.max(contentItem.width, theme.defaultFont.mSize.width * text.length)
+                    }
+                    onClicked: {
+                        root.clicked(index)
+                        root.close()
+                    }
+                }
+            }
+        }
+    }
+
+    onStatusChanged: {
+        if (status == PlasmaComponents.DialogStatus.Opening) {
+            if (listView.currentItem != null) {
+                listView.currentItem.focus = false
+            }
+            listView.currentIndex = -1
+            listView.positionViewAtIndex(0, ListView.Beginning)
+        }
+        else if (status == PlasmaComponents.DialogStatus.Open) {
+            listView.focus = true
+        }
+    }
+}
diff --git a/ksmserver/qml/KSMButton.qml b/ksmserver/qml/KSMButton.qml
new file mode 100644
index 0000000..9aac26c
--- /dev/null
+++ b/ksmserver/qml/KSMButton.qml
@@ -0,0 +1,128 @@
+/*
+    Copyright (C) 2011  Lamarque Souza <lamarque@kde.org>
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License along
+    with this program; if not, write to the Free Software Foundation, Inc.,
+    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+*/
+
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.plasma.components 0.1 as PlasmaComponents
+import org.kde.qtextracomponents 0.1
+
+PlasmaCore.FrameSvgItem {
+    id: button
+    property string iconSource
+    property alias text: labelElement.text
+    property bool smallButton: false
+    property bool focusedButton: false
+    property bool menu: false
+    property ContextMenu contextMenu
+
+    signal clicked()
+    signal pressed()
+    signal pressAndHold()
+
+    PlasmaCore.Theme {
+        id: theme
+    }
+
+    PlasmaCore.SvgItem {
+        id: background
+        anchors.fill: parent
+
+        svg: PlasmaCore.Svg {
+            imagePath: "dialogs/shutdowndialog"
+        }
+        elementId: "button-normal"
+    }
+
+    PlasmaComponents.Label {
+        id: labelElement
+        color: theme.textColor
+        anchors {
+            verticalCenter: parent.verticalCenter
+            left: parent.left
+            leftMargin: 5
+        }
+
+        onPaintedWidthChanged: {
+            button.width = Math.max(button.width, 5 + labelElement.width + 10 + iconElement.width + 5)
+        }
+    }
+
+    QIconItem {
+        id: menuIconElement
+
+        // if textColor is closer to white than to black use "draw-triangle4", which is also close to white.
+        // Otherwise use "arrow-down", which is green. I have not found a black triangle icon.
+        icon: theme.textColor > "#7FFFFF" ? QIcon("draw-triangle4") : QIcon("arrow-down")
+
+        width: 6
+        height: width
+        visible: button.menu
+
+        anchors {
+            right: iconElement.left
+            rightMargin: 2
+            bottom: parent.bottom
+            bottomMargin: 2
+        }
+    }
+
+    QIconItem {
+        id: iconElement
+        icon: QIcon(iconSource)
+        width: height
+        height: parent.height - 6
+
+        anchors {
+            verticalCenter: parent.verticalCenter
+            right: parent.right
+            rightMargin: 3
+        }
+    }
+
+    Component.onCompleted: {
+        if (focusedButton) {
+            background.elementId = button.smallButton ? "button-small-hover" : "button-hover"
+        } else {
+            background.elementId = button.smallButton ? "button-small-normal" : "button-normal"
+        }
+    }
+
+    onFocusedButtonChanged: {
+        if (focusedButton) {
+            background.elementId = button.smallButton ? "button-small-hover" : "button-hover"
+        } else {
+            background.elementId = button.smallButton ? "button-small-normal" : "button-normal"
+        }
+    }
+
+    MouseArea {
+        anchors.fill: parent
+        hoverEnabled: true
+        onClicked: button.clicked()
+        onPressed: button.pressed()
+        onPressAndHold: button.pressAndHold()
+        onEntered: {
+            background.elementId = button.smallButton ? "button-small-hover" : "button-hover"
+        }
+        onExited: {
+            if (!focusedButton) {
+                background.elementId = button.smallButton ? "button-small-normal" : "button-normal"
+            }
+        }
+    }
+}
diff --git a/ksmserver/qml/MenuItem.qml b/ksmserver/qml/MenuItem.qml
new file mode 100644
index 0000000..d89eb64
--- /dev/null
+++ b/ksmserver/qml/MenuItem.qml
@@ -0,0 +1,114 @@
+/****************************************************************************
+**
+** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
+** All rights reserved.
+** Contact: Nokia Corporation (qt-info@nokia.com)
+**
+** This file is part of the Qt Components project.
+**
+** $QT_BEGIN_LICENSE:BSD$
+** You may use this file under the terms of the BSD license as follows:
+**
+** "Redistribution and use in source and binary forms, with or without
+** modification, are permitted provided that the following conditions are
+** met:
+**   * Redistributions of source code must retain the above copyright
+**     notice, this list of conditions and the following disclaimer.
+**   * Redistributions in binary form must reproduce the above copyright
+**     notice, this list of conditions and the following disclaimer in
+**     the documentation and/or other materials provided with the
+**     distribution.
+**   * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
+**     the names of its contributors may be used to endorse or promote
+**     products derived from this software without specific prior written
+**     permission.
+**
+** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.plasma.components 0.1 as PlasmaComponents
+
+Item {
+    id: root
+
+    property alias text: textArea.text
+    property int index: 0
+
+    signal clicked
+
+    property int implicitWidth: textArea.paintedWidth + 6
+    width: parent.width
+    height: textArea.paintedHeight + 6
+
+    PlasmaComponents.Label {
+        id: textArea
+        anchors.centerIn: parent
+        horizontalAlignment: Text.AlignHCenter
+        elide: Text.ElideRight
+    }
+
+    MouseArea {
+        id: mouseArea
+
+        property bool canceled: false
+
+        anchors.fill: parent
+
+        onPressed: {
+            canceled = false
+        }
+        onClicked: {
+            if (!canceled)
+                root.clicked()
+        }
+        onExited: canceled = true
+    }
+
+    Keys.onPressed: {
+        event.accepted = true
+        switch (event.key) {
+            case Qt.Key_Select:
+            case Qt.Key_Enter:
+            case Qt.Key_Return: {
+                if (!event.isAutoRepeat) {
+                        root.clicked()
+                }
+                break
+            }
+
+            case Qt.Key_Up: {
+                    if (ListView.view != null)
+                        ListView.view.decrementCurrentIndex()
+                    else
+                        event.accepted = false
+                break
+            }
+
+            case Qt.Key_Down: {
+                    if (ListView.view != null)
+                        ListView.view.incrementCurrentIndex()
+                    else
+                        event.accepted = false
+                break
+            }
+            default: {
+                event.accepted = false
+                break
+            }
+        }
+    }
+}
diff --git a/ksmserver/qml/contour.qml b/ksmserver/qml/contour.qml
new file mode 100644
index 0000000..b21f83f
--- /dev/null
+++ b/ksmserver/qml/contour.qml
@@ -0,0 +1,166 @@
+/*
+ *   Copyright 2011 Lamarque V. Souza <lamarque@kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2 or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Library General Public License for more details
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+import QtQuick 1.0
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.plasma.graphicswidgets 0.1
+import org.kde.qtextracomponents 0.1
+
+PlasmaCore.FrameSvgItem {
+    id: shutdownUi
+    property int iconSize: 128
+    property int realMarginTop: margins.top
+    property int realMarginBottom: margins.bottom
+    property int realMarginLeft: margins.left
+    property int realMarginRight: margins.right
+    width: realMarginLeft + iconRow.width + realMarginRight
+    height: realMarginTop + iconRow.height + realMarginBottom
+
+    imagePath: "dialogs/shutdowndialog"
+
+    signal logoutRequested()
+    signal haltRequested()
+    signal suspendRequested(int spdMethod)
+    signal rebootRequested()
+    signal rebootRequested2(int opt)
+    signal cancelRequested()
+    signal lockScreenRequested()
+
+    PlasmaCore.Theme {
+        id: theme
+    }
+
+    PlasmaCore.SvgItem {
+        id: background
+
+        anchors {
+            top: parent.top
+            topMargin: realMarginTop
+            bottom: parent.bottom
+            bottomMargin: realMarginBottom
+            left: parent.left
+            leftMargin: realMarginLeft
+            right: parent.right
+            rightMargin: realMarginRight
+        }
+
+        svg: PlasmaCore.Svg {
+            imagePath: "dialogs/shutdowndialog"
+        }
+        elementId: "center"
+    }
+
+    Component.onCompleted: {
+        if (margins.left == 0) {
+            realMarginTop = 9
+            realMarginBottom = 7
+            realMarginLeft = 12
+            realMarginRight = 12
+        }
+        if (background.naturalSize.width < 1) {
+            background.elementId = "background"
+            shutdownUi.width += realMarginLeft + realMarginRight
+            shutdownUi.height += realMarginTop + realMarginBottom
+        }
+    }
+
+    Row {
+        id: iconRow
+        spacing: 5
+        anchors.verticalCenter: parent.verticalCenter
+        anchors.horizontalCenter: parent.horizontalCenter
+        Column {
+            Text {
+                id: lockScreenLabel
+                text: i18n("lock")
+                anchors.horizontalCenter: lockScreenIcon.horizontalCenter
+                color: theme.textColor
+                font.pixelSize: 18
+                // Use theme.defaultFont in plasma-mobile and
+                // theme.font in plasma-desktop.
+                font.family: theme.defaultFont.family
+                font.bold: theme.defaultFont.bold
+                font.capitalization: theme.defaultFont.capitalization
+                font.italic: theme.defaultFont.italic
+                font.weight: theme.defaultFont.weight
+                font.underline: theme.defaultFont.underline
+                font.wordSpacing: theme.defaultFont.wordSpacing
+            }
+            IconWidget {
+                id: lockScreenIcon
+                icon: QIcon("system-lock-screen")
+                minimumIconSize: "128x128"
+
+                onClicked: {
+                    lockScreenRequested();
+                }
+            }
+        }
+
+        Column {
+            Text {
+                text: i18n("sleep")
+                anchors.horizontalCenter: sleepIcon.horizontalCenter
+                color: theme.textColor
+                font.pixelSize: 18
+                font.family: theme.defaultFont.family
+                font.bold: theme.defaultFont.bold
+                font.capitalization: theme.defaultFont.capitalization
+                font.italic: theme.defaultFont.italic
+                font.weight: theme.defaultFont.weight
+                font.underline: theme.defaultFont.underline
+                font.wordSpacing: theme.defaultFont.wordSpacing
+            }
+            IconWidget {
+                id: sleepIcon
+                icon: QIcon("system-suspend")
+                minimumIconSize: "128x128"
+
+                onClicked: {
+                    suspendRequested(2); // Solid::PowerManagement::SuspendState
+                }
+            }
+        }
+
+        Column {
+            Text {
+                text: i18n("turn off")
+                anchors.horizontalCenter: shutdownIcon.horizontalCenter
+                color: theme.textColor
+                font.pixelSize: 18
+                font.family: theme.defaultFont.family
+                font.bold: theme.defaultFont.bold
+                font.capitalization: theme.defaultFont.capitalization
+                font.italic: theme.defaultFont.italic
+                font.weight: theme.defaultFont.weight
+                font.underline: theme.defaultFont.underline
+                font.wordSpacing: theme.defaultFont.wordSpacing
+            }
+            IconWidget {
+                id: shutdownIcon
+                icon: QIcon("system-shutdown")
+                minimumIconSize: "128x128"
+
+                onClicked: {
+                    haltRequested()
+                }
+            }
+        }
+    }
+}
diff --git a/ksmserver/qml/default.qml b/ksmserver/qml/default.qml
new file mode 100644
index 0000000..b21f83f
--- /dev/null
+++ b/ksmserver/qml/default.qml
@@ -0,0 +1,166 @@
+/*
+ *   Copyright 2011 Lamarque V. Souza <lamarque@kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2 or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Library General Public License for more details
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+import QtQuick 1.0
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.plasma.graphicswidgets 0.1
+import org.kde.qtextracomponents 0.1
+
+PlasmaCore.FrameSvgItem {
+    id: shutdownUi
+    property int iconSize: 128
+    property int realMarginTop: margins.top
+    property int realMarginBottom: margins.bottom
+    property int realMarginLeft: margins.left
+    property int realMarginRight: margins.right
+    width: realMarginLeft + iconRow.width + realMarginRight
+    height: realMarginTop + iconRow.height + realMarginBottom
+
+    imagePath: "dialogs/shutdowndialog"
+
+    signal logoutRequested()
+    signal haltRequested()
+    signal suspendRequested(int spdMethod)
+    signal rebootRequested()
+    signal rebootRequested2(int opt)
+    signal cancelRequested()
+    signal lockScreenRequested()
+
+    PlasmaCore.Theme {
+        id: theme
+    }
+
+    PlasmaCore.SvgItem {
+        id: background
+
+        anchors {
+            top: parent.top
+            topMargin: realMarginTop
+            bottom: parent.bottom
+            bottomMargin: realMarginBottom
+            left: parent.left
+            leftMargin: realMarginLeft
+            right: parent.right
+            rightMargin: realMarginRight
+        }
+
+        svg: PlasmaCore.Svg {
+            imagePath: "dialogs/shutdowndialog"
+        }
+        elementId: "center"
+    }
+
+    Component.onCompleted: {
+        if (margins.left == 0) {
+            realMarginTop = 9
+            realMarginBottom = 7
+            realMarginLeft = 12
+            realMarginRight = 12
+        }
+        if (background.naturalSize.width < 1) {
+            background.elementId = "background"
+            shutdownUi.width += realMarginLeft + realMarginRight
+            shutdownUi.height += realMarginTop + realMarginBottom
+        }
+    }
+
+    Row {
+        id: iconRow
+        spacing: 5
+        anchors.verticalCenter: parent.verticalCenter
+        anchors.horizontalCenter: parent.horizontalCenter
+        Column {
+            Text {
+                id: lockScreenLabel
+                text: i18n("lock")
+                anchors.horizontalCenter: lockScreenIcon.horizontalCenter
+                color: theme.textColor
+                font.pixelSize: 18
+                // Use theme.defaultFont in plasma-mobile and
+                // theme.font in plasma-desktop.
+                font.family: theme.defaultFont.family
+                font.bold: theme.defaultFont.bold
+                font.capitalization: theme.defaultFont.capitalization
+                font.italic: theme.defaultFont.italic
+                font.weight: theme.defaultFont.weight
+                font.underline: theme.defaultFont.underline
+                font.wordSpacing: theme.defaultFont.wordSpacing
+            }
+            IconWidget {
+                id: lockScreenIcon
+                icon: QIcon("system-lock-screen")
+                minimumIconSize: "128x128"
+
+                onClicked: {
+                    lockScreenRequested();
+                }
+            }
+        }
+
+        Column {
+            Text {
+                text: i18n("sleep")
+                anchors.horizontalCenter: sleepIcon.horizontalCenter
+                color: theme.textColor
+                font.pixelSize: 18
+                font.family: theme.defaultFont.family
+                font.bold: theme.defaultFont.bold
+                font.capitalization: theme.defaultFont.capitalization
+                font.italic: theme.defaultFont.italic
+                font.weight: theme.defaultFont.weight
+                font.underline: theme.defaultFont.underline
+                font.wordSpacing: theme.defaultFont.wordSpacing
+            }
+            IconWidget {
+                id: sleepIcon
+                icon: QIcon("system-suspend")
+                minimumIconSize: "128x128"
+
+                onClicked: {
+                    suspendRequested(2); // Solid::PowerManagement::SuspendState
+                }
+            }
+        }
+
+        Column {
+            Text {
+                text: i18n("turn off")
+                anchors.horizontalCenter: shutdownIcon.horizontalCenter
+                color: theme.textColor
+                font.pixelSize: 18
+                font.family: theme.defaultFont.family
+                font.bold: theme.defaultFont.bold
+                font.capitalization: theme.defaultFont.capitalization
+                font.italic: theme.defaultFont.italic
+                font.weight: theme.defaultFont.weight
+                font.underline: theme.defaultFont.underline
+                font.wordSpacing: theme.defaultFont.wordSpacing
+            }
+            IconWidget {
+                id: shutdownIcon
+                icon: QIcon("system-shutdown")
+                minimumIconSize: "128x128"
+
+                onClicked: {
+                    haltRequested()
+                }
+            }
+        }
+    }
+}
diff --git a/ksmserver/qml/plasma_desktop.qml b/ksmserver/qml/plasma_desktop.qml
new file mode 100644
index 0000000..8cbbff3
--- /dev/null
+++ b/ksmserver/qml/plasma_desktop.qml
@@ -0,0 +1,331 @@
+/*
+ *   Copyright 2011 Lamarque V. Souza <lamarque@kde.org>
+ *
+ *   This program is free software; you can redistribute it and/or modify
+ *   it under the terms of the GNU Library General Public License as
+ *   published by the Free Software Foundation; either version 2 or
+ *   (at your option) any later version.
+ *
+ *   This program is distributed in the hope that it will be useful,
+ *   but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *   GNU Library General Public License for more details
+ *
+ *   You should have received a copy of the GNU Library General Public
+ *   License along with this program; if not, write to the
+ *   Free Software Foundation, Inc.,
+ *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+
+import QtQuick 1.1
+import org.kde.plasma.core 0.1 as PlasmaCore
+import org.kde.plasma.components 0.1 as PlasmaComponents
+
+PlasmaCore.FrameSvgItem {
+    id: shutdownUi
+    property int realMarginTop: margins.top
+    property int realMarginBottom: margins.bottom
+    property int realMarginLeft: margins.left
+    property int realMarginRight: margins.right
+
+    width: realMarginLeft + 2 * buttonsLayout.width + realMarginRight
+    height: realMarginTop + automaticallyDoLabel.height + buttonsLayout.height + realMarginBottom
+
+    imagePath: "dialogs/shutdowndialog"
+
+    signal logoutRequested()
+    signal haltRequested()
+    signal suspendRequested(int spdMethod)
+    signal rebootRequested()
+    signal rebootRequested2(int opt)
+    signal cancelRequested()
+    signal lockScreenRequested()
+
+    property variant focusedButton: 0
+    property variant lastButton: 0
+    property int automaticallyDoSeconds: 30
+
+    PlasmaCore.Theme {
+        id: theme
+    }
+
+    PlasmaCore.SvgItem {
+        id: background
+
+        anchors {
+            top: parent.top
+            topMargin: realMarginTop
+            bottom: parent.bottom
+            bottomMargin: realMarginBottom
+            left: parent.left
+            leftMargin: realMarginLeft
+            right: parent.right
+            rightMargin: realMarginRight
+        }
+
+        svg: PlasmaCore.Svg {
+            imagePath: "dialogs/shutdowndialog"
+        }
+        elementId: "center"
+    }
+
+    Component.onCompleted: {
+        // Hacky but works :-)
+        logoutButton.width = buttonsLayout.width
+        shutdownButton.width = buttonsLayout.width
+        rebootButton.width = buttonsLayout.width
+
+        if (margins.left == 0) {
+            realMarginTop = 9
+            realMarginBottom = 7
+            realMarginLeft = 12
+            realMarginRight = 12
+        }
+
+        if (leftPicture.naturalSize.width < 1) {
+            background.elementId = "background"
+            shutdownUi.width += realMarginLeft + realMarginRight
+            shutdownUi.height += realMarginTop + realMarginBottom
+            automaticallyDoLabel.anchors.topMargin = 2*realMarginTop
+            automaticallyDoLabel.anchors.rightMargin = 2*realMarginRight
+            leftPicture.anchors.leftMargin = 2*realMarginLeft
+            buttonsLayout.anchors.rightMargin = 2*realMarginRight
+        }
+
+        if (choose || sdtype == ShutdownType.ShutdownTypeNone) {
+            if (sdtype == ShutdownType.ShutdownTypeNone) {
+                focusedButton = logoutButton
+            }
+        }
+
+        if (maysd) {
+            if(choose || sdtype == ShutdownType.ShutdownTypeHalt) {
+                if (sdtype == ShutdownType.ShutdownTypeHalt) {
+                    focusedButton = shutdownButton
+                }
+            }
+
+            if (choose || sdtype == ShutdownType.ShutdownTypeReboot) {
+                if (sdtype == ShutdownType.ShutdownTypeReboot) {
+                    focusedButton = rebootButton
+                }
+            }
+        }
+
+        focusedButton.focusedButton = true
+
+        timer.interval = 1000;
+        timer.running = true;
+    }
+
+    Timer {
+        id: timer
+        repeat: true
+        running: false
+
+        onTriggered: {
+            if (focusedButton != lastButton) {
+                lastButton = focusedButton
+                automaticallyDoSeconds = 30
+            }
+            if (focusedButton != 0) {
+                if (automaticallyDoSeconds <= 0) { // timeout is at 0, do selected action
+                    focusedButton.clicked()
+                // following code is required to provide a clean way to translate strings
+                } else if (focusedButton.text == logoutButton.text) {
+                    automaticallyDoLabel.text = i18np("Logging out in 1 second.",
+                                                      "Logging out in %1 seconds.", automaticallyDoSeconds)
+                } else if (focusedButton.text == shutdownButton.text) {
+                    automaticallyDoLabel.text = i18np("Turning off computer in 1 second.",
+                                                      "Turning off computer in %1 seconds.", automaticallyDoSeconds)
+                } else if (focusedButton.text == rebootButton.text) {
+                    automaticallyDoLabel.text = i18np("Restarting computer in 1 second.",
+                                                      "Restarting computer in %1 seconds.", automaticallyDoSeconds)
+                } else {
+                    automaticallyDoLabel.text = ""
+                }
+
+                --automaticallyDoSeconds;
+            }
+        }
+    }
+
+    Text {
+        id: automaticallyDoLabel
+        text: " "
+        // pixelSize does not work with PlasmaComponents.Label, so I am using a Text element here.
+        font.pixelSize: 11
+        color: theme.textColor
+        anchors {
+            top: parent.top
+            topMargin: realMarginTop
+            right: parent.right
+            rightMargin: realMarginRight
+        }
+    }
+
+    PlasmaCore.SvgItem {
+        id: leftPicture
+        width: buttonsLayout.width
+        height: width * naturalSize.height / naturalSize.width
+        smooth: true
+        anchors {
+            verticalCenter: parent.verticalCenter
+            left: parent.left
+            leftMargin: realMarginLeft
+        }
+
+        svg: PlasmaCore.Svg {
+            imagePath: "dialogs/shutdowndialog"
+        }
+        elementId: "picture"
+    }
+
+    Column {
+        id: buttonsLayout
+        spacing: 9
+        anchors {
+            top: automaticallyDoLabel.bottom
+            topMargin: 4
+            right: parent.right
+            rightMargin: realMarginRight
+        }
+
+        Column {
+            spacing: 4
+
+            KSMButton {
+                id: logoutButton
+                text: i18n("Logout")
+                iconSource: "system-log-out"
+                height: 32
+                anchors.right: parent.right
+                visible: (choose || sdtype == ShutdownType.ShutdownTypeNone)
+
+                onClicked: {
+                    logoutRequested()
+                }
+
+                onPressed: {
+                    if (shutdownUi.focusedButton != logoutButton) {
+                        shutdownUi.focusedButton.focusedButton = false
+                        shutdownUi.focusedButton = logoutButton
+                        focusedButton = true
+                        focus = true
+                    }
+                }
+            }
+
+            KSMButton {
+                id: shutdownButton
+                text: i18n("Turn Off Computer")
+                iconSource: "system-shutdown"
+                height: 32
+                anchors.right: parent.right
+                visible: (choose || sdtype == ShutdownType.ShutdownTypeHalt)
+                menu: true
+
+                onClicked: {
+                    haltRequested()
+                }
+
+                onPressAndHold: {
+                    if (!contextMenu) {
+                        contextMenu = shutdownOptionsComponent.createObject(shutdownButton)
+                        if (spdMethods.StandbyState) {
+                            // 1 == Solid::PowerManagement::StandbyState
+                            contextMenu.append({itemIndex: 1, itemText: i18n("Standby")})
+                        }
+                        if (spdMethods.SuspendState) {
+                            // 2 == Solid::PowerManagement::SuspendState
+                            contextMenu.append({itemIndex: 2, itemText: i18n("Suspend to RAM")})
+                        }
+                        if (spdMethods.HibernateState) {
+                            // 3 == Solid::PowerManagement::HibernateState
+                            contextMenu.append({itemIndex: 3, itemText: i18n("Suspend to Disk")})
+                        }
+                        contextMenu.clicked.connect(shutdownUi.suspendRequested)
+                    }
+                    contextMenu.open()
+                }
+
+                onPressed: {
+                    if (shutdownUi.focusedButton != shutdownButton) {
+                        shutdownUi.focusedButton.focusedButton = false
+                        shutdownUi.focusedButton = shutdownButton
+                        focusedButton = true
+                        focus = true
+                    }
+                }
+            }
+
+            Component {
+                id: shutdownOptionsComponent
+                ContextMenu {
+                    visualParent: shutdownButton
+                }
+            }
+
+            KSMButton {
+                id: rebootButton
+                text: i18n("Restart Computer")
+                iconSource: "system-reboot"
+                height: 32
+                anchors.right: parent.right
+                menu: true
+
+                onClicked: {
+                    rebootRequested()
+                }
+
+                onPressAndHold: {
+                    if (!contextMenu) {
+                        contextMenu = rebootOptionsComponent.createObject(rebootButton)
+                        var options = rebootOptions["options"]
+                        for (var index = 0; index < options.length; ++index) {
+                            var itemData = new Object
+                            itemData["itemIndex"] = index
+                            itemData["itemText"] = options[index]
+                            if (index == rebootOptions["default"]) {
+                                itemData["itemText"] += i18nc("default option in boot loader", " (default)")
+                            }
+                            contextMenu.append(itemData)
+                        }
+
+                        contextMenu.clicked.connect(shutdownUi.rebootRequested2)
+                    }
+                    contextMenu.open()
+                }
+
+                onPressed: {
+                    if (shutdownUi.focusedButton != rebootButton) {
+                        shutdownUi.focusedButton.focusedButton = false
+                        shutdownUi.focusedButton = rebootButton
+                        focusedButton = true
+                        focus = true
+                    }
+                }
+            }
+
+            Component {
+                id: rebootOptionsComponent
+                ContextMenu {
+                    visualParent: rebootButton
+                }
+            }
+        }
+
+        KSMButton {
+            id: cancelButton
+            text: i18n("Cancel")
+            iconSource: "dialog-cancel"
+            smallButton: true
+            height: 22
+            anchors.right: parent.right
+
+            onClicked: {
+                cancelRequested()
+            }
+        }
+    }
+}
diff --git a/ksmserver/shutdowndlg.cpp b/ksmserver/shutdowndlg.cpp
index a09a1a7..676aa9e 100644
--- a/ksmserver/shutdowndlg.cpp
+++ b/ksmserver/shutdowndlg.cpp
@@ -41,6 +41,10 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <QtDBus/QDBusConnection>
 #include <QtDBus/QDBusMessage>
 #include <QtDBus/QDBusPendingCall>
+#include <QDeclarativeView>
+#include <QDeclarativeContext>
+#include <QDeclarativeEngine>
+#include <QDeclarativePropertyMap>
 
 #include <kdialog.h>
 #include <kiconloader.h>
@@ -49,6 +53,8 @@ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #include <Solid/PowerManagement>
 #include <kwindowsystem.h>
 #include <netwm.h>
+#include <KStandardDirs>
+#include <kdeclarative.h>
 
 #include <stdio.h>
 #include <kxerrorhandler.h>
@@ -156,216 +162,11 @@ void KSMShutdownFeedback::logoutCanceled()
 
 ////////////
 
-KSMPushButton::KSMPushButton( const QString &text, QWidget *parent, bool smallButton )
- : QPushButton( text, parent ),  m_highlight( false ), m_text( text ), m_popupMenu(0), m_popupTimer(0),
-   m_glowOpacity( 0.0 ), m_smallButton( smallButton )
-{
-    setAttribute(Qt::WA_Hover, true);
-    m_text = text;
-    init();
-}
-
-void KSMPushButton::init()
-{
-    m_glowSvg = new Plasma::Svg(this);
-    m_glowSvg->setImagePath("dialogs/shutdowndialog");
-
-    if (m_smallButton) {
-        setMinimumSize(88, 22);
-        setFixedHeight(22); // workaround: force correct height
-    } else {
-        setMinimumSize(m_glowSvg->elementSize("button-normal"));
-        setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
-    }
-
-    connect( this, SIGNAL(pressed()), SLOT(slotPressed()) );
-    connect( this, SIGNAL(released()), SLOT(slotReleased()) );
-
-    connect( m_glowSvg, SIGNAL(repaintNeeded()), this, SLOT(update()) );
-
-    m_glowTimeLine = new QTimeLine( 150, this );
-    connect( m_glowTimeLine, SIGNAL(valueChanged(qreal)),
-            this, SLOT(animateGlow(qreal)) );
-
-    QFont fnt;
-    fnt.setPixelSize(12);
-
-    // Calculate the width of the text when splitted on two lines and
-    // properly resize the button.
-    if (QFontMetrics(fnt).width(m_text) > width() - 4 - (m_smallButton ? 16 : 32) ||
-        (2 * QFontMetrics(fnt).lineSpacing() > height() && !m_smallButton) ) {
-        int w, h;
-        int i = m_text.length()/2;
-        int fac = 1;
-        int diff = 1;
-        while( i && i < m_text.length() && m_text[i] != ' ' ) {
-            i = i + (diff * fac);
-            fac *= -1;
-            ++diff;
-        }
-        QString upper = m_text.left( i );
-        QString lower = m_text.right( m_text.length() - i );
-
-        w = qMax(QFontMetrics(fnt).width(upper) + 18 + (m_smallButton ? 16 : 32),
-                 QFontMetrics(fnt).width(lower) + 18 + (m_smallButton ? 16 : 32));
-        w = qMax(w, width());
-        h = qMax(height(), ((upper.isEmpty() || lower.isEmpty()) ? 1 : 2) * QFontMetrics(fnt).lineSpacing());
-        if (w > width() || h > height()) {
-            setMinimumSize(w, h);
-            if (m_smallButton)
-                setFixedHeight(h);
-            updateGeometry();
-        }
-    }
-}
-
-void KSMPushButton::paintEvent( QPaintEvent * e )
-{
-    QPainter p( this );
-    p.setClipRect( e->rect() );
-    p.setRenderHints(QPainter::Antialiasing | QPainter::TextAntialiasing);
-    QPen pen;
-    QFont fnt;
-    QColor fntColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
-    fnt.setPixelSize(12);
-    p.setFont( fnt );
-    p.setCompositionMode(QPainter::CompositionMode_SourceOver);
-
-    p.save();
-
-    m_glowSvg->resize();
-
-    if (m_glowOpacity > 0) {
-        p.setOpacity(m_glowOpacity); // fade in
-        m_glowSvg->paint(&p, QRect(0, 0, width(), height()), m_smallButton ? "button-small-hover" : "button-hover");
-        p.setOpacity(1.0 - m_glowOpacity); // fade normal background out
-        m_glowSvg->paint(&p, QRect(0, 0, width(), height()), m_smallButton ? "button-small-normal" : "button-normal");
-        p.setOpacity(1.0);
-    } else {
-        m_glowSvg->paint(&p, QRect(0, 0, width(), height()), m_smallButton ? "button-small-normal" : "button-normal");
-    }
-
-    p.restore();
-
-    p.setRenderHints( QPainter::Antialiasing, false);
-    p.drawPixmap(width() - (m_smallButton ? 16 : 32) - 4, height() / 2 - (m_smallButton ? 8 : 16), m_pixmap);
-
-    p.save();
-    p.setPen(fntColor);
-    p.drawText(10, 0, width() - (m_smallButton ? 16 : 32) - 8, height(),
-               Qt::AlignVCenter | Qt::AlignLeft | Qt::TextWordWrap | Qt::TextShowMnemonic, m_text);
-    p.restore();
-
-    if( m_popupMenu ) {
-        p.save();
-        p.setBrush(fntColor);
-        pen.setColor(QColor(fntColor));
-        p.setPen( pen );
-        int baseY = height()/2 + m_pixmap.height()/2;
-        QPoint points[3] = {
-            QPoint(width() - 10 - 34, baseY - 3),
-            QPoint(width() - 4 - 34, baseY - 3),
-            QPoint(width() - 7 - 34, baseY) };
-        p.drawPolygon(points, 3); // TODO: use QStyle
-        p.restore();
-    }
-}
-
-void KSMPushButton::resizeEvent(QResizeEvent *e)
-{
-    m_glowSvg->resize( e->size() );
-    QPushButton::resizeEvent( e );
-}
-
-void KSMPushButton::animateGlow( qreal value )
-{
-    m_glowOpacity = value;
-    update();
-}
-
-void KSMPushButton::setPixmap( const QPixmap &p )
-{
-    m_pixmap = p;
-    int size = m_smallButton ? 16 : 32;
-    if (m_pixmap.size().width() != size || m_pixmap.size().height() != size)
-        m_pixmap = m_pixmap.scaled(size, size);
-    update();
-}
-
-void KSMPushButton::setPopupMenu( QMenu *m )
-{
-    m_popupMenu = m;
-    if( !m_popupTimer ) {
-        m_popupTimer = new QTimer( this );
-        connect( m_popupTimer, SIGNAL(timeout()), this, SLOT(slotTimeout()));
-    }
-}
-
-void KSMPushButton::slotPressed()
-{
-    if( m_popupTimer )
-        m_popupTimer->start( QApplication::startDragTime() );
-}
-
-void KSMPushButton::slotReleased()
-{
-    if( m_popupTimer )
-        m_popupTimer->stop();
-}
-
-void KSMPushButton::slotTimeout()
-{
-    m_popupTimer->stop();
-    if( m_popupMenu ) {
-        m_popupMenu->popup( mapToGlobal(rect().bottomLeft()) );
-        m_highlight = false;
-        update();
-    }
-}
-
-bool KSMPushButton::event( QEvent *e )
-{
-    if (e->type() == QEvent::HoverEnter || e->type() == QEvent::FocusIn)
-    {
-        if (m_glowOpacity > 0) // already hovered
-            return true;
-        m_highlight = true;
-        m_glowTimeLine->setDirection( QTimeLine::Forward );
-        if (m_glowTimeLine->state() == QTimeLine::Running)
-            m_glowTimeLine->stop();
-        m_glowTimeLine->start();
-        update();
-        return true;
-    }
-    else if (e->type() == QEvent::HoverLeave || e->type() == QEvent::FocusOut)
-    {
-        if (hasFocus())
-            return true;
-        m_highlight = false;
-        m_glowTimeLine->setDirection( QTimeLine::Backward );
-        if (m_glowTimeLine->state() == QTimeLine::Running)
-            m_glowTimeLine->stop();
-        m_glowTimeLine->start();
-        update();
-        return true;
-    }
-    else
-        return QPushButton::event( e );
-}
-
-//////
-
 Q_DECLARE_METATYPE(Solid::PowerManagement::SleepState)
 
 KSMShutdownDlg::KSMShutdownDlg( QWidget* parent,
                                 bool maysd, bool choose, KWorkSpace::ShutdownType sdtype )
-  : QDialog( parent, Qt::Popup ), //krazy:exclude=qclasses
-    m_lastButton(0),
-    m_btnLogout(0),
-    m_btnHalt(0),
-    m_btnReboot(0),
-    m_automaticallyDoSeconds(30),
-    m_pictureWidth(0)
+  : QDialog( parent, Qt::Popup ) //krazy:exclude=qclasses
     // this is a WType_Popup on purpose. Do not change that! Not
     // having a popup here has severe side effects.
 {
@@ -383,241 +184,85 @@ KSMShutdownDlg::KSMShutdownDlg( QWidget* parent,
         (unsigned char *)"logoutdialog", strlen( "logoutdialog" ));
 
 //#endif
-    m_svg = new Plasma::FrameSvg(this);
-    m_svg->setImagePath("dialogs/shutdowndialog");
-    connect( m_svg, SIGNAL(repaintNeeded()), this, SLOT(update()) );
-    setModal( true );
-
-    QVBoxLayout *mainLayout = new QVBoxLayout();
-
-    qreal left, top, right, bottom;
-    m_svg->getMargins(left, top, right, bottom);
-    //not in framesvg mode
-    if (left == 0) {
-        mainLayout->setContentsMargins(12, 9, 12, 7);
-    } else {
-        mainLayout->setContentsMargins(left, top, right, bottom);
-    }
-
-    QVBoxLayout *buttonLayout = new QVBoxLayout();
-    QHBoxLayout *buttonMainLayout = new QHBoxLayout();
-
-    m_automaticallyDoLabel = new QLabel(this);
-    mainLayout->addWidget(m_automaticallyDoLabel, 0, Qt::AlignRight);
 
-    buttonMainLayout->addLayout(buttonLayout);
-
-    QHBoxLayout *bottomLayout = new QHBoxLayout();
-
-    QFont fnt;
-    fnt.setPixelSize(16);
-    QColor fntColor = Plasma::Theme::defaultTheme()->color(Plasma::Theme::TextColor);
-    QPalette palette;
-    palette.setColor(QPalette::WindowText, fntColor);
+    KDialog::centerOnScreen(this, -3);
 
-    if ( choose || sdtype == KWorkSpace::ShutdownTypeNone ) {
-        m_btnLogout = new KSMPushButton( i18n("&Logout"), this );
-        m_btnLogout->setPixmap(KIconLoader::global()->loadIcon("system-log-out", KIconLoader::NoGroup, 32));
-        if ( sdtype == KWorkSpace::ShutdownTypeNone )
-            m_btnLogout->setFocus();
-        connect(m_btnLogout, SIGNAL(clicked()), SLOT(slotLogout()));
-        buttonLayout->addWidget(m_btnLogout, Qt::AlignRight | Qt::AlignTop);
+    //kDebug() << "Creating QML view";
+    m_view = new QDeclarativeView(this);
+    QDeclarativeContext *context = m_view->rootContext();
+    context->setContextProperty("maysd", maysd);
+    context->setContextProperty("choose", choose);
+    context->setContextProperty("sdtype", sdtype);
+
+    QDeclarativePropertyMap *mapShutdownType = new QDeclarativePropertyMap(this);
+    mapShutdownType->insert("ShutdownTypeDefault", QVariant::fromValue((int)KWorkSpace::ShutdownTypeDefault));
+    mapShutdownType->insert("ShutdownTypeNone", QVariant::fromValue((int)KWorkSpace::ShutdownTypeNone));
+    mapShutdownType->insert("ShutdownTypeReboot", QVariant::fromValue((int)KWorkSpace::ShutdownTypeReboot));
+    mapShutdownType->insert("ShutdownTypeHalt", QVariant::fromValue((int)KWorkSpace::ShutdownTypeHalt));
+    mapShutdownType->insert("ShutdownTypeLogout", QVariant::fromValue((int)KWorkSpace::ShutdownTypeLogout));
+    context->setContextProperty("ShutdownType", mapShutdownType);
+
+    QDeclarativePropertyMap *mapSpdMethods = new QDeclarativePropertyMap(this);
+    QSet<Solid::PowerManagement::SleepState> spdMethods = Solid::PowerManagement::supportedSleepStates();
+    mapSpdMethods->insert("StandbyState", QVariant::fromValue(spdMethods.contains(Solid::PowerManagement::StandbyState)));
+    mapSpdMethods->insert("SuspendState", QVariant::fromValue(spdMethods.contains(Solid::PowerManagement::SuspendState)));
+    mapSpdMethods->insert("HibernateState", QVariant::fromValue(spdMethods.contains(Solid::PowerManagement::HibernateState)));
+    context->setContextProperty("spdMethods", mapSpdMethods);
+
+    QStringList options;
+    int def, cur;
+    if ( KDisplayManager().bootOptions( rebootOptions, def, cur ) ) {
+        if ( cur > -1 ) {
+            def = cur;
+	}
     }
+    QDeclarativePropertyMap *rebootOptionsMap = new QDeclarativePropertyMap(this);
+    rebootOptionsMap->insert("options", QVariant::fromValue(rebootOptions));
+    rebootOptionsMap->insert("default", QVariant::fromValue(def));
+    context->setContextProperty("rebootOptions", rebootOptionsMap);
 
-    if (maysd) {
-        // Shutdown
-
-        if ( choose || sdtype == KWorkSpace::ShutdownTypeHalt ) {
-            m_btnHalt = new KSMPushButton( i18n("&Turn Off Computer"), this );
-            m_btnHalt->setPixmap(KIconLoader::global()->loadIcon("system-shutdown", KIconLoader::NoGroup, 32));
-            buttonLayout->addWidget(m_btnHalt, Qt::AlignTop | Qt::AlignRight);
-            connect(m_btnHalt, SIGNAL(clicked()), SLOT(slotHalt()));
-            if ( sdtype == KWorkSpace::ShutdownTypeHalt )
-                m_btnHalt->setFocus();
-
-            QMenu *shutdownMenu = new QMenu( m_btnHalt );
-            QActionGroup* spdActionGroup = new QActionGroup(shutdownMenu);
-            connect( spdActionGroup, SIGNAL(triggered(QAction*)), SLOT(slotSuspend(QAction*)) );
-            m_btnHalt->setPopupMenu( shutdownMenu );
-            QSet< Solid::PowerManagement::SleepState > spdMethods = Solid::PowerManagement::supportedSleepStates();
-            if( spdMethods.contains(Solid::PowerManagement::StandbyState) ) {
-                QAction* action = new QAction(i18n("&Standby"), spdActionGroup);
-                action->setData(QVariant::fromValue(Solid::PowerManagement::StandbyState));
-            }
-            if( spdMethods.contains(Solid::PowerManagement::SuspendState) ) {
-                QAction* action = new QAction(i18n("Suspend to &RAM"), spdActionGroup);
-                action->setData(QVariant::fromValue(Solid::PowerManagement::SuspendState));
-            }
-            if( spdMethods.contains(Solid::PowerManagement::HibernateState) ) {
-                QAction* action = new QAction(i18n("Suspend to &Disk"), spdActionGroup);
-                action->setData(QVariant::fromValue(Solid::PowerManagement::HibernateState));
-            }
-            shutdownMenu->addActions(spdActionGroup->actions());
-        }
+    setModal( true );
 
-        if ( choose || sdtype == KWorkSpace::ShutdownTypeReboot ) {
-            // Reboot
-            m_btnReboot = new KSMPushButton( i18n("&Restart Computer"), this );
-            m_btnReboot->setPixmap(KIconLoader::global()->loadIcon("system-reboot", KIconLoader::NoGroup, 32));
-            connect(m_btnReboot, SIGNAL(clicked()), SLOT(slotReboot()));
-            buttonLayout->addWidget(m_btnReboot, Qt::AlignTop | Qt::AlignRight);
-            if ( sdtype == KWorkSpace::ShutdownTypeReboot )
-                m_btnReboot->setFocus();
-
-            int def, cur;
-            if ( KDisplayManager().bootOptions( rebootOptions, def, cur ) ) {
-                if ( cur == -1 )
-                    cur = def;
-
-                QMenu *rebootMenu = new QMenu( m_btnReboot );
-                QActionGroup* rebootActionGroup = new QActionGroup(rebootMenu);
-                connect( rebootActionGroup, SIGNAL(triggered(QAction*)), SLOT(slotReboot(QAction*)) );
-                m_btnReboot->setPopupMenu( rebootMenu );
-
-                int index = 0;
-                for (QStringList::ConstIterator it = rebootOptions.constBegin(); it != rebootOptions.constEnd(); ++it, ++index) {
-                    QString label = (*it);
-                    label=label.replace('&',"&&");
-                    QAction* action = new QAction(label, rebootActionGroup);
-                    action->setData(index);
-                    if (index == cur) {
-                        action->setText( label + i18nc("default option in boot loader", " (default)") );
-                    }
-                }
-                rebootMenu->addActions(rebootActionGroup->actions());
-            }
-        }
+    // window stuff
+    m_view->setFrameShape(QFrame::NoFrame);
+    m_view->setWindowFlags(Qt::X11BypassWindowManagerHint);
+    m_view->setAttribute(Qt::WA_TranslucentBackground);
+    setAttribute(Qt::WA_TranslucentBackground);
+    setStyleSheet("background:transparent;");
+    QPalette pal = m_view->palette();
+    pal.setColor(backgroundRole(), Qt::transparent);
+    m_view->setPalette(pal);
+    m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
+    // engine stuff
+    foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports")) {
+        m_view->engine()->addImportPath(importPath);
     }
-
-    btnBack = new KSMPushButton(i18n("&Cancel"), this, true);
-    btnBack->setPixmap(KIconLoader::global()->loadIcon( "dialog-cancel", KIconLoader::NoGroup, 16));
-
-    m_automaticallyDoLabel->setPalette(palette);
-    fnt.setPixelSize(11);
-    m_automaticallyDoLabel->setFont(fnt);
-    automaticallyDoTimeout();
-
-    QTimer *automaticallyDoTimer = new QTimer(this);
-    connect(automaticallyDoTimer, SIGNAL(timeout()), this, SLOT(automaticallyDoTimeout()));
-    automaticallyDoTimer->start(1000);
-
-    bottomLayout->addStretch();
-    bottomLayout->addWidget(btnBack);
-    connect(btnBack, SIGNAL(clicked()), SLOT(reject()));
-
-    mainLayout->addLayout(buttonMainLayout);
-    mainLayout->addSpacing(9);
-    mainLayout->addLayout(bottomLayout);
-
-    setLayout(mainLayout);
+    KDeclarative kdeclarative;
+    kdeclarative.setDeclarativeEngine(m_view->engine());
+    kdeclarative.initialize();
+    kdeclarative.setupBindings();
+    m_view->installEventFilter(this);
+
+    // TODO: add option in systemsettings -> Startup and Shutdown -> Session Management
+    // to select the qml theme.
+    m_view->setSource(QUrl(KStandardDirs::locate("data", "ksmserver/qml/default.qml")));
+    setFocus();
+    connect(m_view, SIGNAL(sceneResized(QSize)), SLOT(resizeFromView(QSize)));
+    connect(m_view->rootObject(), SIGNAL(logoutRequested()), SLOT(slotLogout()));
+    connect(m_view->rootObject(), SIGNAL(haltRequested()), SLOT(slotHalt()));
+    connect(m_view->rootObject(), SIGNAL(suspendRequested(int)), SLOT(slotSuspend(int)) );
+    connect(m_view->rootObject(), SIGNAL(rebootRequested()), SLOT(slotReboot()));
+    connect(m_view->rootObject(), SIGNAL(rebootRequested2(int)), SLOT(slotReboot(int)) );
+    connect(m_view->rootObject(), SIGNAL(cancelRequested()), SLOT(reject()));
+    connect(m_view->rootObject(), SIGNAL(lockScreenRequested()), SLOT(slotLockScreen()));
+    m_view->show();
     adjustSize();
-    if (m_svg->hasElement("picture")) {
-        QRect pictRect = m_svg->elementRect("picture").toRect();
-
-        if (pictRect.height() < 1 || pictRect.width() < 1) {
-            m_pictureWidth = 0;
-        } else if (height() > width()) {
-            m_pictureWidth = width();
-        } else {
-            m_svg->isValid();
-            m_pictureWidth = mainLayout->sizeHint().height() * (pictRect.width() / pictRect.height());
-            //kDebug() << "blurk!" << buttonMainLayout->sizeHint().height() << pictRect;
-        }
-
-        //kDebug() << width() << m_pictureWidth;
-        //FIXME: this spaces will be taken from framesvg borders
-        if (m_pictureWidth > 0) {
-            const int extraSpace = 18;
-            buttonMainLayout->insertSpacing(0, m_pictureWidth + extraSpace);
-        }
-        //resize(width() + m_pictureWidth, height());
-        //kDebug() << width();
-    } else {
-        m_pictureWidth = 0;
-    }
-
-    KDialog::centerOnScreen(this, -3);
-}
-
-void KSMShutdownDlg::automaticallyDoTimeout()
-{
-    QPushButton *focusedButton = qobject_cast<QPushButton *>(focusWidget());
-    if (focusedButton != m_lastButton) {
-        m_lastButton = focusedButton;
-        m_automaticallyDoSeconds = 30;
-    }
-    if (focusedButton) {
-        if (m_automaticallyDoSeconds <= 0) { // timeout is at 0, do selected action
-                focusedButton->click();
-        // following code is required to provide a clean way to translate strings
-        } else if (focusedButton == m_btnLogout) {
-            m_automaticallyDoLabel->setText(i18np("Logging out in 1 second.",
-                                            "Logging out in %1 seconds.", m_automaticallyDoSeconds));
-        } else if (focusedButton == m_btnHalt) {
-                m_automaticallyDoLabel->setText(i18np("Turning off computer in 1 second.",
-                                                      "Turning off computer in %1 seconds.", m_automaticallyDoSeconds));
-        } else if (focusedButton == m_btnReboot) {
-                m_automaticallyDoLabel->setText(i18np("Restarting computer in 1 second.",
-                                                      "Restarting computer in %1 seconds.", m_automaticallyDoSeconds));
-        } else {
-            m_automaticallyDoLabel->setText(QString());
-        }
-
-        if (m_automaticallyDoLabel > 0) {
-            --m_automaticallyDoSeconds;
-        }
-    }
 }
 
-void KSMShutdownDlg::paintEvent(QPaintEvent *e)
+void KSMShutdownDlg::resizeFromView(const QSize &newSize)
 {
-    Q_UNUSED(e);
-    QPainter p(this);
-    p.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);
-    p.setCompositionMode( QPainter::CompositionMode_Source );
-    p.setClipRect(e->rect());
-
-    p.fillRect(QRect(0, 0, width(), height()), Qt::transparent);
-
-    if (m_svg->hasElement("center")) {
-        m_svg->resizeFrame(size());
-        m_svg->paintFrame(&p);
-    } else {
-        m_svg->paint(&p, QRect(0, 0, width(), height()), "background");
-    }
-
-    if (m_pictureWidth > 0) { // implies hasElement("picture")
-        QRect r = layout()->geometry();
-        r.setWidth(m_pictureWidth);
-
-	m_svg->resize();
-        m_svg->resize(m_svg->elementRect("picture").size());
-        QPixmap picture = m_svg->pixmap("picture");
-        m_svg->resize();
-
-        //kDebug() << 1 << r << picture.size();
-        if (r.width() < picture.width()) {
-            picture = picture.scaledToWidth(r.width(), Qt::SmoothTransformation);
-        }
-
-        if (r.height() < picture.height()) {
-            picture = picture.scaledToHeight(r.height(), Qt::SmoothTransformation);
-        }
-
-
-        int left = (r.height() - picture.height())/2;
-        if (QApplication::isLeftToRight()) {
-            r.moveLeft(left);
-        } else {
-            r.moveRight(layout()->geometry().width() - left);
-        }
-
-        //kDebug() << 2 << r << picture.size();
-        QRect dest = picture.rect();
-        dest.moveCenter(r.center());
-        p.setCompositionMode( QPainter::CompositionMode_SourceOver );
-        p.drawPixmap(dest, picture, picture.rect());
-    }
+    resize(newSize);
 }
 
 void KSMShutdownDlg::resizeEvent(QResizeEvent *e)
@@ -627,7 +272,7 @@ void KSMShutdownDlg::resizeEvent(QResizeEvent *e)
     if( KWindowSystem::compositingActive()) {
         clearMask();
     } else {
-        setMask(m_svg->mask());
+        setMask(m_view->mask());
     }
 
     KDialog::centerOnScreen(this, -3);
@@ -647,9 +292,8 @@ void KSMShutdownDlg::slotReboot()
     accept();
 }
 
-void KSMShutdownDlg::slotReboot(QAction* action)
+void KSMShutdownDlg::slotReboot(int opt)
 {
-    int opt = action->data().toInt();
     if (int(rebootOptions.size()) > opt)
         m_bootOption = rebootOptions[opt];
     m_shutdownType = KWorkSpace::ShutdownTypeReboot;
@@ -657,6 +301,17 @@ void KSMShutdownDlg::slotReboot(QAction* action)
 }
 
 
+void KSMShutdownDlg::slotLockScreen()
+{
+    m_bootOption.clear();
+    QDBusMessage call = QDBusMessage::createMethodCall("org.kde.screensaver",
+                                                       "/ScreenSaver",
+                                                       "org.freedesktop.ScreenSaver",
+                                                       "Lock");
+    QDBusConnection::sessionBus().asyncCall(call);
+    reject();
+}
+
 void KSMShutdownDlg::slotHalt()
 {
     m_bootOption.clear();
@@ -665,10 +320,9 @@ void KSMShutdownDlg::slotHalt()
 }
 
 
-void KSMShutdownDlg::slotSuspend(QAction* action)
+void KSMShutdownDlg::slotSuspend(int spdMethod)
 {
     m_bootOption.clear();
-    Solid::PowerManagement::SleepState spdMethod = action->data().value<Solid::PowerManagement::SleepState>();
     QDBusMessage call;
     switch (spdMethod) {
         case Solid::PowerManagement::StandbyState:
diff --git a/ksmserver/shutdowndlg.h b/ksmserver/shutdowndlg.h
index e5f0942..4fad316 100644
--- a/ksmserver/shutdowndlg.h
+++ b/ksmserver/shutdowndlg.h
@@ -69,38 +69,7 @@ private:
     bool initialized;
 };
 
-class KSMPushButton : public QPushButton
-{
-    Q_OBJECT
-
-public:
-    explicit KSMPushButton( const QString &text, QWidget *parent = 0, bool smallButton = false );
-
-    void setPixmap( const QPixmap & );
-    void setPopupMenu( QMenu * );
-protected:
-    void paintEvent(QPaintEvent *e);
-    void resizeEvent(QResizeEvent *e);
-    bool event(QEvent *e);
-
-    void init();
-protected:
-    QPixmap m_pixmap;
-    bool m_highlight;
-    QString m_text;
-private Q_SLOTS:
-    void slotPressed();
-    void slotReleased();
-    void slotTimeout();
-    void animateGlow( qreal );
-private:
-    QMenu* m_popupMenu;
-    QTimer* m_popupTimer;
-    Plasma::Svg* m_glowSvg;
-    qreal m_glowOpacity;
-    QTimeLine *m_glowTimeLine;
-    bool m_smallButton;
-};
+class QDeclarativeView;
 
 // The confirmation dialog
 class KSMShutdownDlg : public QDialog
@@ -115,12 +84,11 @@ public Q_SLOTS:
     void slotLogout();
     void slotHalt();
     void slotReboot();
-    void slotReboot(QAction*);
-    void slotSuspend(QAction*);
+    void slotReboot(int);
+    void slotSuspend(int);
+    void slotLockScreen();
 
 protected:
-    ~KSMShutdownDlg() {}
-    void paintEvent(QPaintEvent *e);
     void resizeEvent(QResizeEvent *e);
 
 private:
@@ -128,19 +96,10 @@ private:
     KWorkSpace::ShutdownType m_shutdownType;
     QString m_bootOption;
     QStringList rebootOptions;
-    QPixmap m_renderedSvg;
-    Plasma::FrameSvg* m_svg;
-    QLabel *m_automaticallyDoLabel;
-    QPushButton *m_lastButton;
-    KSMPushButton *m_btnLogout;
-    KSMPushButton *m_btnHalt;
-    KSMPushButton *m_btnReboot;
-    KSMPushButton *btnBack;
-    int m_automaticallyDoSeconds;
-    int m_pictureWidth;
+    QDeclarativeView* m_view;
 
 private Q_SLOTS:
-    void automaticallyDoTimeout();
+    void resizeFromView(const QSize &newSize);
 };
 
 #endif
