00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include <iostream>
00016 #include <cstdlib>
00017
00018
00019 #include <qdatetime.h>
00020 #include <qpainter.h>
00021 #include <qdir.h>
00022 #include <qprocess.h>
00023 #include <qapplication.h>
00024
00025
00026 #include "mythtv/mythcontext.h"
00027 #include "mythtv/mythdbcon.h"
00028
00029
00030 #include "zmevents.h"
00031 #include "zmplayer.h"
00032 #include "zmclient.h"
00033
00034 ZMEvents::ZMEvents(MythMainWindow *parent,
00035 const QString &window_name, const QString &theme_filename,
00036 const char *name)
00037 :MythThemedDialog(parent, window_name, theme_filename, name)
00038 {
00039 m_eventListSize = 0;
00040 m_currentEvent = 0;
00041 m_eventList = new vector<Event*>;
00042
00043 wireUpTheme();
00044
00045 m_oldestFirst = (gContext->GetNumSetting("ZoneMinderOldestFirst", 1) == 1);
00046 setView(gContext->GetNumSetting("ZoneMinderGridView", 1) == 2);
00047 setGridLayout(gContext->GetNumSetting("ZoneMinderGridLayout", 6));
00048
00049 getCameraList();
00050 getDateList();
00051 getEventList();
00052 }
00053
00054 ZMEvents::~ZMEvents()
00055 {
00056 if (!m_eventList)
00057 delete m_eventList;
00058
00059
00060 gContext->SaveSetting("ZoneMinderOldestFirst", (m_oldestFirst ? "1" : "0"));
00061 gContext->SaveSetting("ZoneMinderGridView", getContext());
00062 gContext->SaveSetting("ZoneMinderGridLayout", m_eventGrid->getVisibleCount());
00063 }
00064
00065 UITextType* ZMEvents::getTextType(QString name)
00066 {
00067 UITextType* type = getUITextType(name);
00068
00069 if (!type)
00070 {
00071 cout << "ERROR: Failed to find '" << name << "' UI element in theme file\n"
00072 << "Bailing out!" << endl;
00073 exit(0);
00074 }
00075
00076 return type;
00077 }
00078
00079 void ZMEvents::keyPressEvent(QKeyEvent *e)
00080 {
00081 if (!e) return;
00082
00083 bool handled = false;
00084 QStringList actions;
00085 gContext->GetMainWindow()->TranslateKeyPress("TV Frontend", e, actions);
00086
00087 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00088 {
00089 QString action = actions[i];
00090 handled = true;
00091
00092 if (getCurrentFocusWidget() == m_eventGrid)
00093 {
00094 if (action == "ESCAPE")
00095 {
00096 nextPrevWidgetFocus(true);
00097 return;
00098 }
00099
00100 if (m_eventGrid->handleKeyPress(action))
00101 return;
00102 }
00103
00104 if (action == "UP")
00105 {
00106 if (getCurrentFocusWidget() == m_event_list)
00107 eventListUp(false);
00108 else if (getCurrentFocusWidget() == m_cameraSelector)
00109 m_cameraSelector->push(false);
00110 else if (getCurrentFocusWidget() == m_dateSelector)
00111 m_dateSelector->push(false);
00112 else
00113 nextPrevWidgetFocus(true);
00114 }
00115 else if (action == "DOWN")
00116 {
00117 if (getCurrentFocusWidget() == m_event_list)
00118 {
00119 eventListDown(false);
00120 }
00121 else if (getCurrentFocusWidget() == m_cameraSelector)
00122 m_cameraSelector->push(true);
00123 else if (getCurrentFocusWidget() == m_dateSelector)
00124 m_dateSelector->push(true);
00125 else
00126 nextPrevWidgetFocus(true);
00127 }
00128 else if (action == "LEFT")
00129 {
00130 nextPrevWidgetFocus(false);
00131 }
00132 else if (action == "RIGHT")
00133 {
00134 nextPrevWidgetFocus(true);
00135 }
00136 else if (action == "PAGEUP")
00137 {
00138 if (getCurrentFocusWidget() == m_event_list)
00139 {
00140 eventListUp(true);
00141 }
00142 else
00143 nextPrevWidgetFocus(true);
00144 }
00145 else if (action == "PAGEDOWN")
00146 {
00147 if (getCurrentFocusWidget() == m_event_list)
00148 {
00149 eventListDown(true);
00150 }
00151 else
00152 nextPrevWidgetFocus(true);
00153 }
00154 else if (action == "SELECT")
00155 {
00156 if (getCurrentFocusWidget() == m_event_list ||
00157 getCurrentFocusWidget() == m_eventGrid)
00158 {
00159 if (m_playButton)
00160 m_playButton->push();
00161 }
00162 else
00163 activateCurrent();
00164 }
00165 else if (action == "DELETE")
00166 {
00167 if (m_deleteButton)
00168 m_deleteButton->push();
00169 }
00170 else if (action == "INFO")
00171 {
00172 m_oldestFirst = !m_oldestFirst;
00173 getEventList();
00174 }
00175 else if (action == "MENU")
00176 showMenu();
00177 else if (action == "0")
00178 {
00179 if (getContext() == 1)
00180 setView(true);
00181 else
00182 setView(false);
00183 }
00184 else if (action == "1")
00185 setGridLayout(1);
00186 else if (action == "2")
00187 setGridLayout(2);
00188 else if (action == "6")
00189 setGridLayout(6);
00190 else
00191 handled = false;
00192 }
00193
00194 if (!handled)
00195 MythThemedDialog::keyPressEvent(e);
00196 }
00197
00198 void ZMEvents::wireUpTheme()
00199 {
00200
00201 m_event_list = (UIListType*) getUIObject("event_list");
00202 if (m_event_list)
00203 {
00204 m_eventListSize = m_event_list->GetItems();
00205 m_event_list->SetItemCurrent(0);
00206 }
00207
00208 m_eventGrid = getUIImageGridType("event_grid");
00209 if (m_eventGrid)
00210 {
00211 connect(m_eventGrid, SIGNAL(itemChanged(ImageGridItem *)),
00212 this, SLOT(gridItemChanged(ImageGridItem *)));
00213 }
00214
00215 m_eventNoText = getUITextType("eventno_text");
00216
00217
00218 m_playButton = getUITextButtonType("play_button");
00219 if (m_playButton)
00220 {
00221 m_playButton->setText(tr("Play"));
00222 connect(m_playButton, SIGNAL(pushed()), this, SLOT(playPressed()));
00223 }
00224
00225
00226 m_deleteButton = getUITextButtonType("delete_button");
00227 if (m_deleteButton)
00228 {
00229 m_deleteButton->setText(tr("Delete"));
00230 connect(m_deleteButton, SIGNAL(pushed()), this, SLOT(deletePressed()));
00231 }
00232
00233
00234 m_cameraSelector = getUISelectorType("camera_selector");
00235 if (m_cameraSelector)
00236 {
00237 connect(m_cameraSelector, SIGNAL(pushed(int)),
00238 this, SLOT(setCamera(int)));
00239 }
00240
00241
00242 m_dateSelector = getUISelectorType("date_selector");
00243 if (m_dateSelector)
00244 {
00245 connect(m_dateSelector, SIGNAL(pushed(int)),
00246 this, SLOT(setDate(int)));
00247 }
00248
00249 buildFocusList();
00250 assignFirstFocus();
00251 }
00252
00253 void ZMEvents::getEventList(void)
00254 {
00255 if (class ZMClient *zm = ZMClient::get())
00256 {
00257 QString monitorName = "<ANY>";
00258 QString date = "<ANY>";
00259
00260 if (m_cameraSelector && m_cameraSelector->getCurrentString() != tr("All Cameras") &&
00261 m_cameraSelector->getCurrentString() != "")
00262 {
00263 monitorName = m_cameraSelector->getCurrentString();
00264 }
00265
00266 if (m_dateSelector && m_dateSelector->getCurrentString() != tr("All Dates") &&
00267 m_dateSelector->getCurrentString() != "")
00268 {
00269 date = m_dateList[m_dateSelector->getCurrentInt() - 1];
00270 }
00271
00272 zm->getEventList(monitorName, m_oldestFirst, date, m_eventList);
00273
00274 updateImageGrid();
00275 updateUIList();
00276 }
00277 }
00278
00279 void ZMEvents::updateUIList()
00280 {
00281 if (!m_eventList)
00282 return;
00283
00284 QString tmptitle;
00285 if (m_event_list)
00286 {
00287 m_event_list->ResetList();
00288 if (m_event_list->isFocused())
00289 m_event_list->SetActive(true);
00290
00291 int skip;
00292 if ((int)m_eventList->size() <= m_eventListSize || m_currentEvent <= m_eventListSize / 2)
00293 skip = 0;
00294 else if (m_currentEvent >= (int)m_eventList->size() - m_eventListSize + m_eventListSize / 2)
00295 skip = m_eventList->size() - m_eventListSize;
00296 else
00297 skip = m_currentEvent - m_eventListSize / 2;
00298 m_event_list->SetUpArrow(skip > 0);
00299 m_event_list->SetDownArrow(skip + m_eventListSize < (int)m_eventList->size());
00300
00301 int i;
00302 for (i = 0; i < m_eventListSize; i++)
00303 {
00304 if (i + skip >= (int)m_eventList->size())
00305 break;
00306
00307 Event *event = m_eventList->at(i + skip);
00308
00309 m_event_list->SetItemText(i, 1, event->eventName);
00310 m_event_list->SetItemText(i, 2, event->monitorName);
00311 m_event_list->SetItemText(i, 3, event->startTime);
00312 m_event_list->SetItemText(i, 4, event->length);
00313 if (i + skip == m_currentEvent)
00314 m_event_list->SetItemCurrent(i);
00315 }
00316
00317 m_event_list->refresh();
00318 }
00319
00320 if (m_eventNoText)
00321 if (m_eventList->size() > 0)
00322 m_eventNoText->SetText(QString("%1/%2")
00323 .arg(m_currentEvent + 1).arg(m_eventList->size()));
00324 else
00325 m_eventNoText->SetText("0/0");
00326 }
00327
00328 void ZMEvents::eventListDown(bool page)
00329 {
00330 if (m_currentEvent < (int)m_eventList->size() - 1)
00331 {
00332 m_currentEvent += (page ? m_eventListSize : 1);
00333 if (m_currentEvent > (int)m_eventList->size() - 1)
00334 m_currentEvent = m_eventList->size() - 1;
00335
00336 updateUIList();
00337 }
00338 }
00339
00340 void ZMEvents::eventListUp(bool page)
00341 {
00342 if (m_currentEvent > 0)
00343 {
00344 m_currentEvent -= (page ? m_eventListSize : 1);
00345 if (m_currentEvent < 0)
00346 m_currentEvent = 0;
00347
00348 updateUIList();
00349 }
00350 }
00351
00352 void ZMEvents::playPressed(void)
00353 {
00354 if (!m_eventList || m_eventList->size() == 0)
00355 return;
00356
00357 Event *event = m_eventList->at(m_currentEvent);
00358 if (event)
00359 {
00360 ZMPlayer *player = new ZMPlayer(m_eventList, &m_currentEvent,
00361 gContext->GetMainWindow(), "zmplayer", "zoneminder-", "zmplayer");
00362 player->exec();
00363 player->deleteLater();
00364
00365 if (m_currentEvent > (int)m_eventList->size() - 1)
00366 m_currentEvent = m_eventList->size() - 1;
00367
00368
00369 int currItem = m_currentEvent;
00370 updateImageGrid();
00371 m_eventGrid->setCurrentPos(currItem);
00372 gridItemChanged(m_eventGrid->getCurrentItem());
00373 updateUIList();
00374 }
00375 }
00376
00377 void ZMEvents::deletePressed(void)
00378 {
00379 if (!m_eventList || m_eventList->size() == 0)
00380 return;
00381
00382 Event *event = m_eventList->at(m_currentEvent);
00383 if (event)
00384 {
00385 if (class ZMClient *zm = ZMClient::get())
00386 zm->deleteEvent(event->eventID);
00387
00388 m_eventGrid->removeItem(m_currentEvent);
00389
00390 vector<Event*>::iterator it;
00391 for (it = m_eventList->begin(); it != m_eventList->end(); it++)
00392 {
00393 if (*it == event)
00394 {
00395 m_eventList->erase(it);
00396 break;
00397 }
00398 }
00399
00400 if (m_currentEvent > (int)m_eventList->size() - 1)
00401 {
00402 m_currentEvent = m_eventList->size() - 1;
00403 m_eventGrid->setCurrentPos(m_currentEvent);
00404 }
00405
00406 gridItemChanged(m_eventGrid->getCurrentItem());
00407
00408 updateUIList();
00409 }
00410 }
00411
00412 void ZMEvents::getCameraList(void)
00413 {
00414 if (class ZMClient *zm = ZMClient::get())
00415 {
00416 QStringList cameraList;
00417 zm->getCameraList(cameraList);
00418 if (!m_cameraSelector)
00419 return;
00420
00421 m_cameraSelector->addItem(0, tr("All Cameras"));
00422 m_cameraSelector->setToItem(0);
00423
00424 for (uint x = 1; x <= cameraList.count(); x++)
00425 {
00426 m_cameraSelector->addItem(x, cameraList[x-1]);
00427 }
00428
00429 }
00430 }
00431
00432 void ZMEvents::setCamera(int item)
00433 {
00434 (void) item;
00435 m_currentEvent = 0;
00436 getEventList();
00437 }
00438
00439 void ZMEvents::getDateList(void)
00440 {
00441 if (class ZMClient *zm = ZMClient::get())
00442 {
00443 QString monitorName = "<ANY>";
00444
00445 if (m_cameraSelector && m_cameraSelector->getCurrentString() != tr("All Cameras") &&
00446 m_cameraSelector->getCurrentString() != "")
00447 {
00448 monitorName = m_cameraSelector->getCurrentString();
00449 }
00450
00451 zm->getEventDates(monitorName, m_oldestFirst, m_dateList);
00452 if (!m_dateSelector)
00453 return;
00454
00455 QString dateFormat = gContext->GetSetting("ZoneMinderDateFormat", "ddd - dd/MM");
00456
00457 m_dateSelector->addItem(0, tr("All Dates"));
00458 m_dateSelector->setToItem(0);
00459
00460 for (uint x = 1; x <= m_dateList.count(); x++)
00461 {
00462 QDate date = QDate::fromString(m_dateList[x-1], Qt::ISODate);
00463 m_dateSelector->addItem(x, date.toString(dateFormat));
00464 }
00465 }
00466 }
00467
00468 void ZMEvents::setDate(int item)
00469 {
00470 (void) item;
00471 m_currentEvent = 0;
00472 getEventList();
00473 }
00474
00475 void ZMEvents::updateImageGrid()
00476 {
00477 m_eventGrid->reset();
00478
00479 for (uint x = 0; x < m_eventList->size(); x++)
00480 {
00481 ImageGridItem *item = new ImageGridItem(m_eventList->at(x)->startTime,
00482 NULL, false, (void*) m_eventList->at(x));
00483 m_eventGrid->appendItem(item);
00484 }
00485 m_eventGrid->setItemCount(m_eventList->size());
00486 m_eventGrid->recalculateLayout();
00487
00488 if (m_eventList->size() > 0)
00489 gridItemChanged(m_eventGrid->getItemAt(0));
00490
00491 m_eventGrid->refresh();
00492 }
00493
00494 void ZMEvents::gridItemChanged(ImageGridItem *item)
00495 {
00496 if (!item)
00497 return;
00498
00499 m_currentEvent = m_eventGrid->getCurrentPos();
00500
00501 if (m_eventNoText)
00502 if (m_eventList->size() > 0)
00503 m_eventNoText->SetText(QString("%1/%2")
00504 .arg(m_currentEvent + 1).arg(m_eventList->size()));
00505 else
00506 m_eventNoText->SetText("0/0");
00507
00508
00509 for (int x = m_eventGrid->getTopItemPos();
00510 x < m_eventGrid->getTopItemPos() + m_eventGrid->getVisibleCount(); x++)
00511 {
00512 ImageGridItem *gridItem = m_eventGrid->getItemAt(x);
00513 if (gridItem && gridItem->pixmap == NULL)
00514 {
00515 if (x < 0 || x > (int)m_eventList->size() - 1)
00516 continue;
00517
00518 Event *event = m_eventList->at(x);
00519 if (event)
00520 {
00521 QImage image;
00522 if (class ZMClient *zm = ZMClient::get())
00523 {
00524 zm->getAnalyseFrame(event->monitorID,
00525 event->eventID,
00526 0, image);
00527 if (!image.isNull())
00528 {
00529 QSize size = m_eventGrid->getImageItemSize();
00530 QPixmap *pixmap = new QPixmap(image.smoothScale(
00531 size.width(), size.height(), QImage::ScaleMin));
00532
00533 gridItem->pixmap = pixmap;
00534 }
00535 }
00536 }
00537 }
00538 }
00539
00540 m_eventGrid->refresh();
00541 }
00542
00543 void ZMEvents::setView(bool gridView)
00544 {
00545 if (gridView)
00546 {
00547 setContext(2);
00548 buildFocusList();
00549 m_eventGrid->setCurrentPos(m_currentEvent);
00550 gridItemChanged(m_eventGrid->getCurrentItem());
00551 setCurrentFocusWidget(m_eventGrid);
00552 }
00553 else
00554 {
00555 setContext(1);
00556 buildFocusList();
00557 setCurrentFocusWidget(m_event_list);
00558 }
00559
00560 updateForeground();
00561 }
00562
00563 void ZMEvents::setGridLayout(int layout)
00564 {
00565 switch (layout)
00566 {
00567 case 1:
00568 m_eventGrid->setRowCount(1);
00569 m_eventGrid->setColumnCount(1);
00570 break;
00571 case 2:
00572 m_eventGrid->setRowCount(1);
00573 m_eventGrid->setColumnCount(2);
00574 break;
00575 case 6:
00576 m_eventGrid->setRowCount(2);
00577 m_eventGrid->setColumnCount(3);
00578 break;
00579 default:
00580 m_eventGrid->setRowCount(2);
00581 m_eventGrid->setColumnCount(3);
00582 break;
00583 }
00584
00585 m_eventGrid->recalculateLayout();
00586 updateImageGrid();
00587 m_eventGrid->refresh();
00588 }
00589
00590 void ZMEvents::showMenu()
00591 {
00592 MythPopupBox *popup = new MythPopupBox(gContext->GetMainWindow(),
00593 "popup_menu");
00594
00595 QLabel *caption = popup->addLabel(tr("Event List Menu"), MythPopupBox::Medium);
00596 caption->setAlignment(Qt::AlignCenter);
00597
00598 QButton *button = popup->addButton(tr("Refresh"));
00599 if (getContext() == 1)
00600 popup->addButton(tr("Show Image View"));
00601 else
00602 popup->addButton(tr("Show List View"));
00603 button->setFocus();
00604
00605 QLabel *splitter = popup->addLabel(" ", MythPopupBox::Small);
00606 splitter->setLineWidth(2);
00607 splitter->setFrameShape(QFrame::HLine);
00608 splitter->setFrameShadow(QFrame::Sunken);
00609 splitter->setMinimumHeight((int) (25 * hmult));
00610 splitter->setMaximumHeight((int) (25 * hmult));
00611
00612 popup->addButton(tr("Delete All"));
00613
00614 DialogCode res = popup->ExecPopup();
00615 switch (res)
00616 {
00617 case kDialogCodeButton0:
00618
00619 getEventList();
00620 break;
00621 case kDialogCodeButton1:
00622 if (getContext() == 1)
00623 {
00624
00625 setView(true);
00626 }
00627 else
00628 {
00629
00630 setView(false);
00631 }
00632 break;
00633 case kDialogCodeButton2:
00634
00635 if (class ZMClient *zm = ZMClient::get())
00636 {
00637 MythBusyDialog *busy = new MythBusyDialog(
00638 QObject::tr("Deleting events. Please wait ..."));
00639 for (int x = 0; x < 5; x++)
00640 {
00641 usleep(1000);
00642 qApp->processEvents();
00643 }
00644
00645 zm->deleteEventList(m_eventList);
00646
00647 getEventList();
00648 busy->Close();
00649 busy->deleteLater();
00650 }
00651 break;
00652 case kDialogCodeRejected:
00653 default:
00654 break;
00655 }
00656
00657 popup->deleteLater();
00658 }