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

« back to all changes in this revision

Viewing changes to kcm/src/unifiedoutputconfig.cpp

  • Committer: Package Import Robot
  • Author(s): Scarlett Clark, Scarlett Clark, Jonathan Riddell, Harald Sitter
  • Date: 2014-08-20 08:35:15 UTC
  • mfrom: (1.1.7)
  • Revision ID: package-import@ubuntu.com-20140820083515-i9lk9nyt0adwd2q5
Tags: 2.0.0~git20141114-0ubuntu1
[ Scarlett Clark ]
* Update packaging for frameworks branch
* Git snapshot of the frameworks branch

[ Jonathan Riddell ]
* Remove kscreen-console.1 manpage which is out of date

[ Harald Sitter ]
* switch to new pkg-kde-tools

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright 2013  Daniel Vrátil <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 "unifiedoutputconfig.h"
 
23
#include "collapsablebutton.h"
 
24
#include "resolutionslider.h"
 
25
#include "utils.h"
 
26
 
 
27
#include <QComboBox>
 
28
#include <QIcon>
 
29
#include <KLocalizedString>
 
30
 
 
31
#include <QGridLayout>
 
32
#include <QSpacerItem>
 
33
#include <QCheckBox>
 
34
#include <QGroupBox>
 
35
 
 
36
#include <kscreen/output.h>
 
37
#include <kscreen/config.h>
 
38
 
 
39
 
 
40
bool operator<(const QSize &s1, const QSize &s2)
 
41
{
 
42
    return s1.width() * s1.height() < s2.width() * s2.height();
 
43
}
 
44
 
 
45
template<>
 
46
bool qMapLessThanKey(const QSize &s1, const QSize &s2)
 
47
{
 
48
    return s1 < s2;
 
49
}
 
50
 
 
51
 
 
52
UnifiedOutputConfig::UnifiedOutputConfig(KScreen::Config *config, QWidget *parent)
 
53
    : OutputConfig(parent)
 
54
    , mConfig(config)
 
55
{
 
56
}
 
57
 
 
58
UnifiedOutputConfig::~UnifiedOutputConfig()
 
59
{
 
60
}
 
61
 
 
62
void UnifiedOutputConfig::setOutput(KScreen::Output *output)
 
63
{
 
64
    mOutput = output;
 
65
 
 
66
    mClones.clear();
 
67
    Q_FOREACH (int id, mOutput->clones()) {
 
68
        mClones << mConfig->output(id);
 
69
    }
 
70
    mClones << mOutput;
 
71
 
 
72
    OutputConfig::setOutput(output);
 
73
}
 
74
 
 
75
void UnifiedOutputConfig::initUi()
 
76
{
 
77
    QVBoxLayout *vbox = new QVBoxLayout(this);
 
78
    mTitle = new QLabel(this);
 
79
    mTitle->setAlignment(Qt::AlignHCenter);
 
80
    vbox->addWidget(mTitle);
 
81
 
 
82
    setTitle(i18n("Unified Outputs"));
 
83
 
 
84
    QGridLayout *formLayout = new QGridLayout();
 
85
    vbox->addLayout(formLayout);
 
86
    vbox->addStretch(2);
 
87
 
 
88
    KScreen::Output *fakeOutput = createFakeOutput();
 
89
    mResolution = new ResolutionSlider(fakeOutput, this);
 
90
    connect(mResolution, SIGNAL(resolutionChanged(QSize)), SLOT(slotResolutionChanged(QSize)));
 
91
    formLayout->addWidget(new QLabel(i18n("Resolution:"), this), 1, 0);
 
92
    formLayout->addWidget(mResolution, 1, 1);
 
93
    slotResolutionChanged(mResolution->currentResolution());
 
94
 
 
95
    mRotation = new QComboBox(this);
 
96
    connect(mRotation, SIGNAL(currentIndexChanged(int)), SLOT(slotRotationChanged(int)));
 
97
    mRotation->addItem(QIcon::fromTheme(QLatin1String("arrow-up")), i18n("Normal"), KScreen::Output::None);
 
98
    mRotation->addItem(QIcon::fromTheme(QLatin1String("arrow-left")), i18n("90° clockwise"), KScreen::Output::Left);
 
99
    mRotation->addItem(QIcon::fromTheme(QLatin1String("arrow-down")), i18n("Upside down"), KScreen::Output::Inverted);
 
100
    mRotation->addItem(QIcon::fromTheme(QLatin1String("arrow-right")), i18n("90° counterclockwise"), KScreen::Output::Right);
 
101
    formLayout->addWidget(new QLabel(i18n("Orientation:"), this), 2, 0);
 
102
    formLayout->addWidget(mRotation, 2, 1);
 
103
 
 
104
    formLayout->addItem(new QSpacerItem(1, 1, QSizePolicy::Expanding, QSizePolicy::Minimum), 0, 2, 3, 1);
 
105
}
 
106
 
 
107
KScreen::Output *UnifiedOutputConfig::createFakeOutput()
 
108
{
 
109
    // Find set of common resolutions
 
110
    QMap<QSize, int> commonSizes;
 
111
    Q_FOREACH (KScreen::Output *clone, mClones) {
 
112
        QList<QSize> processedSizes;
 
113
        Q_FOREACH (KScreen::Mode *mode, clone->modes()) {
 
114
            // Make sure we don't count some modes multiple times because of different
 
115
            // refresh rates
 
116
            if (processedSizes.contains(mode->size())) {
 
117
                continue;
 
118
            }
 
119
 
 
120
            processedSizes << mode->size();
 
121
 
 
122
            if (commonSizes.contains(mode->size())) {
 
123
                commonSizes[mode->size()]++;
 
124
            } else {
 
125
                commonSizes.insert(mode->size(), 1);
 
126
            }
 
127
        }
 
128
    }
 
129
 
 
130
    KScreen::Output *fakeOutput = new KScreen::Output(this);
 
131
 
 
132
    // This will give us list of resolution that are shared by all outputs
 
133
    QList<QSize> commonResults = commonSizes.keys(mClones.count());
 
134
    // If there are no common resolution, fallback to smallest preferred mode
 
135
    if (commonResults.isEmpty()) {
 
136
        QSize smallestMode;
 
137
        Q_FOREACH (KScreen::Output *clone, mClones) {
 
138
            qDebug() << smallestMode << clone->preferredMode()->size();
 
139
            if (!smallestMode.isValid() || clone->preferredMode()->size() < smallestMode) {
 
140
                smallestMode = clone->preferredMode()->size();
 
141
            }
 
142
        }
 
143
        commonResults << smallestMode;
 
144
    }
 
145
    qSort(commonResults);
 
146
 
 
147
    KScreen::ModeList modes;
 
148
    Q_FOREACH (const QSize &size, commonResults) {
 
149
        KScreen::Mode *mode = new KScreen::Mode(fakeOutput);
 
150
        mode->setSize(size);
 
151
        mode->setId(Utils::sizeToString(size));
 
152
        mode->setName(mode->id());
 
153
        modes.insert(mode->id(), mode);
 
154
    }
 
155
    fakeOutput->setModes(modes);
 
156
    fakeOutput->setCurrentModeId(Utils::sizeToString(commonResults.last()));
 
157
    return fakeOutput;
 
158
}
 
159
 
 
160
void UnifiedOutputConfig::slotResolutionChanged(const QSize &size)
 
161
{
 
162
   // Ignore disconnected outputs
 
163
    if (!size.isValid()) {
 
164
        return;
 
165
    }
 
166
 
 
167
    Q_FOREACH (KScreen::Output *clone, mClones) {
 
168
        const QString &id = findBestMode(clone, size);
 
169
        if (id.isEmpty()) {
 
170
            // FIXME: Error?
 
171
            return;
 
172
        }
 
173
 
 
174
        clone->setCurrentModeId(id);
 
175
    }
 
176
 
 
177
    Q_EMIT changed();
 
178
}
 
179
 
 
180
QString UnifiedOutputConfig::findBestMode(const KScreen::Output *output, const QSize &size)
 
181
{
 
182
    float refreshRate = 0;
 
183
    QString id;
 
184
    Q_FOREACH (KScreen::Mode *mode, output->modes()) {
 
185
        if (mode->size() == size && mode->refreshRate() > refreshRate) {
 
186
            refreshRate = mode->refreshRate();
 
187
            id = mode->id();
 
188
        }
 
189
    }
 
190
 
 
191
    return id;
 
192
}