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  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  handled = false;
141  }
142 
143  if (!handled && MythScreenType::keyPressEvent(event))
144  handled = true;
145 
146  return handled;
147 }
148 
150 {
152 
153  if (!item)
154  return;
155 
156  QString label = tr("Channel Options");
157 
158  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
159 
160  auto *menuPopup = new MythDialogBox(label, popupStack, "chanrecmenupopup");
161 
162  if (!menuPopup->Create())
163  {
164  delete menuPopup;
165  menuPopup = nullptr;
166  return;
167  }
168 
169  menuPopup->SetReturnEvent(this, "options");
170 
171  menuPopup->AddButton(tr("Program List"));
172  //menuPopup->AddButton(tr("Reset All Priorities"));
173 
174  popupStack->AddScreen(menuPopup);
175 }
176 
178 {
180 
181  if (!item)
182  return;
183 
184  auto *chanInfo = item->GetData().value<ChannelInfo *>();
185  if (chanInfo == nullptr)
186  return;
187 
188  // inc/dec recording priority
189  int tempRecPriority = chanInfo->m_recPriority + howMuch;
190  if (tempRecPriority > -100 && tempRecPriority < 100)
191  {
192  chanInfo->m_recPriority = tempRecPriority;
193 
194  // order may change if sorting by recoring priority, so resort
195  if (m_sortType == byRecPriority)
196  SortList();
197  else
198  {
199  item->SetText(QString::number(chanInfo->m_recPriority), "priority");
200  updateInfo(item);
201  }
202  }
203 }
204 
206  const QString &newrecpriority)
207 {
208  MSqlQuery query(MSqlQuery::InitCon());
209  query.prepare("UPDATE channel SET recpriority = :RECPRI "
210  "WHERE chanid = :CHANID ;");
211  query.bindValue(":RECPRI", newrecpriority);
212  query.bindValue(":CHANID", chanid);
213 
214  if (!query.exec() || !query.isActive())
215  MythDB::DBError("Save recpriority update", query);
216 }
217 
219 {
220  QMap<QString, ChannelInfo>::Iterator it;
221 
222  for (it = m_channelData.begin(); it != m_channelData.end(); ++it)
223  {
224  ChannelInfo *chanInfo = &(*it);
225  QString key = QString::number(chanInfo->m_chanId);
226 
227  // if this channel's recording priority changed from when we entered
228  // save new value out to db
229  if (QString::number(chanInfo->m_recPriority) != m_origRecPriorityData[key])
230  applyChannelRecPriorityChange(QString::number(chanInfo->m_chanId),
231  QString::number(chanInfo->m_recPriority));
232  }
233  ScheduledRecording::ReschedulePlace("SaveChannelPriority");
234 }
235 
237 {
238  QMap<int, QString> srcMap;
239 
240  m_channelData.clear();
241  m_sortedChannel.clear();
242 
243  MSqlQuery result(MSqlQuery::InitCon());
244  result.prepare("SELECT sourceid, name FROM videosource;");
245 
246  if (result.exec())
247  {
248  while (result.next())
249  {
250  srcMap[result.value(0).toInt()] = result.value(1).toString();
251  }
252  }
253  result.prepare("SELECT chanid, channum, sourceid, callsign, "
254  "icon, recpriority, name FROM channel "
255  "WHERE deleted IS NULL AND visible > 0");
256 
257  if (result.exec())
258  {
259  int cnt = 999;
260  while (result.next())
261  {
262  auto *chaninfo = new ChannelInfo;
263  chaninfo->m_chanId = result.value(0).toInt();
264  chaninfo->m_chanNum = result.value(1).toString();
265  chaninfo->m_sourceId = result.value(2).toInt();
266  chaninfo->m_callSign = result.value(3).toString();
267  QString iconurl = result.value(4).toString();
268  if (!iconurl.isEmpty())
269  iconurl = gCoreContext->GetMasterHostPrefix( "ChannelIcons", iconurl);
270  chaninfo->m_icon = iconurl;
271  chaninfo->m_recPriority = result.value(5).toInt();
272  chaninfo->m_name = result.value(6).toString();
273 
274  chaninfo->SetSourceName(srcMap[chaninfo->m_sourceId]);
275 
276  m_channelData[QString::number(cnt)] = *chaninfo;
277 
278  // save recording priority value in map so we don't have to save
279  // all channel's recording priority values when we exit
280  m_origRecPriorityData[QString::number(chaninfo->m_chanId)] =
281  QString::number(chaninfo->m_recPriority);
282 
283  cnt--;
284  }
285  }
286  else if (!result.isActive())
287  MythDB::DBError("Get channel recording priorities query", result);
288 
289  SortList();
290 }
291 
293 {
294  m_channelList->Reset();
295 
296  QMap<QString, ChannelInfo*>::Iterator it;
297  for (it = m_sortedChannel.begin(); it != m_sortedChannel.end(); ++it)
298  {
299  ChannelInfo *chanInfo = *it;
300 
301  auto *item = new MythUIButtonListItem(m_channelList, "",
302  QVariant::fromValue(chanInfo));
303 
304  QString fontState = "default";
305 
306  item->SetText(chanInfo->GetFormatted(ChannelInfo::kChannelLong),
307  fontState);
308 
309  InfoMap infomap;
310  chanInfo->ToMap(infomap);
311  item->SetTextFromMap(infomap, fontState);
312 
313  item->DisplayState("normal", "status");
314 
315  if (!chanInfo->m_icon.isEmpty())
316  {
317  QString iconUrl = gCoreContext->GetMasterHostPrefix("ChannelIcons",
318  chanInfo->m_icon);
319  item->SetImage(iconUrl, "icon");
320  item->SetImage(iconUrl);
321  }
322 
323  item->SetText(QString::number(chanInfo->m_recPriority), "priority", fontState);
324 
325  if (m_currentItem == chanInfo)
327  }
328 
329  // this textarea name is depreciated use 'nochannels_warning' instead
330  MythUIText *noChannelsText = dynamic_cast<MythUIText*>(GetChild("norecordings_info"));
331 
332  if (!noChannelsText)
333  noChannelsText = dynamic_cast<MythUIText*>(GetChild("nochannels_warning"));
334 
335  if (noChannelsText)
336  noChannelsText->SetVisible(m_channelData.isEmpty());
337 }
338 
339 
341 {
343 
344  if (item)
345  {
346  auto *channelItem = item->GetData().value<ChannelInfo *>();
347  m_currentItem = channelItem;
348  }
349 
350  int i = 0;
351  int j = 0;
352  std::vector<RecPriorityInfo> sortingList;
353  QMap<QString, ChannelInfo>::iterator pit;
354  std::vector<RecPriorityInfo>::iterator sit;
355 
356  // copy m_channelData into sortingList
357  for (i = 0, pit = m_channelData.begin(); pit != m_channelData.end();
358  ++pit, ++i)
359  {
360  ChannelInfo *chanInfo = &(*pit);
361  RecPriorityInfo tmp = {chanInfo, i};
362  sortingList.push_back(tmp);
363  }
364 
365  switch(m_sortType)
366  {
367  case byRecPriority:
368  std::sort(sortingList.begin(), sortingList.end(),
370  break;
371  case byChannel:
372  default:
373  std::sort(sortingList.begin(), sortingList.end(),
374  channelSort());
375  break;
376  }
377 
378  m_sortedChannel.clear();
379 
380  // rebuild m_channelData in sortingList order from m_sortedChannel
381  for (i = 0, sit = sortingList.begin(); sit != sortingList.end(); i++, ++sit)
382  {
383  RecPriorityInfo *recPriorityInfo = &(*sit);
384 
385  // find recPriorityInfo[i] in m_sortedChannel
386  for (j = 0, pit = m_channelData.begin(); j !=recPriorityInfo->m_cnt; j++, ++pit);
387 
388  m_sortedChannel[QString::number(999-i)] = &(*pit);
389  }
390 
391  updateList();
392 }
393 
395 {
396  if (!item)
397  return;
398 
399  auto *channelItem = item->GetData().value<ChannelInfo *>();
400  if (!m_channelData.isEmpty() && channelItem)
401  {
402  if (m_iconImage)
403  {
404  QString iconUrl = gCoreContext->GetMasterHostPrefix("ChannelIcons", channelItem->m_icon);
405  m_iconImage->SetFilename(iconUrl);
406  m_iconImage->Load();
407  }
408 
409  InfoMap chanmap;
410  channelItem->ToMap(chanmap);
411  SetTextFromMap(chanmap);
412 
413  if (m_chanstringText)
414  m_chanstringText->SetText(channelItem->GetFormatted(ChannelInfo::kChannelLong));
415  }
416 
417  MythUIText *norecordingText = dynamic_cast<MythUIText*>
418  (GetChild("norecordings_info"));
419 
420  if (norecordingText)
421  norecordingText->SetVisible(m_channelData.isEmpty());
422 }
423 
425 {
427 
428  if (!item)
429  return;
430 
431  auto *chanInfo = item->GetData().value<ChannelInfo *>();
432 
433  if (!chanInfo || chanInfo->m_chanId < 1)
434  return;
435 
436  QString chanID = QString("%1").arg(chanInfo->m_chanId);
438  auto *pl = new ProgLister(mainStack, plChannel, chanID, "");
439  if (pl->Create())
440  mainStack->AddScreen(pl);
441  else
442  delete pl;
443 }
444 
445 
447 {
448  if (event->type() == DialogCompletionEvent::kEventType)
449  {
450  auto *dce = (DialogCompletionEvent*)(event);
451 
452  QString resultid = dce->GetId();
453  int buttonnum = dce->GetResult();
454 
455  if (resultid == "options")
456  {
457  switch (buttonnum)
458  {
459  case 0:
460  upcoming();
461  break;
462  }
463  }
464  }
465 }
ChannelInfo
Definition: channelinfo.h:31
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:813
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
ChannelRecPriority::m_origRecPriorityData
QMap< QString, QString > m_origRecPriorityData
Definition: channelrecpriority.h:54
tv.h
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1591
ChannelRecPriority::upcoming
void upcoming(void)
Definition: channelrecpriority.cpp:424
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:135
plChannel
@ plChannel
Definition: proglist.h:26
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:966
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
ChannelRecPriority::saveRecPriority
void saveRecPriority(void)
Definition: channelrecpriority.cpp:218
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:204
MythScreenStack
Definition: mythscreenstack.h:16
ProgLister
Definition: proglist.h:33
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:619
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
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:113
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:3268
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:340
ChannelRecPriority::m_currentItem
ChannelInfo * m_currentItem
Definition: channelrecpriority.h:70
ChannelRecPriority::SortType
SortType
Definition: channelrecpriority.h:32
mythlogging.h
ChannelInfo::kChannelLong
@ kChannelLong
Definition: channelinfo.h:49
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:1112
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:551
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
ChannelRecPriority::FillList
void FillList(void)
Definition: channelrecpriority.cpp:236
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
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:394
RecPriorityInfo::m_chan
ChannelInfo * m_chan
Definition: channelrecpriority.cpp:25
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3660
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:912
ScheduledRecording::ReschedulePlace
static void ReschedulePlace(const QString &why)
Definition: scheduledrecording.h:33
ChannelRecPriority::customEvent
void customEvent(QEvent *event) override
Definition: channelrecpriority.cpp:446
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:404
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:687
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:889
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:132
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1110
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:292
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1558
build_compdb.action
action
Definition: build_compdb.py:9
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:323
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
ChannelRecPriority::byChannel
@ byChannel
Definition: channelrecpriority.h:34
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:881
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:798
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:674
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
ChannelRecPriority::byRecPriority
@ byRecPriority
Definition: channelrecpriority.h:35
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:205
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:149
ChannelRecPriority::changeRecPriority
void changeRecPriority(int howMuch)
Definition: channelrecpriority.cpp:177
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:838