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");
126 if (lcd_host.length() > 0 && lcd_port > 1024)
153 while (--
timeout &&
m_socket->state() != QAbstractSocket::ConnectedState)
155 qApp->processEvents();
156 std::this_thread::sleep_for(1ms);
158 if (
m_socket->state() == QAbstractSocket::ConnectedState)
173 if (
m_socket->state() != QAbstractSocket::ConnectedState)
185 LOG(VB_GENERAL, LOG_ERR,
186 "LCDProcClient: Connection to LCDd died unexpectedly.");
191 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
192 os.setCodec(
"ISO 8859-1");
194 os.setEncoding(QStringConverter::Latin1);
202 LOG(VB_NETWORK, LOG_INFO,
203 "LCDProcClient: Sending to Server: " + someText);
207 os << someText <<
"\n";
222 aString =
"screen_set ";
224 aString +=
" priority ";
260 msg =
"widget_add " + screen +
" heartbeat";
264 msg =
"screen_set " + screen +
" heartbeat on";
271 msg =
"widget_del " + screen +
" heartbeat";
275 msg =
"screen_set " + screen +
" heartbeat off";
284 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: checking connections");
290 LOG(VB_GENERAL, LOG_INFO,
291 "LCDProcClient: connecting to master server");
293 LOG(VB_GENERAL, LOG_ERR,
294 "LCDProcClient: connecting to master server failed");
298 if (
m_socket->state() != QAbstractSocket::ConnectedState)
301 LOG(VB_GENERAL, LOG_INFO,
302 "LCDProcClient: connecting to LCDProc server");
314 QString lineFromServer;
317 QStringList::Iterator it;
331 lineFromServer =
m_socket->readLine();
332 lineFromServer = lineFromServer.remove(
"\n");
333 lineFromServer = lineFromServer.remove(
"\r");
338 if (lineFromServer !=
"success")
339 LOG(VB_NETWORK, LOG_INFO,
340 "LCDProcClient: Received from server: " + lineFromServer);
343 aList = lineFromServer.split(
" ");
344 if (aList.first() ==
"connect")
352 if ((*it) !=
"LCDproc")
354 LOG(VB_GENERAL, LOG_WARNING,
355 "LCDProcClient: WARNING: Second parameter "
356 "returned from LCDd was not \"LCDproc\"");
361 QString server_version = *it;
364 QString protocol_version = *it;
365 setVersion (server_version, protocol_version);
395 if (aList.first() ==
"huh?")
397 LOG(VB_GENERAL, LOG_WARNING,
398 "LCDProcClient: WARNING: Something is getting"
399 "passed to LCDd that it doesn't understand");
402 else if (aList.first() ==
"key")
456 aString =
"widget_add Menu menuWidget";
457 aString += QString::number (i);
458 aString +=
" string";
498 sendToServer(
"widget_add RecStatus textWidget1 string");
499 sendToServer(
"widget_add RecStatus textWidget2 string");
500 sendToServer(
"widget_add RecStatus textWidget3 string");
501 sendToServer(
"widget_add RecStatus textWidget4 string");
530 auto add_ws = [](
const QString& str,
auto x){
return str + x + QString(
" "); };
531 return std::accumulate(aString.cbegin(), aString.cend(), QString(), add_ws);
563 if (!old_keystring.isEmpty())
565 aString =
"client_del_key " +
expandString(old_keystring);
599 QList<LCDTextItem> textItems;
605 startrow = ((
m_lcdHeight - list.count()) / 2) + 1;
607 for (
int x = 0; x < list.count(); x++)
695 LOG(VB_GENERAL, LOG_INFO,
696 QString(
"LCDProcClient: The server is %1x%2 with each cell "
699 LOG(VB_GENERAL, LOG_INFO,
700 QString(
"LCDProcClient: LCDd version %1, protocol version %2.")
706 LOG(VB_GENERAL, LOG_INFO,
707 QString(
"LCDProcClient: MythTV LCD settings:"));
708 LOG(VB_GENERAL, LOG_INFO,
709 QString(
"LCDProcClient: - showmusic : %1")
711 LOG(VB_GENERAL, LOG_INFO,
712 QString(
"LCDProcClient: - showmusicitems : %1")
714 LOG(VB_GENERAL, LOG_INFO,
715 QString(
"LCDProcClient: - showtime : %1")
717 LOG(VB_GENERAL, LOG_INFO,
718 QString(
"LCDProcClient: - showchannel : %1")
720 LOG(VB_GENERAL, LOG_INFO,
721 QString(
"LCDProcClient: - showrecstatus : %1")
723 LOG(VB_GENERAL, LOG_INFO,
724 QString(
"LCDProcClient: - showgeneric : %1")
726 LOG(VB_GENERAL, LOG_INFO,
727 QString(
"LCDProcClient: - showvolume : %1")
729 LOG(VB_GENERAL, LOG_INFO,
730 QString(
"LCDProcClient: - showmenu : %1")
732 LOG(VB_GENERAL, LOG_INFO,
733 QString(
"LCDProcClient: - backlighton : %1")
735 LOG(VB_GENERAL, LOG_INFO,
736 QString(
"LCDProcClient: - heartbeaton : %1")
738 LOG(VB_GENERAL, LOG_INFO,
739 QString(
"LCDProcClient: - popuptime : %1")
747 LOG(VB_GENERAL, LOG_ERR, QString(
"Could not connect to LCDd: %1")
774 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: stopAll");
818 QList<LCDTextItem>::iterator it = textItems->begin();
820 unsigned int counter = 1;
825 while (it != textItems->end() && counter <
m_lcdHeight )
829 num.setNum(curItem->
getRow());
834 "textWidget" + num, curItem->
getRow());
842 "textWidget" + num, curItem->
getRow());
846 "textWidget" + num, curItem->
getRow());
850 "textWidget" + num, curItem->
getRow());
871 aString =
"widget_set ";
872 aString += theScreen;
873 aString +=
" " + widget +
" ";
874 aString += QString::number(x);
876 aString += QString::number(row);
878 aString += theText.replace (
'"',
"\"");
887 aString =
"widget_set ";
888 aString += theScreen;
889 aString +=
" " + widget +
" 1 ";
890 aString += QString::number(row);
892 aString += theText.replace (
'"',
"\"");
901 unsigned int x = (int)(
m_lcdWidth - theText.length()) + 1;
903 aString =
"widget_set ";
904 aString += theScreen;
905 aString +=
" " + widget +
" ";
906 aString += QString::number(x);
908 aString += QString::number(row);
910 aString += theText.replace (
'"',
"\"");
916 QString theWidget,
int theRow)
936 const QString& theWidget,
int theRow)
942 theScreen,
true, theWidget));
954 auto longest = [](
int cur,
const auto & item)
955 {
return std::max(cur,
static_cast<int>(item.getText().length())); };
969 temp = temp.fill(QChar(
' '), max_len - curItem->
getText().length());
1006 unsigned int len = 0;
1009 if (item.getScroll())
1012 len = item.getText().length();
1016 item.getWidget(), item.getRow());
1023 LOG(VB_GENERAL, LOG_ERR,
1024 "LCDProcClient::scrollWidgets called without scrollable items");
1058 QString aString = std::move(artist);
1099 aString = channum +
"|" + title;
1100 if (!subtitle.isEmpty())
1101 aString +=
"|" + subtitle;
1111 if (subtitle.length() > 0)
1114 aString += subtitle;
1128 QList<LCDTextItem>::iterator it = textItems->begin();
1141 if (textItems->isEmpty())
1165 "textWidget1", curItem->
getRow());
1170 textItems->removeFirst();
1171 if (!textItems->isEmpty())
1180 if (menuItems->isEmpty())
1196 QList<LCDMenuItem>::iterator it = menuItems->begin();
1200 unsigned int selectedItem = 0;
1201 unsigned int counter = 0;
1202 bool oneSelected =
false;
1204 while (it != menuItems->end())
1210 selectedItem = counter + 1;
1220 sendToServer(
"widget_set Menu topWidget 1 1 \"No menu item selected\"");
1221 sendToServer(
"widget_set Menu menuWidget1 1 2 \" ABORTING \"");
1233 QList<LCDMenuItem>::iterator itTemp = menuItems->begin();
1236 while (itTemp != menuItems->end())
1250 it = menuItems->begin();
1251 while (it != menuItems->end())
1271 aString =
"widget_set Menu menuWidget1 1 2 \">";
1275 aString =
"widget_set Menu menuWidget1 1 1 \"";
1282 case CHECKED: aString +=
"X ";
break;
1301 it = menuItems->begin();
1305 if (selectedItem > midPoint && menuItems->size() >= (int)
m_lcdHeight-1)
1307 while (counter != selectedItem)
1313 counter -= midPoint;
1318 if (counter + midPoint > menuItems->size() - midPoint && counter > midPoint)
1320 it -= (counter + (
m_lcdHeight / 2) - 1) - (menuItems->size() - midPoint);
1324 while (it != menuItems->end())
1333 aString =
"widget_set Menu menuWidget";
1334 aString += QString::number(counter) +
" 1 ";
1335 aString += QString::number(counter + 1) +
" \"";
1344 case CHECKED: aString +=
"X ";
break;
1359 aString =
"widget_set Menu menuWidget";
1360 aString += QString::number(counter) +
" 1 ";
1361 aString += QString::number(counter + 1) +
" \"\"";
1422 unsigned int selectedItem = 0;
1423 unsigned int counter = 0;
1431 selectedItem = counter + 1;
1465 aString =
"widget_set Menu menuWidget1 1 2 \">";
1469 aString =
"widget_set Menu menuWidget1 1 1 \"";
1476 case CHECKED: aString +=
"X";
break;
1486 case CHECKED: aString +=
"X ";
break;
1494 aString += bString.fill(
' ', curItem->
getIndent());
1510 int longest_line = 0;
1511 int max_scroll_pos = 0;
1517 if (curItem->
ItemName().length() > longest_line)
1518 longest_line = curItem->
ItemName().length();
1525 if (max_scroll_pos > longest_line)
1548 while (counter != selectedItem)
1561 bool stopTimer =
true;
1576 aString =
"widget_set Menu menuWidget";
1577 aString += QString::number(counter) +
" 1 ";
1578 aString += QString::number(counter + 1) +
" \"";
1587 case CHECKED: aString +=
"X ";
break;
1595 bString.fill(
' ', curItem->
getIndent());
1740 aString =
"output ";
1741 aString += QString::number(mask);
1755 QString time = QTime::currentTime().toString(
m_timeFormat );
1766 if ((time.length() == 8) || (time.length() == 5))
1770 if (time.length() > 6)
1772 aString = time.at(5 + toffset);
1773 aString += time.at(6 + toffset);
1787 aString = QString::number((
int)
m_tunerList.size());
1800 aString =
"widget_set Time d0 ";
1801 aString += QString::number(
m_lcdWidth/2 - 5 - xoffset) +
" ";
1805 aString += time.at(0);
1809 aString =
"widget_set Time d1 ";
1810 aString += QString::number(
m_lcdWidth/2 - 2 - xoffset) +
" ";
1811 aString += time.at(0 + toffset);
1815 aString =
"widget_set Time sep ";
1816 aString += QString::number(
m_lcdWidth/2 + 1 - xoffset);
1821 aString =
"widget_set Time d2 ";
1822 aString += QString::number(
m_lcdWidth/2 + 2 - xoffset) +
" ";
1823 aString += time.at(2 + toffset);
1827 aString =
"widget_set Time d3 ";
1828 aString += QString::number(
m_lcdWidth/2 + 5 - xoffset) +
" ";
1829 aString += time.at(3 + toffset);
1878 QString time = QTime::currentTime().toString(
m_timeFormat );
1880 aString =
"widget_set Time timeWidget ";
1881 aString += QString::number(x);
1883 aString += QString::number(y);
1886 aString += time +
"\"";
1889 aString = aString.replace(
':',
' ');
1945 std::chrono::milliseconds listTime { 1 };
1959 status += tuner.
title;
1972 status = tuner.
startTime.toLocalTime().toString(
"hh:mm") +
"-" +
1973 tuner.
endTime.toLocalTime().toString(
"hh:mm");
1978 double rec_progress = (double) delta / length;
1980 aString =
"widget_set RecStatus progressBar 13 ";
1983 aString += QString::number((
int)rint(rec_progress * (
m_lcdWidth - 13) *
1991 status = tr(
"RECORDING|");
1992 status += tuner.
title;
1994 status +=
"|(" + tuner.
subtitle +
")";
1996 status +=
"|" + tuner.
startTime.toLocalTime().toString(
"hh:mm")
1998 tuner.
endTime.toLocalTime().toString(
"hh:mm");
2007 double rec_progress = (double) delta / length;
2009 aString =
"widget_set RecStatus progressBar 1 ";
2012 aString += QString::number((
int)rint(rec_progress *
m_lcdWidth *
2017 sendToServer(
"widget_set RecStatus progressBar 1 1 0");
2030 const QString& widget,
int top,
int bottom)
2033 aString =
"widget_set " + theScreen +
" " + widget;
2035 aString += QString::number(top) +
" ";
2036 aString += QString::number(
m_lcdWidth ) +
" ";
2037 aString += QString::number(bottom);
2038 aString +=
" v 8 \"" + theText +
"\"";
2045 QString separators =
" |-_/:('<~";
2051 for (
const auto& x : std::as_const(text))
2053 if (separators.contains(x))
2054 lastSplit = line.length();
2057 if (line.length() > (
int)
m_lcdWidth || x ==
'|')
2059 QString formatedLine;
2061 formatedLine = formatedLine.replace((
m_lcdWidth - lastSplit) / 2,
2062 lastSplit, line.left(lastSplit));
2064 lines.append(formatedLine);
2066 if (line[lastSplit] ==
' ' || line[lastSplit] ==
'|')
2067 line = line.mid(lastSplit + 1);
2069 line = line.mid(lastSplit);
2076 QString formatedLine;
2078 formatedLine = formatedLine.replace((
m_lcdWidth - line.length()) / 2,
2079 line.length(), line);
2081 lines.append(formatedLine);
2096 QString shuffle =
"";
2097 QString repeat =
"";
2122 if (shuffle.length() != 0 || repeat.length() != 0)
2124 aString = shuffle + repeat;
2125 info_width = aString.length();
2131 aString =
"widget_set Music progressBar ";
2132 aString += QString::number(info_width + 1);
2147 aString =
"widget_set Channel progressBar 1 ";
2165 aString =
"widget_set Generic progressBar ";
2166 aString += QString::number (
m_busyPos );
2174 else sendToServer(
"widget_set Generic progressBar 1 1 0");
2184 aString =
"widget_set Volume progressBar 1 ";
2209 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToTime");
2222 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToMusic") ;
2235 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToChannel");
2247 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToMenu");
2249 startMenu(menuItems, app_name, popMenu);
2259 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToGeneric");
2272 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToVolume");
2285 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: switchToNothing");
2291 LOG(VB_GENERAL, LOG_INFO,
"LCDProcClient: shutdown");
2368 LOG(VB_GENERAL, LOG_INFO,
2369 "LCDProcClient: An LCD device is being snuffed out"
2370 "of existence (~LCDProcClient() was called)");
2388 auto *me =
dynamic_cast<MythEvent *
>(e);
2392 if (me->Message().startsWith(
"RECORDING_LIST_CHANGE") ||
2393 me->Message() ==
"UPDATE_PROG_INFO")
2398 LOG(VB_GENERAL, LOG_INFO,
2399 "LCDProcClient: Received recording list change");
2418 LOG(VB_GENERAL, LOG_ERR,
2419 "LCDProcClient: Cannot get recording status "
2420 "- is the master server running?\n\t\t\t"
2421 "Will retry in 30 seconds");