00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include <unistd.h>
00012 #include <stdlib.h>
00013 #include <cmath>
00014
00015
00016 #include <QCoreApplication>
00017 #include <QEvent>
00018 #include <QTimer>
00019
00020
00021 #include "mythcontext.h"
00022 #include "mythdbcon.h"
00023 #include "tv.h"
00024 #include "compat.h"
00025
00026
00027 #include "lcdprocclient.h"
00028 #include "lcdserver.h"
00029 #include "lcddevice.h"
00030
00031 #define LCD_START_COL 3
00032
00033 #define LCD_VERSION_4 1
00034 #define LCD_VERSION_5 2
00035
00036 #define LCD_RECSTATUS_TIME 10000
00037 #define LCD_TIME_TIME 3000
00038 #define LCD_SCROLLLIST_TIME 2000
00039
00040 int lcdStartCol = LCD_START_COL;
00041
00042 LCDProcClient::LCDProcClient(LCDServer *lparent) : QObject(NULL)
00043 {
00044
00045
00046
00047
00048
00049 if (debug_level > 0)
00050 LOG(VB_GENERAL, LOG_INFO,
00051 "LCDProcClient: An LCDProcClient object now exists");
00052
00053 socket = new QTcpSocket(this);
00054 connect(socket, SIGNAL(error(QAbstractSocket::SocketError)),
00055 this, SLOT(veryBadThings(QAbstractSocket::SocketError)));
00056 connect(socket, SIGNAL(readyRead()), this, SLOT(serverSendingData()));
00057
00058 m_parent = lparent;
00059
00060 lcd_ready = false;
00061
00062 lcdWidth = 5;
00063 lcdHeight = 1;
00064 cellWidth = 1;
00065 cellHeight = 1;
00066 lcdStartCol = LCD_START_COL;
00067 if (lcdWidth < 12)
00068 {
00069 if (lcdHeight == 1)
00070 lcdStartCol = 0;
00071 else
00072 lcdStartCol = 1;
00073 }
00074
00075 hostname = "";
00076 port = 13666;
00077
00078 timeFlash = false;
00079 scrollingText = "";
00080 progress = 0.0;
00081 generic_progress = 0.0;
00082 volume_level = 0.0;
00083 connected = false;
00084 send_buffer = "";
00085 lcdMenuItems = new QList<LCDMenuItem>;
00086 lcdTextItems = new QList<LCDTextItem>;
00087
00088 timeTimer = new QTimer(this);
00089 connect(timeTimer, SIGNAL(timeout()), this, SLOT(outputTime()));
00090
00091 scrollWTimer = new QTimer(this);
00092 connect(scrollWTimer, SIGNAL(timeout()), this, SLOT(scrollWidgets()));
00093
00094 preScrollWTimer = new QTimer(this);
00095 preScrollWTimer->setSingleShot(true);
00096 connect(preScrollWTimer, SIGNAL(timeout()), this,
00097 SLOT(beginScrollingWidgets()));
00098
00099 popMenuTimer = new QTimer(this);
00100 popMenuTimer->setSingleShot(true);
00101 connect(popMenuTimer, SIGNAL(timeout()), this, SLOT(unPopMenu()));
00102
00103 menuScrollTimer = new QTimer(this);
00104 connect(menuScrollTimer, SIGNAL(timeout()), this, SLOT(scrollMenuText()));
00105
00106 menuPreScrollTimer = new QTimer(this);
00107 connect(menuPreScrollTimer, SIGNAL(timeout()), this,
00108 SLOT(beginScrollingMenuText()));
00109
00110 checkConnectionsTimer = new QTimer(this);
00111 connect(checkConnectionsTimer, SIGNAL(timeout()), this,
00112 SLOT(checkConnections()));
00113 checkConnectionsTimer->start(10000);
00114
00115 recStatusTimer = new QTimer(this);
00116 connect(recStatusTimer, SIGNAL(timeout()), this, SLOT(outputRecStatus()));
00117
00118 scrollListTimer = new QTimer(this);
00119 connect(scrollListTimer, SIGNAL(timeout()), this, SLOT(scrollList()));
00120
00121 showMessageTimer = new QTimer(this);
00122 showMessageTimer->setSingleShot(true);
00123 connect(showMessageTimer, SIGNAL(timeout()), this,
00124 SLOT(removeStartupMessage()));
00125
00126 updateRecInfoTimer = new QTimer(this);
00127 updateRecInfoTimer->setSingleShot(true);
00128 connect(updateRecInfoTimer, SIGNAL(timeout()), this,
00129 SLOT(updateRecordingList()));
00130
00131 gCoreContext->addListener(this);
00132
00133 isRecording = false;
00134 }
00135
00136 bool LCDProcClient::SetupLCD ()
00137 {
00138 QString lcd_host;
00139 int lcd_port;
00140
00141 lcd_host = gCoreContext->GetSetting("LCDHost", "localhost");
00142 lcd_port = gCoreContext->GetNumSetting("LCDPort", 13666);
00143
00144 if (lcd_host.length() > 0 && lcd_port > 1024)
00145 connectToHost(lcd_host, lcd_port);
00146
00147 return connected;
00148 }
00149
00150 bool LCDProcClient::connectToHost(const QString &lhostname, unsigned int lport)
00151 {
00152
00153
00154
00155 int timeout = 1000;
00156 hostname = lhostname;
00157 port = lport;
00158
00159
00160 if (!gCoreContext->GetNumSetting("LCDEnable", 0))
00161 {
00162 connected = false;
00163 return connected;
00164 }
00165
00166 if (!connected)
00167 {
00168 QTextStream os(socket);
00169 socket->connectToHost(hostname, port);
00170
00171 while (--timeout && socket->state() != QAbstractSocket::ConnectedState)
00172 {
00173 qApp->processEvents();
00174 usleep(1000);
00175
00176 if (socket->state() == QAbstractSocket::ConnectedState)
00177 {
00178 connected = true;
00179 os << "hello\n";
00180 break;
00181 }
00182 }
00183 }
00184
00185 return connected;
00186 }
00187
00188 void LCDProcClient::sendToServer(const QString &someText)
00189 {
00190
00191 if (socket->state() != QAbstractSocket::ConnectedState)
00192 {
00193 if (!lcd_ready)
00194 return;
00195
00196 lcd_ready = false;
00197
00198
00199 stopAll();
00200
00201
00202
00203 LOG(VB_GENERAL, LOG_ERR,
00204 "LCDProcClient: Connection to LCDd died unexpectedly.");
00205 return;
00206 }
00207
00208 QTextStream os(socket);
00209 os.setCodec("ISO 8859-1");
00210
00211 last_command = someText;
00212
00213 if (connected)
00214 {
00215 if (debug_level > 9)
00216 LOG(VB_NETWORK, LOG_INFO,
00217 "LCDProcClient: Sending to Server: " + someText);
00218
00219
00220
00221 os << someText << "\n";
00222 }
00223 else
00224 {
00225
00226
00227 send_buffer += someText;
00228 send_buffer += "\n";
00229 }
00230 }
00231
00232 void LCDProcClient::setPriority(const QString &screen, PRIORITY priority)
00233 {
00234 QString aString;
00235 int err = 0;
00236 aString = "screen_set ";
00237 aString += screen;
00238 aString += " priority ";
00239
00240 switch (priority) {
00241 case TOP:
00242 aString += prioTop;
00243 break;
00244 case URGENT:
00245 aString += prioUrgent;
00246 break;
00247 case HIGH:
00248 aString += prioHigh;
00249 break;
00250 case MEDIUM:
00251 aString += prioMedium;
00252 break;
00253 case LOW:
00254 aString += prioLow;
00255 break;
00256 case OFF:
00257 aString += prioOff;
00258 break;
00259 default:
00260 err = 1;
00261 break;
00262 }
00263 if (err == 0)
00264 sendToServer (aString);
00265 }
00266
00267 void LCDProcClient::setHeartbeat (const QString &screen, bool onoff)
00268 {
00269 QString msg;
00270 if (onoff)
00271 {
00272 if (pVersion == LCD_VERSION_4)
00273 {
00274 msg = "widget_add " + screen + " heartbeat";
00275 }
00276 if (pVersion == LCD_VERSION_5)
00277 {
00278 msg = "screen_set " + screen + " heartbeat on";
00279 }
00280 }
00281 else
00282 {
00283 if (pVersion == LCD_VERSION_4)
00284 {
00285 msg = "widget_del " + screen + " heartbeat";
00286 }
00287 if (pVersion == LCD_VERSION_5)
00288 {
00289 msg = "screen_set " + screen + " heartbeat off";
00290 }
00291 }
00292 sendToServer (msg);
00293 }
00294
00295 void LCDProcClient::checkConnections()
00296 {
00297 if (debug_level > 0)
00298 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: checking connections");
00299
00300
00301 if (!gCoreContext->IsConnectedToMaster())
00302 {
00303 if (debug_level > 0)
00304 LOG(VB_GENERAL, LOG_INFO,
00305 "LCDProcClient: connecting to master server");
00306 if (!gCoreContext->ConnectToMasterServer(false))
00307 LOG(VB_GENERAL, LOG_ERR,
00308 "LCDProcClient: connecting to master server failed");
00309 }
00310
00311
00312 if (socket->state() != QAbstractSocket::ConnectedState)
00313 {
00314 if (debug_level > 0)
00315 LOG(VB_GENERAL, LOG_INFO,
00316 "LCDProcClient: connecting to LCDProc server");
00317
00318 lcd_ready = false;
00319 connected = false;
00320
00321
00322 connectToHost(hostname, port);
00323 }
00324 }
00325
00326 void LCDProcClient::serverSendingData()
00327 {
00328 QString lineFromServer, tempString;
00329 QStringList aList;
00330 QStringList::Iterator it;
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 while(socket->canReadLine())
00343 {
00344 lineFromServer = socket->readLine();
00345 lineFromServer = lineFromServer.replace( QRegExp("\n"), "" );
00346 lineFromServer = lineFromServer.replace( QRegExp("\r"), "" );
00347
00348 if (debug_level > 0)
00349
00350 if (lineFromServer != "success")
00351 LOG(VB_NETWORK, LOG_INFO,
00352 "LCDProcClient: Received from server: " + lineFromServer);
00353
00354 aList = lineFromServer.split(" ");
00355 if (aList.first() == "connect")
00356 {
00357
00358
00359
00360
00361 it = aList.begin();
00362 it++;
00363 if ((*it) != "LCDproc")
00364 {
00365 LOG(VB_GENERAL, LOG_WARNING,
00366 "LCDProcClient: WARNING: Second parameter "
00367 "returned from LCDd was not \"LCDproc\"");
00368 }
00369
00370
00371 it++;
00372 QString server_version = *it;
00373 it++;
00374 it++;
00375 QString protocol_version = *it;
00376 setVersion (server_version, protocol_version);
00377 it++;
00378 it++;
00379 it++;
00380
00381 tempString = *it;
00382 setWidth(tempString.toInt());
00383
00384 it++;
00385 it++;
00386
00387 tempString = *it;
00388 setHeight(tempString.toInt());
00389 it++;
00390 it++;
00391
00392 tempString = *it;
00393 setCellWidth(tempString.toInt());
00394
00395 it++;
00396 it++;
00397
00398 tempString = *it;
00399 setCellHeight(tempString.toInt());
00400
00401 init();
00402
00403 describeServer();
00404 }
00405
00406 if (aList.first() == "huh?")
00407 {
00408 LOG(VB_GENERAL, LOG_WARNING,
00409 "LCDProcClient: WARNING: Something is getting"
00410 "passed to LCDd that it doesn't understand");
00411 LOG(VB_GENERAL, LOG_WARNING, "last command: " + last_command);
00412 }
00413 else if (aList.first() == "key")
00414 {
00415 if (m_parent)
00416 m_parent->sendKeyPress(aList.last().trimmed());
00417 }
00418 }
00419 }
00420
00421 void LCDProcClient::init()
00422 {
00423 QString aString;
00424 lcd_keystring = "";
00425
00426 connected = true;
00427
00428
00429
00430 sendToServer("client_set name Myth");
00431
00432
00433
00434
00435 sendToServer("screen_add Time");
00436 setPriority("Time", MEDIUM);
00437
00438 if (gCoreContext->GetSetting("LCDBigClock", "1") == "1")
00439 {
00440
00441 sendToServer("widget_add Time rec1 string");
00442 sendToServer("widget_add Time rec2 string");
00443 sendToServer("widget_add Time rec3 string");
00444 sendToServer("widget_add Time recCnt string");
00445 sendToServer("widget_add Time d0 num");
00446 sendToServer("widget_add Time d1 num");
00447 sendToServer("widget_add Time sep num");
00448 sendToServer("widget_add Time d2 num");
00449 sendToServer("widget_add Time d3 num");
00450 sendToServer("widget_add Time ampm string");
00451 sendToServer("widget_add Time dot string");
00452 }
00453 else
00454 {
00455 sendToServer("widget_add Time timeWidget string");
00456 sendToServer("widget_add Time topWidget string");
00457 }
00458
00459
00460
00461
00462 sendToServer("screen_add Menu");
00463 setPriority("Menu", LOW);
00464 sendToServer("widget_add Menu topWidget string");
00465 for (unsigned int i = 1; i <= lcdHeight; i++)
00466 {
00467 aString = "widget_add Menu menuWidget";
00468 aString += QString::number (i);
00469 aString += " string";
00470 sendToServer(aString);
00471 }
00472
00473
00474 sendToServer("screen_add Music");
00475 setPriority("Music", LOW);
00476 sendToServer("widget_add Music topWidget1 string");
00477 sendToServer("widget_add Music topWidget2 string");
00478 sendToServer("widget_add Music timeWidget string");
00479 sendToServer("widget_add Music infoWidget string");
00480 sendToServer("widget_add Music progressBar hbar");
00481
00482
00483 sendToServer("screen_add Channel");
00484 setPriority("Channel", LOW);
00485 sendToServer("widget_add Channel topWidget string");
00486 sendToServer("widget_add Channel botWidget string");
00487 sendToServer("widget_add Channel timeWidget string");
00488 sendToServer("widget_add Channel progressBar hbar");
00489
00490
00491 sendToServer("screen_add Generic");
00492 setPriority("Generic", LOW);
00493 sendToServer("widget_add Generic textWidget1 string");
00494 sendToServer("widget_add Generic textWidget2 string");
00495 sendToServer("widget_add Generic textWidget3 string");
00496 sendToServer("widget_add Generic textWidget4 string");
00497 sendToServer("widget_add Generic progressBar hbar");
00498
00499
00500 sendToServer("screen_add Volume");
00501 setPriority("Volume", LOW);
00502 sendToServer("widget_add Volume topWidget string");
00503 sendToServer("widget_add Volume botWidget string");
00504 sendToServer("widget_add Volume progressBar hbar");
00505
00506
00507 sendToServer("screen_add RecStatus");
00508 setPriority("RecStatus", LOW);
00509 sendToServer("widget_add RecStatus textWidget1 string");
00510 sendToServer("widget_add RecStatus textWidget2 string");
00511 sendToServer("widget_add RecStatus textWidget3 string");
00512 sendToServer("widget_add RecStatus textWidget4 string");
00513 sendToServer("widget_add RecStatus progressBar hbar");
00514
00515 lcd_ready = true;
00516 loadSettings();
00517
00518
00519 switchToTime();
00520
00521 updateRecordingList();
00522
00523
00524 if (!startup_message.isEmpty())
00525 showStartupMessage();
00526
00527
00528 if (send_buffer.length() > 0)
00529 {
00530 sendToServer(send_buffer);
00531 send_buffer = "";
00532 }
00533 }
00534
00535 QString LCDProcClient::expandString(const QString &aString)
00536 {
00537 if (pVersion != LCD_VERSION_5)
00538 return aString;
00539
00540 QString bString;
00541
00542
00543 for (int x = 0; x < aString.length(); x++)
00544 {
00545 bString += aString.at(x) + QString(" ");
00546 }
00547
00548 return bString;
00549 }
00550
00551 void LCDProcClient::loadSettings()
00552 {
00553 if (!lcd_ready)
00554 return;
00555
00556 QString aString;
00557 QString old_keystring = lcd_keystring;
00558
00559 timeformat = gCoreContext->GetSetting("LCDTimeFormat", "");
00560 if (timeformat.isEmpty())
00561 timeformat = gCoreContext->GetSetting("TimeFormat", "h:mm AP");
00562
00563 dateformat = gCoreContext->GetSetting("DateFormat", "dd.MM.yyyy");
00564
00565
00566 lcd_showmusic=(gCoreContext->GetSetting("LCDShowMusic", "1")=="1");
00567 lcd_showmusic_items=(gCoreContext->GetSetting("LCDShowMusicItems", "ArtistAlbumTitle"));
00568 lcd_showtime=(gCoreContext->GetSetting("LCDShowTime", "1")=="1");
00569 lcd_showchannel=(gCoreContext->GetSetting("LCDShowChannel", "1")=="1");
00570 lcd_showgeneric=(gCoreContext->GetSetting("LCDShowGeneric", "1")=="1");
00571 lcd_showvolume=(gCoreContext->GetSetting("LCDShowVolume", "1")=="1");
00572 lcd_showmenu=(gCoreContext->GetSetting("LCDShowMenu", "1")=="1");
00573 lcd_showrecstatus=(gCoreContext->GetSetting("LCDShowRecStatus", "1")=="1");
00574 lcd_backlighton=(gCoreContext->GetSetting("LCDBacklightOn", "1")=="1");
00575 lcd_heartbeaton=(gCoreContext->GetSetting("LCDHeartBeatOn", "1")=="1");
00576 aString = gCoreContext->GetSetting("LCDPopupTime", "5");
00577 lcd_popuptime = aString.toInt() * 1000;
00578 lcd_bigclock = (gCoreContext->GetSetting("LCDBigClock", "1")=="1");
00579 lcd_keystring = gCoreContext->GetSetting("LCDKeyString", "ABCDEF");
00580
00581 if (!old_keystring.isEmpty())
00582 {
00583 aString = "client_del_key " + expandString(old_keystring);
00584 sendToServer(aString);
00585 }
00586
00587 aString = "client_add_key " + expandString(lcd_keystring);
00588 sendToServer(aString);
00589
00590 setHeartbeat ("Time", lcd_heartbeaton);
00591 if (lcd_backlighton)
00592 sendToServer("screen_set Time backlight on");
00593 else
00594 sendToServer("screen_set Time backlight off");
00595
00596 setHeartbeat ("Menu", lcd_heartbeaton);
00597 sendToServer("screen_set Menu backlight on");
00598
00599 setHeartbeat ("Music", lcd_heartbeaton);
00600 sendToServer("screen_set Music backlight on");
00601
00602 setHeartbeat ("Channel", lcd_heartbeaton);
00603 sendToServer("screen_set Channel backlight on");
00604
00605 setHeartbeat ("Generic", lcd_heartbeaton);
00606 sendToServer("screen_set Generic backlight on");
00607
00608 setHeartbeat ("Volume", lcd_heartbeaton);
00609 sendToServer("screen_set Volume backlight on");
00610
00611 setHeartbeat ("RecStatus", lcd_heartbeaton);
00612 sendToServer("screen_set RecStatus backlight on");
00613 }
00614
00615 void LCDProcClient::showStartupMessage(void)
00616 {
00617 QList<LCDTextItem> textItems;
00618
00619 QStringList list = formatScrollerText(startup_message);
00620
00621 int startrow = 1;
00622 if (list.count() < (int)lcdHeight)
00623 startrow = ((lcdHeight - list.count()) / 2) + 1;
00624
00625 for (int x = 0; x < list.count(); x++)
00626 {
00627 if (x == (int)lcdHeight)
00628 break;
00629 textItems.append(LCDTextItem(x + startrow, ALIGN_LEFT, list[x],
00630 "Generic", false));
00631 }
00632
00633 switchToGeneric(&textItems);
00634
00635 showMessageTimer->start(startup_showtime * 1000);
00636 }
00637
00638 void LCDProcClient::removeStartupMessage(void)
00639 {
00640 switchToTime();
00641 }
00642
00643 void LCDProcClient::setStartupMessage(QString msg, uint messagetime)
00644 {
00645 startup_message = msg;
00646 startup_showtime = messagetime;
00647 }
00648
00649 void LCDProcClient::setWidth(unsigned int x)
00650 {
00651 if (x < 1 || x > 80)
00652 return;
00653 else
00654 lcdWidth = x;
00655 }
00656
00657 void LCDProcClient::setHeight(unsigned int x)
00658 {
00659 if (x < 1 || x > 80)
00660 return;
00661 else
00662 lcdHeight = x;
00663 }
00664
00665 void LCDProcClient::setCellWidth(unsigned int x)
00666 {
00667 if (x < 1 || x > 16)
00668 return;
00669 else
00670 cellWidth = x;
00671 }
00672
00673 void LCDProcClient::setCellHeight(unsigned int x)
00674 {
00675 if (x < 1 || x > 16)
00676 return;
00677 else
00678 cellHeight = x;
00679 }
00680
00681 void LCDProcClient::setVersion(const QString &sversion, const QString &pversion)
00682 {
00683 protocolVersion = pversion;
00684 serverVersion = sversion;
00685
00686
00687
00688
00689 if (serverVersion.startsWith ("CVS-current") ||
00690 serverVersion.startsWith ("0.5"))
00691 {
00692
00693 pVersion = LCD_VERSION_5;
00694 prioTop = "input";
00695 prioUrgent = "alert";
00696 prioHigh = "foreground";
00697 prioMedium = "info";
00698 prioLow = "background";
00699 prioOff = "hidden";
00700 }
00701 else
00702 {
00703 pVersion = LCD_VERSION_4;
00704 prioTop = "64";
00705 prioUrgent = "128";
00706 prioHigh = "240";
00707 prioMedium = "248";
00708 prioLow = "252";
00709 prioOff = "255";
00710 }
00711 }
00712
00713 void LCDProcClient::describeServer()
00714 {
00715 if (debug_level > 0)
00716 {
00717 LOG(VB_GENERAL, LOG_INFO,
00718 QString("LCDProcClient: The server is %1x%2 with each cell "
00719 "being %3x%4.")
00720 .arg(lcdWidth).arg(lcdHeight).arg(cellWidth).arg(cellHeight));
00721 LOG(VB_GENERAL, LOG_INFO,
00722 QString("LCDProcClient: LCDd version %1, protocol version %2.")
00723 .arg(serverVersion).arg(protocolVersion));
00724 }
00725
00726 if (debug_level > 1)
00727 {
00728 LOG(VB_GENERAL, LOG_INFO,
00729 QString("LCDProcClient: MythTV LCD settings:"));
00730 LOG(VB_GENERAL, LOG_INFO,
00731 QString("LCDProcClient: - showmusic : %1")
00732 .arg(lcd_showmusic));
00733 LOG(VB_GENERAL, LOG_INFO,
00734 QString("LCDProcClient: - showmusicitems : %1")
00735 .arg(lcd_showmusic_items));
00736 LOG(VB_GENERAL, LOG_INFO,
00737 QString("LCDProcClient: - showtime : %1")
00738 .arg(lcd_showtime));
00739 LOG(VB_GENERAL, LOG_INFO,
00740 QString("LCDProcClient: - showchannel : %1")
00741 .arg(lcd_showchannel));
00742 LOG(VB_GENERAL, LOG_INFO,
00743 QString("LCDProcClient: - showrecstatus : %1")
00744 .arg(lcd_showrecstatus));
00745 LOG(VB_GENERAL, LOG_INFO,
00746 QString("LCDProcClient: - showgeneric : %1")
00747 .arg(lcd_showgeneric));
00748 LOG(VB_GENERAL, LOG_INFO,
00749 QString("LCDProcClient: - showvolume : %1")
00750 .arg(lcd_showvolume));
00751 LOG(VB_GENERAL, LOG_INFO,
00752 QString("LCDProcClient: - showmenu : %1")
00753 .arg(lcd_showmenu));
00754 LOG(VB_GENERAL, LOG_INFO,
00755 QString("LCDProcClient: - backlighton : %1")
00756 .arg(lcd_backlighton));
00757 LOG(VB_GENERAL, LOG_INFO,
00758 QString("LCDProcClient: - heartbeaton : %1")
00759 .arg(lcd_heartbeaton));
00760 LOG(VB_GENERAL, LOG_INFO,
00761 QString("LCDProcClient: - popuptime : %1")
00762 .arg(lcd_popuptime));
00763 }
00764 }
00765
00766 void LCDProcClient::veryBadThings(QAbstractSocket::SocketError error)
00767 {
00768
00769 LOG(VB_GENERAL, LOG_ERR, QString("Could not connect to LCDd: %1")
00770 .arg(socket->errorString()));
00771 socket->close();
00772 }
00773
00774 void LCDProcClient::scrollList()
00775 {
00776 if (scrollListItems.count() == 0)
00777 return;
00778
00779 if (activeScreen != scrollListScreen)
00780 return;
00781
00782 outputLeftText(scrollListScreen, scrollListItems[scrollListItem],
00783 scrollListWidget, scrollListRow);
00784
00785 scrollListItem++;
00786 if ((int)scrollListItem >= scrollListItems.count())
00787 scrollListItem = 0;
00788 }
00789
00790 void LCDProcClient::stopAll()
00791 {
00792
00793
00794
00795 if (debug_level > 1)
00796 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: stopAll");
00797
00798 if (lcd_ready)
00799 {
00800 setPriority("Time", OFF);
00801 setPriority("Music", OFF);
00802 setPriority("Channel", OFF);
00803 setPriority("Generic", OFF);
00804 setPriority("Volume", OFF);
00805 setPriority("Menu", OFF);
00806 setPriority("RecStatus", OFF);
00807 }
00808
00809 timeTimer->stop();
00810 preScrollWTimer->stop();
00811 scrollWTimer->stop();
00812 popMenuTimer->stop();
00813 menuScrollTimer->stop();
00814 menuPreScrollTimer->stop();
00815 recStatusTimer->stop();
00816 scrollListTimer->stop();
00817
00818 unPopMenu();
00819 }
00820
00821 void LCDProcClient::startTime()
00822 {
00823 setPriority("Time", MEDIUM);
00824 setPriority("RecStatus", LOW);
00825
00826 timeTimer->start(1000);
00827 outputTime();
00828 activeScreen = "Time";
00829 isTimeVisible = true;
00830
00831 if (lcd_showrecstatus && isRecording)
00832 recStatusTimer->start(LCD_TIME_TIME);
00833 }
00834
00835 void LCDProcClient::outputText(QList<LCDTextItem> *textItems)
00836 {
00837 if (!lcd_ready)
00838 return;
00839
00840 QList<LCDTextItem>::iterator it = textItems->begin();
00841 LCDTextItem *curItem;
00842 QString num;
00843 unsigned int counter = 1;
00844
00845
00846
00847
00848 while (it != textItems->end() && counter < lcdHeight)
00849 {
00850 curItem = &(*it);
00851 ++it;
00852 num.setNum(curItem->getRow());
00853
00854 if (curItem->getScroll())
00855 assignScrollingWidgets(curItem->getText(), curItem->getScreen(),
00856 "textWidget" + num, curItem->getRow());
00857 else
00858 {
00859 switch (curItem->getAlignment())
00860 {
00861 case ALIGN_LEFT:
00862 outputLeftText(curItem->getScreen(), curItem->getText(),
00863 "textWidget" + num, curItem->getRow());
00864 break;
00865 case ALIGN_RIGHT:
00866 outputRightText(curItem->getScreen(), curItem->getText(),
00867 "textWidget" + num, curItem->getRow());
00868 break;
00869 case ALIGN_CENTERED:
00870 outputCenteredText(curItem->getScreen(), curItem->getText(),
00871 "textWidget" + num, curItem->getRow());
00872 break;
00873 default: break;
00874 }
00875 }
00876
00877 ++counter;
00878 }
00879 }
00880
00881 void LCDProcClient::outputCenteredText(QString theScreen, QString theText, QString widget,
00882 int row)
00883 {
00884 QString aString;
00885 unsigned int x = 0;
00886
00887 x = (lcdWidth - theText.length()) / 2 + 1;
00888
00889 if (x > lcdWidth)
00890 x = 1;
00891
00892 aString = "widget_set ";
00893 aString += theScreen;
00894 aString += " " + widget + " ";
00895 aString += QString::number(x);
00896 aString += " ";
00897 aString += QString::number(row);
00898 aString += " \"";
00899 aString += theText.replace ('"', "\"");
00900 aString += "\"";
00901 sendToServer(aString);
00902 }
00903
00904 void LCDProcClient::outputLeftText(QString theScreen, QString theText, QString widget,
00905 int row)
00906 {
00907 QString aString;
00908 aString = "widget_set ";
00909 aString += theScreen;
00910 aString += " " + widget + " 1 ";
00911 aString += QString::number(row);
00912 aString += " \"";
00913 aString += theText.replace ('"', "\"");
00914 aString += "\"";
00915 sendToServer(aString);
00916 }
00917
00918 void LCDProcClient::outputRightText(QString theScreen, QString theText, QString widget,
00919 int row)
00920 {
00921 QString aString;
00922 unsigned int x;
00923
00924 x = (int)(lcdWidth - theText.length()) + 1;
00925
00926 aString = "widget_set ";
00927 aString += theScreen;
00928 aString += " " + widget + " ";
00929 aString += QString::number(x);
00930 aString += " ";
00931 aString += QString::number(row);
00932 aString += " \"";
00933 aString += theText.replace ('"', "\"");
00934 aString += "\"";
00935 sendToServer(aString);
00936 }
00937
00938 void LCDProcClient::assignScrollingList(QStringList theList, QString theScreen,
00939 QString theWidget, int theRow)
00940 {
00941 scrollListScreen = theScreen;
00942 scrollListWidget = theWidget;
00943 scrollListRow = theRow;
00944 scrollListItems = theList;
00945
00946 scrollListItem = 0;
00947 scrollList();
00948 scrollListTimer->start(LCD_SCROLLLIST_TIME);
00949 }
00950
00951
00952
00953
00954
00955
00956
00957
00958 void LCDProcClient::assignScrollingWidgets(QString theText, QString theScreen,
00959 QString theWidget, int theRow)
00960 {
00961 scrollScreen = theScreen;
00962
00963
00964 lcdTextItems->append(LCDTextItem(theRow, ALIGN_LEFT, theText,
00965 theScreen, true, theWidget));
00966 }
00967
00968 void LCDProcClient::formatScrollingWidgets()
00969 {
00970 scrollWTimer->stop();
00971 preScrollWTimer->stop();
00972
00973 if (lcdTextItems->isEmpty())
00974 return;
00975
00976 int max_len = 0;
00977 QList<LCDTextItem>::iterator it = lcdTextItems->begin();
00978 LCDTextItem *curItem;
00979
00980
00981 for(; it != lcdTextItems->end(); ++it)
00982 {
00983 curItem = &(*it);
00984 if (curItem->getText().length() > max_len)
00985 max_len = curItem->getText().length();
00986 }
00987
00988
00989 it = lcdTextItems->begin();
00990 while (it != lcdTextItems->end())
00991 {
00992 curItem = &(*it);
00993 ++it;
00994 if (curItem->getText().length() > (int)lcdWidth)
00995 {
00996 QString temp, temp2;
00997 temp = temp.fill(QChar(' '), max_len - curItem->getText().length());
00998 temp2 = temp2.fill(QChar(' '), lcdWidth);
00999 curItem->setText(temp2 + curItem->getText() + temp);
01000 outputLeftText(scrollScreen,
01001 curItem->getText().mid(lcdWidth, max_len),
01002 curItem->getWidget(), curItem->getRow());
01003 }
01004 else
01005 {
01006 curItem->setScrollable(false);
01007 outputCenteredText(scrollScreen, curItem->getText(),
01008 curItem->getWidget(), curItem->getRow());
01009 }
01010 }
01011
01012 if (max_len <= (int)lcdWidth)
01013
01014 return;
01015
01016 preScrollWTimer->start(2000);
01017 }
01018
01019 void LCDProcClient::beginScrollingWidgets()
01020 {
01021 scrollPosition = lcdWidth;
01022 preScrollWTimer->stop();
01023 scrollWTimer->start(400);
01024 }
01025
01026 void LCDProcClient::scrollWidgets()
01027 {
01028 if (activeScreen != scrollScreen)
01029 return;
01030
01031 if (lcdTextItems->isEmpty())
01032 return;
01033
01034 QList<LCDTextItem>::iterator it = lcdTextItems->begin();
01035 LCDTextItem *curItem;
01036
01037 unsigned int len = 0;
01038 for(; it != lcdTextItems->end(); ++it)
01039 {
01040 curItem = &(*it);
01041 if (curItem->getScroll())
01042 {
01043
01044 len = curItem->getText().length();
01045
01046 outputLeftText(scrollScreen,
01047 curItem->getText().mid(scrollPosition, lcdWidth),
01048 curItem->getWidget(), curItem->getRow());
01049 }
01050 }
01051
01052 if (len == 0)
01053 {
01054
01055 LOG(VB_GENERAL, LOG_ERR,
01056 "LCDProcClient::scrollWidgets called without scrollable items");
01057 scrollWTimer->stop();
01058 return;
01059 }
01060 scrollPosition++;
01061 if (scrollPosition >= len)
01062 scrollPosition = lcdWidth;
01063 }
01064
01065 void LCDProcClient::startMusic(QString artist, QString album, QString track)
01066 {
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077
01078
01079
01080
01081
01082
01083
01084
01085 sendToServer("widget_set Music progressBar 1 1 0");
01086 sendToServer("widget_set Music timeWidget 1 1 \"\"");
01087 lcdTextItems->clear();
01088
01089 QString aString;
01090 music_progress = 0.0f;
01091 aString = artist;
01092 if (lcd_showmusic_items == "ArtistAlbumTitle")
01093 {
01094 aString += " [";
01095 aString += album;
01096 aString += "] ";
01097 }
01098 else if (lcdHeight < 4)
01099 {
01100 aString += " - ";
01101 }
01102
01103 if (lcdHeight < 4)
01104 {
01105 aString += track;
01106 }
01107 else
01108 {
01109 assignScrollingWidgets(track, "Music", "topWidget2", 2);
01110 }
01111 assignScrollingWidgets(aString, "Music", "topWidget1", 1);
01112 formatScrollingWidgets();
01113
01114
01115
01116 activeScreen = "Music";
01117 if (lcd_showmusic)
01118 setPriority("Music", HIGH);
01119 }
01120
01121 void LCDProcClient::startChannel(QString channum, QString title, QString subtitle)
01122 {
01123 QString aString;
01124
01125 if (lcd_showchannel)
01126 setPriority("Channel", HIGH);
01127
01128 activeScreen = "Channel";
01129
01130 if (lcdHeight <= 2)
01131 {
01132 aString = channum + "|" + title;
01133 if (!subtitle.isEmpty())
01134 aString += "|" + subtitle;
01135 QStringList list = formatScrollerText(aString);
01136 assignScrollingList(list, "Channel", "topWidget", 1);
01137 }
01138 else
01139 {
01140 aString = channum;
01141 lcdTextItems->clear();
01142 assignScrollingWidgets(aString, "Channel", "topWidget", 1);
01143 aString = title;
01144 if (subtitle.length() > 0)
01145 {
01146 aString += " - '";
01147 aString += subtitle;
01148 aString += "'";
01149 }
01150 assignScrollingWidgets(aString, "Channel", "botWidget", 2);
01151 formatScrollingWidgets();
01152 }
01153
01154 channel_time = "";
01155 progress = 0.0;
01156 outputChannel();
01157 }
01158
01159 void LCDProcClient::startGeneric(QList<LCDTextItem> *textItems)
01160 {
01161 QList<LCDTextItem>::iterator it = textItems->begin();
01162 LCDTextItem *curItem = &(*it);
01163
01164 QString aString;
01165
01166 if (lcd_showgeneric)
01167 setPriority("Generic", TOP);
01168
01169
01170
01171 outputLeftText("Generic", "", "textWidget1", 1);
01172 outputLeftText("Generic", "", "textWidget2", 2);
01173 outputLeftText("Generic", "", "textWidget3", 3);
01174
01175
01176 if (textItems->isEmpty())
01177 return;
01178
01179 activeScreen = "Generic";
01180
01181 busy_progress = false;
01182 busy_pos = 1;
01183 busy_direction = 1;
01184 busy_indicator_size = 2.0f;
01185 generic_progress = 0.0;
01186
01187
01188 if (textItems->isEmpty())
01189 return;
01190
01191
01192 ++it;
01193
01194
01195
01196
01197
01198
01199
01200
01201
01202 lcdTextItems->clear();
01203 assignScrollingWidgets(curItem->getText(), "Generic",
01204 "textWidget1", curItem->getRow());
01205
01206 outputGeneric();
01207
01208
01209 textItems->removeFirst();
01210 if (!textItems->isEmpty())
01211 outputText(textItems);
01212 formatScrollingWidgets();
01213 }
01214
01215 void LCDProcClient::startMenu(QList<LCDMenuItem> *menuItems, QString app_name,
01216 bool popMenu)
01217 {
01218
01219 if (menuItems->isEmpty())
01220 return;
01221
01222 QString aString;
01223
01224
01225 menuScrollTimer->stop();
01226
01227
01228 if (lcd_showmenu)
01229 setPriority("Menu", URGENT);
01230
01231
01232 if (lcdHeight > 1)
01233 outputCenteredText("Menu", app_name, "topWidget", 1);
01234
01235 QList<LCDMenuItem>::iterator it = menuItems->begin();
01236 LCDMenuItem *curItem;
01237
01238
01239
01240 unsigned int selectedItem = 0;
01241 unsigned int counter = 0;
01242 bool oneSelected = false;
01243
01244 while (it != menuItems->end())
01245 {
01246 curItem = &(*it);
01247 ++it;
01248 if (curItem->isSelected() && !oneSelected)
01249 {
01250 selectedItem = counter + 1;
01251 oneSelected = true;
01252 break;
01253 }
01254 ++counter;
01255 }
01256
01257
01258 if (!oneSelected)
01259 {
01260 sendToServer("widget_set Menu topWidget 1 1 \"No menu item selected\"");
01261 sendToServer("widget_set Menu menuWidget1 1 2 \" ABORTING \"");
01262 menuScrollTimer->stop();
01263 return;
01264 }
01265
01266 popMenuTimer->stop();
01267
01268 if (popMenu)
01269 popMenuTimer->start(lcd_popuptime);
01270
01271
01272
01273 QList<LCDMenuItem>::iterator itTemp = menuItems->begin();
01274 lcdMenuItems->clear();
01275 counter = 1;
01276 while (itTemp != menuItems->end())
01277 {
01278 curItem = &(*itTemp);
01279 ++itTemp;
01280 lcdMenuItems->append(LCDMenuItem(curItem->isSelected(),
01281 curItem->isChecked(), curItem->ItemName(),
01282 curItem->getIndent()));
01283 ++counter;
01284 }
01285
01286
01287
01288 if (lcdHeight <= 2)
01289 {
01290 it = menuItems->begin();
01291 while (it != menuItems->end())
01292 {
01293 curItem = &(*it);
01294 ++it;
01295 if (curItem->isSelected())
01296 {
01297
01298 if (curItem->ItemName().length() > (int)(lcdWidth - lcdStartCol))
01299 {
01300 menuPreScrollTimer->setSingleShot(true);
01301 menuPreScrollTimer->start(2000);
01302 curItem->setScroll(true);
01303 }
01304 else
01305 {
01306 menuPreScrollTimer->stop();
01307 curItem->setScroll(false);
01308 }
01309 if (lcdHeight == 2)
01310 {
01311 aString = "widget_set Menu menuWidget1 1 2 \">";
01312 }
01313 else
01314 {
01315 aString = "widget_set Menu menuWidget1 1 1 \"";
01316 }
01317
01318 if (lcdStartCol == 1)
01319 {
01320 switch (curItem->isChecked())
01321 {
01322 case CHECKED: aString += "X "; break;
01323 case UNCHECKED: aString += "O "; break;
01324 case NOTCHECKABLE: aString += " "; break;
01325 default: break;
01326 }
01327 }
01328 else if (lcdStartCol != 0)
01329 {
01330 switch (curItem->isChecked())
01331 {
01332 case CHECKED: aString += "X "; break;
01333 case UNCHECKED: aString += "O "; break;
01334 case NOTCHECKABLE: aString += " "; break;
01335 default: break;
01336 }
01337 }
01338
01339 aString += curItem->ItemName().left(lcdWidth - lcdStartCol) +
01340 "\"";
01341 sendToServer(aString);
01342 return;
01343 }
01344 }
01345
01346 return;
01347 }
01348
01349
01350 counter = 1;
01351 it = menuItems->begin();
01352
01353
01354 unsigned int midPoint = (lcdHeight/2) - 1;
01355 if (selectedItem > midPoint && menuItems->size() >= (int)lcdHeight-1)
01356 {
01357 while (counter != selectedItem)
01358 {
01359 ++it;
01360 ++counter;
01361 }
01362 it -= midPoint;
01363 counter -= midPoint;
01364 }
01365
01366
01367
01368 if (counter + midPoint > menuItems->size() - midPoint && counter > midPoint)
01369 {
01370 it -= (counter + (lcdHeight / 2) - 1) - (menuItems->size() - midPoint);
01371 }
01372
01373 counter = 1;
01374 while (it != menuItems->end())
01375 {
01376 curItem = &(*it);
01377
01378 if ((counter + 1) > lcdHeight)
01379 break;
01380
01381 ++it;
01382
01383 aString = "widget_set Menu menuWidget";
01384 aString += QString::number(counter) + " 1 ";
01385 aString += QString::number(counter + 1) + " \"";
01386
01387 if (curItem->isSelected())
01388 aString += ">";
01389 else
01390 aString += " ";
01391
01392 switch (curItem->isChecked())
01393 {
01394 case CHECKED: aString += "X "; break;
01395 case UNCHECKED: aString += "O "; break;
01396 case NOTCHECKABLE: aString += " "; break;
01397 default: break;
01398 }
01399
01400 aString += curItem->ItemName().left(lcdWidth - lcdStartCol) + "\"";
01401 sendToServer(aString);
01402
01403 ++counter;
01404 }
01405
01406
01407 while (counter < lcdHeight)
01408 {
01409 aString = "widget_set Menu menuWidget";
01410 aString += QString::number(counter) + " 1 ";
01411 aString += QString::number(counter + 1) + " \"\"";
01412 sendToServer(aString);
01413
01414 ++counter;
01415 }
01416
01417 menuPreScrollTimer->setSingleShot(true);
01418 menuPreScrollTimer->start(2000);
01419 }
01420
01421 void LCDProcClient::beginScrollingMenuText()
01422 {
01423
01424
01425
01426 if (!lcdMenuItems)
01427 return;
01428
01429 menuScrollPosition = 1;
01430
01431 QList<LCDMenuItem>::iterator it = lcdMenuItems->begin();
01432 LCDMenuItem *curItem;
01433
01434 QString temp;
01435
01436
01437 while (it != lcdMenuItems->end())
01438 {
01439 curItem = &(*it);
01440 ++it;
01441
01442
01443 if (curItem->ItemName().length() > (int)(lcdWidth - lcdStartCol))
01444 {
01445 temp = temp.fill(QChar(' '), lcdWidth - curItem->getIndent() -
01446 lcdStartCol);
01447 curItem->setItemName(temp + curItem->ItemName());
01448 curItem->setScrollPos(curItem->getIndent() + temp.length());
01449 curItem->setScroll(true);
01450 }
01451 else
01452 curItem->setScroll(false);
01453 }
01454
01455
01456 menuScrollTimer->stop();
01457 menuScrollTimer->start(250);
01458 }
01459
01460 void LCDProcClient::scrollMenuText()
01461 {
01462 if (!lcdMenuItems)
01463 return;
01464
01465 QString aString, bString;
01466 QList<LCDMenuItem>::iterator it = lcdMenuItems->begin();
01467 LCDMenuItem *curItem;
01468
01469 ++menuScrollPosition;
01470
01471
01472
01473 unsigned int selectedItem = 0;
01474 unsigned int counter = 0;
01475 bool oneSelected = false;
01476
01477 while (it != lcdMenuItems->end())
01478 {
01479 curItem = &(*it);
01480 ++it;
01481 if (curItem->isSelected() && !oneSelected)
01482 {
01483 selectedItem = counter + 1;
01484 oneSelected = true;
01485 break;
01486 }
01487 ++counter;
01488 }
01489
01490
01491
01492 it = lcdMenuItems->begin();
01493 if (lcdHeight <= 2)
01494 {
01495 while (it != lcdMenuItems->end())
01496 {
01497 curItem = &(*it);
01498 ++it;
01499 if (curItem->isSelected())
01500 {
01501 curItem->incrementScrollPos();
01502 if ((int)curItem->getScrollPos() > curItem->ItemName().length())
01503 {
01504
01505 menuScrollTimer->stop();
01506 menuScrollTimer->start(500);
01507 curItem->setScrollPos(curItem->getIndent());
01508 }
01509
01510
01511
01512
01513 if (curItem->ItemName().length() < (int)(lcdWidth - lcdStartCol))
01514 menuScrollTimer->stop();
01515
01516 if (lcdHeight == 2)
01517 {
01518 aString = "widget_set Menu menuWidget1 1 2 \">";
01519 }
01520 else
01521 {
01522 aString = "widget_set Menu menuWidget1 1 1 \"";
01523 }
01524
01525 if (lcdWidth < 12)
01526 {
01527 switch(curItem->isChecked())
01528 {
01529 case CHECKED: aString += "X"; break;
01530 case UNCHECKED: aString += "O"; break;
01531 case NOTCHECKABLE: aString += ""; break;
01532 default: break;
01533 }
01534 }
01535 else
01536 {
01537 switch(curItem->isChecked())
01538 {
01539 case CHECKED: aString += "X "; break;
01540 case UNCHECKED: aString += "O "; break;
01541 case NOTCHECKABLE: aString += " "; break;
01542 default: break;
01543 }
01544 }
01545
01546
01547 aString += bString.fill(' ', curItem->getIndent());
01548
01549 aString += curItem->ItemName().mid(curItem->getScrollPos(),
01550 (lcdWidth - lcdStartCol));
01551 aString += "\"";
01552 sendToServer(aString);
01553 return;
01554 }
01555 }
01556
01557 return;
01558 }
01559
01560
01561
01562 it = lcdMenuItems->begin();
01563 int longest_line = 0;
01564 int max_scroll_pos = 0;
01565
01566 while (it != lcdMenuItems->end())
01567 {
01568 curItem = &(*it);
01569 ++it;
01570 if (curItem->ItemName().length() > longest_line)
01571 longest_line = curItem->ItemName().length();
01572
01573 if ((int)curItem->getScrollPos() > max_scroll_pos)
01574 max_scroll_pos = curItem->getScrollPos();
01575 }
01576
01577
01578 if (max_scroll_pos > longest_line)
01579 {
01580
01581 menuScrollTimer->stop();
01582 menuScrollTimer->start(500);
01583 menuScrollPosition = 0;
01584
01585 it = lcdMenuItems->begin();
01586 while (it != lcdMenuItems->end())
01587 {
01588 curItem = &(*it);
01589 ++it;
01590 curItem->setScrollPos(curItem->getIndent());
01591 }
01592 }
01593
01594
01595 counter = 1;
01596 it = lcdMenuItems->begin();
01597
01598
01599 if (selectedItem != 1 && lcdMenuItems->size() >= (int)lcdHeight)
01600 {
01601 while (counter != selectedItem)
01602 {
01603 ++it;
01604 ++counter;
01605 }
01606 --it;
01607 }
01608
01609
01610
01611 if ((int)counter == lcdMenuItems->size())
01612 --it;
01613
01614 bool stopTimer = true;
01615
01616 counter = 1;
01617 while (it != lcdMenuItems->end() && counter <= lcdHeight)
01618 {
01619 curItem = &(*it);
01620
01621 if ((counter + 1) > lcdHeight)
01622 break;
01623
01624 ++it;
01625
01626 if (curItem->Scroll())
01627 {
01628 stopTimer = false;
01629 aString = "widget_set Menu menuWidget";
01630 aString += QString::number(counter) + " 1 ";
01631 aString += QString::number(counter + 1) + " \"";
01632
01633 if (curItem->isSelected())
01634 aString += ">";
01635 else
01636 aString += " ";
01637
01638 switch (curItem->isChecked())
01639 {
01640 case CHECKED: aString += "X "; break;
01641 case UNCHECKED: aString += "O "; break;
01642 case NOTCHECKABLE: aString += " "; break;
01643 default: break;
01644 }
01645
01646
01647 bString = "";
01648 bString.fill(' ', curItem->getIndent());
01649 aString += bString;
01650
01651
01652 curItem->incrementScrollPos();
01653
01654 if ((int)curItem->getScrollPos() <= longest_line)
01655 aString += curItem->ItemName().mid(curItem->getScrollPos(),
01656 (lcdWidth-lcdStartCol));
01657
01658 aString += "\"";
01659 sendToServer(aString);
01660 }
01661
01662 ++counter;
01663 }
01664
01665
01666 if (stopTimer)
01667 menuScrollTimer->stop();
01668 }
01669
01670 void LCDProcClient::startVolume(QString app_name)
01671 {
01672 if (lcd_showvolume)
01673 setPriority("Volume", TOP);
01674 if (lcdHeight > 1)
01675 outputCenteredText("Volume", "MythTV " + app_name + " Volume");
01676 volume_level = 0.0;
01677
01678 outputVolume();
01679 }
01680
01681 void LCDProcClient::unPopMenu()
01682 {
01683
01684 menuScrollTimer->stop();
01685 setPriority("Menu", OFF);
01686 }
01687
01688 void LCDProcClient::setChannelProgress(const QString &time, float value)
01689 {
01690 if (!lcd_ready)
01691 return;
01692
01693 progress = value;
01694 channel_time = time;
01695
01696 if (progress < 0.0)
01697 progress = 0.0;
01698 else if (progress > 1.0)
01699 progress = 1.0;
01700
01701 outputChannel();
01702 }
01703
01704 void LCDProcClient::setGenericProgress(bool b, float value)
01705 {
01706 if (!lcd_ready)
01707 return;
01708
01709 generic_progress = value;
01710
01711 if (generic_progress < 0.0)
01712 generic_progress = 0.0;
01713 else if (generic_progress > 1.0)
01714 generic_progress = 1.0;
01715
01716
01717
01718 busy_progress = b;
01719 if (busy_progress)
01720 {
01721
01722 if ((busy_pos + busy_direction >
01723 (signed int)lcdWidth - busy_indicator_size) ||
01724 (busy_pos + busy_direction < 1))
01725 {
01726 busy_direction = -busy_direction;
01727 }
01728 busy_pos += busy_direction;
01729 generic_progress = busy_indicator_size / (float)lcdWidth;
01730 }
01731 else
01732 {
01733 busy_pos = 1;
01734 }
01735
01736 outputGeneric();
01737 }
01738
01739 void LCDProcClient::setMusicProgress(QString time, float value)
01740 {
01741 if (!lcd_ready)
01742 return;
01743
01744 music_progress = value;
01745 music_time = time;
01746
01747 if (music_progress < 0.0)
01748 music_progress = 0.0;
01749 else if (music_progress > 1.0)
01750 music_progress = 1.0;
01751
01752 outputMusic();
01753 }
01754
01755 void LCDProcClient::setMusicRepeat (int repeat)
01756 {
01757 if (!lcd_ready)
01758 return;
01759
01760 music_repeat = repeat;
01761
01762 outputMusic ();
01763 }
01764
01765 void LCDProcClient::setMusicShuffle (int shuffle)
01766 {
01767 if (!lcd_ready)
01768 return;
01769
01770 music_shuffle = shuffle;
01771
01772 outputMusic ();
01773 }
01774
01775 void LCDProcClient::setVolumeLevel(float value)
01776 {
01777 if (!lcd_ready)
01778 return;
01779
01780 volume_level = value;
01781
01782 if (volume_level < 0.0)
01783 volume_level = 0.0;
01784 if (volume_level > 1.0)
01785 volume_level = 1.0;
01786
01787 outputVolume();
01788 }
01789
01790 void LCDProcClient::updateLEDs(int mask)
01791 {
01792 QString aString;
01793 aString = "output ";
01794 aString += QString::number(mask);
01795 sendToServer(aString);
01796 }
01797
01798 void LCDProcClient::reset()
01799 {
01800 removeWidgets();
01801 loadSettings();
01802 init();
01803 }
01804
01805 void LCDProcClient::dobigclock (bool init)
01806 {
01807 QString aString;
01808 QString time = QTime::currentTime().toString(timeformat);
01809 int toffset = 0;
01810 int xoffset = 0;
01811
01812
01813
01814
01815
01816
01817
01818
01819 if ((time.length() == 8) || (time.length() == 5))
01820 toffset = 1;
01821
01822
01823 if (time.length() > 6)
01824 {
01825 aString = time.at(5 + toffset);
01826 aString += time.at(6 + toffset);
01827 xoffset = 1;
01828 }
01829 else
01830 {
01831 aString = " ";
01832 }
01833 outputRightText("Time", aString, "ampm", lcdHeight - 1);
01834
01835 if (isRecording)
01836 {
01837 outputLeftText("Time","R","rec1",1);
01838 outputLeftText("Time","E","rec2",2);
01839 outputLeftText("Time","C","rec3",3);
01840 aString = QString::number((int) tunerList.size());
01841 outputLeftText("Time",aString,"recCnt",4);
01842
01843 }
01844 else
01845 {
01846 outputLeftText("Time"," ","rec1",1);
01847 outputLeftText("Time"," ","rec2",2);
01848 outputLeftText("Time"," ","rec3",3);
01849 outputLeftText("Time"," ","recCnt",4);
01850 }
01851
01852
01853 aString = "widget_set Time d0 ";
01854 aString += QString::number(lcdWidth/2 - 5 - xoffset) + " ";
01855 if (toffset == 0)
01856 aString += "11";
01857 else
01858 aString += time.at(0);
01859 sendToServer(aString);
01860
01861
01862 aString = "widget_set Time d1 ";
01863 aString += QString::number(lcdWidth/2 - 2 - xoffset) + " ";
01864 aString += time.at(0 + toffset);
01865 sendToServer(aString);
01866
01867
01868 aString = "widget_set Time sep ";
01869 aString += QString::number(lcdWidth/2 + 1 - xoffset);
01870 aString += " 10";
01871 sendToServer(aString);
01872
01873
01874 aString = "widget_set Time d2 ";
01875 aString += QString::number(lcdWidth/2 + 2 - xoffset) + " ";
01876 aString += time.at(2 + toffset);
01877 sendToServer(aString);
01878
01879
01880 aString = "widget_set Time d3 ";
01881 aString += QString::number(lcdWidth/2 + 5 - xoffset) + " ";
01882 aString += time.at(3 + toffset);
01883 sendToServer(aString);
01884
01885
01886 if (timeFlash)
01887 {
01888 outputRightText("Time", ".", "dot", lcdHeight);
01889 timeFlash = false;
01890 }
01891 else
01892 {
01893 outputRightText("Time", " ", "dot", lcdHeight);
01894 timeFlash = true;
01895 }
01896 }
01897
01898 void LCDProcClient::outputTime()
01899 {
01900 if (lcd_bigclock)
01901 dobigclock(0);
01902 else
01903 dostdclock();
01904 }
01905
01906 void LCDProcClient::dostdclock()
01907 {
01908 if (!lcd_showtime)
01909 return;
01910
01911 if (lcd_showrecstatus && isRecording)
01912 outputCenteredText("Time", tr("RECORDING"), "topWidget", 1);
01913 else
01914 outputCenteredText("Time", QDate::currentDate().toString(dateformat), "topWidget", 1);
01915
01916 QString aString;
01917 int x, y;
01918
01919 if (lcdHeight < 3)
01920 y = lcdHeight;
01921 else
01922 y = (int) rint(lcdHeight / 2) + 1;
01923
01924 QString time = QTime::currentTime().toString(timeformat);
01925 x = (lcdWidth - time.length()) / 2 + 1;
01926 aString = "widget_set Time timeWidget ";
01927 aString += QString::number(x);
01928 aString += " ";
01929 aString += QString::number(y);
01930 aString += " \"";
01931 if (lcd_showtime) {
01932 aString += time + "\"";
01933 if (timeFlash)
01934 {
01935 aString = aString.replace(QRegExp(":"), " ");
01936 timeFlash = false;
01937 }
01938 else
01939 timeFlash = true;
01940 }
01941 else
01942 aString += " \"";
01943 sendToServer(aString);
01944 }
01945
01946
01947
01948 void LCDProcClient::outputRecStatus(void)
01949 {
01950 if (!lcd_ready || !isRecording || !lcd_showrecstatus)
01951 return;
01952
01953 int listTime;
01954
01955 if (isTimeVisible || !lcd_showtime)
01956 {
01957
01958 setPriority("RecStatus", MEDIUM);
01959 setPriority("Time", LOW);
01960
01961 timeTimer->stop();
01962 scrollWTimer->stop();
01963 scrollListTimer->stop();
01964 listTime = LCD_RECSTATUS_TIME;
01965 isTimeVisible = false;
01966 activeScreen = "RecStatus";
01967 }
01968 else if (lcdTunerNo > (int) tunerList.size() - 1)
01969 {
01970 lcdTunerNo = 0;
01971
01972
01973 setPriority("Time", MEDIUM);
01974 setPriority("RecStatus", LOW);
01975
01976 timeTimer->start(1000);
01977 scrollWTimer->stop();
01978 scrollListTimer->stop();
01979 recStatusTimer->start(LCD_TIME_TIME);
01980
01981 outputTime();
01982 activeScreen = "Time";
01983 isTimeVisible = true;
01984
01985 return;
01986 }
01987
01988 QString aString, status;
01989 QStringList list;
01990
01991 TunerStatus tuner = tunerList[lcdTunerNo];
01992
01993 scrollListItems.clear();
01994 if (lcdHeight >= 4)
01995 {
01996
01997 status = tr("R ");
01998 status += tuner.channame;
01999 outputLeftText("RecStatus", status, "textWidget1", 1);
02000
02001
02002 status = tr("E ");
02003 status += tuner.title;
02004 outputLeftText("RecStatus", status, "textWidget2", 2);
02005
02006
02007
02008
02009 status = tr("C ");
02010 status += tuner.subtitle;
02011 outputLeftText("RecStatus", status, "textWidget3", 3);
02012
02013
02014
02015
02016 status = tuner.startTime.toString("hh:mm") + "-" +
02017 tuner.endTime.toString("hh:mm");
02018 outputLeftText("RecStatus", status, "textWidget4", 4);
02019
02020 int length = tuner.startTime.secsTo(tuner.endTime);
02021 int delta = tuner.startTime.secsTo(QDateTime::currentDateTime());
02022 double rec_progress = (double) delta / length;
02023
02024 aString = "widget_set RecStatus progressBar 13 ";
02025 aString += QString::number(lcdHeight);
02026 aString += " ";
02027 aString += QString::number((int)rint(rec_progress * (lcdWidth - 13) *
02028 cellWidth));
02029 sendToServer(aString);
02030
02031 listTime = list.count() * LCD_SCROLLLIST_TIME * 2;
02032 }
02033 else
02034 {
02035 status = tr("RECORDING|");
02036 status += tuner.title;
02037 if (!tuner.subtitle.isEmpty())
02038 status += "|(" + tuner.subtitle + ")";
02039
02040 status += "|" + tuner.startTime.toString("hh:mm") + " to " +
02041 tuner.endTime.toString("hh:mm");
02042
02043 list = formatScrollerText(status);
02044 assignScrollingList(list, "RecStatus", "textWidget1", 1);
02045
02046 if (lcdHeight > 1)
02047 {
02048 int length = tuner.startTime.secsTo(tuner.endTime);
02049 int delta = tuner.startTime.secsTo(QDateTime::currentDateTime());
02050 double rec_progress = (double) delta / length;
02051
02052 aString = "widget_set RecStatus progressBar 1 ";
02053 aString += QString::number(lcdHeight);
02054 aString += " ";
02055 aString += QString::number((int)rint(rec_progress * lcdWidth *
02056 cellWidth));
02057 sendToServer(aString);
02058 }
02059 else
02060 sendToServer("widget_set RecStatus progressBar 1 1 0");
02061
02062 listTime = list.count() * LCD_SCROLLLIST_TIME * 2;
02063 }
02064
02065 if (listTime < LCD_TIME_TIME)
02066 listTime = LCD_TIME_TIME;
02067
02068 recStatusTimer->start(listTime);
02069 lcdTunerNo++;
02070 }
02071
02072 void LCDProcClient::outputScrollerText(QString theScreen, QString theText,
02073 QString widget, int top, int bottom)
02074 {
02075 QString aString;
02076 aString = "widget_set " + theScreen + " " + widget;
02077 aString += " 1 ";
02078 aString += QString::number(top) + " ";
02079 aString += QString::number(lcdWidth) + " ";
02080 aString += QString::number(bottom);
02081 aString += " v 8 \"" + theText + "\"";
02082
02083 sendToServer(aString);
02084 }
02085
02086 QStringList LCDProcClient::formatScrollerText(const QString &text)
02087 {
02088 QString separators = " |-_/:('<~";
02089 QStringList lines;
02090
02091 int lastSplit = 0;
02092 QString line = "";
02093
02094 for (int x = 0; x < text.length(); x++)
02095 {
02096 if (separators.contains(text[x]) > 0)
02097 lastSplit = line.length();
02098
02099 line += text[x];
02100 if (line.length() > (int)lcdWidth || text[x] == '|')
02101 {
02102 QString formatedLine;
02103 formatedLine.fill(' ', lcdWidth);
02104 formatedLine = formatedLine.replace((lcdWidth - lastSplit) / 2,
02105 lastSplit, line.left(lastSplit));
02106
02107 lines.append(formatedLine);
02108
02109 if (line[lastSplit] == ' ' || line[lastSplit] == '|')
02110 line = line.mid(lastSplit + 1);
02111 else
02112 line = line.mid(lastSplit);
02113
02114 lastSplit = lcdWidth;
02115 }
02116 }
02117
02118
02119 QString formatedLine;
02120 formatedLine.fill(' ', lcdWidth);
02121 formatedLine = formatedLine.replace((lcdWidth - line.length()) / 2,
02122 line.length(), line);
02123
02124 lines.append(formatedLine);
02125
02126 return lines;
02127 }
02128
02129 void LCDProcClient::outputMusic()
02130 {
02131 int info_width = 0;
02132
02133
02134
02135 outputCenteredText("Music", music_time, "timeWidget",
02136 lcdHeight < 4 ? 2 : 3);
02137
02138 if (lcdHeight > 2)
02139 {
02140 QString aString;
02141 QString shuffle = "";
02142 QString repeat = "";
02143
02144 if (music_shuffle == 1)
02145 {
02146 shuffle = "S:? ";
02147 }
02148 else if (music_shuffle == 2)
02149 {
02150 shuffle = "S:i ";
02151 }
02152 else if (music_shuffle == 3)
02153 {
02154 shuffle = "S:a ";
02155 }
02156
02157 if (music_repeat == 1)
02158 {
02159 repeat = "R:1 ";
02160 }
02161 else if (music_repeat == 2)
02162 {
02163 repeat = "R:* ";
02164 }
02165
02166 if (shuffle.length() != 0 || repeat.length() != 0)
02167 {
02168 aString = shuffle + repeat;
02169 info_width = aString.length();
02170 outputLeftText("Music", aString, "infoWidget", lcdHeight);
02171 }
02172 else
02173 outputLeftText("Music", " ", "infoWidget", lcdHeight);
02174
02175 aString = "widget_set Music progressBar ";
02176 aString += QString::number(info_width + 1);
02177 aString += " ";
02178 aString += QString::number(lcdHeight);
02179 aString += " ";
02180 aString += QString::number((int)rint(music_progress *
02181 (lcdWidth - info_width) * cellWidth));
02182 sendToServer(aString);
02183 }
02184 }
02185
02186 void LCDProcClient::outputChannel()
02187 {
02188 if (lcdHeight > 1)
02189 {
02190 QString aString;
02191 aString = "widget_set Channel progressBar 1 ";
02192 aString += QString::number(lcdHeight);
02193 aString += " ";
02194 aString += QString::number((int)rint(progress * lcdWidth * cellWidth));
02195 sendToServer(aString);
02196
02197 if (lcdHeight >= 4)
02198 outputCenteredText("Channel", channel_time, "timeWidget", 3);
02199 }
02200 else
02201 sendToServer("widget_set Channel progressBar 1 1 0");
02202 }
02203
02204 void LCDProcClient::outputGeneric()
02205 {
02206 if (lcdHeight > 1)
02207 {
02208 QString aString;
02209 aString = "widget_set Generic progressBar ";
02210 aString += QString::number (busy_pos);
02211 aString += " ";
02212 aString += QString::number(lcdHeight);
02213 aString += " ";
02214 aString += QString::number((int)rint(generic_progress * lcdWidth *
02215 cellWidth));
02216 sendToServer(aString);
02217 }
02218 else sendToServer("widget_set Generic progressBar 1 1 0");
02219 }
02220
02221 void LCDProcClient::outputVolume()
02222 {
02223 QString aString;
02224 int line;
02225
02226 if (lcdHeight > 1)
02227 {
02228 aString = "widget_set Volume progressBar 1 ";
02229 aString += QString::number(lcdHeight);
02230 aString += " ";
02231 aString += QString::number((int)rint(volume_level * lcdWidth * cellWidth));
02232 sendToServer(aString);
02233 }
02234
02235 aString = QString::number((int)(volume_level * 100));
02236 aString += "%";
02237
02238 if (lcdHeight > 3)
02239 line = 3;
02240 else
02241 line = lcdHeight;
02242 outputRightText("Volume", aString, "botWidget", line);
02243 }
02244
02245 void LCDProcClient::switchToTime()
02246 {
02247 if (!lcd_ready)
02248 return;
02249
02250 stopAll();
02251
02252 if (debug_level > 1)
02253 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToTime");
02254
02255 startTime();
02256 }
02257
02258 void LCDProcClient::switchToMusic(const QString &artist, const QString &album, const QString &track)
02259 {
02260 if (!lcd_ready)
02261 return;
02262
02263 stopAll();
02264
02265 if (debug_level > 1)
02266 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToMusic") ;
02267
02268 startMusic(artist, album, track);
02269 }
02270
02271 void LCDProcClient::switchToChannel(QString channum, QString title, QString subtitle)
02272 {
02273 if (!lcd_ready)
02274 return;
02275
02276 stopAll();
02277
02278 if (debug_level > 1)
02279 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToChannel");
02280
02281 startChannel(channum, title, subtitle);
02282 }
02283
02284 void LCDProcClient::switchToMenu(QList<LCDMenuItem> *menuItems, QString app_name,
02285 bool popMenu)
02286 {
02287 if (!lcd_ready)
02288 return;
02289
02290 if (debug_level > 1)
02291 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToMenu");
02292
02293 startMenu(menuItems, app_name, popMenu);
02294 }
02295
02296 void LCDProcClient::switchToGeneric(QList<LCDTextItem> *textItems)
02297 {
02298 if (!lcd_ready)
02299 return;
02300 stopAll();
02301
02302 if (debug_level > 1)
02303 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToGeneric");
02304
02305 startGeneric(textItems);
02306 }
02307
02308 void LCDProcClient::switchToVolume(QString app_name)
02309 {
02310 if (!lcd_ready)
02311 return;
02312
02313 stopAll();
02314
02315 if (debug_level > 1)
02316 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToVolume");
02317
02318 startVolume(app_name);
02319 }
02320
02321 void LCDProcClient::switchToNothing()
02322 {
02323 if (!lcd_ready)
02324 return;
02325
02326 stopAll();
02327
02328 if (debug_level > 1)
02329 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: switchToNothing");
02330 }
02331
02332 void LCDProcClient::shutdown()
02333 {
02334 if (debug_level > 1)
02335 LOG(VB_GENERAL, LOG_INFO, "LCDProcClient: shutdown");
02336
02337 stopAll();
02338
02339
02340 removeWidgets();
02341
02342 socket->close();
02343
02344 lcd_ready = false;
02345 connected = false;
02346 }
02347
02348 void LCDProcClient::removeWidgets()
02349 {
02350 sendToServer("widget_del Channel progressBar");
02351 sendToServer("widget_del Channel topWidget");
02352 sendToServer("widget_del Channel timeWidget");
02353 sendToServer("screen_del Channel");
02354
02355 sendToServer("widget_del Generic progressBar");
02356 sendToServer("widget_del Generic textWidget1");
02357 sendToServer("widget_del Generic textWidget2");
02358 sendToServer("widget_del Generic textWidget3");
02359 sendToServer("screen_del Generic");
02360
02361 sendToServer("widget_del Volume progressBar");
02362 sendToServer("widget_del Volume topWidget");
02363 sendToServer("screen_del Volume");
02364
02365 sendToServer("widget_del Menu topWidget");
02366 sendToServer("widget_del Menu menuWidget1");
02367 sendToServer("widget_del Menu menuWidget2");
02368 sendToServer("widget_del Menu menuWidget3");
02369 sendToServer("widget_del Menu menuWidget4");
02370 sendToServer("widget_del Menu menuWidget5");
02371 sendToServer("screen_del Menu");
02372
02373 sendToServer("widget_del Music progressBar");
02374 sendToServer("widget_del Music infoWidget");
02375 sendToServer("widget_del Music timeWidget");
02376 sendToServer("widget_del Music topWidget");
02377 sendToServer("screen_del Music");
02378
02379 if (lcd_bigclock)
02380 {
02381 sendToServer("widget_del Time rec1");
02382 sendToServer("widget_del Time rec2");
02383 sendToServer("widget_del Time rec3");
02384 sendToServer("widget_del Time recCnt");
02385 sendToServer("widget_del Time d0");
02386 sendToServer("widget_del Time d1");
02387 sendToServer("widget_del Time sep");
02388 sendToServer("widget_del Time d2");
02389 sendToServer("widget_del Time d3");
02390 sendToServer("widget_del Time ampm");
02391 sendToServer("widget_del Time dot");
02392 }
02393 else
02394 {
02395 sendToServer("widget_del Time timeWidget");
02396 sendToServer("widget_del Time topWidget");
02397 }
02398
02399 sendToServer("screen_del Time");
02400
02401 sendToServer("widget_del RecStatus textWidget1");
02402 sendToServer("widget_del RecStatus textWidget2");
02403 sendToServer("widget_del RecStatus textWidget3");
02404 sendToServer("widget_del RecStatus textWidget4");
02405 sendToServer("widget_del RecStatus progressBar");
02406 }
02407
02408 LCDProcClient::~LCDProcClient()
02409 {
02410 if (debug_level > 1)
02411 LOG(VB_GENERAL, LOG_INFO,
02412 "LCDProcClient: An LCD device is being snuffed out"
02413 "of existence (~LCDProcClient() was called)");
02414
02415 if (socket)
02416 {
02417 delete socket;
02418 lcd_ready = false;
02419 }
02420
02421 if (lcdMenuItems)
02422 delete lcdMenuItems;
02423
02424 gCoreContext->removeListener(this);
02425 }
02426
02427 void LCDProcClient::customEvent(QEvent *e)
02428 {
02429 if ((MythEvent::Type)(e->type()) == MythEvent::MythEventMessage)
02430 {
02431 MythEvent *me = (MythEvent *) e;
02432
02433 if (me->Message().left(21) == "RECORDING_LIST_CHANGE" ||
02434 me->Message() == "UPDATE_PROG_INFO")
02435 {
02436 if (lcd_showrecstatus && !updateRecInfoTimer->isActive())
02437 {
02438 if (debug_level > 1)
02439 LOG(VB_GENERAL, LOG_INFO,
02440 "LCDProcClient: Received recording list change");
02441
02442
02443
02444 updateRecInfoTimer->start(500);
02445 }
02446 }
02447 }
02448 }
02449
02450 void LCDProcClient::updateRecordingList(void)
02451 {
02452 tunerList.clear();
02453 isRecording = false;
02454
02455 if (!gCoreContext->IsConnectedToMaster())
02456 {
02457 if (!gCoreContext->ConnectToMasterServer(false))
02458 {
02459 LOG(VB_GENERAL, LOG_ERR,
02460 "LCDProcClient: Cannot get recording status "
02461 "- is the master server running?\n\t\t\t"
02462 "Will retry in 30 seconds");
02463 QTimer::singleShot(30 * 1000, this, SLOT(updateRecordingList()));
02464
02465
02466
02467
02468 if (activeScreen == "RecStatus")
02469 switchToTime();
02470 return;
02471 }
02472 }
02473
02474 isRecording = RemoteGetRecordingStatus(&tunerList, false);
02475
02476 lcdTunerNo = 0;
02477
02478 if (activeScreen == "Time" || activeScreen == "RecStatus")
02479 startTime();
02480 }
02481