MythTV  master
importicons.cpp
Go to the documentation of this file.
1 // Qt
2 #include <QBuffer>
3 #include <QCoreApplication>
4 #include <QDir>
5 #include <QFileInfo>
6 #include <QRegularExpression>
7 
8 // MythTV
10 #include "libmythbase/mythdate.h"
11 #include "libmythbase/mythdb.h"
12 #include "libmythbase/mythdirs.h"
15 #include "libmythbase/remotefile.h"
18 #include "libmythui/mythuibutton.h"
20 #include "libmythui/mythuiimage.h"
21 #include "libmythui/mythuitext.h"
23 
24 // MythTV Setup
25 #include "importicons.h"
26 
28  QString channelname)
29  :MythScreenType(parent, "ChannelIconImporter"),
30  m_strChannelname(std::move(channelname)), m_fRefresh(fRefresh)
31 {
32  if (!m_strChannelname.isEmpty())
33  {
34  LOG(VB_GENERAL, LOG_INFO,
35  QString("Fetching icon for channel %1").arg(m_strChannelname));
36  }
37  else
38  {
39  LOG(VB_GENERAL, LOG_INFO, "Fetching icons for multiple channels");
40  }
41 
42  m_popupStack = GetMythMainWindow()->GetStack("popup stack");
43 
44  m_tmpDir = QDir(QString("%1/tmp/icon").arg(GetConfDir()));
45 
46  if (!m_tmpDir.exists())
47  m_tmpDir.mkpath(m_tmpDir.absolutePath());
48 }
49 
51 {
52  if (m_tmpDir.exists())
53  {
54  QStringList files = m_tmpDir.entryList();
55  for (const QString &file : qAsConst(files))
56  m_tmpDir.remove(file);
57  m_tmpDir.rmpath(m_tmpDir.absolutePath());
58  }
59 }
60 
62 {
63  // Load the theme for this screen
64  bool foundtheme = LoadWindowFromXML("config-ui.xml", "iconimport", this);
65  if (!foundtheme)
66  return false;
67 
68  m_iconsList = dynamic_cast<MythUIButtonList *>(GetChild("icons"));
69  m_manualEdit = dynamic_cast<MythUITextEdit *>(GetChild("manualsearch"));
70  m_nameText = dynamic_cast<MythUIText *>(GetChild("name"));
71  m_manualButton = dynamic_cast<MythUIButton *>(GetChild("search"));
72  m_skipButton = dynamic_cast<MythUIButton *>(GetChild("skip"));
73  m_statusText = dynamic_cast<MythUIText *>(GetChild("status"));
74  m_preview = dynamic_cast<MythUIImage *>(GetChild("preview"));
75  m_previewtitle = dynamic_cast<MythUIText *>(GetChild("previewtitle"));
76 
79  {
80  LOG(VB_GENERAL, LOG_ERR,
81  "Unable to load window 'iconimport', missing required element(s)");
82  return false;
83  }
84 
85  m_nameText->SetEnabled(false);
86 
87  m_nameText->SetHelpText(tr("Name of the icon file"));
88  m_iconsList->SetHelpText(tr("List of possible icon files"));
89  m_manualEdit->SetHelpText(tr("Enter text here for the manual search"));
90  m_manualButton->SetHelpText(tr("Manually search for the text"));
91  m_skipButton->SetHelpText(tr("Skip this icon"));
92 
99 
100  BuildFocusList();
101 
103 
104  return true;
105 }
106 
108 {
110  Close();
111 }
112 
114 {
115  if (m_nMaxCount > 0)
116  {
118  if (!doLoad())
119  {
120  if (!m_strMatches.isEmpty())
122  }
123  }
124 }
125 
127 {
128  switch (state)
129  {
130  case STATE_NORMAL:
132  m_skipButton->SetText(tr("Finish"));
133  else
134  m_skipButton->SetText(tr("Skip"));
135  m_skipButton->SetEnabled(true);
136  m_nameText->SetEnabled(true);
137  m_iconsList->SetEnabled(true);
138  m_manualEdit->SetEnabled(true);
139  m_manualButton->SetEnabled(true);
140  break;
141  case STATE_SEARCHING:
142  m_skipButton->SetEnabled(false);
143  m_manualButton->SetEnabled(false);
144  m_iconsList->SetEnabled(false);
145  m_iconsList->Reset();
146  m_manualEdit->Reset();
147  break;
148  case STATE_DISABLED:
149  m_skipButton->SetEnabled(false);
150  m_manualButton->SetEnabled(false);
151  m_iconsList->SetEnabled(false);
152  m_iconsList->Reset();
153  m_nameText->SetEnabled(false);
154  m_nameText->Reset();
155  m_manualEdit->SetEnabled(false);
156  m_manualEdit->Reset();
158  break;
159  }
160 }
161 
163 {
164  QString str = m_manualEdit->GetText();
165  if (!search(str))
166  m_statusText->SetText(tr("No matches found for \"%1\"").arg(str));
167  else
168  m_statusText->Reset();
169 }
170 
172 {
173  m_missingCount++;
174  m_missingIter++;
175 
176  if (!doLoad())
177  {
178  if (!m_strMatches.isEmpty())
180  else
181  Close();
182  }
183 }
184 
186 {
187  if (!item)
188  return;
189 
190  auto entry = item->GetData().value<SearchEntry>();
191 
192  LOG(VB_GENERAL, LOG_INFO, QString("Menu Selection: %1 %2 %3")
193  .arg(entry.strID, entry.strName, entry.strLogo));
194 
196 
197  CSVEntry entry2 = (*m_missingIter);
198  m_strMatches += QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n")
199  .arg(escape_csv(entry.strID),
200  escape_csv(entry2.strName),
201  escape_csv(entry2.strXmlTvId),
202  escape_csv(entry2.strCallsign),
203  escape_csv(entry2.strTransportId),
206  escape_csv(entry2.strNetworkId),
207  escape_csv(entry2.strServiceId));
208 
209  if (checkAndDownload(entry.strLogo, entry2.strChanId))
210  {
211  m_statusText->SetText(tr("Icon for %1 was downloaded successfully.")
212  .arg(entry2.strName));
213  }
214  else
215  {
216  m_statusText->SetText(tr("Failed to download the icon for %1.")
217  .arg(entry2.strName));
218  }
219 
220  if (m_missingMaxCount > 1)
221  {
222  m_missingCount++;
223  m_missingIter++;
224  if (!doLoad())
225  {
226  if (!m_strMatches.isEmpty())
228  else
229  Close();
230  }
231  }
232  else
233  {
235 
237  if (!m_strMatches.isEmpty())
239  else
240  Close();
241  }
242 
243 }
244 
246 {
247  if (!item)
248  return;
249 
250  if (m_preview)
251  {
252  m_preview->Reset();
253  QString iconpath = item->GetImageFilename("icon");
254  if (!iconpath.isEmpty())
255  {
256  m_preview->SetFilename(iconpath);
257  m_preview->Load();
258  }
259  }
260 
261  if (m_previewtitle)
262  m_previewtitle->SetText(item->GetText("iconname"));
263 }
264 
265 bool ImportIconsWizard::initialLoad(const QString& name)
266 {
267 
268  QString dirpath = GetConfDir();
269  QDir configDir(dirpath);
270  if (!configDir.exists() && !configDir.mkdir(dirpath))
271  {
272  LOG(VB_GENERAL, LOG_ERR, QString("Could not create %1").arg(dirpath));
273  }
274 
275  m_strChannelDir = QString("%1/%2").arg(configDir.absolutePath(),
276  "/channels");
277  QDir strChannelDir(m_strChannelDir);
278  if (!strChannelDir.exists() && !strChannelDir.mkdir(m_strChannelDir))
279  {
280  LOG(VB_GENERAL, LOG_ERR,
281  QString("Could not create %1").arg(m_strChannelDir));
282  }
283  m_strChannelDir += "/";
284 
285  bool closeDialog = false;
286 
287  QString querystring("SELECT chanid, name, xmltvid, callsign,"
288  "dtv_multiplex.transportid, atsc_major_chan, "
289  "atsc_minor_chan, dtv_multiplex.networkid, "
290  "channel.serviceid, channel.mplexid,"
291  "dtv_multiplex.mplexid, channel.icon, channel.visible "
292  "FROM channel LEFT JOIN dtv_multiplex "
293  "ON channel.mplexid = dtv_multiplex.mplexid "
294  "WHERE deleted IS NULL AND ");
295  if (!name.isEmpty())
296  querystring.append("name=\"" + name + "\"");
297  else
298  querystring.append("channel.visible > 0");
299  querystring.append(" ORDER BY name");
300 
301  MSqlQuery query(MSqlQuery::InitCon());
302  query.prepare(querystring);
303 
304  m_listEntries.clear();
305  m_nCount=0;
306  m_nMaxCount=0;
308 
309  if (query.exec() && query.size() > 0)
310  {
312  new MythUIProgressDialog(tr("Initializing, please wait..."),
313  m_popupStack, "IconImportInitProgress");
314 
315  if (m_progressDialog->Create())
316  {
318  m_progressDialog->SetTotal(query.size());
319  QCoreApplication::processEvents();
320  }
321  else
322  {
323  delete m_progressDialog;
324  m_progressDialog = nullptr;
325  }
326 
327  while(query.next())
328  {
329  CSVEntry entry;
330  QString relativeIconPath = query.value(11).toString();
331  QString absoluteIconPath = QString("%1%2").arg(m_strChannelDir,
332  relativeIconPath);
333 
334  if (m_fRefresh && !relativeIconPath.isEmpty() &&
335  QFile(absoluteIconPath).exists() &&
336  !QImage(absoluteIconPath).isNull())
337  {
338  LOG(VB_GENERAL, LOG_NOTICE, QString("Icon already exists, skipping (%1)").arg(absoluteIconPath));
339  }
340  else
341  {
342  entry.strChanId=query.value(0).toString();
343  entry.strName=query.value(1).toString();
344  entry.strXmlTvId=query.value(2).toString();
345  entry.strCallsign=query.value(3).toString();
346  entry.strTransportId=query.value(4).toString();
347  entry.strAtscMajorChan=query.value(5).toString();
348  entry.strAtscMinorChan=query.value(6).toString();
349  entry.strNetworkId=query.value(7).toString();
350  entry.strServiceId=query.value(8).toString();
351  entry.strIconCSV= QString("%1,%2,%3,%4,%5,%6,%7,%8,%9\n").
352  arg(escape_csv(entry.strChanId),
353  escape_csv(entry.strName),
354  escape_csv(entry.strXmlTvId),
355  escape_csv(entry.strCallsign),
356  escape_csv(entry.strTransportId),
359  escape_csv(entry.strNetworkId),
360  escape_csv(entry.strServiceId));
361  entry.strNameCSV=escape_csv(entry.strName);
362  LOG(VB_CHANNEL, LOG_INFO,
363  QString("chanid %1").arg(entry.strIconCSV));
364 
365  m_listEntries.append(entry);
366  }
367 
368  m_nMaxCount++;
369  if (m_progressDialog)
370  {
372  QCoreApplication::processEvents();
373  }
374  }
375 
376  if (m_progressDialog)
377  {
379  m_progressDialog = nullptr;
380  }
381  }
382 
383  m_iter = m_listEntries.begin();
384 
386  tr("Downloading, please wait..."), m_popupStack,
387  "IconImportInitProgress");
388 
389  if (m_progressDialog->Create())
390  {
393  QCoreApplication::processEvents();
394  }
395  else
396  {
397  delete m_progressDialog;
398  m_progressDialog = nullptr;
399  }
400 
401  /*: %1 is the current channel position,
402  * %2 is the total number of channels,
403  */
404  QString downloadMessage = tr("Downloading %1 of %2");
405 
406  while (!closeDialog && (m_iter != m_listEntries.end()))
407  {
408  QString message = downloadMessage.arg(m_nCount+1)
409  .arg(m_listEntries.size());
410 
411  LOG(VB_GENERAL, LOG_NOTICE, message);
412 
413  if (!m_missingEntries.empty())
414  {
415  message.append("\n");
416  message.append(tr("Could not find %n icon(s).", "",
417  m_missingEntries.size()));
418  }
419 
420  if (!findmissing((*m_iter).strIconCSV))
421  {
422  m_missingEntries.append((*m_iter));
424  }
425 
426  m_nCount++;
427  m_iter++;
428  if (m_progressDialog)
429  {
430  m_progressDialog->SetMessage(message);
432  QCoreApplication::processEvents();
433  }
434  }
435 
436  if (m_progressDialog)
437  {
439  m_progressDialog = nullptr;
440  }
441 
442  if (m_missingEntries.empty() || closeDialog)
443  return false;
444 
445  if (m_nMaxCount <= 0)
446  return false;
447 
448  return true;
449 }
450 
452 {
453  LOG(VB_CHANNEL, LOG_INFO, QString("Icons: Found %1 / Missing %2")
454  .arg(m_missingCount).arg(m_missingMaxCount));
455 
456  // skip over empty entries
457  while (m_missingIter != m_missingEntries.end() &&
458  (*m_missingIter).strName.isEmpty())
459  {
460  m_missingCount++;
461  m_missingIter++;
462  }
463 
464  if (m_missingIter == m_missingEntries.end())
465  {
466  LOG(VB_CHANNEL, LOG_INFO, "doLoad Icon search complete");
468  return false;
469  }
470 
471  // Look for the next missing icon
472  m_nameText->SetText(tr("Choose icon for channel %1")
473  .arg((*m_missingIter).strName));
474  m_manualEdit->SetText((*m_missingIter).strName);
475  if (!search((*m_missingIter).strName))
476  {
477  m_statusText->SetText(tr("No matches found for %1")
478  .arg((*m_missingIter).strName));
479  }
480  else
481  {
482  m_statusText->Reset();
483  }
484 
485  return true;
486 }
487 
488 QString ImportIconsWizard::escape_csv(const QString& str)
489 {
490  static const QRegularExpression rxDblForEscape("\"");
491  QString str2 = str;
492  str2.replace(rxDblForEscape,"\\\"");
493  return "\""+str2+"\"";
494 }
495 
496 QStringList ImportIconsWizard::extract_csv(const QString &line)
497 {
498  QStringList ret;
499  QString str;
500  bool in_comment = false;
501  bool in_escape = false;
502  int comma_count = 0;
503  for (auto cur : qAsConst(line))
504  {
505  if (in_escape)
506  {
507  str += cur;
508  in_escape = false;
509  }
510  else if (cur == '"')
511  {
512  in_comment = !in_comment;
513  }
514  else if (cur == '\\')
515  {
516  in_escape = true;
517  }
518  else if (!in_comment && (cur == ','))
519  {
520  ret += str;
521  str.clear();
522  ++comma_count;
523  }
524  else
525  {
526  str += cur;
527  }
528  }
529  if (comma_count)
530  ret += str;
531 
532  // This is just to avoid segfaulting, we should add some error recovery
533  while (ret.size() < 5)
534  ret.push_back("");
535 
536  return ret;
537 }
538 
539 QString ImportIconsWizard::wget(QUrl& url, const QString& strParam )
540 {
541  QByteArray data(strParam.toLatin1());
542 
543  auto *req = new QNetworkRequest(url);
544  req->setHeader(QNetworkRequest::ContentTypeHeader, QString("application/x-www-form-urlencoded"));
545  req->setHeader(QNetworkRequest::ContentLengthHeader, data.size());
546 
547  LOG(VB_CHANNEL, LOG_DEBUG, QString("ImportIconsWizard: posting to: %1, params: %2")
548  .arg(url.toString(), strParam));
549 
550  if (GetMythDownloadManager()->post(req, &data))
551  {
552  LOG(VB_CHANNEL, LOG_DEBUG, QString("ImportIconsWizard: result: %1").arg(QString(data)));
553  return {data};
554  }
555 
556  return {};
557 }
558 
559 #include <QTemporaryFile>
560 bool ImportIconsWizard::checkAndDownload(const QString& url, const QString& localChanId)
561 {
562  QString filename = url.section('/', -1);
563  QString filePath = m_strChannelDir + filename;
564 
565  // If we get to this point we've already checked whether the icon already
566  // exist locally, we want to download anyway to fix a broken image or
567  // get the latest version of the icon
568 
569  QTemporaryFile tmpFile(filePath);
570  if (!tmpFile.open())
571  {
572  LOG(VB_GENERAL, LOG_INFO, "Icon Download: Couldn't create temporary file");
573  return false;
574  }
575 
576  bool fRet = GetMythDownloadManager()->download(url, tmpFile.fileName());
577 
578  if (!fRet)
579  {
580  LOG(VB_GENERAL, LOG_INFO,
581  QString("Download for icon %1 failed").arg(filename));
582  return false;
583  }
584 
585  QImage icon(tmpFile.fileName());
586  if (icon.isNull())
587  {
588  LOG(VB_GENERAL, LOG_INFO,
589  QString("Downloaded icon for %1 isn't a valid image").arg(filename));
590  return false;
591  }
592 
593  // Remove any existing icon
594  QFile file(filePath);
595  file.remove();
596 
597  // Rename temporary file & prevent it being cleaned up
598  tmpFile.rename(filePath);
599  tmpFile.setAutoRemove(false);
600 
601  MSqlQuery query(MSqlQuery::InitCon());
602  QString qstr = "UPDATE channel SET icon = :ICON "
603  "WHERE chanid = :CHANID";
604 
605  query.prepare(qstr);
606  query.bindValue(":ICON", filename);
607  query.bindValue(":CHANID", localChanId);
608 
609  if (!query.exec())
610  {
611  MythDB::DBError("Error inserting channel icon", query);
612  return false;
613  }
614 
615  return fRet;
616 }
617 
618 bool ImportIconsWizard::lookup(const QString& strParam)
619 {
620  QString strParam1 = QUrl::toPercentEncoding("callsign="+strParam);
621  QUrl url(m_url+"/lookup");
622 
623  QString str = wget(url,strParam1);
624  if (str.isEmpty() || str.startsWith("Error", Qt::CaseInsensitive))
625  {
626  LOG(VB_GENERAL, LOG_ERR,
627  QString("Error from icon lookup : %1").arg(str));
628  return true;
629  }
630  LOG(VB_CHANNEL, LOG_INFO,
631  QString("Icon Import: Working lookup : %1").arg(str));
632  return false;
633 }
634 
635 bool ImportIconsWizard::search(const QString& strParam)
636 {
637 
638  QString strParam1 = QUrl::toPercentEncoding(strParam);
639  bool retVal = false;
641  QUrl url(m_url+"/search");
642 
643  CSVEntry entry2 = (*m_missingIter);
644  QString channelcsv = QString("%1,%2,%3,%4,%5,%6,%7,%8\n")
645  .arg(escape_csv(QUrl::toPercentEncoding(entry2.strName)),
646  escape_csv(QUrl::toPercentEncoding(entry2.strXmlTvId)),
647  escape_csv(QUrl::toPercentEncoding(entry2.strCallsign)),
648  escape_csv(entry2.strTransportId),
651  escape_csv(entry2.strNetworkId),
652  escape_csv(entry2.strServiceId));
653 
654  QString message = QObject::tr("Searching for icons for channel %1")
655  .arg(entry2.strName);
656 
657  OpenBusyPopup(message);
658 
659  QString str = wget(url,"s="+strParam1+"&csv="+channelcsv);
660  m_listSearch.clear();
661  m_iconsList->Reset();
662 
663  if (str.isEmpty() || str.startsWith("#") ||
664  str.startsWith("Error", Qt::CaseInsensitive))
665  {
666  LOG(VB_GENERAL, LOG_ERR, QString("Error from search : %1").arg(str));
667  retVal = false;
668  }
669  else
670  {
671  LOG(VB_CHANNEL, LOG_INFO,
672  QString("Icon Import: Working search : %1").arg(str));
673  QStringList strSplit = str.split("\n");
674 
675  // HACK HACK HACK -- begin
676  // This is needed since the user can't escape out of the progress dialog
677  // and the result set may contain thousands of channels.
678  if (strSplit.size() > 150)
679  {
680  LOG(VB_GENERAL, LOG_WARNING,
681  QString("Warning: Result set contains %1 items, "
682  "truncating to the first %2 results")
683  .arg(strSplit.size()).arg(150));
684  while (strSplit.size() > 150)
685  strSplit.removeLast();
686  }
687  // HACK HACK HACK -- end
688 
689  QString prevIconName;
690  int namei = 1;
691 
692  for (const QString& row : qAsConst(strSplit))
693  {
694  if (row != "#" )
695  {
696  QStringList ret = extract_csv(row);
697  LOG(VB_CHANNEL, LOG_INFO,
698  QString("Icon Import: search : %1 %2 %3")
699  .arg(ret[0], ret[1], ret[2]));
700  SearchEntry entry;
701  entry.strID = ret[0];
702  entry.strName = ret[1];
703  entry.strLogo = ret[2];
704  m_listSearch.append(entry);
705 
706  MythUIButtonListItem *item = nullptr;
707  if (prevIconName == entry.strName)
708  {
709  QString newname = QString("%1 (%2)").arg(entry.strName)
710  .arg(namei);
711  item = new MythUIButtonListItem(m_iconsList, newname,
712  QVariant::fromValue(entry));
713  namei++;
714  }
715  else
716  {
717  item = new MythUIButtonListItem(m_iconsList, entry.strName,
718  QVariant::fromValue(entry));
719  namei=1;
720  }
721 
722  QString iconname = entry.strName;
723 
724  item->SetImage(entry.strLogo, "icon", false);
725  item->SetText(iconname, "iconname");
726 
727  prevIconName = entry.strName;
728  }
729  }
730 
731  retVal = true;
732  }
734  CloseBusyPopup();
735  return retVal;
736 }
737 
738 bool ImportIconsWizard::findmissing(const QString& strParam)
739 {
740  QString strParam1 = QUrl::toPercentEncoding(strParam);
741  QUrl url(m_url+"/findmissing");
742 
743  QString str = wget(url,"csv="+strParam1);
744  LOG(VB_CHANNEL, LOG_INFO,
745  QString("Icon Import: findmissing : strParam1 = %1. str = %2")
746  .arg(strParam1, str));
747  if (str.isEmpty() || str.startsWith("#"))
748  {
749  return false;
750  }
751  if (str.startsWith("Error", Qt::CaseInsensitive))
752  {
753  LOG(VB_GENERAL, LOG_ERR,
754  QString("Error from findmissing : %1").arg(str));
755  return false;
756  }
757 
758  LOG(VB_CHANNEL, LOG_INFO,
759  QString("Icon Import: Working findmissing : %1") .arg(str));
760 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
761  QStringList strSplit = str.split("\n", QString::SkipEmptyParts);
762 #else
763  QStringList strSplit = str.split("\n", Qt::SkipEmptyParts);
764 #endif
765  for (auto line : qAsConst(strSplit))
766  {
767  if (line[0] == QChar('#'))
768  continue;
769 
770  const QStringList ret = extract_csv(line);
771  LOG(VB_CHANNEL, LOG_INFO,
772  QString("Icon Import: findmissing : %1 %2 %3 %4 %5")
773  .arg(ret[0], ret[1], ret[2], ret[3], ret[4]));
774  checkAndDownload(ret[4], (*m_iter).strChanId);
775  }
776  return true;
777 }
778 
779 void ImportIconsWizard::askSubmit(const QString& strParam)
780 {
781  m_strParam = strParam;
782  QString message = tr("You now have the opportunity to transmit your "
783  "choices back to mythtv.org so that others can "
784  "benefit from your selections.");
785 
786  auto *confirmPopup = new MythConfirmationDialog(m_popupStack, message);
787 
788  confirmPopup->SetReturnEvent(this, "submitresults");
789 
790  if (confirmPopup->Create())
791  m_popupStack->AddScreen(confirmPopup, false);
792 }
793 
795 {
796  QString strParam1 = QUrl::toPercentEncoding(m_strParam);
797  QUrl url(m_url+"/submit");
798 
799  QString str = wget(url,"csv="+strParam1);
800  if (str.isEmpty() || str.startsWith("#") ||
801  str.startsWith("Error", Qt::CaseInsensitive))
802  {
803  LOG(VB_GENERAL, LOG_ERR, QString("Error from submit : %1").arg(str));
804  m_statusText->SetText(tr("Failed to submit icon choices."));
805  return false;
806  }
807 
808  LOG(VB_CHANNEL, LOG_INFO, QString("Icon Import: Working submit : %1")
809  .arg(str));
810 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
811  QStringList strSplit = str.split("\n", QString::SkipEmptyParts);
812 #else
813  QStringList strSplit = str.split("\n", Qt::SkipEmptyParts);
814 #endif
815  unsigned atsc = 0;
816  unsigned dvb = 0;
817  unsigned callsign = 0;
818  unsigned tv = 0;
819  unsigned xmltvid = 0;
820  for (auto line : qAsConst(strSplit))
821  {
822  if (line[0] == QChar('#'))
823  continue;
824 
825 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
826  QStringList strSplit2=(line).split(":", QString::SkipEmptyParts);
827 #else
828  QStringList strSplit2=(line).split(":", Qt::SkipEmptyParts);
829 #endif
830  if (strSplit2.size() < 2)
831  continue;
832 
833  QString s = strSplit2[0].trimmed();
834  if (s == "a")
835  atsc = strSplit2[1].toUInt();
836  else if (s == "c")
837  callsign = strSplit2[1].toUInt();
838  else if (s == "d")
839  dvb = strSplit2[1].toUInt();
840  else if (s == "t")
841  tv = strSplit2[1].toUInt();
842  else if (s == "x")
843  xmltvid = strSplit2[1].toUInt();
844  }
845  LOG(VB_CHANNEL, LOG_INFO,
846  QString("Icon Import: working submit : atsc=%1 callsign=%2 "
847  "dvb=%3 tv=%4 xmltvid=%5")
848  .arg(atsc).arg(callsign).arg(dvb).arg(tv).arg(xmltvid));
849  m_statusText->SetText(tr("Icon choices submitted successfully."));
850  return true;
851 }
852 
854 {
855  if (event->type() == DialogCompletionEvent::kEventType)
856  {
857  auto *dce = (DialogCompletionEvent*)(event);
858 
859  QString resultid = dce->GetId();
860  int buttonnum = dce->GetResult();
861 
862  if (resultid == "submitresults")
863  {
864  switch (buttonnum)
865  {
866  case 0 :
867  Close();
868  break;
869  case 1 :
870  submit();
871  Close();
872  break;
873  }
874  }
875  }
876 }
877 
879 {
881 }
MythUITextEdit::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitextedit.cpp:76
MythUIButton::Clicked
void Clicked()
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:807
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:128
MythUIProgressDialog::Create
bool Create(void) override
Definition: mythprogressdialog.cpp:130
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:215
mythuitext.h
ImportIconsWizard::CSVEntry::strCallsign
QString strCallsign
callsign
Definition: importicons.h:65
MythUIImage
Image widget, displays a single image or multiple images in sequence.
Definition: mythuiimage.h:97
MythUIText::Reset
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:82
ImportIconsWizard::SearchEntry::strName
QString strName
the remote name
Definition: importicons.h:47
mythdb.h
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:386
ImportIconsWizard::itemChanged
void itemChanged(MythUIButtonListItem *item)
Definition: importicons.cpp:245
ImportIconsWizard::escape_csv
static QString escape_csv(const QString &str)
changes a string into csv format
Definition: importicons.cpp:488
ImportIconsWizard::m_popupStack
MythScreenStack * m_popupStack
Definition: importicons.h:183
MythUIType::GetChild
MythUIType * GetChild(const QString &name) const
Get a named child of this UIType.
Definition: mythuitype.cpp:133
MythUIImage::Load
bool Load(bool allowLoadInBackground=true, bool forceStat=false)
Load the image(s), wraps ImageLoader::LoadImage()
Definition: mythuiimage.cpp:969
ImportIconsWizard::CSVEntry::strNameCSV
QString strNameCSV
name (csv form)
Definition: importicons.h:72
DialogCompletionEvent::kEventType
static Type kEventType
Definition: mythdialogbox.h:57
ImportIconsWizard::m_strChannelname
QString m_strChannelname
the channel name if searching for a single channel icon
Definition: importicons.h:168
MythUIButtonList::itemSelected
void itemSelected(MythUIButtonListItem *item)
ImportIconsWizard::m_url
const QString m_url
Definition: importicons.h:178
mythdialogbox.h
MSqlQuery::value
QVariant value(int i) const
Definition: mythdbcon.h:205
MythScreenStack
Definition: mythscreenstack.h:16
ImportIconsWizard::m_missingCount
int m_missingCount
the current search point (0..m_missingCount)
Definition: importicons.h:175
ImportIconsWizard::doLoad
bool doLoad()
attempts to move the iteration on one/more than one
Definition: importicons.cpp:451
ImportIconsWizard::Create
bool Create(void) override
Definition: importicons.cpp:61
ImportIconsWizard::search
bool search(const QString &strParam)
search the remote db for icons etc
Definition: importicons.cpp:635
ImportIconsWizard::CSVEntry::strServiceId
QString strServiceId
service id
Definition: importicons.h:70
MSqlQuery::exec
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:608
MythUITextEdit
A text entry and edit widget.
Definition: mythuitextedit.h:34
MythScreenType::OpenBusyPopup
void OpenBusyPopup(const QString &message="")
Definition: mythscreentype.cpp:320
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
ImportIconsWizard::extract_csv
static QStringList extract_csv(const QString &strLine)
extracts the csv values out of a string
Definition: importicons.cpp:496
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:45
ImportIconsWizard::m_nCount
int m_nCount
the current search point (0..m_nMaxCount)
Definition: importicons.h:173
MythUITextEdit::GetText
QString GetText(void) const
Definition: mythuitextedit.h:50
build_compdb.file
file
Definition: build_compdb.py:55
ImportIconsWizard::CSVEntry::strIconCSV
QString strIconCSV
icon name (csv form)
Definition: importicons.h:71
mythdirs.h
MythUIImage::Reset
void Reset(void) override
Reset the image back to the default defined in the theme.
Definition: mythuiimage.cpp:646
MythUIProgressDialog::SetMessage
void SetMessage(const QString &message)
Definition: mythprogressdialog.cpp:205
ImportIconsWizard::m_manualButton
MythUIButton * m_manualButton
manual button field
Definition: importicons.h:189
ImportIconsWizard::initialLoad
bool initialLoad(const QString &name="")
attempt the inital load of the TV channel information
Definition: importicons.cpp:265
mythuibuttonlist.h
mythuiimage.h
mythprogressdialog.h
ImportIconsWizard::m_iter
ListEntriesIter m_iter
the current iterator
Definition: importicons.h:81
ImportIconsWizard::m_nMaxCount
int m_nMaxCount
the maximum number of TV channels
Definition: importicons.h:172
ImportIconsWizard::m_iconsList
MythUIButtonList * m_iconsList
list of potential icons
Definition: importicons.h:186
ImportIconsWizard::m_listEntries
ListEntries m_listEntries
list of TV channels to search for
Definition: importicons.h:79
MythUIButtonListItem::SetText
void SetText(const QString &text, const QString &name="", const QString &state="")
Definition: mythuibuttonlist.cpp:3268
MythUIButtonListItem
Definition: mythuibuttonlist.h:41
ImportIconsWizard::STATE_NORMAL
@ STATE_NORMAL
Definition: importicons.h:55
ImportIconsWizard::CSVEntry::strName
QString strName
channel name
Definition: importicons.h:63
MythUITextEdit::SetText
void SetText(const QString &text, bool moveCursor=true)
Definition: mythuitextedit.cpp:219
ImportIconsWizard::CSVEntry::strNetworkId
QString strNetworkId
network id
Definition: importicons.h:69
mythdate.h
mythlogging.h
GetConfDir
QString GetConfDir(void)
Definition: mythdirs.cpp:224
ImportIconsWizard::lookup
bool lookup(const QString &strParam)
looks up the string to determine the caller/xmltvid
Definition: importicons.cpp:618
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
remotefile.h
ImportIconsWizard::m_preview
MythUIImage * m_preview
Definition: importicons.h:193
MythUIProgressDialog
Definition: mythprogressdialog.h:59
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:118
MythUIButton::SetText
void SetText(const QString &msg)
Definition: mythuibutton.cpp:227
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
ImportIconsWizard::m_strChannelDir
QString m_strChannelDir
the location of the channel icon dir
Definition: importicons.h:167
ImportIconsWizard::m_missingEntries
ListEntries m_missingEntries
list of TV channels with no unique icon
Definition: importicons.h:80
MythUIProgressDialog::SetProgress
void SetProgress(uint count)
Definition: mythprogressdialog.cpp:199
MythUIType::SetHelpText
void SetHelpText(const QString &text)
Definition: mythuitype.h:175
ImportIconsWizard::enableControls
void enableControls(ImportIconsWizard::dialogState state=STATE_NORMAL)
enable/disable the controls
Definition: importicons.cpp:126
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:206
ImportIconsWizard::m_manualEdit
MythUITextEdit * m_manualEdit
manual edit field
Definition: importicons.h:187
MythUIButton
A single button widget.
Definition: mythuibutton.h:21
MythDownloadManager::download
bool download(const QString &url, const QString &dest, bool reload=false)
Downloads a URL to a file in blocking mode.
Definition: mythdownloadmanager.cpp:430
ImportIconsWizard::STATE_DISABLED
@ STATE_DISABLED
Definition: importicons.h:57
ImportIconsWizard::m_progressDialog
MythUIProgressDialog * m_progressDialog
Definition: importicons.h:184
ImportIconsWizard::skip
void skip()
skip this icon
Definition: importicons.cpp:171
MythUIType::SetEnabled
void SetEnabled(bool enable)
Definition: mythuitype.cpp:1131
ImportIconsWizard::Close
void Close() override
Definition: importicons.cpp:878
ImportIconsWizard::CSVEntry::strXmlTvId
QString strXmlTvId
the xmltvid
Definition: importicons.h:64
ImportIconsWizard::m_strParam
QString m_strParam
Definition: importicons.h:169
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3665
ImportIconsWizard::m_missingIter
ListEntriesIter m_missingIter
Definition: importicons.h:82
ImportIconsWizard::m_tmpDir
QDir m_tmpDir
Definition: importicons.h:179
ImportIconsWizard::m_listSearch
ListSearchEntries m_listSearch
the list of SearchEntry
Definition: importicons.h:164
ImportIconsWizard::CSVEntry
describes the TV channel name
Definition: importicons.h:60
ImportIconsWizard::SearchEntry
search entry results
Definition: importicons.h:44
ImportIconsWizard::checkAndDownload
bool checkAndDownload(const QString &url, const QString &localChanId)
checks and attempts to download the logo file to the appropriate place
Definition: importicons.cpp:560
ImportIconsWizard::~ImportIconsWizard
~ImportIconsWizard() override
Definition: importicons.cpp:50
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3315
ImportIconsWizard::m_strMatches
QString m_strMatches
the string for the submit() call
Definition: importicons.h:165
MythUIText
All purpose text widget, displays a text string.
Definition: mythuitext.h:28
ImportIconsWizard::ImportIconsWizard
ImportIconsWizard(MythScreenStack *parent, bool fRefresh, QString channelname="")
Definition: importicons.cpp:27
ImportIconsWizard::wget
static QString wget(QUrl &url, const QString &strParam)
use the equivalent of wget to fetch the POST command
Definition: importicons.cpp:539
MythConfirmationDialog
Dialog asking for user confirmation. Ok and optional Cancel button.
Definition: mythdialogbox.h:272
mythcorecontext.h
mythuitextedit.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:695
MythUIButtonListItem::SetImage
void SetImage(MythImage *image, const QString &name="")
Sets an image directly, should only be used in special circumstances since it bypasses the cache.
Definition: mythuibuttonlist.cpp:3429
ImportIconsWizard::m_statusText
MythUIText * m_statusText
Definition: importicons.h:191
ImportIconsWizard::askSubmit
void askSubmit(const QString &strParam)
Definition: importicons.cpp:779
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:883
MythUIProgressDialog::SetTotal
void SetTotal(uint total)
Definition: mythprogressdialog.cpp:193
std
Definition: mythchrono.h:23
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:41
ImportIconsWizard::CSVEntry::strAtscMajorChan
QString strAtscMajorChan
ATSC major number.
Definition: importicons.h:67
ImportIconsWizard::m_previewtitle
MythUIText * m_previewtitle
Definition: importicons.h:194
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:132
ImportIconsWizard::CSVEntry::strChanId
QString strChanId
local channel id
Definition: importicons.h:62
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
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:102
ImportIconsWizard::m_missingMaxCount
int m_missingMaxCount
the total number of missing icons
Definition: importicons.h:174
ImportIconsWizard::SearchEntry::strLogo
QString strLogo
the actual logo
Definition: importicons.h:48
ImportIconsWizard::customEvent
void customEvent(QEvent *event) override
Definition: importicons.cpp:853
ImportIconsWizard::menuSelection
void menuSelection(MythUIButtonListItem *item)
process the icon selection
Definition: importicons.cpp:185
ImportIconsWizard::manualSearch
void manualSearch()
process the manual search
Definition: importicons.cpp:162
ImportIconsWizard::CSVEntry::strTransportId
QString strTransportId
transport id
Definition: importicons.h:66
mythuibutton.h
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:320
MythUIButtonListItem::GetImageFilename
QString GetImageFilename(const QString &name="") const
Definition: mythuibuttonlist.cpp:3523
ImportIconsWizard::m_nameText
MythUIText * m_nameText
name field for the icon
Definition: importicons.h:188
ImportIconsWizard::m_fRefresh
bool m_fRefresh
are we doing a refresh or not
Definition: importicons.h:171
ImportIconsWizard::STATE_SEARCHING
@ STATE_SEARCHING
Definition: importicons.h:56
ImportIconsWizard::m_skipButton
MythUIButton * m_skipButton
button skip
Definition: importicons.h:190
MythUIImage::SetFilename
void SetFilename(const QString &filename)
Must be followed by a call to Load() to load the image.
Definition: mythuiimage.cpp:677
mythdownloadmanager.h
MythUIButtonList
List widget, displays list items in a variety of themeable arrangements and can trigger signals when ...
Definition: mythuibuttonlist.h:191
build_compdb.filename
filename
Definition: build_compdb.py:21
ImportIconsWizard::submit
bool submit()
submit the icon information back to the remote db
Definition: importicons.cpp:794
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:50
ImportIconsWizard::CSVEntry::strAtscMinorChan
QString strAtscMinorChan
ATSC minor number.
Definition: importicons.h:68
MythScreenType::CloseBusyPopup
void CloseBusyPopup(void)
Definition: mythscreentype.cpp:338
ImportIconsWizard::Load
void Load(void) override
Load data which will ultimately be displayed on-screen or used to determine what appears on-screen (S...
Definition: importicons.cpp:107
ImportIconsWizard::findmissing
bool findmissing(const QString &strParam)
retrieve the actual logo for the TV channel
Definition: importicons.cpp:738
ImportIconsWizard::Init
void Init(void) override
Used after calling Load() to assign data to widgets and other UI initilisation which is prohibited in...
Definition: importicons.cpp:113
importicons.h
ImportIconsWizard::SearchEntry::strID
QString strID
the remote channel id
Definition: importicons.h:46
GetMythDownloadManager
MythDownloadManager * GetMythDownloadManager(void)
Gets the pointer to the MythDownloadManager singleton.
Definition: mythdownloadmanager.cpp:145
MSqlQuery::prepare
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:832
ImportIconsWizard::dialogState
dialogState
Definition: importicons.h:53