MythTV  master
zmevents.cpp
Go to the documentation of this file.
1 /* ============================================================
2  * This program is free software; you can redistribute it
3  * and/or modify it under the terms of the GNU General
4  * Public License as published by the Free Software Foundation;
5  * either version 2, or (at your option)
6  * any later version.
7  *
8  * This program is distributed in the hope that it will be useful,
9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  * GNU General Public License for more details.
12  *
13  * ============================================================ */
14 
15 // C++
16 #include <algorithm>
17 #include <cstdlib>
18 #include <iostream>
19 
20 // qt
21 #include <QKeyEvent>
22 
23 // MythTV
25 #include <libmythbase/mythdate.h>
26 #include <libmythbase/mythdbcon.h>
29 
30 // zoneminder
31 #include "zmevents.h"
32 #include "zmplayer.h"
33 #include "zmclient.h"
34 
36 
38 {
39  delete m_eventList;
40 
41  // remember how the user wants to display the event list
42  gCoreContext->SaveSetting("ZoneMinderOldestFirst", (m_oldestFirst ? "1" : "0"));
43  gCoreContext->SaveSetting("ZoneMinderShowContinuous", (m_showContinuous ? "1" : "0"));
44  gCoreContext->SaveSetting("ZoneMinderGridLayout", m_layout);
45 }
46 
47 bool ZMEvents::Create(void)
48 {
49  // Load the theme for this screen
50  bool foundtheme = LoadWindowFromXML("zoneminder-ui.xml", "zmevents", this);
51  if (!foundtheme)
52  return false;
53 
54  bool err = false;
55  UIUtilE::Assign(this, m_eventNoText, "eventno_text", &err);
56  UIUtilE::Assign(this, m_playButton, "play_button", &err);
57  UIUtilE::Assign(this, m_deleteButton, "delete_button", &err);
58  UIUtilE::Assign(this, m_cameraSelector, "camera_selector", &err);
59  UIUtilE::Assign(this, m_dateSelector, "date_selector", &err);
60 
61  if (err)
62  {
63  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'zmevents'");
64  return false;
65  }
66 
68 
69  getCameraList();
70  getDateList();
71 
75  this, &ZMEvents::dateChanged);
76 
77  // play button
78  if (m_playButton)
79  {
80  m_playButton->SetText(tr("Play"));
82  }
83 
84  // delete button
85  if (m_deleteButton)
86  {
87  m_deleteButton->SetText(tr("Delete"));
89  }
90 
91  m_oldestFirst = (gCoreContext->GetNumSetting("ZoneMinderOldestFirst", 1) == 1);
92  m_showContinuous = (gCoreContext->GetNumSetting("ZoneMinderShowContinuous", 0) == 1);
93 
94  getEventList();
95 
96  setGridLayout(gCoreContext->GetNumSetting("ZoneMinderGridLayout", 1));
97 
98  return true;
99 }
100 
101 bool ZMEvents::keyPressEvent(QKeyEvent *event)
102 {
103  // if there is a pending jump point pass the key press to the default handler
104  if (GetMythMainWindow()->IsExitingToMain())
105  return MythScreenType::keyPressEvent(event);
106 
107  if (GetFocusWidget()->keyPressEvent(event))
108  return true;
109 
110  QStringList actions;
111  bool handled = GetMythMainWindow()->TranslateKeyPress("TV Playback", event, actions);
112 
113  for (int i = 0; i < actions.size() && !handled; i++)
114  {
115  const QString& action = actions[i];
116  handled = true;
117 
118  if (action == "MENU")
119  {
120  ShowMenu();
121  }
122  else if (action == "ESCAPE")
123  {
124  if (GetFocusWidget() == m_eventGrid)
126  else
127  handled = false;
128  }
129 
130  else if (action == "DELETE")
131  {
132  if (m_deleteButton)
133  m_deleteButton->Push();
134  }
135  else if (action == "PAUSE")
136  {
137  if (m_playButton)
138  m_playButton->Push();
139  }
140  else if (action == "INFO")
141  {
143  getEventList();
144  }
145  else if (action == "1")
146  {
147  setGridLayout(1);
148  }
149  else if (action == "2")
150  {
151  setGridLayout(2);
152  }
153  else if (action == "3")
154  {
155  setGridLayout(3);
156  }
157  else
158  {
159  handled = false;
160  }
161  }
162 
163  if (!handled && MythScreenType::keyPressEvent(event))
164  handled = true;
165 
166  return handled;
167 }
168 
170 {
171  if (ZMClient *zm = ZMClient::get())
172  {
173  QString monitorName = "<ANY>";
174  QString date = "<ANY>";
175 
176  if (m_cameraSelector->GetValue() != tr("All Cameras"))
177  monitorName = m_cameraSelector->GetValue();
178 
179  if (m_dateSelector->GetValue() != tr("All Dates"))
180  date = m_dateList[m_dateSelector->GetCurrentPos() - 1];
181 
182  zm->getEventList(monitorName, m_oldestFirst, date, m_showContinuous, m_eventList);
183 
184  updateUIList();
185  }
186 }
187 
189 {
190  if (!m_eventGrid)
191  return;
192 
193  m_eventGrid->Reset();
194 
195  for (auto *event : *m_eventList)
196  {
197  auto *item = new MythUIButtonListItem(m_eventGrid, "",
198  QVariant::fromValue(event));
199 
200  item->SetText(event->eventName());
201  item->SetText(event->monitorName(), "camera" );
202  item->SetText(
204  event->startTime(),
206  item->SetText(event->length(), "length");
207  }
208 
211 }
212 
214 {
216  return;
217 
219 
220  getEventList();
221 }
222 
224 {
226  return;
227 
229 
230  getEventList();
231 }
232 
233 void ZMEvents::eventChanged([[maybe_unused]] MythUIButtonListItem *item)
234 {
235  if (m_eventNoText)
236  {
237  if (m_eventGrid->GetCount() > 0)
238  {
239  m_eventNoText->SetText(QString("%1/%2")
240  .arg(m_eventGrid->GetCurrentPos() + 1).arg(m_eventGrid->GetCount()));
241  }
242  else
243  {
244  m_eventNoText->SetText("0/0");
245  }
246  }
247 }
248 
250 {
251  if (!item)
252  return;
253 
254  if (item->HasImage())
255  return;
256 
257  auto *event = item->GetData().value<Event*>();
258 
259  if (event)
260  {
261  QImage image;
262  if (ZMClient *zm = ZMClient::get())
263  {
264  zm->getAnalyseFrame(event, 0, image);
265  if (!image.isNull())
266  {
267  MythImage *mimage = GetMythPainter()->GetFormatImage();
268  mimage->Assign(image);
269  item->SetImage(mimage);
270  mimage->SetChanged();
271  mimage->DecrRef();
272  }
273  }
274  }
275 }
276 
278 {
279  if (!m_eventList || m_eventList->empty())
280  return;
281 
283  Event *event = m_eventList->at(m_savedPosition);
284  if (event)
285  {
287 
288  auto *player = new ZMPlayer(mainStack, "ZMPlayer",
290 
291  connect(player, &MythScreenType::Exiting, this, &ZMEvents::playerExited);
292 
293  if (player->Create())
294  mainStack->AddScreen(player);
295  }
296 }
297 
299 {
300  // refresh the grid and restore the saved position
301 
302  m_savedPosition = std::min(m_savedPosition, m_eventList->size() - 1);
303 
304  updateUIList();
306 }
307 
309 {
310  if (!m_eventList || m_eventList->empty())
311  return;
312 
314  Event *event = m_eventList->at(m_savedPosition);
315  if (event)
316  {
317  if (ZMClient *zm = ZMClient::get())
318  zm->deleteEvent(event->eventID());
319 
321  delete item;
322 
323  std::vector<Event*>::iterator it;
324  for (it = m_eventList->begin(); it != m_eventList->end(); ++it)
325  {
326  if (*it == event)
327  {
328  m_eventList->erase(it);
329  break;
330  }
331  }
332  }
333 }
334 
336 {
337  if (ZMClient *zm = ZMClient::get())
338  {
339  QStringList cameraList;
340  zm->getCameraList(cameraList);
341  if (!m_cameraSelector)
342  return;
343 
344  new MythUIButtonListItem(m_cameraSelector, tr("All Cameras"));
345 
346  for (int x = 1; x <= cameraList.count(); x++)
347  {
348  new MythUIButtonListItem(m_cameraSelector, cameraList[x-1]);
349  }
350  }
351 }
352 
354 {
355  if (ZMClient *zm = ZMClient::get())
356  {
357  QString monitorName = "<ANY>";
358 
359  if (m_cameraSelector->GetValue() != tr("All Cameras"))
360  {
361  monitorName = m_cameraSelector->GetValue();
362  }
363 
364  zm->getEventDates(monitorName, m_oldestFirst, m_dateList);
365 
366  QString dateFormat = gCoreContext->GetSetting("ZoneMinderDateFormat", "ddd - dd/MM");
367 
368  new MythUIButtonListItem(m_dateSelector, tr("All Dates"));
369 
370  for (int x = 0; x < m_dateList.count(); x++)
371  {
372  QDate date = QDate::fromString(m_dateList[x], Qt::ISODate);
373  new MythUIButtonListItem(m_dateSelector, date.toString(dateFormat));
374  }
375  }
376 }
377 
378 void ZMEvents::setGridLayout(int layout)
379 {
380  if (layout < 1 || layout > 3)
381  layout = 1;
382 
383  if (layout == m_layout)
384  return;
385 
386  if (m_eventGrid)
387  m_eventGrid->Reset();
388 
389  m_layout = layout;
390 
391  // iterate though the children showing/hiding them as appropriate
392  QString name;
393  QString layoutName = QString("layout%1").arg(layout);
394  QList<MythUIType *> *children = GetAllChildren();
395 
396  for (auto *type : std::as_const(*children))
397  {
398  name = type->objectName();
399  if (name.startsWith("layout"))
400  {
401  if (name.startsWith(layoutName))
402  type->SetVisible(true);
403  else
404  type->SetVisible(false);
405  }
406  }
407 
408  // get the correct grid
409  m_eventGrid = dynamic_cast<MythUIButtonList *> (GetChild(layoutName + "_eventlist"));
410 
411  if (m_eventGrid)
412  {
414  this, &ZMEvents::eventChanged);
416  this, &ZMEvents::playPressed);
418  this, &ZMEvents::eventVisible);
419 
420  updateUIList();
421 
422  BuildFocusList();
423 
425  }
426  else
427  {
428  LOG(VB_GENERAL, LOG_ERR, QString("Theme is missing grid layout (%1).")
429  .arg(layoutName + "_eventlist"));
430  Close();
431  }
432 }
433 
435 {
436  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
437 
438  m_menuPopup = new MythDialogBox("Menu", popupStack, "actionmenu");
439 
440  if (m_menuPopup->Create())
441  popupStack->AddScreen(m_menuPopup);
442 
443  m_menuPopup->SetReturnEvent(this, "action");
444 
445  m_menuPopup->AddButton(tr("Refresh"), &ZMEvents::getEventList);
446 
447  if (m_showContinuous)
448  m_menuPopup->AddButton(tr("Hide Continuous Events"), &ZMEvents::toggleShowContinuous);
449  else
450  m_menuPopup->AddButton(tr("Show Continuous Events"), &ZMEvents::toggleShowContinuous);
451 
452  m_menuPopup->AddButton(tr("Change View"), &ZMEvents::changeView);
453  m_menuPopup->AddButton(tr("Delete All"), &ZMEvents::deleteAll);
454 }
455 
457 {
458  setGridLayout(m_layout + 1);
459 }
460 
462 {
464  getEventList();
465 }
466 
468 {
469  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
470 
471  QString title = tr("Delete All Events?");
472  QString msg = tr("Deleting %1 events in this view.").arg(m_eventGrid->GetCount());
473 
474  auto *dialog = new MythConfirmationDialog(popupStack, title + '\n' + msg, true);
475 
476  if (dialog->Create())
477  popupStack->AddScreen(dialog);
478 
479  connect(dialog, &MythConfirmationDialog::haveResult,
480  this, &ZMEvents::doDeleteAll, Qt::QueuedConnection);
481 }
482 
483 void ZMEvents::doDeleteAll(bool doDelete)
484 {
485  if (!doDelete)
486  return;
487 
488  //delete all events
489  if (ZMClient *zm = ZMClient::get())
490  {
491  zm->deleteEventList(m_eventList);
492 
493  getEventList();
494  }
495 }
ZMEvents::Create
bool Create(void) override
Definition: zmevents.cpp:47
MythUIButton::Clicked
void Clicked()
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:317
MythDialogBox::SetReturnEvent
void SetReturnEvent(QObject *retobject, const QString &resultid)
Definition: mythdialogbox.cpp:303
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:93
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1614
ZMEvents::m_menuPopup
MythDialogBox * m_menuPopup
Definition: zmevents.h:84
ZMPlayer
Definition: zmplayer.h:33
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:384
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:138
ZMEvents::changeView
void changeView(void)
Definition: zmevents.cpp:456
MythPainter::GetFormatImage
MythImage * GetFormatImage()
Returns a blank reference counted image in the format required for the Draw functions for this painte...
Definition: mythpainter.cpp:524
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
ZMEvents::cameraChanged
void cameraChanged(void)
Definition: zmevents.cpp:213
MythConfirmationDialog::haveResult
void haveResult(bool)
MythScreenStack
Definition: mythscreenstack.h:16
mythdbcon.h
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythUIType::GetAllChildren
QList< MythUIType * > * GetAllChildren(void)
Return a list of all child widgets.
Definition: mythuitype.cpp:202
ZMEvents::m_deleteButton
MythUIButton * m_deleteButton
Definition: zmevents.h:79
ZMEvents::m_eventGrid
MythUIButtonList * m_eventGrid
Definition: zmevents.h:76
ZMEvents::eventChanged
void eventChanged(MythUIButtonListItem *item)
Definition: zmevents.cpp:233
ZMEvents::m_dateList
QStringList m_dateList
Definition: zmevents.h:69
ZMEvents::m_savedPosition
size_t m_savedPosition
Definition: zmevents.h:70
ZMEvents::updateUIList
void updateUIList()
Definition: zmevents.cpp:188
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1679
ZMEvents::eventVisible
static void eventVisible(MythUIButtonListItem *item)
Definition: zmevents.cpp:249
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:111
MythUIButtonListItem::HasImage
bool HasImage(const QString &name="")
Returns true when the image exists.
Definition: mythuibuttonlist.h:95
ZMEvents::playPressed
void playPressed(void)
Definition: zmevents.cpp:277
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
zmclient.h
mythdate.h
Q_DECLARE_METATYPE
Q_DECLARE_METATYPE(Event *)
mythlogging.h
ZMEvents::m_eventNoText
MythUIText * m_eventNoText
Definition: zmevents.h:74
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1111
zmevents.h
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:240
ZMEvents::deletePressed
void deletePressed(void)
Definition: zmevents.cpp:308
Event
Event details.
Definition: zmdefines.h:27
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:116
MythDialogBox::AddButton
void AddButton(const QString &title)
Definition: mythdialogbox.h:197
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:165
MythUIButton::SetText
void SetText(const QString &msg)
Definition: mythuibutton.cpp:229
ZMEvents::~ZMEvents
~ZMEvents() override
Definition: zmevents.cpp:37
MythDialogBox::Create
bool Create(void) override
Definition: mythdialogbox.cpp:127
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:204
MythImage::DecrRef
int DecrRef(void) override
Decrements reference count and deletes on 0.
Definition: mythimage.cpp:52
MythUIButton::Push
void Push(bool lock=false)
Definition: mythuibutton.cpp:175
ZMEvents::m_layout
int m_layout
Definition: zmevents.h:66
ZMEvents::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: zmevents.cpp:101
ZMEvents::m_showContinuous
bool m_showContinuous
Definition: zmevents.h:65
ZMEvents::doDeleteAll
void doDeleteAll(bool doDelete)
Definition: zmevents.cpp:483
MythImage::SetChanged
virtual void SetChanged(bool change=true)
Definition: mythimage.h:50
ZMClient::get
static ZMClient * get(void)
Definition: zmclient.cpp:37
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3715
zmplayer.h
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
ZMEvents::m_cameraSelector
MythUIButtonList * m_cameraSelector
Definition: zmevents.h:81
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:918
MythUIButtonList::itemVisible
void itemVisible(MythUIButtonListItem *item)
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:39
ZMEvents::m_playButton
MythUIButton * m_playButton
Definition: zmevents.h:78
MythDate::kSimplify
@ kSimplify
Do Today/Yesterday/Tomorrow transform.
Definition: mythdate.h:26
ZMEvents::getEventList
void getEventList(void)
Definition: zmevents.cpp:169
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:402
ZMEvents::setGridLayout
void setGridLayout(int layout)
Definition: zmevents.cpp:378
ZMEvents::ShowMenu
void ShowMenu(void) override
Definition: zmevents.cpp:434
ZMEvents::getDateList
void getDateList(void)
Definition: zmevents.cpp:353
ZMEvents::m_dateSelector
MythUIButtonList * m_dateSelector
Definition: zmevents.h:82
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:271
mythcorecontext.h
ZMEvents::deleteAll
void deleteAll(void)
Definition: zmevents.cpp:467
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:701
MythUIButtonListItem::SetImage
void SetImage(MythImage *image, const QString &name="")
Sets an image directly, should only be used in special circumstances since it bypasses the cache.
Definition: mythuibuttonlist.cpp:3479
ZMEvents::m_currentCamera
int m_currentCamera
Definition: zmevents.h:71
MythImage
Definition: mythimage.h:36
ZMEvents::m_eventList
std::vector< Event * > * m_eventList
Definition: zmevents.h:68
ZMEvents::m_currentDate
int m_currentDate
Definition: zmevents.h:72
MythDate::ISODate
@ ISODate
Default UTC.
Definition: mythdate.h:17
MythUIButtonList::GetValue
virtual QString GetValue() const
Definition: mythuibuttonlist.cpp:1633
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:116
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1581
build_compdb.action
action
Definition: build_compdb.py:9
MythScreenType::Exiting
void Exiting()
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
ZMEvents::m_oldestFirst
bool m_oldestFirst
Definition: zmevents.h:64
MythDate::kDateTimeFull
@ kDateTimeFull
Default local time.
Definition: mythdate.h:23
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:887
MythImage::Assign
void Assign(const QImage &img)
Definition: mythimage.cpp:77
GetMythPainter
MythPainter * GetMythPainter(void)
Definition: mythmainwindow.cpp:119
ZMEvents::getCameraList
void getCameraList(void)
Definition: zmevents.cpp:335
MythUIButtonList::GetItemFirst
MythUIButtonListItem * GetItemFirst() const
Definition: mythuibuttonlist.cpp:1660
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ZMEvents::dateChanged
void dateChanged(void)
Definition: zmevents.cpp:223
ZMClient
Definition: zmclient.h:19
MythCoreContext::GetSetting
QString GetSetting(const QString &key, const QString &defaultval="")
Definition: mythcorecontext.cpp:904
ZMEvents::toggleShowContinuous
void toggleShowContinuous(void)
Definition: zmevents.cpp:461
ZMEvents::playerExited
void playerExited(void)
Definition: zmevents.cpp:298