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 #include <QTimer>
20 #include <utility>
21 
22 // mythtv
23 #include "mythcontext.h"
24 #include "mythdbcon.h"
25 #include "mythdate.h"
26 #include "tv.h"
27 #include "compat.h"
28 
29 //mythlcdserver
30 #include "lcdprocclient.h"
31 #include "lcdserver.h"
32 #include "lcddevice.h"
33 
34 #define LCD_START_COL 3
35 
36 #define LCD_VERSION_4 1
37 #define LCD_VERSION_5 2
38 
39 using namespace std::chrono_literals;
40 
41 static constexpr std::chrono::milliseconds LCD_TIME_TIME { 3s };
42 static constexpr std::chrono::milliseconds LCD_SCROLLLIST_TIME { 2s };
43 
45 
47  : QObject(nullptr),
48  m_socket(new QTcpSocket(this)),
49  m_timeTimer (new QTimer(this)),
50  m_scrollWTimer (new QTimer(this)),
51  m_preScrollWTimer (new QTimer(this)),
52  m_menuScrollTimer (new QTimer(this)),
53  m_menuPreScrollTimer (new QTimer(this)),
54  m_popMenuTimer (new QTimer(this)),
55  m_checkConnectionsTimer (new QTimer(this)),
56  m_recStatusTimer (new QTimer(this)),
57  m_scrollListTimer (new QTimer(this)),
58  m_showMessageTimer (new QTimer(this)),
59  m_updateRecInfoTimer (new QTimer(this)),
60  m_lcdTextItems (new QList<LCDTextItem>),
61  m_lcdMenuItems (new QList<LCDMenuItem>),
62  m_parentLCDServer (lparent)
63 {
64  // Constructor for LCDProcClient
65  //
66  // Note that this does *not* include opening the socket and initiating
67  // communications with the LDCd daemon.
68 
69  if (debug_level > 0)
70  LOG(VB_GENERAL, LOG_INFO,
71  "LCDProcClient: An LCDProcClient object now exists");
72 
73 #if QT_VERSION < QT_VERSION_CHECK(5,15,0)
74  connect(m_socket, qOverload<QAbstractSocket::SocketError>(&QAbstractSocket::error),
76 #else
77  connect(m_socket, &QAbstractSocket::errorOccurred, this, &LCDProcClient::veryBadThings);
78 #endif
79  connect(m_socket, &QIODevice::readyRead, this, &LCDProcClient::serverSendingData);
80 
82  if ( m_lcdWidth < 12)
83  {
84  if ( m_lcdHeight == 1)
85  lcdStartCol = 0;
86  else
87  lcdStartCol = 1;
88  }
89 
91 
93 
94  m_preScrollWTimer->setSingleShot(true);
95  connect( m_preScrollWTimer, &QTimer::timeout, this,
97 
98  m_popMenuTimer->setSingleShot(true);
100 
102 
103  connect( m_menuPreScrollTimer, &QTimer::timeout, this,
105 
106  connect( m_checkConnectionsTimer, &QTimer::timeout, this,
108  m_checkConnectionsTimer->start(10s);
109 
111 
113 
114  m_showMessageTimer->setSingleShot(true);
115  connect( m_showMessageTimer, &QTimer::timeout, this,
117 
118  m_updateRecInfoTimer->setSingleShot(true);
119  connect( m_updateRecInfoTimer, &QTimer::timeout, this,
121 
122  gCoreContext->addListener(this);
123 }
124 
126 {
127  QString lcd_host = gCoreContext->GetSetting("LCDHost", "localhost");
128  int lcd_port = gCoreContext->GetNumSetting("LCDPort", 13666);
129 
130  if (lcd_host.length() > 0 && lcd_port > 1024)
131  connectToHost(lcd_host, lcd_port);
132 
133  return m_connected;
134 }
135 
136 bool LCDProcClient::connectToHost(const QString &lhostname, unsigned int lport)
137 {
138  // Open communications
139  // Store the hostname and port in case we need to reconnect.
140 
141  // cppcheck-suppress variableScope
142  int timeout = 1000;
143  m_hostname = lhostname;
144  m_port = lport;
145 
146  // Don't even try to connect if we're currently disabled.
147  if (!gCoreContext->GetBoolSetting("LCDEnable", false))
148  {
149  m_connected = false;
150  return m_connected;
151  }
152 
153  if (!m_connected )
154  {
155  QTextStream os(m_socket);
156  m_socket->connectToHost(m_hostname, m_port);
157 
158  while (--timeout && m_socket->state() != QAbstractSocket::ConnectedState)
159  {
160  qApp->processEvents();
161  std::this_thread::sleep_for(std::chrono::milliseconds(1));
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  os.setCodec("ISO 8859-1");
197 
198  m_lastCommand = someText;
199 
200  if ( m_connected )
201  {
202  if (debug_level > 9)
203  LOG(VB_NETWORK, LOG_INFO,
204  "LCDProcClient: Sending to Server: " + someText);
205 
206  // Just stream the text out the socket
207 
208  os << someText << "\n";
209  }
210  else
211  {
212  // Buffer this up in the hope that the connection will open soon
213 
214  m_sendBuffer += someText;
215  m_sendBuffer += "\n";
216  }
217 }
218 
219 void LCDProcClient::setPriority(const QString &screen, PRIORITY priority)
220 {
221  QString aString;
222  int err = 0;
223  aString = "screen_set ";
224  aString += screen;
225  aString += " priority ";
226 
227  switch (priority) {
228  case TOP:
229  aString += m_prioTop;
230  break;
231  case URGENT:
232  aString += m_prioUrgent;
233  break;
234  case HIGH:
235  aString += m_prioHigh;
236  break;
237  case MEDIUM:
238  aString += m_prioMedium;
239  break;
240  case LOW:
241  aString += m_prioLow;
242  break;
243  case OFF:
244  aString += m_prioOff;
245  break;
246  default:
247  err = 1;
248  break;
249  }
250  if (err == 0)
251  sendToServer (aString);
252 }
253 
254 void LCDProcClient::setHeartbeat (const QString &screen, bool onoff)
255 {
256  QString msg;
257  if (onoff)
258  {
259  if ( m_pVersion == LCD_VERSION_4)
260  {
261  msg = "widget_add " + screen + " heartbeat";
262  }
263  if ( m_pVersion == LCD_VERSION_5)
264  {
265  msg = "screen_set " + screen + " heartbeat on";
266  }
267  }
268  else
269  {
270  if ( m_pVersion == LCD_VERSION_4)
271  {
272  msg = "widget_del " + screen + " heartbeat";
273  }
274  if ( m_pVersion == LCD_VERSION_5)
275  {
276  msg = "screen_set " + screen + " heartbeat off";
277  }
278  }
279  sendToServer (msg);
280 }
281 
283 {
284  if (debug_level > 0)
285  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: checking connections");
286 
287  // check connection to mythbackend
289  {
290  if (debug_level > 0)
291  LOG(VB_GENERAL, LOG_INFO,
292  "LCDProcClient: connecting to master server");
293  if (!gCoreContext->ConnectToMasterServer(false))
294  LOG(VB_GENERAL, LOG_ERR,
295  "LCDProcClient: connecting to master server failed");
296  }
297 
298  //check connection to LCDProc server
299  if (m_socket->state() != QAbstractSocket::ConnectedState)
300  {
301  if (debug_level > 0)
302  LOG(VB_GENERAL, LOG_INFO,
303  "LCDProcClient: connecting to LCDProc server");
304 
305  m_lcdReady = false;
306  m_connected = false;
307 
308  // Retry to connect. . . Maybe the user restarted LCDd?
310  }
311 }
312 
314 {
315  QString lineFromServer;
316  QString tempString;
317  QStringList aList;
318  QStringList::Iterator it;
319 
320  // This gets activated automatically by the QSocket class whenever
321  // there's something to read.
322  //
323  // We currently spend most of our time (except for the first line sent
324  // back) ignoring it.
325  //
326  // Note that if anyone has an LCDproc type lcd with buttons on it, this is
327  // where we would want to catch button presses and make the rest of
328  // mythTV/mythMusic do something (change tracks, channels, etc.)
329 
330  while(m_socket->canReadLine())
331  {
332  lineFromServer = m_socket->readLine();
333  lineFromServer = lineFromServer.replace( QRegExp("\n"), "" );
334  lineFromServer = lineFromServer.replace( QRegExp("\r"), "" );
335 
336  if (debug_level > 0)
337  {
338  // Make debugging be less noisy
339  if (lineFromServer != "success")
340  LOG(VB_NETWORK, LOG_INFO,
341  "LCDProcClient: Received from server: " + lineFromServer);
342  }
343 
344  aList = lineFromServer.split(" ");
345  if (aList.first() == "connect")
346  {
347  // We got a connect, which is a response to "hello"
348  //
349  // Need to parse out some data according the LCDproc client/server
350  // spec (which is poorly documented)
351  it = aList.begin();
352  it++;
353  if ((*it) != "LCDproc")
354  {
355  LOG(VB_GENERAL, LOG_WARNING,
356  "LCDProcClient: WARNING: Second parameter "
357  "returned from LCDd was not \"LCDproc\"");
358  }
359 
360  // Skip through some stuff
361  it++; // server version
362  QString server_version = *it;
363  it++; // the string "protocol"
364  it++; // protocol version
365  QString protocol_version = *it;
366  setVersion (server_version, protocol_version);
367  it++; // the string "lcd"
368  it++; // the string "wid";
369  it++; // Ah, the LCD width
370 
371  tempString = *it;
372  setWidth(tempString.toInt());
373 
374  it++; // the string "hgt"
375  it++; // the LCD height
376 
377  tempString = *it;
378  setHeight(tempString.toInt());
379  it++; // the string "cellwid"
380  it++; // Cell width in pixels;
381 
382  tempString = *it;
383  setCellWidth(tempString.toInt());
384 
385  it++; // the string "cellhgt"
386  it++; // Cell height in pixels;
387 
388  tempString = *it;
389  setCellHeight(tempString.toInt());
390 
391  init();
392 
393  describeServer();
394  }
395 
396  if (aList.first() == "huh?")
397  {
398  LOG(VB_GENERAL, LOG_WARNING,
399  "LCDProcClient: WARNING: Something is getting"
400  "passed to LCDd that it doesn't understand");
401  LOG(VB_GENERAL, LOG_WARNING, "last command: " + m_lastCommand );
402  }
403  else if (aList.first() == "key")
404  {
405  if ( m_parentLCDServer )
406  m_parentLCDServer->sendKeyPress(aList.last().trimmed());
407  }
408  }
409 }
410 
412 {
413  QString aString;
414  m_lcdKeyString = "";
415 
416  m_connected = true;
417 
418  // This gets called when we receive the "connect" string from the server
419  // indicating that "hello" was succesful
420  sendToServer("client_set name Myth");
421 
422  // Create all the screens and widgets (when we change activity in the myth
423  // program, we just swap the priorities of the screens to show only the
424  // "current one")
425  sendToServer("screen_add Time");
426  setPriority("Time", MEDIUM);
427 
428  if (gCoreContext->GetSetting("LCDBigClock", "1") == "1")
429  {
430  // Big Clock - spans multiple lines
431  sendToServer("widget_add Time rec1 string");
432  sendToServer("widget_add Time rec2 string");
433  sendToServer("widget_add Time rec3 string");
434  sendToServer("widget_add Time recCnt string");
435  sendToServer("widget_add Time d0 num");
436  sendToServer("widget_add Time d1 num");
437  sendToServer("widget_add Time sep num");
438  sendToServer("widget_add Time d2 num");
439  sendToServer("widget_add Time d3 num");
440  sendToServer("widget_add Time ampm string");
441  sendToServer("widget_add Time dot string");
442  }
443  else
444  {
445  sendToServer("widget_add Time timeWidget string");
446  sendToServer("widget_add Time topWidget string");
447  }
448 
449  // The Menu Screen
450  // I'm not sure how to do multi-line widgets with lcdproc so we're going
451  // the ghetto way
452  sendToServer("screen_add Menu");
453  setPriority("Menu", LOW);
454  sendToServer("widget_add Menu topWidget string");
455  for (unsigned int i = 1; i <= m_lcdHeight; i++)
456  {
457  aString = "widget_add Menu menuWidget";
458  aString += QString::number (i);
459  aString += " string";
460  sendToServer(aString);
461  }
462 
463  // The Music Screen
464  sendToServer("screen_add Music");
465  setPriority("Music", LOW);
466  sendToServer("widget_add Music topWidget1 string");
467  sendToServer("widget_add Music topWidget2 string");
468  sendToServer("widget_add Music timeWidget string");
469  sendToServer("widget_add Music infoWidget string");
470  sendToServer("widget_add Music progressBar hbar");
471 
472  // The Channel Screen
473  sendToServer("screen_add Channel");
474  setPriority("Channel", LOW);
475  sendToServer("widget_add Channel topWidget string");
476  sendToServer("widget_add Channel botWidget string");
477  sendToServer("widget_add Channel timeWidget string");
478  sendToServer("widget_add Channel progressBar hbar");
479 
480  // The Generic Screen
481  sendToServer("screen_add Generic");
482  setPriority("Generic", LOW);
483  sendToServer("widget_add Generic textWidget1 string");
484  sendToServer("widget_add Generic textWidget2 string");
485  sendToServer("widget_add Generic textWidget3 string");
486  sendToServer("widget_add Generic textWidget4 string");
487  sendToServer("widget_add Generic progressBar hbar");
488 
489  // The Volume Screen
490  sendToServer("screen_add Volume");
491  setPriority("Volume", LOW);
492  sendToServer("widget_add Volume topWidget string");
493  sendToServer("widget_add Volume botWidget string");
494  sendToServer("widget_add Volume progressBar hbar");
495 
496  // The Recording Status Screen
497  sendToServer("screen_add RecStatus");
498  setPriority("RecStatus", LOW);
499  sendToServer("widget_add RecStatus textWidget1 string");
500  sendToServer("widget_add RecStatus textWidget2 string");
501  sendToServer("widget_add RecStatus textWidget3 string");
502  sendToServer("widget_add RecStatus textWidget4 string");
503  sendToServer("widget_add RecStatus progressBar hbar");
504 
505  m_lcdReady = true;
506  loadSettings();
507 
508  // default to showing time
509  switchToTime();
510 
512 
513  // do we need to show the startup message
514  if (!m_startupMessage.isEmpty())
516 
517  // send buffer if there's anything in there
518  if ( m_sendBuffer.length() > 0)
519  {
521  m_sendBuffer = "";
522  }
523 }
524 
525 QString LCDProcClient::expandString(const QString &aString) const
526 {
527  if ( m_pVersion != LCD_VERSION_5)
528  return aString;
529 
530  // if version 5 then white space seperate the list of characters
531  auto add_ws = [](const QString& str, auto x){ return str + x + QString(" "); };
532  return std::accumulate(aString.cbegin(), aString.cend(), QString(), add_ws);
533 }
534 
536 {
537  if (!m_lcdReady )
538  return;
539 
540  QString aString;
541  QString old_keystring = m_lcdKeyString;
542 
543  m_timeFormat = gCoreContext->GetSetting("LCDTimeFormat", "");
544  if ( m_timeFormat.isEmpty())
545  m_timeFormat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
546 
547  m_dateFormat = gCoreContext->GetSetting("DateFormat", "dd.MM.yyyy");
548 
549  // Get LCD settings
550  m_lcdShowMusic=(gCoreContext->GetSetting("LCDShowMusic", "1")=="1");
551  m_lcdShowMusicItems=(gCoreContext->GetSetting("LCDShowMusicItems", "ArtistAlbumTitle"));
552  m_lcdShowTime=(gCoreContext->GetSetting("LCDShowTime", "1")=="1");
553  m_lcdShowChannel=(gCoreContext->GetSetting("LCDShowChannel", "1")=="1");
554  m_lcdShowGeneric=(gCoreContext->GetSetting("LCDShowGeneric", "1")=="1");
555  m_lcdShowVolume=(gCoreContext->GetSetting("LCDShowVolume", "1")=="1");
556  m_lcdShowMenu=(gCoreContext->GetSetting("LCDShowMenu", "1")=="1");
557  m_lcdShowRecstatus=(gCoreContext->GetSetting("LCDShowRecStatus", "1")=="1");
558  m_lcdBacklightOn=(gCoreContext->GetSetting("LCDBacklightOn", "1")=="1");
559  m_lcdHeartbeatOn=(gCoreContext->GetSetting("LCDHeartBeatOn", "1")=="1");
560  aString = gCoreContext->GetSetting("LCDPopupTime", "5");
561  m_lcdPopupTime = aString.toInt() * 1000;
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 
619  m_showMessageTimer->start( m_startupShowTime * 1000);
620 }
621 
623 {
624  switchToTime();
625 }
626 
627 void LCDProcClient::setStartupMessage(QString msg, uint 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.")
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")
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 ));
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, 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 : qAsConst(*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  curItem->setScroll(false);
1404  }
1405 
1406  // Can get segfaults if we try to start a timer thats already running. . .
1407  m_menuScrollTimer->stop();
1408  m_menuScrollTimer->start(250ms);
1409 }
1410 
1412 {
1413  if (!m_lcdMenuItems )
1414  return;
1415 
1416  QString aString;
1417  QString bString;
1418  QList<LCDMenuItem>::iterator it = m_lcdMenuItems->begin();
1419 
1421 
1422  // First loop through and figure out where the selected item is in the
1423  // list so we know how many above and below to display
1424  unsigned int selectedItem = 0;
1425  unsigned int counter = 0;
1426 
1427  while (it != m_lcdMenuItems->end())
1428  {
1429  LCDMenuItem *curItem = &(*it);
1430  ++it;
1431  if (curItem->isSelected())
1432  {
1433  selectedItem = counter + 1;
1434  break;
1435  }
1436  ++counter;
1437  }
1438 
1439  // If there is only one or two lines on the display, then just write
1440  // the selected item and leave
1441  it = m_lcdMenuItems->begin();
1442  if ( m_lcdHeight <= 2)
1443  {
1444  while (it != m_lcdMenuItems->end())
1445  {
1446  LCDMenuItem *curItem = &(*it);
1447  ++it;
1448  if (curItem->isSelected())
1449  {
1450  curItem->incrementScrollPos();
1451  if ((int)curItem->getScrollPos() > curItem->ItemName().length())
1452  {
1453  // Scroll slower second and subsequent times through
1454  m_menuScrollTimer->stop();
1455  m_menuScrollTimer->start(500ms);
1456  curItem->setScrollPos(curItem->getIndent());
1457  }
1458 
1459  // Stop the timer if this item really doesn't need to scroll.
1460  // This should never have to get invoked because in theory
1461  // the code in startMenu has done its job. . .
1462  if (curItem->ItemName().length() < (int)( m_lcdWidth - lcdStartCol))
1463  m_menuScrollTimer->stop();
1464 
1465  if ( m_lcdHeight == 2)
1466  {
1467  aString = "widget_set Menu menuWidget1 1 2 \">";
1468  }
1469  else
1470  {
1471  aString = "widget_set Menu menuWidget1 1 1 \"";
1472  }
1473 
1474  if ( m_lcdWidth < 12)
1475  {
1476  switch(curItem->isChecked())
1477  {
1478  case CHECKED: aString += "X"; break;
1479  case UNCHECKED: aString += "O"; break;
1480  case NOTCHECKABLE: aString += ""; break;
1481  default: break;
1482  }
1483  }
1484  else
1485  {
1486  switch(curItem->isChecked())
1487  {
1488  case CHECKED: aString += "X "; break;
1489  case UNCHECKED: aString += "O "; break;
1490  case NOTCHECKABLE: aString += " "; break;
1491  default: break;
1492  }
1493  }
1494 
1495  // Indent this item if nessicary
1496  aString += bString.fill(' ', curItem->getIndent());
1497 
1498  aString += curItem->ItemName().midRef(curItem->getScrollPos(),
1499  ( m_lcdWidth - lcdStartCol));
1500  aString += "\"";
1501  sendToServer(aString);
1502  return;
1503  }
1504  }
1505 
1506  return;
1507  }
1508 
1509  // Find the longest line, if menuScrollPosition is longer then this, then
1510  // reset them all
1511  it = m_lcdMenuItems->begin();
1512  int longest_line = 0;
1513  int max_scroll_pos = 0;
1514 
1515  while (it != m_lcdMenuItems->end())
1516  {
1517  LCDMenuItem *curItem = &(*it);
1518  ++it;
1519  if (curItem->ItemName().length() > longest_line)
1520  longest_line = curItem->ItemName().length();
1521 
1522  if ((int)curItem->getScrollPos() > max_scroll_pos)
1523  max_scroll_pos = curItem->getScrollPos();
1524  }
1525 
1526  // If max_scroll_pos > longest_line then reset
1527  if (max_scroll_pos > longest_line)
1528  {
1529  // Scroll slower second and subsequent times through
1530  m_menuScrollTimer->stop();
1531  m_menuScrollTimer->start(500ms);
1533 
1534  it = m_lcdMenuItems->begin();
1535  while (it != m_lcdMenuItems->end())
1536  {
1537  LCDMenuItem *curItem = &(*it);
1538  ++it;
1539  curItem->setScrollPos(curItem->getIndent());
1540  }
1541  }
1542 
1543  // Reset things
1544  counter = 1;
1545  it = m_lcdMenuItems->begin();
1546 
1547  // Move the iterator to selectedItem -1
1548  if (selectedItem != 1 && m_lcdMenuItems->size() >= (int) m_lcdHeight )
1549  {
1550  while (counter != selectedItem)
1551  {
1552  ++it;
1553  ++counter;
1554  }
1555  --it;
1556  }
1557 
1558  // Back up one if were at the end so the last item shows up at the bottom
1559  // of the display
1560  if (counter > 1 && (int)counter == m_lcdMenuItems->size())
1561  --it;
1562 
1563  bool stopTimer = true;
1564 
1565  counter = 1;
1566  while (it != m_lcdMenuItems->end() && counter <= m_lcdHeight )
1567  {
1568  LCDMenuItem *curItem = &(*it);
1569  // Can't write more menu items then we have on the display
1570  if ((counter + 1) > m_lcdHeight )
1571  break;
1572 
1573  ++it;
1574 
1575  if (curItem->Scroll())
1576  {
1577  stopTimer = false;
1578  aString = "widget_set Menu menuWidget";
1579  aString += QString::number(counter) + " 1 ";
1580  aString += QString::number(counter + 1) + " \"";
1581 
1582  if (curItem->isSelected())
1583  aString += ">";
1584  else
1585  aString += " ";
1586 
1587  switch (curItem->isChecked())
1588  {
1589  case CHECKED: aString += "X "; break;
1590  case UNCHECKED: aString += "O "; break;
1591  case NOTCHECKABLE: aString += " "; break;
1592  default: break;
1593  }
1594 
1595  // Indent this item if nessicary
1596  bString = "";
1597  bString.fill(' ', curItem->getIndent());
1598  aString += bString;
1599 
1600  // Increment the scroll position counter for this item
1601  curItem->incrementScrollPos();
1602 
1603  if ((int)curItem->getScrollPos() <= longest_line)
1604  aString += curItem->ItemName().midRef(curItem->getScrollPos(),
1605  ( m_lcdWidth-lcdStartCol));
1606 
1607  aString += "\"";
1608  sendToServer(aString);
1609  }
1610 
1611  ++counter;
1612  }
1613 
1614  // If there are no items to scroll, don't waste our time
1615  if (stopTimer)
1616  m_menuScrollTimer->stop();
1617 }
1618 
1619 void LCDProcClient::startVolume(const QString& app_name)
1620 {
1621  if ( m_lcdShowVolume )
1622  setPriority("Volume", TOP);
1623  if ( m_lcdHeight > 1)
1624  outputCenteredText("Volume", "MythTV " + app_name + " Volume");
1625  m_volumeLevel = 0.0;
1626 
1627  outputVolume();
1628 }
1629 
1631 {
1632  // Stop the scrolling timer
1633  m_menuScrollTimer->stop();
1634  setPriority("Menu", OFF);
1635 }
1636 
1637 void LCDProcClient::setChannelProgress(const QString &time, float value)
1638 {
1639  if (!m_lcdReady )
1640  return;
1641 
1642  m_progress = value;
1643  m_channelTime = time;
1644 
1645  if ( m_progress < 0.0F)
1646  m_progress = 0.0F;
1647  else if ( m_progress > 1.0F)
1648  m_progress = 1.0F;
1649 
1650  outputChannel();
1651 }
1652 
1653 void LCDProcClient::setGenericProgress(bool b, float value)
1654 {
1655  if (!m_lcdReady )
1656  return;
1657 
1658  m_genericProgress = value;
1659 
1660  if ( m_genericProgress < 0.0F)
1661  m_genericProgress = 0.0F;
1662  else if ( m_genericProgress > 1.0F)
1663  m_genericProgress = 1.0F;
1664 
1665  // Note, this will let us switch to/from busy indicator by
1666  // alternating between being passed true or false for b.
1667  m_busyProgress = b;
1668  if ( m_busyProgress )
1669  {
1670  // If we're at either end of the line, switch direction
1671  if (( m_busyPos + m_busyDirection >
1672  (signed int) m_lcdWidth - m_busyIndicatorSize ) ||
1673  ( m_busyPos + m_busyDirection < 1))
1674  {
1676  }
1679  }
1680  else
1681  {
1682  m_busyPos = 1;
1683  }
1684 
1685  outputGeneric();
1686 }
1687 
1688 void LCDProcClient::setMusicProgress(QString time, float value)
1689 {
1690  if (!m_lcdReady )
1691  return;
1692 
1693  m_musicProgress = value;
1694  m_musicTime = std::move(time);
1695 
1696  if ( m_musicProgress < 0.0F)
1697  m_musicProgress = 0.0F;
1698  else if ( m_musicProgress > 1.0F)
1699  m_musicProgress = 1.0F;
1700 
1701  outputMusic();
1702 }
1703 
1705 {
1706  if (!m_lcdReady )
1707  return;
1708 
1709  m_musicRepeat = repeat;
1710 
1711  outputMusic ();
1712 }
1713 
1715 {
1716  if (!m_lcdReady )
1717  return;
1718 
1719  m_musicShuffle = shuffle;
1720 
1721  outputMusic ();
1722 }
1723 
1725 {
1726  if (!m_lcdReady )
1727  return;
1728 
1729  m_volumeLevel = value;
1730 
1731  if ( m_volumeLevel < 0.0F)
1732  m_volumeLevel = 0.0F;
1733  if ( m_volumeLevel > 1.0F)
1734  m_volumeLevel = 1.0F;
1735 
1736  outputVolume();
1737 }
1738 
1740 {
1741  QString aString;
1742  aString = "output ";
1743  aString += QString::number(mask);
1744  sendToServer(aString);
1745 }
1746 
1748 {
1749  removeWidgets();
1750  loadSettings();
1751  init();
1752 }
1753 
1755 {
1756  QString aString;
1757  QString time = QTime::currentTime().toString( m_timeFormat );
1758  int toffset = 0;
1759  int xoffset = 0;
1760 
1761  // kludge ahead: use illegal number (11) to clear num display type
1762 
1763  // kluge - Uses string length to determine time format for parsing
1764  // 1:00 = 4 characters = 24-hour format, 1 digit hour
1765  // 12:00 = 5 characters = 24-hour format, 2 digit hour
1766  // 1:00 am = 7 characters = 12-hour format, 1 digit hour
1767  // 12:00 am = 8 characters = 12-hour format, 2 digit hour
1768  if ((time.length() == 8) || (time.length() == 5))
1769  toffset = 1;
1770 
1771  // if 12-hour clock, add AM/PM indicator to end of the 2nd line
1772  if (time.length() > 6)
1773  {
1774  aString = time.at(5 + toffset);
1775  aString += time.at(6 + toffset);
1776  xoffset = 1;
1777  }
1778  else
1779  {
1780  aString = " ";
1781  }
1782  outputRightText("Time", aString, "ampm", m_lcdHeight - 1);
1783 
1784  if ( m_isRecording )
1785  {
1786  outputLeftText("Time","R","rec1",1);
1787  outputLeftText("Time","E","rec2",2);
1788  outputLeftText("Time","C","rec3",3);
1789  aString = QString::number((int) m_tunerList.size());
1790  outputLeftText("Time",aString,"recCnt",4);
1791 
1792  }
1793  else
1794  {
1795  outputLeftText("Time"," ","rec1",1);
1796  outputLeftText("Time"," ","rec2",2);
1797  outputLeftText("Time"," ","rec3",3);
1798  outputLeftText("Time"," ","recCnt",4);
1799  }
1800 
1801  // Add Hour 10's Digit
1802  aString = "widget_set Time d0 ";
1803  aString += QString::number( m_lcdWidth/2 - 5 - xoffset) + " ";
1804  if (toffset == 0)
1805  aString += "11";
1806  else
1807  aString += time.at(0);
1808  sendToServer(aString);
1809 
1810  // Add Hour 1's Digit
1811  aString = "widget_set Time d1 ";
1812  aString += QString::number( m_lcdWidth/2 - 2 - xoffset) + " ";
1813  aString += time.at(0 + toffset);
1814  sendToServer(aString);
1815 
1816  // Add the Colon
1817  aString = "widget_set Time sep ";
1818  aString += QString::number( m_lcdWidth/2 + 1 - xoffset);
1819  aString += " 10"; // 10 means: colon
1820  sendToServer(aString);
1821 
1822  // Add Minute 10's Digit
1823  aString = "widget_set Time d2 ";
1824  aString += QString::number( m_lcdWidth/2 + 2 - xoffset) + " ";
1825  aString += time.at(2 + toffset);
1826  sendToServer(aString);
1827 
1828  // Add Minute 1's Digit
1829  aString = "widget_set Time d3 ";
1830  aString += QString::number( m_lcdWidth/2 + 5 - xoffset) + " ";
1831  aString += time.at(3 + toffset);
1832  sendToServer(aString);
1833 
1834  // Added a flashing dot in the bottom-right corner
1835  if ( m_timeFlash )
1836  {
1837  outputRightText("Time", ".", "dot", m_lcdHeight );
1838  m_timeFlash = false;
1839  }
1840  else
1841  {
1842  outputRightText("Time", " ", "dot", m_lcdHeight );
1843  m_timeFlash = true;
1844  }
1845 }
1846 
1848 {
1849  if ( m_lcdBigClock )
1850  dobigclock();
1851  else
1852  dostdclock();
1853 }
1854 
1856 {
1857  if (!m_lcdShowTime )
1858  return;
1859 
1861  {
1862  outputCenteredText("Time", tr("RECORDING"), "topWidget", 1);
1863  }
1864  else
1865  {
1867  "Time", MythDate::current().toLocalTime().toString( m_dateFormat ),
1868  "topWidget", 1);
1869  }
1870 
1871  QString aString;
1872  int x = 0;
1873  int y = 0;
1874 
1875  if ( m_lcdHeight < 3)
1876  y = m_lcdHeight;
1877  else
1878  y = (int) std::rint( m_lcdHeight / 2) + 1;
1879 
1880  QString time = QTime::currentTime().toString( m_timeFormat );
1881  x = ( m_lcdWidth - time.length()) / 2 + 1;
1882  aString = "widget_set Time timeWidget ";
1883  aString += QString::number(x);
1884  aString += " ";
1885  aString += QString::number(y);
1886  aString += " \"";
1887  if ( m_lcdShowTime ) {
1888  aString += time + "\"";
1889  if ( m_timeFlash )
1890  {
1891  aString = aString.replace(QRegExp(":"), " ");
1892  m_timeFlash = false;
1893  }
1894  else
1895  m_timeFlash = true;
1896  }
1897  else
1898  aString += " \"";
1899  sendToServer(aString);
1900 }
1901 
1902 // if one or more recordings are taking place we alternate between
1903 // showing the time and the recording status screen
1905 {
1907  return;
1908 
1909  if ( m_isTimeVisible || !m_lcdShowTime )
1910  {
1911  // switch to the rec status screen
1912  setPriority("RecStatus", MEDIUM);
1913  setPriority("Time", LOW);
1914 
1915  m_timeTimer->stop();
1916  m_scrollWTimer->stop();
1917  m_scrollListTimer->stop();
1918  m_isTimeVisible = false;
1919  m_activeScreen = "RecStatus";
1920 
1921  if (m_lcdTunerNo > (int) m_tunerList.size() - 1)
1922  m_lcdTunerNo = 0;
1923  }
1924  else if ( m_lcdTunerNo > (int) m_tunerList.size() - 1)
1925  {
1926  m_lcdTunerNo = 0;
1927 
1928  // switch to the time screen
1929  setPriority("Time", MEDIUM);
1930  setPriority("RecStatus", LOW);
1931 
1932  m_timeTimer->start(1s);
1933  m_scrollWTimer->stop();
1934  m_scrollListTimer->stop();
1936 
1937  outputTime();
1938  m_activeScreen = "Time";
1939  m_isTimeVisible = true;
1940 
1941  return;
1942  }
1943 
1944  QString aString;
1945  QString status;
1946  QStringList list;
1947  std::chrono::milliseconds listTime { 1 };
1948 
1950 
1951  m_scrollListItems.clear();
1952  if ( m_lcdHeight >= 4)
1953  {
1954  // LINE 1 - "R" + Channel
1955  status = tr("R ");
1956  status += tuner.channame;
1957  outputLeftText("RecStatus", status, "textWidget1", 1);
1958 
1959  // LINE 2 - "E" + Program Title
1960  status = tr("E ");
1961  status += tuner.title;
1962  outputLeftText("RecStatus", status, "textWidget2", 2);
1963  //list = formatScrollerText(status);
1964  //assignScrollingList(list, "RecStatus", "textWidget2", 2);
1965 
1966  // LINE 3 - "C" + Program Subtitle
1967  status = tr("C ");
1968  status += tuner.subtitle;
1969  outputLeftText("RecStatus", status, "textWidget3", 3);
1970  //list = formatScrollerText(status);
1971  //assignScrollingList(list, "RecStatus", "textWidget3", 3);
1972 
1973  // LINE 4 - hh:mm-hh:mm + Progress Bar
1974  status = tuner.startTime.toLocalTime().toString("hh:mm") + "-" +
1975  tuner.endTime.toLocalTime().toString("hh:mm");
1976  outputLeftText("RecStatus", status, "textWidget4", 4);
1977 
1978  int length = tuner.startTime.secsTo(tuner.endTime);
1979  int delta = tuner.startTime.secsTo(MythDate::current());
1980  double rec_progress = (double) delta / length;
1981 
1982  aString = "widget_set RecStatus progressBar 13 ";
1983  aString += QString::number( m_lcdHeight );
1984  aString += " ";
1985  aString += QString::number((int)rint(rec_progress * ( m_lcdWidth - 13) *
1986  m_cellWidth ));
1987  sendToServer(aString);
1988 
1989  listTime = list.count() * LCD_SCROLLLIST_TIME * 2;
1990  }
1991  else
1992  {
1993  status = tr("RECORDING|");
1994  status += tuner.title;
1995  if (!tuner.subtitle.isEmpty())
1996  status += "|(" + tuner.subtitle + ")";
1997 
1998  status += "|" + tuner.startTime.toLocalTime().toString("hh:mm")
1999  + " to " +
2000  tuner.endTime.toLocalTime().toString("hh:mm");
2001 
2002  list = formatScrollerText(status);
2003  assignScrollingList(list, "RecStatus", "textWidget1", 1);
2004 
2005  if ( m_lcdHeight > 1)
2006  {
2007  int length = tuner.startTime.secsTo(tuner.endTime);
2008  int delta = tuner.startTime.secsTo(MythDate::current());
2009  double rec_progress = (double) delta / length;
2010 
2011  aString = "widget_set RecStatus progressBar 1 ";
2012  aString += QString::number( m_lcdHeight );
2013  aString += " ";
2014  aString += QString::number((int)rint(rec_progress * m_lcdWidth *
2015  m_cellWidth ));
2016  sendToServer(aString);
2017  }
2018  else
2019  sendToServer("widget_set RecStatus progressBar 1 1 0");
2020 
2021  listTime = list.count() * LCD_SCROLLLIST_TIME * 2;
2022  }
2023 
2024  if (listTime < LCD_TIME_TIME)
2025  listTime = LCD_TIME_TIME;
2026 
2027  m_recStatusTimer->start(listTime);
2028  m_lcdTunerNo++;
2029 }
2030 
2031 void LCDProcClient::outputScrollerText(const QString& theScreen, const QString& theText,
2032  const QString& widget, int top, int bottom)
2033 {
2034  QString aString;
2035  aString = "widget_set " + theScreen + " " + widget;
2036  aString += " 1 ";
2037  aString += QString::number(top) + " ";
2038  aString += QString::number( m_lcdWidth ) + " ";
2039  aString += QString::number(bottom);
2040  aString += " v 8 \"" + theText + "\"";
2041 
2042  sendToServer(aString);
2043 }
2044 
2045 QStringList LCDProcClient::formatScrollerText(const QString &text) const
2046 {
2047  QString separators = " |-_/:('<~";
2048  QStringList lines;
2049 
2050  int lastSplit = 0;
2051  QString line = "";
2052 
2053  for (auto x : qAsConst(text))
2054  {
2055  if (separators.contains(x))
2056  lastSplit = line.length();
2057 
2058  line += x;
2059  if (line.length() > (int) m_lcdWidth || x == '|')
2060  {
2061  QString formatedLine;
2062  formatedLine.fill(' ', m_lcdWidth );
2063  formatedLine = formatedLine.replace(( m_lcdWidth - lastSplit) / 2,
2064  lastSplit, line.left(lastSplit));
2065 
2066  lines.append(formatedLine);
2067 
2068  if (line[lastSplit] == ' ' || line[lastSplit] == '|')
2069  line = line.mid(lastSplit + 1);
2070  else
2071  line = line.mid(lastSplit);
2072 
2073  lastSplit = m_lcdWidth;
2074  }
2075  }
2076 
2077  // make sure we add the last line
2078  QString formatedLine;
2079  formatedLine.fill(' ', m_lcdWidth );
2080  formatedLine = formatedLine.replace(( m_lcdWidth - line.length()) / 2,
2081  line.length(), line);
2082 
2083  lines.append(formatedLine);
2084 
2085  return lines;
2086 }
2087 
2089 {
2090  // See startMusic() for a discription of the Music screen contents
2091 
2092  outputCenteredText("Music", m_musicTime, "timeWidget",
2093  m_lcdHeight < 4 ? 2 : 3);
2094 
2095  if ( m_lcdHeight > 2)
2096  {
2097  QString aString;
2098  QString shuffle = "";
2099  QString repeat = "";
2100  int info_width = 0;
2101 
2102  if ( m_musicShuffle == 1)
2103  {
2104  shuffle = "S:? ";
2105  }
2106  else if ( m_musicShuffle == 2)
2107  {
2108  shuffle = "S:i ";
2109  }
2110  else if ( m_musicShuffle == 3)
2111  {
2112  shuffle = "S:a ";
2113  }
2114 
2115  if ( m_musicRepeat == 1)
2116  {
2117  repeat = "R:1 ";
2118  }
2119  else if ( m_musicRepeat == 2)
2120  {
2121  repeat = "R:* ";
2122  }
2123 
2124  if (shuffle.length() != 0 || repeat.length() != 0)
2125  {
2126  aString = shuffle + repeat;
2127  info_width = aString.length();
2128  outputLeftText("Music", aString, "infoWidget", m_lcdHeight );
2129  }
2130  else
2131  outputLeftText("Music", " ", "infoWidget", m_lcdHeight );
2132 
2133  aString = "widget_set Music progressBar ";
2134  aString += QString::number(info_width + 1);
2135  aString += " ";
2136  aString += QString::number( m_lcdHeight );
2137  aString += " ";
2138  aString += QString::number((int)std::rint( m_musicProgress *
2139  ( m_lcdWidth - info_width) * m_cellWidth ));
2140  sendToServer(aString);
2141  }
2142 }
2143 
2145 {
2146  if ( m_lcdHeight > 1)
2147  {
2148  QString aString;
2149  aString = "widget_set Channel progressBar 1 ";
2150  aString += QString::number( m_lcdHeight );
2151  aString += " ";
2152  aString += QString::number((int)std::rint( m_progress * m_lcdWidth * m_cellWidth ));
2153  sendToServer(aString);
2154 
2155  if ( m_lcdHeight >= 4)
2156  outputCenteredText("Channel", m_channelTime, "timeWidget", 3);
2157  }
2158  else
2159  sendToServer("widget_set Channel progressBar 1 1 0");
2160 }
2161 
2163 {
2164  if ( m_lcdHeight > 1)
2165  {
2166  QString aString;
2167  aString = "widget_set Generic progressBar ";
2168  aString += QString::number ( m_busyPos );
2169  aString += " ";
2170  aString += QString::number( m_lcdHeight );
2171  aString += " ";
2172  aString += QString::number((int)std::rint( m_genericProgress * m_lcdWidth *
2173  m_cellWidth ));
2174  sendToServer(aString);
2175 }
2176  else sendToServer("widget_set Generic progressBar 1 1 0");
2177 }
2178 
2180 {
2181  QString aString;
2182  int line = 3;
2183 
2184  if ( m_lcdHeight > 1)
2185  {
2186  aString = "widget_set Volume progressBar 1 ";
2187  aString += QString::number( m_lcdHeight );
2188  aString += " ";
2189  aString += QString::number((int)std::rint( m_volumeLevel * m_lcdWidth * m_cellWidth ));
2190  sendToServer(aString);
2191  }
2192 
2193  aString = QString::number((int)( m_volumeLevel * 100));
2194  aString += "%";
2195 
2196  if ( m_lcdHeight > 3)
2197  line = 3;
2198  else
2199  line = m_lcdHeight;
2200  outputRightText("Volume", aString, "botWidget", line);
2201 }
2202 
2204 {
2205  if (!m_lcdReady )
2206  return;
2207 
2208  stopAll();
2209 
2210  if (debug_level > 1)
2211  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToTime");
2212 
2213  startTime();
2214 }
2215 
2216 void LCDProcClient::switchToMusic(const QString &artist, const QString &album, const QString &track)
2217 {
2218  if (!m_lcdReady )
2219  return;
2220 
2221  stopAll();
2222 
2223  if (debug_level > 1)
2224  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToMusic") ;
2225 
2226  startMusic(artist, album, track);
2227 }
2228 
2229 void LCDProcClient::switchToChannel(const QString& channum, const QString& title, const QString& subtitle)
2230 {
2231  if (!m_lcdReady )
2232  return;
2233 
2234  stopAll();
2235 
2236  if (debug_level > 1)
2237  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToChannel");
2238 
2239  startChannel(channum, title, subtitle);
2240 }
2241 
2242 void LCDProcClient::switchToMenu(QList<LCDMenuItem> *menuItems, const QString& app_name,
2243  bool popMenu)
2244 {
2245  if (!m_lcdReady )
2246  return;
2247 
2248  if (debug_level > 1)
2249  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToMenu");
2250 
2251  startMenu(menuItems, app_name, popMenu);
2252 }
2253 
2254 void LCDProcClient::switchToGeneric(QList<LCDTextItem> *textItems)
2255 {
2256  if (!m_lcdReady )
2257  return;
2258  stopAll();
2259 
2260  if (debug_level > 1)
2261  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToGeneric");
2262 
2263  startGeneric(textItems);
2264 }
2265 
2266 void LCDProcClient::switchToVolume(const QString& app_name)
2267 {
2268  if (!m_lcdReady )
2269  return;
2270 
2271  stopAll();
2272 
2273  if (debug_level > 1)
2274  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToVolume");
2275 
2276  startVolume(app_name);
2277 }
2278 
2280 {
2281  if (!m_lcdReady )
2282  return;
2283 
2284  stopAll();
2285 
2286  if (debug_level > 1)
2287  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToNothing");
2288 }
2289 
2291 {
2292  if (debug_level > 1)
2293  LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: shutdown");
2294 
2295  stopAll();
2296 
2297  // Remove all the widgets and screens for a clean exit from the server
2298  removeWidgets();
2299 
2300  m_socket->close();
2301 
2302  m_lcdReady = false;
2303  m_connected = false;
2304 }
2305 
2307 {
2308  sendToServer("widget_del Channel progressBar");
2309  sendToServer("widget_del Channel topWidget");
2310  sendToServer("widget_del Channel timeWidget");
2311  sendToServer("screen_del Channel");
2312 
2313  sendToServer("widget_del Generic progressBar");
2314  sendToServer("widget_del Generic textWidget1");
2315  sendToServer("widget_del Generic textWidget2");
2316  sendToServer("widget_del Generic textWidget3");
2317  sendToServer("screen_del Generic");
2318 
2319  sendToServer("widget_del Volume progressBar");
2320  sendToServer("widget_del Volume topWidget");
2321  sendToServer("screen_del Volume");
2322 
2323  sendToServer("widget_del Menu topWidget");
2324  sendToServer("widget_del Menu menuWidget1");
2325  sendToServer("widget_del Menu menuWidget2");
2326  sendToServer("widget_del Menu menuWidget3");
2327  sendToServer("widget_del Menu menuWidget4");
2328  sendToServer("widget_del Menu menuWidget5");
2329  sendToServer("screen_del Menu");
2330 
2331  sendToServer("widget_del Music progressBar");
2332  sendToServer("widget_del Music infoWidget");
2333  sendToServer("widget_del Music timeWidget");
2334  sendToServer("widget_del Music topWidget");
2335  sendToServer("screen_del Music");
2336 
2337  if ( m_lcdBigClock )
2338  {
2339  sendToServer("widget_del Time rec1");
2340  sendToServer("widget_del Time rec2");
2341  sendToServer("widget_del Time rec3");
2342  sendToServer("widget_del Time recCnt");
2343  sendToServer("widget_del Time d0");
2344  sendToServer("widget_del Time d1");
2345  sendToServer("widget_del Time sep");
2346  sendToServer("widget_del Time d2");
2347  sendToServer("widget_del Time d3");
2348  sendToServer("widget_del Time ampm");
2349  sendToServer("widget_del Time dot");
2350  }
2351  else
2352  {
2353  sendToServer("widget_del Time timeWidget");
2354  sendToServer("widget_del Time topWidget");
2355  }
2356 
2357  sendToServer("screen_del Time");
2358 
2359  sendToServer("widget_del RecStatus textWidget1");
2360  sendToServer("widget_del RecStatus textWidget2");
2361  sendToServer("widget_del RecStatus textWidget3");
2362  sendToServer("widget_del RecStatus textWidget4");
2363  sendToServer("widget_del RecStatus progressBar");
2364 }
2365 
2367 {
2368  if (debug_level > 1)
2369  {
2370  LOG(VB_GENERAL, LOG_INFO,
2371  "LCDProcClient: An LCD device is being snuffed out"
2372  "of existence (~LCDProcClient() was called)");
2373  }
2374 
2375  if (m_socket)
2376  {
2377  delete m_socket;
2378  m_lcdReady = false;
2379  }
2380 
2381  delete m_lcdMenuItems;
2382 
2384 }
2385 
2387 {
2388  if (e->type() == MythEvent::MythEventMessage)
2389  {
2390  auto *me = dynamic_cast<MythEvent *>(e);
2391  if (me == nullptr)
2392  return;
2393 
2394  if (me->Message().startsWith("RECORDING_LIST_CHANGE") ||
2395  me->Message() == "UPDATE_PROG_INFO")
2396  {
2397  if ( m_lcdShowRecstatus && !m_updateRecInfoTimer->isActive())
2398  {
2399  if (debug_level > 1)
2400  LOG(VB_GENERAL, LOG_INFO,
2401  "LCDProcClient: Received recording list change");
2402 
2403  // we can't query the backend from inside the customEvent
2404  // so fire the recording list update from a timer
2405  m_updateRecInfoTimer->start(500ms);
2406  }
2407  }
2408  }
2409 }
2410 
2412 {
2413  m_tunerList.clear();
2414  m_isRecording = false;
2415 
2417  {
2418  if (!gCoreContext->ConnectToMasterServer(false))
2419  {
2420  LOG(VB_GENERAL, LOG_ERR,
2421  "LCDProcClient: Cannot get recording status "
2422  "- is the master server running?\n\t\t\t"
2423  "Will retry in 30 seconds");
2424  QTimer::singleShot(30s, this, &LCDProcClient::updateRecordingList);
2425 
2426  // If we can't get the recording status and we're showing
2427  // it, switch back to time. Maybe it would be even better
2428  // to show that the backend is unreachable ?
2429  if (m_activeScreen == "RecStatus")
2430  switchToTime();
2431  return;
2432  }
2433  }
2434 
2436 
2437  m_lcdTunerNo = 0;
2438 
2439  if (m_activeScreen == "Time" || m_activeScreen == "RecStatus")
2440  startTime();
2441 }
2442 /* vim: set expandtab tabstop=4 shiftwidth=4: */
LCDProcClient::outputTime
void outputTime()
Definition: lcdprocclient.cpp:1847
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:238
LCDProcClient::m_dateFormat
QString m_dateFormat
Definition: lcdprocclient.h:196
LCDProcClient::TOP
@ TOP
Definition: lcdprocclient.h:105
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:179
LCDProcClient::shutdown
void shutdown()
Definition: lcdprocclient.cpp:2290
LCDProcClient::m_lcdWidth
unsigned int m_lcdWidth
Definition: lcdprocclient.h:160
LCD_TIME_TIME
static constexpr std::chrono::milliseconds LCD_TIME_TIME
Definition: lcdprocclient.cpp:41
e
QDomElement e
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:1420
LCDProcClient::setMusicShuffle
void setMusicShuffle(int shuffle)
Definition: lcdprocclient.cpp:1714
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:1724
LCDProcClient::setVersion
void setVersion(const QString &sversion, const QString &pversion)
Definition: lcdprocclient.cpp:661
tv.h
MythEvent::MythEventMessage
static Type MythEventMessage
Definition: mythevent.h:73
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
LCDProcClient::m_lcdShowVolume
bool m_lcdShowVolume
Definition: lcdprocclient.h:222
LCDProcClient::m_timeFormat
QString m_timeFormat
Definition: lcdprocclient.h:195
LCDProcClient::assignScrollingWidgets
void assignScrollingWidgets(const QString &theText, const QString &theScreen, const QString &theWidget="topWidget", int theRow=1)
Definition: lcdprocclient.cpp:937
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:294
LCDProcClient::outputRecStatus
void outputRecStatus()
Definition: lcdprocclient.cpp:1904
error
static void error(const char *str,...)
Definition: vbi.cpp:42
LCDTextItem::getText
QString getText() const
Definition: lcddevice.h:73
LCDProcClient::formatScrollerText
QStringList formatScrollerText(const QString &text) const
Definition: lcdprocclient.cpp:2045
LCDProcClient::m_prioOff
QString m_prioOff
Definition: lcdprocclient.h:158
LCDProcClient::m_lcdShowMusicItems
QString m_lcdShowMusicItems
Definition: lcdprocclient.h:228
TunerStatus::title
QString title
Definition: tvremoteutil.h:22
LCDProcClient::m_lastCommand
QString m_lastCommand
Definition: lcdprocclient.h:211
LCDProcClient::init
void init()
Definition: lcdprocclient.cpp:411
LCDProcClient::OFF
@ OFF
Definition: lcdprocclient.h:105
title
QString title
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:636
MythCoreContext::ConnectToMasterServer
bool ConnectToMasterServer(bool blockingClient=true, bool openEventSocket=true)
Definition: mythcorecontext.cpp:377
LCDProcClient::m_scrollListTimer
QTimer * m_scrollListTimer
Definition: lcdprocclient.h:149
LCDProcClient::PRIORITY
PRIORITY
Definition: lcdprocclient.h:105
LCDProcClient::outputMusic
void outputMusic()
Definition: lcdprocclient.cpp:2088
LCDProcClient::m_cellWidth
unsigned int m_cellWidth
Definition: lcdprocclient.h:162
LCDProcClient::m_recStatusTimer
QTimer * m_recStatusTimer
Definition: lcdprocclient.h:148
LCDProcClient::m_checkConnectionsTimer
QTimer * m_checkConnectionsTimer
Definition: lcdprocclient.h:147
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:17
LCDProcClient::m_activeScreen
QString m_activeScreen
Definition: lcdprocclient.h:138
LCDProcClient::dobigclock
void dobigclock(void)
Definition: lcdprocclient.cpp:1754
arg
arg(title).arg(filename).arg(doDelete))
LCDProcClient::sendToServer
void sendToServer(const QString &someText)
Definition: lcdprocclient.cpp:175
mythdbcon.h
LCDProcClient::formatScrollingWidgets
void formatScrollingWidgets(void)
Definition: lcdprocclient.cpp:947
LCDProcClient::checkConnections
void checkConnections()
Definition: lcdprocclient.cpp:282
LCDProcClient::m_lcdShowMenu
bool m_lcdShowMenu
Definition: lcdprocclient.h:218
LCDProcClient::m_port
unsigned int m_port
Definition: lcdprocclient.h:213
TunerStatus::endTime
QDateTime endTime
Definition: tvremoteutil.h:25
LCDProcClient::m_lcdHeight
unsigned int m_lcdHeight
Definition: lcdprocclient.h:161
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
LCDProcClient::LCDProcClient
LCDProcClient(LCDServer *lparent)
Definition: lcdprocclient.cpp:46
LCDProcClient::~LCDProcClient
~LCDProcClient() override
Definition: lcdprocclient.cpp:2366
LCDProcClient::m_scrollListScreen
QString m_scrollListScreen
Definition: lcdprocclient.h:199
LCDProcClient::m_prioHigh
QString m_prioHigh
Definition: lcdprocclient.h:155
LCDProcClient::m_lcdHeartbeatOn
bool m_lcdHeartbeatOn
Definition: lcdprocclient.h:225
UNCHECKED
@ UNCHECKED
Definition: lcddevice.h:17
LCDProcClient::m_lcdPopupTime
int m_lcdPopupTime
Definition: lcdprocclient.h:227
LCDMenuItem::setScrollPos
void setScrollPos(unsigned int value)
Definition: lcddevice.h:45
LCD_SCROLLLIST_TIME
static constexpr std::chrono::milliseconds LCD_SCROLLLIST_TIME
Definition: lcdprocclient.cpp:42
LCD_START_COL
#define LCD_START_COL
Definition: lcdprocclient.cpp:34
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:236
LCDProcClient::m_lcdKeyString
QString m_lcdKeyString
Definition: lcdprocclient.h:229
LCDProcClient::setStartupMessage
void setStartupMessage(QString msg, uint messagetime)
Definition: lcdprocclient.cpp:627
LCDProcClient::m_lcdShowChannel
bool m_lcdShowChannel
Definition: lcdprocclient.h:221
LCDProcClient::m_serverVersion
QString m_serverVersion
Definition: lcdprocclient.h:165
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:2179
MythCoreContext::IsConnectedToMaster
bool IsConnectedToMaster(void)
Definition: mythcorecontext.cpp:611
LCDProcClient::m_protocolVersion
QString m_protocolVersion
Definition: lcdprocclient.h:166
LCDProcClient::switchToGeneric
void switchToGeneric(QList< LCDTextItem > *textItems)
Definition: lcdprocclient.cpp:2254
TunerStatus
recording status stuff
Definition: tvremoteutil.h:17
LCDProcClient::serverSendingData
void serverSendingData()
Definition: lcdprocclient.cpp:313
toString
QString toString(MarkTypes type)
Definition: programtypes.cpp:26
LCDProcClient::m_isRecording
bool m_isRecording
Definition: lcdprocclient.h:234
mythdate.h
LCDProcClient::scrollMenuText
void scrollMenuText()
Definition: lcdprocclient.cpp:1411
LCDProcClient::m_lcdShowTime
bool m_lcdShowTime
Definition: lcdprocclient.h:217
LCDProcClient::m_prioTop
QString m_prioTop
Definition: lcdprocclient.h:153
LCDProcClient::switchToTime
void switchToTime()
Definition: lcdprocclient.cpp:2203
LCDProcClient::loadSettings
void loadSettings()
Definition: lcdprocclient.cpp:535
LCDProcClient::m_hostname
QString m_hostname
Definition: lcdprocclient.h:212
LCDProcClient::m_scrollListItem
unsigned int m_scrollListItem
Definition: lcdprocclient.h:202
LCDProcClient::m_channelTime
QString m_channelTime
Definition: lcdprocclient.h:170
LCDMenuItem::isChecked
CHECKED_STATE isChecked() const
Definition: lcddevice.h:33
LCDMenuItem::setScroll
void setScroll(bool value)
Definition: lcddevice.h:43
LCDProcClient::m_menuScrollPosition
unsigned int m_menuScrollPosition
Definition: lcdprocclient.h:204
LCDProcClient::setCellHeight
void setCellHeight(unsigned int x)
Definition: lcdprocclient.cpp:654
RemoteGetRecordingStatus
int RemoteGetRecordingStatus(const ProgramInfo *pginfo, int overrecsecs, int underrecsecs)
Get status of an individual programme (with pre-post roll?).
Definition: remoteutil.cpp:493
LCDProcClient::customEvent
void customEvent(QEvent *e) override
Definition: lcdprocclient.cpp:2386
LCDProcClient::m_lcdMenuItems
QList< LCDMenuItem > * m_lcdMenuItems
Definition: lcdprocclient.h:205
LCDTextItem::setText
void setText(const QString &value)
Definition: lcddevice.h:80
LCDProcClient::switchToNothing
void switchToNothing()
Definition: lcdprocclient.cpp:2279
compat.h
LCDProcClient::removeWidgets
void removeWidgets()
Definition: lcdprocclient.cpp:2306
LCDProcClient::m_prioLow
QString m_prioLow
Definition: lcdprocclient.h:157
LCDProcClient::outputChannel
void outputChannel()
Definition: lcdprocclient.cpp:2144
LCDProcClient::m_lcdTextItems
QList< LCDTextItem > * m_lcdTextItems
Definition: lcdprocclient.h:191
LCDProcClient::setChannelProgress
void setChannelProgress(const QString &time, float value)
Definition: lcdprocclient.cpp:1637
LCDProcClient::m_pVersion
int m_pVersion
Definition: lcdprocclient.h:167
LCDProcClient::expandString
QString expandString(const QString &aString) const
Definition: lcdprocclient.cpp:525
LCDProcClient::m_timeFlash
bool m_timeFlash
Definition: lcdprocclient.h:208
LCDProcClient::setMusicRepeat
void setMusicRepeat(int repeat)
Definition: lcdprocclient.cpp:1704
LCDProcClient::switchToChannel
void switchToChannel(const QString &channum="", const QString &title="", const QString &subtitle="")
Definition: lcdprocclient.cpp:2229
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:223
LCDProcClient::m_sendBuffer
QString m_sendBuffer
Definition: lcdprocclient.h:210
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:182
LCDProcClient::setCellWidth
void setCellWidth(unsigned int x)
Definition: lcdprocclient.cpp:647
ALIGN_CENTERED
@ ALIGN_CENTERED
Definition: lcddevice.h:57
LCDTextItem::getAlignment
TEXT_ALIGNMENT getAlignment() const
Definition: lcddevice.h:72
LCDProcClient::m_lcdShowMusic
bool m_lcdShowMusic
Definition: lcdprocclient.h:220
uint
unsigned int uint
Definition: compat.h:141
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:60
LCDProcClient::dostdclock
void dostdclock()
Definition: lcdprocclient.cpp:1855
LCDProcClient::m_volumeLevel
float m_volumeLevel
Definition: lcdprocclient.h:184
LCDProcClient::m_socket
QTcpSocket * m_socket
Definition: lcdprocclient.h:140
LCDProcClient::switchToMusic
void switchToMusic(const QString &artist, const QString &album, const QString &track)
Definition: lcdprocclient.cpp:2216
LCDTextItem::getScreen
QString getScreen() const
Definition: lcddevice.h:74
LCDProcClient::m_timeTimer
QTimer * m_timeTimer
Definition: lcdprocclient.h:141
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:933
LCDProcClient::m_updateRecInfoTimer
QTimer * m_updateRecInfoTimer
Definition: lcdprocclient.h:151
LCDProcClient::setHeartbeat
void setHeartbeat(const QString &screen, bool onoff)
Definition: lcdprocclient.cpp:254
LCDProcClient::m_scrollWTimer
QTimer * m_scrollWTimer
Definition: lcdprocclient.h:142
LCDProcClient::setGenericProgress
void setGenericProgress(bool busy, float value)
Definition: lcdprocclient.cpp:1653
ALIGN_LEFT
@ ALIGN_LEFT
Definition: lcddevice.h:57
LCDProcClient::m_lcdBigClock
bool m_lcdBigClock
Definition: lcdprocclient.h:226
LCDProcClient::m_busyProgress
bool m_busyProgress
true if the generic progress indicator is a busy (ie.
Definition: lcdprocclient.h:173
LCDMenuItem
Definition: lcddevice.h:22
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:927
LCDProcClient::startGeneric
void startGeneric(QList< LCDTextItem > *textItems)
Definition: lcdprocclient.cpp:1128
LCDProcClient::m_scrollListRow
int m_scrollListRow
Definition: lcdprocclient.h:201
lcdprocclient.h
LCDProcClient::m_menuScrollTimer
QTimer * m_menuScrollTimer
Definition: lcdprocclient.h:144
LCDProcClient::MEDIUM
@ MEDIUM
Definition: lcdprocclient.h:105
LCDProcClient::HIGH
@ HIGH
Definition: lcdprocclient.h:105
LCDMenuItem::ItemName
QString ItemName() const
Definition: lcddevice.h:35
LCDProcClient::m_isTimeVisible
bool m_isTimeVisible
Definition: lcdprocclient.h:235
LCDServer
Definition: lcdserver.h:28
LCDProcClient::m_scrollScreen
QString m_scrollScreen
Definition: lcdprocclient.h:193
LCDProcClient::m_menuPreScrollTimer
QTimer * m_menuPreScrollTimer
Definition: lcdprocclient.h:145
LCDProcClient::m_musicRepeat
int m_musicRepeat
Definition: lcdprocclient.h:188
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:156
LCD_VERSION_4
#define LCD_VERSION_4
Definition: lcdprocclient.cpp:36
LCDProcClient::outputGeneric
void outputGeneric()
Definition: lcdprocclient.cpp:2162
ALIGN_RIGHT
@ ALIGN_RIGHT
Definition: lcddevice.h:57
LCDProcClient::m_lcdReady
bool m_lcdReady
Definition: lcdprocclient.h:215
LCDProcClient::updateLEDs
void updateLEDs(int mask)
Definition: lcdprocclient.cpp:1739
lcdserver.h
NOTCHECKABLE
@ NOTCHECKABLE
Definition: lcddevice.h:17
LCDProcClient::m_lcdShowGeneric
bool m_lcdShowGeneric
Definition: lcdprocclient.h:219
LCDProcClient::scrollWidgets
void scrollWidgets(void)
Definition: lcdprocclient.cpp:1000
LCDProcClient::LOW
@ LOW
Definition: lcdprocclient.h:105
LCDProcClient::veryBadThings
void veryBadThings(QAbstractSocket::SocketError error)
Definition: lcdprocclient.cpp:746
LCDProcClient::m_genericProgress
float m_genericProgress
Definition: lcdprocclient.h:183
LCDProcClient::switchToVolume
void switchToVolume(const QString &app_name)
Definition: lcdprocclient.cpp:2266
LCDProcClient::m_busyPos
int m_busyPos
Current position of the busy indicator, used if m_busyProgress is true.
Definition: lcdprocclient.h:176
mythcontext.h
debug_level
int debug_level
Definition: lcdserver.cpp:73
LCDTextItem
Definition: lcddevice.h:60
LCDProcClient::unPopMenu
void unPopMenu()
Definition: lcdprocclient.cpp:1630
LCDProcClient::m_scrollListWidget
QString m_scrollListWidget
Definition: lcdprocclient.h:200
LCDProcClient::m_startupMessage
QString m_startupMessage
Definition: lcdprocclient.h:231
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:2031
LCDProcClient::setPriority
void setPriority(const QString &screen, PRIORITY priority)
Definition: lcdprocclient.cpp:219
LCDMenuItem::getIndent
unsigned int getIndent() const
Definition: lcddevice.h:37
LCDProcClient::m_startupShowTime
uint m_startupShowTime
Definition: lcdprocclient.h:232
LCDProcClient::setHeight
void setHeight(unsigned int x)
Definition: lcdprocclient.cpp:640
LCDProcClient::m_musicTime
QString m_musicTime
Definition: lcdprocclient.h:187
LCDProcClient::m_lcdBacklightOn
bool m_lcdBacklightOn
Definition: lcdprocclient.h:224
LCDProcClient::m_prioUrgent
QString m_prioUrgent
Definition: lcdprocclient.h:154
LCDProcClient::outputText
void outputText(QList< LCDTextItem > *textItems)
Definition: lcdprocclient.cpp:815
LCDProcClient::connectToHost
bool connectToHost(const QString &hostname, unsigned int port)
Definition: lcdprocclient.cpp:136
LCDProcClient::m_progress
float m_progress
Definition: lcdprocclient.h:169
LCDMenuItem::isSelected
bool isSelected() const
Definition: lcddevice.h:34
LCDProcClient::m_connected
bool m_connected
Definition: lcdprocclient.h:207
LCDProcClient::m_popMenuTimer
QTimer * m_popMenuTimer
Definition: lcdprocclient.h:146
LCDProcClient::updateRecordingList
void updateRecordingList(void)
Definition: lcdprocclient.cpp:2411
CHECKED
@ CHECKED
Definition: lcddevice.h:17
LCD_VERSION_5
#define LCD_VERSION_5
Definition: lcdprocclient.cpp:37
lcdStartCol
int lcdStartCol
Definition: lcdprocclient.cpp:44
LCDProcClient::switchToMenu
void switchToMenu(QList< LCDMenuItem > *menuItems, const QString &app_name="", bool popMenu=true)
Definition: lcdprocclient.cpp:2242
lcddevice.h
LCDProcClient::beginScrollingMenuText
void beginScrollingMenuText()
Definition: lcdprocclient.cpp:1373
LCDProcClient::startVolume
void startVolume(const QString &app_name)
Definition: lcdprocclient.cpp:1619
LCDTextItem::getRow
unsigned int getRow() const
Definition: lcddevice.h:71
LCDProcClient::m_scrollListItems
QStringList m_scrollListItems
Definition: lcdprocclient.h:198
LCDProcClient::SetupLCD
bool SetupLCD(void)
Definition: lcdprocclient.cpp:125
LCDProcClient::m_parentLCDServer
LCDServer * m_parentLCDServer
Definition: lcdprocclient.h:230
LCDProcClient::m_musicProgress
float m_musicProgress
Definition: lcdprocclient.h:186
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:143
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:189
LCDProcClient::m_cellHeight
unsigned int m_cellHeight
Definition: lcdprocclient.h:163
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::URGENT
@ URGENT
Definition: lcdprocclient.h:105
LCDProcClient::m_scrollPosition
unsigned int m_scrollPosition
Definition: lcdprocclient.h:194
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:919
LCDProcClient::setMusicProgress
void setMusicProgress(QString time, float value)
Definition: lcdprocclient.cpp:1688
LCDProcClient::m_showMessageTimer
QTimer * m_showMessageTimer
Definition: lcdprocclient.h:150
LCDProcClient::reset
void reset(void)
Definition: lcdprocclient.cpp:1747