Thermostat pour piloter jusqu'à 4 radiateurs avec fil pilote
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

322 lines
7.4 KiB

// SPDX-License-Identifier: GPL-3.0-or-later
/*
* Qt mutizone MQTT thermostat
*
* Copyright (C) 2020 Richard Genoud
*
*/
#include <QLoggingCategory>
#include <QDialogButtonBox>
#include <QSpinBox>
#include <QPushButton>
#include <QVBoxLayout>
#include <QHBoxLayout>
#include <QGridLayout>
#include <QLocale>
#include <QLabel>
#include <QtMath>
#include <QDateTime>
#include <QTime>
#include "settings.h"
#include "edit_dlg.h"
#define SPIN_ARROW_W 75
#define SPIN_ARROW_H 50
#define SPIN_FONT_SZ 20
EditDlg::EditDlg(int idx, QWidget *parent, Qt::WindowFlags f) : QWidget(parent, f)
{
Settings *s = Settings::getInstance();
const struct Room r = s->getRoom(idx);
QString sheet;
QString text;
QLabel *room_name = new QLabel(QString(tr("%1 default target:").arg(r.name)));
set_font(room_name);
m_idx = idx;
m_progs = r.progs;
m_default_temperature.setDecimals(1);
m_default_temperature.setValue(r.default_temperature);
m_default_temperature.setSingleStep(0.1);
m_default_temperature.setSuffix(" °C");
set_font(&m_default_temperature);
/*
* TODO: setting size in pixels sucks
* We should set size in mm or ratio of the window size
*/
sheet = QString("QDoubleSpinBox { height: %1px; font-size: %4px }"
"QDoubleSpinBox::up-button { width: %2px; height: %3px }"
"QDoubleSpinBox::down-button { width: %2px; height: %3px }")
.arg(2*SPIN_ARROW_H)
.arg(SPIN_ARROW_W)
.arg(SPIN_ARROW_H)
.arg(SPIN_FONT_SZ);
m_default_temperature.setStyleSheet(sheet);
QHBoxLayout *upperLayout = new QHBoxLayout;
upperLayout->addWidget(room_name);
upperLayout->addWidget(&m_default_temperature);
QPushButton *ok_btn = new QPushButton(tr("Ok"), this);
QPushButton *add_btn = new QPushButton(tr("Add"), this);
QPushButton *cancel_btn = new QPushButton(tr("Cancel"), this);
QSizePolicy *szPolicy = new QSizePolicy(QSizePolicy::Minimum,
QSizePolicy::MinimumExpanding,
QSizePolicy::PushButton);
set_font(ok_btn);
set_font(add_btn);
set_font(cancel_btn);
ok_btn->setSizePolicy(*szPolicy);
add_btn->setSizePolicy(*szPolicy);
cancel_btn->setSizePolicy(*szPolicy);
connect(ok_btn, SIGNAL(clicked(void)), this, SLOT(save(void)));
connect(add_btn, SIGNAL(clicked(void)), this, SLOT(add(void)));
connect(cancel_btn, SIGNAL(clicked(void)), this, SLOT(reject(void)));
QHBoxLayout *btnLayout = new QHBoxLayout;
btnLayout->addWidget(cancel_btn);
btnLayout->addWidget(add_btn);
btnLayout->addWidget(ok_btn);
QVBoxLayout *topLayout = new QVBoxLayout;
topLayout->addLayout(upperLayout);
m_progsLayout = new QVBoxLayout;
for (int i = 0; i < m_progs.count(); i++) {
QHBoxLayout *progLayout = add_prog_layout(&(m_progs.at(i)), i);
m_progsLayout->addLayout(progLayout);
}
topLayout->addLayout(m_progsLayout);
topLayout->addLayout(btnLayout);
this->setLayout(topLayout);
}
QHBoxLayout *EditDlg::add_prog_layout(const struct Program *p, int idx)
{
QString sheet;
QString text;
QHBoxLayout *progLayout = new QHBoxLayout;
QSizePolicy *szPolicy = new QSizePolicy(QSizePolicy::Minimum,
QSizePolicy::MinimumExpanding,
QSizePolicy::PushButton);
text = QString("");
if (p->temperature == FORCE_OFF) {
text += QString("-");
} else {
if (p->temperature == FORCE_ON) {
text += QString("+");
} else {
text += QString::number(p->temperature);
}
}
text += QString("°C");
QLabel *prog_temperature = new QLabel(QString(text));
set_font(prog_temperature);
progLayout->addWidget(prog_temperature, 0, Qt::AlignHCenter);
text = QString("");
if (p->DoW == 0) {
text += QString("-");
} else {
bool isFirst = true;
for (int j = 0; j < 7; j++) {
if (p->DoW & (1 << j)) {
if (isFirst) {
isFirst = false;
} else {
text += QString("/");
}
switch (j) {
case 0: text += QString(tr("M")); break;
case 1: text += QString(tr("Tu")); break;
case 2: text += QString(tr("W")); break;
case 3: text += QString(tr("Th")); break;
case 4: text += QString(tr("F")); break;
case 5: text += QString(tr("Sa")); break;
case 6: text += QString(tr("Su")); break;
}
}
}
}
QLabel *prog_DoW = new QLabel(QString(text));
set_font(prog_DoW);
progLayout->addWidget(prog_DoW, 0, Qt::AlignHCenter);
text = QString("");
text += p->start_time.toString(QString(" HH:mm"));
text += p->end_time.toString(QString("-HH:mm"));
QLabel *prog_time= new QLabel(QString(text));
set_font(prog_time);
progLayout->addWidget(prog_time, 0, Qt::AlignHCenter);
QPushButton *edit_btn = new QPushButton(tr("Edit"), this);
QPushButton *delete_btn = new QPushButton(tr("Delete"), this);
set_font(edit_btn);
set_font(delete_btn);
edit_btn->setSizePolicy(*szPolicy);
delete_btn->setSizePolicy(*szPolicy);
edit_btn->setProperty("idx", idx);
delete_btn->setProperty("idx", idx);
connect(delete_btn, SIGNAL(clicked(void)), this, SLOT(delete_prog_clicked(void)));
progLayout->addWidget(edit_btn, 0, Qt::AlignHCenter);
progLayout->addWidget(delete_btn, 0, Qt::AlignHCenter);
return progLayout;
}
void EditDlg::set_font(QWidget *widget)
{
QFont font = widget->font();
font.setPointSize(12);
font.setBold(true);
widget->setFont(font);
QSizePolicy *szQPolicy = new QSizePolicy(QSizePolicy::Minimum,
QSizePolicy::MinimumExpanding,
QSizePolicy::PushButton);
widget->setSizePolicy(*szQPolicy);
}
void EditDlg::save(void)
{
Settings *s = Settings::getInstance();
s->setRoomDefaultTemperature(m_idx, m_default_temperature.value());
s->setRoomPrograms(m_idx, m_progs);
emit close_edit_dlg();
}
void EditDlg::reject(void)
{
emit close_edit_dlg();
}
void EditDlg::add(void)
{
QHBoxLayout *layout;
struct Program p;
int idx = m_progsLayout->count();
if (m_progsLayout->count() != m_progs.count()) {
// TODO ERROR: index mismatch
return;
}
p.temperature = 20;
p.DoW = 0;
p.start_time = QTime(0,0);
p.end_time = QTime(0,0);
m_progs << p;
layout = add_prog_layout(&(m_progs.at(idx)), idx);
m_progsLayout->addLayout(layout);
}
void EditDlg::delete_prog_clicked(void)
{
QLayoutItem *lineItem, *item;
QLayout *layout;
QObject* obj = sender();
QWidget *w;
QVariant v;
int idx;
v = obj->property("idx");
if (!v.isValid())
return;
idx = v.toInt();
if (idx >= m_progsLayout->count()) {
// TODO ERROR: index mismatch
return;
}
// remove the corresponding program
m_progs.remove(idx);
// retrieve the corresponding line
lineItem = m_progsLayout->itemAt(idx);
if (lineItem == NULL) {
// TODO: hum, this should not happend
return;
}
// and remove it
m_progsLayout->removeItem(lineItem);
// We also need to remove the Hlayout and all widgets attached
layout = lineItem->layout();
if (layout == NULL) {
// TODO: this shouldn't happend neither
return;
}
while (layout->count()) {
item = layout->itemAt(0);
if (item && item->widget()) {
w = item->widget();
layout->removeWidget(w);
w->hide();
delete w;
} else {
layout->removeItem(item);
delete item;
}
}
delete lineItem;
// renumber the buttons' properties
for (int i = idx; i < m_progsLayout->count(); i++) {
lineItem = m_progsLayout->itemAt(i);
if (lineItem && lineItem->layout()) {
layout = lineItem->layout();
for (int j = 0; j < layout->count(); j++) {
item = layout->itemAt(j);
if (item && item->widget()) {
w = item->widget();
v = w->property("idx");
if (v.isValid()) {
qDebug() << "new:" << v.toInt()-1;
w->setProperty("idx", v.toInt() - 1);
}
}
}
}
}
}
EditDlg::~EditDlg()
{
}
/* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */