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