MythTV  master
galleryinfo.cpp
Go to the documentation of this file.
1 #include "galleryinfo.h"
2 
3 #include "mythcoreutil.h"
4 #include "mythdate.h"
5 #include "imagemetadata.h"
6 
7 
9 static QSet<QString> kBasicInfoSet {
10  // Exif tags
15  "Exif.Image.Make",
16  "Exif.Image.Model",
17  "Exif.Photo.ExposureTime",
18  "Exif.Photo.ShutterSpeedValue",
19  "Exif.Photo.FNumber",
20  "Exif.Photo.ApertureValue",
21  "Exif.Photo.ExposureBiasValue",
22  "Exif.Photo.Flash",
23  "Exif.Photo.FocalLength",
24  "Exif.Photo.FocalLengthIn35mmFilm",
25  "ISO speed",
26  "Exif.Photo.MeteringMode",
27  "Exif.Photo.PixelXDimension",
28  "Exif.Photo.PixelYDimension",
29  // Video tags
30  "FFmpeg.format.format_long_name",
31  "FFmpeg.format.duration",
32  "FFmpeg.format.creation_time",
33  "FFmpeg.format.model",
34  "FFmpeg.format.make",
35  // Only detects tags within the first 2 streams for efficiency
36  "FFmpeg.stream0:.codec_long_name",
37  "FFmpeg.stream1:.codec_long_name",
38  "FFmpeg.stream0:.width",
39  "FFmpeg.stream1:.width",
40  "FFmpeg.stream0:.height",
41  "FFmpeg.stream1:.height",
42  "FFmpeg.stream0:.sample_rate",
43  "FFmpeg.stream1:.sample_rate",
44  "FFmpeg.stream0:.rotate",
45  "FFmpeg.stream1:.rotate" };
46 
49  : m_screen(screen), m_mgr(ImageManagerFe::getInstance())
50 {
51  m_timer.setSingleShot(true);
52  m_timer.setInterval(1000);
53  connect(&m_timer, SIGNAL(timeout()), this, SLOT(Clear()));
54 }
55 
56 
62 bool InfoList::Create(bool focusable)
63 {
64  bool err = false;
65  UIUtilE::Assign(&m_screen, m_btnList, "infolist", &err);
66  if (err)
67  return false;
68 
69  m_btnList->SetVisible(false);
70  m_btnList->SetCanTakeFocus(focusable);
71  return true;
72 }
73 
74 
80 void InfoList::Toggle(const ImagePtrK& im)
81 {
82  if (!im)
83  return;
84 
85  // Only focusable lists have an extra 'full' state as they can
86  // be scrolled to view it all
87  if (m_btnList->CanTakeFocus())
88  {
89  // Start showing basic info then toggle between basic/full
91 
92  // Toggle between off/basic
93  }
94  else if (m_infoVisible == kBasicInfo)
95  {
97  m_btnList->SetVisible(false);
98  return;
99  }
100  else
102 
103  Clear();
104  Update(im);
105 
106  m_btnList->SetVisible(true);
107 }
108 
109 
115 {
116  // Only handle event if info currently displayed
117  bool handled = (m_infoVisible != kNoInfo);
119 
120  m_btnList->SetVisible(false);
121 
122  return handled;
123 }
124 
125 
131 void InfoList::CreateButton(const QString& name, const QString& value)
132 {
133  if (value.isEmpty())
134  return;
135 
136  auto *item = new MythUIButtonListItem(m_btnList, "");
137 
138  InfoMap infoMap;
139  infoMap.insert("name", name);
140  infoMap.insert("value", value);
141 
142  item->SetTextFromMap(infoMap);
143 }
144 
145 
151 {
152  int dirCount = 0;
153  int imageCount = 0;
154  int videoCount = 0;
155  int size = 0;
156  m_mgr.GetDescendantCount(im.m_id, dirCount, imageCount, videoCount, size);
157 
158  QStringList report;
159  if (imageCount > 0)
160  report << tr("%Ln image(s)", "", imageCount);
161  if (videoCount > 0)
162  report << tr("%Ln video(s)", "", videoCount);
163  if (dirCount > 0)
164  report << tr("%Ln directory(ies)", "", dirCount);
165 
166  CreateButton(tr("Contains"), report.join(", "));
167  CreateButton(tr("Dir size"), ImageAdapterBase::FormatSize(size));
168 
169  if (im.IsDevice() && im.IsLocal())
170  {
171  // Returns KiB
172  int64_t total = 0;
173  int64_t used = 0;
174  int64_t free = getDiskSpace(im.m_filePath, total, used);
175  if (total > 0)
176  {
177  CreateButton(tr("Free space"), tr("%L1 (%L2\%) Used: %L3 / %L4")
179  .arg(100 * free / total)
182  }
183  }
184 }
185 
186 
192 {
193  if (!im || m_infoVisible == kNoInfo)
194  return;
195 
196  if (im->m_id == GALLERY_DB_ID)
197  {
198  // No metadata for root
199  Clear();
200  CreateButton(tr("Name"), m_mgr.DeviceCaption(*im));
201  CreateCount(*im);
202  return;
203  }
204 
205  // Request metadata
206  m_mgr.RequestMetaData(im->m_id);
207  // Reduce flicker by waiting for new data before clearing list
208  m_timer.start();
209 }
210 
211 
217 void InfoList::Display(ImageItemK &im, const QStringList &tagStrings)
218 {
219  // Cancel timer & build list
220  m_timer.stop();
221  Clear();
222 
223  // Each tag has 3 elements: key, label, value
224  ImageMetaData::TagMap tags = ImageMetaData::ToMap(tagStrings);
225 
226  QString tagHost = tags.take(EXIF_MYTH_HOST).value(2);
227  QString tagPath = tags.take(EXIF_MYTH_PATH).value(2);
228  QString tagName = tags.take(EXIF_MYTH_NAME).value(2);
229 
230  // Override SG
231  if (im.m_id == PHOTO_DB_ID)
232  {
233  tagPath = tr("Storage Group");
234  tagName = m_mgr.DeviceCaption(im);
235  }
236 
237  CreateButton(tr("Name"), tagName);
238 
239  // Only show non-local hostnames
240  QString host = (tagHost == gCoreContext->GetHostName()) ? "" : tagHost + ":";
241  QString clone = (im.m_type == kCloneDir) ? tr("(and others)") : "";
242  CreateButton(tr("Path"), QString("%1%2 %3").arg(host, tagPath, clone));
243 
244  if (im.IsDevice())
245  {
246  CreateButton(tr("Last scan"),
249  }
250 
251  if (im.IsDirectory())
252  CreateCount(im);
253 
254  if (!im.IsDevice())
255  {
256  CreateButton(tr("Modified"),
259  }
260 
261  if (im.IsFile())
262  {
263  CreateButton(tr("File size"), tags.take(EXIF_MYTH_SIZE).value(2));
264  CreateButton(tr("Orientation"), tags.take(EXIF_MYTH_ORIENT).value(2));
265 
266  // Create buttons for exif/video tags
267  // Multimap iterates each key latest->earliest so we must do it the long way
268  for (const QString & group : tags.uniqueKeys())
269  {
270  // Iterate earliest->latest to preserve tag order
271  using TagList = QList<QStringList>;
272  TagList tagList = tags.values(group);
273  TagList::const_iterator i = tagList.constEnd();
274 
275  if (m_infoVisible == kFullInfo)
276  {
277  // Show all tags
278  while (i-- != tagList.constBegin())
279  CreateButton(i->at(1), i->at(2));
280  }
281  else
282  {
283  // Only show specific keys
284  while (i-- != tagList.constBegin())
285  if (kBasicInfoSet.contains(i->at(0)))
286  CreateButton(i->at(1), i->at(2));
287  }
288  }
289 
290  // Only give list focus if requested
291  if (m_btnList->CanTakeFocus())
293  }
294 }
ImagePtrK
QSharedPointer< ImageItemK > ImagePtrK
Definition: imagetypes.h:164
InfoList::m_mgr
ImageManagerFe & m_mgr
Image Manager.
Definition: galleryinfo.h:45
InfoList::m_btnList
MythUIButtonList * m_btnList
Overlay buttonlist.
Definition: galleryinfo.h:43
InfoList::Display
void Display(ImageItemK &im, const QStringList &tagStrings)
Build list of metadata tags.
Definition: galleryinfo.cpp:217
PHOTO_DB_ID
#define PHOTO_DB_ID
Definition: imagetypes.h:28
MythDate::toString
QString toString(const QDateTime &raw_dt, uint format)
Returns formatted string representing the time.
Definition: mythdate.cpp:80
hardwareprofile.smolt.timeout
float timeout
Definition: smolt.py:103
MythUIType::CanTakeFocus
bool CanTakeFocus(void) const
Return if this widget can accept input focus.
Definition: mythuitype.cpp:334
InfoList::m_screen
MythScreenType & m_screen
Parent screen.
Definition: galleryinfo.h:42
ImageItem::m_type
int m_type
Type of node: dir, video etc.
Definition: imagetypes.h:96
InfoList::CreateButton
void CreateButton(const QString &name, const QString &value)
Populate a buttonlist item with exif tag name & value.
Definition: galleryinfo.cpp:131
ImageItem::m_id
int m_id
Uniquely identifies an image (file/dir).
Definition: imagetypes.h:88
getDiskSpace
int64_t getDiskSpace(const QString &file_on_disk, int64_t &total, int64_t &used)
Definition: mythcoreutil.cpp:40
ImageItem::IsLocal
bool IsLocal() const
Definition: imagetypes.h:118
InfoList::m_infoVisible
InfoVisibleState m_infoVisible
Info list state.
Definition: galleryinfo.h:44
EXIF_MYTH_SIZE
#define EXIF_MYTH_SIZE
Definition: imagemetadata.h:41
mythcoreutil.h
arg
arg(title).arg(filename).arg(doDelete))
MythUIType::SetCanTakeFocus
void SetCanTakeFocus(bool set=true)
Set whether this widget can take focus.
Definition: mythuitype.cpp:342
kNoInfo
@ kNoInfo
Details not displayed.
Definition: galleryinfo.h:16
InfoList::Update
void Update(const ImagePtrK &im)
Populates available exif details for the current image/dir.
Definition: galleryinfo.cpp:191
MythScreenType
Screen in which all other widgets are contained and rendered.
Definition: mythscreentype.h:44
EXIF_TAG_ORIENTATION
#define EXIF_TAG_ORIENTATION
Definition: imagemetadata.h:25
InfoList::m_timer
QTimer m_timer
Clears list if no new metadata arrives.
Definition: galleryinfo.h:46
InfoMap
QHash< QString, QString > InfoMap
Definition: mythtypes.h:15
EXIF_TAG_USERCOMMENT
#define EXIF_TAG_USERCOMMENT
Definition: imagemetadata.h:29
ImageManagerFe::DeviceCaption
QString DeviceCaption(ImageItemK &im) const
Return translated device name.
Definition: imagemanager.cpp:2350
MythUIButtonListItem
Definition: mythuibuttonlist.h:27
EXIF_MYTH_ORIENT
#define EXIF_MYTH_ORIENT
Definition: imagemetadata.h:42
MythDate::fromSecsSinceEpoch
MBASE_PUBLIC QDateTime fromSecsSinceEpoch(uint seconds)
This function takes the number of seconds since the start of the epoch and returns a QDateTime with t...
Definition: mythdate.cpp:68
ImageItem::m_modTime
qint64 m_modTime
Filesystem modified datestamp.
Definition: imagetypes.h:97
mythdate.h
InfoList::Toggle
void Toggle(const ImagePtrK &im)
Toggle infolist state for an image. Focusable widgets toggle between Basic & Full info....
Definition: galleryinfo.cpp:80
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:117
ImageAdapterBase::FormatSize
static QString FormatSize(int sizeKib)
Definition: imagemanager.h:143
EXIF_TAG_IMAGEDESCRIPTION
#define EXIF_TAG_IMAGEDESCRIPTION
Definition: imagemetadata.h:28
ImageMetaData::ToMap
static TagMap ToMap(const QStringList &tags)
Creates a map of metadata tags as.
Definition: imagemetadata.cpp:721
InfoList::Clear
void Clear()
Definition: galleryinfo.h:36
galleryinfo.h
The info/details overlay that shows image metadata.
EXIF_MYTH_PATH
#define EXIF_MYTH_PATH
Definition: imagemetadata.h:39
InfoList::CreateCount
void CreateCount(ImageItemK &im)
Creates buttons detailing dir counts & size.
Definition: galleryinfo.cpp:150
gCoreContext
MythCoreContext * gCoreContext
This global variable contains the MythCoreContext instance for the app.
Definition: mythcorecontext.cpp:57
ImageMetaData::TagMap
QMap< QString, QStringList > TagMap
Definition: imagemetadata.h:119
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
kBasicInfoSet
static QSet< QString > kBasicInfoSet
The exif/video tags comprising the Basic file info.
Definition: galleryinfo.cpp:9
ImageDbReader::GetDescendantCount
void GetDescendantCount(int id, int &dirs, int &pics, int &videos, int &sizeKb) const
Return counts of dirs, pics and videos in the subtree of a dir. Also dir size.
Definition: imagemanager.cpp:1892
InfoList::Hide
bool Hide()
Remove infolist from display.
Definition: galleryinfo.cpp:114
kFullInfo
@ kFullInfo
Shows all exif tags.
Definition: galleryinfo.h:18
ImageItem::IsFile
bool IsFile() const
Definition: imagetypes.h:117
MythDate::kAddYear
@ kAddYear
Add year to string if not included.
Definition: mythdate.h:22
ImageManagerFe
The image manager for use by Frontends.
Definition: imagemanager.h:456
ImageItem
Represents a picture, video or directory.
Definition: imagetypes.h:67
imagemetadata.h
Handles Exif/FFMpeg metadata tags for images.
EXIF_MYTH_NAME
#define EXIF_MYTH_NAME
Definition: imagemetadata.h:40
kBasicInfo
@ kBasicInfo
Shows just the most useful exif tags.
Definition: galleryinfo.h:17
MythUIType::SetVisible
virtual void SetVisible(bool visible)
Definition: mythuitype.cpp:1080
EXIF_MYTH_HOST
#define EXIF_MYTH_HOST
Definition: imagemetadata.h:38
ImageItem::IsDirectory
bool IsDirectory() const
Definition: imagetypes.h:116
MythCoreContext::GetHostName
QString GetHostName(void)
Definition: mythcorecontext.cpp:856
ImageItem::IsDevice
bool IsDevice() const
Definition: imagetypes.h:115
InfoList::Create
bool Create(bool focusable)
Initialise buttonlist from XML.
Definition: galleryinfo.cpp:62
MythDate::kDateTimeFull
@ kDateTimeFull
Default local time.
Definition: mythdate.h:20
ImageItem::m_date
qint64 m_date
Image creation date, from Exif metadata.
Definition: imagetypes.h:99
ImageManagerFe::RequestMetaData
void RequestMetaData(int id)
Requests all exif/ffmpeg tags for an image, which returns by event.
Definition: imagemanager.cpp:2126
InfoList::InfoList
InfoList(MythScreenType &screen)
Constructor.
Definition: galleryinfo.cpp:48
EXIF_TAG_DATETIME
#define EXIF_TAG_DATETIME
Definition: imagemetadata.h:26
kCloneDir
@ kCloneDir
A device sub dir comprised from multiple SG dirs.
Definition: imagetypes.h:36
GALLERY_DB_ID
#define GALLERY_DB_ID
Definition: imagetypes.h:26
ImageItem::m_filePath
QString m_filePath
Absolute for local images. Usually SG-relative for remotes.
Definition: imagetypes.h:92