Files
yremote/mainwindow.cpp
2018-11-18 00:34:50 +01:00

237 lines
7.2 KiB
C++

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QFile>
#include <QTimer>
#include <QtNetwork/QNetworkReply>
class QNetworkReply;
namespace yremote {
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
setFixedSize(size());
#if defined(Q_OS_WIN)
setWindowFlags(windowFlags() | Qt::MSWindowsFixedSizeDialogHint);
#endif
mSettings = new QSettings(QSettings::IniFormat, QSettings::UserScope, "RogoSoftware", "yremote");
restoreGeometry(mSettings->value("geometry", saveGeometry()).toByteArray());
move(mSettings->value("pos", pos()).toPoint());
ui->txt_address->setText(mSettings->value("av_address", "").toString());
mAddress = ui->txt_address->text();
// setup volume value collection
connect(&mTimerValCollect, &QTimer::timeout, this, &MainWindow::sendVolume);
mTimerValCollect.setSingleShot(true);
connect(&mTimerUpdateAddress, &QTimer::timeout, this, &MainWindow::updateAVState);
mTimerUpdateAddress.setSingleShot(true);
// load initial data and set update rate
updateAVState();
connect(&mTimerUpdateState, &QTimer::timeout, this, &MainWindow::updateAVState);
mTimerUpdateState.start(TIME_UPDATE_STATE);
QFile css(":style.css");
if (css.open(QFile::ReadOnly | QFile::Text))
this->setStyleSheet(css.readAll());
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::sendCommand(QString cmd)
{
QNetworkRequest request;
request.setUrl("http://" + mAddress + ":80/YamahaRemoteControl/ctrl");
request.setRawHeader("Content-Type", "text/xml; charset=UTF-8");
request.setRawHeader("Content-Length", QByteArray::number(cmd.size()));
QNetworkAccessManager *networkManager = new QNetworkAccessManager(this);
networkManager->post(request, cmd.toUtf8());
connect(networkManager, &QNetworkAccessManager::finished, this, &MainWindow::replyFinished);
}
void MainWindow::replyFinished(QNetworkReply* reply)
{
QString ans;
if(reply->error() == QNetworkReply::NoError) {
QByteArray data = reply->readAll();
ans = QString(data);
} else {
qDebug() << reply->url();
qDebug() << reply->errorString();
mPowered = false;
}
// check power state
QRegularExpression regexPower("<Power_Control><Power>(.+)</Power></Power_Control>");
QRegularExpressionMatch matchPower = regexPower.match(ans);
if (matchPower.hasMatch()) {
if (matchPower.captured(1) == "On") mPowered = true;
else if (matchPower.captured(1) == "Off") mPowered = false;
}
// check volume
QRegularExpression regexVolume("<Volume><Lvl><Val>(.+)</Val>");
QRegularExpressionMatch matchVolume = regexVolume.match(ans);
if (matchVolume.hasMatch()) {
mVolume = matchVolume.captured(1).toInt();
}
// check input
QRegularExpression regexInput("<Input><Input_Sel>(.+)</Input_Sel>");
QRegularExpressionMatch matchInput = regexInput.match(ans);
if (matchInput.hasMatch())
mInput = matchInput.captured(1);
reply->deleteLater();
updateUi();
}
void MainWindow::updateUi() {
ui->dial->setEnabled(mPowered);
ui->dial->setValue(mVolume);
ui->lbl_volume->setEnabled(mPowered);
ui->btn_hdmi1->setEnabled(mPowered);
ui->btn_hdmi2->setEnabled(mPowered);
ui->btn_hdmi3->setEnabled(mPowered);
ui->btn_spotify->setEnabled(mPowered);
ui->btn_airplay->setEnabled(mPowered);
ui->btn_audioin->setEnabled(mPowered);
setActiveButton(mInput);
setPowerState();
}
void MainWindow::setActiveButton(QString prop)
{
for (QObject *q : ui->groupBox->children()) {
QPushButton *b = dynamic_cast<QPushButton*>(q);
if (b){
if (b->property("input") == prop)
b->setStyleSheet("background-color: #24e895; color: #404040;");
else
b->setStyleSheet("");
}
}
}
void MainWindow::setPowerState()
{
if (mPowered) {
ui->btn_onoff->setText("On");
ui->btn_onoff->setStyleSheet("background-color: #24e895; color: #404040;");
ui->lbl_volume->setStyleSheet("color: #24e895");
ui->dial->setStyleSheet("background-color: #24e895");
} else {
ui->btn_onoff->setText("Off");
ui->btn_onoff->setStyleSheet("");
ui->lbl_volume->setStyleSheet("");
ui->dial->setStyleSheet("");
setActiveButton("");
}
}
void MainWindow::on_txt_address_textEdited(const QString &arg1)
{
mAddress = arg1;
mSettings->setValue("av_address", mAddress);
mTimerUpdateAddress.start(TIME_UPDATE_ADDRESS);
}
void MainWindow::on_btn_onoff_clicked()
{
if (mPowered){
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone>"
"<Power_Control><Power>Standby</Power></Power_Control>"
"</Main_Zone></YAMAHA_AV>");
} else {
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone>"
"<Power_Control><Power>On</Power></Power_Control>"
"</Main_Zone></YAMAHA_AV>");
}
mPowered = !mPowered;
updateUi();
}
void MainWindow::on_dial_valueChanged(int value)
{
int d = value % 10;
if (!( d == -5 || d == 0 ))
value -= d;
ui->lbl_volume->setText(QString::number(value));
mVolume = value;
mTimerValCollect.start(TIME_VOL_COLLECT);
}
void MainWindow::sendVolume()
{
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Volume><Lvl><Val>"
+ QString::number(mVolume)
+ "</Val><Exp>1</Exp><Unit>dB</Unit></Lvl></Volume></Main_Zone></YAMAHA_AV>");
}
void MainWindow::moveEvent(QMoveEvent *)
{
mSettings->setValue("geometry", geometry());
mSettings->setValue("pos", pos());
}
void MainWindow::updateAVState()
{
sendCommand("<YAMAHA_AV cmd=\"GET\"><System><Power_Control><Power>GetParam</Power></Power_Control></System></YAMAHA_AV>");
sendCommand("<YAMAHA_AV cmd=\"GET\"><Main_Zone><Volume><Lvl>GetParam</Lvl></Volume></Main_Zone></YAMAHA_AV>");
sendCommand("<YAMAHA_AV cmd=\"GET\"><Main_Zone><Input><Input_Sel>GetParam</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
}
void MainWindow::on_btn_hdmi1_clicked()
{
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>HDMI1</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
mInput = "HDMI1";
}
void MainWindow::on_btn_hdmi2_clicked()
{
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>HDMI2</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
mInput = "HDMI2";
}
void MainWindow::on_btn_hdmi3_clicked()
{
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>HDMI3</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
mInput = "HDMI3";
}
void MainWindow::on_btn_spotify_clicked()
{
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>Spotify</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
mInput = "Spotify";
}
void MainWindow::on_btn_airplay_clicked()
{
// TODO
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>IPOD</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
mInput = "IPOD";
}
void MainWindow::on_btn_audioin_clicked()
{
sendCommand("<YAMAHA_AV cmd=\"PUT\"><Main_Zone><Input><Input_Sel>AUDIO</Input_Sel></Input></Main_Zone></YAMAHA_AV>");
mInput = "AUDIO";
}
}