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