MythTV  master
importnative.cpp
Go to the documentation of this file.
1 #include <cstdlib>
2 
3 // Qt
4 #include <QApplication>
5 #include <QDir>
6 #include <QFileInfo>
7 #include <QDomDocument>
8 
9 // Myth
10 #include <mythcontext.h>
11 #include <mythdbcon.h>
12 #include <mythuihelper.h>
13 #include <mythmainwindow.h>
14 #include <mythuitext.h>
15 #include <mythuitextedit.h>
16 #include <mythuibutton.h>
17 #include <mythuibuttonlist.h>
18 #include <mythdialogbox.h>
19 #include <mythsystemlegacy.h>
20 #include <exitcodes.h>
21 #include <mythdate.h>
22 
23 // mytharchive
24 #include "importnative.h"
25 #include "archiveutil.h"
26 #include "logviewer.h"
27 
28 
30 
31 static bool loadDetailsFromXML(const QString &filename, FileDetails *details)
32 {
33  QDomDocument doc("mydocument");
34  QFile file(filename);
35  if (!file.open(QIODevice::ReadOnly))
36  return false;
37 
38  if (!doc.setContent(&file))
39  {
40  file.close();
41  return false;
42  }
43  file.close();
44 
45  QString docType = doc.doctype().name();
46 
47  if (docType == "MYTHARCHIVEITEM")
48  {
49  QDomNodeList itemNodeList = doc.elementsByTagName("item");
50  QString type;
51  QString dbVersion;
52 
53  if (itemNodeList.count() < 1)
54  {
55  LOG(VB_GENERAL, LOG_ERR,
56  "Couldn't find an 'item' element in XML file");
57  return false;
58  }
59 
60  QDomNode n = itemNodeList.item(0);
61  QDomElement e = n.toElement();
62  type = e.attribute("type");
63  dbVersion = e.attribute("databaseversion");
64  if (type == "recording")
65  {
66  QDomNodeList nodeList = e.elementsByTagName("recorded");
67  if (nodeList.count() < 1)
68  {
69  LOG(VB_GENERAL, LOG_ERR,
70  "Couldn't find a 'recorded' element in XML file");
71  return false;
72  }
73 
74  n = nodeList.item(0);
75  e = n.toElement();
76  n = e.firstChild();
77  while (!n.isNull())
78  {
79  e = n.toElement();
80  if (!e.isNull())
81  {
82  if (e.tagName() == "title")
83  details->title = e.text();
84 
85  if (e.tagName() == "subtitle")
86  details->subtitle = e.text();
87 
88  if (e.tagName() == "starttime")
89  details->startTime = MythDate::fromString(e.text());
90 
91  if (e.tagName() == "description")
92  details->description = e.text();
93  }
94  n = n.nextSibling();
95  }
96 
97  // get channel info
98  n = itemNodeList.item(0);
99  e = n.toElement();
100  nodeList = e.elementsByTagName("channel");
101  if (nodeList.count() < 1)
102  {
103  LOG(VB_GENERAL, LOG_ERR,
104  "Couldn't find a 'channel' element in XML file");
105  details->chanID = "";
106  details->chanNo = "";
107  details->chanName = "";
108  details->callsign = "";
109  return false;
110  }
111 
112  n = nodeList.item(0);
113  e = n.toElement();
114  details->chanID = e.attribute("chanid");
115  details->chanNo = e.attribute("channum");
116  details->chanName = e.attribute("name");
117  details->callsign = e.attribute("callsign");
118  return true;
119  }
120  if (type == "video")
121  {
122  QDomNodeList nodeList = e.elementsByTagName("videometadata");
123  if (nodeList.count() < 1)
124  {
125  LOG(VB_GENERAL, LOG_ERR,
126  "Couldn't find a 'videometadata' element in XML file");
127  return false;
128  }
129 
130  n = nodeList.item(0);
131  e = n.toElement();
132  n = e.firstChild();
133  while (!n.isNull())
134  {
135  e = n.toElement();
136  if (!e.isNull())
137  {
138  if (e.tagName() == "title")
139  {
140  details->title = e.text();
141  details->subtitle = "";
142  details->startTime = QDateTime();
143  }
144 
145  if (e.tagName() == "plot")
146  {
147  details->description = e.text();
148  }
149  }
150  n = n.nextSibling();
151  }
152 
153  details->chanID = "N/A";
154  details->chanNo = "N/A";
155  details->chanName = "N/A";
156  details->callsign = "N/A";
157 
158  return true;
159  }
160  }
161 
162  return false;
163 }
164 
166 
168  FileSelector(parent, nullptr, FSTYPE_FILE, "", "*.xml")
169 {
170  m_curDirectory = gCoreContext->GetSetting("MythNativeLoadFilename", "/");
171 }
172 
174 {
175  gCoreContext->SaveSetting("MythNativeLoadFilename", m_curDirectory);
176 }
177 
179 {
180  // Load the theme for this screen
181  bool foundtheme = LoadWindowFromXML("mythnative-ui.xml", "archivefile_selector", this);
182  if (!foundtheme)
183  return false;
184 
185  bool err = false;
186  UIUtilW::Assign(this, m_titleText, "title");
187  UIUtilE::Assign(this, m_fileButtonList, "filelist", &err);
188  UIUtilE::Assign(this, m_locationEdit, "location_edit", &err);
189  UIUtilE::Assign(this, m_backButton, "back_button", &err);
190  UIUtilE::Assign(this, m_homeButton, "home_button", &err);
191  UIUtilE::Assign(this, m_nextButton, "next_button", &err);
192  UIUtilE::Assign(this, m_prevButton, "prev_button", &err);
193  UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err);
194  UIUtilE::Assign(this, m_progTitle, "title_text", &err);
195  UIUtilE::Assign(this, m_progSubtitle, "subtitle_text", &err);
196  UIUtilE::Assign(this, m_progStartTime, "starttime_text", &err);
197 
198  if (err)
199  {
200  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'archivefile_selector'");
201  return false;
202  }
203 
204  if (m_titleText)
205  m_titleText->SetText(tr("Find File To Import"));
206 
207  connect(m_nextButton, SIGNAL(Clicked()), this, SLOT(nextPressed()));
208  connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(cancelPressed()));
209  connect(m_prevButton, SIGNAL(Clicked()), this, SLOT(prevPressed()));
210 
211  connect(m_locationEdit, SIGNAL(LosingFocus()),
212  this, SLOT(locationEditLostFocus()));
214 
215  connect(m_backButton, SIGNAL(Clicked()), this, SLOT(backPressed()));
216  connect(m_homeButton, SIGNAL(Clicked()), this, SLOT(homePressed()));
217 
219  this, SLOT(itemSelected(MythUIButtonListItem *)));
220 
222  this, SLOT(itemClicked(MythUIButtonListItem *)));
223 
224  BuildFocusList();
225 
227 
229  updateFileList();
230 
231  return true;
232 }
233 
235 {
236  m_xmlFile.clear();
237 
238  if (!item)
239  return;
240 
241  auto *fileData = item->GetData().value<FileData*>();
242  if (!fileData)
243  return;
244 
245  if (loadDetailsFromXML(m_curDirectory + "/" + fileData->filename, &m_details))
246  {
247  m_xmlFile = m_curDirectory + "/" + fileData->filename;
251  .toString("dd MMM yy (hh:mm)"));
252  }
253  else
254  {
255  m_progTitle->Reset();
258  }
259 }
260 
262 {
263  if (m_xmlFile == "")
264  {
265  ShowOkPopup(tr("The selected item is not a valid archive file!"));
266  }
267  else
268  {
270 
271  auto *native = new ImportNative(mainStack, this, m_xmlFile, m_details);
272 
273  if (native->Create())
274  mainStack->AddScreen(native);
275  }
276 }
277 
279 {
280  Close();
281 }
282 
284 {
285  Close();
286 }
287 
289 
291 {
292  // Load the theme for this screen
293  bool foundtheme = LoadWindowFromXML("mythnative-ui.xml", "importnative", this);
294  if (!foundtheme)
295  return false;
296 
297  bool err = false;
298  UIUtilE::Assign(this, m_progTitleText, "progtitle", &err);
299  UIUtilE::Assign(this, m_progDateTimeText, "progdatetime", &err);
300  UIUtilE::Assign(this, m_progDescriptionText, "progdescription", &err);
301 
302  UIUtilE::Assign(this, m_chanIDText, "chanid", &err);
303  UIUtilE::Assign(this, m_chanNoText, "channo", &err);
304  UIUtilE::Assign(this, m_chanNameText, "name", &err);
305  UIUtilE::Assign(this, m_callsignText, "callsign", &err);
306 
307  UIUtilE::Assign(this, m_localChanIDText, "local_chanid", &err);
308  UIUtilE::Assign(this, m_localChanNoText, "local_channo", &err);
309  UIUtilE::Assign(this, m_localChanNameText, "local_name", &err);
310  UIUtilE::Assign(this, m_localCallsignText, "local_callsign", &err);
311 
312  UIUtilE::Assign(this, m_searchChanIDButton, "searchchanid_button", &err);
313  UIUtilE::Assign(this, m_searchChanNoButton, "searchchanno_button", &err);
314  UIUtilE::Assign(this, m_searchChanNameButton, "searchname_button", &err);
315  UIUtilE::Assign(this, m_searchCallsignButton ,"searchcallsign_button", &err);
316 
317  UIUtilE::Assign(this, m_finishButton, "finish_button", &err);
318  UIUtilE::Assign(this, m_prevButton, "prev_button", &err);
319  UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err);
320 
321  if (err)
322  {
323  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'importarchive'");
324  return false;
325  }
326 
327  connect(m_finishButton, SIGNAL(Clicked()), this, SLOT(finishedPressed()));
328  connect(m_prevButton, SIGNAL(Clicked()), this, SLOT(prevPressed()));
329  connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(cancelPressed()));
330 
331  connect(m_searchChanIDButton, SIGNAL(Clicked()), this, SLOT(searchChanID()));
332  connect(m_searchChanNoButton, SIGNAL(Clicked()), this, SLOT(searchChanNo()));
333  connect(m_searchChanNameButton, SIGNAL(Clicked()), this, SLOT(searchName()));
334  connect(m_searchCallsignButton, SIGNAL(Clicked()), this, SLOT(searchCallsign()));
335 
337 
339  .toString("dd MMM yy (hh:mm)"));
341  (m_details.subtitle == "" ? m_details.subtitle + "\n" : "") + m_details.description);
342 
347 
350 
351  BuildFocusList();
352 
354 
355  return true;
356 }
357 
358 bool ImportNative::keyPressEvent(QKeyEvent *event)
359 {
360  if (GetFocusWidget()->keyPressEvent(event))
361  return true;
362 
363  QStringList actions;
364  bool handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
365 
366  for (int i = 0; i < actions.size() && !handled; i++)
367  {
368  QString action = actions[i];
369  handled = true;
370 
371  if (action == "MENU")
372  {
373  }
374  else
375  handled = false;
376  }
377 
378  if (!handled && MythScreenType::keyPressEvent(event))
379  handled = true;
380 
381  return handled;
382 }
383 
385 
386 {
387  if (m_details.chanID != "N/A" && m_localChanIDText->GetText() == "")
388  {
389  ShowOkPopup(tr("You need to select a valid channel id!"));
390  return;
391  }
392 
393  QString commandline;
394  QString tempDir = gCoreContext->GetSetting("MythArchiveTempDir", "");
395  QString chanID = m_localChanIDText->GetText();
396 
397  if (chanID == "")
398  chanID = m_details.chanID;
399 
400  if (tempDir == "")
401  return;
402 
403  if (!tempDir.endsWith("/"))
404  tempDir += "/";
405 
406  QString logDir = tempDir + "logs";
407 
408  // remove any existing logs
409  myth_system("rm -f " + logDir + "/*.log");
410 
411  commandline = "mytharchivehelper --logpath " + logDir + " --importarchive "
412  "--infile \"" + m_xmlFile +
413  "\" --chanid " + chanID;
414 
417  uint retval = myth_system(commandline, flags);
418  if (retval != GENERIC_EXIT_RUNNING && retval != GENERIC_EXIT_OK)
419  {
420  ShowOkPopup(tr("It was not possible to import the Archive. "
421  " An error occured when running 'mytharchivehelper'") );
422  return;
423  }
424 
425  showLogViewer();
426 
428  Close();
429 }
430 
432 {
433  Close();
434 }
435 
437 {
439  Close();
440 }
441 
442 void ImportNative::findChannelMatch(const QString &chanID, const QString &chanNo,
443  const QString &name, const QString &callsign)
444 {
445  // find best match in channel table for this recording
446 
447  // look for an exact match - maybe the user is importing back an old recording
449  query.prepare("SELECT chanid, channum, name, callsign FROM channel "
450  "WHERE chanid = :CHANID AND channum = :CHANNUM AND name = :NAME "
451  "AND callsign = :CALLSIGN;");
452  query.bindValue(":CHANID", chanID);
453  query.bindValue(":CHANNUM", chanNo);
454  query.bindValue(":NAME", name);
455  query.bindValue(":CALLSIGN", callsign);
456 
457  if (query.exec() && query.next())
458  {
459  // got match
460  m_localChanIDText->SetText(query.value(0).toString());
461  m_localChanNoText->SetText(query.value(1).toString());
462  m_localChanNameText->SetText(query.value(2).toString());
463  m_localCallsignText->SetText(query.value(3).toString());
464  return;
465  }
466 
467  // try to find callsign
468  query.prepare("SELECT chanid, channum, name, callsign FROM channel "
469  "WHERE callsign = :CALLSIGN;");
470  query.bindValue(":CALLSIGN", callsign);
471 
472  if (query.exec() && query.next())
473  {
474  // got match
475  m_localChanIDText->SetText(query.value(0).toString());
476  m_localChanNoText->SetText(query.value(1).toString());
477  m_localChanNameText->SetText(query.value(2).toString());
478  m_localCallsignText->SetText(query.value(3).toString());
479  return;
480  }
481 
482  // try to find name
483  query.prepare("SELECT chanid, channum, name, callsign FROM channel "
484  "WHERE name = :NAME;");
485  query.bindValue(":NAME", callsign);
486 
487  if (query.exec() && query.next())
488  {
489  // got match
490  m_localChanIDText->SetText(query.value(0).toString());
491  m_localChanNoText->SetText(query.value(1).toString());
492  m_localChanNameText->SetText(query.value(2).toString());
493  m_localCallsignText->SetText(query.value(3).toString());
494  return;
495  }
496 
497  // give up
502 }
503 
504 void ImportNative::showList(const QString &caption, QString &value,
505  const char *slot)
506 {
507  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
508 
509  auto *searchDialog = new
510  MythUISearchDialog(popupStack, caption, m_searchList, true, value);
511 
512  if (!searchDialog->Create())
513  {
514  delete searchDialog;
515  searchDialog = nullptr;
516  return;
517  }
518 
519  connect(searchDialog, SIGNAL(haveResult(QString)), this, slot);
520 
521  popupStack->AddScreen(searchDialog);
522 }
523 
524 void ImportNative::fillSearchList(const QString &field)
525 {
526 
527  m_searchList.clear();
528 
529  QString querystr;
530  querystr = QString("SELECT %1 FROM channel ORDER BY %2").arg(field).arg(field);
531 
533 
534  if (query.exec(querystr))
535  {
536  while (query.next())
537  {
538  m_searchList << query.value(0).toString();
539  }
540  }
541 }
542 
544 {
545  QString s;
546 
547  fillSearchList("chanid");
548 
549  s = m_chanIDText->GetText();
550  showList(tr("Select a channel id"), s, SLOT(gotChanID(QString)));
551 }
552 
553 void ImportNative::gotChanID(const QString& value)
554 {
556  query.prepare("SELECT chanid, channum, name, callsign "
557  "FROM channel WHERE chanid = :CHANID;");
558  query.bindValue(":CHANID", value);
559 
560  if (query.exec() && query.next())
561  {
562  m_localChanIDText->SetText(query.value(0).toString());
563  m_localChanNoText->SetText(query.value(1).toString());
564  m_localChanNameText->SetText(query.value(2).toString());
565  m_localCallsignText->SetText(query.value(3).toString());
566  }
567 }
568 
570 {
571  QString s;
572 
573  fillSearchList("channum");
574 
575  s = m_chanNoText->GetText();
576  showList(tr("Select a channel number"), s, SLOT(gotChanNo(QString)));
577 }
578 
579 void ImportNative::gotChanNo(const QString& value)
580 {
582  query.prepare("SELECT chanid, channum, name, callsign "
583  "FROM channel WHERE channum = :CHANNUM;");
584  query.bindValue(":CHANNUM", value);
585 
586  if (query.exec() && query.next())
587  {
588  m_localChanIDText->SetText(query.value(0).toString());
589  m_localChanNoText->SetText(query.value(1).toString());
590  m_localChanNameText->SetText(query.value(2).toString());
591  m_localCallsignText->SetText(query.value(3).toString());
592  }
593 }
594 
596 {
597  QString s;
598 
599  fillSearchList("name");
600 
601  s = m_chanNameText->GetText();
602  showList(tr("Select a channel name"), s, SLOT(gotName(QString)));
603 }
604 
605 void ImportNative::gotName(const QString& value)
606 {
608  query.prepare("SELECT chanid, channum, name, callsign "
609  "FROM channel WHERE name = :NAME;");
610  query.bindValue(":NAME", value);
611 
612  if (query.exec() && query.next())
613  {
614  m_localChanIDText->SetText(query.value(0).toString());
615  m_localChanNoText->SetText(query.value(1).toString());
616  m_localChanNameText->SetText(query.value(2).toString());
617  m_localCallsignText->SetText(query.value(3).toString());
618  }
619 }
620 
622 {
623  QString s;
624 
625  fillSearchList("callsign");
626 
627  s = m_callsignText->GetText();
628  showList(tr("Select a Callsign"), s, SLOT(gotCallsign(QString)));
629 }
630 
631 void ImportNative::gotCallsign(const QString& value)
632 {
634  query.prepare("SELECT chanid, channum, name, callsign "
635  "FROM channel WHERE callsign = :CALLSIGN;");
636  query.bindValue(":CALLSIGN", value);
637 
638  if (query.exec() && query.next())
639  {
640  m_localChanIDText->SetText(query.value(0).toString());
641  m_localChanNoText->SetText(query.value(1).toString());
642  m_localChanNameText->SetText(query.value(2).toString());
643  m_localCallsignText->SetText(query.value(3).toString());
644  }
645 }
MythUIText * m_progStartTime
Definition: importnative.h:71
bool next(void)
Wrap QSqlQuery::next() so we can display the query results.
Definition: mythdbcon.cpp:783
ArchiveFileSelector(MythScreenStack *parent)
void finishedPressed()
void bindValue(const QString &placeholder, const QVariant &val)
Add a single binding.
Definition: mythdbcon.cpp:864
MythUIButton * m_cancelButton
Definition: importnative.h:136
void showList(const QString &caption, QString &value, const char *slot)
bool Create(void) override
QString m_xmlFile
Definition: importnative.h:109
FileDetails m_details
Definition: importnative.h:64
#define GENERIC_EXIT_OK
Exited with no error.
Definition: exitcodes.h:10
bool TranslateKeyPress(const QString &context, QKeyEvent *e, QStringList &actions, bool allowJumps=true)
Get a list of actions for a keypress in the given context.
void LosingFocus()
QDateTime startTime
Definition: importnative.h:33
MythConfirmationDialog * ShowOkPopup(const QString &message, QObject *parent, const char *slot, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
MythUIText * m_titleText
Definition: fileselector.h:86
FileDetails m_details
Definition: importnative.h:110
MythUIButton * m_nextButton
Definition: importnative.h:67
void SaveSetting(const QString &key, int newValue)
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:30
MythUIText * m_chanNoText
Definition: importnative.h:120
QSqlQuery wrapper that fetches a DB connection from the connection pool.
Definition: mythdbcon.h:125
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:135
void cancelPressed(void)
MythScreenType * m_previousScreen
Definition: importnative.h:111
QDomDocument doc("MYTHARCHIVEITEM")
void gotCallsign(const QString &value)
MythUIText * m_progTitle
Definition: importnative.h:69
MythScreenStack * GetStack(const QString &stackname)
void backPressed(void)
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
MythUIText * m_chanIDText
Definition: importnative.h:119
MythScreenStack * GetMainStack()
void updateFileList(void)
QString m_curDirectory
Definition: fileselector.h:79
MythUIButton * m_prevButton
Definition: importnative.h:68
QString description
Definition: importnative.h:34
bool Create(void) override
void BuildFocusList(void)
MythUIButton * m_homeButton
Definition: fileselector.h:92
void searchCallsign(void)
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
MythUIText * m_localCallsignText
Definition: importnative.h:127
void findChannelMatch(const QString &chanid, const QString &chanNo, const QString &name, const QString &callsign)
QString GetText(void) const
Definition: mythuitext.h:43
QVariant value(int i) const
Definition: mythdbcon.h:198
virtual void Close()
void gotChanNo(const QString &value)
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
void updateSelectedList(void)
MSqlQuery query(MSqlQuery::InitCon())
MythUIButton * m_cancelButton
Definition: fileselector.h:90
MythUIButtonList * m_fileButtonList
Definition: fileselector.h:87
QString GetSetting(const QString &key, const QString &defaultval="")
void gotChanID(const QString &value)
MythUIText * m_callsignText
Definition: importnative.h:122
MythUIText * m_progDateTimeText
Definition: importnative.h:116
MythUIText * m_progTitleText
Definition: importnative.h:115
void Reset(void) override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuitext.cpp:83
void searchChanNo(void)
#define GENERIC_EXIT_RUNNING
Process is running.
Definition: exitcodes.h:25
void gotName(const QString &value)
void cancelPressed()
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
unsigned int uint
Definition: compat.h:140
MythUIText * m_progDescriptionText
Definition: importnative.h:117
void fillSearchList(const QString &field)
static MSqlQueryInfo InitCon(ConnectionReuse _reuse=kNormalConnection)
Only use this in combination with MSqlQuery constructor.
Definition: mythdbcon.cpp:535
void homePressed(void)
MythUIButton * m_searchChanNoButton
Definition: importnative.h:130
uint myth_system(const QString &command, uint flags, uint timeout)
void searchChanID(void)
MythUIButton * m_finishButton
Definition: importnative.h:134
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
QString title
Definition: importnative.h:31
void SetText(const QString &text, bool moveCursor=true)
MythUIText * m_progSubtitle
Definition: importnative.h:70
MythUIType * GetFocusWidget(void) const
MythMainWindow * GetMythMainWindow(void)
MythUIButton * m_prevButton
Definition: importnative.h:135
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool prepare(const QString &query)
QSqlQuery::prepare() is not thread safe in Qt <= 3.3.2.
Definition: mythdbcon.cpp:808
MythUIButton * m_searchChanNameButton
Definition: importnative.h:131
MythUIText * m_localChanIDText
Definition: importnative.h:124
string dbVersion
Definition: mythburn.py:172
QString callsign
Definition: importnative.h:38
avoid disabling UI drawing
Definition: mythsystem.h:35
MythUIButton * m_backButton
Definition: fileselector.h:91
QString subtitle
Definition: importnative.h:32
run child in the background
Definition: mythsystem.h:36
void showLogViewer(void)
Definition: logviewer.cpp:24
QString chanName
Definition: importnative.h:37
void searchName(void)
QString chanID
Definition: importnative.h:35
bool SetFocusWidget(MythUIType *widget=nullptr)
bool exec(void)
Wrap QSqlQuery::exec() so we can display SQL.
Definition: mythdbcon.cpp:603
MythUIButton * m_searchChanIDButton
Definition: importnative.h:129
void itemClicked(MythUIButtonListItem *item)
MythUIText * m_localChanNoText
Definition: importnative.h:125
void prevPressed()
MythUIText * m_localChanNameText
Definition: importnative.h:126
MythUIButton * m_searchCallsignButton
Definition: importnative.h:132
avoid blocking LIRC & Joystick Menu
Definition: mythsystem.h:34
void itemSelected(MythUIButtonListItem *item)
QString chanNo
Definition: importnative.h:36
void locationEditLostFocus(void)
~ArchiveFileSelector(void) override
Provide a dialog to quickly find an entry in a list.
static bool loadDetailsFromXML(const QString &filename, FileDetails *details)
QStringList m_searchList
Definition: importnative.h:113
MythUIText * m_chanNameText
Definition: importnative.h:121
MythUITextEdit * m_locationEdit
Definition: fileselector.h:88
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23