19 #include <QCoreApplication>
21 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
22 #include <QStringConverter>
51 m_socket(new QTcpSocket(this)),
52 m_timeTimer (new QTimer(this)),
53 m_scrollWTimer (new QTimer(this)),
54 m_preScrollWTimer (new QTimer(this)),
55 m_menuScrollTimer (new QTimer(this)),
56 m_menuPreScrollTimer (new QTimer(this)),
57 m_popMenuTimer (new QTimer(this)),
58 m_checkConnectionsTimer (new QTimer(this)),
59 m_recStatusTimer (new QTimer(this)),
60 m_scrollListTimer (new QTimer(this)),
61 m_showMessageTimer (new QTimer(this)),
62 m_updateRecInfoTimer (new QTimer(this)),
65 m_parentLCDServer (lparent)
73 LOG(VB_GENERAL, LOG_INFO,
74 "LCDProcClient: An LCDProcClient object now exists");
128 if (lcd_host.length() > 0 && lcd_port > 1024)
155 while (--
timeout &&
m_socket->state() != QAbstractSocket::ConnectedState)
157 qApp->processEvents();
158 std::this_thread::sleep_for(1ms);
160 if (
m_socket->state() == QAbstractSocket::ConnectedState)
175 if (
m_socket->state() != QAbstractSocket::ConnectedState)
187 LOG(VB_GENERAL, LOG_ERR,
188 "LCDProcClient: Connection to LCDd died unexpectedly.");
193 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
194 os.setCodec(
"ISO 8859-1");
196 os.setEncoding(QStringConverter::Latin1);
204 LOG(VB_NETWORK, LOG_INFO,
205 "LCDProcClient: Sending to Server: " + someText);
209 os << someText <<
"\n";
224 aString =
"screen_set ";
226 aString +=
" priority ";
262 msg =
"widget_add " + screen +
" heartbeat";
266 msg =
"screen_set " + screen +
" heartbeat on";
273 msg =
"widget_del " + screen +
" heartbeat";
277 msg =
"screen_set " + screen +
" heartbeat off";
286 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: checking connections");
292 LOG(VB_GENERAL, LOG_INFO,
293 "LCDProcClient: connecting to master server");
295 LOG(VB_GENERAL, LOG_ERR,
296 "LCDProcClient: connecting to master server failed");
300 if (
m_socket->state() != QAbstractSocket::ConnectedState)
303 LOG(VB_GENERAL, LOG_INFO,
304 "LCDProcClient: connecting to LCDProc server");
316 QString lineFromServer;
319 QStringList::Iterator it;
333 lineFromServer =
m_socket->readLine();
334 lineFromServer = lineFromServer.remove(
"\n");
335 lineFromServer = lineFromServer.remove(
"\r");
340 if (lineFromServer !=
"success")
341 LOG(VB_NETWORK, LOG_INFO,
342 "LCDProcClient: Received from server: " + lineFromServer);
345 aList = lineFromServer.split(
" ");
346 if (aList.first() ==
"connect")
354 if ((*it) !=
"LCDproc")
356 LOG(VB_GENERAL, LOG_WARNING,
357 "LCDProcClient: WARNING: Second parameter "
358 "returned from LCDd was not \"LCDproc\"");
363 QString server_version = *it;
366 QString protocol_version = *it;
367 setVersion (server_version, protocol_version);
397 if (aList.first() ==
"huh?")
399 LOG(VB_GENERAL, LOG_WARNING,
400 "LCDProcClient: WARNING: Something is getting"
401 "passed to LCDd that it doesn't understand");
404 else if (aList.first() ==
"key")
458 aString =
"widget_add Menu menuWidget";
459 aString += QString::number (i);
460 aString +=
" string";
500 sendToServer(
"widget_add RecStatus textWidget1 string");
501 sendToServer(
"widget_add RecStatus textWidget2 string");
502 sendToServer(
"widget_add RecStatus textWidget3 string");
503 sendToServer(
"widget_add RecStatus textWidget4 string");
532 auto add_ws = [](
const QString& str,
auto x){
return str + x + QString(
" "); };
533 return std::accumulate(aString.cbegin(), aString.cend(), QString(), add_ws);
565 if (!old_keystring.isEmpty())
567 aString =
"client_del_key " +
expandString(old_keystring);
601 QList<LCDTextItem> textItems;
607 startrow = ((
m_lcdHeight - list.count()) / 2) + 1;
609 for (
int x = 0; x < list.count(); x++)
697 LOG(VB_GENERAL, LOG_INFO,
698 QString(
"LCDProcClient: The server is %1x%2 with each cell "
701 LOG(VB_GENERAL, LOG_INFO,
702 QString(
"LCDProcClient: LCDd version %1, protocol version %2.")
708 LOG(VB_GENERAL, LOG_INFO,
709 QString(
"LCDProcClient: MythTV LCD settings:"));
710 LOG(VB_GENERAL, LOG_INFO,
711 QString(
"LCDProcClient: - showmusic : %1")
713 LOG(VB_GENERAL, LOG_INFO,
714 QString(
"LCDProcClient: - showmusicitems : %1")
716 LOG(VB_GENERAL, LOG_INFO,
717 QString(
"LCDProcClient: - showtime : %1")
719 LOG(VB_GENERAL, LOG_INFO,
720 QString(
"LCDProcClient: - showchannel : %1")
722 LOG(VB_GENERAL, LOG_INFO,
723 QString(
"LCDProcClient: - showrecstatus : %1")
725 LOG(VB_GENERAL, LOG_INFO,
726 QString(
"LCDProcClient: - showgeneric : %1")
728 LOG(VB_GENERAL, LOG_INFO,
729 QString(
"LCDProcClient: - showvolume : %1")
731 LOG(VB_GENERAL, LOG_INFO,
732 QString(
"LCDProcClient: - showmenu : %1")
734 LOG(VB_GENERAL, LOG_INFO,
735 QString(
"LCDProcClient: - backlighton : %1")
737 LOG(VB_GENERAL, LOG_INFO,
738 QString(
"LCDProcClient: - heartbeaton : %1")
740 LOG(VB_GENERAL, LOG_INFO,
741 QString(
"LCDProcClient: - popuptime : %1")
749 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not connect to LCDd: %1")
776 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: stopAll");
820 QList<LCDTextItem>::iterator it = textItems->begin();
822 unsigned int counter = 1;
827 while (it != textItems->end() && counter <
m_lcdHeight )
831 num.setNum(curItem->
getRow());
836 "textWidget" + num, curItem->
getRow());
844 "textWidget" + num, curItem->
getRow());
848 "textWidget" + num, curItem->
getRow());
852 "textWidget" + num, curItem->
getRow());
873 aString =
"widget_set ";
874 aString += theScreen;
875 aString +=
" " + widget +
" ";
876 aString += QString::number(x);
878 aString += QString::number(row);
880 aString += theText.replace (
'"',
"\"");
889 aString =
"widget_set ";
890 aString += theScreen;
891 aString +=
" " + widget +
" 1 ";
892 aString += QString::number(row);
894 aString += theText.replace (
'"',
"\"");
903 unsigned int x = (int)(
m_lcdWidth - theText.length()) + 1;
905 aString =
"widget_set ";
906 aString += theScreen;
907 aString +=
" " + widget +
" ";
908 aString += QString::number(x);
910 aString += QString::number(row);
912 aString += theText.replace (
'"',
"\"");
918 QString theWidget,
int theRow)
938 const QString& theWidget,
int theRow)
944 theScreen,
true, theWidget));
956 auto longest = [](
int cur,
const auto & item)
957 {
return std::max(cur,
static_cast<int>(item.getText().length())); };
971 temp = temp.fill(QChar(
' '), max_len - curItem->
getText().length());
1008 unsigned int len = 0;
1011 if (item.getScroll())
1014 len = item.getText().length();
1018 item.getWidget(), item.getRow());
1025 LOG(VB_GENERAL, LOG_ERR,
1026 "LCDProcClient::scrollWidgets called without scrollable items");
1060 QString aString = std::move(artist);
1101 aString = channum +
"|" + title;
1102 if (!subtitle.isEmpty())
1103 aString +=
"|" + subtitle;
1113 if (subtitle.length() > 0)
1116 aString += subtitle;
1130 QList<LCDTextItem>::iterator it = textItems->begin();
1143 if (textItems->isEmpty())
1167 "textWidget1", curItem->
getRow());
1172 textItems->removeFirst();
1173 if (!textItems->isEmpty())
1182 if (menuItems->isEmpty())
1198 QList<LCDMenuItem>::iterator it = menuItems->begin();
1202 unsigned int selectedItem = 0;
1203 unsigned int counter = 0;
1204 bool oneSelected =
false;
1206 while (it != menuItems->end())
1212 selectedItem = counter + 1;
1222 sendToServer(
"widget_set Menu topWidget 1 1 \"No menu item selected\"");
1223 sendToServer(
"widget_set Menu menuWidget1 1 2 \" ABORTING \"");
1235 QList<LCDMenuItem>::iterator itTemp = menuItems->begin();
1238 while (itTemp != menuItems->end())
1252 it = menuItems->begin();
1253 while (it != menuItems->end())
1273 aString =
"widget_set Menu menuWidget1 1 2 \">";
1277 aString =
"widget_set Menu menuWidget1 1 1 \"";
1284 case CHECKED: aString +=
"X ";
break;
1303 it = menuItems->begin();
1307 if (selectedItem > midPoint && menuItems->size() >= (int)
m_lcdHeight-1)
1309 while (counter != selectedItem)
1315 counter -= midPoint;
1320 if (counter + midPoint > menuItems->size() - midPoint && counter > midPoint)
1322 it -= (counter + (
m_lcdHeight / 2) - 1) - (menuItems->size() - midPoint);
1326 while (it != menuItems->end())
1335 aString =
"widget_set Menu menuWidget";
1336 aString += QString::number(counter) +
" 1 ";
1337 aString += QString::number(counter + 1) +
" \"";
1346 case CHECKED: aString +=
"X ";
break;
1361 aString =
"widget_set Menu menuWidget";
1362 aString += QString::number(counter) +
" 1 ";
1363 aString += QString::number(counter + 1) +
" \"\"";
1426 unsigned int selectedItem = 0;
1427 unsigned int counter = 0;
1435 selectedItem = counter + 1;
1469 aString =
"widget_set Menu menuWidget1 1 2 \">";
1473 aString =
"widget_set Menu menuWidget1 1 1 \"";
1480 case CHECKED: aString +=
"X";
break;
1490 case CHECKED: aString +=
"X ";
break;
1498 aString += bString.fill(
' ', curItem->
getIndent());
1514 int longest_line = 0;
1515 int max_scroll_pos = 0;
1521 longest_line = std::max(
1522 #
if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1525 static_cast<int>(curItem->
ItemName().length()),
1534 if (max_scroll_pos > longest_line)
1557 while (counter != selectedItem)
1570 bool stopTimer =
true;
1585 aString =
"widget_set Menu menuWidget";
1586 aString += QString::number(counter) +
" 1 ";
1587 aString += QString::number(counter + 1) +
" \"";
1596 case CHECKED: aString +=
"X ";
break;
1604 bString.fill(
' ', curItem->
getIndent());
1746 aString =
"output ";
1747 aString += QString::number(mask);
1761 QString time = QTime::currentTime().toString(
m_timeFormat );
1772 if ((time.length() == 8) || (time.length() == 5))
1776 if (time.length() > 6)
1778 aString = time.at(5 + toffset);
1779 aString += time.at(6 + toffset);
1793 aString = QString::number((
int)
m_tunerList.size());
1806 aString =
"widget_set Time d0 ";
1807 aString += QString::number( (
m_lcdWidth/2) - 5 - xoffset) +
" ";
1811 aString += time.at(0);
1815 aString =
"widget_set Time d1 ";
1816 aString += QString::number( (
m_lcdWidth/2) - 2 - xoffset) +
" ";
1817 aString += time.at(0 + toffset);
1821 aString =
"widget_set Time sep ";
1822 aString += QString::number( (
m_lcdWidth/2) + 1 - xoffset);
1827 aString =
"widget_set Time d2 ";
1828 aString += QString::number( (
m_lcdWidth/2) + 2 - xoffset) +
" ";
1829 aString += time.at(2 + toffset);
1833 aString =
"widget_set Time d3 ";
1834 aString += QString::number( (
m_lcdWidth/2) + 5 - xoffset) +
" ";
1835 aString += time.at(3 + toffset);
1884 QString time = QTime::currentTime().toString(
m_timeFormat );
1886 aString =
"widget_set Time timeWidget ";
1887 aString += QString::number(x);
1889 aString += QString::number(y);
1892 aString += time +
"\"";
1895 aString = aString.replace(
':',
' ');
1955 std::chrono::milliseconds listTime { 1 };
1969 status += tuner.
title;
1982 status = tuner.
startTime.toLocalTime().toString(
"hh:mm") +
"-" +
1983 tuner.
endTime.toLocalTime().toString(
"hh:mm");
1988 double rec_progress = (double) delta / length;
1990 aString =
"widget_set RecStatus progressBar 13 ";
1993 aString += QString::number((
int)rint(rec_progress * (
m_lcdWidth - 13) *
2001 status = tr(
"RECORDING|");
2002 status += tuner.
title;
2004 status +=
"|(" + tuner.
subtitle +
")";
2006 status +=
"|" + tuner.
startTime.toLocalTime().toString(
"hh:mm")
2008 tuner.
endTime.toLocalTime().toString(
"hh:mm");
2017 double rec_progress = (double) delta / length;
2019 aString =
"widget_set RecStatus progressBar 1 ";
2022 aString += QString::number((
int)rint(rec_progress *
m_lcdWidth *
2028 sendToServer(
"widget_set RecStatus progressBar 1 1 0");
2042 const QString& widget,
int top,
int bottom)
2045 aString =
"widget_set " + theScreen +
" " + widget;
2047 aString += QString::number(top) +
" ";
2048 aString += QString::number(
m_lcdWidth ) +
" ";
2049 aString += QString::number(bottom);
2050 aString +=
" v 8 \"" + theText +
"\"";
2057 QString separators =
" |-_/:('<~";
2063 for (
const auto& x : std::as_const(text))
2065 if (separators.contains(x))
2066 lastSplit = line.length();
2069 if (line.length() > (
int)
m_lcdWidth || x ==
'|')
2071 QString formatedLine;
2073 formatedLine = formatedLine.replace((
m_lcdWidth - lastSplit) / 2,
2074 lastSplit, line.left(lastSplit));
2076 lines.append(formatedLine);
2078 if (line[lastSplit] ==
' ' || line[lastSplit] ==
'|')
2079 line = line.mid(lastSplit + 1);
2081 line = line.mid(lastSplit);
2088 QString formatedLine;
2090 formatedLine = formatedLine.replace((
m_lcdWidth - line.length()) / 2,
2091 line.length(), line);
2093 lines.append(formatedLine);
2108 QString shuffle =
"";
2109 QString repeat =
"";
2134 if (shuffle.length() != 0 || repeat.length() != 0)
2136 aString = shuffle + repeat;
2137 info_width = aString.length();
2145 aString =
"widget_set Music progressBar ";
2146 aString += QString::number(info_width + 1);
2161 aString =
"widget_set Channel progressBar 1 ";
2181 aString =
"widget_set Generic progressBar ";
2182 aString += QString::number (
m_busyPos );
2203 aString =
"widget_set Volume progressBar 1 ";
2228 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToTime");
2241 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToMusic") ;
2254 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToChannel");
2266 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToMenu");
2268 startMenu(menuItems, app_name, popMenu);
2278 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToGeneric");
2291 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToVolume");
2304 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToNothing");
2310 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: shutdown");
2387 LOG(VB_GENERAL, LOG_INFO,
2388 "LCDProcClient: An LCD device is being snuffed out"
2389 "of existence (~LCDProcClient() was called)");
2407 auto *me =
dynamic_cast<MythEvent *
>(e);
2411 if (me->Message().startsWith(
"RECORDING_LIST_CHANGE") ||
2412 me->Message() ==
"UPDATE_PROG_INFO")
2417 LOG(VB_GENERAL, LOG_INFO,
2418 "LCDProcClient: Received recording list change");
2437 LOG(VB_GENERAL, LOG_ERR,
2438 "LCDProcClient: Cannot get recording status "
2439 "- is the master server running?\n\t\t\t"
2440 "Will retry in 30 seconds");