~ubuntu-branches/ubuntu/wily/kscreen/wily

« back to all changes in this revision

Viewing changes to plasma/kscreenapplet.cpp

  • Committer: Package Import Robot
  • Author(s): Howard Chan
  • Date: 2013-03-11 21:24:40 UTC
  • mfrom: (1.1.1)
  • Revision ID: package-import@ubuntu.com-20130311212440-85jrf9k7tl8csj0f
Tags: 0.0.71+git20130311-0ubuntu1
* New upstream snapshot. 
* Make build-depends libkscreen (>= 0.0.71+git20130311 so it can build

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2013  Dan Vratil <dvratil@redhat.com>
 
3
 *
 
4
 * This program is free software; you can redistribute it and/or
 
5
 * modify it under the terms of the GNU General Public License as
 
6
 * published by the Free Software Foundation; either version 2 of
 
7
 * the License or (at your option) version 3 or any later version
 
8
 * accepted by the membership of KDE e.V. (or its successor approved
 
9
 * by the membership of KDE e.V.), which shall act as a proxy
 
10
 * defined in Section 14 of version 3 of the license.
 
11
 *
 
12
 * This program is distributed in the hope that it will be useful,
 
13
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
14
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
15
 * GNU General Public License for more details.
 
16
 *
 
17
 * You should have received a copy of the GNU General Public License
 
18
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
19
 *
 
20
 */
 
21
 
 
22
#include "kscreenapplet.h"
 
23
 
 
24
#include <QTimer>
 
25
#include <QDeclarativeItem>
 
26
#include <QGraphicsSceneMouseEvent>
 
27
 
 
28
#include <QDBusConnection>
 
29
#include <QDBusInterface>
 
30
 
 
31
#include <Plasma/Package>
 
32
#include <Plasma/DeclarativeWidget>
 
33
#include <KToolInvocation>
 
34
 
 
35
#include <kscreen/config.h>
 
36
#include <kscreen/output.h>
 
37
#include <kscreen/edid.h>
 
38
 
 
39
bool leftPos(KScreen::Output* output1, KScreen::Output* output2) {
 
40
    return (output1->pos().x() < output2->pos().x());
 
41
}
 
42
 
 
43
KScreenApplet::KScreenApplet(QObject *parent, const QVariantList &args):
 
44
    Plasma::PopupApplet(parent, args),
 
45
    m_declarativeWidget(0),
 
46
    m_hasNewOutput(false)
 
47
{
 
48
    qmlRegisterType<KScreenApplet>("org.kde.kscreen", 1, 0, "KScreenApplet");
 
49
    setPopupIcon(QLatin1String("video-display"));
 
50
 
 
51
    setenv("KSCREEN_BACKEND", "XRandR", false);
 
52
 
 
53
    m_resetTimer = new QTimer(this);
 
54
}
 
55
 
 
56
KScreenApplet::KScreenApplet():
 
57
    PopupApplet(0, QVariantList())
 
58
{
 
59
 
 
60
}
 
61
 
 
62
KScreenApplet::~KScreenApplet()
 
63
{
 
64
}
 
65
 
 
66
void KScreenApplet::init()
 
67
{
 
68
    QDBusConnection connection = QDBusConnection::sessionBus();
 
69
    bool conn = connection.connect(QLatin1String("org.kde.kded"),
 
70
                                   QLatin1String("/modules/kscreen"),
 
71
                                   QLatin1String("org.kde.KScreen"),
 
72
                                   QLatin1String("unkownOutputConnected"),
 
73
                                   //QLatin1String("outputConnected"),
 
74
                                   QLatin1String("s"),
 
75
                                   this, SLOT(slotUnknownDisplayConnected(QString)));
 
76
    if (!conn) {
 
77
        setFailedToLaunch(true, i18n("Failed to connect to KScreen daemon"));
 
78
    }
 
79
}
 
80
 
 
81
void KScreenApplet::initDeclarativeWidget()
 
82
{
 
83
    m_declarativeWidget = new Plasma::DeclarativeWidget(this);
 
84
 
 
85
    Plasma::PackageStructure::Ptr structure = Plasma::PackageStructure::load("Plasma/Generic");
 
86
    Plasma::Package package(QString(), "org.kde.plasma.kscreen.qml", structure);
 
87
    m_declarativeWidget->setQmlPath(package.filePath("mainscript"));
 
88
 
 
89
    QDeclarativeItem *rootObject = qobject_cast<QDeclarativeItem*>(m_declarativeWidget->rootObject());
 
90
    if (!rootObject) {
 
91
        setFailedToLaunch(true, i18n("Failed to load root object"));
 
92
        return;
 
93
    }
 
94
 
 
95
    connect(rootObject, SIGNAL(runKCM()), SLOT(slotRunKCM()));
 
96
    connect(rootObject, SIGNAL(applyAction(int)), SLOT(slotApplyAction(int)));
 
97
}
 
98
 
 
99
 
 
100
QGraphicsWidget *KScreenApplet::graphicsWidget()
 
101
{
 
102
    if (hasFailedToLaunch()) {
 
103
        return 0;
 
104
    }
 
105
 
 
106
    if (!m_declarativeWidget) {
 
107
        initDeclarativeWidget();
 
108
    }
 
109
 
 
110
    return m_declarativeWidget;
 
111
}
 
112
 
 
113
void KScreenApplet::slotUnknownDisplayConnected(const QString &outputName)
 
114
{
 
115
    kDebug() << "New display connected to output" << outputName;
 
116
    m_newOutputName = outputName;
 
117
 
 
118
    QString displayName;
 
119
    KScreen::Output *newOutput = outputForName(outputName, KScreen::Config::current());
 
120
    KScreen::Edid *edid = newOutput->edid();
 
121
    if (!edid) {
 
122
        displayName = outputName;
 
123
    } else {
 
124
        displayName = edid->vendor() + QLatin1String(" ") + edid->name();
 
125
    }
 
126
 
 
127
    QDeclarativeItem *rootObject = qobject_cast<QDeclarativeItem*>(m_declarativeWidget->rootObject());
 
128
    rootObject->setProperty("displayName", displayName);
 
129
 
 
130
    m_hasNewOutput = true;
 
131
    showPopup();
 
132
 
 
133
    // Show the notification for only 20 seconds, should be enough...
 
134
    m_resetTimer->singleShot(20000, this, SLOT(slotResetApplet()));
 
135
}
 
136
 
 
137
void KScreenApplet::slotApplyAction(int actionId)
 
138
{
 
139
    DisplayAction action = (DisplayAction) actionId;
 
140
    kDebug() << "Applying changes" << action;
 
141
 
 
142
    if (action == ActionNone) {
 
143
        kDebug() << "Action: None";
 
144
        slotResetApplet();
 
145
        return;
 
146
    }
 
147
 
 
148
    KScreen::Config *config = KScreen::Config::current();
 
149
    KScreen::Output *newOutput = outputForName(m_newOutputName, config);
 
150
    kDebug() << "Output for" << m_newOutputName << ":" << newOutput;
 
151
 
 
152
    if (newOutput == 0) {
 
153
        slotResetApplet();
 
154
        return;
 
155
    }
 
156
 
 
157
    if (action == ActionDisable) {
 
158
        kDebug() << "Action: Disable";
 
159
        newOutput->setEnabled(false);
 
160
        slotResetApplet();
 
161
        return;
 
162
    }
 
163
 
 
164
    newOutput->setEnabled(true);
 
165
    newOutput->setCurrentModeId(newOutput->preferredModeId());
 
166
    KScreen::Mode *newMode = newOutput->currentMode();
 
167
    kDebug() << "It's mode is" << newMode;
 
168
 
 
169
    // Only take enabled outputs, order them from left to right
 
170
    KScreen::OutputList allOutputs = config->outputs();
 
171
    KScreen::OutputList::Iterator iter;
 
172
    QList<KScreen::Output*> outputs;
 
173
    for (iter = allOutputs.begin(); iter != allOutputs.end(); ++iter) {
 
174
        KScreen::Output *output = iter.value();
 
175
        if (output->isConnected() && output->isEnabled()) {
 
176
            outputs << output;
 
177
        }
 
178
    }
 
179
    qSort(outputs.begin(), outputs.end(), &leftPos);
 
180
 
 
181
    if (action == ActionClone) {
 
182
        kDebug() << "Action: Clone";
 
183
        /* Set the new output as a clone of the primary output */
 
184
        KScreen::Output *primary = config->primaryOutput();
 
185
        if (!primary || primary == newOutput) {
 
186
            primary = outputs.first();
 
187
            if (primary == newOutput) {
 
188
                primary = outputs.at(1);
 
189
            }
 
190
        }
 
191
        newOutput->setPos(primary->pos());
 
192
        QList<int> clones = primary->clones();
 
193
        clones << newOutput->id();
 
194
        primary->setClones(clones);
 
195
    } else if (action == ActionExtendLeft) {
 
196
        kDebug() << "Action: ExtendLeft";
 
197
        int globalWidth = newMode->size().width();
 
198
        newOutput->setPos(QPoint(0, 0));
 
199
        Q_FOREACH(KScreen::Output *output, outputs) {
 
200
            if (!output->isConnected() || !output->isEnabled() || (output == newOutput)) {
 
201
                continue;
 
202
            }
 
203
 
 
204
            QPoint pos = output->pos();
 
205
            pos.setX(globalWidth);
 
206
            output->setPos(pos);
 
207
            globalWidth += output->currentMode()->size().width();
 
208
        }
 
209
 
 
210
    } else if (action == ActionExtendRight) {
 
211
        kDebug() << "Action: ExtendRight";
 
212
        int globalWidth = 0;
 
213
        Q_FOREACH(KScreen::Output *output, outputs) {
 
214
            if (!output->isConnected() || !output->isEnabled() || (output == newOutput)) {
 
215
                continue;
 
216
            }
 
217
 
 
218
            QPoint pos = output->pos();
 
219
            pos.setX(globalWidth);
 
220
            output->setPos(pos);
 
221
            globalWidth += output->currentMode()->size().width();
 
222
        }
 
223
        newOutput->setPos(QPoint(globalWidth, 0));
 
224
    }
 
225
 
 
226
    /* Update the settings */
 
227
    Q_FOREACH(KScreen::Output *output, outputs) {
 
228
        if (!output->isEnabled()) {
 
229
            continue;
 
230
        }
 
231
 
 
232
        kDebug() << output->name();
 
233
        kDebug() << "\tSize:" << output->currentMode()->size();
 
234
        kDebug() << "\tPos:" << output->pos();
 
235
        kDebug() << "\tClones:" << output->clones();
 
236
    }
 
237
 
 
238
    KScreen::Config::setConfig(config);
 
239
    slotResetApplet();
 
240
}
 
241
 
 
242
void KScreenApplet::slotRunKCM()
 
243
{
 
244
    KToolInvocation::kdeinitExec(
 
245
        QLatin1String("kcmshell4"),
 
246
        QStringList() << QLatin1String("kscreen"));
 
247
 
 
248
    hidePopup();
 
249
}
 
250
 
 
251
void KScreenApplet::slotResetApplet()
 
252
{
 
253
    m_hasNewOutput = false;
 
254
    m_newOutputName.clear();
 
255
    hidePopup();
 
256
}
 
257
 
 
258
void KScreenApplet::popupEvent(bool show)
 
259
{
 
260
    if (show && !m_hasNewOutput) {
 
261
        slotRunKCM();
 
262
        return;
 
263
    }
 
264
 
 
265
    Plasma::PopupApplet::popupEvent(show);
 
266
}
 
267
 
 
268
KScreen::Output *KScreenApplet::outputForName(const QString &name, KScreen::Config *config)
 
269
{
 
270
    KScreen::OutputList outputs = config->outputs();
 
271
    KScreen::OutputList::Iterator iter;
 
272
    for (iter = outputs.begin(); iter != outputs.end(); ++iter) {
 
273
        KScreen::Output *output = iter.value();
 
274
 
 
275
        if (output->name() == name) {
 
276
            return output;
 
277
        }
 
278
    }
 
279
 
 
280
    return 0;
 
281
}
 
282
 
 
283
#include "kscreenapplet.moc"