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