~ubuntu-branches/ubuntu/quantal/kde-runtime/quantal

« back to all changes in this revision

Viewing changes to plasma/declarativeimports/plasmacomponents/fullscreenwindow.cpp

  • Committer: Package Import Robot
  • Author(s): Philip Muškovac
  • Date: 2012-06-03 21:50:00 UTC
  • mto: This revision was merged to the branch mainline in revision 21.
  • Revision ID: package-import@ubuntu.com-20120603215000-vn7oarsq0ynrydj5
Tags: upstream-4.8.80
Import upstream version 4.8.80

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/***************************************************************************
 
2
 *   Copyright 2012 Marco Martin <mart@kde.org>                            *
 
3
 *                                                                         *
 
4
 *   This program is free software; you can redistribute it and/or modify  *
 
5
 *   it under the terms of the GNU General Public License as published by  *
 
6
 *   the Free Software Foundation; either version 2 of the License, or     *
 
7
 *   (at your option) any later version.                                   *
 
8
 *                                                                         *
 
9
 *   This program is distributed in the hope that it will be useful,       *
 
10
 *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
 
11
 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
 
12
 *   GNU General Public License for more details.                          *
 
13
 *                                                                         *
 
14
 *   You should have received a copy of the GNU General Public License     *
 
15
 *   along with this program; if not, write to the                         *
 
16
 *   Free Software Foundation, Inc.,                                       *
 
17
 *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA .        *
 
18
 ***************************************************************************/
 
19
 
 
20
#include "fullscreenwindow.h"
 
21
#include "../core/declarativeitemcontainer_p.h"
 
22
#include "plasmacomponentsplugin.h"
 
23
 
 
24
#include <QApplication>
 
25
#include <QDeclarativeItem>
 
26
#include <QDeclarativeContext>
 
27
#include <QGraphicsObject>
 
28
#include <QGraphicsScene>
 
29
#include <QGraphicsView>
 
30
#include <QGraphicsWidget>
 
31
#include <QLayout>
 
32
#include <QTimer>
 
33
#include <QDesktopWidget>
 
34
#include <QFile>
 
35
 
 
36
#include <KWindowSystem>
 
37
#include <KStandardDirs>
 
38
 
 
39
#include <Plasma/Corona>
 
40
#include <Plasma/WindowEffects>
 
41
 
 
42
 
 
43
uint FullScreenWindow::s_numItems = 0;
 
44
 
 
45
class Background : public QWidget
 
46
{
 
47
public:
 
48
    Background(FullScreenWindow *dialog)
 
49
        : QWidget( 0L ),
 
50
          m_dialog(dialog)
 
51
    {
 
52
        setAttribute( Qt::WA_NoSystemBackground );
 
53
        setAttribute( Qt::WA_TranslucentBackground );
 
54
 
 
55
        setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint);
 
56
        KWindowSystem::setOnAllDesktops(winId(), true);
 
57
        unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager | NET::MaxVert | NET::MaxHoriz;
 
58
        KWindowSystem::setState(effectiveWinId(), state);
 
59
    }
 
60
 
 
61
    ~Background()
 
62
    {}
 
63
 
 
64
    void paintEvent( QPaintEvent *e )
 
65
    {
 
66
        QPainter painter( this );
 
67
        painter.setCompositionMode(QPainter::CompositionMode_Source);
 
68
        painter.fillRect(e->rect(), QColor(0, 0, 0, 80));
 
69
    }
 
70
 
 
71
    void mousePressEvent(QMouseEvent *event)
 
72
    {
 
73
        event->accept();
 
74
        m_dialog->view()->winId();
 
75
        KWindowSystem::forceActiveWindow(m_dialog->view()->winId());
 
76
    }
 
77
 
 
78
    void mouseReleaseEvent(QMouseEvent *event)
 
79
    {
 
80
        if (!m_dialog->view()->geometry().contains(event->globalPos())) {
 
81
            m_dialog->close();
 
82
        }
 
83
    }
 
84
 
 
85
private:
 
86
    FullScreenWindow *m_dialog;
 
87
};
 
88
 
 
89
FullScreenWindow::FullScreenWindow(QDeclarativeItem *parent)
 
90
    : QDeclarativeItem(parent),
 
91
      m_declarativeItemContainer(0)
 
92
{
 
93
    m_view = new QGraphicsView();
 
94
    m_view->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
95
    m_view->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
 
96
    m_view->installEventFilter(this);
 
97
    m_view->setAutoFillBackground(false);
 
98
    m_view->viewport()->setAutoFillBackground(false);
 
99
    m_view->setAttribute(Qt::WA_TranslucentBackground);
 
100
    m_view->setAttribute(Qt::WA_NoSystemBackground);
 
101
    m_view->viewport()->setAttribute(Qt::WA_NoSystemBackground);
 
102
    m_view->setCacheMode(QGraphicsView::CacheNone);
 
103
    m_view->setWindowFlags(Qt::FramelessWindowHint | Qt::CustomizeWindowHint);
 
104
    m_view->setFrameShape(QFrame::NoFrame);
 
105
    KWindowSystem::setOnAllDesktops(m_view->winId(), true);
 
106
    unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager;
 
107
    KWindowSystem::setState(m_view->effectiveWinId(), state);
 
108
 
 
109
    m_background = new Background(this);
 
110
}
 
111
 
 
112
FullScreenWindow::~FullScreenWindow()
 
113
{
 
114
    delete m_view;
 
115
}
 
116
 
 
117
void FullScreenWindow::init(const QString &componentName)
 
118
{
 
119
    if (m_rootObject) {
 
120
        return;
 
121
    }
 
122
 
 
123
    //Try to figure out the path of the dialog component
 
124
    QString componentsPlatform = getenv("KDE_PLASMA_COMPONENTS_PLATFORM");
 
125
    if (componentsPlatform.isEmpty()) {
 
126
        KConfigGroup cg(KSharedConfig::openConfig("kdeclarativerc"), "Components-platform");
 
127
        componentsPlatform = cg.readEntry("name", "desktop");
 
128
    }
 
129
 
 
130
    QString filePath;
 
131
    if (componentsPlatform == "desktop") {
 
132
        foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "imports/")) {
 
133
            filePath = importPath % "org/kde/plasma/components/" % componentName % ".qml";
 
134
            QFile f(filePath);
 
135
            if (f.exists()) {
 
136
                break;
 
137
            }
 
138
        }
 
139
    } else {
 
140
        foreach(const QString &importPath, KGlobal::dirs()->findDirs("module", "platformimports/" % componentsPlatform)) {
 
141
            filePath = importPath % "org/kde/plasma/components/" % componentName % ".qml";
 
142
            QFile f(filePath);
 
143
            if (f.exists()) {
 
144
                break;
 
145
            }
 
146
        }
 
147
    }
 
148
 
 
149
 
 
150
    QDeclarativeEngine *engine = EngineBookKeeping::self()->engine();
 
151
    if (!engine) {
 
152
        kWarning() << "Warning, no QDeclarativeEngines available anymore, should never happen";
 
153
        Q_ASSERT(0);
 
154
    }
 
155
    QDeclarativeComponent *component = new QDeclarativeComponent(engine, filePath, this);
 
156
 
 
157
    QDeclarativeContext *creationContext = component->creationContext();
 
158
    m_rootObject = component->create(creationContext);
 
159
    if (component->status() == QDeclarativeComponent::Error) {
 
160
        kWarning()<<component->errors();
 
161
    }
 
162
 
 
163
    if (m_rootObject) {
 
164
        setMainItem(qobject_cast<QGraphicsObject *>(m_rootObject.data()));
 
165
        connect(m_rootObject.data(), SIGNAL(statusChanged()), this, SLOT(statusHasChanged()));
 
166
        connect(m_rootObject.data(), SIGNAL(accepted()), this, SIGNAL(accepted()));
 
167
        connect(m_rootObject.data(), SIGNAL(rejected()), this, SIGNAL(rejected()));
 
168
        connect(m_rootObject.data(), SIGNAL(clickedOutside()), this, SIGNAL(clickedOutside()));
 
169
    }
 
170
}
 
171
 
 
172
QGraphicsObject *FullScreenWindow::mainItem() const
 
173
{
 
174
    return m_mainItem.data();
 
175
}
 
176
 
 
177
void FullScreenWindow::setMainItem(QGraphicsObject *mainItem)
 
178
{
 
179
    if (m_mainItem.data() != mainItem) {
 
180
        if (m_mainItem) {
 
181
            m_mainItem.data()->setParent(mainItem->parent());
 
182
            m_mainItem.data()->removeEventFilter(this);
 
183
            m_mainItem.data()->setY(0);
 
184
            m_scene = 0;
 
185
        }
 
186
        m_mainItem = mainItem;
 
187
        if (mainItem) {
 
188
            mainItem->setParentItem(0);
 
189
            mainItem->setParent(this);
 
190
            m_scene = mainItem->scene();
 
191
        }
 
192
 
 
193
        mainItem->installEventFilter(this);
 
194
 
 
195
        //if this is called in Compenent.onCompleted we have to wait a loop the item is added to a scene
 
196
        QTimer::singleShot(0, this, SLOT(syncViewToMainItem()));
 
197
    }
 
198
}
 
199
 
 
200
void FullScreenWindow::syncViewToMainItem()
 
201
{
 
202
    if (!m_mainItem) {
 
203
        return;
 
204
    }
 
205
 
 
206
    //not have a scene? go up in the hyerarchy until we find something with a scene
 
207
    QGraphicsScene *scene = m_mainItem.data()->scene();
 
208
    if (!scene) {
 
209
        QObject *parent = m_mainItem.data();
 
210
        while ((parent = parent->parent())) {
 
211
            QGraphicsObject *qo = qobject_cast<QGraphicsObject *>(parent);
 
212
            if (qo) {
 
213
                scene = qo->scene();
 
214
 
 
215
                if (scene) {
 
216
                    scene->addItem(m_mainItem.data());
 
217
                    ++s_numItems;
 
218
                    Plasma::Corona *corona = qobject_cast<Plasma::Corona *>(scene);
 
219
                    QDeclarativeItem *di = qobject_cast<QDeclarativeItem *>(m_mainItem.data());
 
220
 
 
221
                    if (corona && di) {
 
222
                        if (!m_declarativeItemContainer) {
 
223
                            m_declarativeItemContainer = new DeclarativeItemContainer();
 
224
                            scene->addItem(m_declarativeItemContainer);
 
225
                            corona->addOffscreenWidget(m_declarativeItemContainer);
 
226
                        }
 
227
                        m_declarativeItemContainer->setDeclarativeItem(di);
 
228
                    } else {
 
229
                        m_mainItem.data()->setY(-10000*s_numItems);
 
230
                        m_mainItem.data()->setY(10000*s_numItems);
 
231
                    }
 
232
                    break;
 
233
                }
 
234
            }
 
235
        }
 
236
    }
 
237
 
 
238
    if (!scene) {
 
239
        return;
 
240
    }
 
241
 
 
242
    m_view->setScene(scene);
 
243
 
 
244
 
 
245
    if (m_declarativeItemContainer) {
 
246
        m_view->resize(m_declarativeItemContainer->size().toSize());
 
247
        m_view->setSceneRect(m_declarativeItemContainer->geometry());
 
248
    } else {
 
249
        QRectF itemGeometry(QPointF(m_mainItem.data()->x(), m_mainItem.data()->y()),
 
250
                        QSizeF(m_mainItem.data()->boundingRect().size()));
 
251
        m_view->resize(itemGeometry.size().toSize());
 
252
        m_view->setSceneRect(itemGeometry);
 
253
    }
 
254
 
 
255
    m_view->move(QApplication::desktop()->availableGeometry().center() - QPoint(m_view->width()/2, m_view->height()/2));
 
256
}
 
257
 
 
258
void FullScreenWindow::syncMainItemToView()
 
259
{
 
260
    if (!m_mainItem) {
 
261
        return;
 
262
    }
 
263
 
 
264
    m_mainItem.data()->setProperty("width", m_view->width());
 
265
    m_mainItem.data()->setProperty("height", m_view->height());
 
266
 
 
267
    if (m_declarativeItemContainer) {
 
268
        m_view->resize(m_declarativeItemContainer->size().toSize());
 
269
        m_view->setSceneRect(m_declarativeItemContainer->geometry());
 
270
    } else {
 
271
        QRectF itemGeometry(QPointF(m_mainItem.data()->x(), m_mainItem.data()->y()),
 
272
                        QSizeF(m_mainItem.data()->boundingRect().size()));
 
273
        m_view->setSceneRect(itemGeometry);
 
274
    }
 
275
}
 
276
 
 
277
bool FullScreenWindow::isVisible() const
 
278
{
 
279
    return m_view->isVisible();
 
280
}
 
281
 
 
282
void FullScreenWindow::setVisible(const bool visible)
 
283
{
 
284
    if (m_view->isVisible() != visible) {
 
285
        m_background->setVisible(visible);
 
286
        Plasma::WindowEffects::slideWindow(m_view->winId(), Plasma::BottomEdge, 0);
 
287
        m_view->setVisible(visible);
 
288
        unsigned long state = NET::Sticky | NET::StaysOnTop | NET::KeepAbove | NET::SkipTaskbar | NET::SkipPager;
 
289
        KWindowSystem::setState(m_view->effectiveWinId(), state);
 
290
        KWindowSystem::setState(m_background->effectiveWinId(), state);
 
291
        if (visible) {
 
292
            m_view->raise();
 
293
            KWindowSystem::forceActiveWindow(m_view->effectiveWinId());
 
294
        }
 
295
    }
 
296
}
 
297
 
 
298
QGraphicsView *FullScreenWindow::view() const
 
299
{
 
300
    return m_view;
 
301
}
 
302
 
 
303
 
 
304
QDeclarativeListProperty<QGraphicsObject> FullScreenWindow::title()
 
305
{
 
306
    if (m_rootObject) {
 
307
        return m_rootObject.data()->property("title").value<QDeclarativeListProperty<QGraphicsObject> >();
 
308
    } else {
 
309
        return QDeclarativeListProperty<QGraphicsObject>(this, m_dummyTitleElements);
 
310
    }
 
311
}
 
312
 
 
313
QDeclarativeListProperty<QGraphicsObject> FullScreenWindow::content()
 
314
{
 
315
    if (m_rootObject) {
 
316
        return m_rootObject.data()->property("content").value<QDeclarativeListProperty<QGraphicsObject> >();
 
317
    } else {
 
318
        return QDeclarativeListProperty<QGraphicsObject>(this, m_dummyContentElements);
 
319
    }
 
320
}
 
321
 
 
322
QDeclarativeListProperty<QGraphicsObject> FullScreenWindow::buttons()
 
323
{
 
324
    if (m_rootObject) {
 
325
        return m_rootObject.data()->property("buttons").value<QDeclarativeListProperty<QGraphicsObject> >();
 
326
    } else {
 
327
        return QDeclarativeListProperty<QGraphicsObject>(this, m_dummyButtonsElements);
 
328
    }
 
329
}
 
330
 
 
331
DialogStatus::Status FullScreenWindow::status() const
 
332
{
 
333
    if (m_rootObject) {
 
334
        return (DialogStatus::Status)m_rootObject.data()->property("status").toInt();
 
335
    } else {
 
336
        return DialogStatus::Closed;
 
337
    }
 
338
}
 
339
 
 
340
 
 
341
void FullScreenWindow::statusHasChanged()
 
342
{
 
343
    if (status() == DialogStatus::Closed) {
 
344
        setVisible(false);
 
345
    } else {
 
346
        setVisible(true);
 
347
    }
 
348
    emit statusChanged();
 
349
}
 
350
 
 
351
void FullScreenWindow::open()
 
352
{
 
353
    if (m_rootObject) {
 
354
        QMetaObject::invokeMethod(m_rootObject.data(), "open");
 
355
    }
 
356
}
 
357
 
 
358
void FullScreenWindow::accept()
 
359
{
 
360
    if (m_rootObject) {
 
361
        QMetaObject::invokeMethod(m_rootObject.data(), "accept");
 
362
    }
 
363
}
 
364
 
 
365
void FullScreenWindow::reject()
 
366
{
 
367
    if (m_rootObject) {
 
368
        QMetaObject::invokeMethod(m_rootObject.data(), "reject");
 
369
    }
 
370
}
 
371
 
 
372
void FullScreenWindow::close()
 
373
{
 
374
    if (m_rootObject) {
 
375
        QMetaObject::invokeMethod(m_rootObject.data(), "close");
 
376
    }
 
377
}
 
378
 
 
379
 
 
380
 
 
381
 
 
382
bool FullScreenWindow::eventFilter(QObject *watched, QEvent *event)
 
383
{
 
384
    if (watched == m_mainItem.data() &&
 
385
        (event->type() == QEvent::GraphicsSceneResize)) {
 
386
        syncViewToMainItem();
 
387
    } else if (watched == m_view &&
 
388
        (event->type() == QEvent::Resize)) {
 
389
        syncMainItemToView();
 
390
    }
 
391
    return false;
 
392
}
 
393
 
 
394
 
 
395
 
 
396
#include "fullscreenwindow.moc"
 
397