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