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 : std::as_const(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  const 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  {
384  state = "warning";
385  }
386 
387  // Also hide channels that are not visible
388  if ((!visible || channum.isEmpty()) && m_currentHideMode)
389  continue;
390 
391  if (name.isEmpty())
392  name = "(Unnamed : " + chanid + ")";
393 
394  QString compoundname = name;
395 
396  if (m_currentSortMode == tr("Channel Name"))
397  {
398  if (!channum.isEmpty())
399  compoundname += " (" + channum + ")";
400  }
401  else if (m_currentSortMode == tr("Channel Number"))
402  {
403  if (!channum.isEmpty())
404  compoundname = channum + ". " + compoundname;
405  else
406  compoundname = "???. " + compoundname;
407  }
408 
409  if (m_sourceFilter == FILTER_ALL)
410  compoundname += " (" + sourcename + ")";
411 
412  bool sel = ((serviceid == currentServiceID ) &&
413  (transportid == currentTransportID) &&
414  (sourcename == currentSourceName ));
415  selidx = (sel) ? idx : selidx;
416 
417  item = new MythUIButtonListItem(m_channelList, "", QVariant::fromValue(chanid));
418  item->SetText(compoundname, "compoundname");
419  item->SetText(chanid, "chanid");
420  item->SetText(channum, "channum");
421  item->SetText(name, "name");
422  item->SetText(callsign, "callsign");
423  item->SetText(serviceid, "serviceid");
424  item->SetText(frequency, "frequency");
425  item->SetText(transportid, "transportid");
426  item->SetText(sourcename, "sourcename");
427 
428  // mythtv-setup needs direct access to channel icon dir to import. We
429  // also can't rely on the backend to be running, so access the file directly.
430  QString tmpIcon = GetConfDir() + "/channels/" + icon;
431  item->SetImage(tmpIcon);
432  item->SetImage(tmpIcon, "icon");
433 
434  item->DisplayState(state, "status");
435  }
436  }
437 
438  // Make sure we select the current item, or the following one after
439  // deletion, with wrap around to "(New Channel)" after deleting last item.
440  // Preserve the position on the screen of the current item as much as possible
441  // when the sorting order is changed.
442 
443  // Index of current item
444  int newPosition = (!selidx && currentIndex < idx) ? currentIndex : selidx;
445 
446  // Index of item on top line
447  int newTopPosition = newPosition - posOffset;
448 
449  // Correction for number of items from first item to current item.
450  newTopPosition = std::max(newTopPosition, 0);
451 
452  // Correction for number of items from current item to last item.
453  int getCount = m_channelList->GetCount();
454  int getVisibleCount = m_channelList->GetVisibleCount();
455  newTopPosition = std::min(newTopPosition, getCount - getVisibleCount);
456 
457  m_channelList->SetItemCurrent(newPosition, newTopPosition);
458 }
459 
461 {
462  if (!item)
463  return;
464 
465  QString sortName = item->GetText();
466 
467  if (m_currentSortMode != sortName)
468  {
469  m_currentSortMode = sortName;
470  fillList();
471  }
472 }
473 
475 {
476  if (!item)
477  return;
478 
479  QString sourceName = item->GetText();
480  int sourceID = item->GetData().toInt();
481 
482  if (m_sourceFilter != sourceID)
483  {
484  m_sourceFilterName = sourceName;
485  m_sourceFilter = sourceID;
486  fillList();
487  }
488 }
489 
491 {
492  if (m_currentHideMode != hide)
493  {
494  m_currentHideMode = hide;
495  fillList();
496  }
497 }
498 
500 {
502 
503  if (!item)
504  return;
505 
506  QString message = tr("Delete channel '%1'?").arg(item->GetText("name"));
507 
508  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
509  auto *dialog = new MythConfirmationDialog(popupStack, message, true);
510 
511  if (dialog->Create())
512  {
513  dialog->SetData(QVariant::fromValue(item));
514  dialog->SetReturnEvent(this, "delsingle");
515  popupStack->AddScreen(dialog);
516  }
517  else
518  {
519  delete dialog;
520  }
521 
522 }
523 
525 {
526  const QString currentLabel = m_sourceList->GetValue();
527 
528  bool del_all = m_sourceFilter == FILTER_ALL;
529  bool del_nul = m_sourceFilter == FILTER_UNASSIGNED;
530 
531  QString message;
532  if (del_all)
533  message = tr("Delete ALL channels?");
534  else if (del_nul)
535  message = tr("Delete all unassigned channels?");
536  else
537  message =tr("Delete all channels on %1?").arg(currentLabel);
538 
539  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
540  auto *dialog = new MythConfirmationDialog(popupStack, message, true);
541 
542  if (dialog->Create())
543  {
544  dialog->SetReturnEvent(this, "delall");
545  popupStack->AddScreen(dialog);
546  }
547  else
548  {
549  delete dialog;
550  }
551 }
552 
554 {
555  if (!item)
556  item = m_channelList->GetItemCurrent();
557 
558  if (!item)
559  return;
560 
562 
563  int chanid = item->GetData().toInt();
564  auto *cw = new ChannelWizard(chanid, m_sourceFilter);
565  auto *ssd = new StandardSettingDialog(mainStack, "channelwizard", cw);
566  if (ssd->Create())
567  {
568  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
569  mainStack->AddScreen(ssd);
570  }
571  else
572  {
573  delete ssd;
574  }
575 }
576 
578 {
580 
581  if (!item)
582  return;
583 
584  int chanid = item->GetData().toInt();
585  if (chanid == 0)
586  edit(item);
587  else
588  {
589  QString label = tr("Channel Options");
590 
591  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
592 
593  auto *menu = new MythDialogBox(label, popupStack, "chanoptmenu");
594 
595  if (menu->Create())
596  {
597  menu->SetReturnEvent(this, "channelopts");
598 
599  menu->AddButton(tr("Edit"));
600 // if ()
601 // menu->AddButton(tr("Set Hidden"));
602 // else
603 // menu->AddButton(tr("Set Visible"));
604  menu->AddButton(tr("Delete"));
605 
606  popupStack->AddScreen(menu);
607  }
608  else
609  {
610  delete menu;
611  return;
612  }
613  }
614 }
615 
616 // Check that we have a video source and that at least one
617 // capture card is connected to the video source.
618 //
619 static bool check_cardsource(int sourceid, QString &sourcename)
620 {
621  // Check for videosource
622  if (sourceid < 1)
623  {
624  MythConfirmationDialog *md = ShowOkPopup(QObject::tr(
625  "Select a video source. 'All' cannot be used. "
626  "If there is no video source then create one in the "
627  "'Video sources' menu page and connect a capture card."));
628  WaitFor(md);
629  return false;
630  }
631 
632  // Check for a connected capture card
633  MSqlQuery query(MSqlQuery::InitCon());
634  query.prepare(
635  "SELECT capturecard.cardid "
636  "FROM capturecard "
637  "WHERE capturecard.sourceid = :SOURCEID AND "
638  " capturecard.hostname = :HOSTNAME");
639  query.bindValue(":SOURCEID", sourceid);
640  query.bindValue(":HOSTNAME", gCoreContext->GetHostName());
641 
642  if (!query.exec() || !query.isActive())
643  {
644  MythDB::DBError("check_capturecard()", query);
645  return false;
646  }
647  uint cardid = 0;
648  if (query.next())
649  cardid = query.value(0).toUInt();
650 
651  if (cardid < 1)
652  {
653  MythConfirmationDialog *md = ShowOkPopup(QObject::tr(
654  "No capture card!"
655  "\n"
656  "Connect video source '%1' to a capture card "
657  "in the 'Input Connections' menu page.")
658  .arg(sourcename));
659  WaitFor(md);
660  return false;
661  }
662 
663  // At least one capture card connected to the video source
664  // must be able to do channel scanning
665  if (SourceUtil::IsUnscanable(sourceid))
666  {
667  MythConfirmationDialog *md = ShowOkPopup(QObject::tr(
668  "The capture card(s) connected to video source '%1' "
669  "cannot be used for channel scanning.")
670  .arg(sourcename));
671  WaitFor(md);
672  return false;
673  }
674 
675  return true;
676 }
677 
679 {
680  // Check that we have a videosource and a connected capture card
682  return;
683 
684  // Create the dialog now that we have a video source and a capture card
686  auto *ssd = new StandardSettingDialog(mainStack, "scanwizard",
688  if (ssd->Create())
689  {
690  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
691  mainStack->AddScreen(ssd);
692  }
693  else
694  {
695  delete ssd;
696  }
697 }
698 
700 {
701  // Check that we have a videosource and a connected capture card
703  return;
704 
705  // Create the dialog now that we have a video source and a capture card
707 
708  auto *ssd = new StandardSettingDialog(mainStack, "restoredata",
710  if (ssd->Create())
711  {
712  // Reload channel list with fillList after Restore
713  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
714  mainStack->AddScreen(ssd);
715  }
716  else
717  {
718  delete ssd;
719  }
720 }
721 
723 {
724  // Check that we have a videosource and a connected capture card
726  return;
727 
728  // Create the dialog now that we have a video source and a capture card
730  auto *ssd = new StandardSettingDialog(mainStack, "transporteditor",
732  if (ssd->Create())
733  {
734  connect(ssd, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
735  mainStack->AddScreen(ssd);
736  }
737  else
738  {
739  delete ssd;
740  }
741 }
742 
744 {
745  if (m_channelList->GetCount() == 0)
746  {
747  ShowOkPopup(tr("Add some channels first!"));
748  return;
749  }
750 
751  int channelID = 0;
753  if (item)
754  channelID = item->GetData().toInt();
755 
756  // Get selected channel name from database
757  QString querystr = QString("SELECT channel.name FROM channel "
758  "WHERE chanid='%1'").arg(channelID);
759  QString channelname;
760  MSqlQuery query(MSqlQuery::InitCon());
761  query.prepare(querystr);
762 
763  if (query.exec() && query.next())
764  {
765  channelname = query.value(0).toString();
766  }
767 
768  QString label = tr("Icon Import Options");
769 
770  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
771 
772  auto *menu = new MythDialogBox(label, popupStack, "iconoptmenu");
773 
774  if (menu->Create())
775  {
776  menu->SetReturnEvent(this, "iconimportopt");
777 
778  menu->AddButton(tr("Download all icons..."));
779  menu->AddButton(tr("Rescan for missing icons..."));
780  if (!channelname.isEmpty())
781  menu->AddButtonV(tr("Download icon for %1").arg(channelname),
782  channelname);
783 
784  popupStack->AddScreen(menu);
785  }
786  else
787  {
788  delete menu;
789  return;
790  }
791 }
792 
793 void ChannelEditor::customEvent(QEvent *event)
794 {
795  if (event->type() == DialogCompletionEvent::kEventType)
796  {
797  auto *dce = (DialogCompletionEvent*)(event);
798 
799  QString resultid= dce->GetId();
800  int buttonnum = dce->GetResult();
801 
802  if (resultid == "channelopts")
803  {
804  switch (buttonnum)
805  {
806  case 0 :
808  break;
809  case 1 :
810  del();
811  break;
812  }
813  }
814  else if (resultid == "delsingle" && buttonnum == 1)
815  {
816  auto *item = dce->GetData().value<MythUIButtonListItem *>();
817  if (!item)
818  return;
819  uint chanid = item->GetData().toUInt();
820  if (chanid && ChannelUtil::DeleteChannel(chanid))
821  m_channelList->RemoveItem(item);
822  }
823  else if (resultid == "delall" && buttonnum == 1)
824  {
825  bool del_all = m_sourceFilter == FILTER_ALL;
826  bool del_nul = m_sourceFilter == FILTER_UNASSIGNED;
827 
828  MSqlQuery query(MSqlQuery::InitCon());
829  if (del_all)
830  {
831  query.prepare("TRUNCATE TABLE channel");
832  }
833  else if (del_nul)
834  {
835  query.prepare("SELECT sourceid "
836  "FROM videosource "
837  "GROUP BY sourceid");
838 
839  if (!query.exec() || !query.isActive())
840  {
841  MythDB::DBError("ChannelEditor Delete Channels", query);
842  return;
843  }
844 
845  QString tmp = "";
846  while (query.next())
847  tmp += "'" + query.value(0).toString() + "',";
848 
849  if (tmp.isEmpty())
850  {
851  query.prepare("TRUNCATE TABLE channel");
852  }
853  else
854  {
855  tmp = tmp.left(tmp.length() - 1);
856  query.prepare(QString("UPDATE channel "
857  "SET deleted = NOW() "
858  "WHERE deleted IS NULL AND "
859  " sourceid NOT IN (%1)").arg(tmp));
860  }
861  }
862  else
863  {
864  query.prepare("UPDATE channel "
865  "SET deleted = NOW() "
866  "WHERE deleted IS NULL AND sourceid = :SOURCEID");
867  query.bindValue(":SOURCEID", m_sourceFilter);
868  }
869 
870  if (!query.exec())
871  MythDB::DBError("ChannelEditor Delete Channels", query);
872 
873  fillList();
874  }
875  else if (resultid == "iconimportopt")
876  {
878 
879  ImportIconsWizard *iconwizard = nullptr;
880 
881  QString channelname = dce->GetData().toString();
882 
883  switch (buttonnum)
884  {
885  case 0 : // Import all icons
886  iconwizard = new ImportIconsWizard(mainStack, false);
887  break;
888  case 1 : // Rescan for missing
889  iconwizard = new ImportIconsWizard(mainStack, true);
890  break;
891  case 2 : // Import a single channel icon
892  iconwizard = new ImportIconsWizard(mainStack, true,
893  channelname);
894  break;
895  default:
896  return;
897  }
898 
899  if (iconwizard->Create())
900  {
901  connect(iconwizard, &MythScreenType::Exiting, this, &ChannelEditor::fillList);
902  mainStack->AddScreen(iconwizard);
903  }
904  else
905  {
906  delete iconwizard;
907 
908  if (buttonnum == 2)
909  {
910  // Reload the list since ImportIconsWizard::Create() will return false
911  // if it automatically downloaded an icon for the selected channel
912  fillList();
913  }
914  }
915  }
916  }
917 }
MythUIButton::Clicked
void Clicked()
ChannelEditor::m_sourceFilterName
QString m_sourceFilterName
Definition: channeleditor.h:46
MSqlQuery::isActive
bool isActive(void) const
Definition: mythdbcon.h:215
ChannelEditor::FILTER_UNASSIGNED
@ FILTER_UNASSIGNED
Definition: channeleditor.h:42
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:812
WaitFor
bool WaitFor(MythConfirmationDialog *dialog)
Blocks until confirmation dialog exits.
Definition: mythdialogbox.cpp:603
ChannelOptionsFilters
Definition: channelsettings.h:145
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:127
MythMainWindow::GetMainStack
MythScreenStack * GetMainStack()
Definition: mythmainwindow.cpp:317
MythUIButtonList::GetTopItemPos
int GetTopItemPos(void) const
Definition: mythuibuttonlist.h:242
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:214
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1614
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:678
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:1787
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:138
MythUIButtonList::RemoveItem
void RemoveItem(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1512
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:971
ChannelEditor::menu
void menu(void)
Definition: channeleditor.cpp:577
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:204
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:618
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:619
mythdirs.h
MythUIImage::Reset
void Reset(void) override
Reset the image back to the default defined in the theme.
Definition: mythuiimage.cpp:644
mythuibuttonlist.h
ChannelEditor::edit
void edit(MythUIButtonListItem *item=nullptr)
Definition: channeleditor.cpp:553
ScanWizard
Definition: scanwizard.h:44
mythuiimage.h
MythUIButtonList::GetCount
int GetCount() const
Definition: mythuibuttonlist.cpp:1679
mythprogressdialog.h
scanwizard.h
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:110
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:825
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:793
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:240
ChannelEditor::FILTER_ALL
@ FILTER_ALL
Definition: channeleditor.h:41
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:550
MythDB::DBError
static void DBError(const QString &where, const MSqlQuery &query)
Definition: mythdb.cpp:225
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:699
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:203
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:499
ChannelEditor::m_channum
MythUIText * m_channum
Definition: channeleditor.h:55
MythUIType::SetEnabled
void SetEnabled(bool enable)
Definition: mythuitype.cpp:1128
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:524
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3715
uint
unsigned int uint
Definition: compat.h:81
MythUIButtonList::GetVisibleCount
int GetVisibleCount()
Definition: mythuibuttonlist.cpp:1684
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:3368
ChannelEditor::setSourceID
void setSourceID(MythUIButtonListItem *item)
Definition: channeleditor.cpp:474
ChannelEditor::channelIconImport
void channelIconImport(void)
Definition: channeleditor.cpp:743
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:401
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:687
cardutil.h
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:888
ChannelEditor::Create
bool Create(void) override
Definition: channeleditor.cpp:76
ChannelEditor::setHideMode
void setHideMode(bool hide)
Definition: channeleditor.cpp:490
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
MythUIButtonList::GetValue
virtual QString GetValue() const
Definition: mythuibuttonlist.cpp:1633
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
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:460
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MythUIButtonList::SetItemCurrent
void SetItemCurrent(MythUIButtonListItem *item)
Definition: mythuibuttonlist.cpp:1581
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:322
ChannelEditor::transportEditor
void transportEditor(void)
Definition: channeleditor.cpp:722
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:842
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:3573
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:677
ChannelWizard::ChannelWizard
ChannelWizard(int id, int default_sourceid)
Definition: channeleditor.cpp:31
MythUIButtonList::SetValue
virtual void SetValue(int value)
Definition: mythuibuttonlist.h:216
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
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:566
importicons.h
common
Definition: __init__.py:1
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:837