Files
raDIYo/swalarmcontrol.cpp
2025-08-05 22:36:00 +02:00

232 lines
6.0 KiB
C++

/***************************************************************************
source::worx raDIYo
Copyright © 2020-2022 c.holzheuer
chris@sourceworx.org
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
***************************************************************************/
#include <QDebug>
#include <QPainter>
#include <QKeyEvent>
#include <QDateTime>
#include <QTime>
#include <QAction>
#include <QtMath>
#include <QDir>
#include <QStandardPaths>
#include <swalarmcontrol.h>
#include <raDIYo.h>
/**
* @brief Das AlarmControl steuert den Wecker.
* @param parent
* @param psettings
*/
SWAlarmControl::SWAlarmControl( QWidget* parent, QSettings* psettings )
: SWDialControl( parent, psettings )
{
Ui_SWAlarmControl::setupUi( this );
setHeaderText( "Alarm" );
connect( &_alarmTimer, SIGNAL( timeout() ), this, SLOT( onWakeUp() ) );
// die Minuten beobachten, um die Stunden anzupassen
connect( _digitMinute, SIGNAL( valueOverflow(int) ), this, SLOT( onMinuteOverflow(int) ) );
connect( _digitHour, SIGNAL( valueOverflow(int) ), this, SLOT( onHourOverflow(int) ) );
connect( _switchAlarm, SIGNAL( widgetClicked(SWDialWidget*) ), this, SLOT( onWidgetClicked(SWDialWidget*) ) );
connect( _switchRepeat, SIGNAL( widgetClicked(SWDialWidget*) ), this, SLOT( onWidgetClicked(SWDialWidget*) ) );
connect( _switchWeekdays, SIGNAL( widgetClicked(SWDialWidget*) ), this, SLOT( onWidgetClicked(SWDialWidget*) ) );
connect( _digitMinute, &SWAdjustableDigit::valueChanged, this, [=]{ if( _alarmEnabled ) setAlarm(); } );
connect( _digitHour, &SWAdjustableDigit::valueChanged, this, [=]{ if( _alarmEnabled ) setAlarm(); } );
_digitHour->setRange( 0, 23 );
_digitMinute->setRange( 0, 59 );
collectDialWidgets();
}
void SWAlarmControl::onMinuteOverflow( int value )
{
int hour = _digitHour->value();
if( value < 0 )
{
_digitMinute->setValue( 59 );
_digitHour->setValue( hour-1 );
}
else if( value > 59 )
{
_digitMinute->setValue( 0 );
_digitHour->setValue( hour+1 );
}
}
void SWAlarmControl::onHourOverflow( int value )
{
// Stunde < 0: Stunde zurück
if( value < 0 )
_digitHour->setValue( 23 );
else if( value > 23 )
_digitHour->setValue( 0 );
}
void SWAlarmControl::onShow()
{
current().setHightlighted( true );
// sync sttings -> screen
_alarmEnabled = settings().value( raDIYo::KeyAlarmEnabled, raDIYo::AlarmEnabled ).toBool();
_switchAlarm->setChecked( _alarmEnabled );
_alarmRepeat = settings().value( raDIYo::KeyAlarmRepeat, raDIYo::AlarmRepeat ).toBool();
_switchRepeat->setChecked( _alarmWeekdays );
_alarmWeekdays = settings().value( raDIYo::KeyWeekdaysOnly, raDIYo::WeekdaysOnly ).toBool();
_switchWeekdays->setChecked( _alarmWeekdays );
// die Uhrzeit setzen
int alarmHour = settings().value( raDIYo::KeyAlarmHour, raDIYo::KeyAlarmHour ).toInt();
int alarmMinute = settings().value( raDIYo::KeyAlarmMinute, raDIYo::KeyAlarmMinute ).toInt();
_digitHour->setValue( alarmHour );
_digitMinute->setValue( alarmMinute );
setAlarm();
}
void SWAlarmControl::onHide()
{
// sync screen to settings
settings().setValue( raDIYo::KeyAlarmEnabled, _switchAlarm->isChecked() );
settings().setValue( raDIYo::KeyAlarmRepeat, _switchRepeat->isChecked() );
settings().setValue( raDIYo::KeyWeekdaysOnly, _switchWeekdays->isChecked() );
settings().setValue( raDIYo::KeyAlarmHour, _digitHour->value() );
settings().setValue( raDIYo::KeyAlarmMinute, _digitMinute->value() );
setAlarm();
}
void SWAlarmControl::onWidgetClicked( SWDialWidget* child )
{
if( _switchAlarm == child )
{
_alarmEnabled = !_alarmEnabled;
_switchAlarm->setChecked( _alarmEnabled );
_labelAlarm->setText( _alarmEnabled ? SWAlarmOn : SWAlarmOff );
_switchRepeat->setEnabled( _alarmEnabled );
_switchWeekdays->setEnabled( _alarmEnabled );
goto end;
}
if( _switchRepeat == child )
{
_alarmRepeat = !_alarmRepeat;
_switchRepeat->setChecked( _alarmRepeat );
_labelRepeat->setText( _alarmRepeat ? SWAlarmRepeat : SWAlarmOnce );
goto end;
}
if( _switchWeekdays == child )
{
_alarmWeekdays = !_alarmWeekdays;
_switchWeekdays->setChecked( _alarmWeekdays );
_labelWeekdays->setText( _alarmWeekdays ? SWAlarmWeekdays : SWAlarmAlldays );
goto end;
}
//if( _digitHour == child || _digitMinute == child )
// onTimeChanged( 42 );
end:
setAlarm();
}
/**
* @brief Berechnet den nächsten Alarmzeitpunkt aus den Vorgaben der Benutzeroberfläche
* und startet den Alarmtimer.
*/
void SWAlarmControl::setAlarm()
{
_alarmTimer.stop();
if( !_alarmEnabled )
return;
/*
if( !_alarmEnabled )
{
_labelAlarm->setText( SWAlarmOff );
return;
}
*/
// ab hier: alarm gewüschnt
int hour = _digitHour->value();
int minute = _digitMinute->value();
// timer basteln
QTime alarmTime( hour, minute );
QDateTime now = QDateTime::currentDateTime();
int millisToAlarm = 1000 * now.time().secsTo( alarmTime );
int shiftDays = 0;
// ist der Alarm nicht mehr heute?
if( millisToAlarm < 0 )
shiftDays = 1;
// Gnade am Wochenende?
if( _alarmWeekdays )
{
int today = now.date().dayOfWeek();
// samstag?
shiftDays += today >= 6 ? (today == 7) ? 1 : 2 : 0 ;
}
millisToAlarm += shiftDays * SecsPerDay * 1000;
_labelAlarm->setText( SWAlarmOn + now.addMSecs( millisToAlarm ).toString( " dd.MM, hh:mm" ) );
_alarmTimer.start( millisToAlarm );
}
void SWAlarmControl::onWakeUp()
{
_alarmTimer.stop();
emit playCurrentUrl();
}