13#define LOC QString("Galleryviews: ")
32static constexpr qint64
BETA_CLIP { 24LL * 60 * 60 };
36 for (
int newid : newIds)
43 for (
int tmpint : all)
45 for (
int tmpint : std::as_const(*
this))
69 return m_active < 0 || m_active >=
m_sequence.size()
107 LOG(VB_FILE, LOG_DEBUG,
LOC + QString(
"Modified id %1").arg(
id));
226 for (
const QSharedPointer<ImageItem> & im : std::as_const(files))
233 Cache(im->m_id, im->m_parentId, im->m_url, im->m_thumbNails.at(0).second);
239 for (
const QSharedPointer<ImageItem> & im : std::as_const(files))
243 if (files.size() > 1)
249 std::mt19937(std::random_device()()));
256 int size = files.size();
257 int range = files.size() - 1;
277 std::vector<uint32_t> weights;
278 weights.reserve(cdf.size());
279 for (
int i = 0; i < cdf.size(); i++)
281 weights.emplace_back(lround(cdf[i] / cdf.back() * UINT32_MAX));
285 if (!weights.empty())
287 uint32_t maxWeight = weights.back() - 1;
289 for (
int count = 0; count < files.size(); ++count)
291 uint32_t randWeight =
MythRandom(0, maxWeight);
292 auto it = std::ranges::upper_bound(weights, randWeight);
293 int index = std::distance(weights.begin(), it);
315 double totalWeight = 0;
316 QDateTime now = QDateTime::currentDateTime();
318 for (
int i = 0; i < files.size(); ++i)
323 if (im->m_date == 0s)
330 QDateTime curYearAnniversary =
331 QDateTime(QDate(now.date().year(),
332 timestamp.date().month(),
333 timestamp.date().day()),
336 bool isAnniversaryPast = curYearAnniversary < now;
338 QDateTime adjacentYearAnniversary =
339 QDateTime(QDate(now.date().year() +
340 (isAnniversaryPast ? 1 : -1),
341 timestamp.date().month(),
342 timestamp.date().day()),
345 double range = llabs(curYearAnniversary.secsTo(
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,
360 totalWeight += weight;
361 weights[i] = totalWeight;
385 return !files.isEmpty();
394 LOG(VB_FILE, LOG_DEBUG,
LOC +
"Cleared File cache");
416 if (!
file.m_url.isEmpty())
419 if (!
file.m_thumbUrl.isEmpty())
420 urls <<
file.m_thumbUrl;
422 LOG(VB_FILE, LOG_DEBUG,
LOC + QString(
"Cleared %1 from file cache (%2)")
423 .arg(
id).arg(urls.join(
",")));
466 for (
const auto & thumb : std::as_const(
m_thumbs))
467 ids << QString::number(thumb.first);
468 return QString(
"Dir %1 (%2, %3) Thumbs %4 (%5) Parent %6")
530 for (
const ImagePtr & im : std::as_const(dirs))
548 for (
const QSharedPointer<ImageItem> & im : std::as_const(images))
549 ids.insert(im->m_id);
554 images.prepend(parent);
558 int activeId = selected ? selected->m_id : 0;
615 for (
const ImagePtr & im : std::as_const(images))
635 else if (userIm->IsFile())
637 thumbFiles.append(userIm);
642 thumbDirs.append(userIm);
647#if QT_VERSION < QT_VERSION_CHECK(6,0,0)
650 for (
int i = 0; i < std::min(kMaxFolderThumbnails, static_cast<int>(thumbFiles.size())); ++i)
653 parent.
m_thumbNails.append(thumbFiles.at(i)->m_thumbNails.at(0));
658 if (thumbsNeeded > 0)
664 LOG(VB_GENERAL, LOG_NOTICE,
LOC +
665 "Directory thumbnails are more than 10 levels deep");
670 for (
const ImagePtr & im : std::as_const(thumbDirs))
679 if (!im->m_thumbNails.empty())
685 if (--thumbsNeeded == 0)
695 for (
const QSharedPointer<ImageItem> & im : std::as_const(thumbDirs))
697 if (i < im->m_thumbNails.size())
700 if (--thumbsNeeded == 0)
711 int scanned = (userIm || thumbsNeeded > 0)
716 Cache(parent, scanned);
823 bool hiddenMarked =
false;
824 bool unhiddenMarked =
false;
825 for (
int id : std::as_const(
m_marked))
834 unhiddenMarked =
true;
836 if (hiddenMarked && unhiddenMarked)
842 hiddenMarked, unhiddenMarked};
901 LOG(VB_FILE, LOG_DEBUG,
LOC +
"Cleared Dir cache");
936 LOG(VB_FILE, LOG_DEBUG,
LOC + QString(
"Cleared %1 from dir cache").arg(dirId));
963 return !files.isEmpty();
Records dir info for every displayed dir.
QString ToString(int id) const
QList< ThumbPair > m_thumbs
void LoadDirThumbs(ImageItem &parent, int thumbsNeeded, int level=0)
Populate thumbs for a dir.
QString GetPosition() const
Get positional status.
void ClearMarked()
Unmark all items.
void Clear(bool resetParent=true)
Resets view.
bool PopulateFromCache(ImageItem &dir, int required)
Retrieve cached dir, if available.
MenuSubjects GetMenuSubjects()
Determine current selection, markings & various info to support menu display.
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,...
QHash< int, DirCacheEntry > m_dirCache
Caches displayed image dirs.
DirectoryView(SlideOrderType order)
Constructs a view of images & directories that can be marked.
void MarkAll()
Mark all images/dirs.
bool LoadFromDb(int parentId) override
Populate view from database as images/subdirs of a directory. View is ordered: Parent dir,...
void ClearCache()
Clears UI cache.
MarkedFiles m_prevMarked
Marked items in previous dir.
ImageIdList GetChildren() const
QStringList RemoveImage(int id, bool deleted=false)
Clear file/dir and all its ancestors from UI cache so that ancestor thumbnails are recalculated....
void InvertMarked()
Mark all unmarked items, unmark all marked items.
MarkedFiles m_marked
Marked items in current dir/view.
void SetDirectory(int newParent)
Manage markings on tree navigation.
void Cache(ImageItemK &dir, int thumbCount)
Cache displayed dir.
void Mark(int id, bool mark)
Mark/unmark an image/dir.
Records info of displayed image files to enable clean-up of the UI image cache.
QString ToString(int id) const
A datastore of images for display by a screen.
void Cache(int id, int parent, const QString &url, const QString &thumb)
Cache image properties to optimize UI.
bool Update(int id)
Updates view with images that have been updated.
QStringList ClearImage(int id, bool remove=false)
Clear file from UI cache and optionally from view.
void ClearCache()
Clears UI cache.
ImagePtrK Prev(int inc)
Decrements iterator and returns previous image. Wraps at start.
bool Select(int id, int fallback=0)
Selects first occurrence of an image.
void Populate(ImageList &files)
Fills view with Db images, re-ordering them as required.
ImagePtrK HasNext(int inc) const
Peeks at next image in view but does not advance iterator.
void Clear(bool resetParent=true)
Reset view.
int m_active
Sequence index of current selected image.
ImagePtrK Next(int inc)
Advance iterator and return next image, wrapping if necessary. Regenerates unordered views on wrap.
QHash< int, FileCacheEntry > m_fileCache
Caches displayed image files.
ImageIdList m_sequence
The sequence in which to display images.
QString GetPosition() const
Get positional status.
ImagePtrK GetSelected() const
Get current selection.
virtual bool LoadFromDb(int parentId)
Populate view with database images from a directory.
ImageListK GetAllNodes() const
Get all images/dirs in view.
ImagePtrK HasPrev(int inc) const
Peeks at previous image in view but does not decrement iterator.
QHash< int, ImagePtrK > m_images
Image objects currently displayed.
void Rotate(int id)
Rotate view so that starting image is at front.
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...
int GetDirectory(int id, ImagePtr &parent, ImageList &files, ImageList &dirs) const
Return images (local and/or remote) for a dir and its direct children.
int GetImages(const ImageIdList &ids, ImageList &files, ImageList &dirs) const
Returns images (local or remote but not a combination)
void GetImageTree(int id, ImageList &files) const
Return all files (local or remote) in the sub-trees of a dir.
int GetChildren(int id, ImageList &files, ImageList &dirs) const
Return (local or remote) images that are direct children of a dir.
Represents a picture, video or directory.
int m_id
Uniquely identifies an image (file/dir).
QList< ThumbPair > m_thumbNails
int m_fileCount
Number of child images (dirs only)
int m_dirCount
Id & URLs of thumbnail(s). 1 for a file, 4 for dirs.
int m_parentId
Id of parent dir.
int m_userThumbnail
Id of thumbnail to use as cover (dirs only)
void Add(const ImageIdList &newIds)
void Invert(const ImageIdList &all)
bool LoadFromDb(int parentId) override
Populate view from database as images of a directory sub-tree. Default order of a tree is depth-first...
static constexpr qint64 BETA_CLIP
The edges of the distribution get clipped to avoid a singularity.
const double TRAILING_BETA_SHAPE
See LEADING_BETA_SHAPE.
const double DEFAULT_WEIGHT
Photos without an exif timestamp will default to the mode of the beta distribution.
static const int kMaxFolderThumbnails
Number of thumbnails to use for folders.
const double LEADING_BETA_SHAPE
Tuning parameter for seasonal weights, between 0 and 1, where lower numbers give greater weight to se...
Provides view datastores for Gallery screens.
SlideOrderType
Order of images in slideshow.
@ kSeasonal
Biased random selection so that images are more likely to appear on anniversaries.
@ kShuffle
Each image appears exactly once, but in random order.
@ kRandom
Random selection from view. An image may be absent or appear multiple times.
@ kOrdered
Ordered as per user setting GallerySortOrder.
QVector< double > WeightList
Seasonal weightings for images in a view.
QVector< ImagePtr > ImageList
QList< ImagePtrK > ImageListK
QSharedPointer< ImageItemK > ImagePtrK
QPair< int, QString > ThumbPair
static constexpr int GALLERY_DB_ID
static constexpr int PHOTO_DB_ID
QSharedPointer< ImageItem > ImagePtr
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Convenience inline random number generator functions.
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...
uint32_t MythRandom()
generate 32 random bits