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 (int i = 0; i < files.size(); ++i)
54  {
55  m_tmpDir.remove(files.at(i));
56  }
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) .arg(entry.strName) .arg(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  .arg(escape_csv(entry2.strName))
201  .arg(escape_csv(entry2.strXmlTvId))
202  .arg(escape_csv(entry2.strCallsign))
203  .arg(escape_csv(entry2.strTransportId))
204  .arg(escape_csv(entry2.strAtscMajorChan))
205  .arg(escape_csv(entry2.strAtscMinorChan))
206  .arg(escape_csv(entry2.strNetworkId))
207  .arg(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  .arg("/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 
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  {
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  .arg(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  arg(escape_csv(entry.strName)).
354  arg(escape_csv(entry.strXmlTvId)).
355  arg(escape_csv(entry.strCallsign)).
356  arg(escape_csv(entry.strTransportId)).
359  arg(escape_csv(entry.strNetworkId)).
360  arg(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")
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  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()).arg(strParam));
549 
550  if (GetMythDownloadManager()->post(req, &data))
551  {
552  LOG(VB_CHANNEL, LOG_DEBUG, QString("ImportIconsWizard: result: %1").arg(QString(data)));
553  return QString(data);
554  }
555 
556  return QString();
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 
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  .arg(escape_csv(QUrl::toPercentEncoding(entry2.strXmlTvId)))
647  .arg(escape_csv(QUrl::toPercentEncoding(entry2.strCallsign)))
648  .arg(escape_csv(entry2.strTransportId))
649  .arg(escape_csv(entry2.strAtscMajorChan))
650  .arg(escape_csv(entry2.strAtscMinorChan))
651  .arg(escape_csv(entry2.strNetworkId))
652  .arg(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 (int x = 0; x < strSplit.size(); ++x)
693  {
694  QString row = strSplit[x];
695  if (row != "#" )
696  {
697  QStringList ret = extract_csv(row);
698  LOG(VB_CHANNEL, LOG_INFO,
699  QString("Icon Import: search : %1 %2 %3")
700  .arg(ret[0]).arg(ret[1]).arg(ret[2]));
701  SearchEntry entry;
702  entry.strID = ret[0];
703  entry.strName = ret[1];
704  entry.strLogo = ret[2];
705  m_listSearch.append(entry);
706 
707  MythUIButtonListItem *item = nullptr;
708  if (prevIconName == entry.strName)
709  {
710  QString newname = QString("%1 (%2)").arg(entry.strName)
711  .arg(namei);
712  item = new MythUIButtonListItem(m_iconsList, newname,
713  QVariant::fromValue(entry));
714  namei++;
715  }
716  else
717  {
718  item = new MythUIButtonListItem(m_iconsList, entry.strName,
719  QVariant::fromValue(entry));
720  namei=1;
721  }
722 
723  QString iconname = entry.strName;
724 
725  item->SetImage(entry.strLogo, "icon", false);
726  item->SetText(iconname, "iconname");
727 
728  prevIconName = entry.strName;
729  }
730  }
731 
732  retVal = true;
733  }
735  CloseBusyPopup();
736  return retVal;
737 }
738 
739 bool ImportIconsWizard::findmissing(const QString& strParam)
740 {
741  QString strParam1 = QUrl::toPercentEncoding(strParam);
742  QUrl url(m_url+"/findmissing");
743 
744  QString str = wget(url,"csv="+strParam1);
745  LOG(VB_CHANNEL, LOG_INFO,
746  QString("Icon Import: findmissing : strParam1 = %1. str = %2")
747  .arg(strParam1).arg(str));
748  if (str.isEmpty() || str.startsWith("#"))
749  {
750  return false;
751  }
752  if (str.startsWith("Error", Qt::CaseInsensitive))
753  {
754  LOG(VB_GENERAL, LOG_ERR,
755  QString("Error from findmissing : %1").arg(str));
756  return false;
757  }
758 
759  LOG(VB_CHANNEL, LOG_INFO,
760  QString("Icon Import: Working findmissing : %1") .arg(str));
761 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
762  QStringList strSplit = str.split("\n", QString::SkipEmptyParts);
763 #else
764  QStringList strSplit = str.split("\n", Qt::SkipEmptyParts);
765 #endif
766  for (auto line : qAsConst(strSplit))
767  {
768  if (line[0] == "#")
769  continue;
770 
771  const QStringList ret = extract_csv(line);
772  LOG(VB_CHANNEL, LOG_INFO,
773  QString("Icon Import: findmissing : %1 %2 %3 %4 %5")
774  .arg(ret[0]).arg(ret[1]).arg(ret[2])
775  .arg(ret[3]).arg(ret[4]));
776  checkAndDownload(ret[4], (*m_iter).strChanId);
777  }
778  return true;
779 }
780 
781 void ImportIconsWizard::askSubmit(const QString& strParam)
782 {
783  m_strParam = strParam;
784  QString message = tr("You now have the opportunity to transmit your "
785  "choices back to mythtv.org so that others can "
786  "benefit from your selections.");
787 
788  auto *confirmPopup = new MythConfirmationDialog(m_popupStack, message);
789 
790  confirmPopup->SetReturnEvent(this, "submitresults");
791 
792  if (confirmPopup->Create())
793  m_popupStack->AddScreen(confirmPopup, false);
794 }
795 
797 {
798  QString strParam1 = QUrl::toPercentEncoding(m_strParam);
799  QUrl url(m_url+"/submit");
800 
801  QString str = wget(url,"csv="+strParam1);
802  if (str.isEmpty() || str.startsWith("#") ||
803  str.startsWith("Error", Qt::CaseInsensitive))
804  {
805  LOG(VB_GENERAL, LOG_ERR, QString("Error from submit : %1").arg(str));
806  m_statusText->SetText(tr("Failed to submit icon choices."));
807  return false;
808  }
809 
810  LOG(VB_CHANNEL, LOG_INFO, QString("Icon Import: Working submit : %1")
811  .arg(str));
812 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
813  QStringList strSplit = str.split("\n", QString::SkipEmptyParts);
814 #else
815  QStringList strSplit = str.split("\n", Qt::SkipEmptyParts);
816 #endif
817  unsigned atsc = 0;
818  unsigned dvb = 0;
819  unsigned callsign = 0;
820  unsigned tv = 0;
821  unsigned xmltvid = 0;
822  for (auto line : qAsConst(strSplit))
823  {
824  if (line[0] == "#")
825  continue;
826 
827 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
828  QStringList strSplit2=(line).split(":", QString::SkipEmptyParts);
829 #else
830  QStringList strSplit2=(line).split(":", Qt::SkipEmptyParts);
831 #endif
832  if (strSplit2.size() < 2)
833  continue;
834 
835  QString s = strSplit2[0].trimmed();
836  if (s == "a")
837  atsc = strSplit2[1].toUInt();
838  else if (s == "c")
839  callsign = strSplit2[1].toUInt();
840  else if (s == "d")
841  dvb = strSplit2[1].toUInt();
842  else if (s == "t")
843  tv = strSplit2[1].toUInt();
844  else if (s == "x")
845  xmltvid = strSplit2[1].toUInt();
846  }
847  LOG(VB_CHANNEL, LOG_INFO,
848  QString("Icon Import: working submit : atsc=%1 callsign=%2 "
849  "dvb=%3 tv=%4 xmltvid=%5")
850  .arg(atsc).arg(callsign).arg(dvb).arg(tv).arg(xmltvid));
851  m_statusText->SetText(tr("Icon choices submitted successfully."));
852  return true;
853 }
854 
856 {
857  if (event->type() == DialogCompletionEvent::kEventType)
858  {
859  auto *dce = (DialogCompletionEvent*)(event);
860 
861  QString resultid = dce->GetId();
862  int buttonnum = dce->GetResult();
863 
864  if (resultid == "submitresults")
865  {
866  switch (buttonnum)
867  {
868  case 0 :
869  Close();
870  break;
871  case 1 :
872  submit();
873  Close();
874  break;
875  }
876  }
877  }
878 }
879 
881 {
883 }
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:73
MythUIButton::Clicked
void Clicked()
MSqlQuery::next
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
MSqlQuery
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:126
MythUIProgressDialog::Create
bool Create(void) override
Definition: mythprogressdialog.cpp:130
MSqlQuery::size
int size(void) const
Definition: mythdbcon.h:203
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:98
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:84
ImportIconsWizard::SearchEntry::strName
QString strName
the remote name
Definition: importicons.h:45
mythdb.h
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:402
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: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:198
MythScreenStack
Definition: mythscreenstack.h:16
ImportIconsWizard::m_missingCount
int m_missingCount
the current search point (0..m_missingCount)
Definition: importicons.h:173
arg
arg(title).arg(filename).arg(doDelete))
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: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:33
MythScreenType::OpenBusyPopup
void OpenBusyPopup(const QString &message="")
Definition: mythscreentype.cpp:336
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: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: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:265
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &stackname)
Definition: mythmainwindow.cpp:326
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:3264
MythUIButtonListItem
Definition: mythuibuttonlist.h:28
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:216
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:618
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
remotefile.h
ImportIconsWizard::m_preview
MythUIImage * m_preview
Definition: importicons.h:191
MythUIProgressDialog
Definition: mythprogressdialog.h:60
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:117
MythUIButton::SetText
void SetText(const QString &msg)
Definition: mythuibutton.cpp:226
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:178
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:153
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:222
ImportIconsWizard::m_manualEdit
MythUITextEdit * m_manualEdit
manual edit field
Definition: importicons.h:185
MythUIButton
A single button widget.
Definition: mythuibutton.h:22
filename
QString filename
Definition: mythplugins/mytharchive/mytharchivehelper/main.cpp:637
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:171
MythUIType::SetEnabled
void SetEnabled(bool enable)
Definition: mythuitype.cpp:1109
ImportIconsWizard::Close
void Close() override
Definition: importicons.cpp:880
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:3580
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:59
ImportIconsWizard::SearchEntry
search entry results
Definition: importicons.h:43
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:48
MythUIButtonListItem::GetText
QString GetText(const QString &name="") const
Definition: mythuibuttonlist.cpp:3305
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:29
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:539
MythConfirmationDialog
Dialog asking for user confirmation.
Definition: mythdialogbox.h:222
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:3398
ImportIconsWizard::m_statusText
MythUIText * m_statusText
Definition: importicons.h:189
ImportIconsWizard::askSubmit
void askSubmit(const QString &strParam)
Definition: importicons.cpp:781
MSqlQuery::bindValue
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
MythUIProgressDialog::SetTotal
void SetTotal(uint total)
Definition: mythprogressdialog.cpp:193
DialogCompletionEvent
Event dispatched from MythUI modal dialogs to a listening class containing a result of some form.
Definition: mythdialogbox.h:42
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:134
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:105
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:855
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:64
mythuibutton.h
MythUIButtonListItem::GetImageFilename
QString GetImageFilename(const QString &name="") const
Definition: mythuibuttonlist.cpp:3486
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:144
ImportIconsWizard::submit
bool submit()
submit the icon information back to the remote db
Definition: importicons.cpp:796
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:49
query
MSqlQuery query(MSqlQuery::InitCon())
ImportIconsWizard::CSVEntry::strAtscMinorChan
QString strAtscMinorChan
ATSC minor number.
Definition: importicons.h:66
MythScreenType::CloseBusyPopup
void CloseBusyPopup(void)
Definition: mythscreentype.cpp:354
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:739
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: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:808
ImportIconsWizard::dialogState
dialogState
Definition: importicons.h:52