// SPDX-License-Identifier: GPL-3.0-or-later /* * Qt mutizone MQTT thermostat * * Copyright (C) 2020 Richard Genoud * */ #include #include #include #include #include #include #include #include #include #include #include #include #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()) { w->setProperty("idx", v.toInt() - 1); } } } } } } EditDlg::~EditDlg() { } /* vim: set tabstop=8 shiftwidth=8 softtabstop=0 noexpandtab: */