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