MythTV  master
channelrecpriority.cpp
Go to the documentation of this file.
1 
2 #include "channelrecpriority.h"
3 
4 #include <algorithm> // For std::sort()
5 #include <vector> // For std::vector
6 
7 #include "tv.h"
8 
9 #include "mythcorecontext.h"
10 #include "mythdb.h"
11 #include "mythlogging.h"
12 #include "scheduledrecording.h"
13 #include "proglist.h"
14 #include "channelinfo.h"
15 
16 #include "mythuihelper.h"
17 #include "mythuitext.h"
18 #include "mythuiimage.h"
19 #include "mythuibuttonlist.h"
20 #include "mythdialogbox.h"
21 #include "mythmainwindow.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 {
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  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:32
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:204
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:324
ChannelRecPriority::m_origRecPriorityData
QMap< QString, QString > m_origRecPriorityData
Definition: channelrecpriority.h:55
tv.h
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1590
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:98
mythdb.h
ChannelRecPriority::m_priorityText
MythUIText * m_priorityText
Definition: channelrecpriority.h:65
ChannelInfo::m_chanId
uint m_chanId
Definition: channelinfo.h:85
ChannelRecPriority::m_channelList
MythUIButtonList * m_channelList
Definition: channelrecpriority.h:57
ChannelInfo::ToMap
void ToMap(InfoMap &infoMap)
Definition: channelinfo.cpp:218
ChannelRecPriority::m_channelData
QMap< QString, ChannelInfo > m_channelData
Definition: channelrecpriority.h:53
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1142
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:131
plChannel
@ plChannel
Definition: proglist.h:24
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:968
DialogCompletionEvent::kEventType
static Type kEventType
Definition: mythdialogbox.h:57
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:198
MythScreenStack
Definition: mythscreenstack.h:16
ProgLister
Definition: proglist.h:32
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:603
ChannelRecPriority::m_sortedChannel
QMap< QString, ChannelInfo * > m_sortedChannel
Definition: channelrecpriority.h:54
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &stackname)
Definition: mythmainwindow.cpp:329
mythuibuttonlist.h
channelRecPrioritySort
Definition: channelrecpriority.cpp:41
mythuiimage.h
ChannelInfo::m_icon
QString m_icon
Definition: channelinfo.h:93
proglist.h
tmp
static guint32 * tmp
Definition: goom_core.cpp:31
ChannelRecPriority::m_iconImage
MythUIImage * m_iconImage
Definition: channelrecpriority.h:67
channelrecpriority.h
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:112
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:3264
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:190
MythUIButtonListItem
Definition: mythuibuttonlist.h:28
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:71
ChannelRecPriority::SortType
SortType
Definition: channelrecpriority.h:34
mythlogging.h
ChannelInfo::kChannelLong
@ kChannelLong
Definition: channelinfo.h:49
MythDialogBox
Basic menu dialog, message and a list of options.
Definition: mythdialogbox.h:167
MSqlQuery::InitCon
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:178
ChannelRecPriority::FillList
void FillList(void)
Definition: channelrecpriority.cpp:236
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:222
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:3580
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:60
channelSort
Definition: channelrecpriority.cpp:30
MythCoreContext::GetNumSetting
int GetNumSetting(const QString &key, int defaultval=0)
Definition: mythcorecontext.cpp:933
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:29
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:414
mythcorecontext.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:692
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:42
ChannelInfo::m_sourceId
uint m_sourceId
Definition: channelinfo.h:89
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:134
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1086
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:114
ChannelInfo::m_recPriority
int m_recPriority
Definition: channelinfo.h:98
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:108
ChannelRecPriority::updateList
void updateList(void)
Definition: channelrecpriority.cpp:292
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1557
build_compdb.action
action
Definition: build_compdb.py:9
ChannelRecPriority::m_sortType
SortType m_sortType
Definition: channelrecpriority.h:69
RecPriorityInfo
Definition: channelrecpriority.cpp:24
ChannelRecPriority::m_chanstringText
MythUIText * m_chanstringText
Definition: channelrecpriority.h:59
ChannelRecPriority::byChannel
@ byChannel
Definition: channelrecpriority.h:35
MythCoreContext::SaveSetting
void SaveSetting(const QString &key, int newValue)
Definition: mythcorecontext.cpp:902
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:819
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:676
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:152
ChannelRecPriority::byRecPriority
@ byRecPriority
Definition: channelrecpriority.h:36
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
query
MSqlQuery query(MSqlQuery::InitCon())
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:808