MythTV  master
galleryviews.cpp
Go to the documentation of this file.
1 #include "galleryviews.h"
2 
3 #include <algorithm>
4 #include <cmath> // for qsrand
5 #include <random>
6 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
7 #include <QRandomGenerator>
8 #endif
9 
10 #define LOC QString("Galleryviews: ")
11 
13 const static int kMaxFolderThumbnails = 4;
14 
21 const double LEADING_BETA_SHAPE = 0.175;
23 const double TRAILING_BETA_SHAPE = 0.31;
24 
26 const double DEFAULT_WEIGHT = std::pow(0.5, TRAILING_BETA_SHAPE - 1) *
27  std::pow(0.5, LEADING_BETA_SHAPE - 1);
29 static constexpr qint64 BETA_CLIP { 24LL * 60 * 60 };
30 
31 void MarkedFiles::Add(const ImageIdList& newIds)
32 {
33  for (int newid : newIds)
34  insert(newid);
35 }
36 
38 {
39  QSet tmp;
40  for (int tmpint : all)
41  tmp.insert(tmpint);
42  for (int tmpint : qAsConst(*this))
43  tmp.remove(tmpint);
44  swap(tmp);
45 }
46 
52 {
53  ImageListK files;
54  for (int id : qAsConst(m_sequence))
55  files.append(m_images.value(id));
56  return files;
57 }
58 
59 
65 {
66  return m_active < 0 || m_active >= m_sequence.size()
67  ? ImagePtrK() : m_images.value(m_sequence.at(m_active));
68 }
69 
70 
75 QString FlatView::GetPosition() const
76 {
77  return QString("%1/%2").arg(m_active + 1).arg(m_sequence.size());
78 }
79 
80 
86 bool FlatView::Update(int id)
87 {
88  ImagePtrK im = m_images.value(id);
89  if (!im)
90  return false;
91 
92  // Get updated image
93  ImageList files;
94  ImageList dirs;
95  ImageIdList ids = ImageIdList() << id;
96  if (m_mgr.GetImages(ids, files, dirs) != 1 || files.size() != 1)
97  return false;
98 
99  bool active = (im == GetSelected());
100 
101  // Replace image
102  m_images.insert(id, files.at(0));
103 
104  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Modified id %1").arg(id));
105 
106  return active;
107 }
108 
109 
117 bool FlatView::Select(int id, int fallback)
118 {
119  // Select first appearance of image
120  int index = m_sequence.indexOf(id);
121  if (index >= 0)
122  {
123  m_active = index;
124  return true;
125  }
126 
127  if (fallback >= 0)
128  m_active = fallback;
129 
130  return false;
131 }
132 
133 
138 void FlatView::Clear(bool resetParent)
139 {
140  m_images.clear();
141  m_sequence.clear();
142  m_active = -1;
143  if (resetParent)
145 }
146 
147 
153 {
154  return m_sequence.isEmpty() || m_active + inc >= m_sequence.size()
155  ? ImagePtrK() : m_images.value(m_sequence.at(m_active + inc));
156 }
157 
158 
165 {
166  if (m_sequence.isEmpty())
167  return {};
168 
169  // Preserve index as it may be reset when wrapping
170  int next = m_active + inc;
171 
172  // Regenerate unordered views when wrapping
173  if (next >= m_sequence.size() && m_order != kOrdered && !LoadFromDb(m_parentId))
174  // Images have disappeared
175  return {};
176 
177  m_active = next % m_sequence.size();
178  return m_images.value(m_sequence.at(m_active));
179 }
180 
181 
187 {
188  return m_sequence.isEmpty() || m_active < inc
189  ? ImagePtrK() : m_images.value(m_sequence.at(m_active - inc));
190 }
191 
192 
198 {
199  if (m_sequence.isEmpty())
200  return {};
201 
202  // Wrap avoiding modulo of negative uncertainty
203  m_active -= inc % m_sequence.size();
204  if (m_active < 0)
205  m_active += m_sequence.size();
206 
207  return m_images.value(m_sequence.at(m_active));
208 }
209 
210 
216 {
217  // Do not reset parent
218  Clear(false);
219 
220  if (files.isEmpty())
221  return;
222 
223  for (const QSharedPointer<ImageItem> & im : qAsConst(files))
224  {
225  // Add image to view
226  m_images.insert(im->m_id, im);
227 
228  // Cache all displayed images
229  if (im->IsFile())
230  Cache(im->m_id, im->m_parentId, im->m_url, im->m_thumbNails.at(0).second);
231  }
232 
233  if (files.size() == 1 || m_order == kOrdered || m_order == kShuffle)
234  {
235  // Default sequence is ordered
236  for (const QSharedPointer<ImageItem> & im : qAsConst(files))
237  m_sequence.append(im->m_id);
238  }
239 
240  if (files.size() > 1)
241  {
242  // Modify viewing sequence
243  if (m_order == kShuffle)
244  {
245  std::shuffle(m_sequence.begin(), m_sequence.end(),
246  std::mt19937(std::random_device()()));
247  }
248  else if (m_order == kRandom)
249  {
250 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
251  QVector<quint32> rands;
252  rands.resize(files.size());
253  QRandomGenerator::global()->fillRange(rands.data(), rands.size());
254 #else
255  // cppcheck-suppress qsrandCalled
256  qsrand(QTime::currentTime().msec());
257 #endif
258  // An image is not a valid candidate for its successor
259  int range = files.size() - 1;
260  int index = range;
261  for (int count = 0; count < files.size(); ++count)
262  {
263 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
264  int rand = rands[count] % range;
265 #else
266  // cppcheck-suppress qrandCalled
267  int rand = qrand() % range;
268 #endif
269  // Avoid consecutive repeats
270  index = (rand < index) ? rand : rand + 1;
271  m_sequence.append(files.at(index)->m_id);
272  }
273  }
274  else if (m_order == kSeasonal)
275  {
276  WeightList weights = CalculateSeasonalWeights(files);
277  double maxWeight = weights.last();
278 
279 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
280  auto *randgen = QRandomGenerator::global();
281 #else
282  // cppcheck-suppress qsrandCalled
283  qsrand(QTime::currentTime().msec());
284 #endif
285  for (int count = 0; count < files.size(); ++count)
286  {
287 #if QT_VERSION >= QT_VERSION_CHECK(5,10,0)
288  // generateDouble() returns in the range [0, 1)
289  double randWeight = randgen->generateDouble() * maxWeight;
290 #else
291  // cppcheck-suppress qrandCalled
292  double randWeight = qrand() * maxWeight / RAND_MAX;
293 #endif
294  WeightList::iterator it =
295  std::upper_bound(weights.begin(), weights.end(), randWeight);
296  int index = std::distance(weights.begin(), it);
297  m_sequence.append(files.at(index)->m_id);
298  }
299  }
300  }
301 }
302 
303 
315 {
316  WeightList weights(files.size());
317  double totalWeight = 0;
318  QDateTime now = QDateTime::currentDateTime();
319 
320  for (int i = 0; i < files.size(); ++i)
321  {
322  ImagePtrK im = files.at(i);
323  double weight = 0;
324 
325  if (im->m_date == 0s)
326  weight = DEFAULT_WEIGHT;
327  else
328  {
329  QDateTime timestamp = QDateTime::fromSecsSinceEpoch(im->m_date.count());
330  QDateTime curYearAnniversary =
331  QDateTime(QDate(now.date().year(),
332  timestamp.date().month(),
333  timestamp.date().day()),
334  timestamp.time());
335 
336  bool isAnniversaryPast = curYearAnniversary < now;
337 
338  QDateTime adjacentYearAnniversary =
339  QDateTime(QDate(now.date().year() +
340  (isAnniversaryPast ? 1 : -1),
341  timestamp.date().month(),
342  timestamp.date().day()),
343  timestamp.time());
344 
345  double range = llabs(curYearAnniversary.secsTo(
346  adjacentYearAnniversary)) + BETA_CLIP;
347 
348  // This calculation is not normalized, because that would require the
349  // beta function, which isn't part of the C++98 libraries. Weights
350  // that aren't normalized work just as well relative to each other.
351  QDateTime d1(isAnniversaryPast ? curYearAnniversary
352  : adjacentYearAnniversary);
353  QDateTime d2(isAnniversaryPast ? adjacentYearAnniversary
354  : curYearAnniversary);
355  weight = std::pow(llabs(now.secsTo(d1) + BETA_CLIP) / range,
357  * std::pow(llabs(now.secsTo(d2) + BETA_CLIP) / range,
358  LEADING_BETA_SHAPE - 1);
359  }
360  totalWeight += weight;
361  weights[i] = totalWeight;
362  }
363  return weights;
364 }
365 
366 
373 bool FlatView::LoadFromDb(int parentId)
374 {
375  m_parentId = parentId;
376 
377  // Load child images of the parent
378  ImageList files;
379  ImageList dirs;
380  m_mgr.GetChildren(m_parentId, files, dirs);
381 
382  // Load gallery datastore with current dir
383  Populate(files);
384 
385  return !files.isEmpty();
386 }
387 
388 
393 {
394  LOG(VB_FILE, LOG_DEBUG, LOC + "Cleared File cache");
395  m_fileCache.clear();
396 }
397 
398 
405 QStringList FlatView::ClearImage(int id, bool remove)
406 {
407  if (remove)
408  {
409  m_sequence.removeAll(id);
410  m_images.remove(id);
411  }
412 
413  QStringList urls;
414  FileCacheEntry file = m_fileCache.take(id);
415 
416  if (!file.m_url.isEmpty())
417  urls << file.m_url;
418 
419  if (!file.m_thumbUrl.isEmpty())
420  urls << file.m_thumbUrl;
421 
422  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Cleared %1 from file cache (%2)")
423  .arg(id).arg(urls.join(",")));
424  return urls;
425 }
426 
427 
432 void FlatView::Rotate(int id)
433 {
434  // Rotate sequence so that (first appearance of) specified image is
435  // at offset from front
436  int index = m_sequence.indexOf(id);
437  if (index >= 0)
438  {
439  int first = index % m_sequence.size();
440  if (first > 0)
441  m_sequence = m_sequence.mid(first) + m_sequence.mid(0, first);
442  }
443 }
444 
445 
453 void FlatView::Cache(int id, int parent, const QString &url, const QString &thumb)
454 {
455  // Cache parent dir so that dir thumbs are updated when a child changes.
456  // Also store urls for image cache cleanup
457  FileCacheEntry cached(parent, url, thumb);
458  m_fileCache.insert(id, cached);
459  LOG(VB_FILE, LOG_DEBUG, LOC + "Caching " + cached.ToString(id));
460 }
461 
462 
463 QString DirCacheEntry::ToString(int id) const
464 {
465  QStringList ids;
466  for (const auto & thumb : qAsConst(m_thumbs))
467  ids << QString::number(thumb.first);
468  return QString("Dir %1 (%2, %3) Thumbs %4 (%5) Parent %6")
469  .arg(id).arg(m_fileCount).arg(m_dirCount).arg(ids.join(","))
470  .arg(m_thumbCount).arg(m_parent);
471 }
472 
473 
479  : FlatView(order)
480 {
481  m_marked.Clear();
483 }
484 
485 
491 {
492  return QString("%1/%2").arg(m_active).arg(m_sequence.size() - 1);
493 }
494 
495 
504 bool DirectoryView::LoadFromDb(int parentId)
505 {
506  // Determine parent (defaulting to ancestor) & get initial children
507  ImageList files;
508  ImageList dirs;
509  ImagePtr parent;
510  int count = 0;
511  // Root is guaranteed to return at least 1 item
512  while ((count = m_mgr.GetDirectory(parentId, parent, files, dirs)) == 0)
513  {
514  // Fallback if dir no longer exists
515  // Ascend to Gallery for gallery subdirs, Root for device dirs & Gallery
516  parentId = parentId > PHOTO_DB_ID ? PHOTO_DB_ID : GALLERY_DB_ID;
517  }
518 
519  SetDirectory(parentId);
520  m_parentId = parentId;
521 
522  // No SG & no devices uses special 'empty' screen
523  if (!parent || (parentId == GALLERY_DB_ID && count == 1))
524  {
525  parent.clear();
526  return false;
527  }
528 
529  // Populate all subdirs
530  for (const ImagePtr & im : qAsConst(dirs))
531  {
532  if (im)
533  // Load sufficient thumbs from each dir as subsequent dirs may be empty
535  }
536 
537  // Populate parent
539  PopulateThumbs(*parent, kMaxFolderThumbnails, files, dirs);
540 
541  // Dirs shown before images
542  ImageList images = dirs + files;
543 
544  // Validate marked images
545  if (!m_marked.isEmpty())
546  {
547  QSet<int> ids;
548  for (const QSharedPointer<ImageItem> & im : qAsConst(images))
549  ids.insert(im->m_id);
550  m_marked.intersect(ids);
551  }
552 
553  // Parent is always first (for navigating up).
554  images.prepend(parent);
555 
556  // Preserve current selection before view is destroyed
557  ImagePtrK selected = GetSelected();
558  int activeId = selected ? selected->m_id : 0;
559 
560  // Construct view
561  Populate(images);
562 
563  // Reinstate selection, falling back to parent
564  Select(activeId);
565 
566  return true;
567 }
568 
569 
576 void DirectoryView::LoadDirThumbs(ImageItem &parent, int thumbsNeeded, int level)
577 {
578  // Use cached data, if available
579  if (PopulateFromCache(parent, thumbsNeeded))
580  return;
581 
582  // Load child images & dirs
583  ImageList files;
584  ImageList dirs;
585  m_mgr.GetChildren(parent.m_id, files, dirs);
586 
587  PopulateThumbs(parent, thumbsNeeded, files, dirs, level);
588 }
589 
590 
601 void DirectoryView::PopulateThumbs(ImageItem &parent, int thumbsNeeded,
602  const ImageList &files, const ImageList &dirs,
603  int level)
604 {
605  // Set parent stats
606  parent.m_fileCount = files.size();
607  parent.m_dirCount = dirs.size();
608 
609  // Locate user assigned thumb amongst children, if defined
610  ImagePtr userIm;
611  if (parent.m_userThumbnail != 0)
612  {
613  ImageList images = files + dirs;
614  // ImageItem has been explicitly marked Q_DISABLE_COPY
615  for (const ImagePtr & im : qAsConst(images))
616  {
617  if (im && im->m_id == parent.m_userThumbnail)
618  { // cppcheck-suppress useStlAlgorithm
619  userIm = im;
620  break;
621  }
622  }
623  }
624 
625  // Children to use as thumbnails
626  ImageList thumbFiles;
627  ImageList thumbDirs;
628 
629  if (!userIm)
630  {
631  // Construct multi-thumbnail from all children
632  thumbFiles = files;
633  thumbDirs = dirs;
634  }
635  else if (userIm->IsFile())
636  {
637  thumbFiles.append(userIm);
638  thumbsNeeded = 1;
639  }
640  else
641  thumbDirs.append(userIm);
642 
643  // Fill parent thumbs from child files first
644  // Whilst they're available fill as many as possible for cache
645  for (int i = 0; i < std::min(kMaxFolderThumbnails, static_cast<int>(thumbFiles.size())); ++i)
646  {
647  parent.m_thumbNails.append(thumbFiles.at(i)->m_thumbNails.at(0));
648  --thumbsNeeded;
649  }
650 
651  // Only recurse if necessary
652  if (thumbsNeeded > 0)
653  {
654  // Prevent lengthy/infinite recursion due to deep/cyclic folder
655  // structures
656  if (++level > 10)
657  {
658  LOG(VB_GENERAL, LOG_NOTICE, LOC +
659  "Directory thumbnails are more than 10 levels deep");
660  }
661  else
662  {
663  // Recursively load subdir thumbs to try to get 1 thumb from each
664  for (const ImagePtr & im : qAsConst(thumbDirs))
665  {
666  if (!im)
667  continue;
668 
669  // Load sufficient thumbs from each dir as subsequent dirs may
670  // be empty
671  LoadDirThumbs(*im, thumbsNeeded, level);
672 
673  if (!im->m_thumbNails.empty())
674  {
675  // Add first thumbnail to parent thumb
676  parent.m_thumbNails.append(im->m_thumbNails.at(0));
677 
678  // Quit when we have sufficient thumbs
679  if (--thumbsNeeded == 0)
680  break;
681  }
682  }
683 
684  // If insufficient dirs to supply 1 thumb per dir, use other dir
685  // thumbs (indices 1-3) as well
686  int i = 0;
687  while (thumbsNeeded > 0 && ++i < kMaxFolderThumbnails)
688  {
689  for (const QSharedPointer<ImageItem> & im : qAsConst(thumbDirs))
690  {
691  if (i < im->m_thumbNails.size())
692  {
693  parent.m_thumbNails.append(im->m_thumbNails.at(i));
694  if (--thumbsNeeded == 0)
695  break;
696  }
697  }
698  }
699  }
700  }
701 
702  // Flag the cached entry with number of thumbs loaded. If future uses require
703  // more, then the dir must be reloaded.
704  // For user thumbs and dirs with insufficient child images, the cache is always valid
705  int scanned = (userIm || thumbsNeeded > 0)
707  : parent.m_thumbNails.size();
708 
709  // Cache result to optimize navigation
710  Cache(parent, scanned);
711 }
712 
713 
718 void DirectoryView::Clear(bool /*resetParent*/)
719 {
720  ClearMarked();
721  ClearCache();
722  FlatView::Clear();
723 }
724 
725 
730 {
731  // Any marking clears previous marks
734 }
735 
736 
742 void DirectoryView::Mark(int id, bool mark)
743 {
744  if (mark)
745  {
746  // Any marking clears previous marks
748  m_marked.Add(id);
749  }
750  else
751  {
752  m_prevMarked.remove(id);
753  m_marked.remove(id);
754  }
755 }
756 
757 
762 {
763  // Any marking clears previous marks
766 }
767 
768 
773 {
774  m_marked.Clear();
776 }
777 
778 
783 void DirectoryView::SetDirectory(int newParent)
784 {
785  if (m_marked.IsFor(newParent))
786  // Directory hasn't changed
787  return;
788 
789  // Markings are cleared on every dir change
790  // Any current markings become previous markings
791  // Only 1 set of previous markings are preserved
792  if (m_prevMarked.IsFor(newParent))
793  {
794  // Returned to dir of previous markings: reinstate them
797  return;
798  }
799 
800  if (!m_marked.isEmpty())
801  // Preserve current markings
803 
804  // Initialise current markings for new dir
805  m_marked.Initialise(newParent);
806 }
807 
808 
814 {
815  // hiddenMarked is true if 1 or more marked items are hidden
816  // unhiddenMarked is true if 1 or more marked items are not hidden
817  bool hiddenMarked = false;
818  bool unhiddenMarked = false;
819  for (int id : qAsConst(m_marked))
820  {
821  ImagePtrK im = m_images.value(id);
822  if (!im)
823  continue;
824 
825  if (im->m_isHidden)
826  hiddenMarked = true;
827  else
828  unhiddenMarked = true;
829 
830  if (hiddenMarked && unhiddenMarked)
831  break;
832  }
833 
834  return {GetSelected(), m_sequence.size() - 1,
836  hiddenMarked, unhiddenMarked};
837 }
838 
839 
847 {
848  DirCacheEntry cached(m_dirCache.value(dir.m_id));
849  if (cached.m_dirCount == -1 || cached.m_thumbCount < required)
850  return false;
851 
852  dir.m_fileCount = cached.m_fileCount;
853  dir.m_dirCount = cached.m_dirCount;
854  dir.m_thumbNails = cached.m_thumbs;
855 
856  LOG(VB_FILE, LOG_DEBUG, LOC + "Using cached " + cached.ToString(dir.m_id));
857  return true;
858 }
859 
860 
866 void DirectoryView::Cache(ImageItemK &dir, int thumbCount)
867 {
868  // Cache counts & thumbnails for each dir so that we don't need to reload its
869  // children from Db each time it's displayed
870  DirCacheEntry cacheEntry(dir.m_parentId, dir.m_dirCount, dir.m_fileCount,
871  dir.m_thumbNails, thumbCount);
872 
873  m_dirCache.insert(dir.m_id, cacheEntry);
874 
875  // Cache images used by dir thumbnails
876  for (const ThumbPair & thumb : qAsConst(dir.m_thumbNails))
877  {
878  // Do not overwrite any existing image url nor parent.
879  // Image url is cached when image is displayed as a child, but not as a
880  // ancestor dir thumbnail
881  // First cache attempt will be by parent. Subsequent attempts may be
882  // by ancestor dirs.
883  if (!m_fileCache.contains(thumb.first))
884  FlatView::Cache(thumb.first, dir.m_id, "", thumb.second);
885  }
886  LOG(VB_FILE, LOG_DEBUG, LOC + "Caching " + cacheEntry.ToString(dir.m_id));
887 }
888 
889 
894 {
895  LOG(VB_FILE, LOG_DEBUG, LOC + "Cleared Dir cache");
896  m_dirCache.clear();
898 }
899 
900 
908 QStringList DirectoryView::RemoveImage(int id, bool deleted)
909 {
910  QStringList urls;
911  int dirId = id;
912 
913  if (deleted)
914  {
915  m_marked.remove(id);
916  m_prevMarked.remove(id);
917  }
918 
919  // If id is a file then start with its parent
920  if (m_fileCache.contains(id))
921  {
922  // Clear file cache & start from its parent dir
923  dirId = m_fileCache.value(id).m_parent;
924  urls = FlatView::ClearImage(id, deleted);
925  }
926 
927  // Clear ancestor dirs
928  while (m_dirCache.contains(dirId))
929  {
930  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Cleared %1 from dir cache").arg(dirId));
931  DirCacheEntry dir = m_dirCache.take(dirId);
932  dirId = dir.m_parent;
933  }
934  return urls;
935 }
936 
937 
945 bool TreeView::LoadFromDb(int parentId)
946 {
947  m_parentId = parentId;
948 
949  // Load visible subtree of the parent
950  // Ordered images of parent first, then breadth-first recursion of ordered dirs
951  ImageList files;
952  m_mgr.GetImageTree(m_parentId, files);
953 
954  // Load view
955  Populate(files);
956 
957  return !files.isEmpty();
958 }
ImagePtrK
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:165
MarkedFiles::Add
void Add(const ImageIdList &newIds)
Definition: galleryviews.cpp:31
PHOTO_DB_ID
#define PHOTO_DB_ID
Definition: imagetypes.h:29
FlatView::CalculateSeasonalWeights
static WeightList CalculateSeasonalWeights(ImageList &files)
This method calculates a weight for the item based on how closely it was taken to the current time of...
Definition: galleryviews.cpp:314
ImageDbReader::GetImages
int GetImages(const ImageIdList &ids, ImageList &files, ImageList &dirs) const
Returns images (local or remote but not a combination)
Definition: imagemanager.cpp:1862
FlatView::HasNext
ImagePtrK HasNext(int inc) const
Peeks at next image in view but does not advance iterator.
Definition: galleryviews.cpp:152
LEADING_BETA_SHAPE
const double LEADING_BETA_SHAPE
Tuning parameter for seasonal weights, between 0 and 1, where lower numbers give greater weight to se...
Definition: galleryviews.cpp:21
DirectoryView::GetPosition
QString GetPosition() const
Get positional status.
Definition: galleryviews.cpp:490
ImageDbReader::GetImageTree
void GetImageTree(int id, ImageList &files) const
Return all files (local or remote) in the sub-trees of a dir.
Definition: imagemanager.cpp:1921
TreeView::LoadFromDb
bool LoadFromDb(int parentId) override
Populate view from database as images of a directory sub-tree. Default order of a tree is depth-first...
Definition: galleryviews.cpp:945
MarkedFiles::Initialise
void Initialise(int id)
Definition: galleryviews.h:38
FlatView::m_images
QHash< int, ImagePtrK > m_images
Image objects currently displayed.
Definition: galleryviews.h:133
ImageItem::m_id
int m_id
Uniquely identifies an image (file/dir).
Definition: imagetypes.h:89
FlatView::ClearImage
QStringList ClearImage(int id, bool remove=false)
Clear file from UI cache and optionally from view.
Definition: galleryviews.cpp:405
FileCacheEntry
Records info of displayed image files to enable clean-up of the UI image cache.
Definition: galleryviews.h:76
ImageDbReader::GetDirectory
int GetDirectory(int id, ImagePtr &parent, ImageList &files, ImageList &dirs) const
Return images (local and/or remote) for a dir and its direct children.
Definition: imagemanager.cpp:1830
DEFAULT_WEIGHT
const double DEFAULT_WEIGHT
Photos without an exif timestamp will default to the mode of the beta distribution.
Definition: galleryviews.cpp:26
kMaxFolderThumbnails
const static int kMaxFolderThumbnails
Number of thumbnails to use for folders.
Definition: galleryviews.cpp:13
FlatView::m_order
SlideOrderType m_order
Definition: galleryviews.h:131
DirectoryView::Mark
void Mark(int id, bool mark)
Mark/unmark an image/dir.
Definition: galleryviews.cpp:742
DirCacheEntry::m_thumbs
QList< ThumbPair > m_thumbs
Definition: galleryviews.h:160
FlatView::Rotate
void Rotate(int id)
Rotate view so that starting image is at front.
Definition: galleryviews.cpp:432
FlatView::LoadFromDb
virtual bool LoadFromDb(int parentId)
Populate view with database images from a directory.
Definition: galleryviews.cpp:373
DirectoryView::PopulateFromCache
bool PopulateFromCache(ImageItem &dir, int required)
Retrieve cached dir, if available.
Definition: galleryviews.cpp:846
FlatView::m_mgr
ImageManagerFe & m_mgr
Definition: galleryviews.h:132
FileCacheEntry::ToString
QString ToString(int id) const
Definition: galleryviews.h:84
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
FlatView
A datastore of images for display by a screen.
Definition: galleryviews.h:98
kSeasonal
@ kSeasonal
Biased random selection so that images are more likely to appear on anniversaries.
Definition: galleryviews.h:25
TRAILING_BETA_SHAPE
const double TRAILING_BETA_SHAPE
See LEADING_BETA_SHAPE.
Definition: galleryviews.cpp:23
build_compdb.file
file
Definition: build_compdb.py:55
FlatView::Populate
void Populate(ImageList &files)
Fills view with Db images, re-ordering them as required.
Definition: galleryviews.cpp:215
FlatView::GetPosition
QString GetPosition() const
Get positional status.
Definition: galleryviews.cpp:75
DirectoryView::Cache
void Cache(ImageItemK &dir, int thumbCount)
Cache displayed dir.
Definition: galleryviews.cpp:866
FlatView::ClearCache
void ClearCache()
Clears UI cache.
Definition: galleryviews.cpp:392
DirectoryView::m_dirCache
QHash< int, DirCacheEntry > m_dirCache
Caches displayed image dirs.
Definition: galleryviews.h:205
MarkedFiles::Clear
void Clear()
Definition: galleryviews.h:39
FlatView::Select
bool Select(int id, int fallback=0)
Selects first occurrence of an image.
Definition: galleryviews.cpp:117
FlatView::Prev
ImagePtrK Prev(int inc)
Decrements iterator and returns previous image. Wraps at start.
Definition: galleryviews.cpp:197
tmp
static guint32 * tmp
Definition: goom_core.cpp:32
FlatView::Update
bool Update(int id)
Updates view with images that have been updated.
Definition: galleryviews.cpp:86
DirectoryView::MarkAll
void MarkAll()
Mark all images/dirs.
Definition: galleryviews.cpp:729
BETA_CLIP
static constexpr qint64 BETA_CLIP
The edges of the distribution get clipped to avoid a singularity.
Definition: galleryviews.cpp:29
DirCacheEntry
Records dir info for every displayed dir.
Definition: galleryviews.h:145
MythDate::fromSecsSinceEpoch
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(int64_t seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:72
FlatView::m_fileCache
QHash< int, FileCacheEntry > m_fileCache
Caches displayed image files.
Definition: galleryviews.h:138
DirectoryView::DirectoryView
DirectoryView(SlideOrderType order)
Constructs a view of images & directories that can be marked.
Definition: galleryviews.cpp:478
mark
Definition: lang.cpp:22
FlatView::HasPrev
ImagePtrK HasPrev(int inc) const
Peeks at previous image in view but does not decrement iterator.
Definition: galleryviews.cpp:186
LOC
#define LOC
Definition: galleryviews.cpp:10
kShuffle
@ kShuffle
Each image appears exactly once, but in random order.
Definition: galleryviews.h:23
FlatView::GetAllNodes
ImageListK GetAllNodes() const
Get all images/dirs in view.
Definition: galleryviews.cpp:51
FlatView::m_parentId
int m_parentId
Definition: galleryviews.h:130
MenuSubjects
A snapshot of current selection, markings & dir info when menu is invoked.
Definition: galleryviews.h:52
DirectoryView::InvertMarked
void InvertMarked()
Mark all unmarked items, unmark all marked items.
Definition: galleryviews.cpp:761
ImageListK
QList< ImagePtrK > ImageListK
Definition: imagetypes.h:166
FlatView::GetSelected
ImagePtrK GetSelected() const
Get current selection.
Definition: galleryviews.cpp:64
DirectoryView::SetDirectory
void SetDirectory(int newParent)
Manage markings on tree navigation.
Definition: galleryviews.cpp:783
DirCacheEntry::m_fileCount
int m_fileCount
Definition: galleryviews.h:159
FlatView::Clear
void Clear(bool resetParent=true)
Reset view.
Definition: galleryviews.cpp:138
ImageList
QVector< ImagePtr > ImageList
Definition: imagetypes.h:160
DirectoryView::m_prevMarked
MarkedFiles m_prevMarked
Marked items in previous dir.
Definition: galleryviews.h:202
ImageItem::m_thumbNails
QList< ThumbPair > m_thumbNails
Definition: imagetypes.h:111
DirCacheEntry::ToString
QString ToString(int id) const
Definition: galleryviews.cpp:463
ImageItem::m_dirCount
int m_dirCount
Id & URLs of thumbnail(s). 1 for a file, 4 for dirs.
Definition: imagetypes.h:112
FlatView::Next
ImagePtrK Next(int inc)
Advance iterator and return next image, wrapping if necessary. Regenerates unordered views on wrap.
Definition: galleryviews.cpp:164
DirectoryView::LoadFromDb
bool LoadFromDb(int parentId) override
Populate view from database as images/subdirs of a directory. View is ordered: Parent dir,...
Definition: galleryviews.cpp:504
DirectoryView::m_marked
MarkedFiles m_marked
Marked items in current dir/view.
Definition: galleryviews.h:201
galleryviews.h
Provides view datastores for Gallery screens.
DirectoryView::LoadDirThumbs
void LoadDirThumbs(ImageItem &parent, int thumbsNeeded, int level=0)
Populate thumbs for a dir.
Definition: galleryviews.cpp:576
ImagePtr
QSharedPointer< ImageItem > ImagePtr
Definition: imagetypes.h:159
DirCacheEntry::m_thumbCount
int m_thumbCount
Definition: galleryviews.h:157
ImageItem
Represents a picture, video or directory.
Definition: imagetypes.h:68
DirCacheEntry::m_parent
int m_parent
Definition: galleryviews.h:156
FlatView::m_sequence
ImageIdList m_sequence
The sequence in which to display images.
Definition: galleryviews.h:134
ImageIdList
QList< int > ImageIdList
Definition: imagetypes.h:60
ImageItem::m_parentId
int m_parentId
Id of parent dir.
Definition: imagetypes.h:96
DirectoryView::GetMenuSubjects
MenuSubjects GetMenuSubjects()
Determine current selection, markings & various info to support menu display.
Definition: galleryviews.cpp:813
MarkedFiles::Invert
void Invert(const ImageIdList &all)
Definition: galleryviews.cpp:37
ImageDbReader::GetChildren
int GetChildren(int id, ImageList &files, ImageList &dirs) const
Return (local or remote) images that are direct children of a dir.
Definition: imagemanager.cpp:1883
DirectoryView::PopulateThumbs
void PopulateThumbs(ImageItem &parent, int thumbsNeeded, const ImageList &files, const ImageList &dirs, int level=0)
Populate directory stats & thumbnails recursively from database as follows: Use user cover,...
Definition: galleryviews.cpp:601
SlideOrderType
SlideOrderType
Order of images in slideshow.
Definition: galleryviews.h:21
DirectoryView::ClearCache
void ClearCache()
Clears UI cache.
Definition: galleryviews.cpp:893
DirectoryView::Clear
void Clear(bool resetParent=true)
Resets view.
Definition: galleryviews.cpp:718
DirectoryView::RemoveImage
QStringList RemoveImage(int id, bool deleted=false)
Clear file/dir and all its ancestors from UI cache so that ancestor thumbnails are recalculated....
Definition: galleryviews.cpp:908
WeightList
QVector< double > WeightList
Seasonal weightings for images in a view.
Definition: galleryviews.h:30
ThumbPair
QPair< int, QString > ThumbPair
Definition: imagetypes.h:64
ImageItem::m_userThumbnail
int m_userThumbnail
Id of thumbnail to use as cover (dirs only)
Definition: imagetypes.h:106
kOrdered
@ kOrdered
Ordered as per user setting GallerySortOrder.
Definition: galleryviews.h:22
FlatView::Cache
void Cache(int id, int parent, const QString &url, const QString &thumb)
Cache image properties to optimize UI.
Definition: galleryviews.cpp:453
MarkedFiles::IsFor
bool IsFor(int id) const
Definition: galleryviews.h:40
DirectoryView::GetChildren
ImageIdList GetChildren() const
Definition: galleryviews.h:197
DirectoryView::ClearMarked
void ClearMarked()
Unmark all items.
Definition: galleryviews.cpp:772
kRandom
@ kRandom
Random selection from view. An image may be absent or appear multiple times.
Definition: galleryviews.h:24
DirCacheEntry::m_dirCount
int m_dirCount
Definition: galleryviews.h:158
GALLERY_DB_ID
#define GALLERY_DB_ID
Definition: imagetypes.h:27
ImageItem::m_fileCount
int m_fileCount
Number of child images (dirs only)
Definition: imagetypes.h:113
FlatView::m_active
int m_active
Sequence index of current selected image.
Definition: galleryviews.h:135