MythTV  master
lcdprocclient.cpp
Go to the documentation of this file.
1 /*
2  lcdprocclient.cpp
3 
4  a MythTV project object to control an
5  LCDproc server
6 
7  (c) 2002, 2003 Thor Sigvaldason, Dan Morphis and Isaac Richards
8 */
9 
10 // c/c++
11 #include <algorithm>
12 #include <chrono> // for milliseconds
13 #include <cmath>
14 #include <cstdlib>
15 #include <thread> // for sleep_for
16 #include <utility>
17 
18 //qt
19 #include <QCoreApplication>
20 #include <QEvent>
21 #if QT_VERSION >= QT_VERSION_CHECK(6,0,0)
22 #include <QStringConverter>
23 #endif
24 #include <QTimer>
25 
26 // mythtv
27 #include "libmythbase/compat.h"
28 #include "libmythbase/lcddevice.h"
30 #include "libmythbase/mythdate.h"
31 #include "libmythbase/mythdbcon.h"
33 #include "libmythtv/tv.h"
34 
35 // mythlcdserver
36 #include "lcdprocclient.h"
37 #include "lcdserver.h"
38 
39 static constexpr uint8_t LCD_START_COL { 3 };
40 
41 static constexpr uint8_t LCD_VERSION_4 { 1 };
42 static constexpr uint8_t LCD_VERSION_5 { 2 };
43 
44 static constexpr std::chrono::milliseconds LCD_TIME_TIME { 3s };
45 static constexpr std::chrono::milliseconds LCD_SCROLLLIST_TIME { 2s };
46 
48 
50  : QObject(nullptr),
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)),
63  m_lcdTextItems (new QList<LCDTextItem>),
64  m_lcdMenuItems (new QList<LCDMenuItem>),
65  m_parentLCDServer (lparent)
66 {
67  // Constructor for LCDProcClient
68  //
69  // Note that this does *not* include opening the socket and initiating
70  // communications with the LDCd daemon.
71 
72  if (debug_level > 0)
73  LOG(VB_GENERAL, LOG_INFO,
74  "LCDProcClient: An LCDProcClient object now exists");
75 
76  connect(m_socket, &QAbstractSocket::errorOccurred, this, &LCDProcClient::veryBadThings);
77  connect(m_socket, &QIODevice::readyRead, this, &LCDProcClient::serverSendingData);
78 
80  if ( m_lcdWidth < 12)
81  {
82  if ( m_lcdHeight == 1)
83  lcdStartCol = 0;
84  else
85  lcdStartCol = 1;
86  }
87 
89 
91 
92  m_preScrollWTimer->setSingleShot(true);
93  connect( m_preScrollWTimer, &QTimer::timeout, this,
95 
96  m_popMenuTimer->setSingleShot(true);
98 
100 
101  connect( m_menuPreScrollTimer, &QTimer::timeout, this,
103 
104  connect( m_checkConnectionsTimer, &QTimer::timeout, this,
106  m_checkConnectionsTimer->start(10s);
107 
109 
111 
112  m_showMessageTimer->setSingleShot(true);
113  connect( m_showMessageTimer, &QTimer::timeout, this,
115 
116  m_updateRecInfoTimer->setSingleShot(true);
117  connect( m_updateRecInfoTimer, &QTimer::timeout, this,
119 
120  gCoreContext->addListener(this);
121 }
122 
124 {
125  QString lcd_host = gCoreContext->GetSetting("LCDHost", "localhost");
126  int lcd_port = gCoreContext->GetNumSetting("LCDPort", 13666);
127 
128  if (lcd_host.length() > 0 && lcd_port > 1024)
129  connectToHost(lcd_host, lcd_port);
130 
131  return m_connected;
132 }
133 
134 bool LCDProcClient::connectToHost(const QString &lhostname, unsigned int lport)
135 {
136  // Open communications
137  // Store the hostname and port in case we need to reconnect.
138 
139  m_hostname = lhostname;
140  m_port = lport;
141 
142  // Don't even try to connect if we're currently disabled.
143  if (!gCoreContext->GetBoolSetting("LCDEnable", false))
144  {
145  m_connected = false;
146  return m_connected;
147  }
148 
149  if (!m_connected )
150  {
151  QTextStream os(m_socket);
152  m_socket->connectToHost(m_hostname, m_port);
153 
154  int timeout = 1000;
155  while (--timeout && m_socket->state() != QAbstractSocket::ConnectedState)
156  {
157  qApp->processEvents();
158  std::this_thread::sleep_for(1ms);
159 
160  if (m_socket->state() == QAbstractSocket::ConnectedState)
161  {
162  m_connected = true;
163  os << "hello\n";
164  break;
165  }
166  }
167  }
168 
169  return m_connected;
170 }
171 
172 void LCDProcClient::sendToServer(const QString &someText)
173 {
174  // Check the socket, make sure the connection is still up
175  if (m_socket->state() != QAbstractSocket::ConnectedState)
176  {
177  if (!m_lcdReady )
178  return;
179 
180  m_lcdReady = false;
181 
182  //Stop everything
183  stopAll();
184 
185  // Ack, connection to server has been severed try to re-establish the
186  // connection
187  LOG(VB_GENERAL, LOG_ERR,
188  "LCDProcClient: Connection to LCDd died unexpectedly.");
189  return;
190  }
191 
192  QTextStream os(m_socket);
193 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
194  os.setCodec("ISO 8859-1");
195 #else
196  os.setEncoding(QStringConverter::Latin1);
197 #endif
198 
199  m_lastCommand = someText;
200 
201  if ( m_connected )
202  {
203  if (debug_level > 9)
204  LOG(VB_NETWORK, LOG_INFO,
205  "LCDProcClient: Sending to Server: " + someText);
206 
207  // Just stream the text out the socket
208 
209  os << someText << "\n";
210  }
211  else
212  {
213  // Buffer this up in the hope that the connection will open soon
214 
215  m_sendBuffer += someText;
216  m_sendBuffer += "\n";
217  }
218 }
219 
220 void LCDProcClient::setPriority(const QString &screen, PRIORITY priority)
221 {
222  QString aString;
223  int err = 0;
224  aString = "screen_set ";
225  aString += screen;
226  aString += " priority ";
227 
228  switch (priority) {
229  case TOP:
230  aString += m_prioTop;
231  break;
232  case URGENT:
233  aString += m_prioUrgent;
234  break;
235  case HIGH:
236  aString += m_prioHigh;
237  break;
238  case MEDIUM:
239  aString += m_prioMedium;
240  break;
241  case LOW:
242  aString += m_prioLow;
243  break;
244  case OFF:
245  aString += m_prioOff;
246  break;
247  default:
248  err = 1;
249  break;
250  }
251  if (err == 0)
252  sendToServer (aString);
253 }
254 
255 void LCDProcClient::setHeartbeat (const QString &screen, bool onoff)
256 {
257  QString msg;
258  if (onoff)
259  {
260  if ( m_pVersion == LCD_VERSION_4)
261  {
262  msg = "widget_add " + screen + " heartbeat";
263  }
264  if ( m_pVersion == LCD_VERSION_5)
265  {
266  msg = "screen_set " + screen + " heartbeat on";
267  }
268  }
269  else
270  {
271  if ( m_pVersion == LCD_VERSION_4)
272  {
273  msg = "widget_del " + screen + " heartbeat";
274  }
275  if ( m_pVersion == LCD_VERSION_5)
276  {
277  msg = "screen_set " + screen + " heartbeat off";
278  }
279  }
280  sendToServer (msg);
281 }
282 
284 {
285  if (debug_level > 0)
286  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: checking connections");
287 
288  // check connection to mythbackend
290  {
291  if (debug_level > 0)
292  LOG(VB_GENERAL, LOG_INFO,
293  "LCDProcClient: connecting to master server");
294  if (!gCoreContext->ConnectToMasterServer(false))
295  LOG(VB_GENERAL, LOG_ERR,
296  "LCDProcClient: connecting to master server failed");
297  }
298 
299  //check connection to LCDProc server
300  if (m_socket->state() != QAbstractSocket::ConnectedState)
301  {
302  if (debug_level > 0)
303  LOG(VB_GENERAL, LOG_INFO,
304  "LCDProcClient: connecting to LCDProc server");
305 
306  m_lcdReady = false;
307  m_connected = false;
308 
309  // Retry to connect. . . Maybe the user restarted LCDd?
311  }
312 }
313 
315 {
316  QString lineFromServer;
317  QString tempString;
318  QStringList aList;
319  QStringList::Iterator it;
320 
321  // This gets activated automatically by the QSocket class whenever
322  // there's something to read.
323  //
324  // We currently spend most of our time (except for the first line sent
325  // back) ignoring it.
326  //
327  // Note that if anyone has an LCDproc type lcd with buttons on it, this is
328  // where we would want to catch button presses and make the rest of
329  // mythTV/mythMusic do something (change tracks, channels, etc.)
330 
331  while(m_socket->canReadLine())
332  {
333  lineFromServer = m_socket->readLine();
334  lineFromServer = lineFromServer.remove("\n");
335  lineFromServer = lineFromServer.remove("\r");
336 
337  if (debug_level > 0)
338  {
339  // Make debugging be less noisy
340  if (lineFromServer != "success")
341  LOG(VB_NETWORK, LOG_INFO,
342  "LCDProcClient: Received from server: " + lineFromServer);
343  }
344 
345  aList = lineFromServer.split(" ");
346  if (aList.first() == "connect")
347  {
348  // We got a connect, which is a response to "hello"
349  //
350  // Need to parse out some data according the LCDproc client/server
351  // spec (which is poorly documented)
352  it = aList.begin();
353  it++;
354  if ((*it) != "LCDproc")
355  {
356  LOG(VB_GENERAL, LOG_WARNING,
357  "LCDProcClient: WARNING: Second parameter "
358  "returned from LCDd was not \"LCDproc\"");
359  }
360 
361  // Skip through some stuff
362  it++; // server version
363  QString server_version = *it;
364  it++; // the string "protocol"
365  it++; // protocol version
366  QString protocol_version = *it;
367  setVersion (server_version, protocol_version);
368  it++; // the string "lcd"
369  it++; // the string "wid";
370  it++; // Ah, the LCD width
371 
372  tempString = *it;
373  setWidth(tempString.toInt());
374 
375  it++; // the string "hgt"
376  it++; // the LCD height
377 
378  tempString = *it;
379  setHeight(tempString.toInt());
380  it++; // the string "cellwid"
381  it++; // Cell width in pixels;
382 
383  tempString = *it;
384  setCellWidth(tempString.toInt());
385 
386  it++; // the string "cellhgt"
387  it++; // Cell height in pixels;
388 
389  tempString = *it;
390  setCellHeight(tempString.toInt());
391 
392  init();
393 
394  describeServer();
395  }
396 
397  if (aList.first() == "huh?")
398  {
399  LOG(VB_GENERAL, LOG_WARNING,
400  "LCDProcClient: WARNING: Something is getting"
401  "passed to LCDd that it doesn't understand");
402  LOG(VB_GENERAL, LOG_WARNING, "last command: " + m_lastCommand );
403  }
404  else if (aList.first() == "key")
405  {
406  if ( m_parentLCDServer )
407  m_parentLCDServer->sendKeyPress(aList.last().trimmed());
408  }
409  }
410 }
411 
413 {
414  QString aString;
415  m_lcdKeyString = "";
416 
417  m_connected = true;
418 
419  // This gets called when we receive the "connect" string from the server
420  // indicating that "hello" was succesful
421  sendToServer("client_set name Myth");
422 
423  // Create all the screens and widgets (when we change activity in the myth
424  // program, we just swap the priorities of the screens to show only the
425  // "current one")
426  sendToServer("screen_add Time");
427  setPriority("Time", MEDIUM);
428 
429  if (gCoreContext->GetSetting("LCDBigClock", "1") == "1")
430  {
431  // Big Clock - spans multiple lines
432  sendToServer("widget_add Time rec1 string");
433  sendToServer("widget_add Time rec2 string");
434  sendToServer("widget_add Time rec3 string");
435  sendToServer("widget_add Time recCnt string");
436  sendToServer("widget_add Time d0 num");
437  sendToServer("widget_add Time d1 num");
438  sendToServer("widget_add Time sep num");
439  sendToServer("widget_add Time d2 num");
440  sendToServer("widget_add Time d3 num");
441  sendToServer("widget_add Time ampm string");
442  sendToServer("widget_add Time dot string");
443  }
444  else
445  {
446  sendToServer("widget_add Time timeWidget string");
447  sendToServer("widget_add Time topWidget string");
448  }
449 
450  // The Menu Screen
451  // I'm not sure how to do multi-line widgets with lcdproc so we're going
452  // the ghetto way
453  sendToServer("screen_add Menu");
454  setPriority("Menu", LOW);
455  sendToServer("widget_add Menu topWidget string");
456  for (unsigned int i = 1; i <= m_lcdHeight; i++)
457  {
458  aString = "widget_add Menu menuWidget";
459  aString += QString::number (i);
460  aString += " string";
461  sendToServer(aString);
462  }
463 
464  // The Music Screen
465  sendToServer("screen_add Music");
466  setPriority("Music", LOW);
467  sendToServer("widget_add Music topWidget1 string");
468  sendToServer("widget_add Music topWidget2 string");
469  sendToServer("widget_add Music timeWidget string");
470  sendToServer("widget_add Music infoWidget string");
471  sendToServer("widget_add Music progressBar hbar");
472 
473  // The Channel Screen
474  sendToServer("screen_add Channel");
475  setPriority("Channel", LOW);
476  sendToServer("widget_add Channel topWidget string");
477  sendToServer("widget_add Channel botWidget string");
478  sendToServer("widget_add Channel timeWidget string");
479  sendToServer("widget_add Channel progressBar hbar");
480 
481  // The Generic Screen
482  sendToServer("screen_add Generic");
483  setPriority("Generic", LOW);
484  sendToServer("widget_add Generic textWidget1 string");
485  sendToServer("widget_add Generic textWidget2 string");
486  sendToServer("widget_add Generic textWidget3 string");
487  sendToServer("widget_add Generic textWidget4 string");
488  sendToServer("widget_add Generic progressBar hbar");
489 
490  // The Volume Screen
491  sendToServer("screen_add Volume");
492  setPriority("Volume", LOW);
493  sendToServer("widget_add Volume topWidget string");
494  sendToServer("widget_add Volume botWidget string");
495  sendToServer("widget_add Volume progressBar hbar");
496 
497  // The Recording Status Screen
498  sendToServer("screen_add RecStatus");
499  setPriority("RecStatus", LOW);
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");
504  sendToServer("widget_add RecStatus progressBar hbar");
505 
506  m_lcdReady = true;
507  loadSettings();
508 
509  // default to showing time
510  switchToTime();
511 
513 
514  // do we need to show the startup message
515  if (!m_startupMessage.isEmpty())
517 
518  // send buffer if there's anything in there
519  if ( m_sendBuffer.length() > 0)
520  {
522  m_sendBuffer = "";
523  }
524 }
525 
526 QString LCDProcClient::expandString(const QString &aString) const
527 {
528  if ( m_pVersion != LCD_VERSION_5)
529  return aString;
530 
531  // if version 5 then white space seperate the list of characters
532  auto add_ws = [](const QString& str, auto x){ return str + x + QString(" "); };
533  return std::accumulate(aString.cbegin(), aString.cend(), QString(), add_ws);
534 }
535 
537 {
538  if (!m_lcdReady )
539  return;
540 
541  QString aString;
542  QString old_keystring = m_lcdKeyString;
543 
544  m_timeFormat = gCoreContext->GetSetting("LCDTimeFormat", "");
545  if ( m_timeFormat.isEmpty())
546  m_timeFormat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
547 
548  m_dateFormat = gCoreContext->GetSetting("DateFormat", "dd.MM.yyyy");
549 
550  // Get LCD settings
551  m_lcdShowMusic=(gCoreContext->GetSetting("LCDShowMusic", "1")=="1");
552  m_lcdShowMusicItems=(gCoreContext->GetSetting("LCDShowMusicItems", "ArtistAlbumTitle"));
553  m_lcdShowTime=(gCoreContext->GetSetting("LCDShowTime", "1")=="1");
554  m_lcdShowChannel=(gCoreContext->GetSetting("LCDShowChannel", "1")=="1");
555  m_lcdShowGeneric=(gCoreContext->GetSetting("LCDShowGeneric", "1")=="1");
556  m_lcdShowVolume=(gCoreContext->GetSetting("LCDShowVolume", "1")=="1");
557  m_lcdShowMenu=(gCoreContext->GetSetting("LCDShowMenu", "1")=="1");
558  m_lcdShowRecstatus=(gCoreContext->GetSetting("LCDShowRecStatus", "1")=="1");
559  m_lcdBacklightOn=(gCoreContext->GetSetting("LCDBacklightOn", "1")=="1");
560  m_lcdHeartbeatOn=(gCoreContext->GetSetting("LCDHeartBeatOn", "1")=="1");
561  m_lcdPopupTime = gCoreContext->GetDurSetting<std::chrono::seconds>("LCDPopupTime", 5s);
562  m_lcdBigClock = (gCoreContext->GetSetting("LCDBigClock", "1")=="1");
563  m_lcdKeyString = gCoreContext->GetSetting("LCDKeyString", "ABCDEF");
564 
565  if (!old_keystring.isEmpty())
566  {
567  aString = "client_del_key " + expandString(old_keystring);
568  sendToServer(aString);
569  }
570 
571  aString = "client_add_key " + expandString( m_lcdKeyString );
572  sendToServer(aString);
573 
574  setHeartbeat ("Time", m_lcdHeartbeatOn );
575  if ( m_lcdBacklightOn )
576  sendToServer("screen_set Time backlight on");
577  else
578  sendToServer("screen_set Time backlight off");
579 
580  setHeartbeat ("Menu", m_lcdHeartbeatOn );
581  sendToServer("screen_set Menu backlight on");
582 
583  setHeartbeat ("Music", m_lcdHeartbeatOn );
584  sendToServer("screen_set Music backlight on");
585 
586  setHeartbeat ("Channel", m_lcdHeartbeatOn );
587  sendToServer("screen_set Channel backlight on");
588 
589  setHeartbeat ("Generic", m_lcdHeartbeatOn );
590  sendToServer("screen_set Generic backlight on");
591 
592  setHeartbeat ("Volume", m_lcdHeartbeatOn );
593  sendToServer("screen_set Volume backlight on");
594 
595  setHeartbeat ("RecStatus", m_lcdHeartbeatOn );
596  sendToServer("screen_set RecStatus backlight on");
597 }
598 
600 {
601  QList<LCDTextItem> textItems;
602 
603  QStringList list = formatScrollerText( m_startupMessage );
604 
605  int startrow = 1;
606  if (list.count() < (int) m_lcdHeight )
607  startrow = (( m_lcdHeight - list.count()) / 2) + 1;
608 
609  for (int x = 0; x < list.count(); x++)
610  {
611  if (x == (int) m_lcdHeight )
612  break;
613  textItems.append(LCDTextItem(x + startrow, ALIGN_LEFT, list[x],
614  "Generic", false));
615  }
616 
617  switchToGeneric(&textItems);
618 
620 }
621 
623 {
624  switchToTime();
625 }
626 
627 void LCDProcClient::setStartupMessage(QString msg, std::chrono::seconds messagetime)
628 {
629  m_startupMessage = std::move(msg);
630  m_startupShowTime = messagetime;
631 }
632 
633 void LCDProcClient::setWidth(unsigned int x)
634 {
635  if (x < 1 || x > 80)
636  return;
637  m_lcdWidth = x;
638 }
639 
640 void LCDProcClient::setHeight(unsigned int x)
641 {
642  if (x < 1 || x > 80)
643  return;
644  m_lcdHeight = x;
645 }
646 
647 void LCDProcClient::setCellWidth(unsigned int x)
648 {
649  if (x < 1 || x > 16)
650  return;
651  m_cellWidth = x;
652 }
653 
654 void LCDProcClient::setCellHeight(unsigned int x)
655 {
656  if (x < 1 || x > 16)
657  return;
658  m_cellHeight = x;
659 }
660 
661 void LCDProcClient::setVersion(const QString &sversion, const QString &pversion)
662 {
663  m_protocolVersion = pversion;
664  m_serverVersion = sversion;
665 
666  // the pVersion number is used internally to designate which protocol
667  // version LCDd is using:
668 
669  if ( m_serverVersion.startsWith ("CVS-current") ||
670  m_serverVersion.startsWith ("0.5"))
671  {
672  // Latest CVS versions of LCDd has priorities switched
674  m_prioTop = "input";
675  m_prioUrgent = "alert";
676  m_prioHigh = "foreground";
677  m_prioMedium = "info";
678  m_prioLow = "background";
679  m_prioOff = "hidden";
680  }
681  else
682  {
684  m_prioTop = "64";
685  m_prioUrgent = "128";
686  m_prioHigh = "240";
687  m_prioMedium = "248";
688  m_prioLow = "252";
689  m_prioOff = "255";
690  }
691 }
692 
694 {
695  if (debug_level > 0)
696  {
697  LOG(VB_GENERAL, LOG_INFO,
698  QString("LCDProcClient: The server is %1x%2 with each cell "
699  "being %3x%4.")
700  .arg( m_lcdWidth ).arg( m_lcdHeight ).arg( m_cellWidth ).arg( m_cellHeight ));
701  LOG(VB_GENERAL, LOG_INFO,
702  QString("LCDProcClient: LCDd version %1, protocol version %2.")
704  }
705 
706  if (debug_level > 1)
707  {
708  LOG(VB_GENERAL, LOG_INFO,
709  QString("LCDProcClient: MythTV LCD settings:"));
710  LOG(VB_GENERAL, LOG_INFO,
711  QString("LCDProcClient: - showmusic : %1")
712  .arg( m_lcdShowMusic ));
713  LOG(VB_GENERAL, LOG_INFO,
714  QString("LCDProcClient: - showmusicitems : %1")
715  .arg( m_lcdShowMusicItems ));
716  LOG(VB_GENERAL, LOG_INFO,
717  QString("LCDProcClient: - showtime : %1")
718  .arg( m_lcdShowTime ));
719  LOG(VB_GENERAL, LOG_INFO,
720  QString("LCDProcClient: - showchannel : %1")
721  .arg( m_lcdShowChannel ));
722  LOG(VB_GENERAL, LOG_INFO,
723  QString("LCDProcClient: - showrecstatus : %1")
724  .arg( m_lcdShowRecstatus ));
725  LOG(VB_GENERAL, LOG_INFO,
726  QString("LCDProcClient: - showgeneric : %1")
727  .arg( m_lcdShowGeneric ));
728  LOG(VB_GENERAL, LOG_INFO,
729  QString("LCDProcClient: - showvolume : %1")
730  .arg( m_lcdShowVolume ));
731  LOG(VB_GENERAL, LOG_INFO,
732  QString("LCDProcClient: - showmenu : %1")
733  .arg( m_lcdShowMenu ));
734  LOG(VB_GENERAL, LOG_INFO,
735  QString("LCDProcClient: - backlighton : %1")
736  .arg( m_lcdBacklightOn ));
737  LOG(VB_GENERAL, LOG_INFO,
738  QString("LCDProcClient: - heartbeaton : %1")
739  .arg( m_lcdHeartbeatOn ));
740  LOG(VB_GENERAL, LOG_INFO,
741  QString("LCDProcClient: - popuptime : %1")
742  .arg( m_lcdPopupTime.count() ));
743  }
744 }
745 
746 void LCDProcClient::veryBadThings(QAbstractSocket::SocketError /*error*/)
747 {
748  // Deal with failures to connect and inabilities to communicate
749  LOG(VB_GENERAL, LOG_ERR, QString("Could not connect to LCDd: %1")
750  .arg(m_socket->errorString()));
751  m_socket->close();
752 }
753 
755 {
756  if ( m_scrollListItems.count() == 0)
757  return;
758 
760  return;
761 
764 
766  if ((int) m_scrollListItem >= m_scrollListItems.count())
767  m_scrollListItem = 0;
768 }
769 
771 {
772  // The usual reason things would get this far and then lcd_ready being
773  // false is the connection died and we're trying to re-establish the
774  // connection
775  if (debug_level > 1)
776  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: stopAll");
777 
778  if ( m_lcdReady )
779  {
780  setPriority("Time", OFF);
781  setPriority("Music", OFF);
782  setPriority("Channel", OFF);
783  setPriority("Generic", OFF);
784  setPriority("Volume", OFF);
785  setPriority("Menu", OFF);
786  setPriority("RecStatus", OFF);
787  }
788 
789  m_timeTimer->stop();
790  m_preScrollWTimer->stop();
791  m_scrollWTimer->stop();
792  m_popMenuTimer->stop();
793  m_menuScrollTimer->stop();
794  m_menuPreScrollTimer->stop();
795  m_recStatusTimer->stop();
796  m_scrollListTimer->stop();
797 
798  unPopMenu();
799 }
800 
802 {
803  setPriority("Time", MEDIUM);
804  setPriority("RecStatus", LOW);
805 
806  m_timeTimer->start(1s);
807  outputTime();
808  m_activeScreen = "Time";
809  m_isTimeVisible = true;
810 
813 }
814 
815 void LCDProcClient::outputText(QList<LCDTextItem> *textItems)
816 {
817  if (!m_lcdReady )
818  return;
819 
820  QList<LCDTextItem>::iterator it = textItems->begin();
821  QString num;
822  unsigned int counter = 1;
823 
824  // Do the definable scrolling in here.
825  // Use asignScrollingWidgets(curItem->getText(), "textWidget" + num);
826  // When scrolling is set, alignment has no effect
827  while (it != textItems->end() && counter < m_lcdHeight )
828  {
829  LCDTextItem *curItem = &(*it);
830  ++it;
831  num.setNum(curItem->getRow());
832 
833  if (curItem->getScroll())
834  {
835  assignScrollingWidgets(curItem->getText(), curItem->getScreen(),
836  "textWidget" + num, curItem->getRow());
837  }
838  else
839  {
840  switch (curItem->getAlignment())
841  {
842  case ALIGN_LEFT:
843  outputLeftText(curItem->getScreen(), curItem->getText(),
844  "textWidget" + num, curItem->getRow());
845  break;
846  case ALIGN_RIGHT:
847  outputRightText(curItem->getScreen(), curItem->getText(),
848  "textWidget" + num, curItem->getRow());
849  break;
850  case ALIGN_CENTERED:
851  outputCenteredText(curItem->getScreen(), curItem->getText(),
852  "textWidget" + num, curItem->getRow());
853  break;
854  default: break;
855  }
856  }
857 
858  ++counter;
859  }
860 }
861 
862 void LCDProcClient::outputCenteredText(const QString& theScreen, QString theText, const QString& widget,
863  int row)
864 {
865  QString aString;
866  unsigned int x = 0;
867 
868  x = ( m_lcdWidth - theText.length()) / 2 + 1;
869 
870  if (x > m_lcdWidth )
871  x = 1;
872 
873  aString = "widget_set ";
874  aString += theScreen;
875  aString += " " + widget + " ";
876  aString += QString::number(x);
877  aString += " ";
878  aString += QString::number(row);
879  aString += " \"";
880  aString += theText.replace ('"', "\"");
881  aString += "\"";
882  sendToServer(aString);
883 }
884 
885 void LCDProcClient::outputLeftText(const QString& theScreen, QString theText, const QString& widget,
886  int row)
887 {
888  QString aString;
889  aString = "widget_set ";
890  aString += theScreen;
891  aString += " " + widget + " 1 ";
892  aString += QString::number(row);
893  aString += " \"";
894  aString += theText.replace ('"', "\"");
895  aString += "\"";
896  sendToServer(aString);
897 }
898 
899 void LCDProcClient::outputRightText(const QString& theScreen, QString theText, const QString& widget,
900  int row)
901 {
902  QString aString;
903  unsigned int x = (int)( m_lcdWidth - theText.length()) + 1;
904 
905  aString = "widget_set ";
906  aString += theScreen;
907  aString += " " + widget + " ";
908  aString += QString::number(x);
909  aString += " ";
910  aString += QString::number(row);
911  aString += " \"";
912  aString += theText.replace ('"', "\"");
913  aString += "\"";
914  sendToServer(aString);
915 }
916 
917 void LCDProcClient::assignScrollingList(QStringList theList, QString theScreen,
918  QString theWidget, int theRow)
919 {
920  m_scrollListScreen = std::move(theScreen);
921  m_scrollListWidget = std::move(theWidget);
922  m_scrollListRow = theRow;
923  m_scrollListItems = std::move(theList);
924 
925  m_scrollListItem = 0;
926  scrollList();
928 }
929 
930 //
931 // Prepare for scrolling one or more text widgets on a single screen.
932 // Notes:
933 // - Before assigning the first text, call: lcdTextItems->clear();
934 // - After assigning the last text, call: formatScrollingWidgets()
935 // That's it ;-)
936 
937 void LCDProcClient::assignScrollingWidgets(const QString& theText, const QString& theScreen,
938  const QString& theWidget, int theRow)
939 {
940  m_scrollScreen = theScreen;
941 
942  // Alignment is not used...
943  m_lcdTextItems->append(LCDTextItem(theRow, ALIGN_LEFT, theText,
944  theScreen, true, theWidget));
945 }
946 
948 {
949  m_scrollWTimer->stop();
950  m_preScrollWTimer->stop();
951 
952  if ( m_lcdTextItems->isEmpty())
953  return; // Weird...
954 
955  // Get the length of the longest item to scroll
956  auto longest = [](int cur, const auto & item)
957  { return std::max(cur, static_cast<int>(item.getText().length())); };
958  int max_len = std::accumulate(m_lcdTextItems->cbegin(), m_lcdTextItems->cend(),
959  0, longest);
960 
961  // Make all scrollable items the same lenght and do the initial output
962  auto it = m_lcdTextItems->begin();
963  while (it != m_lcdTextItems->end())
964  {
965  LCDTextItem *curItem = &(*it);
966  ++it;
967  if (curItem->getText().length() > (int) m_lcdWidth )
968  {
969  QString temp;
970  QString temp2;
971  temp = temp.fill(QChar(' '), max_len - curItem->getText().length());
972  temp2 = temp2.fill(QChar(' '), m_lcdWidth );
973  curItem->setText(temp2 + curItem->getText() + temp);
975  curItem->getText().mid( m_lcdWidth, max_len),
976  curItem->getWidget(), curItem->getRow());
977  }
978  else
979  {
980  curItem->setScrollable(false);
982  curItem->getWidget(), curItem->getRow());
983  }
984  }
985 
986  if (max_len <= (int) m_lcdWidth )
987  // We're done, no scrolling
988  return;
989 
990  m_preScrollWTimer->start(2s);
991 }
992 
994 {
996  m_preScrollWTimer->stop();
997  m_scrollWTimer->start(400ms);
998 }
999 
1001 {
1003  return;
1004 
1005  if ( m_lcdTextItems->isEmpty())
1006  return; // Weird...
1007 
1008  unsigned int len = 0;
1009  for (const auto & item : std::as_const(*m_lcdTextItems))
1010  {
1011  if (item.getScroll())
1012  {
1013  // Note that all scrollable items have the same length!
1014  len = item.getText().length();
1015 
1017  item.getText().mid( m_scrollPosition, m_lcdWidth ),
1018  item.getWidget(), item.getRow());
1019  }
1020  }
1021 
1022  if (len == 0)
1023  {
1024  // Shouldn't happen, but....
1025  LOG(VB_GENERAL, LOG_ERR,
1026  "LCDProcClient::scrollWidgets called without scrollable items");
1027  m_scrollWTimer->stop();
1028  return;
1029  }
1030  m_scrollPosition++;
1031  if ( m_scrollPosition >= len)
1033 }
1034 
1035 void LCDProcClient::startMusic(QString artist, const QString& album, const QString& track)
1036 {
1037  // Playing music displays:
1038  // For 1-line displays:
1039  // <ArtistAlbumTitle>
1040  // For 2-line displays:
1041  // <ArtistAlbumTitle>
1042  // <Elapse/Remaining Time>
1043  // For 3-line displays:
1044  // <ArtistAlbumTitle>
1045  // <Elapse/Remaining Time>
1046  // <Info+ProgressBar>
1047  // For displays with more than 3 lines:
1048  // <ArtistAlbum>
1049  // <Title>
1050  // <Elapse/Remaining Time>
1051  // <Info+ProgressBar>
1052 
1053  // Clear the progressBar and timeWidget before activating the Music
1054  // screen. This prevents the display of outdated junk.
1055  sendToServer("widget_set Music progressBar 1 1 0");
1056  sendToServer("widget_set Music timeWidget 1 1 \"\"");
1057  m_lcdTextItems->clear();
1058 
1059  m_musicProgress = 0.0F;
1060  QString aString = std::move(artist);
1061  if ( m_lcdShowMusicItems == "ArtistAlbumTitle")
1062  {
1063  aString += " [";
1064  aString += album;
1065  aString += "] ";
1066  }
1067  else if ( m_lcdHeight < 4)
1068  {
1069  aString += " - ";
1070  }
1071 
1072  if ( m_lcdHeight < 4)
1073  {
1074  aString += track;
1075  }
1076  else
1077  {
1078  assignScrollingWidgets(track, "Music", "topWidget2", 2);
1079  }
1080  assignScrollingWidgets(aString, "Music", "topWidget1", 1);
1082 
1083  // OK, everything is at least somewhat initialised. Activate
1084  // the music screen.
1085  m_activeScreen = "Music";
1086  if ( m_lcdShowMusic )
1087  setPriority("Music", HIGH);
1088 }
1089 
1090 void LCDProcClient::startChannel(const QString& channum, const QString& title, const QString& subtitle)
1091 {
1092  QString aString;
1093 
1094  if ( m_lcdShowChannel )
1095  setPriority("Channel", HIGH);
1096 
1097  m_activeScreen = "Channel";
1098 
1099  if ( m_lcdHeight <= 2)
1100  {
1101  aString = channum + "|" + title;
1102  if (!subtitle.isEmpty())
1103  aString += "|" + subtitle;
1104  QStringList list = formatScrollerText(aString);
1105  assignScrollingList(list, "Channel", "topWidget", 1);
1106  }
1107  else
1108  {
1109  aString = channum;
1110  m_lcdTextItems->clear();
1111  assignScrollingWidgets(aString, "Channel", "topWidget", 1);
1112  aString = title;
1113  if (subtitle.length() > 0)
1114  {
1115  aString += " - '";
1116  aString += subtitle;
1117  aString += "'";
1118  }
1119  assignScrollingWidgets(aString, "Channel", "botWidget", 2);
1121  }
1122 
1123  m_channelTime = "";
1124  m_progress = 0.0;
1125  outputChannel();
1126 }
1127 
1128 void LCDProcClient::startGeneric(QList<LCDTextItem> *textItems)
1129 {
1130  QList<LCDTextItem>::iterator it = textItems->begin();
1131  LCDTextItem *curItem = &(*it);
1132 
1133  if ( m_lcdShowGeneric )
1134  setPriority("Generic", TOP);
1135 
1136  // Clear out the LCD. Do this before checking if its empty incase the user
1137  // wants to just clear the lcd
1138  outputLeftText("Generic", "", "textWidget1", 1);
1139  outputLeftText("Generic", "", "textWidget2", 2);
1140  outputLeftText("Generic", "", "textWidget3", 3);
1141 
1142  // If nothing, return without setting up the timer, etc
1143  if (textItems->isEmpty())
1144  return;
1145 
1146  m_activeScreen = "Generic";
1147 
1148  m_busyProgress = false;
1149  m_busyPos = 1;
1150  m_busyDirection = 1;
1151  m_busyIndicatorSize = 2.0F;
1152  m_genericProgress = 0.0;
1153 
1154  // Todo, make scrolling definable in LCDTextItem
1155  ++it;
1156 
1157 
1158  // Weird observations:
1159  // - The first item is always assumed 'scrolling', for this
1160  // item, the scrollable property is ignored...
1161  // - Why output line 1, progressbar, rest of lines? Why not
1162  // all outputlines, progressbar? That way, outputText() can
1163  // just handle the whole thing and the 'pop off' stuff can go.
1164  //
1165  m_lcdTextItems->clear();
1166  assignScrollingWidgets(curItem->getText(), "Generic",
1167  "textWidget1", curItem->getRow());
1168 
1169  outputGeneric();
1170 
1171  // Pop off the first item so item one isn't written twice
1172  textItems->removeFirst();
1173  if (!textItems->isEmpty())
1174  outputText(textItems);
1176 }
1177 
1178 void LCDProcClient::startMenu(QList<LCDMenuItem> *menuItems, QString app_name,
1179  bool popMenu)
1180 {
1181  // Now do the menu items
1182  if (menuItems->isEmpty())
1183  return;
1184 
1185  QString aString;
1186 
1187  // Stop the scrolling if the menu has changed
1188  m_menuScrollTimer->stop();
1189 
1190  // Menu is higher priority than volume
1191  if ( m_lcdShowMenu )
1192  setPriority("Menu", URGENT);
1193 
1194  // Write out the app name
1195  if ( m_lcdHeight > 1)
1196  outputCenteredText("Menu", std::move(app_name), "topWidget", 1);
1197 
1198  QList<LCDMenuItem>::iterator it = menuItems->begin();
1199 
1200  // First loop through and figure out where the selected item is in the
1201  // list so we know how many above and below to display
1202  unsigned int selectedItem = 0;
1203  unsigned int counter = 0;
1204  bool oneSelected = false;
1205 
1206  while (it != menuItems->end())
1207  {
1208  LCDMenuItem *curItem = &(*it);
1209  ++it;
1210  if (curItem->isSelected() && !oneSelected)
1211  {
1212  selectedItem = counter + 1;
1213  oneSelected = true;
1214  break;
1215  }
1216  ++counter;
1217  }
1218 
1219  // If there isn't one selected item, then write it on the display and return
1220  if (!oneSelected)
1221  {
1222  sendToServer("widget_set Menu topWidget 1 1 \"No menu item selected\"");
1223  sendToServer("widget_set Menu menuWidget1 1 2 \" ABORTING \"");
1224  m_menuScrollTimer->stop();
1225  return;
1226  }
1227 
1228  m_popMenuTimer->stop();
1229  // Start the unPop timer if this is a popup menu
1230  if (popMenu)
1231  m_popMenuTimer->start( m_lcdPopupTime );
1232 
1233  // QPtrListIterator doesn't contain a deep copy constructor. . .
1234  // This will contain a copy of the menuItems for scrolling purposes
1235  QList<LCDMenuItem>::iterator itTemp = menuItems->begin();
1236  m_lcdMenuItems->clear();
1237  counter = 1;
1238  while (itTemp != menuItems->end())
1239  {
1240  LCDMenuItem *curItem = &(*itTemp);
1241  ++itTemp;
1242  m_lcdMenuItems->append(LCDMenuItem(curItem->isSelected(),
1243  curItem->isChecked(), curItem->ItemName(),
1244  curItem->getIndent()));
1245  ++counter;
1246  }
1247 
1248  // If there is only one or two lines on the display, then just write the selected
1249  // item and leave
1250  if ( m_lcdHeight <= 2)
1251  {
1252  it = menuItems->begin();
1253  while (it != menuItems->end())
1254  {
1255  LCDMenuItem *curItem = &(*it);
1256  ++it;
1257  if (curItem->isSelected())
1258  {
1259  // Set the scroll flag if necessary, otherwise set it to false
1260  if (curItem->ItemName().length() > (int)( m_lcdWidth -lcdStartCol))
1261  {
1262  m_menuPreScrollTimer->setSingleShot(true);
1263  m_menuPreScrollTimer->start(2s);
1264  curItem->setScroll(true);
1265  }
1266  else
1267  {
1268  m_menuPreScrollTimer->stop();
1269  curItem->setScroll(false);
1270  }
1271  if ( m_lcdHeight == 2)
1272  {
1273  aString = "widget_set Menu menuWidget1 1 2 \">";
1274  }
1275  else
1276  {
1277  aString = "widget_set Menu menuWidget1 1 1 \"";
1278  }
1279 
1280  if (lcdStartCol != 0)
1281  {
1282  switch (curItem->isChecked())
1283  {
1284  case CHECKED: aString += "X "; break;
1285  case UNCHECKED: aString += "O "; break;
1286  case NOTCHECKABLE: aString += " "; break;
1287  default: break;
1288  }
1289  }
1290 
1291  aString += curItem->ItemName().left( m_lcdWidth - lcdStartCol) +
1292  "\"";
1293  sendToServer(aString);
1294  return;
1295  }
1296  }
1297 
1298  return;
1299  }
1300 
1301  // Reset things
1302  counter = 1;
1303  it = menuItems->begin();
1304 
1305  // Move the iterator to selectedItem lcdHeight/2, if > 1, -1.
1306  unsigned int midPoint = ( m_lcdHeight/2) - 1;
1307  if (selectedItem > midPoint && menuItems->size() >= (int) m_lcdHeight-1)
1308  {
1309  while (counter != selectedItem)
1310  {
1311  ++it;
1312  ++counter;
1313  }
1314  it -= midPoint;
1315  counter -= midPoint;
1316  }
1317 
1318  // Back up one if we're at the end so the last item shows up at the bottom
1319  // of the display
1320  if (counter + midPoint > menuItems->size() - midPoint && counter > midPoint)
1321  {
1322  it -= (counter + ( m_lcdHeight / 2) - 1) - (menuItems->size() - midPoint);
1323  }
1324 
1325  counter = 1;
1326  while (it != menuItems->end())
1327  {
1328  LCDMenuItem *curItem = &(*it);
1329  // Can't write more menu items then we have on the display
1330  if ((counter + 1) > m_lcdHeight )
1331  break;
1332 
1333  ++it;
1334 
1335  aString = "widget_set Menu menuWidget";
1336  aString += QString::number(counter) + " 1 ";
1337  aString += QString::number(counter + 1) + " \"";
1338 
1339  if (curItem->isSelected())
1340  aString += ">";
1341  else
1342  aString += " ";
1343 
1344  switch (curItem->isChecked())
1345  {
1346  case CHECKED: aString += "X "; break;
1347  case UNCHECKED: aString += "O "; break;
1348  case NOTCHECKABLE: aString += " "; break;
1349  default: break;
1350  }
1351 
1352  aString += curItem->ItemName().left( m_lcdWidth - lcdStartCol) + "\"";
1353  sendToServer(aString);
1354 
1355  ++counter;
1356  }
1357 
1358  // Make sure to clear out the rest of the screen
1359  while (counter < m_lcdHeight )
1360  {
1361  aString = "widget_set Menu menuWidget";
1362  aString += QString::number(counter) + " 1 ";
1363  aString += QString::number(counter + 1) + " \"\"";
1364  sendToServer(aString);
1365 
1366  ++counter;
1367  }
1368 
1369  m_menuPreScrollTimer->setSingleShot(true);
1370  m_menuPreScrollTimer->start(2s);
1371 }
1372 
1374 {
1375  // If there are items to scroll, wait 2 seconds for the user to read whats
1376  // already there
1377 
1378  if (!m_lcdMenuItems )
1379  return;
1380 
1382 
1383  QList<LCDMenuItem>::iterator it = m_lcdMenuItems->begin();
1384 
1385  QString temp;
1386  // Loop through and prepend everything with enough spaces
1387  // for smooth scrolling, and update the position
1388  while (it != m_lcdMenuItems->end())
1389  {
1390  LCDMenuItem *curItem = &(*it);
1391  ++it;
1392  // Don't setup for smooth scrolling if the item isn't long enough
1393  // (It causes problems with items being scrolled when they shouldn't)
1394  if (curItem->ItemName().length() > (int)( m_lcdWidth - lcdStartCol))
1395  {
1396  temp = temp.fill(QChar(' '), m_lcdWidth - curItem->getIndent() -
1397  lcdStartCol);
1398  curItem->setItemName(temp + curItem->ItemName());
1399  curItem->setScrollPos(curItem->getIndent() + temp.length());
1400  curItem->setScroll(true);
1401  }
1402  else
1403  {
1404  curItem->setScroll(false);
1405  }
1406  }
1407 
1408  // Can get segfaults if we try to start a timer thats already running. . .
1409  m_menuScrollTimer->stop();
1410  m_menuScrollTimer->start(250ms);
1411 }
1412 
1414 {
1415  if (!m_lcdMenuItems )
1416  return;
1417 
1418  QString aString;
1419  QString bString;
1420  QList<LCDMenuItem>::iterator it = m_lcdMenuItems->begin();
1421 
1423 
1424  // First loop through and figure out where the selected item is in the
1425  // list so we know how many above and below to display
1426  unsigned int selectedItem = 0;
1427  unsigned int counter = 0;
1428 
1429  while (it != m_lcdMenuItems->end())
1430  {
1431  LCDMenuItem *curItem = &(*it);
1432  ++it;
1433  if (curItem->isSelected())
1434  {
1435  selectedItem = counter + 1;
1436  break;
1437  }
1438  ++counter;
1439  }
1440 
1441  // If there is only one or two lines on the display, then just write
1442  // the selected item and leave
1443  it = m_lcdMenuItems->begin();
1444  if ( m_lcdHeight <= 2)
1445  {
1446  while (it != m_lcdMenuItems->end())
1447  {
1448  LCDMenuItem *curItem = &(*it);
1449  ++it;
1450  if (curItem->isSelected())
1451  {
1452  curItem->incrementScrollPos();
1453  if ((int)curItem->getScrollPos() > curItem->ItemName().length())
1454  {
1455  // Scroll slower second and subsequent times through
1456  m_menuScrollTimer->stop();
1457  m_menuScrollTimer->start(500ms);
1458  curItem->setScrollPos(curItem->getIndent());
1459  }
1460 
1461  // Stop the timer if this item really doesn't need to scroll.
1462  // This should never have to get invoked because in theory
1463  // the code in startMenu has done its job. . .
1464  if (curItem->ItemName().length() < (int)( m_lcdWidth - lcdStartCol))
1465  m_menuScrollTimer->stop();
1466 
1467  if ( m_lcdHeight == 2)
1468  {
1469  aString = "widget_set Menu menuWidget1 1 2 \">";
1470  }
1471  else
1472  {
1473  aString = "widget_set Menu menuWidget1 1 1 \"";
1474  }
1475 
1476  if ( m_lcdWidth < 12)
1477  {
1478  switch(curItem->isChecked())
1479  {
1480  case CHECKED: aString += "X"; break;
1481  case UNCHECKED: aString += "O"; break;
1482  case NOTCHECKABLE: aString += ""; break;
1483  default: break;
1484  }
1485  }
1486  else
1487  {
1488  switch(curItem->isChecked())
1489  {
1490  case CHECKED: aString += "X "; break;
1491  case UNCHECKED: aString += "O "; break;
1492  case NOTCHECKABLE: aString += " "; break;
1493  default: break;
1494  }
1495  }
1496 
1497  // Indent this item if nessicary
1498  aString += bString.fill(' ', curItem->getIndent());
1499 
1500  aString += curItem->ItemName().mid(curItem->getScrollPos(),
1501  ( m_lcdWidth - lcdStartCol));
1502  aString += "\"";
1503  sendToServer(aString);
1504  return;
1505  }
1506  }
1507 
1508  return;
1509  }
1510 
1511  // Find the longest line, if menuScrollPosition is longer then this, then
1512  // reset them all
1513  it = m_lcdMenuItems->begin();
1514  int longest_line = 0;
1515  int max_scroll_pos = 0;
1516 
1517  while (it != m_lcdMenuItems->end())
1518  {
1519  LCDMenuItem *curItem = &(*it);
1520  ++it;
1521  longest_line = std::max(
1522 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
1523  curItem->ItemName().length(),
1524 #else
1525  static_cast<int>(curItem->ItemName().length()),
1526 #endif
1527  longest_line);
1528 
1529  if ((int)curItem->getScrollPos() > max_scroll_pos)
1530  max_scroll_pos = curItem->getScrollPos();
1531  }
1532 
1533  // If max_scroll_pos > longest_line then reset
1534  if (max_scroll_pos > longest_line)
1535  {
1536  // Scroll slower second and subsequent times through
1537  m_menuScrollTimer->stop();
1538  m_menuScrollTimer->start(500ms);
1540 
1541  it = m_lcdMenuItems->begin();
1542  while (it != m_lcdMenuItems->end())
1543  {
1544  LCDMenuItem *curItem = &(*it);
1545  ++it;
1546  curItem->setScrollPos(curItem->getIndent());
1547  }
1548  }
1549 
1550  // Reset things
1551  counter = 1;
1552  it = m_lcdMenuItems->begin();
1553 
1554  // Move the iterator to selectedItem -1
1555  if (selectedItem != 1 && m_lcdMenuItems->size() >= (int) m_lcdHeight )
1556  {
1557  while (counter != selectedItem)
1558  {
1559  ++it;
1560  ++counter;
1561  }
1562  --it;
1563  }
1564 
1565  // Back up one if were at the end so the last item shows up at the bottom
1566  // of the display
1567  if (counter > 1 && (int)counter == m_lcdMenuItems->size())
1568  --it;
1569 
1570  bool stopTimer = true;
1571 
1572  counter = 1;
1573  while (it != m_lcdMenuItems->end() && counter <= m_lcdHeight )
1574  {
1575  LCDMenuItem *curItem = &(*it);
1576  // Can't write more menu items then we have on the display
1577  if ((counter + 1) > m_lcdHeight )
1578  break;
1579 
1580  ++it;
1581 
1582  if (curItem->Scroll())
1583  {
1584  stopTimer = false;
1585  aString = "widget_set Menu menuWidget";
1586  aString += QString::number(counter) + " 1 ";
1587  aString += QString::number(counter + 1) + " \"";
1588 
1589  if (curItem->isSelected())
1590  aString += ">";
1591  else
1592  aString += " ";
1593 
1594  switch (curItem->isChecked())
1595  {
1596  case CHECKED: aString += "X "; break;
1597  case UNCHECKED: aString += "O "; break;
1598  case NOTCHECKABLE: aString += " "; break;
1599  default: break;
1600  }
1601 
1602  // Indent this item if nessicary
1603  bString = "";
1604  bString.fill(' ', curItem->getIndent());
1605  aString += bString;
1606 
1607  // Increment the scroll position counter for this item
1608  curItem->incrementScrollPos();
1609 
1610  if ((int)curItem->getScrollPos() <= longest_line)
1611  aString += curItem->ItemName().mid(curItem->getScrollPos(),
1612  ( m_lcdWidth-lcdStartCol));
1613 
1614  aString += "\"";
1615  sendToServer(aString);
1616  }
1617 
1618  ++counter;
1619  }
1620 
1621  // If there are no items to scroll, don't waste our time
1622  if (stopTimer)
1623  m_menuScrollTimer->stop();
1624 }
1625 
1626 void LCDProcClient::startVolume(const QString& app_name)
1627 {
1628  if ( m_lcdShowVolume )
1629  setPriority("Volume", TOP);
1630  if ( m_lcdHeight > 1)
1631  outputCenteredText("Volume", "MythTV " + app_name + " Volume");
1632  m_volumeLevel = 0.0;
1633 
1634  outputVolume();
1635 }
1636 
1638 {
1639  // Stop the scrolling timer
1640  m_menuScrollTimer->stop();
1641  setPriority("Menu", OFF);
1642 }
1643 
1644 void LCDProcClient::setChannelProgress(const QString &time, float value)
1645 {
1646  if (!m_lcdReady )
1647  return;
1648 
1649  m_progress = value;
1650  m_channelTime = time;
1651 
1652  if ( m_progress < 0.0F)
1653  m_progress = 0.0F;
1654  else if ( m_progress > 1.0F)
1655  m_progress = 1.0F;
1656 
1657  outputChannel();
1658 }
1659 
1660 void LCDProcClient::setGenericProgress(bool b, float value)
1661 {
1662  if (!m_lcdReady )
1663  return;
1664 
1665  m_genericProgress = value;
1666 
1667  if ( m_genericProgress < 0.0F)
1668  m_genericProgress = 0.0F;
1669  else if ( m_genericProgress > 1.0F)
1670  m_genericProgress = 1.0F;
1671 
1672  // Note, this will let us switch to/from busy indicator by
1673  // alternating between being passed true or false for b.
1674  m_busyProgress = b;
1675  if ( m_busyProgress )
1676  {
1677  // If we're at either end of the line, switch direction
1678  if (( m_busyPos + m_busyDirection >
1679  (signed int) m_lcdWidth - m_busyIndicatorSize ) ||
1680  ( m_busyPos + m_busyDirection < 1))
1681  {
1683  }
1686  }
1687  else
1688  {
1689  m_busyPos = 1;
1690  }
1691 
1692  outputGeneric();
1693 }
1694 
1695 void LCDProcClient::setMusicProgress(QString time, float value)
1696 {
1697  if (!m_lcdReady )
1698  return;
1699 
1700  m_musicProgress = value;
1701  m_musicTime = std::move(time);
1702 
1703  if ( m_musicProgress < 0.0F)
1704  m_musicProgress = 0.0F;
1705  else if ( m_musicProgress > 1.0F)
1706  m_musicProgress = 1.0F;
1707 
1708  outputMusic();
1709 }
1710 
1712 {
1713  if (!m_lcdReady )
1714  return;
1715 
1716  m_musicRepeat = repeat;
1717 
1718  outputMusic ();
1719 }
1720 
1722 {
1723  if (!m_lcdReady )
1724  return;
1725 
1726  m_musicShuffle = shuffle;
1727 
1728  outputMusic ();
1729 }
1730 
1732 {
1733  if (!m_lcdReady )
1734  return;
1735 
1736  m_volumeLevel = value;
1737 
1738  m_volumeLevel = std::clamp(m_volumeLevel, 0.0F, 1.0F);
1739 
1740  outputVolume();
1741 }
1742 
1744 {
1745  QString aString;
1746  aString = "output ";
1747  aString += QString::number(mask);
1748  sendToServer(aString);
1749 }
1750 
1752 {
1753  removeWidgets();
1754  loadSettings();
1755  init();
1756 }
1757 
1759 {
1760  QString aString;
1761  QString time = QTime::currentTime().toString( m_timeFormat );
1762  int toffset = 0;
1763  int xoffset = 0;
1764 
1765  // kludge ahead: use illegal number (11) to clear num display type
1766 
1767  // kluge - Uses string length to determine time format for parsing
1768  // 1:00 = 4 characters = 24-hour format, 1 digit hour
1769  // 12:00 = 5 characters = 24-hour format, 2 digit hour
1770  // 1:00 am = 7 characters = 12-hour format, 1 digit hour
1771  // 12:00 am = 8 characters = 12-hour format, 2 digit hour
1772  if ((time.length() == 8) || (time.length() == 5))
1773  toffset = 1;
1774 
1775  // if 12-hour clock, add AM/PM indicator to end of the 2nd line
1776  if (time.length() > 6)
1777  {
1778  aString = time.at(5 + toffset);
1779  aString += time.at(6 + toffset);
1780  xoffset = 1;
1781  }
1782  else
1783  {
1784  aString = " ";
1785  }
1786  outputRightText("Time", aString, "ampm", m_lcdHeight - 1);
1787 
1788  if ( m_isRecording )
1789  {
1790  outputLeftText("Time","R","rec1",1);
1791  outputLeftText("Time","E","rec2",2);
1792  outputLeftText("Time","C","rec3",3);
1793  aString = QString::number((int) m_tunerList.size());
1794  outputLeftText("Time",aString,"recCnt",4);
1795 
1796  }
1797  else
1798  {
1799  outputLeftText("Time"," ","rec1",1);
1800  outputLeftText("Time"," ","rec2",2);
1801  outputLeftText("Time"," ","rec3",3);
1802  outputLeftText("Time"," ","recCnt",4);
1803  }
1804 
1805  // Add Hour 10's Digit
1806  aString = "widget_set Time d0 ";
1807  aString += QString::number( (m_lcdWidth/2) - 5 - xoffset) + " ";
1808  if (toffset == 0)
1809  aString += "11";
1810  else
1811  aString += time.at(0);
1812  sendToServer(aString);
1813 
1814  // Add Hour 1's Digit
1815  aString = "widget_set Time d1 ";
1816  aString += QString::number( (m_lcdWidth/2) - 2 - xoffset) + " ";
1817  aString += time.at(0 + toffset);
1818  sendToServer(aString);
1819 
1820  // Add the Colon
1821  aString = "widget_set Time sep ";
1822  aString += QString::number( (m_lcdWidth/2) + 1 - xoffset);
1823  aString += " 10"; // 10 means: colon
1824  sendToServer(aString);
1825 
1826  // Add Minute 10's Digit
1827  aString = "widget_set Time d2 ";
1828  aString += QString::number( (m_lcdWidth/2) + 2 - xoffset) + " ";
1829  aString += time.at(2 + toffset);
1830  sendToServer(aString);
1831 
1832  // Add Minute 1's Digit
1833  aString = "widget_set Time d3 ";
1834  aString += QString::number( (m_lcdWidth/2) + 5 - xoffset) + " ";
1835  aString += time.at(3 + toffset);
1836  sendToServer(aString);
1837 
1838  // Added a flashing dot in the bottom-right corner
1839  if ( m_timeFlash )
1840  {
1841  outputRightText("Time", ".", "dot", m_lcdHeight );
1842  m_timeFlash = false;
1843  }
1844  else
1845  {
1846  outputRightText("Time", " ", "dot", m_lcdHeight );
1847  m_timeFlash = true;
1848  }
1849 }
1850 
1852 {
1853  if ( m_lcdBigClock )
1854  dobigclock();
1855  else
1856  dostdclock();
1857 }
1858 
1860 {
1861  if (!m_lcdShowTime )
1862  return;
1863 
1865  {
1866  outputCenteredText("Time", tr("RECORDING"), "topWidget", 1);
1867  }
1868  else
1869  {
1871  "Time", MythDate::current().toLocalTime().toString( m_dateFormat ),
1872  "topWidget", 1);
1873  }
1874 
1875  QString aString;
1876  int x = 0;
1877  int y = 0;
1878 
1879  if ( m_lcdHeight < 3)
1880  y = m_lcdHeight;
1881  else
1882  y = (int) std::rint( m_lcdHeight / 2) + 1;
1883 
1884  QString time = QTime::currentTime().toString( m_timeFormat );
1885  x = ( m_lcdWidth - time.length()) / 2 + 1;
1886  aString = "widget_set Time timeWidget ";
1887  aString += QString::number(x);
1888  aString += " ";
1889  aString += QString::number(y);
1890  aString += " \"";
1891  if ( m_lcdShowTime ) {
1892  aString += time + "\"";
1893  if ( m_timeFlash )
1894  {
1895  aString = aString.replace(':', ' ');
1896  m_timeFlash = false;
1897  }
1898  else
1899  {
1900  m_timeFlash = true;
1901  }
1902  }
1903  else
1904  {
1905  aString += " \"";
1906  }
1907  sendToServer(aString);
1908 }
1909 
1910 // if one or more recordings are taking place we alternate between
1911 // showing the time and the recording status screen
1913 {
1915  return;
1916 
1917  if ( m_isTimeVisible || !m_lcdShowTime )
1918  {
1919  // switch to the rec status screen
1920  setPriority("RecStatus", MEDIUM);
1921  setPriority("Time", LOW);
1922 
1923  m_timeTimer->stop();
1924  m_scrollWTimer->stop();
1925  m_scrollListTimer->stop();
1926  m_isTimeVisible = false;
1927  m_activeScreen = "RecStatus";
1928 
1929  if (m_lcdTunerNo > (int) m_tunerList.size() - 1)
1930  m_lcdTunerNo = 0;
1931  }
1932  else if ( m_lcdTunerNo > (int) m_tunerList.size() - 1)
1933  {
1934  m_lcdTunerNo = 0;
1935 
1936  // switch to the time screen
1937  setPriority("Time", MEDIUM);
1938  setPriority("RecStatus", LOW);
1939 
1940  m_timeTimer->start(1s);
1941  m_scrollWTimer->stop();
1942  m_scrollListTimer->stop();
1944 
1945  outputTime();
1946  m_activeScreen = "Time";
1947  m_isTimeVisible = true;
1948 
1949  return;
1950  }
1951 
1952  QString aString;
1953  QString status;
1954  QStringList list;
1955  std::chrono::milliseconds listTime { 1 };
1956 
1958 
1959  m_scrollListItems.clear();
1960  if ( m_lcdHeight >= 4)
1961  {
1962  // LINE 1 - "R" + Channel
1963  status = tr("R ");
1964  status += tuner.channame;
1965  outputLeftText("RecStatus", status, "textWidget1", 1);
1966 
1967  // LINE 2 - "E" + Program Title
1968  status = tr("E ");
1969  status += tuner.title;
1970  outputLeftText("RecStatus", status, "textWidget2", 2);
1971  //list = formatScrollerText(status);
1972  //assignScrollingList(list, "RecStatus", "textWidget2", 2);
1973 
1974  // LINE 3 - "C" + Program Subtitle
1975  status = tr("C ");
1976  status += tuner.subtitle;
1977  outputLeftText("RecStatus", status, "textWidget3", 3);
1978  //list = formatScrollerText(status);
1979  //assignScrollingList(list, "RecStatus", "textWidget3", 3);
1980 
1981  // LINE 4 - hh:mm-hh:mm + Progress Bar
1982  status = tuner.startTime.toLocalTime().toString("hh:mm") + "-" +
1983  tuner.endTime.toLocalTime().toString("hh:mm");
1984  outputLeftText("RecStatus", status, "textWidget4", 4);
1985 
1986  int length = tuner.startTime.secsTo(tuner.endTime);
1987  int delta = tuner.startTime.secsTo(MythDate::current());
1988  double rec_progress = (double) delta / length;
1989 
1990  aString = "widget_set RecStatus progressBar 13 ";
1991  aString += QString::number( m_lcdHeight );
1992  aString += " ";
1993  aString += QString::number((int)rint(rec_progress * ( m_lcdWidth - 13) *
1994  m_cellWidth ));
1995  sendToServer(aString);
1996 
1997  listTime = list.count() * LCD_SCROLLLIST_TIME * 2;
1998  }
1999  else
2000  {
2001  status = tr("RECORDING|");
2002  status += tuner.title;
2003  if (!tuner.subtitle.isEmpty())
2004  status += "|(" + tuner.subtitle + ")";
2005 
2006  status += "|" + tuner.startTime.toLocalTime().toString("hh:mm")
2007  + " to " +
2008  tuner.endTime.toLocalTime().toString("hh:mm");
2009 
2010  list = formatScrollerText(status);
2011  assignScrollingList(list, "RecStatus", "textWidget1", 1);
2012 
2013  if ( m_lcdHeight > 1)
2014  {
2015  int length = tuner.startTime.secsTo(tuner.endTime);
2016  int delta = tuner.startTime.secsTo(MythDate::current());
2017  double rec_progress = (double) delta / length;
2018 
2019  aString = "widget_set RecStatus progressBar 1 ";
2020  aString += QString::number( m_lcdHeight );
2021  aString += " ";
2022  aString += QString::number((int)rint(rec_progress * m_lcdWidth *
2023  m_cellWidth ));
2024  sendToServer(aString);
2025  }
2026  else
2027  {
2028  sendToServer("widget_set RecStatus progressBar 1 1 0");
2029  }
2030 
2031  listTime = list.count() * LCD_SCROLLLIST_TIME * 2;
2032  }
2033 
2034  if (listTime < LCD_TIME_TIME)
2035  listTime = LCD_TIME_TIME;
2036 
2037  m_recStatusTimer->start(listTime);
2038  m_lcdTunerNo++;
2039 }
2040 
2041 void LCDProcClient::outputScrollerText(const QString& theScreen, const QString& theText,
2042  const QString& widget, int top, int bottom)
2043 {
2044  QString aString;
2045  aString = "widget_set " + theScreen + " " + widget;
2046  aString += " 1 ";
2047  aString += QString::number(top) + " ";
2048  aString += QString::number( m_lcdWidth ) + " ";
2049  aString += QString::number(bottom);
2050  aString += " v 8 \"" + theText + "\"";
2051 
2052  sendToServer(aString);
2053 }
2054 
2055 QStringList LCDProcClient::formatScrollerText(const QString &text) const
2056 {
2057  QString separators = " |-_/:('<~";
2058  QStringList lines;
2059 
2060  int lastSplit = 0;
2061  QString line = "";
2062 
2063  for (const auto& x : std::as_const(text))
2064  {
2065  if (separators.contains(x))
2066  lastSplit = line.length();
2067 
2068  line += x;
2069  if (line.length() > (int) m_lcdWidth || x == '|')
2070  {
2071  QString formatedLine;
2072  formatedLine.fill(' ', m_lcdWidth );
2073  formatedLine = formatedLine.replace(( m_lcdWidth - lastSplit) / 2,
2074  lastSplit, line.left(lastSplit));
2075 
2076  lines.append(formatedLine);
2077 
2078  if (line[lastSplit] == ' ' || line[lastSplit] == '|')
2079  line = line.mid(lastSplit + 1);
2080  else
2081  line = line.mid(lastSplit);
2082 
2083  lastSplit = m_lcdWidth;
2084  }
2085  }
2086 
2087  // make sure we add the last line
2088  QString formatedLine;
2089  formatedLine.fill(' ', m_lcdWidth );
2090  formatedLine = formatedLine.replace(( m_lcdWidth - line.length()) / 2,
2091  line.length(), line);
2092 
2093  lines.append(formatedLine);
2094 
2095  return lines;
2096 }
2097 
2099 {
2100  // See startMusic() for a discription of the Music screen contents
2101 
2102  outputCenteredText("Music", m_musicTime, "timeWidget",
2103  m_lcdHeight < 4 ? 2 : 3);
2104 
2105  if ( m_lcdHeight > 2)
2106  {
2107  QString aString;
2108  QString shuffle = "";
2109  QString repeat = "";
2110  int info_width = 0;
2111 
2112  if ( m_musicShuffle == 1)
2113  {
2114  shuffle = "S:? ";
2115  }
2116  else if ( m_musicShuffle == 2)
2117  {
2118  shuffle = "S:i ";
2119  }
2120  else if ( m_musicShuffle == 3)
2121  {
2122  shuffle = "S:a ";
2123  }
2124 
2125  if ( m_musicRepeat == 1)
2126  {
2127  repeat = "R:1 ";
2128  }
2129  else if ( m_musicRepeat == 2)
2130  {
2131  repeat = "R:* ";
2132  }
2133 
2134  if (shuffle.length() != 0 || repeat.length() != 0)
2135  {
2136  aString = shuffle + repeat;
2137  info_width = aString.length();
2138  outputLeftText("Music", aString, "infoWidget", m_lcdHeight );
2139  }
2140  else
2141  {
2142  outputLeftText("Music", " ", "infoWidget", m_lcdHeight );
2143  }
2144 
2145  aString = "widget_set Music progressBar ";
2146  aString += QString::number(info_width + 1);
2147  aString += " ";
2148  aString += QString::number( m_lcdHeight );
2149  aString += " ";
2150  aString += QString::number((int)std::rint( m_musicProgress *
2151  ( m_lcdWidth - info_width) * m_cellWidth ));
2152  sendToServer(aString);
2153  }
2154 }
2155 
2157 {
2158  if ( m_lcdHeight > 1)
2159  {
2160  QString aString;
2161  aString = "widget_set Channel progressBar 1 ";
2162  aString += QString::number( m_lcdHeight );
2163  aString += " ";
2164  aString += QString::number((int)std::rint( m_progress * m_lcdWidth * m_cellWidth ));
2165  sendToServer(aString);
2166 
2167  if ( m_lcdHeight >= 4)
2168  outputCenteredText("Channel", m_channelTime, "timeWidget", 3);
2169  }
2170  else
2171  {
2172  sendToServer("widget_set Channel progressBar 1 1 0");
2173  }
2174 }
2175 
2177 {
2178  if ( m_lcdHeight > 1)
2179  {
2180  QString aString;
2181  aString = "widget_set Generic progressBar ";
2182  aString += QString::number ( m_busyPos );
2183  aString += " ";
2184  aString += QString::number( m_lcdHeight );
2185  aString += " ";
2186  aString += QString::number((int)std::rint( m_genericProgress * m_lcdWidth *
2187  m_cellWidth ));
2188  sendToServer(aString);
2189  }
2190  else
2191  {
2192  sendToServer("widget_set Generic progressBar 1 1 0");
2193  }
2194 }
2195 
2197 {
2198  QString aString;
2199  int line = 3;
2200 
2201  if ( m_lcdHeight > 1)
2202  {
2203  aString = "widget_set Volume progressBar 1 ";
2204  aString += QString::number( m_lcdHeight );
2205  aString += " ";
2206  aString += QString::number((int)std::rint( m_volumeLevel * m_lcdWidth * m_cellWidth ));
2207  sendToServer(aString);
2208  }
2209 
2210  aString = QString::number((int)( m_volumeLevel * 100));
2211  aString += "%";
2212 
2213  if ( m_lcdHeight > 3)
2214  line = 3;
2215  else
2216  line = m_lcdHeight;
2217  outputRightText("Volume", aString, "botWidget", line);
2218 }
2219 
2221 {
2222  if (!m_lcdReady )
2223  return;
2224 
2225  stopAll();
2226 
2227  if (debug_level > 1)
2228  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToTime");
2229 
2230  startTime();
2231 }
2232 
2233 void LCDProcClient::switchToMusic(const QString &artist, const QString &album, const QString &track)
2234 {
2235  if (!m_lcdReady )
2236  return;
2237 
2238  stopAll();
2239 
2240  if (debug_level > 1)
2241  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToMusic") ;
2242 
2243  startMusic(artist, album, track);
2244 }
2245 
2246 void LCDProcClient::switchToChannel(const QString& channum, const QString& title, const QString& subtitle)
2247 {
2248  if (!m_lcdReady )
2249  return;
2250 
2251  stopAll();
2252 
2253  if (debug_level > 1)
2254  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToChannel");
2255 
2256  startChannel(channum, title, subtitle);
2257 }
2258 
2259 void LCDProcClient::switchToMenu(QList<LCDMenuItem> *menuItems, const QString& app_name,
2260  bool popMenu)
2261 {
2262  if (!m_lcdReady )
2263  return;
2264 
2265  if (debug_level > 1)
2266  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToMenu");
2267 
2268  startMenu(menuItems, app_name, popMenu);
2269 }
2270 
2271 void LCDProcClient::switchToGeneric(QList<LCDTextItem> *textItems)
2272 {
2273  if (!m_lcdReady )
2274  return;
2275  stopAll();
2276 
2277  if (debug_level > 1)
2278  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToGeneric");
2279 
2280  startGeneric(textItems);
2281 }
2282 
2283 void LCDProcClient::switchToVolume(const QString& app_name)
2284 {
2285  if (!m_lcdReady )
2286  return;
2287 
2288  stopAll();
2289 
2290  if (debug_level > 1)
2291  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToVolume");
2292 
2293  startVolume(app_name);
2294 }
2295 
2297 {
2298  if (!m_lcdReady )
2299  return;
2300 
2301  stopAll();
2302 
2303  if (debug_level > 1)
2304  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToNothing");
2305 }
2306 
2308 {
2309  if (debug_level > 1)
2310  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: shutdown");
2311 
2312  stopAll();
2313 
2314  // Remove all the widgets and screens for a clean exit from the server
2315  removeWidgets();
2316 
2317  m_socket->close();
2318 
2319  m_lcdReady = false;
2320  m_connected = false;
2321 }
2322 
2324 {
2325  sendToServer("widget_del Channel progressBar");
2326  sendToServer("widget_del Channel topWidget");
2327  sendToServer("widget_del Channel timeWidget");
2328  sendToServer("screen_del Channel");
2329 
2330  sendToServer("widget_del Generic progressBar");
2331  sendToServer("widget_del Generic textWidget1");
2332  sendToServer("widget_del Generic textWidget2");
2333  sendToServer("widget_del Generic textWidget3");
2334  sendToServer("screen_del Generic");
2335 
2336  sendToServer("widget_del Volume progressBar");
2337  sendToServer("widget_del Volume topWidget");
2338  sendToServer("screen_del Volume");
2339 
2340  sendToServer("widget_del Menu topWidget");
2341  sendToServer("widget_del Menu menuWidget1");
2342  sendToServer("widget_del Menu menuWidget2");
2343  sendToServer("widget_del Menu menuWidget3");
2344  sendToServer("widget_del Menu menuWidget4");
2345  sendToServer("widget_del Menu menuWidget5");
2346  sendToServer("screen_del Menu");
2347 
2348  sendToServer("widget_del Music progressBar");
2349  sendToServer("widget_del Music infoWidget");
2350  sendToServer("widget_del Music timeWidget");
2351  sendToServer("widget_del Music topWidget");
2352  sendToServer("screen_del Music");
2353 
2354  if ( m_lcdBigClock )
2355  {
2356  sendToServer("widget_del Time rec1");
2357  sendToServer("widget_del Time rec2");
2358  sendToServer("widget_del Time rec3");
2359  sendToServer("widget_del Time recCnt");
2360  sendToServer("widget_del Time d0");
2361  sendToServer("widget_del Time d1");
2362  sendToServer("widget_del Time sep");
2363  sendToServer("widget_del Time d2");
2364  sendToServer("widget_del Time d3");
2365  sendToServer("widget_del Time ampm");
2366  sendToServer("widget_del Time dot");
2367  }
2368  else
2369  {
2370  sendToServer("widget_del Time timeWidget");
2371  sendToServer("widget_del Time topWidget");
2372  }
2373 
2374  sendToServer("screen_del Time");
2375 
2376  sendToServer("widget_del RecStatus textWidget1");
2377  sendToServer("widget_del RecStatus textWidget2");
2378  sendToServer("widget_del RecStatus textWidget3");
2379  sendToServer("widget_del RecStatus textWidget4");
2380  sendToServer("widget_del RecStatus progressBar");
2381 }
2382 
2384 {
2385  if (debug_level > 1)
2386  {
2387  LOG(VB_GENERAL, LOG_INFO,
2388  "LCDProcClient: An LCD device is being snuffed out"
2389  "of existence (~LCDProcClient() was called)");
2390  }
2391 
2392  if (m_socket)
2393  {
2394  delete m_socket;
2395  m_lcdReady = false;
2396  }
2397 
2398  delete m_lcdMenuItems;
2399 
2401 }
2402 
2404 {
2405  if (e->type() == MythEvent::kMythEventMessage)
2406  {
2407  auto *me = dynamic_cast<MythEvent *>(e);
2408  if (me == nullptr)
2409  return;
2410 
2411  if (me->Message().startsWith("RECORDING_LIST_CHANGE") ||
2412  me->Message() == "UPDATE_PROG_INFO")
2413  {
2414  if ( m_lcdShowRecstatus && !m_updateRecInfoTimer->isActive())
2415  {
2416  if (debug_level > 1)
2417  LOG(VB_GENERAL, LOG_INFO,
2418  "LCDProcClient: Received recording list change");
2419 
2420  // we can't query the backend from inside the customEvent
2421  // so fire the recording list update from a timer
2422  m_updateRecInfoTimer->start(500ms);
2423  }
2424  }
2425  }
2426 }
2427 
2429 {
2430  m_tunerList.clear();
2431  m_isRecording = false;
2432 
2434  {
2435  if (!gCoreContext->ConnectToMasterServer(false))
2436  {
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");
2441  QTimer::singleShot(30s, this, &LCDProcClient::updateRecordingList);
2442 
2443  // If we can't get the recording status and we're showing
2444  // it, switch back to time. Maybe it would be even better
2445  // to show that the backend is unreachable ?
2446  if (m_activeScreen == "RecStatus")
2447  switchToTime();
2448  return;
2449  }
2450  }
2451 
2453 
2454  m_lcdTunerNo = 0;
2455 
2456  if (m_activeScreen == "Time" || m_activeScreen == "RecStatus")
2457  startTime();
2458 }
2459 /* vim: set expandtab tabstop=4 shiftwidth=4: */
LCDProcClient::outputTime
void outputTime()
Definition: lcdprocclient.cpp:1851
LCDTextItem::getScroll
bool getScroll() const
Definition: lcddevice.h:76
LCDProcClient::assignScrollingList
void assignScrollingList(QStringList theList, QString theScreen, QString theWidget="topWidget", int theRow=1)
Definition: lcdprocclient.cpp:917
LCDProcClient::m_tunerList
std::vector< TunerStatus > m_tunerList
Definition: lcdprocclient.h:240
LCDProcClient::m_dateFormat
QString m_dateFormat
Definition: lcdprocclient.h:198
LCDProcClient::outputCenteredText
void outputCenteredText(const QString &theScreen, QString theText, const QString &widget="topWidget", int row=1)
Definition: lcdprocclient.cpp:862
LCDProcClient::m_busyIndicatorSize
float m_busyIndicatorSize
How many "blocks" the busy indicator must be, used if m_busyProgress is true.
Definition: lcdprocclient.h:181
LCDProcClient::shutdown
void shutdown()
Definition: lcdprocclient.cpp:2307
LCD_TIME_TIME
static constexpr std::chrono::milliseconds LCD_TIME_TIME
Definition: lcdprocclient.cpp:44
LCDProcClient::setMusicShuffle
void setMusicShuffle(int shuffle)
Definition: lcdprocclient.cpp:1721
LCDProcClient::outputRightText
void outputRightText(const QString &theScreen, QString theText, const QString &widget="topWidget", int row=1)
Definition: lcdprocclient.cpp:899
LCDProcClient::setVolumeLevel
void setVolumeLevel(float value)
Definition: lcdprocclient.cpp:1731
LCDProcClient::setVersion
void setVersion(const QString &sversion, const QString &pversion)
Definition: lcdprocclient.cpp:661
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
tv.h
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:101
LCDProcClient::m_lcdShowVolume
bool m_lcdShowVolume
Definition: lcdprocclient.h:224
LCDProcClient::m_timeFormat
QString m_timeFormat
Definition: lcdprocclient.h:197
LCDProcClient::assignScrollingWidgets
void assignScrollingWidgets(const QString &theText, const QString &theScreen, const QString &theWidget="topWidget", int theRow=1)
Definition: lcdprocclient.cpp:937
MythEvent::kMythEventMessage
static const Type kMythEventMessage
Definition: mythevent.h:79
LCDMenuItem::getScrollPos
unsigned int getScrollPos() const
Definition: lcddevice.h:38
LCDMenuItem::incrementScrollPos
void incrementScrollPos()
Definition: lcddevice.h:46
LCDServer::sendKeyPress
void sendKeyPress(const QString &key_pressed)
Definition: lcdserver.cpp:298
LCDProcClient::outputRecStatus
void outputRecStatus()
Definition: lcdprocclient.cpp:1912
LCDTextItem::getText
QString getText() const
Definition: lcddevice.h:73
LCDProcClient::URGENT
@ URGENT
Definition: lcdprocclient.h:107
LCDProcClient::formatScrollerText
QStringList formatScrollerText(const QString &text) const
Definition: lcdprocclient.cpp:2055
LCDProcClient::m_prioOff
QString m_prioOff
Definition: lcdprocclient.h:160
LCDProcClient::m_lcdShowMusicItems
QString m_lcdShowMusicItems
Definition: lcdprocclient.h:230
UNCHECKED
@ UNCHECKED
Definition: lcddevice.h:17
TunerStatus::title
QString title
Definition: tvremoteutil.h:22
LCDProcClient::m_lastCommand
QString m_lastCommand
Definition: lcdprocclient.h:213
LCDProcClient::LOW
@ LOW
Definition: lcdprocclient.h:107
LCDProcClient::init
void init()
Definition: lcdprocclient.cpp:412
ALIGN_CENTERED
@ ALIGN_CENTERED
Definition: lcddevice.h:57
MythCoreContext::ConnectToMasterServer
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Definition: mythcorecontext.cpp:359
LCDProcClient::m_scrollListTimer
QTimer * m_scrollListTimer
Definition: lcdprocclient.h:151
LCD_START_COL
static constexpr uint8_t LCD_START_COL
Definition: lcdprocclient.cpp:39
LCDProcClient::outputMusic
void outputMusic()
Definition: lcdprocclient.cpp:2098
LCD_VERSION_4
static constexpr uint8_t LCD_VERSION_4
Definition: lcdprocclient.cpp:41
LCDProcClient::m_recStatusTimer
QTimer * m_recStatusTimer
Definition: lcdprocclient.h:150
LCDProcClient::m_pVersion
uint8_t m_pVersion
Definition: lcdprocclient.h:169
LCDProcClient::m_checkConnectionsTimer
QTimer * m_checkConnectionsTimer
Definition: lcdprocclient.h:149
LCDProcClient::MEDIUM
@ MEDIUM
Definition: lcdprocclient.h:107
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
LCDProcClient::m_activeScreen
QString m_activeScreen
Definition: lcdprocclient.h:140
LCDProcClient::dobigclock
void dobigclock(void)
Definition: lcdprocclient.cpp:1758
LCDProcClient::sendToServer
void sendToServer(const QString &someText)
Definition: lcdprocclient.cpp:172
mythdbcon.h
LCDProcClient::formatScrollingWidgets
void formatScrollingWidgets(void)
Definition: lcdprocclient.cpp:947
LCDProcClient::checkConnections
void checkConnections()
Definition: lcdprocclient.cpp:283
LCDProcClient::m_lcdShowMenu
bool m_lcdShowMenu
Definition: lcdprocclient.h:220
LCDProcClient::m_port
unsigned int m_port
Definition: lcdprocclient.h:215
TunerStatus::endTime
QDateTime endTime
Definition: tvremoteutil.h:25
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
LCDProcClient::LCDProcClient
LCDProcClient(LCDServer *lparent)
Definition: lcdprocclient.cpp:49
LCDProcClient::~LCDProcClient
~LCDProcClient() override
Definition: lcdprocclient.cpp:2383
LCDProcClient::m_cellHeight
uint8_t m_cellHeight
Definition: lcdprocclient.h:165
LCDProcClient::m_scrollListScreen
QString m_scrollListScreen
Definition: lcdprocclient.h:201
LCDProcClient::m_prioHigh
QString m_prioHigh
Definition: lcdprocclient.h:157
LCDProcClient::m_lcdHeartbeatOn
bool m_lcdHeartbeatOn
Definition: lcdprocclient.h:227
LCDMenuItem::setScrollPos
void setScrollPos(unsigned int value)
Definition: lcddevice.h:45
CHECKED
@ CHECKED
Definition: lcddevice.h:17
LCD_SCROLLLIST_TIME
static constexpr std::chrono::milliseconds LCD_SCROLLLIST_TIME
Definition: lcdprocclient.cpp:45
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:15
LCDProcClient::m_lcdTunerNo
int m_lcdTunerNo
Definition: lcdprocclient.h:238
LCDProcClient::m_lcdKeyString
QString m_lcdKeyString
Definition: lcdprocclient.h:231
LCDProcClient::m_lcdShowChannel
bool m_lcdShowChannel
Definition: lcdprocclient.h:223
LCDProcClient::m_serverVersion
QString m_serverVersion
Definition: lcdprocclient.h:167
TunerStatus::channame
QString channame
Definition: tvremoteutil.h:21
LCDProcClient::startMenu
void startMenu(QList< LCDMenuItem > *menuItems, QString app_name, bool popMenu)
Definition: lcdprocclient.cpp:1178
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
LCDProcClient::outputVolume
void outputVolume()
Definition: lcdprocclient.cpp:2196
MythCoreContext::IsConnectedToMaster
bool IsConnectedToMaster(void)
Definition: mythcorecontext.cpp:596
LCDProcClient::m_protocolVersion
QString m_protocolVersion
Definition: lcdprocclient.h:168
LCDProcClient::switchToGeneric
void switchToGeneric(QList< LCDTextItem > *textItems)
Definition: lcdprocclient.cpp:2271
TunerStatus
recording status stuff
Definition: tvremoteutil.h:16
LCDProcClient::serverSendingData
void serverSendingData()
Definition: lcdprocclient.cpp:314
LCDProcClient::m_isRecording
bool m_isRecording
Definition: lcdprocclient.h:236
mythdate.h
LCDProcClient::setStartupMessage
void setStartupMessage(QString msg, std::chrono::seconds messagetime)
Definition: lcdprocclient.cpp:627
LCDProcClient::scrollMenuText
void scrollMenuText()
Definition: lcdprocclient.cpp:1413
LCDProcClient::m_lcdShowTime
bool m_lcdShowTime
Definition: lcdprocclient.h:219
LCDProcClient::m_prioTop
QString m_prioTop
Definition: lcdprocclient.h:155
LCDProcClient::switchToTime
void switchToTime()
Definition: lcdprocclient.cpp:2220
lcdStartCol
uint8_t lcdStartCol
Definition: lcdprocclient.cpp:47
LCDProcClient::loadSettings
void loadSettings()
Definition: lcdprocclient.cpp:536
LCDProcClient::m_hostname
QString m_hostname
Definition: lcdprocclient.h:214
mythlogging.h
LCDProcClient::m_scrollListItem
unsigned int m_scrollListItem
Definition: lcdprocclient.h:204
LCDProcClient::m_channelTime
QString m_channelTime
Definition: lcdprocclient.h:172
LCDMenuItem::isChecked
CHECKED_STATE isChecked() const
Definition: lcddevice.h:33
LCDProcClient::OFF
@ OFF
Definition: lcdprocclient.h:107
LCDMenuItem::setScroll
void setScroll(bool value)
Definition: lcddevice.h:43
LCDProcClient::m_menuScrollPosition
unsigned int m_menuScrollPosition
Definition: lcdprocclient.h:206
LCDProcClient::setCellHeight
void setCellHeight(unsigned int x)
Definition: lcdprocclient.cpp:654
LCDProcClient::m_lcdPopupTime
std::chrono::milliseconds m_lcdPopupTime
Definition: lcdprocclient.h:229
RemoteGetRecordingStatus
int RemoteGetRecordingStatus(const ProgramInfo *pginfo, int overrecsecs, int underrecsecs)
Get status of an individual programme (with pre-post roll?).
Definition: remoteutil.cpp:505
LCDProcClient::customEvent
void customEvent(QEvent *e) override
Definition: lcdprocclient.cpp:2403
LCDProcClient::m_lcdMenuItems
QList< LCDMenuItem > * m_lcdMenuItems
Definition: lcdprocclient.h:207
LCDProcClient::TOP
@ TOP
Definition: lcdprocclient.h:107
LCDTextItem::setText
void setText(const QString &value)
Definition: lcddevice.h:80
LCDProcClient::switchToNothing
void switchToNothing()
Definition: lcdprocclient.cpp:2296
compat.h
LCDProcClient::HIGH
@ HIGH
Definition: lcdprocclient.h:107
ALIGN_RIGHT
@ ALIGN_RIGHT
Definition: lcddevice.h:57
LCDProcClient::removeWidgets
void removeWidgets()
Definition: lcdprocclient.cpp:2323
LCDProcClient::m_prioLow
QString m_prioLow
Definition: lcdprocclient.h:159
MythCoreContext::GetDurSetting
std::enable_if_t< std::chrono::__is_duration< T >::value, T > GetDurSetting(const QString &key, T defaultval=T::zero())
Definition: mythcorecontext.h:147
LCDProcClient::outputChannel
void outputChannel()
Definition: lcdprocclient.cpp:2156
LCDProcClient::m_lcdTextItems
QList< LCDTextItem > * m_lcdTextItems
Definition: lcdprocclient.h:193
LCDProcClient::m_startupShowTime
std::chrono::seconds m_startupShowTime
Definition: lcdprocclient.h:234
LCDProcClient::setChannelProgress
void setChannelProgress(const QString &time, float value)
Definition: lcdprocclient.cpp:1644
LCDProcClient::expandString
QString expandString(const QString &aString) const
Definition: lcdprocclient.cpp:526
LCDProcClient::m_timeFlash
bool m_timeFlash
Definition: lcdprocclient.h:210
LCDProcClient::setMusicRepeat
void setMusicRepeat(int repeat)
Definition: lcdprocclient.cpp:1711
LCDProcClient::switchToChannel
void switchToChannel(const QString &channum="", const QString &title="", const QString &subtitle="")
Definition: lcdprocclient.cpp:2246
LCDProcClient::beginScrollingWidgets
void beginScrollingWidgets(void)
Definition: lcdprocclient.cpp:993
LCDProcClient::stopAll
void stopAll(void)
Definition: lcdprocclient.cpp:770
LCDProcClient::describeServer
void describeServer()
Definition: lcdprocclient.cpp:693
LCDProcClient::m_lcdShowRecstatus
bool m_lcdShowRecstatus
Definition: lcdprocclient.h:225
LCDProcClient::m_sendBuffer
QString m_sendBuffer
Definition: lcdprocclient.h:212
LCDProcClient::m_busyDirection
int m_busyDirection
Direction of the busy indicator on the, -1 or 1, used if m_busyProgress is true.
Definition: lcdprocclient.h:184
LCDProcClient::setCellWidth
void setCellWidth(unsigned int x)
Definition: lcdprocclient.cpp:647
LCDTextItem::getAlignment
TEXT_ALIGNMENT getAlignment() const
Definition: lcddevice.h:72
LCDProcClient::m_cellWidth
uint8_t m_cellWidth
Definition: lcdprocclient.h:164
ALIGN_LEFT
@ ALIGN_LEFT
Definition: lcddevice.h:57
LCDProcClient::m_lcdShowMusic
bool m_lcdShowMusic
Definition: lcdprocclient.h:222
LCDProcClient::setWidth
void setWidth(unsigned int x)
Definition: lcdprocclient.cpp:633
LCDTextItem::getWidget
QString getWidget() const
Definition: lcddevice.h:75
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
LCDProcClient::dostdclock
void dostdclock()
Definition: lcdprocclient.cpp:1859
clamp
static eu8 clamp(eu8 value, eu8 low, eu8 high)
Definition: pxsup2dast.c:204
LCDProcClient::m_volumeLevel
float m_volumeLevel
Definition: lcdprocclient.h:186
NOTCHECKABLE
@ NOTCHECKABLE
Definition: lcddevice.h:17
LCDProcClient::m_socket
QTcpSocket * m_socket
Definition: lcdprocclient.h:142
LCDProcClient::switchToMusic
void switchToMusic(const QString &artist, const QString &album, const QString &track)
Definition: lcdprocclient.cpp:2233
LCDTextItem::getScreen
QString getScreen() const
Definition: lcddevice.h:74
LCDProcClient::m_timeTimer
QTimer * m_timeTimer
Definition: lcdprocclient.h:143
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:918
LCDProcClient::m_updateRecInfoTimer
QTimer * m_updateRecInfoTimer
Definition: lcdprocclient.h:153
LCDProcClient::setHeartbeat
void setHeartbeat(const QString &screen, bool onoff)
Definition: lcdprocclient.cpp:255
LCDProcClient::m_scrollWTimer
QTimer * m_scrollWTimer
Definition: lcdprocclient.h:144
LCDProcClient::setGenericProgress
void setGenericProgress(bool busy, float value)
Definition: lcdprocclient.cpp:1660
LCDProcClient::m_lcdBigClock
bool m_lcdBigClock
Definition: lcdprocclient.h:228
LCDProcClient::m_busyProgress
bool m_busyProgress
true if the generic progress indicator is a busy (ie.
Definition: lcdprocclient.h:175
LCDMenuItem
Definition: lcddevice.h:21
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:912
LCDProcClient::startGeneric
void startGeneric(QList< LCDTextItem > *textItems)
Definition: lcdprocclient.cpp:1128
LCDProcClient::m_scrollListRow
int m_scrollListRow
Definition: lcdprocclient.h:203
lcdprocclient.h
LCDProcClient::m_menuScrollTimer
QTimer * m_menuScrollTimer
Definition: lcdprocclient.h:146
LCDMenuItem::ItemName
QString ItemName() const
Definition: lcddevice.h:35
LCDProcClient::m_isTimeVisible
bool m_isTimeVisible
Definition: lcdprocclient.h:237
LCDServer
Definition: lcdserver.h:27
LCDProcClient::m_scrollScreen
QString m_scrollScreen
Definition: lcdprocclient.h:195
LCDProcClient::m_menuPreScrollTimer
QTimer * m_menuPreScrollTimer
Definition: lcdprocclient.h:147
LCDProcClient::m_musicRepeat
int m_musicRepeat
Definition: lcdprocclient.h:190
LCDProcClient::startTime
void startTime()
Definition: lcdprocclient.cpp:801
LCDProcClient::showStartupMessage
void showStartupMessage(void)
Definition: lcdprocclient.cpp:599
LCDProcClient::m_prioMedium
QString m_prioMedium
Definition: lcdprocclient.h:158
LCDProcClient::outputGeneric
void outputGeneric()
Definition: lcdprocclient.cpp:2176
mythcorecontext.h
LCDProcClient::m_lcdReady
bool m_lcdReady
Definition: lcdprocclient.h:217
LCDProcClient::updateLEDs
void updateLEDs(int mask)
Definition: lcdprocclient.cpp:1743
lcdserver.h
LCDProcClient::m_lcdShowGeneric
bool m_lcdShowGeneric
Definition: lcdprocclient.h:221
LCDProcClient::scrollWidgets
void scrollWidgets(void)
Definition: lcdprocclient.cpp:1000
LCDProcClient::veryBadThings
void veryBadThings(QAbstractSocket::SocketError error)
Definition: lcdprocclient.cpp:746
LCDProcClient::PRIORITY
PRIORITY
Definition: lcdprocclient.h:107
LCD_VERSION_5
static constexpr uint8_t LCD_VERSION_5
Definition: lcdprocclient.cpp:42
LCDProcClient::m_genericProgress
float m_genericProgress
Definition: lcdprocclient.h:185
LCDProcClient::switchToVolume
void switchToVolume(const QString &app_name)
Definition: lcdprocclient.cpp:2283
LCDProcClient::m_busyPos
int m_busyPos
Current position of the busy indicator, used if m_busyProgress is true.
Definition: lcdprocclient.h:178
debug_level
int debug_level
Definition: lcdserver.cpp:76
LCDTextItem
Definition: lcddevice.h:59
LCDProcClient::unPopMenu
void unPopMenu()
Definition: lcdprocclient.cpp:1637
LCDProcClient::m_scrollListWidget
QString m_scrollListWidget
Definition: lcdprocclient.h:202
LCDProcClient::m_startupMessage
QString m_startupMessage
Definition: lcdprocclient.h:233
LCDProcClient::scrollList
void scrollList()
Definition: lcdprocclient.cpp:754
LCDProcClient::removeStartupMessage
void removeStartupMessage(void)
Definition: lcdprocclient.cpp:622
LCDTextItem::setScrollable
void setScrollable(bool value)
Definition: lcddevice.h:83
TunerStatus::startTime
QDateTime startTime
Definition: tvremoteutil.h:24
LCDProcClient::outputScrollerText
void outputScrollerText(const QString &theScreen, const QString &theText, const QString &widget="scroller", int top=1, int bottom=1)
Definition: lcdprocclient.cpp:2041
LCDProcClient::m_lcdWidth
uint8_t m_lcdWidth
Definition: lcdprocclient.h:162
LCDProcClient::setPriority
void setPriority(const QString &screen, PRIORITY priority)
Definition: lcdprocclient.cpp:220
LCDMenuItem::getIndent
unsigned int getIndent() const
Definition: lcddevice.h:37
LCDProcClient::setHeight
void setHeight(unsigned int x)
Definition: lcdprocclient.cpp:640
LCDProcClient::m_musicTime
QString m_musicTime
Definition: lcdprocclient.h:189
LCDProcClient::m_lcdBacklightOn
bool m_lcdBacklightOn
Definition: lcdprocclient.h:226
LCDProcClient::m_prioUrgent
QString m_prioUrgent
Definition: lcdprocclient.h:156
LCDProcClient::outputText
void outputText(QList< LCDTextItem > *textItems)
Definition: lcdprocclient.cpp:815
LCDProcClient::connectToHost
bool connectToHost(const QString &hostname, unsigned int port)
Definition: lcdprocclient.cpp:134
LCDProcClient::m_progress
float m_progress
Definition: lcdprocclient.h:171
LCDMenuItem::isSelected
bool isSelected() const
Definition: lcddevice.h:34
LCDProcClient::m_connected
bool m_connected
Definition: lcdprocclient.h:209
LCDProcClient::m_popMenuTimer
QTimer * m_popMenuTimer
Definition: lcdprocclient.h:148
LCDProcClient::updateRecordingList
void updateRecordingList(void)
Definition: lcdprocclient.cpp:2428
LCDProcClient::switchToMenu
void switchToMenu(QList< LCDMenuItem > *menuItems, const QString &app_name="", bool popMenu=true)
Definition: lcdprocclient.cpp:2259
lcddevice.h
LCDProcClient::beginScrollingMenuText
void beginScrollingMenuText()
Definition: lcdprocclient.cpp:1373
LCDProcClient::startVolume
void startVolume(const QString &app_name)
Definition: lcdprocclient.cpp:1626
LCDTextItem::getRow
unsigned int getRow() const
Definition: lcddevice.h:71
LCDProcClient::m_scrollListItems
QStringList m_scrollListItems
Definition: lcdprocclient.h:200
LCDProcClient::SetupLCD
bool SetupLCD(void)
Definition: lcdprocclient.cpp:123
LCDProcClient::m_lcdHeight
uint8_t m_lcdHeight
Definition: lcdprocclient.h:163
LCDProcClient::m_parentLCDServer
LCDServer * m_parentLCDServer
Definition: lcdprocclient.h:232
LCDProcClient::m_musicProgress
float m_musicProgress
Definition: lcdprocclient.h:188
TunerStatus::subtitle
QString subtitle
Definition: tvremoteutil.h:23
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
LCDProcClient::m_preScrollWTimer
QTimer * m_preScrollWTimer
Definition: lcdprocclient.h:145
LCDMenuItem::Scroll
bool Scroll() const
Definition: lcddevice.h:36
LCDMenuItem::setItemName
void setItemName(const QString &value)
Definition: lcddevice.h:42
LCDProcClient::m_musicShuffle
int m_musicShuffle
Definition: lcdprocclient.h:191
LCDProcClient::startMusic
void startMusic(QString artist, const QString &album, const QString &track)
Definition: lcdprocclient.cpp:1035
LCDProcClient::outputLeftText
void outputLeftText(const QString &theScreen, QString theText, const QString &widget="topWidget", int row=1)
Definition: lcdprocclient.cpp:885
LCDProcClient::startChannel
void startChannel(const QString &channum, const QString &title, const QString &subtitle)
Definition: lcdprocclient.cpp:1090
LCDProcClient::m_scrollPosition
unsigned int m_scrollPosition
Definition: lcdprocclient.h:196
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:904
LCDProcClient::setMusicProgress
void setMusicProgress(QString time, float value)
Definition: lcdprocclient.cpp:1695
LCDProcClient::m_showMessageTimer
QTimer * m_showMessageTimer
Definition: lcdprocclient.h:152
LCDProcClient::reset
void reset(void)
Definition: lcdprocclient.cpp:1751