1 /*
2     Copyright (C) 2016  P.L. Lucas <selairi@gmail.com>
3 
4     This library is free software; you can redistribute it and/or
5     modify it under the terms of the GNU Lesser General Public
6     License as published by the Free Software Foundation; either
7     version 2.1 of the License, or (at your option) any later version.
8 
9     This library 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 GNU
12     Lesser General Public License for more details.
13 
14     You should have received a copy of the GNU Lesser General Public
15     License along with this library; if not, write to the Free Software
16     Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
17 */
18 
19 #include "brightnesssettings.h"
20 #include "outputwidget.h"
21 #include <QMessageBox>
22 #include <QPushButton>
23 
BrightnessSettings(QWidget * parent)24 BrightnessSettings::BrightnessSettings(QWidget *parent):QDialog(parent)
25 {
26     ui = new Ui::BrightnessSettings();
27     ui->setupUi(this);
28 
29     mBrightness = new XRandrBrightness();
30     mMonitors = mBrightness->getMonitorsInfo();
31     mMonitorsInitial = mBrightness->getMonitorsInfo();
32     mBacklight = new LXQt::Backlight(this);
33 
34     ui->headIconLabel->setPixmap(QIcon::fromTheme(QStringLiteral("display-brightness-symbolic")).pixmap(32, 32));
35 
36     ui->backlightSlider->setEnabled(mBacklight->isBacklightAvailable() || mBacklight->isBacklightOff());
37     ui->backlightGroupBox->setEnabled(mBacklight->isBacklightAvailable() || mBacklight->isBacklightOff());
38     if(mBacklight->isBacklightAvailable()) {
39         setBacklightSliderValue(mBacklight->getBacklight());
40 
41         mInitialBacklightValue = mLastBacklightValue = mBacklight->getBacklight();
42         connect(ui->backlightSlider, &QSlider::valueChanged, this, &BrightnessSettings::setBacklight);
43 
44         connect(ui->backlightDownButton, &QToolButton::clicked,
45             [this](bool){ ui->backlightSlider->setValue(ui->backlightSlider->value()-1); });
46         connect(ui->backlightUpButton, &QToolButton::clicked,
47             [this](bool){ ui->backlightSlider->setValue(ui->backlightSlider->value()+1); });
48     }
49 
50     for(const MonitorInfo &monitor: qAsConst(mMonitors))
51     {
52         OutputWidget *output = new OutputWidget(monitor, this);
53         ui->layout->addWidget(output);
54         output->show();
55         connect(output, &OutputWidget::changed, this, &BrightnessSettings::monitorSettingsChanged);
56         connect(this, &BrightnessSettings::monitorReverted, output, &OutputWidget::setRevertedValues);
57     }
58 
59     mConfirmRequestTimer.setSingleShot(true);
60     mConfirmRequestTimer.setInterval(1000);
61     connect(&mConfirmRequestTimer, &QTimer::timeout, this, &BrightnessSettings::requestConfirmation);
62 
63     connect(ui->buttonBox, &QDialogButtonBox::clicked,
64         [this](QAbstractButton *button) {
65             if(ui->buttonBox->button(QDialogButtonBox::Reset) == button) {
66                 revertValues();
67             }
68         } );
69 }
70 
~BrightnessSettings()71 BrightnessSettings::~BrightnessSettings()
72 {
73     delete ui;
74     ui = nullptr;
75 
76     delete mBrightness;
77     mBrightness = nullptr;
78 }
79 
setBacklight()80 void BrightnessSettings::setBacklight()
81 {
82     int value = ui->backlightSlider->value();
83     // Set the minimum to 5% of the maximum to prevent a black screen
84     int minBacklight = qMax(qRound((qreal)(mBacklight->getMaxBacklight())*0.05), 1);
85     int maxBacklight = mBacklight->getMaxBacklight();
86     int interval = maxBacklight - minBacklight;
87     if(interval > 100)
88         value = (value * maxBacklight) / 100;
89     mBacklight->setBacklight(value);
90 
91     if (ui->confirmCB->isChecked())
92         mConfirmRequestTimer.start();
93 }
94 
monitorSettingsChanged(MonitorInfo monitor)95 void BrightnessSettings::monitorSettingsChanged(MonitorInfo monitor)
96 {
97     mBrightness->setMonitorsSettings(QList<MonitorInfo>{}  << monitor);
98     if (ui->confirmCB->isChecked())
99         mConfirmRequestTimer.start();
100     else {
101         for (auto & m : mMonitors) {
102             if (m.id() == monitor.id() && m.name() == monitor.name()) {
103                 m.setBacklight(monitor.backlight());
104                 m.setBrightness(monitor.brightness());
105             }
106         }
107     }
108 }
109 
requestConfirmation()110 void BrightnessSettings::requestConfirmation()
111 {
112     QMessageBox msg{QMessageBox::Question, tr("Brightness settings changed")
113         , tr("Confirmation required. Are the settings correct?")
114         , QMessageBox::Yes | QMessageBox::No};
115     int timeout = 5; // seconds
116     QString no_text = msg.button(QMessageBox::No)->text();
117     no_text += QStringLiteral("(%1)");
118     msg.setButtonText(QMessageBox::No, no_text.arg(timeout));
119     msg.setDefaultButton(QMessageBox::No);
120 
121     QTimer timeoutTimer;
122     timeoutTimer.setSingleShot(false);
123     timeoutTimer.setInterval(1000);
124     connect(&timeoutTimer, &QTimer::timeout, [&] {
125         msg.setButtonText(QMessageBox::No, no_text.arg(--timeout));
126         if (timeout == 0)
127         {
128             timeoutTimer.stop();
129             msg.reject();
130         }
131     });
132     timeoutTimer.start();
133 
134     if (QMessageBox::Yes == msg.exec())
135     {
136         // re-read current values
137         if(mBacklight->isBacklightAvailable())
138             mLastBacklightValue = mBacklight->getBacklight();
139 
140         mMonitors = mBrightness->getMonitorsInfo();
141     } else
142     {
143         // revert the changes
144         if(mBacklight->isBacklightAvailable()) {
145             disconnect(ui->backlightSlider, &QSlider::valueChanged, this, &BrightnessSettings::setBacklight);
146                 mBacklight->setBacklight(mLastBacklightValue);
147                 setBacklightSliderValue(mLastBacklightValue);
148             connect(ui->backlightSlider, &QSlider::valueChanged, this, &BrightnessSettings::setBacklight);
149         }
150 
151         mBrightness->setMonitorsSettings(mMonitors);
152         for (const auto & monitor : qAsConst(mMonitors))
153             emit monitorReverted(monitor);
154     }
155 }
156 
revertValues()157 void BrightnessSettings::revertValues()
158 {
159     if(mBacklight->isBacklightAvailable()) {
160         disconnect(ui->backlightSlider, &QSlider::valueChanged, this, &BrightnessSettings::setBacklight);
161             mBacklight->setBacklight(mInitialBacklightValue);
162             setBacklightSliderValue(mInitialBacklightValue);
163         connect(ui->backlightSlider, &QSlider::valueChanged, this, &BrightnessSettings::setBacklight);
164     }
165 
166     mBrightness->setMonitorsSettings(mMonitorsInitial);
167     for (const auto & monitor : qAsConst(mMonitorsInitial))
168             emit monitorReverted(monitor);
169 }
170 
171 
setBacklightSliderValue(int value)172 void BrightnessSettings::setBacklightSliderValue(int value)
173 {
174     // Set the minimum to 5% of the maximum to prevent a black screen
175     int minBacklight = qMax(qRound((qreal)(mBacklight->getMaxBacklight())*0.05), 1);
176     int maxBacklight = mBacklight->getMaxBacklight();
177     int interval = maxBacklight - minBacklight;
178     if(interval <= 100) {
179         ui->backlightSlider->setMaximum(maxBacklight);
180         ui->backlightSlider->setMinimum(minBacklight);
181         ui->backlightSlider->setValue(value);
182     } else {
183         ui->backlightSlider->setMaximum(100);
184         // Set the minimum to 5% of the maximum to prevent a black screen
185         ui->backlightSlider->setMinimum(5);
186         ui->backlightSlider->setValue( (value * 100) / maxBacklight);
187     }
188 }