MythTV  master
videoscan.cpp
Go to the documentation of this file.
1 
2 #include "videoscan.h"
3 
4 #include <QApplication>
5 #include <QImageReader>
6 #include <QUrl>
7 #include <utility>
8 
9 // mythtv
10 #include "libmyth/mythcontext.h"
11 #include "libmythbase/mythdate.h"
12 #include "libmythbase/mythevent.h"
14 #include "libmythbase/remoteutil.h"
19 
20 // libmythmetadata
22 #include "videoutils.h"
23 #include "globals.h"
24 #include "dbaccess.h"
25 #include "dirscan.h"
26 
27 const QEvent::Type VideoScanChanges::kEventType =
28  (QEvent::Type) QEvent::registerEventType();
29 
30 namespace
31 {
32  template <typename DirListType>
33  class dirhandler : public DirectoryHandler
34  {
35  public:
36  dirhandler(DirListType &video_files,
37  const QStringList &image_extensions) :
38  m_videoFiles(video_files)
39  {
40  for (const auto& ext : std::as_const(image_extensions))
41  m_imageExt.insert(ext.toLower());
42  }
43 
44  DirectoryHandler *newDir([[maybe_unused]] const QString &dir_name,
45  [[maybe_unused]] const QString &fq_dir_name) override // DirectoryHandler
46  {
47  return this;
48  }
49 
50  void handleFile([[maybe_unused]] const QString &file_name,
51  const QString &fq_file_name,
52  const QString &extension,
53  const QString &host) override // DirectoryHandler
54 
55  {
56 #if 0
57  LOG(VB_GENERAL, LOG_DEBUG,
58  QString("handleFile: %1 :: %2").arg(fq_file_name).arg(host));
59 #endif
60  if (m_imageExt.find(extension.toLower()) == m_imageExt.end())
61  {
62  m_videoFiles[fq_file_name].check = false;
63  m_videoFiles[fq_file_name].host = host;
64  }
65  }
66 
67  private:
68  using image_ext = std::set<QString>;
69  image_ext m_imageExt;
70  DirListType &m_videoFiles;
71  };
72 }
73 
76 
78  MThread("VideoScanner")
79 {
80  m_parent = parent;
83  m_listUnknown = gCoreContext->GetBoolSetting("VideoListUnknownFiletypes", false);
84 }
85 
87 {
88  delete m_dbMetadata;
89 }
90 
91 void VideoScannerThread::SetHosts(const QStringList &hosts)
92 {
93  m_liveSGHosts.clear();
94  for (const auto& host : std::as_const(hosts))
95  m_liveSGHosts << host.toLower();
96 }
97 
98 void VideoScannerThread::SetDirs(QStringList dirs)
99 {
100  QString master = gCoreContext->GetMasterHostName().toLower();
101  QStringList searchhosts;
102  QStringList mdirs;
103  m_offlineSGHosts.clear();
104 
105  QStringList::iterator iter = dirs.begin();
106  QStringList::iterator iter2;
107  while ( iter != dirs.end() )
108  {
109  if (iter->startsWith("myth://"))
110  {
111  QUrl sgurl = *iter;
112  QString host = sgurl.host().toLower();
113  QString path = sgurl.path();
114 
115  if (!m_liveSGHosts.contains(host))
116  {
117  // mark host as offline to warn user
118  if (!m_offlineSGHosts.contains(host))
119  m_offlineSGHosts.append(host);
120  // erase from directory list to skip scanning
121  iter = dirs.erase(iter);
122  continue;
123  }
124  if ((host == master) && (!mdirs.contains(path)))
125  {
126  // collect paths defined on master backend so other
127  // online backends can be set to fall through to them
128  mdirs.append(path);
129  }
130  else if (!searchhosts.contains(host))
131  {
132  // mark host as having directories defined so it
133  // does not fall through to those on the master
134  searchhosts.append(host);
135  }
136  }
137 
138  ++iter;
139  }
140 
141  for (iter = m_liveSGHosts.begin(); iter != m_liveSGHosts.end(); ++iter)
142  {
143  if ((!searchhosts.contains(*iter)) && (master != *iter))
144  {
145  for (iter2 = mdirs.begin(); iter2 != mdirs.end(); ++iter2)
146  {
147  // backend is online, but has no directories listed
148  // fall back to those on the master backend
149  dirs.append(MythCoreContext::GenMythURL(*iter,
150  0, *iter2, "Videos"));
151  }
152  }
153  }
154 
155  m_directories = dirs;
156 }
157 
159 {
160  RunProlog();
161 
164  m_dbMetadata->setList(ml);
165 
166  QList<QByteArray> image_types = QImageReader::supportedImageFormats();
167  QStringList imageExtensions;
168  for (const auto & format : std::as_const(image_types))
169  imageExtensions.push_back(QString(format));
170 
171  LOG(VB_GENERAL, LOG_INFO, QString("Beginning Video Scan."));
172 
173  uint counter = 0;
174  FileCheckList fs_files;
175 
176  if (m_hasGUI)
177  SendProgressEvent(counter, (uint)m_directories.size(),
178  tr("Searching for video files"));
179  for (const auto & dir : std::as_const(m_directories))
180  {
181  if (!buildFileList(dir, imageExtensions, fs_files))
182  {
183  if (dir.startsWith("myth://"))
184  {
185  QUrl sgurl = dir;
186  QString host = sgurl.host().toLower();
187 
188  m_liveSGHosts.removeAll(host);
189 
190  LOG(VB_GENERAL, LOG_ERR,
191  QString("Failed to scan :%1:").arg(dir));
192  }
193  }
194  if (m_hasGUI)
195  SendProgressEvent(++counter);
196  }
197 
198  PurgeList db_remove;
199  verifyFiles(fs_files, db_remove);
200  m_dbDataChanged = updateDB(fs_files, db_remove);
201 
202  if (m_dbDataChanged)
203  {
204  QCoreApplication::postEvent(m_parent,
206  m_delList));
207 
208  QStringList slist;
209 
210  for (int id : std::as_const(m_addList))
211  slist << QString("added::%1").arg(id);
212  for (int id : std::as_const(m_movList))
213  slist << QString("moved::%1").arg(id);
214  for (int id : std::as_const(m_delList))
215  slist << QString("deleted::%1").arg(id);
216 
217  MythEvent me("VIDEO_LIST_CHANGE", slist);
218 
219  gCoreContext->SendEvent(me);
220  }
221  else
222  gCoreContext->SendMessage("VIDEO_LIST_NO_CHANGE");
223 
224  RunEpilog();
225 }
226 
227 
229  [[maybe_unused]] const QString &filename)
230 {
231  // TODO: use single DB connection for all calls
232  if (m_removeAll)
233  m_dbMetadata->purgeByID(id);
234 
235  if (!m_keepAll && !m_removeAll)
236  {
237  m_removeAll = true;
238  m_dbMetadata->purgeByID(id);
239  }
240 }
241 
243  PurgeList &remove)
244 {
245  int counter = 0;
246  FileCheckList::iterator iter;
247 
248  if (m_hasGUI)
249  SendProgressEvent(counter, (uint)m_dbMetadata->getList().size(),
250  tr("Verifying video files"));
251 
252  // For every file we know about, check to see if it still exists.
253  for (const auto & file : m_dbMetadata->getList())
254  {
255  QString lname = file->GetFilename();
256  QString lhost = file->GetHost().toLower();
257  if (!lname.isEmpty())
258  {
259  iter = files.find(lname);
260  if (iter != files.end())
261  {
262  if (lhost != iter->second.host)
263  {
264  // file has changed hosts
265  // add to delete list for further processing
266  remove.emplace_back(file->GetID(), lname);
267  }
268  else
269  {
270  // file is on disk on the proper host and in the database
271  // we're done with it
272  iter->second.check = true;
273  }
274  }
275  else if (lhost.isEmpty())
276  {
277  // If it's only in the database, and not on a host we
278  // cannot reach, mark it as for removal later.
279  remove.emplace_back(file->GetID(), lname);
280  }
281  else if (m_liveSGHosts.contains(lhost))
282  {
283  LOG(VB_GENERAL, LOG_INFO,
284  QString("Removing file SG(%1) :%2:")
285  .arg(lhost, lname));
286  remove.emplace_back(file->GetID(), lname);
287  }
288  else
289  {
290  LOG(VB_GENERAL, LOG_WARNING,
291  QString("SG(%1) not available. Not removing file :%2:")
292  .arg(lhost, lname));
293  if (!m_offlineSGHosts.contains(lhost))
294  m_offlineSGHosts.append(lhost);
295  }
296  }
297  if (m_hasGUI)
298  SendProgressEvent(++counter);
299  }
300 }
301 
302 bool VideoScannerThread::updateDB(const FileCheckList &add, const PurgeList &remove)
303 {
304  int ret = 0;
305  uint counter = 0;
306  if (m_hasGUI)
307  SendProgressEvent(counter, (uint)(add.size() + remove.size()),
308  tr("Updating video database"));
309 
310  for (auto p = add.cbegin(); p != add.cend(); ++p)
311  {
312  // add files not already in the DB
313  if (!p->second.check)
314  {
315  int id = -1;
316 
317  // Are we sure this needs adding? Let's check our Hash list.
318  QString hash = VideoMetadata::VideoFileHash(p->first, p->second.host);
319  if (hash != "NULL" && !hash.isEmpty())
320  {
321  id = VideoMetadata::UpdateHashedDBRecord(hash, p->first, p->second.host);
322  if (id != -1)
323  {
324  // Whew, that was close. Let's remove that thing from
325  // our purge list, too.
326  LOG(VB_GENERAL, LOG_ERR,
327  QString("Hash %1 already exists in the "
328  "database, updating record %2 "
329  "with new filename %3")
330  .arg(hash).arg(id).arg(p->first));
331  m_movList.append(id);
332  }
333  }
334  if (id == -1)
335  {
336  VideoMetadata newFile(
337  p->first, QString(), hash,
343  QString(), QString(), QString(), QString(),
344  QString(),
346  QDate::fromString("0000-00-00","YYYY-MM-DD"),
347  VIDEO_INETREF_DEFAULT, 0, QString(),
349  0.0, VIDEO_RATING_DEFAULT, 0, 0,
350  0, 0,
351  MythDate::current().date(),
353 
354  LOG(VB_GENERAL, LOG_INFO, QString("Adding : %1 : %2 : %3")
355  .arg(newFile.GetHost(), newFile.GetFilename(), hash));
356  newFile.SetHost(p->second.host);
357  newFile.SaveToDatabase();
358  m_addList << newFile.GetID();
359  }
360  ret += 1;
361  }
362  if (m_hasGUI)
363  SendProgressEvent(++counter);
364  }
365 
366  // When prompting is restored, account for the answer here.
367  ret += remove.size();
368  for (const auto & item : remove)
369  {
370  if (!m_movList.contains(item.first))
371  {
372  removeOrphans(item.first, item.second);
373  m_delList << item.first;
374  }
375  if (m_hasGUI)
376  SendProgressEvent(++counter);
377  }
378 
379  return ret > 0;
380 }
381 
382 bool VideoScannerThread::buildFileList(const QString &directory,
383  const QStringList &imageExtensions,
384  FileCheckList &filelist) const
385 {
386  // TODO: FileCheckList is a std::map, keyed off the filename. In the event
387  // multiple backends have access to shared storage, the potential exists
388  // for files to be scanned onto the wrong host. Add in some logic to prefer
389  // the backend with the content stored in a storage group determined to be
390  // local.
391 
392  LOG(VB_GENERAL,LOG_INFO, QString("buildFileList directory = %1")
393  .arg(directory));
396 
397  dirhandler<FileCheckList> dh(filelist, imageExtensions);
398  return ScanVideoDirectory(directory, &dh, ext_list, m_listUnknown);
399 }
400 
402  QString messsage)
403 {
404  if (!m_dialog)
405  return;
406 
407  auto *pue = new ProgressUpdateEvent(progress, total, std::move(messsage));
408  QApplication::postEvent(m_dialog, pue);
409 }
410 
412 {
413  m_scanThread = new VideoScannerThread(this);
414 }
415 
417 {
418  if (m_scanThread && m_scanThread->wait())
419  delete m_scanThread;
420 }
421 
422 void VideoScanner::doScan(const QStringList &dirs)
423 {
424  if (m_scanThread->isRunning())
425  return;
426 
427  if (gCoreContext->HasGUI())
428  {
429  MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
430 
431  auto *progressDlg = new MythUIProgressDialog("", popupStack,
432  "videoscanprogressdialog");
433 
434  if (progressDlg->Create())
435  {
436  popupStack->AddScreen(progressDlg, false);
437  connect(m_scanThread->qthread(), &QThread::finished,
438  progressDlg, &MythScreenType::Close);
439  connect(m_scanThread->qthread(), &QThread::finished,
441  }
442  else
443  {
444  delete progressDlg;
445  progressDlg = nullptr;
446  }
447  m_scanThread->SetProgressDialog(progressDlg);
448  }
449 
450  QStringList hosts;
451  if (!RemoteGetActiveBackends(&hosts))
452  {
453  LOG(VB_GENERAL, LOG_WARNING, "Could not retrieve list of "
454  "available backends.");
455  hosts.clear();
456  }
457  m_scanThread->SetHosts(hosts);
458  m_scanThread->SetDirs(dirs);
459  m_scanThread->start();
460 }
461 
463 {
464  doScan(GetVideoDirs());
465 }
466 
468 {
469  QStringList failedHosts = m_scanThread->GetOfflineSGHosts();
470  if (!failedHosts.empty())
471  {
472  QString hosts = failedHosts.join(" ");
473  QString msg = tr("Failed to Scan SG Video Hosts:\n\n%1\n\n"
474  "If they no longer exist please remove them")
475  .arg(hosts);
476 
477  ShowOkPopup(msg);
478  }
479 
481 }
482 
VideoScanner::finished
void finished(bool)
VideoMetadata
Definition: videometadata.h:24
mythevent.h
MythCoreContext::SendMessage
void SendMessage(const QString &message)
Definition: mythcorecontext.cpp:1517
MThread::start
void start(QThread::Priority p=QThread::InheritPriority)
Tell MThread to start running the thread in the near future.
Definition: mthread.cpp:283
MythCoreContext::GetMasterHostName
QString GetMasterHostName(void)
Definition: mythcorecontext.cpp:807
VideoScannerThread::m_listUnknown
bool m_listUnknown
Definition: videoscan.h:101
VideoScanner::VideoScanner
VideoScanner()
Definition: videoscan.cpp:411
VideoScannerThread::SendProgressEvent
void SendProgressEvent(uint progress, uint total=0, QString messsage=QString())
Definition: videoscan.cpp:401
VideoScannerThread::m_keepAll
bool m_keepAll
Definition: videoscan.h:103
FileAssociations::getExtensionIgnoreList
void getExtensionIgnoreList(ext_ignore_list &ext_ignore) const
Definition: dbaccess.cpp:810
dirscan.h
ParentalLevel::plLowest
@ plLowest
Definition: parentalcontrols.h:12
VideoMetadata::GetHost
const QString & GetHost() const
Definition: videometadata.cpp:1832
VideoMetadataListManager
Definition: videometadatalistmanager.h:10
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:386
VideoScanner::doScan
void doScan(const QStringList &dirs)
Definition: videoscan.cpp:422
progress
bool progress
Definition: mythcommflag.cpp:69
MThread::wait
bool wait(std::chrono::milliseconds time=std::chrono::milliseconds::max())
Wait for the MThread to exit, with a maximum timeout.
Definition: mthread.cpp:300
mythscreenstack.h
MythEvent
This class is used as a container for messages.
Definition: mythevent.h:16
mythdialogbox.h
MythScreenStack
Definition: mythscreenstack.h:16
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MThread::RunProlog
void RunProlog(void)
Sets up a thread, call this if you reimplement run().
Definition: mthread.cpp:196
VideoMetadataListManager::getList
const metadata_list & getList() const
Definition: videometadatalistmanager.cpp:168
VideoMetadataListManager::setList
void setList(metadata_list &list)
Definition: videometadatalistmanager.cpp:162
build_compdb.file
file
Definition: build_compdb.py:55
VideoScannerThread::GetOfflineSGHosts
QStringList GetOfflineSGHosts(void)
Definition: videoscan.h:72
remoteutil.h
VideoScannerThread::m_movList
QList< int > m_movList
Definition: videoscan.h:113
MythDate::current
QDateTime current(bool stripped)
Returns current Date and Time in UTC.
Definition: mythdate.cpp:14
mythprogressdialog.h
VideoScannerThread::buildFileList
bool buildFileList(const QString &directory, const QStringList &imageExtensions, FileCheckList &filelist) const
Definition: videoscan.cpp:382
MythUIProgressDialog::MythUIProgressDialog
MythUIProgressDialog(QString message, MythScreenStack *parent, const char *name)
Definition: mythprogressdialog.h:63
dbaccess.h
VideoScanner::m_scanThread
class VideoScannerThread * m_scanThread
Definition: videoscan.h:40
VideoMetadataListManager::loadAllFromDatabase
static void loadAllFromDatabase(metadata_list &items, const QString &sql="", const QString &bindValue="")
Load videometadata database into memory.
Definition: videometadatalistmanager.cpp:128
dirhandler::handleFile
void handleFile(const QString &file_name, const QString &fq_file_name, const QString &extension)
Definition: videolist.cpp:1163
videoscan.h
VideoScannerThread
Definition: videoscan.h:60
ProgressUpdateEvent
Definition: mythprogressdialog.h:16
mythdate.h
VideoMetadata::GetFilename
const QString & GetFilename() const
Definition: videometadata.cpp:1812
mythlogging.h
MythCoreContext::GenMythURL
static QString GenMythURL(const QString &host=QString(), int port=0, QString path=QString(), const QString &storageGroup=QString())
Definition: mythcorecontext.cpp:760
VideoScannerThread::m_dialog
MythUIProgressDialog * m_dialog
Definition: videoscan.h:110
GetVideoDirs
QStringList GetVideoDirs()
Definition: videoutils.cpp:116
MythCoreContext::SendEvent
void SendEvent(const MythEvent &event)
Definition: mythcorecontext.cpp:1530
hardwareprofile.config.p
p
Definition: config.py:33
MythUIProgressDialog
Definition: mythprogressdialog.h:59
globals.h
FileAssociations::ext_ignore_list
std::vector< std::pair< QString, bool > > ext_ignore_list
Definition: dbaccess.h:155
VideoScannerThread::m_addList
QList< int > m_addList
Definition: videoscan.h:112
VideoMetadata::UpdateHashedDBRecord
static int UpdateHashedDBRecord(const QString &hash, const QString &file_name, const QString &host)
Definition: videometadata.cpp:1070
VideoScannerThread::SetDirs
void SetDirs(QStringList dirs)
Definition: videoscan.cpp:98
VideoMetadata::SaveToDatabase
void SaveToDatabase()
Definition: videometadata.cpp:1947
VIDEO_COVERFILE_DEFAULT
const QString VIDEO_COVERFILE_DEFAULT
Definition: globals.cpp:25
VIDEO_PLOT_DEFAULT
const QString VIDEO_PLOT_DEFAULT
Definition: globals.cpp:32
VideoScannerThread::m_liveSGHosts
QStringList m_liveSGHosts
Definition: videoscan.h:106
MThread::qthread
QThread * qthread(void)
Returns the thread, this will always return the same pointer no matter how often you restart the thre...
Definition: mthread.cpp:233
MThread::RunEpilog
void RunEpilog(void)
Cleans up a thread's resources, call this if you reimplement run().
Definition: mthread.cpp:209
VideoScanChanges::kEventType
static const Type kEventType
Definition: videoscan.h:57
VIDEO_TRAILER_DEFAULT
const QString VIDEO_TRAILER_DEFAULT
Definition: globals.cpp:26
uint
unsigned int uint
Definition: compat.h:81
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:55
VideoScannerThread::m_dbMetadata
VideoMetadataListManager * m_dbMetadata
Definition: videoscan.h:109
VideoScannerThread::m_removeAll
bool m_removeAll
Definition: videoscan.h:102
VIDEO_INETREF_DEFAULT
const QString VIDEO_INETREF_DEFAULT
Definition: globals.cpp:24
VIDEO_FANART_DEFAULT
const QString VIDEO_FANART_DEFAULT
Definition: globals.cpp:29
videometadatalistmanager.h
VideoScannerThread::m_delList
QList< int > m_delList
Definition: videoscan.h:114
MythDate::fromString
QDateTime fromString(const QString &dtstr)
Converts kFilename && kISODate formats to QDateTime.
Definition: mythdate.cpp:34
MythCoreContext::GetBoolSetting
bool GetBoolSetting(const QString &key, bool defaultval=false)
Definition: mythcorecontext.cpp:906
FileAssociations::getFileAssociation
static FileAssociations & getFileAssociation()
Definition: dbaccess.cpp:830
VideoMetadataListManager::purgeByID
bool purgeByID(unsigned int db_id)
Definition: videometadatalistmanager.cpp:190
VideoScannerThread::m_dbDataChanged
bool m_dbDataChanged
Definition: videoscan.h:115
dirhandler::newDir
DirectoryHandler * newDir(const QString &dir_name, [[maybe_unused]] const QString &fq_dir_name) override
Definition: videolist.cpp:1152
VideoScannerThread::SetProgressDialog
void SetProgressDialog(MythUIProgressDialog *dialog)
Definition: videoscan.h:71
ScanVideoDirectory
bool ScanVideoDirectory(const QString &start_path, DirectoryHandler *handler, const FileAssociations::ext_ignore_list &ext_disposition, bool list_unknown_extensions)
Definition: dirscan.cpp:227
VideoMetadata::SetHost
void SetHost(const QString &host)
Definition: videometadata.cpp:1837
VideoScannerThread::run
void run() override
Runs the Qt event loop unless we have a QRunnable, in which case we run the runnable run instead.
Definition: videoscan.cpp:158
VideoScannerThread::~VideoScannerThread
~VideoScannerThread() override
Definition: videoscan.cpp:86
VIDEO_RATING_DEFAULT
const QString VIDEO_RATING_DEFAULT
Definition: globals.cpp:30
VideoScannerThread::m_parent
QObject * m_parent
Definition: videoscan.h:99
mythcontext.h
MThread
This is a wrapper around QThread that does several additional things.
Definition: mthread.h:48
VideoScannerThread::VideoScannerThread
VideoScannerThread(QObject *parent)
Definition: videoscan.cpp:77
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:104
MThread::isRunning
bool isRunning(void) const
Definition: mthread.cpp:263
VideoMetadata::GetID
unsigned int GetID() const
Definition: videometadata.cpp:1732
VideoScannerThread::verifyFiles
void verifyFiles(FileCheckList &files, PurgeList &remove)
Definition: videoscan.cpp:242
VideoScanChanges
Definition: videoscan.h:44
VideoScannerThread::removeOrphans
void removeOrphans(unsigned int id, const QString &filename)
Definition: videoscan.cpp:228
MythMainWindow::GetStack
MythScreenStack * GetStack(const QString &Stackname)
Definition: mythmainwindow.cpp:323
VideoMetadataListManager::metadata_list
std::list< VideoMetadataPtr > metadata_list
Definition: videometadatalistmanager.h:14
VideoScanner::~VideoScanner
~VideoScanner() override
Definition: videoscan.cpp:416
VideoScannerThread::updateDB
bool updateDB(const FileCheckList &add, const PurgeList &remove)
Definition: videoscan.cpp:302
VideoScannerThread::m_offlineSGHosts
QStringList m_offlineSGHosts
Definition: videoscan.h:107
VideoScannerThread::FileCheckList
std::map< QString, CheckStruct > FileCheckList
Definition: videoscan.h:86
VideoScannerThread::m_hasGUI
bool m_hasGUI
Definition: videoscan.h:104
MythCoreContext::HasGUI
bool HasGUI(void) const
Definition: mythcorecontext.cpp:1738
VIDEO_YEAR_DEFAULT
static constexpr uint16_t VIDEO_YEAR_DEFAULT
Definition: videometadata.h:18
VIDEO_BANNER_DEFAULT
const QString VIDEO_BANNER_DEFAULT
Definition: globals.cpp:28
VideoScannerThread::SetHosts
void SetHosts(const QStringList &hosts)
Definition: videoscan.cpp:91
build_compdb.filename
filename
Definition: build_compdb.py:21
VideoMetadata::VideoFileHash
static QString VideoFileHash(const QString &file_name, const QString &host)
Definition: videometadata.cpp:1118
DirectoryHandler
Definition: dirscan.h:6
mythmainwindow.h
MythScreenStack::AddScreen
virtual void AddScreen(MythScreenType *screen, bool allowFade=true)
Definition: mythscreenstack.cpp:52
VideoScannerThread::m_directories
QStringList m_directories
Definition: videoscan.h:105
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:562
VideoScannerThread::getDataChanged
bool getDataChanged() const
Definition: videoscan.h:73
VideoScanner::finishedScan
void finishedScan()
Definition: videoscan.cpp:467
videoutils.h
RemoteGetActiveBackends
bool RemoteGetActiveBackends(QStringList *list)
return list of backends currently connected to the master
Definition: remoteutil.cpp:572
dirhandler
Definition: videolist.cpp:1138
VideoScannerThread::PurgeList
std::vector< std::pair< int, QString > > PurgeList
Definition: videoscan.h:85
VIDEO_DIRECTOR_DEFAULT
const QString VIDEO_DIRECTOR_DEFAULT
Definition: globals.cpp:23
VIDEO_SCREENSHOT_DEFAULT
const QString VIDEO_SCREENSHOT_DEFAULT
Definition: globals.cpp:27
VideoScanner::doScanAll
void doScanAll(void)
Definition: videoscan.cpp:462