MythTV  master
channeleditor.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QCoreApplication>
3 
4 // MythTV
6 #include "libmythbase/mythdb.h"
7 #include "libmythbase/mythdirs.h"
9 #include "libmythtv/cardutil.h"
11 #include "libmythtv/channelutil.h"
12 #include "libmythtv/restoredata.h"
13 #include "libmythtv/scanwizard.h"
14 #include "libmythtv/sourceutil.h"
18 #include "libmythui/mythuibutton.h"
21 #include "libmythui/mythuiimage.h"
22 #include "libmythui/mythuitext.h"
24 
25 // MythTV Setup
26 #include "channeleditor.h"
27 #include "importicons.h"
28 
29 #define LOC QString("ChannelEditor: ")
30 
31 ChannelWizard::ChannelWizard(int id, int default_sourceid)
32 {
33  setLabel(tr("Channel Options"));
34 
35  // Must be first.
36  addChild(m_cid = new ChannelID());
37  m_cid->setValue(id);
38 
39  QStringList cardtypes = ChannelUtil::GetInputTypes(m_cid->getValue().toUInt());
40 
41  // For a new channel the list will be empty so get it this way.
42  if (cardtypes.empty())
43  cardtypes = CardUtil::GetInputTypeNames(default_sourceid);
44 
45  bool all_v4l = !cardtypes.empty();
46  bool all_asi = !cardtypes.empty();
47  for (const QString& cardtype : qAsConst(cardtypes))
48  {
49  all_v4l &= CardUtil::IsV4L(cardtype);
50  all_asi &= cardtype == "ASI";
51  }
52 
53  auto *common = new ChannelOptionsCommon(*m_cid, default_sourceid,!all_v4l);
55 
56  auto *iptv = new ChannelOptionsIPTV(*m_cid);
57  addChild(iptv);
58 
59  auto *filters = new ChannelOptionsFilters(*m_cid);
60  addChild(filters);
61 
62  if (all_v4l)
64  else if (all_asi)
66 }
67 
69 
71  : MythScreenType(parent, "channeleditor"),
72  m_currentSortMode(QCoreApplication::translate("(Common)", "Channel Number"))
73 {
74 }
75 
77 {
78  // Load the theme for this screen
79  bool foundtheme = LoadWindowFromXML("config-ui.xml", "channeloverview", this);
80  if (!foundtheme)
81  return false;
82 
83  MythUIButtonList *sortList = dynamic_cast<MythUIButtonList *>(GetChild("sorting"));
84  m_sourceList = dynamic_cast<MythUIButtonList *>(GetChild("source"));
85  m_channelList = dynamic_cast<MythUIButtonList *>(GetChild("channels"));
86  m_preview = dynamic_cast<MythUIImage *>(GetChild("preview"));
87  m_channame = dynamic_cast<MythUIText *>(GetChild("name"));
88  m_channum = dynamic_cast<MythUIText *>(GetChild("channum"));
89  m_callsign = dynamic_cast<MythUIText *>(GetChild("callsign"));
90  m_chanid = dynamic_cast<MythUIText *>(GetChild("chanid"));
91  m_sourcename = dynamic_cast<MythUIText *>(GetChild("sourcename"));
92  m_frequency = dynamic_cast<MythUIText *>(GetChild("frequency"));
93  m_transportid = dynamic_cast<MythUIText *>(GetChild("transportid"));
94  m_compoundname = dynamic_cast<MythUIText *>(GetChild("compoundname"));
95 
96  MythUIButton *deleteButton = dynamic_cast<MythUIButton *>(GetChild("delete"));
97  MythUIButton *scanButton = dynamic_cast<MythUIButton *>(GetChild("scan"));
98  MythUIButton *restoreDataButton = dynamic_cast<MythUIButton *>(GetChild("restoredata"));
99  MythUIButton *importIconButton = dynamic_cast<MythUIButton *>(GetChild("importicons"));
100  MythUIButton *transportEditorButton = dynamic_cast<MythUIButton *>(GetChild("edittransport"));
101 
102  MythUICheckBox *hideCheck = dynamic_cast<MythUICheckBox *>(GetChild("nochannum"));
103 
104  if (!sortList || !m_sourceList || !m_channelList || !deleteButton ||
105  !scanButton || !importIconButton || !transportEditorButton ||
106  !hideCheck)
107  {
108  LOG(VB_GENERAL, LOG_ERR, LOC + "One or more buttons not found in theme.");
109  return false;
110  }
111 
112  // Delete button help text
113  deleteButton->SetHelpText(tr("Delete all channels on currently selected video source."));
114 
115  // Sort List
116  new MythUIButtonListItem(sortList, tr("Channel Number"));
117  new MythUIButtonListItem(sortList, tr("Channel Name"));
118  new MythUIButtonListItem(sortList, tr("Service ID"));
119  new MythUIButtonListItem(sortList, tr("Frequency"));
120  new MythUIButtonListItem(sortList, tr("Transport ID"));
121  new MythUIButtonListItem(sortList, tr("Video Source"));
124  sortList->SetValue(m_currentSortMode);
125 
126  // Source List
127  new MythUIButtonListItem(m_sourceList,tr("All"),
128  QVariant::fromValue((int)FILTER_ALL));
129  MSqlQuery query(MSqlQuery::InitCon());
130  query.prepare("SELECT name, sourceid FROM videosource");
131  if (query.exec())
132  {
133  while(query.next())
134  {
135  new MythUIButtonListItem(m_sourceList, query.value(0).toString(),
136  query.value(1).toInt());
137  }
138  }
139  new MythUIButtonListItem(m_sourceList,tr("(Unassigned)"),
140  QVariant::fromValue((int)FILTER_UNASSIGNED));
141  connect(sortList, &MythUIButtonList::itemSelected,
143 
144  // Hide/Show channels without channum checkbox
145  hideCheck->SetCheckState(m_currentHideMode);
146  connect(hideCheck, &MythUICheckBox::toggled,
148 
149  // Scan Button
150  scanButton->SetHelpText(tr("Starts the channel scanner."));
152 
153  // Restore Data button
154  if (restoreDataButton)
155  {
156  restoreDataButton->SetHelpText(tr("Restore Data from deleted channels."));
157  restoreDataButton->SetEnabled(true);
158  connect(restoreDataButton, &MythUIButton::Clicked, this, &ChannelEditor::restoreData);
159  }
160  else
161  {
162  LOG(VB_GENERAL, LOG_ERR, LOC + "Button \"Restore Data\" not found in theme.");
163  }
164 
165  // Import Icons Button
166  importIconButton->SetHelpText(tr("Starts the icon downloader"));
167  importIconButton->SetEnabled(true);
168  connect(importIconButton, &MythUIButton::Clicked, this, &ChannelEditor::channelIconImport);
169 
170  // Transport Editor Button
171  transportEditorButton->SetHelpText(
172  tr("Allows you to edit the transports directly. "
173  "This is rarely required unless you are using "
174  "a satellite dish and must enter an initial "
175  "frequency to for the channel scanner to try."));
176  connect(transportEditorButton, &MythUIButton::Clicked, this, &ChannelEditor::transportEditor);
177 
178  // Other signals
180  this, &ChannelEditor::edit);
183  connect(scanButton, &MythUIButton::Clicked, this, &ChannelEditor::scan);
184  connect(deleteButton, &MythUIButton::Clicked, this, &ChannelEditor::deleteChannels);
185 
186  fillList();
187 
188  BuildFocusList();
189 
190  return true;
191 }
192 
193 bool ChannelEditor::keyPressEvent(QKeyEvent *event)
194 {
195  if (GetFocusWidget()->keyPressEvent(event))
196  return true;
197 
198  QStringList actions;
199  bool handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
200 
201  for (int i = 0; i < actions.size() && !handled; i++)
202  {
203  QString action = actions[i];
204  handled = true;
205 
206  if (action == "MENU")
207  menu();
208  else if (action == "DELETE")
209  del();
210  else if (action == "EDIT")
211  edit();
212  else
213  handled = false;
214  }
215 
216  if (!handled && MythScreenType::keyPressEvent(event))
217  handled = true;
218 
219  return handled;
220 }
221 
223 {
224  if (!item)
225  return;
226 
227  if (m_preview)
228  {
229  m_preview->Reset();
230  QString iconpath = item->GetImageFilename();
231  if (!iconpath.isEmpty())
232  {
233  // mythtv-setup needs direct access to channel icon dir to import. We
234  // also can't rely on the backend to be running, so access the file directly.
235  QString tmpIcon = GetConfDir() + "/channels/" + iconpath;
236  m_preview->SetFilename(tmpIcon);
237  m_preview->Load();
238  }
239  }
240 
241  if (m_channame)
242  m_channame->SetText(item->GetText("name"));
243 
244  if (m_channum)
245  m_channum->SetText(item->GetText("channum"));
246 
247  if (m_callsign)
248  m_callsign->SetText(item->GetText("callsign"));
249 
250  if (m_chanid)
251  m_chanid->SetText(item->GetText("chanid"));
252 
253  if (m_serviceid)
254  m_serviceid->SetText(item->GetText("serviceid"));
255 
256  if (m_frequency)
257  m_frequency->SetText(item->GetText("frequency"));
258 
259  if (m_transportid)
260  m_transportid->SetText(item->GetText("transportid"));
261 
262  if (m_sourcename)
263  m_sourcename->SetText(item->GetText("sourcename"));
264 
265  if (m_compoundname)
266  m_compoundname->SetText(item->GetText("compoundname"));
267 }
268 
270 {
271  // Index of current item and offset to the first displayed item
272  int currentIndex = std::max(m_channelList->GetCurrentPos(), 0);
273  int currentTopItemPos = std::max(m_channelList->GetTopItemPos(), 0);
274  int posOffset = currentIndex - currentTopItemPos;
275 
276  // Identify the current item in the list with the new sorting order
278  QString currentServiceID;
279  QString currentTransportID;
280  QString currentSourceName;
281  if (currentItem)
282  {
283  currentServiceID = currentItem->GetText("serviceid");
284  currentTransportID = currentItem->GetText("transportid");
285  currentSourceName = currentItem->GetText("sourcename");
286  }
287 
288  m_channelList->Reset();
289  QString newchanlabel = tr("(Add New Channel)");
290  auto *item = new MythUIButtonListItem(m_channelList, "");
291  item->SetText(newchanlabel, "compoundname");
292  item->SetText(newchanlabel, "name");
293 
294  bool fAllSources = true;
295 
296  QString querystr = "SELECT channel.name, channum, chanid, callsign, icon, "
297  "channel.visible, videosource.name, serviceid, "
298  "dtv_multiplex.frequency, dtv_multiplex.polarity, "
299  "dtv_multiplex.transportid, dtv_multiplex.mod_sys, "
300  "channel.sourceid FROM channel "
301  "LEFT JOIN videosource ON "
302  "(channel.sourceid = videosource.sourceid) "
303  "LEFT JOIN dtv_multiplex ON "
304  "(channel.mplexid = dtv_multiplex.mplexid) "
305  "WHERE deleted IS NULL ";
306 
307  if (m_sourceFilter == FILTER_ALL)
308  {
309  fAllSources = true;
310  }
311  else
312  {
313  querystr += QString("AND channel.sourceid='%1' ")
314  .arg(m_sourceFilter);
315  fAllSources = false;
316  }
317 
318  if (m_currentSortMode == tr("Channel Name"))
319  {
320  querystr += " ORDER BY channel.name, dtv_multiplex.transportid, serviceid, channel.sourceid";
321  }
322  else if (m_currentSortMode == tr("Channel Number"))
323  {
324  querystr += " ORDER BY channum + 0, SUBSTRING_INDEX(channum, '_', -1) + 0, dtv_multiplex.transportid, serviceid, channel.sourceid";
325  }
326  else if (m_currentSortMode == tr("Service ID"))
327  {
328  querystr += " ORDER BY serviceid, dtv_multiplex.transportid, channel.sourceid";
329  }
330  else if (m_currentSortMode == tr("Frequency"))
331  {
332  querystr += " ORDER BY dtv_multiplex.frequency, dtv_multiplex.transportid, serviceid, channel.sourceid";
333  }
334  else if (m_currentSortMode == tr("Transport ID"))
335  {
336  querystr += " ORDER BY dtv_multiplex.transportid, serviceid";
337  }
338  else if (m_currentSortMode == tr("Video Source"))
339  {
340  querystr += " ORDER BY channel.sourceid, dtv_multiplex.transportid, serviceid";
341  }
342 
343  MSqlQuery query(MSqlQuery::InitCon());
344  query.prepare(querystr);
345 
346  int selidx = 0;
347  int idx = 1;
348  if (query.exec() && query.size() > 0)
349  {
350  for (; query.next() ; idx++)
351  {
352  QString name = query.value(0).toString();
353  QString channum = query.value(1).toString();
354  QString chanid = query.value(2).toString();
355  QString callsign = query.value(3).toString();
356  QString icon = query.value(4).toString();
357  bool visible = query.value(5).toBool();
358  QString serviceid = query.value(7).toString();
359  QString frequency = query.value(8).toString();
360  QString polarity = query.value(9).toString().toUpper();
361  QString transportid = query.value(10).toString();
362  QString mod_sys = query.value(11).toString();
363  QString sourcename = "Unassigned";
364 
365  // Add polarity for satellite frequencies
366  if (mod_sys.startsWith("DVB-S"))
367  {
368  frequency += polarity;
369  }
370 
371  QString state = "normal";
372 
373  if (!visible)
374  state = "disabled";
375 
376  if (!query.value(6).toString().isEmpty())
377  {
378  sourcename = query.value(6).toString();
379  if (fAllSources && m_sourceFilter == FILTER_UNASSIGNED)
380  continue;
381  }
382  else
383  state = "warning";
384 
385  // Also hide channels that are not visible
386  if ((!visible || channum.isEmpty()) && m_currentHideMode)
387  continue;
388 
389  if (name.isEmpty())
390  name = "(Unnamed : " + chanid + ")";
391 
392  QString compoundname = name;
393 
394  if (m_currentSortMode == tr("Channel Name"))
395  {
396  if (!channum.isEmpty())
397  compoundname += " (" + channum + ")";
398  }
399  else if (m_currentSortMode == tr("Channel Number"))
400  {
401  if (!channum.isEmpty())
402  compoundname = channum + ". " + compoundname;
403  else
404  compoundname = "???. " + compoundname;
405  }
406 
407  if (m_sourceFilter == FILTER_ALL)
408  compoundname += " (" + sourcename + ")";
409 
410  bool sel = ((serviceid == currentServiceID ) &&
411  (transportid == currentTransportID) &&
412  (sourcename == currentSourceName ));
413  selidx = (sel) ? idx : selidx;
414 
415  item = new MythUIButtonListItem(m_channelList, "", QVariant::fromValue(chanid));
416  item->SetText(compoundname, "compoundname");
417  item->SetText(chanid, "chanid");
418  item->SetText(channum, "channum");
419  item->SetText(name, "name");
420  item->SetText(callsign, "callsign");
421  item->SetText(serviceid, "serviceid");
422  item->SetText(frequency, "frequency");
423  item->SetText(transportid, "transportid");
424  item->SetText(sourcename, "sourcename");
425 
426  // mythtv-setup needs direct access to channel icon dir to import. We
427  // also can't rely on the backend to be running, so access the file directly.
428  QString tmpIcon = GetConfDir() + "/channels/" + icon;
429  item->SetImage(tmpIcon);
430  item->SetImage(tmpIcon, "icon");
431 
432  item->DisplayState(state, "status");
433  }
434  }
435 
436  // Make sure we select the current item, or the following one after
437  // deletion, with wrap around to "(New Channel)" after deleting last item.
438  // Preserve the position on the screen of the current item as much as possible
439  // when the sorting order is changed.
440 
441  // Index of current item
442  int newPosition = (!selidx && currentIndex < idx) ? currentIndex : selidx;
443 
444  // Index of item on top line
445  int newTopPosition = newPosition - posOffset;
446 
447  // Correction for number of items from first item to current item.
448  newTopPosition = std::max(newTopPosition, 0);
449 
450  // Correction for number of items from current item to last item.
451  int getCount = m_channelList->GetCount();
452  int getVisibleCount = m_channelList->GetVisibleCount();
453  newTopPosition = std::min(newTopPosition, getCount - getVisibleCount);
454 
455  m_channelList->SetItemCurrent(newPosition, newTopPosition);
456 }
457 
459 {
460  if (!item)
461  return;
462 
463  QString sortName = item->GetText();
464 
465  if (m_currentSortMode != sortName)
466  {
467  m_currentSortMode = sortName;
468  fillList();
469  }
470 }
471 
473 {
474  if (!item)
475  return;
476 
477  QString sourceName = item->GetText();
478  int sourceID = item->GetData().toInt();
479 
480  if (m_sourceFilter != sourceID)
481  {
482  m_sourceFilterName = sourceName;
483  m_sourceFilter = sourceID;
484  fillList();
485  }
486 }
487 
489 {
490  if (m_currentHideMode != hide)
491  {
492  m_currentHideMode = hide;
493  fillList();
494  }
495 }
496 
498 {
500 
501  if (!item)
502  return;
503 
504  QString message = tr("Delete channel '%1'?").arg(item->GetText("name"));
505 
506  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
507  auto *dialog = new MythConfirmationDialog(popupStack, message, true);
508 
509  if (dialog->Create())
510  {
511  dialog->SetData(QVariant::fromValue(item));
512  dialog->SetReturnEvent(this, "delsingle");
513  popupStack->AddScreen(dialog);
514  }
515  else
516  delete dialog;
517 
518 }
519 
521 {
522  const QString currentLabel = m_sourceList->GetValue();
523 
524  bool del_all = m_sourceFilter == FILTER_ALL;
525  bool del_nul = m_sourceFilter == FILTER_UNASSIGNED;
526 
527  QString message =
528  (del_all) ? tr("Delete ALL channels?") :
529  ((del_nul) ? tr("Delete all unassigned channels?") :
530  tr("Delete all channels on %1?").arg(currentLabel));
531 
532  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
533  auto *dialog = new MythConfirmationDialog(popupStack, message, true);
534 
535  if (dialog->Create())
536  {
537  dialog->SetReturnEvent(this, "delall");
538  popupStack->AddScreen(dialog);
539  }
540  else
541  delete dialog;
542 }
543 
545 {
546  if (!item)
547  item = m_channelList->GetItemCurrent();
548 
549  if (!item)
550  return;
551 
553 
554  int chanid = item->GetData().toInt();
555  auto *cw = new ChannelWizard(chanid, m_sourceFilter);
556  auto *ssd = new StandardSettingDialog(mainStack, "channelwizard", cw);
557  if (ssd->Create())
558  {
559  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
560  mainStack->AddScreen(ssd);
561  }
562  else
563  delete ssd;
564 }
565 
567 {
569 
570  if (!item)
571  return;
572 
573  int chanid = item->GetData().toInt();
574  if (chanid == 0)
575  edit(item);
576  else
577  {
578  QString label = tr("Channel Options");
579 
580  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
581 
582  auto *menu = new MythDialogBox(label, popupStack, "chanoptmenu");
583 
584  if (menu->Create())
585  {
586  menu->SetReturnEvent(this, "channelopts");
587 
588  menu->AddButton(tr("Edit"));
589 // if ()
590 // menu->AddButton(tr("Set Hidden"));
591 // else
592 // menu->AddButton(tr("Set Visible"));
593  menu->AddButton(tr("Delete"));
594 
595  popupStack->AddScreen(menu);
596  }
597  else
598  {
599  delete menu;
600  return;
601  }
602  }
603 }
604 
605 // Check that we have a video source and that at least one
606 // capture card is connected to the video source.
607 //
608 static bool check_cardsource(int sourceid, QString &sourcename)
609 {
610  // Check for videosource
611  if (sourceid < 1)
612  {
613  MythConfirmationDialog *md = ShowOkPopup(QObject::tr(
614  "Select a video source. 'All' cannot be used. "
615  "If there is no video source then create one in the "
616  "'Video sources' menu page and connect a capture card."));
617  WaitFor(md);
618  return false;
619  }
620 
621  // Check for a connected capture card
622  MSqlQuery query(MSqlQuery::InitCon());
623  query.prepare(
624  "SELECT capturecard.cardid "
625  "FROM capturecard "
626  "WHERE capturecard.sourceid = :SOURCEID AND "
627  " capturecard.hostname = :HOSTNAME");
628  query.bindValue(":SOURCEID", sourceid);
629  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
630 
631  if (!query.exec() || !query.isActive())
632  {
633  MythDB::DBError("check_capturecard()", query);
634  return false;
635  }
636  uint cardid = 0;
637  if (query.next())
638  cardid = query.value(0).toUInt();
639 
640  if (cardid < 1)
641  {
642  MythConfirmationDialog *md = ShowOkPopup(QObject::tr(
643  "No capture card!"
644  "\n"
645  "Connect video source '%1' to a capture card "
646  "in the 'Input Connections' menu page.")
647  .arg(sourcename));
648  WaitFor(md);
649  return false;
650  }
651 
652  // At least one capture card connected to the video source
653  // must be able to do channel scanning
654  if (SourceUtil::IsUnscanable(sourceid))
655  {
656  MythConfirmationDialog *md = ShowOkPopup(QObject::tr(
657  "The capture card(s) connected to video source '%1' "
658  "cannot be used for channel scanning.")
659  .arg(sourcename));
660  WaitFor(md);
661  return false;
662  }
663 
664  return true;
665 }
666 
668 {
669  // Check that we have a videosource and a connected capture card
671  return;
672 
673  // Create the dialog now that we have a video source and a capture card
675  auto *ssd = new StandardSettingDialog(mainStack, "scanwizard",
677  if (ssd->Create())
678  {
679  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
680  mainStack->AddScreen(ssd);
681  }
682  else
683  delete ssd;
684 }
685 
687 {
688  // Check that we have a videosource and a connected capture card
690  return;
691 
692  // Create the dialog now that we have a video source and a capture card
694 
695  auto *ssd = new StandardSettingDialog(mainStack, "restoredata",
697  if (ssd->Create())
698  {
699  // Reload channel list with fillList after Restore
700  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
701  mainStack->AddScreen(ssd);
702  }
703  else
704  delete ssd;
705 }
706 
708 {
709  // Check that we have a videosource and a connected capture card
711  return;
712 
713  // Create the dialog now that we have a video source and a capture card
715  auto *ssd = new StandardSettingDialog(mainStack, "transporteditor",
717  if (ssd->Create())
718  {
719  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
720  mainStack->AddScreen(ssd);
721  }
722  else
723  delete ssd;
724 }
725 
727 {
728  if (m_channelList->GetCount() == 0)
729  {
730  ShowOkPopup(tr("Add some channels first!"));
731  return;
732  }
733 
734  int channelID = 0;
736  if (item)
737  channelID = item->GetData().toInt();
738 
739  // Get selected channel name from database
740  QString querystr = QString("SELECT channel.name FROM channel "
741  "WHERE chanid='%1'").arg(channelID);
742  QString channelname;
743  MSqlQuery query(MSqlQuery::InitCon());
744  query.prepare(querystr);
745 
746  if (query.exec() && query.next())
747  {
748  channelname = query.value(0).toString();
749  }
750 
751  QString label = tr("Icon Import Options");
752 
753  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
754 
755  auto *menu = new MythDialogBox(label, popupStack, "iconoptmenu");
756 
757  if (menu->Create())
758  {
759  menu->SetReturnEvent(this, "iconimportopt");
760 
761  menu->AddButton(tr("Download all icons..."));
762  menu->AddButton(tr("Rescan for missing icons..."));
763  if (!channelname.isEmpty())
764  menu->AddButtonV(tr("Download icon for %1").arg(channelname),
765  channelname);
766 
767  popupStack->AddScreen(menu);
768  }
769  else
770  {
771  delete menu;
772  return;
773  }
774 }
775 
776 void ChannelEditor::customEvent(QEvent *event)
777 {
778  if (event->type() == DialogCompletionEvent::kEventType)
779  {
780  auto *dce = (DialogCompletionEvent*)(event);
781 
782  QString resultid= dce->GetId();
783  int buttonnum = dce->GetResult();
784 
785  if (resultid == "channelopts")
786  {
787  switch (buttonnum)
788  {
789  case 0 :
791  break;
792  case 1 :
793  del();
794  break;
795  }
796  }
797  else if (resultid == "delsingle" && buttonnum == 1)
798  {
799  auto *item = dce->GetData().value<MythUIButtonListItem *>();
800  if (!item)
801  return;
802  uint chanid = item->GetData().toUInt();
803  if (chanid && ChannelUtil::DeleteChannel(chanid))
804  m_channelList->RemoveItem(item);
805  }
806  else if (resultid == "delall" && buttonnum == 1)
807  {
808  bool del_all = m_sourceFilter == FILTER_ALL;
809  bool del_nul = m_sourceFilter == FILTER_UNASSIGNED;
810 
811  MSqlQuery query(MSqlQuery::InitCon());
812  if (del_all)
813  {
814  query.prepare("TRUNCATE TABLE channel");
815  }
816  else if (del_nul)
817  {
818  query.prepare("SELECT sourceid "
819  "FROM videosource "
820  "GROUP BY sourceid");
821 
822  if (!query.exec() || !query.isActive())
823  {
824  MythDB::DBError("ChannelEditor Delete Channels", query);
825  return;
826  }
827 
828  QString tmp = "";
829  while (query.next())
830  tmp += "'" + query.value(0).toString() + "',";
831 
832  if (tmp.isEmpty())
833  {
834  query.prepare("TRUNCATE TABLE channel");
835  }
836  else
837  {
838  tmp = tmp.left(tmp.length() - 1);
839  query.prepare(QString("UPDATE channel "
840  "SET deleted = NOW() "
841  "WHERE deleted IS NULL AND "
842  " sourceid NOT IN (%1)").arg(tmp));
843  }
844  }
845  else
846  {
847  query.prepare("UPDATE channel "
848  "SET deleted = NOW() "
849  "WHERE deleted IS NULL AND sourceid = :SOURCEID");
850  query.bindValue(":SOURCEID", m_sourceFilter);
851  }
852 
853  if (!query.exec())
854  MythDB::DBError("ChannelEditor Delete Channels", query);
855 
856  fillList();
857  }
858  else if (resultid == "iconimportopt")
859  {
861 
862  ImportIconsWizard *iconwizard = nullptr;
863 
864  QString channelname = dce->GetData().toString();
865 
866  switch (buttonnum)
867  {
868  case 0 : // Import all icons
869  iconwizard = new ImportIconsWizard(mainStack, false);
870  break;
871  case 1 : // Rescan for missing
872  iconwizard = new ImportIconsWizard(mainStack, true);
873  break;
874  case 2 : // Import a single channel icon
875  iconwizard = new ImportIconsWizard(mainStack, true,
876  channelname);
877  break;
878  default:
879  return;
880  }
881 
882  if (iconwizard->Create())
883  {
884  connect(iconwizard, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
885  mainStack->AddScreen(iconwizard);
886  }
887  else
888  {
889  delete iconwizard;
890 
891  if (buttonnum == 2)
892  {
893  // Reload the list since ImportIconsWizard::Create() will return false
894  // if it automatically downloaded an icon for the selected channel
895  fillList();
896  }
897  }
898  }
899  }
900 }
MythUIButton::Clicked
void Clicked()
ChannelEditor::m_sourceFilterName
QString m_sourceFilterName
Definition: channeleditor.h:46
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:216
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:811
WaitFor
bool WaitFor(MythConfirmationDialog *dialog)
Blocks until confirmation dialog exits.
Definition: mythdialogbox.cpp:599
ChannelOptionsFilters
Definition: channelsettings.h:145
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:318
MythUIButtonList::GetTopItemPos
int GetTopItemPos(void) const
Definition: mythuibuttonlist.h:240
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:215
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1587
transporteditor.h
mythuitext.h
MythUIImage
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
StandardSetting::setValue
virtual void setValue(const QString &newValue)
Definition: standardsettings.cpp:170
RestoreData
Definition: restoredata.h:82
LOC
#define LOC
Definition: channeleditor.cpp:29
mythdb.h
ChannelEditor::scan
void scan(void)
Definition: channeleditor.cpp:667
ChannelEditor::m_transportid
MythUIText * m_transportid
Definition: channeleditor.h:61
ChannelEditor::m_callsign
MythUIText * m_callsign
Definition: channeleditor.h:56
ChannelEditor::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: channeleditor.cpp:193
ChannelEditor::m_frequency
MythUIText * m_frequency
Definition: channeleditor.h:60
ChannelUtil::DeleteChannel
static bool DeleteChannel(uint channel_id)
Definition: channelutil.cpp:1785
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:133
MythUIButtonList::RemoveItem
void RemoveItem(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1485
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:966
ChannelEditor::menu
void menu(void)
Definition: channeleditor.cpp:566
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
ChannelWizard::m_cid
ChannelID * m_cid
Definition: channeleditor.h:74
mythdialogbox.h
ChannelEditor::m_currentHideMode
bool m_currentHideMode
Definition: channeleditor.h:48
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MythScreenStack
Definition: mythscreenstack.h:16
ImportIconsWizard::Create
bool Create(void) override
Definition: importicons.cpp:61
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:617
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
ChannelOptionsCommon
Definition: channelsettings.h:125
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
check_cardsource
static bool check_cardsource(int sourceid, QString &sourcename)
Definition: channeleditor.cpp:608
mythdirs.h
MythUIImage::Reset
void Reset(void) override
Reset the image back to the default defined in the theme.
Definition: mythuiimage.cpp:643
mythuibuttonlist.h
ChannelEditor::edit
void edit(MythUIButtonListItem *item=nullptr)
Definition: channeleditor.cpp:544
ScanWizard
Definition: scanwizard.h:44
mythuiimage.h
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1652
mythprogressdialog.h
scanwizard.h
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:113
MythUICheckBox::toggled
void toggled(bool)
SourceUtil::IsAnySourceScanable
static bool IsAnySourceScanable(void)
Definition: sourceutil.cpp:360
ChannelUtil::GetInputTypes
static QStringList GetInputTypes(uint chanid)
Definition: channelutil.cpp:823
ChannelID
Definition: channelsettings.h:20
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
ImportIconsWizard
Definition: importicons.h:30
ChannelEditor::m_channame
MythUIText * m_channame
Definition: channeleditor.h:54
StandardSettingDialog
Definition: standardsettings.h:468
ChannelEditor::customEvent
void customEvent(QEvent *event) override
Definition: channeleditor.cpp:776
StandardSetting::addChild
virtual void addChild(StandardSetting *child)
Definition: standardsettings.cpp:71
sourceutil.h
ChannelEditor::m_sourceList
MythUIButtonList * m_sourceList
Definition: channeleditor.h:51
ChannelEditor::m_serviceid
MythUIText * m_serviceid
Definition: channeleditor.h:59
mythlogging.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:256
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
MythUIButtonList::GetCurrentPos
int GetCurrentPos() const
Definition: mythuibuttonlist.h:238
ChannelOptionsIPTV
Definition: channelsettings.h:151
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:549
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:226
restoredata.h
MythUIType::SetHelpText
void SetHelpText(const QString &text)
Definition: mythuitype.h:175
TransportListEditor
Definition: transporteditor.h:69
ChannelEditor::restoreData
void restoreData(void)
Definition: channeleditor.cpp:686
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
MythUIButton
A single button widget.
Definition: mythuibutton.h:21
ChannelOptionsRawTS
Definition: channelsettings.h:163
ChannelEditor::m_channelList
MythUIButtonList * m_channelList
Definition: channeleditor.h:50
ChannelEditor::del
void del(void)
Definition: channeleditor.cpp:497
ChannelEditor::m_channum
MythUIText * m_channum
Definition: channeleditor.h:55
MythUIType::SetEnabled
void SetEnabled(bool enable)
Definition: mythuitype.cpp:1131
SourceUtil::IsUnscanable
static bool IsUnscanable(uint sourceid)
Definition: sourceutil.cpp:342
StandardSetting::getValue
virtual QString getValue(void) const
Definition: standardsettings.h:52
ChannelEditor::deleteChannels
void deleteChannels(void)
Definition: channeleditor.cpp:520
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3665
uint
unsigned int uint
Definition: compat.h:81
MythUIButtonList::GetVisibleCount
int GetVisibleCount()
Definition: mythuibuttonlist.cpp:1657
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
MythUICheckBox
A checkbox widget supporting three check states - on,off,half and two conditions - selected and unsel...
Definition: mythuicheckbox.h:15
CardUtil::IsV4L
static bool IsV4L(const QString &rawtype)
Definition: cardutil.h:145
channeleditor.h
StandardSetting::setLabel
virtual void setLabel(QString str)
Definition: standardsettings.h:34
channelutil.h
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3315
ChannelEditor::setSourceID
void setSourceID(MythUIButtonListItem *item)
Definition: channeleditor.cpp:472
ChannelEditor::channelIconImport
void channelIconImport(void)
Definition: channeleditor.cpp:726
ChannelEditor::m_compoundname
MythUIText * m_compoundname
Definition: channeleditor.h:62
ChannelEditor::m_chanid
MythUIText * m_chanid
Definition: channeleditor.h:57
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
ChannelEditor::m_sourcename
MythUIText * m_sourcename
Definition: channeleditor.h:58
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:272
mythcorecontext.h
ChannelOptionsV4L
Definition: channelsettings.h:157
mythuitextedit.h
MythUICheckBox::SetCheckState
void SetCheckState(MythUIStateType::StateType state)
Definition: mythuicheckbox.cpp:66
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:695
cardutil.h
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:887
ChannelEditor::Create
bool Create(void) override
Definition: channeleditor.cpp:76
ChannelEditor::setHideMode
void setHideMode(bool hide)
Definition: channeleditor.cpp:488
ChannelEditor::fillList
void fillList()
Definition: channeleditor.cpp:269
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
ChannelEditor::FILTER_UNASSIGNED
@ FILTER_UNASSIGNED
Definition: channeleditor.h:42
MythUIButtonList::GetValue
virtual QString GetValue() const
Definition: mythuibuttonlist.cpp:1606
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:132
channelsettings.h
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
ChannelEditor::setSortMode
void setSortMode(MythUIButtonListItem *item)
Definition: channeleditor.cpp:458
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1554
ChannelEditor::m_preview
MythUIImage * m_preview
Definition: channeleditor.h:53
build_compdb.action
action
Definition: build_compdb.py:9
MythScreenType::Exiting
void Exiting()
mythuibutton.h
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:323
ChannelEditor::transportEditor
void transportEditor(void)
Definition: channeleditor.cpp:707
CardUtil::GetInputTypeNames
static QStringList GetInputTypeNames(uint sourceid)
Get a list of card input types for a source id.
Definition: cardutil.cpp:368
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:837
ChannelEditor::m_currentSortMode
QString m_currentSortMode
Definition: channeleditor.h:47
ChannelWizard
Definition: channeleditor.h:67
MythUIButtonListItem::GetImageFilename
QString GetImageFilename(const QString &name="") const
Definition: mythuibuttonlist.cpp:3523
ChannelEditor::m_sourceFilter
int m_sourceFilter
Definition: channeleditor.h:45
ChannelEditor::itemChanged
void itemChanged(MythUIButtonListItem *item)
Definition: channeleditor.cpp:222
mythuicheckbox.h
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:674
ChannelWizard::ChannelWizard
ChannelWizard(int id, int default_sourceid)
Definition: channeleditor.cpp:31
MythUIButtonList::SetValue
virtual void SetValue(int value)
Definition: mythuibuttonlist.h:214
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
ChannelEditor::ChannelEditor
ChannelEditor(MythScreenStack *parent)
Definition: channeleditor.cpp:70
ChannelEditor::FILTER_ALL
@ FILTER_ALL
Definition: channeleditor.h:41
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
importicons.h
common
Definition: mythtv/programs/scripts/metadata/Music/lyrics/common/__init__.py:1
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:836