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