MythTV  master
galleryviews.cpp
Go to the documentation of this file.
1 #include "galleryviews.h"
2 
3 #include <algorithm> // std::shuffle, upper_bound
4 #include <cmath> // std::pow
5 #include <cstdint>
6 #include <iterator> // std::distance
7 #include <random>
8 #include <vector>
9 
10 #include "libmythbase/mythrandom.h"
11 
12 #define LOC QString("Galleryviews: ")
13 
15 const static int kMaxFolderThumbnails = 4;
16 
23 const double LEADING_BETA_SHAPE = 0.175;
25 const double TRAILING_BETA_SHAPE = 0.31;
26 
28 const double DEFAULT_WEIGHT = std::pow(0.5, TRAILING_BETA_SHAPE - 1) *
29  std::pow(0.5, LEADING_BETA_SHAPE - 1);
31 static constexpr qint64 BETA_CLIP { 24LL * 60 * 60 };
32 
33 void MarkedFiles::Add(const ImageIdList& newIds)
34 {
35  for (int newid : newIds)
36  insert(newid);
37 }
38 
40 {
41  QSet tmp;
42  for (int tmpint : all)
43  tmp.insert(tmpint);
44  for (int tmpint : std::as_const(*this))
45  tmp.remove(tmpint);
46  swap(tmp);
47 }
48 
54 {
55  ImageListK files;
56  for (int id : std::as_const(m_sequence))
57  files.append(m_images.value(id));
58  return files;
59 }
60 
61 
67 {
68  return m_active < 0 || m_active >= m_sequence.size()
69  ? ImagePtrK() : m_images.value(m_sequence.at(m_active));
70 }
71 
72 
77 QString FlatView::GetPosition() const
78 {
79  return QString("%1/%2").arg(m_active + 1).arg(m_sequence.size());
80 }
81 
82 
88 bool FlatView::Update(int id)
89 {
90  ImagePtrK im = m_images.value(id);
91  if (!im)
92  return false;
93 
94  // Get updated image
95  ImageList files;
96  ImageList dirs;
97  ImageIdList ids = ImageIdList() << id;
98  if (m_mgr.GetImages(ids, files, dirs) != 1 || files.size() != 1)
99  return false;
100 
101  bool active = (im == GetSelected());
102 
103  // Replace image
104  m_images.insert(id, files.at(0));
105 
106  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Modified id %1").arg(id));
107 
108  return active;
109 }
110 
111 
119 bool FlatView::Select(int id, int fallback)
120 {
121  // Select first appearance of image
122  int index = m_sequence.indexOf(id);
123  if (index >= 0)
124  {
125  m_active = index;
126  return true;
127  }
128 
129  if (fallback >= 0)
130  m_active = fallback;
131 
132  return false;
133 }
134 
135 
140 void FlatView::Clear(bool resetParent)
141 {
142  m_images.clear();
143  m_sequence.clear();
144  m_active = -1;
145  if (resetParent)
147 }
148 
149 
155 {
156  return m_sequence.isEmpty() || m_active + inc >= m_sequence.size()
157  ? ImagePtrK() : m_images.value(m_sequence.at(m_active + inc));
158 }
159 
160 
167 {
168  if (m_sequence.isEmpty())
169  return {};
170 
171  // Preserve index as it may be reset when wrapping
172  int next = m_active + inc;
173 
174  // Regenerate unordered views when wrapping
175  if (next >= m_sequence.size() && m_order != kOrdered && !LoadFromDb(m_parentId))
176  // Images have disappeared
177  return {};
178 
179  m_active = next % m_sequence.size();
180  return m_images.value(m_sequence.at(m_active));
181 }
182 
183 
189 {
190  return m_sequence.isEmpty() || m_active < inc
191  ? ImagePtrK() : m_images.value(m_sequence.at(m_active - inc));
192 }
193 
194 
200 {
201  if (m_sequence.isEmpty())
202  return {};
203 
204  // Wrap avoiding modulo of negative uncertainty
205  m_active -= inc % m_sequence.size();
206  if (m_active < 0)
207  m_active += m_sequence.size();
208 
209  return m_images.value(m_sequence.at(m_active));
210 }
211 
212 
218 {
219  // Do not reset parent
220  Clear(false);
221 
222  if (files.isEmpty())
223  return;
224 
225  for (const QSharedPointer<ImageItem> & im : std::as_const(files))
226  {
227  // Add image to view
228  m_images.insert(im->m_id, im);
229 
230  // Cache all displayed images
231  if (im->IsFile())
232  Cache(im->m_id, im->m_parentId, im->m_url, im->m_thumbNails.at(0).second);
233  }
234 
235  if (files.size() == 1 || m_order == kOrdered || m_order == kShuffle)
236  {
237  // Default sequence is ordered
238  for (const QSharedPointer<ImageItem> & im : std::as_const(files))
239  m_sequence.append(im->m_id);
240  }
241 
242  if (files.size() > 1)
243  {
244  // Modify viewing sequence
245  if (m_order == kShuffle)
246  {
247  std::shuffle(m_sequence.begin(), m_sequence.end(),
248  std::mt19937(std::random_device()()));
249  }
250  else if (m_order == kRandom)
251  {
252  // An image is not a valid candidate for its successor
253  // add files.size() elements from files in a random order
254  // to m_sequence allowing non-consecutive repetition
255  int size = files.size();
256  int range = files.size() - 1;
257  int last = size; // outside of the random interval [0, size)
258  int count = 0;
259  while (count < size)
260  {
261  int rand = MythRandom(0, range);
262 
263  // Avoid consecutive repeats
264  if (last == rand)
265  {
266  continue;
267  }
268  last = rand;
269  m_sequence.append(files.at(rand)->m_id);
270  count++;
271  }
272  }
273  else if (m_order == kSeasonal)
274  {
275  WeightList cdf = CalculateSeasonalWeights(files); // not normalized to 1.0
276  std::vector<uint32_t> weights;
277  weights.reserve(cdf.size());
278  for (int i = 0; i < cdf.size(); i++)
279  {
280  weights.emplace_back(lround(cdf[i] / cdf.back() * UINT32_MAX));
281  }
282  // exclude the last value so the past the end iterator is not returned
283  // by std::upper_bound
284  if (!weights.empty())
285  {
286  uint32_t maxWeight = weights.back() - 1;
287 
288  for (int count = 0; count < files.size(); ++count)
289  {
290  uint32_t randWeight = MythRandom(0, maxWeight);
291  auto it = std::upper_bound(weights.begin(), weights.end(), randWeight);
292  int index = std::distance(weights.begin(), it);
293  m_sequence.append(files.at(index)->m_id);
294  }
295  }
296  }
297  }
298 }
299 
300 
312 {
313  WeightList weights(files.size());
314  double totalWeight = 0;
315  QDateTime now = QDateTime::currentDateTime();
316 
317  for (int i = 0; i < files.size(); ++i)
318  {
319  ImagePtrK im = files.at(i);
320  double weight = 0;
321 
322  if (im->m_date == 0s)
323  weight = DEFAULT_WEIGHT;
324  else
325  {
326  QDateTime timestamp = QDateTime::fromSecsSinceEpoch(im->m_date.count());
327  QDateTime curYearAnniversary =
328  QDateTime(QDate(now.date().year(),
329  timestamp.date().month(),
330  timestamp.date().day()),
331  timestamp.time());
332 
333  bool isAnniversaryPast = curYearAnniversary < now;
334 
335  QDateTime adjacentYearAnniversary =
336  QDateTime(QDate(now.date().year() +
337  (isAnniversaryPast ? 1 : -1),
338  timestamp.date().month(),
339  timestamp.date().day()),
340  timestamp.time());
341 
342  double range = llabs(curYearAnniversary.secsTo(
343  adjacentYearAnniversary)) + BETA_CLIP;
344 
345  // This calculation is not normalized, because that would require the
346  // beta function, which isn't part of the C++98 libraries. Weights
347  // that aren't normalized work just as well relative to each other.
348  QDateTime d1(isAnniversaryPast ? curYearAnniversary
349  : adjacentYearAnniversary);
350  QDateTime d2(isAnniversaryPast ? adjacentYearAnniversary
351  : curYearAnniversary);
352  weight = std::pow(llabs(now.secsTo(d1) + BETA_CLIP) / range,
354  * std::pow(llabs(now.secsTo(d2) + BETA_CLIP) / range,
355  LEADING_BETA_SHAPE - 1);
356  }
357  totalWeight += weight;
358  weights[i] = totalWeight;
359  }
360  return weights;
361 }
362 
363 
370 bool FlatView::LoadFromDb(int parentId)
371 {
372  m_parentId = parentId;
373 
374  // Load child images of the parent
375  ImageList files;
376  ImageList dirs;
377  m_mgr.GetChildren(m_parentId, files, dirs);
378 
379  // Load gallery datastore with current dir
380  Populate(files);
381 
382  return !files.isEmpty();
383 }
384 
385 
390 {
391  LOG(VB_FILE, LOG_DEBUG, LOC + "Cleared File cache");
392  m_fileCache.clear();
393 }
394 
395 
402 QStringList FlatView::ClearImage(int id, bool remove)
403 {
404  if (remove)
405  {
406  m_sequence.removeAll(id);
407  m_images.remove(id);
408  }
409 
410  QStringList urls;
411  FileCacheEntry file = m_fileCache.take(id);
412 
413  if (!file.m_url.isEmpty())
414  urls << file.m_url;
415 
416  if (!file.m_thumbUrl.isEmpty())
417  urls << file.m_thumbUrl;
418 
419  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Cleared %1 from file cache (%2)")
420  .arg(id).arg(urls.join(",")));
421  return urls;
422 }
423 
424 
429 void FlatView::Rotate(int id)
430 {
431  // Rotate sequence so that (first appearance of) specified image is
432  // at offset from front
433  int index = m_sequence.indexOf(id);
434  if (index >= 0)
435  {
436  int first = index % m_sequence.size();
437  if (first > 0)
438  m_sequence = m_sequence.mid(first) + m_sequence.mid(0, first);
439  }
440 }
441 
442 
450 void FlatView::Cache(int id, int parent, const QString &url, const QString &thumb)
451 {
452  // Cache parent dir so that dir thumbs are updated when a child changes.
453  // Also store urls for image cache cleanup
454  FileCacheEntry cached(parent, url, thumb);
455  m_fileCache.insert(id, cached);
456  LOG(VB_FILE, LOG_DEBUG, LOC + "Caching " + cached.ToString(id));
457 }
458 
459 
460 QString DirCacheEntry::ToString(int id) const
461 {
462  QStringList ids;
463  for (const auto & thumb : std::as_const(m_thumbs))
464  ids << QString::number(thumb.first);
465  return QString("Dir %1 (%2, %3) Thumbs %4 (%5) Parent %6")
466  .arg(id).arg(m_fileCount).arg(m_dirCount).arg(ids.join(","))
467  .arg(m_thumbCount).arg(m_parent);
468 }
469 
470 
476  : FlatView(order)
477 {
478  m_marked.Clear();
480 }
481 
482 
488 {
489  return QString("%1/%2").arg(m_active).arg(m_sequence.size() - 1);
490 }
491 
492 
501 bool DirectoryView::LoadFromDb(int parentId)
502 {
503  // Determine parent (defaulting to ancestor) & get initial children
504  ImageList files;
505  ImageList dirs;
506  ImagePtr parent;
507  int count = 0;
508  // Root is guaranteed to return at least 1 item
509  while ((count = m_mgr.GetDirectory(parentId, parent, files, dirs)) == 0)
510  {
511  // Fallback if dir no longer exists
512  // Ascend to Gallery for gallery subdirs, Root for device dirs & Gallery
513  parentId = parentId > PHOTO_DB_ID ? PHOTO_DB_ID : GALLERY_DB_ID;
514  }
515 
516  SetDirectory(parentId);
517  m_parentId = parentId;
518 
519  // No SG & no devices uses special 'empty' screen
520  if (!parent || (parentId == GALLERY_DB_ID && count == 1))
521  {
522  parent.clear();
523  return false;
524  }
525 
526  // Populate all subdirs
527  for (const ImagePtr & im : std::as_const(dirs))
528  {
529  if (im)
530  // Load sufficient thumbs from each dir as subsequent dirs may be empty
532  }
533 
534  // Populate parent
536  PopulateThumbs(*parent, kMaxFolderThumbnails, files, dirs);
537 
538  // Dirs shown before images
539  ImageList images = dirs + files;
540 
541  // Validate marked images
542  if (!m_marked.isEmpty())
543  {
544  QSet<int> ids;
545  for (const QSharedPointer<ImageItem> & im : std::as_const(images))
546  ids.insert(im->m_id);
547  m_marked.intersect(ids);
548  }
549 
550  // Parent is always first (for navigating up).
551  images.prepend(parent);
552 
553  // Preserve current selection before view is destroyed
554  ImagePtrK selected = GetSelected();
555  int activeId = selected ? selected->m_id : 0;
556 
557  // Construct view
558  Populate(images);
559 
560  // Reinstate selection, falling back to parent
561  Select(activeId);
562 
563  return true;
564 }
565 
566 
573 void DirectoryView::LoadDirThumbs(ImageItem &parent, int thumbsNeeded, int level)
574 {
575  // Use cached data, if available
576  if (PopulateFromCache(parent, thumbsNeeded))
577  return;
578 
579  // Load child images & dirs
580  ImageList files;
581  ImageList dirs;
582  m_mgr.GetChildren(parent.m_id, files, dirs);
583 
584  PopulateThumbs(parent, thumbsNeeded, files, dirs, level);
585 }
586 
587 
598 void DirectoryView::PopulateThumbs(ImageItem &parent, int thumbsNeeded,
599  const ImageList &files, const ImageList &dirs,
600  int level)
601 {
602  // Set parent stats
603  parent.m_fileCount = files.size();
604  parent.m_dirCount = dirs.size();
605 
606  // Locate user assigned thumb amongst children, if defined
607  ImagePtr userIm;
608  if (parent.m_userThumbnail != 0)
609  {
610  ImageList images = files + dirs;
611  // ImageItem has been explicitly marked Q_DISABLE_COPY
612  for (const ImagePtr & im : std::as_const(images))
613  {
614  if (im && im->m_id == parent.m_userThumbnail)
615  { // cppcheck-suppress useStlAlgorithm
616  userIm = im;
617  break;
618  }
619  }
620  }
621 
622  // Children to use as thumbnails
623  ImageList thumbFiles;
624  ImageList thumbDirs;
625 
626  if (!userIm)
627  {
628  // Construct multi-thumbnail from all children
629  thumbFiles = files;
630  thumbDirs = dirs;
631  }
632  else if (userIm->IsFile())
633  {
634  thumbFiles.append(userIm);
635  thumbsNeeded = 1;
636  }
637  else
638  {
639  thumbDirs.append(userIm);
640  }
641 
642  // Fill parent thumbs from child files first
643  // Whilst they're available fill as many as possible for cache
644 #if QT_VERSION < QT_VERSION_CHECK(6,0,0)
645  for (int i = 0; i < std::min(kMaxFolderThumbnails, thumbFiles.size()); ++i)
646 #else
647  for (int i = 0; i < std::min(kMaxFolderThumbnails, static_cast<int>(thumbFiles.size())); ++i)
648 #endif
649  {
650  parent.m_thumbNails.append(thumbFiles.at(i)->m_thumbNails.at(0));
651  --thumbsNeeded;
652  }
653 
654  // Only recurse if necessary
655  if (thumbsNeeded > 0)
656  {
657  // Prevent lengthy/infinite recursion due to deep/cyclic folder
658  // structures
659  if (++level > 10)
660  {
661  LOG(VB_GENERAL, LOG_NOTICE, LOC +
662  "Directory thumbnails are more than 10 levels deep");
663  }
664  else
665  {
666  // Recursively load subdir thumbs to try to get 1 thumb from each
667  for (const ImagePtr & im : std::as_const(thumbDirs))
668  {
669  if (!im)
670  continue;
671 
672  // Load sufficient thumbs from each dir as subsequent dirs may
673  // be empty
674  LoadDirThumbs(*im, thumbsNeeded, level);
675 
676  if (!im->m_thumbNails.empty())
677  {
678  // Add first thumbnail to parent thumb
679  parent.m_thumbNails.append(im->m_thumbNails.at(0));
680 
681  // Quit when we have sufficient thumbs
682  if (--thumbsNeeded == 0)
683  break;
684  }
685  }
686 
687  // If insufficient dirs to supply 1 thumb per dir, use other dir
688  // thumbs (indices 1-3) as well
689  int i = 0;
690  while (thumbsNeeded > 0 && ++i < kMaxFolderThumbnails)
691  {
692  for (const QSharedPointer<ImageItem> & im : std::as_const(thumbDirs))
693  {
694  if (i < im->m_thumbNails.size())
695  {
696  parent.m_thumbNails.append(im->m_thumbNails.at(i));
697  if (--thumbsNeeded == 0)
698  break;
699  }
700  }
701  }
702  }
703  }
704 
705  // Flag the cached entry with number of thumbs loaded. If future uses require
706  // more, then the dir must be reloaded.
707  // For user thumbs and dirs with insufficient child images, the cache is always valid
708  int scanned = (userIm || thumbsNeeded > 0)
710  : parent.m_thumbNails.size();
711 
712  // Cache result to optimize navigation
713  Cache(parent, scanned);
714 }
715 
716 
721 void DirectoryView::Clear(bool /*resetParent*/)
722 {
723  ClearMarked();
724  ClearCache();
725  FlatView::Clear();
726 }
727 
728 
733 {
734  // Any marking clears previous marks
737 }
738 
739 
745 void DirectoryView::Mark(int id, bool mark)
746 {
747  if (mark)
748  {
749  // Any marking clears previous marks
751  m_marked.Add(id);
752  }
753  else
754  {
755  m_prevMarked.remove(id);
756  m_marked.remove(id);
757  }
758 }
759 
760 
765 {
766  // Any marking clears previous marks
769 }
770 
771 
776 {
777  m_marked.Clear();
779 }
780 
781 
786 void DirectoryView::SetDirectory(int newParent)
787 {
788  if (m_marked.IsFor(newParent))
789  // Directory hasn't changed
790  return;
791 
792  // Markings are cleared on every dir change
793  // Any current markings become previous markings
794  // Only 1 set of previous markings are preserved
795  if (m_prevMarked.IsFor(newParent))
796  {
797  // Returned to dir of previous markings: reinstate them
800  return;
801  }
802 
803  if (!m_marked.isEmpty())
804  // Preserve current markings
806 
807  // Initialise current markings for new dir
808  m_marked.Initialise(newParent);
809 }
810 
811 
817 {
818  // hiddenMarked is true if 1 or more marked items are hidden
819  // unhiddenMarked is true if 1 or more marked items are not hidden
820  bool hiddenMarked = false;
821  bool unhiddenMarked = false;
822  for (int id : std::as_const(m_marked))
823  {
824  ImagePtrK im = m_images.value(id);
825  if (!im)
826  continue;
827 
828  if (im->m_isHidden)
829  hiddenMarked = true;
830  else
831  unhiddenMarked = true;
832 
833  if (hiddenMarked && unhiddenMarked)
834  break;
835  }
836 
837  return {GetSelected(), m_sequence.size() - 1,
839  hiddenMarked, unhiddenMarked};
840 }
841 
842 
850 {
851  DirCacheEntry cached(m_dirCache.value(dir.m_id));
852  if (cached.m_dirCount == -1 || cached.m_thumbCount < required)
853  return false;
854 
855  dir.m_fileCount = cached.m_fileCount;
856  dir.m_dirCount = cached.m_dirCount;
857  dir.m_thumbNails = cached.m_thumbs;
858 
859  LOG(VB_FILE, LOG_DEBUG, LOC + "Using cached " + cached.ToString(dir.m_id));
860  return true;
861 }
862 
863 
869 void DirectoryView::Cache(ImageItemK &dir, int thumbCount)
870 {
871  // Cache counts & thumbnails for each dir so that we don't need to reload its
872  // children from Db each time it's displayed
873  DirCacheEntry cacheEntry(dir.m_parentId, dir.m_dirCount, dir.m_fileCount,
874  dir.m_thumbNails, thumbCount);
875 
876  m_dirCache.insert(dir.m_id, cacheEntry);
877 
878  // Cache images used by dir thumbnails
879  for (const ThumbPair & thumb : std::as_const(dir.m_thumbNails))
880  {
881  // Do not overwrite any existing image url nor parent.
882  // Image url is cached when image is displayed as a child, but not as a
883  // ancestor dir thumbnail
884  // First cache attempt will be by parent. Subsequent attempts may be
885  // by ancestor dirs.
886  if (!m_fileCache.contains(thumb.first))
887  FlatView::Cache(thumb.first, dir.m_id, "", thumb.second);
888  }
889  LOG(VB_FILE, LOG_DEBUG, LOC + "Caching " + cacheEntry.ToString(dir.m_id));
890 }
891 
892 
897 {
898  LOG(VB_FILE, LOG_DEBUG, LOC + "Cleared Dir cache");
899  m_dirCache.clear();
901 }
902 
903 
911 QStringList DirectoryView::RemoveImage(int id, bool deleted)
912 {
913  QStringList urls;
914  int dirId = id;
915 
916  if (deleted)
917  {
918  m_marked.remove(id);
919  m_prevMarked.remove(id);
920  }
921 
922  // If id is a file then start with its parent
923  if (m_fileCache.contains(id))
924  {
925  // Clear file cache & start from its parent dir
926  dirId = m_fileCache.value(id).m_parent;
927  urls = FlatView::ClearImage(id, deleted);
928  }
929 
930  // Clear ancestor dirs
931  while (m_dirCache.contains(dirId))
932  {
933  LOG(VB_FILE, LOG_DEBUG, LOC + QString("Cleared %1 from dir cache").arg(dirId));
934  DirCacheEntry dir = m_dirCache.take(dirId);
935  dirId = dir.m_parent;
936  }
937  return urls;
938 }
939 
940 
948 bool TreeView::LoadFromDb(int parentId)
949 {
950  m_parentId = parentId;
951 
952  // Load visible subtree of the parent
953  // Ordered images of parent first, then breadth-first recursion of ordered dirs
954  ImageList files;
955  m_mgr.GetImageTree(m_parentId, files);
956 
957  // Load view
958  Populate(files);
959 
960  return !files.isEmpty();
961 }
ImagePtrK
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:165
SlideOrderType
SlideOrderType
Order of images in slideshow.
Definition: galleryviews.h:21
MarkedFiles::Add
void Add(const ImageIdList &newIds)
Definition: galleryviews.cpp:33
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:311
ImageDbReader::GetImages
int GetImages(const ImageIdList &ids, ImageList &files, ImageList &dirs) const
Returns images (local or remote but not a combination)
Definition: imagemanager.cpp:1834
FlatView::HasNext
ImagePtrK HasNext(int inc) const
Peeks at next image in view but does not advance iterator.
Definition: galleryviews.cpp:154
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:23
DirectoryView::GetPosition
QString GetPosition() const
Get positional status.
Definition: galleryviews.cpp:487
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:1893
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:948
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:402
FileCacheEntry
Records info of displayed image files to enable clean-up of the UI image cache.
Definition: galleryviews.h:76
mythrandom.h
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:1802
DEFAULT_WEIGHT
const double DEFAULT_WEIGHT
Photos without an exif timestamp will default to the mode of the beta distribution.
Definition: galleryviews.cpp:28
kMaxFolderThumbnails
const static int kMaxFolderThumbnails
Number of thumbnails to use for folders.
Definition: galleryviews.cpp:15
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:745
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:429
FlatView::LoadFromDb
virtual bool LoadFromDb(int parentId)
Populate view with database images from a directory.
Definition: galleryviews.cpp:370
DirectoryView::PopulateFromCache
bool PopulateFromCache(ImageItem &dir, int required)
Retrieve cached dir, if available.
Definition: galleryviews.cpp:849
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:39
FlatView
A datastore of images for display by a screen.
Definition: galleryviews.h:98
TRAILING_BETA_SHAPE
const double TRAILING_BETA_SHAPE
See LEADING_BETA_SHAPE.
Definition: galleryviews.cpp:25
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:217
FlatView::GetPosition
QString GetPosition() const
Get positional status.
Definition: galleryviews.cpp:77
DirectoryView::Cache
void Cache(ImageItemK &dir, int thumbCount)
Cache displayed dir.
Definition: galleryviews.cpp:869
FlatView::ClearCache
void ClearCache()
Clears UI cache.
Definition: galleryviews.cpp:389
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:119
kRandom
@ kRandom
Random selection from view. An image may be absent or appear multiple times.
Definition: galleryviews.h:24
FlatView::Prev
ImagePtrK Prev(int inc)
Decrements iterator and returns previous image. Wraps at start.
Definition: galleryviews.cpp:199
tmp
static guint32 * tmp
Definition: goom_core.cpp:26
FlatView::Update
bool Update(int id)
Updates view with images that have been updated.
Definition: galleryviews.cpp:88
DirectoryView::MarkAll
void MarkAll()
Mark all images/dirs.
Definition: galleryviews.cpp:732
BETA_CLIP
static constexpr qint64 BETA_CLIP
The edges of the distribution get clipped to avoid a singularity.
Definition: galleryviews.cpp:31
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:81
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:475
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:188
LOC
#define LOC
Definition: galleryviews.cpp:12
FlatView::GetAllNodes
ImageListK GetAllNodes() const
Get all images/dirs in view.
Definition: galleryviews.cpp:53
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:764
ImageListK
QList< ImagePtrK > ImageListK
Definition: imagetypes.h:166
FlatView::GetSelected
ImagePtrK GetSelected() const
Get current selection.
Definition: galleryviews.cpp:66
DirectoryView::SetDirectory
void SetDirectory(int newParent)
Manage markings on tree navigation.
Definition: galleryviews.cpp:786
DirCacheEntry::m_fileCount
int m_fileCount
Definition: galleryviews.h:159
FlatView::Clear
void Clear(bool resetParent=true)
Reset view.
Definition: galleryviews.cpp:140
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:460
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:166
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:501
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:573
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:816
PHOTO_DB_ID
static constexpr int PHOTO_DB_ID
Definition: imagetypes.h:29
MarkedFiles::Invert
void Invert(const ImageIdList &all)
Definition: galleryviews.cpp:39
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:1855
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:598
DirectoryView::ClearCache
void ClearCache()
Clears UI cache.
Definition: galleryviews.cpp:896
DirectoryView::Clear
void Clear(bool resetParent=true)
Resets view.
Definition: galleryviews.cpp:721
kSeasonal
@ kSeasonal
Biased random selection so that images are more likely to appear on anniversaries.
Definition: galleryviews.h:25
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:911
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:450
GALLERY_DB_ID
static constexpr int GALLERY_DB_ID
Definition: imagetypes.h:27
MarkedFiles::IsFor
bool IsFor(int id) const
Definition: galleryviews.h:40
kShuffle
@ kShuffle
Each image appears exactly once, but in random order.
Definition: galleryviews.h:23
DirectoryView::GetChildren
ImageIdList GetChildren() const
Definition: galleryviews.h:197
DirectoryView::ClearMarked
void ClearMarked()
Unmark all items.
Definition: galleryviews.cpp:775
MythRandomStd::MythRandom
uint32_t MythRandom()
generate 32 random bits
Definition: mythrandom.h:20
DirCacheEntry::m_dirCount
int m_dirCount
Definition: galleryviews.h:158
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