18 #include <QCoreApplication>
20 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
21 #include <QStringConverter>
49 m_socket(new QTcpSocket(this)),
50 m_timeTimer (new QTimer(this)),
51 m_scrollWTimer (new QTimer(this)),
52 m_preScrollWTimer (new QTimer(this)),
53 m_menuScrollTimer (new QTimer(this)),
54 m_menuPreScrollTimer (new QTimer(this)),
55 m_popMenuTimer (new QTimer(this)),
56 m_checkConnectionsTimer (new QTimer(this)),
57 m_recStatusTimer (new QTimer(this)),
58 m_scrollListTimer (new QTimer(this)),
59 m_showMessageTimer (new QTimer(this)),
60 m_updateRecInfoTimer (new QTimer(this)),
63 m_parentLCDServer (lparent)
71 LOG(VB_GENERAL, LOG_INFO,
72 "LCDProcClient: An LCDProcClient object now exists");
74 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
131 if (lcd_host.length() > 0 && lcd_port > 1024)
158 while (--
timeout &&
m_socket->state() != QAbstractSocket::ConnectedState)
160 qApp->processEvents();
161 std::this_thread::sleep_for(1ms);
163 if (
m_socket->state() == QAbstractSocket::ConnectedState)
178 if (
m_socket->state() != QAbstractSocket::ConnectedState)
190 LOG(VB_GENERAL, LOG_ERR,
191 "LCDProcClient: Connection to LCDd died unexpectedly.");
196 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
197 os.setCodec(
"ISO 8859-1");
199 os.setEncoding(QStringConverter::Latin1);
207 LOG(VB_NETWORK, LOG_INFO,
208 "LCDProcClient: Sending to Server: " + someText);
212 os << someText <<
"\n";
227 aString =
"screen_set ";
229 aString +=
" priority ";
265 msg =
"widget_add " + screen +
" heartbeat";
269 msg =
"screen_set " + screen +
" heartbeat on";
276 msg =
"widget_del " + screen +
" heartbeat";
280 msg =
"screen_set " + screen +
" heartbeat off";
289 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: checking connections");
295 LOG(VB_GENERAL, LOG_INFO,
296 "LCDProcClient: connecting to master server");
298 LOG(VB_GENERAL, LOG_ERR,
299 "LCDProcClient: connecting to master server failed");
303 if (
m_socket->state() != QAbstractSocket::ConnectedState)
306 LOG(VB_GENERAL, LOG_INFO,
307 "LCDProcClient: connecting to LCDProc server");
319 QString lineFromServer;
322 QStringList::Iterator it;
336 lineFromServer =
m_socket->readLine();
337 lineFromServer = lineFromServer.remove(
"\n");
338 lineFromServer = lineFromServer.remove(
"\r");
343 if (lineFromServer !=
"success")
344 LOG(VB_NETWORK, LOG_INFO,
345 "LCDProcClient: Received from server: " + lineFromServer);
348 aList = lineFromServer.split(
" ");
349 if (aList.first() ==
"connect")
357 if ((*it) !=
"LCDproc")
359 LOG(VB_GENERAL, LOG_WARNING,
360 "LCDProcClient: WARNING: Second parameter "
361 "returned from LCDd was not \"LCDproc\"");
366 QString server_version = *it;
369 QString protocol_version = *it;
370 setVersion (server_version, protocol_version);
400 if (aList.first() ==
"huh?")
402 LOG(VB_GENERAL, LOG_WARNING,
403 "LCDProcClient: WARNING: Something is getting"
404 "passed to LCDd that it doesn't understand");
407 else if (aList.first() ==
"key")
461 aString =
"widget_add Menu menuWidget";
462 aString += QString::number (i);
463 aString +=
" string";
503 sendToServer(
"widget_add RecStatus textWidget1 string");
504 sendToServer(
"widget_add RecStatus textWidget2 string");
505 sendToServer(
"widget_add RecStatus textWidget3 string");
506 sendToServer(
"widget_add RecStatus textWidget4 string");
535 auto add_ws = [](
const QString& str,
auto x){
return str + x + QString(
" "); };
536 return std::accumulate(aString.cbegin(), aString.cend(), QString(), add_ws);
568 if (!old_keystring.isEmpty())
570 aString =
"client_del_key " +
expandString(old_keystring);
604 QList<LCDTextItem> textItems;
610 startrow = ((
m_lcdHeight - list.count()) / 2) + 1;
612 for (
int x = 0; x < list.count(); x++)
700 LOG(VB_GENERAL, LOG_INFO,
701 QString(
"LCDProcClient: The server is %1x%2 with each cell "
704 LOG(VB_GENERAL, LOG_INFO,
705 QString(
"LCDProcClient: LCDd version %1, protocol version %2.")
711 LOG(VB_GENERAL, LOG_INFO,
712 QString(
"LCDProcClient: MythTV LCD settings:"));
713 LOG(VB_GENERAL, LOG_INFO,
714 QString(
"LCDProcClient: - showmusic : %1")
716 LOG(VB_GENERAL, LOG_INFO,
717 QString(
"LCDProcClient: - showmusicitems : %1")
719 LOG(VB_GENERAL, LOG_INFO,
720 QString(
"LCDProcClient: - showtime : %1")
722 LOG(VB_GENERAL, LOG_INFO,
723 QString(
"LCDProcClient: - showchannel : %1")
725 LOG(VB_GENERAL, LOG_INFO,
726 QString(
"LCDProcClient: - showrecstatus : %1")
728 LOG(VB_GENERAL, LOG_INFO,
729 QString(
"LCDProcClient: - showgeneric : %1")
731 LOG(VB_GENERAL, LOG_INFO,
732 QString(
"LCDProcClient: - showvolume : %1")
734 LOG(VB_GENERAL, LOG_INFO,
735 QString(
"LCDProcClient: - showmenu : %1")
737 LOG(VB_GENERAL, LOG_INFO,
738 QString(
"LCDProcClient: - backlighton : %1")
740 LOG(VB_GENERAL, LOG_INFO,
741 QString(
"LCDProcClient: - heartbeaton : %1")
743 LOG(VB_GENERAL, LOG_INFO,
744 QString(
"LCDProcClient: - popuptime : %1")
752 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not connect to LCDd: %1")
779 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: stopAll");
823 QList<LCDTextItem>::iterator it = textItems->begin();
825 unsigned int counter = 1;
830 while (it != textItems->end() && counter <
m_lcdHeight )
834 num.setNum(curItem->
getRow());
839 "textWidget" + num, curItem->
getRow());
847 "textWidget" + num, curItem->
getRow());
851 "textWidget" + num, curItem->
getRow());
855 "textWidget" + num, curItem->
getRow());
876 aString =
"widget_set ";
877 aString += theScreen;
878 aString +=
" " + widget +
" ";
879 aString += QString::number(x);
881 aString += QString::number(row);
883 aString += theText.replace (
'"',
"\"");
892 aString =
"widget_set ";
893 aString += theScreen;
894 aString +=
" " + widget +
" 1 ";
895 aString += QString::number(row);
897 aString += theText.replace (
'"',
"\"");
906 unsigned int x = (int)(
m_lcdWidth - theText.length()) + 1;
908 aString =
"widget_set ";
909 aString += theScreen;
910 aString +=
" " + widget +
" ";
911 aString += QString::number(x);
913 aString += QString::number(row);
915 aString += theText.replace (
'"',
"\"");
921 QString theWidget,
int theRow)
941 const QString& theWidget,
int theRow)
947 theScreen,
true, theWidget));
959 auto longest = [](
int cur,
const auto & item)
960 {
return std::max(cur,
static_cast<int>(item.getText().length())); };
974 temp = temp.fill(QChar(
' '), max_len - curItem->
getText().length());
1011 unsigned int len = 0;
1014 if (item.getScroll())
1017 len = item.getText().length();
1021 item.getWidget(), item.getRow());
1028 LOG(VB_GENERAL, LOG_ERR,
1029 "LCDProcClient::scrollWidgets called without scrollable items");
1063 QString aString = std::move(artist);
1104 aString = channum +
"|" + title;
1105 if (!subtitle.isEmpty())
1106 aString +=
"|" + subtitle;
1116 if (subtitle.length() > 0)
1119 aString += subtitle;
1133 QList<LCDTextItem>::iterator it = textItems->begin();
1146 if (textItems->isEmpty())
1170 "textWidget1", curItem->
getRow());
1175 textItems->removeFirst();
1176 if (!textItems->isEmpty())
1185 if (menuItems->isEmpty())
1201 QList<LCDMenuItem>::iterator it = menuItems->begin();
1205 unsigned int selectedItem = 0;
1206 unsigned int counter = 0;
1207 bool oneSelected =
false;
1209 while (it != menuItems->end())
1215 selectedItem = counter + 1;
1225 sendToServer(
"widget_set Menu topWidget 1 1 \"No menu item selected\"");
1226 sendToServer(
"widget_set Menu menuWidget1 1 2 \" ABORTING \"");
1238 QList<LCDMenuItem>::iterator itTemp = menuItems->begin();
1241 while (itTemp != menuItems->end())
1255 it = menuItems->begin();
1256 while (it != menuItems->end())
1276 aString =
"widget_set Menu menuWidget1 1 2 \">";
1280 aString =
"widget_set Menu menuWidget1 1 1 \"";
1287 case CHECKED: aString +=
"X ";
break;
1306 it = menuItems->begin();
1310 if (selectedItem > midPoint && menuItems->size() >= (int)
m_lcdHeight-1)
1312 while (counter != selectedItem)
1318 counter -= midPoint;
1323 if (counter + midPoint > menuItems->size() - midPoint && counter > midPoint)
1325 it -= (counter + (
m_lcdHeight / 2) - 1) - (menuItems->size() - midPoint);
1329 while (it != menuItems->end())
1338 aString =
"widget_set Menu menuWidget";
1339 aString += QString::number(counter) +
" 1 ";
1340 aString += QString::number(counter + 1) +
" \"";
1349 case CHECKED: aString +=
"X ";
break;
1364 aString =
"widget_set Menu menuWidget";
1365 aString += QString::number(counter) +
" 1 ";
1366 aString += QString::number(counter + 1) +
" \"\"";
1427 unsigned int selectedItem = 0;
1428 unsigned int counter = 0;
1436 selectedItem = counter + 1;
1470 aString =
"widget_set Menu menuWidget1 1 2 \">";
1474 aString =
"widget_set Menu menuWidget1 1 1 \"";
1481 case CHECKED: aString +=
"X";
break;
1491 case CHECKED: aString +=
"X ";
break;
1499 aString += bString.fill(
' ', curItem->
getIndent());
1515 int longest_line = 0;
1516 int max_scroll_pos = 0;
1522 if (curItem->
ItemName().length() > longest_line)
1523 longest_line = curItem->
ItemName().length();
1530 if (max_scroll_pos > longest_line)
1553 while (counter != selectedItem)
1566 bool stopTimer =
true;
1581 aString =
"widget_set Menu menuWidget";
1582 aString += QString::number(counter) +
" 1 ";
1583 aString += QString::number(counter + 1) +
" \"";
1592 case CHECKED: aString +=
"X ";
break;
1600 bString.fill(
' ', curItem->
getIndent());
1745 aString =
"output ";
1746 aString += QString::number(mask);
1760 QString time = QTime::currentTime().toString(
m_timeFormat );
1771 if ((time.length() == 8) || (time.length() == 5))
1775 if (time.length() > 6)
1777 aString = time.at(5 + toffset);
1778 aString += time.at(6 + toffset);
1792 aString = QString::number((
int)
m_tunerList.size());
1805 aString =
"widget_set Time d0 ";
1806 aString += QString::number(
m_lcdWidth/2 - 5 - xoffset) +
" ";
1810 aString += time.at(0);
1814 aString =
"widget_set Time d1 ";
1815 aString += QString::number(
m_lcdWidth/2 - 2 - xoffset) +
" ";
1816 aString += time.at(0 + toffset);
1820 aString =
"widget_set Time sep ";
1821 aString += QString::number(
m_lcdWidth/2 + 1 - xoffset);
1826 aString =
"widget_set Time d2 ";
1827 aString += QString::number(
m_lcdWidth/2 + 2 - xoffset) +
" ";
1828 aString += time.at(2 + toffset);
1832 aString =
"widget_set Time d3 ";
1833 aString += QString::number(
m_lcdWidth/2 + 5 - xoffset) +
" ";
1834 aString += time.at(3 + toffset);
1883 QString time = QTime::currentTime().toString(
m_timeFormat );
1885 aString =
"widget_set Time timeWidget ";
1886 aString += QString::number(x);
1888 aString += QString::number(y);
1891 aString += time +
"\"";
1894 aString = aString.replace(
':',
' ');
1950 std::chrono::milliseconds listTime { 1 };
1964 status += tuner.
title;
1977 status = tuner.
startTime.toLocalTime().toString(
"hh:mm") +
"-" +
1978 tuner.
endTime.toLocalTime().toString(
"hh:mm");
1983 double rec_progress = (double) delta / length;
1985 aString =
"widget_set RecStatus progressBar 13 ";
1988 aString += QString::number((
int)rint(rec_progress * (
m_lcdWidth - 13) *
1996 status = tr(
"RECORDING|");
1997 status += tuner.
title;
1999 status +=
"|(" + tuner.
subtitle +
")";
2001 status +=
"|" + tuner.
startTime.toLocalTime().toString(
"hh:mm")
2003 tuner.
endTime.toLocalTime().toString(
"hh:mm");
2012 double rec_progress = (double) delta / length;
2014 aString =
"widget_set RecStatus progressBar 1 ";
2017 aString += QString::number((
int)rint(rec_progress *
m_lcdWidth *
2022 sendToServer(
"widget_set RecStatus progressBar 1 1 0");
2035 const QString& widget,
int top,
int bottom)
2038 aString =
"widget_set " + theScreen +
" " + widget;
2040 aString += QString::number(top) +
" ";
2041 aString += QString::number(
m_lcdWidth ) +
" ";
2042 aString += QString::number(bottom);
2043 aString +=
" v 8 \"" + theText +
"\"";
2050 QString separators =
" |-_/:('<~";
2056 for (
const auto& x : qAsConst(text))
2058 if (separators.contains(x))
2059 lastSplit = line.length();
2062 if (line.length() > (
int)
m_lcdWidth || x ==
'|')
2064 QString formatedLine;
2066 formatedLine = formatedLine.replace((
m_lcdWidth - lastSplit) / 2,
2067 lastSplit, line.left(lastSplit));
2069 lines.append(formatedLine);
2071 if (line[lastSplit] ==
' ' || line[lastSplit] ==
'|')
2072 line = line.mid(lastSplit + 1);
2074 line = line.mid(lastSplit);
2081 QString formatedLine;
2083 formatedLine = formatedLine.replace((
m_lcdWidth - line.length()) / 2,
2084 line.length(), line);
2086 lines.append(formatedLine);
2101 QString shuffle =
"";
2102 QString repeat =
"";
2127 if (shuffle.length() != 0 || repeat.length() != 0)
2129 aString = shuffle + repeat;
2130 info_width = aString.length();
2136 aString =
"widget_set Music progressBar ";
2137 aString += QString::number(info_width + 1);
2152 aString =
"widget_set Channel progressBar 1 ";
2170 aString =
"widget_set Generic progressBar ";
2171 aString += QString::number (
m_busyPos );
2179 else sendToServer(
"widget_set Generic progressBar 1 1 0");
2189 aString =
"widget_set Volume progressBar 1 ";
2214 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToTime");
2227 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToMusic") ;
2240 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToChannel");
2252 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToMenu");
2254 startMenu(menuItems, app_name, popMenu);
2264 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToGeneric");
2277 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToVolume");
2290 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToNothing");
2296 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: shutdown");
2373 LOG(VB_GENERAL, LOG_INFO,
2374 "LCDProcClient: An LCD device is being snuffed out"
2375 "of existence (~LCDProcClient() was called)");
2393 auto *me =
dynamic_cast<MythEvent *
>(e);
2397 if (me->Message().startsWith(
"RECORDING_LIST_CHANGE") ||
2398 me->Message() ==
"UPDATE_PROG_INFO")
2403 LOG(VB_GENERAL, LOG_INFO,
2404 "LCDProcClient: Received recording list change");
2423 LOG(VB_GENERAL, LOG_ERR,
2424 "LCDProcClient: Cannot get recording status "
2425 "- is the master server running?\n\t\t\t"
2426 "Will retry in 30 seconds");