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