not quite so much needs to be delayed to the init() function
[personal-kdebase.git] / workspace / kcontrol / randr / outputconfig.cpp
blob82322b56d72af5d4c1c76f556efec9d2d63ba028
1 /*
2 * Copyright (c) 2007 Gustavo Pichorim Boiko <gustavo.boiko@kdemail.net>
3 * Copyright (c) 2007, 2008 Harry Bock <hbock@providence.edu>
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License
16 * along with this program; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20 #include "outputconfig.h"
21 #include "outputgraphicsitem.h"
22 #include "randroutput.h"
23 #include "randrscreen.h"
24 #include "randrmode.h"
25 #include <kdebug.h>
27 OutputConfig::OutputConfig(QWidget *parent, RandROutput *output, OutputGraphicsItem *item)
28 : QWidget(parent)
30 m_output = output;
31 Q_ASSERT(output);
33 m_item = item;
34 Q_ASSERT(item);
36 setupUi(this);
38 // connect signals
39 connect(positionCombo, SIGNAL(currentIndexChanged(int)),
40 this, SLOT(positionComboChanged(int)));
41 connect(sizeCombo, SIGNAL(currentIndexChanged(int)),
42 this, SLOT(updateRateList(int)));
43 connect(m_output, SIGNAL(outputChanged(RROutput, int)),
44 this, SLOT(outputChanged(RROutput, int)));
46 connect(sizeCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setConfigDirty()));
47 connect(refreshCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setConfigDirty()));
48 connect(orientationCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setConfigDirty()));
49 connect(positionCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setConfigDirty()));
50 connect(positionOutputCombo, SIGNAL(currentIndexChanged(int)), this, SLOT(setConfigDirty()));
52 load();
55 OutputConfig::~OutputConfig()
59 RandROutput *OutputConfig::output(void) const
61 return m_output;
64 QPoint OutputConfig::position(void) const
66 int index = positionCombo->currentIndex();
67 if((Relation)positionCombo->itemData(index).toInt() == Absolute)
68 return QPoint(absolutePosX->text().toInt(), absolutePosY->text().toInt());
70 return QPoint(0, 0);
73 QSize OutputConfig::resolution(void) const
75 return sizeCombo->itemData(sizeCombo->currentIndex()).toSize();
78 float OutputConfig::refreshRate(void) const
80 float rate = float(refreshCombo->itemData(refreshCombo->currentIndex()).toDouble());
81 if(rate == 0.0f) {
82 RateList rates = m_output->refreshRates(resolution());
83 return rates.first();
85 return rate;
88 int OutputConfig::rotation(void) const
90 return orientationCombo->itemData(orientationCombo->currentIndex()).toInt();
93 bool OutputConfig::hasPendingChanges(void) const
95 if (m_output->rect() != QRect(position(), resolution())) {
96 return true;
98 else if (m_output->rotation() != rotation()) {
99 return true;
101 else if (m_output->refreshRate() != refreshRate()) {
102 return true;
104 return false;
107 void OutputConfig::outputChanged(RROutput output, int changes)
109 Q_ASSERT(m_output->id() == output);
110 kDebug() << "Output" << m_output->name() << "changed. ( mask =" << QString::number(changes) << ")";
112 if(changes & RandR::ChangeOutputs) {
113 kDebug() << "Outputs changed.";
116 if(changes & RandR::ChangeCrtc) {
117 kDebug() << "Output CRTC changed.";
119 updateSizeList();
120 updateRateList();
121 updateRotationList();
124 if(changes & RandR::ChangeRect) {
125 QRect r = m_output->rect();
126 kDebug() << "Output rect changed:" << r;
127 //m_item->setRect(0, 0, r.width(), r.height());
128 m_item->setRect(r);
129 //m_item->setPos
132 if(changes & RandR::ChangeRotation) {
133 kDebug() << "Output rotation changed.";
134 updateRotationList();
137 if(changes & RandR::ChangeConnection) {
138 kDebug() << "Output connection status changed.";
139 setEnabled(m_output->isConnected());
142 if(changes & RandR::ChangeRate) {
143 kDebug() << "Output rate changed.";
144 updateRateList();
147 if(changes & RandR::ChangeMode) {
148 kDebug() << "Output mode changed.";
149 updateSizeList();
151 // This NEEDS to be fixed..
152 //QSize modeSize = m_output->screen()->mode(m_output->mode()).size();
153 QSize modeSize = m_output->mode().size();
154 updateRateList(sizeCombo->findData(modeSize));
158 QString OutputConfig::positionName(Relation position)
160 switch(position) {
161 case LeftOf: return i18n("Left of");
162 case RightOf: return i18n("Right of");
163 case Over: return i18nc("Output is placed above another one", "Above");
164 case Under: return i18nc("Output is placed below another one", "Below");
165 case SameAs: return i18n("Clone of");
166 case Absolute: return i18nc("Fixed, abitrary position", "Absolute");
169 return i18n("No relative position");
172 void OutputConfig::load()
174 kDebug() << "Loading output configuration for" << m_output->name();
175 setEnabled( m_output->isConnected() );
177 orientationCombo->clear();
179 m_item->setVisible(m_output->isActive());
180 if (!m_output->isConnected())
181 return;
183 /* Mode size configuration */
184 updateSizeList();
186 /* Output rotation and relative position */
187 updateRotationList();
188 updatePositionList();
190 // update the item
191 m_item->setRect( 0, 0, m_output->rect().width(), m_output->rect().height());
192 kDebug() << " Setting graphic rect pos: " << m_output->rect().topLeft();
193 m_item->setPos( m_output->rect().topLeft() );
195 emit updateView();
198 void OutputConfig::setConfigDirty(void)
200 m_changed = true;
201 emit optionChanged();
204 void OutputConfig::positionComboChanged(int item)
206 Relation rel;
207 rel = (Relation)positionCombo->itemData(item).toInt();
209 bool isAbsolute = (rel == Absolute);
211 positionOutputCombo->setVisible(!isAbsolute);
212 absolutePosX->setVisible(isAbsolute);
213 absolutePosY->setVisible(isAbsolute);
215 if(isAbsolute) {
216 int posX = m_output->rect().topLeft().x();
217 int posY = m_output->rect().topLeft().y();
219 absolutePosX->setText(QString::number(posX));
220 absolutePosY->setText(QString::number(posY));
224 void OutputConfig::updatePositionList(void)
226 positionCombo->clear();
227 positionOutputCombo->clear();
229 Relation rel = SameAs;
230 // FIXME: get default value from KConfig
231 for(int i = -1; i < 5; i++)
232 positionCombo->addItem(OutputConfig::positionName((Relation)i), i);
234 int index = positionCombo->findData((int)rel);
235 if(index != -1)
236 positionCombo->setCurrentIndex(index);
238 /* Relative Output Name Configuration */
239 OutputMap outputs = m_output->screen()->outputs();
240 foreach(RandROutput *output, outputs)
241 positionOutputCombo->addItem(QIcon(output->icon()), output->name(), (int)output->id());
243 // FIXME: get this from Kconfig again
244 /*if(m_output->relation(0) != m_output) {
245 index = positionOutputCombo->findData((int)m_output->relation(0)->id());
246 if(index != -1)
247 positionOutputCombo->setCurrentIndex(index);
249 bool enabled = (m_output->screen()->activeCount() >= 2);
250 positionLabel->setEnabled(enabled);
251 positionCombo->setEnabled(enabled);
252 positionOutputCombo->setEnabled(enabled);
254 // FIXME: RandRScreen::applyProposed() has a bit of code for positioning
255 // outputs, but it's commented out and might not work as is. Until someone
256 // gets this to work, it's probably better not to show these controls.
257 positionLabel->setVisible(false);
258 positionCombo->setVisible(false);
259 positionOutputCombo->setVisible(false);
262 void OutputConfig::updateRotationList(void)
264 orientationCombo->clear();
265 int rotations = m_output->rotations();
266 for(int i =0; i < 6; ++i) {
267 int rot = (1 << i);
268 if (rot & rotations) {
269 orientationCombo->addItem(QIcon(RandR::rotationIcon(rot, RandR::Rotate0)),
270 RandR::rotationName(rot), rot);
274 int index = orientationCombo->findData(m_output->rotation());
275 if (index != -1)
276 orientationCombo->setCurrentIndex( index );
279 void OutputConfig::updateSizeList(void)
281 SizeList sizes = m_output->sizes();
282 RandRMode preferredMode = m_output->preferredMode();
283 sizeCombo->clear();
284 sizeCombo->addItem( i18n("Disabled"), QSize(0, 0) );
286 foreach (QSize s, sizes) {
287 QString sizeDesc = QString("%1x%2").arg(s.width()).arg(s.height());
288 if (preferredMode.isValid() && s == preferredMode.size()) {
289 sizeDesc = i18nc("Automatic screen size (native resolution)",
290 "%1 (Auto)", sizeDesc);
292 sizeCombo->addItem( sizeDesc, s );
295 int index = sizeCombo->findData( m_output->rect().size() );
296 if (index != -1)
297 sizeCombo->setCurrentIndex( index );
299 index = refreshCombo->findData(m_output->refreshRate());
300 if (index != -1)
301 refreshCombo->setCurrentIndex(index);
304 void OutputConfig::updateRateList(int resolutionIndex)
306 QSize resolution = sizeCombo->itemData(resolutionIndex).toSize();
307 if((resolution == QSize(0, 0)) || !resolution.isValid()) {
308 refreshCombo->setEnabled(false);
309 return;
312 ModeList modeList = m_output->modes();
314 refreshCombo->clear();
315 refreshCombo->addItem(i18nc("Automatic configuration", "Auto"), 0.0f);
316 refreshCombo->setEnabled(true);
317 foreach(RRMode m, modeList) {
318 RandRMode outMode = m_output->screen()->mode(m);
319 if(outMode.isValid() && outMode.size() == resolution) {
320 float rate = outMode.refreshRate();
321 refreshCombo->addItem(ki18n("%1 Hz").subs(rate, 0, 'f', 1).toString(), rate);
326 void OutputConfig::updateRateList()
328 if (sizeCombo->currentIndex() == -1)
329 return;
331 // update the refresh rate list to reflect the currently selected
332 // resolution
333 updateRateList(sizeCombo->currentIndex());
336 #include "outputconfig.moc"