MythTV  master
channelrecpriority.cpp
Go to the documentation of this file.
1 // C++
2 #include <algorithm> // For std::sort()
3 #include <vector> // For std::vector
4 
5 // MythTV
7 #include "libmythbase/mythdb.h"
11 #include "libmythtv/tv.h"
15 #include "libmythui/mythuihelper.h"
16 #include "libmythui/mythuiimage.h"
17 #include "libmythui/mythuitext.h"
18 
19 // MythFrontend
20 #include "channelrecpriority.h"
21 #include "proglist.h"
22 
24 {
26  int m_cnt;
27 };
28 
30 {
31  public:
33  {
34  if (a.m_chan->m_chanNum.toInt() == b.m_chan->m_chanNum.toInt())
35  return(a.m_chan->m_sourceId > b.m_chan->m_sourceId);
36  return(a.m_chan->m_chanNum.toInt() > b.m_chan->m_chanNum.toInt());
37  }
38 };
39 
41 {
42  public:
44  {
46  return (a.m_chan->m_chanNum.toInt() > b.m_chan->m_chanNum.toInt());
47  return (a.m_chan->m_recPriority < b.m_chan->m_recPriority);
48  }
49 };
50 
52  : MythScreenType(parent, "ChannelRecPriority")
53 {
54  m_sortType = (SortType)gCoreContext->GetNumSetting("ChannelRecPrioritySorting",
55  (int)byChannel);
56 
58 }
59 
61 {
63  gCoreContext->SaveSetting("ChannelRecPrioritySorting",
64  (int)m_sortType);
66 }
67 
69 {
70  if (!LoadWindowFromXML("schedule-ui.xml", "channelrecpriority", this))
71  return false;
72 
73  m_channelList = dynamic_cast<MythUIButtonList *> (GetChild("channels"));
74 
75  m_chanstringText = dynamic_cast<MythUIText *> (GetChild("chanstring")); // Deprecated, use mapped text
76  m_priorityText = dynamic_cast<MythUIText *> (GetChild("priority"));
77 
78  m_iconImage = dynamic_cast<MythUIImage *> (GetChild("icon"));
79 
80  if (!m_channelList)
81  {
82  LOG(VB_GENERAL, LOG_ERR, "Theme is missing critical theme elements.");
83  return false;
84  }
85 
88 
89  FillList();
90 
92 
93  return true;
94 }
95 
96 bool ChannelRecPriority::keyPressEvent(QKeyEvent *event)
97 {
98  if (GetFocusWidget()->keyPressEvent(event))
99  return true;
100 
101  QStringList actions;
102  bool handled = GetMythMainWindow()->TranslateKeyPress("TV Frontend", event, actions);
103 
104  for (int i = 0; i < actions.size() && !handled; i++)
105  {
106  const QString& action = actions[i];
107  handled = true;
108 
109  if (action == "UPCOMING")
110  upcoming();
111  else if (action == "RANKINC")
113  else if (action == "RANKDEC")
114  changeRecPriority(-1);
115  else if (action == "1")
116  {
117  if (m_sortType != byChannel)
118  {
120  SortList();
121  }
122  }
123  else if (action == "2")
124  {
125  if (m_sortType != byRecPriority)
126  {
128  SortList();
129  }
130  }
131  else if (action == "PREVVIEW" || action == "NEXTVIEW")
132  {
133  if (m_sortType == byChannel)
135  else
137  SortList();
138  }
139  else
140  {
141  handled = false;
142  }
143  }
144 
145  if (!handled && MythScreenType::keyPressEvent(event))
146  handled = true;
147 
148  return handled;
149 }
150 
152 {
154 
155  if (!item)
156  return;
157 
158  QString label = tr("Channel Options");
159 
160  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
161 
162  auto *menuPopup = new MythDialogBox(label, popupStack, "chanrecmenupopup");
163 
164  if (!menuPopup->Create())
165  {
166  delete menuPopup;
167  menuPopup = nullptr;
168  return;
169  }
170 
171  menuPopup->SetReturnEvent(this, "options");
172 
173  menuPopup->AddButton(tr("Program List"));
174  //menuPopup->AddButton(tr("Reset All Priorities"));
175 
176  popupStack->AddScreen(menuPopup);
177 }
178 
180 {
182 
183  if (!item)
184  return;
185 
186  auto *chanInfo = item->GetData().value<ChannelInfo *>();
187  if (chanInfo == nullptr)
188  return;
189 
190  // inc/dec recording priority
191  int tempRecPriority = chanInfo->m_recPriority + howMuch;
192  if (tempRecPriority > -100 && tempRecPriority < 100)
193  {
194  chanInfo->m_recPriority = tempRecPriority;
195 
196  // order may change if sorting by recoring priority, so resort
197  if (m_sortType == byRecPriority)
198  SortList();
199  else
200  {
201  item->SetText(QString::number(chanInfo->m_recPriority), "priority");
202  updateInfo(item);
203  }
204  }
205 }
206 
208  const QString &newrecpriority)
209 {
210  MSqlQuery query(MSqlQuery::InitCon());
211  query.prepare("UPDATE channel SET recpriority = :RECPRI "
212  "WHERE chanid = :CHANID ;");
213  query.bindValue(":RECPRI", newrecpriority);
214  query.bindValue(":CHANID", chanid);
215 
216  if (!query.exec() || !query.isActive())
217  MythDB::DBError("Save recpriority update", query);
218 }
219 
221 {
222  QMap<QString, ChannelInfo>::Iterator it;
223 
224  for (it = m_channelData.begin(); it != m_channelData.end(); ++it)
225  {
226  ChannelInfo *chanInfo = &(*it);
227  QString key = QString::number(chanInfo->m_chanId);
228 
229  // if this channel's recording priority changed from when we entered
230  // save new value out to db
231  if (QString::number(chanInfo->m_recPriority) != m_origRecPriorityData[key])
232  applyChannelRecPriorityChange(QString::number(chanInfo->m_chanId),
233  QString::number(chanInfo->m_recPriority));
234  }
235  ScheduledRecording::ReschedulePlace("SaveChannelPriority");
236 }
237 
239 {
240  QMap<int, QString> srcMap;
241 
242  m_channelData.clear();
243  m_sortedChannel.clear();
244 
245  MSqlQuery result(MSqlQuery::InitCon());
246  result.prepare("SELECT sourceid, name FROM videosource;");
247 
248  if (result.exec())
249  {
250  while (result.next())
251  {
252  srcMap[result.value(0).toInt()] = result.value(1).toString();
253  }
254  }
255  result.prepare("SELECT chanid, channum, sourceid, callsign, "
256  "icon, recpriority, name FROM channel "
257  "WHERE deleted IS NULL AND visible > 0");
258 
259  if (result.exec())
260  {
261  int cnt = 999;
262  while (result.next())
263  {
264  auto *chaninfo = new ChannelInfo;
265  chaninfo->m_chanId = result.value(0).toInt();
266  chaninfo->m_chanNum = result.value(1).toString();
267  chaninfo->m_sourceId = result.value(2).toInt();
268  chaninfo->m_callSign = result.value(3).toString();
269  QString iconurl = result.value(4).toString();
270  if (!iconurl.isEmpty())
271  iconurl = gCoreContext->GetMasterHostPrefix( "ChannelIcons", iconurl);
272  chaninfo->m_icon = iconurl;
273  chaninfo->m_recPriority = result.value(5).toInt();
274  chaninfo->m_name = result.value(6).toString();
275 
276  chaninfo->SetSourceName(srcMap[chaninfo->m_sourceId]);
277 
278  m_channelData[QString::number(cnt)] = *chaninfo;
279 
280  // save recording priority value in map so we don't have to save
281  // all channel's recording priority values when we exit
282  m_origRecPriorityData[QString::number(chaninfo->m_chanId)] =
283  QString::number(chaninfo->m_recPriority);
284 
285  cnt--;
286  }
287  }
288  else if (!result.isActive())
289  {
290  MythDB::DBError("Get channel recording priorities query", result);
291  }
292 
293  SortList();
294 }
295 
297 {
298  m_channelList->Reset();
299 
300  QMap<QString, ChannelInfo*>::Iterator it;
301  for (it = m_sortedChannel.begin(); it != m_sortedChannel.end(); ++it)
302  {
303  ChannelInfo *chanInfo = *it;
304 
305  auto *item = new MythUIButtonListItem(m_channelList, "",
306  QVariant::fromValue(chanInfo));
307 
308  QString fontState = "default";
309 
310  item->SetText(chanInfo->GetFormatted(ChannelInfo::kChannelLong),
311  fontState);
312 
313  InfoMap infomap;
314  chanInfo->ToMap(infomap);
315  item->SetTextFromMap(infomap, fontState);
316 
317  item->DisplayState("normal", "status");
318 
319  if (!chanInfo->m_icon.isEmpty())
320  {
321  QString iconUrl = gCoreContext->GetMasterHostPrefix("ChannelIcons",
322  chanInfo->m_icon);
323  item->SetImage(iconUrl, "icon");
324  item->SetImage(iconUrl);
325  }
326 
327  item->SetText(QString::number(chanInfo->m_recPriority), "priority", fontState);
328 
329  if (m_currentItem == chanInfo)
331  }
332 
333  // this textarea name is depreciated use 'nochannels_warning' instead
334  MythUIText *noChannelsText = dynamic_cast<MythUIText*>(GetChild("norecordings_info"));
335 
336  if (!noChannelsText)
337  noChannelsText = dynamic_cast<MythUIText*>(GetChild("nochannels_warning"));
338 
339  if (noChannelsText)
340  noChannelsText->SetVisible(m_channelData.isEmpty());
341 }
342 
343 
345 {
347 
348  if (item)
349  {
350  auto *channelItem = item->GetData().value<ChannelInfo *>();
351  m_currentItem = channelItem;
352  }
353 
354  int i = 0;
355  int j = 0;
356  std::vector<RecPriorityInfo> sortingList;
357  QMap<QString, ChannelInfo>::iterator pit;
358  std::vector<RecPriorityInfo>::iterator sit;
359 
360  // copy m_channelData into sortingList
361  for (i = 0, pit = m_channelData.begin(); pit != m_channelData.end();
362  ++pit, ++i)
363  {
364  ChannelInfo *chanInfo = &(*pit);
365  RecPriorityInfo tmp = {chanInfo, i};
366  sortingList.push_back(tmp);
367  }
368 
369  switch(m_sortType)
370  {
371  case byRecPriority:
372  std::sort(sortingList.begin(), sortingList.end(),
374  break;
375  case byChannel:
376  default:
377  std::sort(sortingList.begin(), sortingList.end(),
378  channelSort());
379  break;
380  }
381 
382  m_sortedChannel.clear();
383 
384  // rebuild m_channelData in sortingList order from m_sortedChannel
385  for (i = 0, sit = sortingList.begin(); sit != sortingList.end(); i++, ++sit)
386  {
387  RecPriorityInfo *recPriorityInfo = &(*sit);
388 
389  // find recPriorityInfo[i] in m_sortedChannel
390  for (j = 0, pit = m_channelData.begin(); j !=recPriorityInfo->m_cnt; j++, ++pit);
391 
392  m_sortedChannel[QString::number(999-i)] = &(*pit);
393  }
394 
395  updateList();
396 }
397 
399 {
400  if (!item)
401  return;
402 
403  auto *channelItem = item->GetData().value<ChannelInfo *>();
404  if (!m_channelData.isEmpty() && channelItem)
405  {
406  if (m_iconImage)
407  {
408  QString iconUrl = gCoreContext->GetMasterHostPrefix("ChannelIcons", channelItem->m_icon);
409  m_iconImage->SetFilename(iconUrl);
410  m_iconImage->Load();
411  }
412 
413  InfoMap chanmap;
414  channelItem->ToMap(chanmap);
415  SetTextFromMap(chanmap);
416 
417  if (m_chanstringText)
418  m_chanstringText->SetText(channelItem->GetFormatted(ChannelInfo::kChannelLong));
419  }
420 
421  MythUIText *norecordingText = dynamic_cast<MythUIText*>
422  (GetChild("norecordings_info"));
423 
424  if (norecordingText)
425  norecordingText->SetVisible(m_channelData.isEmpty());
426 }
427 
429 {
431 
432  if (!item)
433  return;
434 
435  auto *chanInfo = item->GetData().value<ChannelInfo *>();
436 
437  if (!chanInfo || chanInfo->m_chanId < 1)
438  return;
439 
440  QString chanID = QString("%1").arg(chanInfo->m_chanId);
442  auto *pl = new ProgLister(mainStack, plChannel, chanID, "");
443  if (pl->Create())
444  mainStack->AddScreen(pl);
445  else
446  delete pl;
447 }
448 
449 
451 {
452  if (event->type() == DialogCompletionEvent::kEventType)
453  {
454  auto *dce = (DialogCompletionEvent*)(event);
455 
456  QString resultid = dce->GetId();
457  int buttonnum = dce->GetResult();
458 
459  if (resultid == "options")
460  {
461  switch (buttonnum)
462  {
463  case 0:
464  upcoming();
465  break;
466  }
467  }
468  }
469 }
ChannelInfo
Definition: channelinfo.h:31
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
ChannelRecPriority::SortType
SortType
Definition: channelrecpriority.h:32
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:317
ChannelRecPriority::m_origRecPriorityData
QMap< QString, QString > m_origRecPriorityData
Definition: channelrecpriority.h:54
tv.h
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1614
ChannelRecPriority::upcoming
void upcoming(void)
Definition: channelrecpriority.cpp:428
mythuitext.h
MythUIImage
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
mythdb.h
ChannelRecPriority::m_priorityText
MythUIText * m_priorityText
Definition: channelrecpriority.h:64
ChannelInfo::m_chanId
uint m_chanId
Definition: channelinfo.h:85
ChannelRecPriority::m_channelList
MythUIButtonList * m_channelList
Definition: channelrecpriority.h:56
ChannelInfo::ToMap
void ToMap(InfoMap &infoMap)
Definition: channelinfo.cpp:220
ChannelRecPriority::m_channelData
QMap< QString, ChannelInfo > m_channelData
Definition: channelrecpriority.h:52
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:138
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:971
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
ChannelRecPriority::saveRecPriority
void saveRecPriority(void)
Definition: channelrecpriority.cpp:220
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MythScreenStack
Definition: mythscreenstack.h:16
ProgLister
Definition: proglist.h:35
ChannelRecPriority::Create
bool Create(void) override
Definition: channelrecpriority.cpp:68
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:618
ChannelRecPriority::m_sortedChannel
QMap< QString, ChannelInfo * > m_sortedChannel
Definition: channelrecpriority.h:53
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
mythuibuttonlist.h
channelRecPrioritySort
Definition: channelrecpriority.cpp:40
mythuiimage.h
ChannelInfo::m_icon
QString m_icon
Definition: channelinfo.h:93
ChannelInfo::kChannelLong
@ kChannelLong
Definition: channelinfo.h:49
proglist.h
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
ChannelRecPriority::m_iconImage
MythUIImage * m_iconImage
Definition: channelrecpriority.h:66
channelrecpriority.h
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:110
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3319
MythObservable::addListener
void addListener(QObject *listener)
Add a listener to the observable.
Definition: mythobservable.cpp:38
ChannelInfo::GetFormatted
QString GetFormatted(ChannelFormat format) const
Definition: channelinfo.cpp:192
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
ChannelRecPriority::ChannelRecPriority
ChannelRecPriority(MythScreenStack *parent)
Definition: channelrecpriority.cpp:51
channelSort::operator()
bool operator()(const RecPriorityInfo a, const RecPriorityInfo b)
Definition: channelrecpriority.cpp:32
ChannelRecPriority::SortList
void SortList(void)
Definition: channelrecpriority.cpp:344
ChannelRecPriority::m_currentItem
ChannelInfo * m_currentItem
Definition: channelrecpriority.h:70
mythlogging.h
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
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:166
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:550
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
ChannelRecPriority::byRecPriority
@ byRecPriority
Definition: channelrecpriority.h:35
ChannelRecPriority::FillList
void FillList(void)
Definition: channelrecpriority.cpp:238
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:203
ChannelInfo::m_chanNum
QString m_chanNum
Definition: channelinfo.h:86
channelRecPrioritySort::operator()
bool operator()(const RecPriorityInfo a, const RecPriorityInfo b)
Definition: channelrecpriority.cpp:43
MythUIComposite::SetTextFromMap
virtual void SetTextFromMap(const InfoMap &infoMap)
Definition: mythuicomposite.cpp:9
RecPriorityInfo::m_cnt
int m_cnt
Definition: channelrecpriority.cpp:26
scheduledrecording.h
ChannelRecPriority::updateInfo
void updateInfo(MythUIButtonListItem *item)
Definition: channelrecpriority.cpp:398
RecPriorityInfo::m_chan
ChannelInfo * m_chan
Definition: channelrecpriority.cpp:25
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3715
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
channelSort
Definition: channelrecpriority.cpp:29
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:916
ScheduledRecording::ReschedulePlace
static void ReschedulePlace(const QString &why)
Definition: scheduledrecording.h:33
ChannelRecPriority::customEvent
void customEvent(QEvent *event) override
Definition: channelrecpriority.cpp:450
channelinfo.h
mythuihelper.h
ChannelRecPriority::~ChannelRecPriority
~ChannelRecPriority() override
Definition: channelrecpriority.cpp:60
MythUIText
All purpose text widget, displays a text string.
Definition: mythuitext.h:28
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:401
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:701
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
ChannelInfo::m_sourceId
uint m_sourceId
Definition: channelinfo.h:89
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1105
DialogCompletionEvent::kEventType
static const Type kEventType
Definition: mythdialogbox.h:57
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
ChannelInfo::m_recPriority
int m_recPriority
Definition: channelinfo.h:98
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
ChannelRecPriority::updateList
void updateList(void)
Definition: channelrecpriority.cpp:296
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1581
build_compdb.action
action
Definition: build_compdb.py:9
ChannelRecPriority::byChannel
@ byChannel
Definition: channelrecpriority.h:34
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:322
ChannelRecPriority::m_sortType
SortType m_sortType
Definition: channelrecpriority.h:68
RecPriorityInfo
Definition: channelrecpriority.cpp:23
ChannelRecPriority::m_chanstringText
MythUIText * m_chanstringText
Definition: channelrecpriority.h:58
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:885
ChannelRecPriority::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: channelrecpriority.cpp:96
MythCoreContext::GetMasterHostPrefix
QString GetMasterHostPrefix(const QString &storageGroup=QString(), const QString &path=QString())
Definition: mythcorecontext.cpp:802
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:677
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
plChannel
@ plChannel
Definition: proglist.h:28
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ChannelRecPriority::applyChannelRecPriorityChange
static void applyChannelRecPriorityChange(const QString &chanid, const QString &newrecpriority)
Definition: channelrecpriority.cpp:207
MythObservable::removeListener
void removeListener(QObject *listener)
Remove a listener to the observable.
Definition: mythobservable.cpp:55
ChannelRecPriority::ShowMenu
void ShowMenu(void) override
Definition: channelrecpriority.cpp:151
ChannelRecPriority::changeRecPriority
void changeRecPriority(int howMuch)
Definition: channelrecpriority.cpp:179
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837