MythTV  master
fileselector.cpp
Go to the documentation of this file.
1 #include <cstdlib>
2 
3 // Qt
4 #include <QApplication>
5 #include <QDir>
6 #include <QFileInfo>
7 #include <QVariant>
8 
9 // Myth
10 #include <mythcontext.h>
11 #include <mythdb.h>
12 #include <mythuihelper.h>
13 #include <mythuitext.h>
14 #include <mythuitextedit.h>
15 #include <mythuibutton.h>
16 #include <mythuiimage.h>
17 #include <mythuibuttonlist.h>
18 #include <mythmainwindow.h>
19 #include <mythdialogbox.h>
20 
21 // mytharchive
22 #include "fileselector.h"
23 #include "archiveutil.h"
24 
25 #if QT_VERSION < QT_VERSION_CHECK(5,10,0)
26 #define qEnvironmentVariable getenv
27 #endif
28 
30 
32 {
33  while (!m_fileData.isEmpty())
34  delete m_fileData.takeFirst();
35 }
36 
38 {
39  // Load the theme for this screen
40  bool foundtheme = LoadWindowFromXML("mytharchive-ui.xml", "file_selector", this);
41  if (!foundtheme)
42  return false;
43 
44  bool err = false;
45  UIUtilW::Assign(this, m_titleText, "title_text");
46  UIUtilE::Assign(this, m_fileButtonList, "filelist", &err);
47  UIUtilE::Assign(this, m_locationEdit, "location_edit", &err);
48  UIUtilE::Assign(this, m_backButton, "back_button", &err);
49  UIUtilE::Assign(this, m_homeButton, "home_button", &err);
50  UIUtilE::Assign(this, m_okButton, "ok_button", &err);
51  UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err);
52 
53  if (err)
54  {
55  LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'file_selector'");
56  return false;
57  }
58 
59  if (m_titleText)
60  {
61  switch (m_selectorType)
62  {
63  case FSTYPE_FILE:
64  m_titleText->SetText(tr("Find File"));
65  break;
66  case FSTYPE_DIRECTORY:
67  m_titleText->SetText(tr("Find Directory"));
68  break;
69  default:
70  m_titleText->SetText(tr("Find Files"));
71  break;
72  }
73  }
74 
77 
81 
84 
87 
89 
91 
94 
95  return true;
96 }
97 
98 bool FileSelector::keyPressEvent(QKeyEvent *event)
99 {
100  if (GetFocusWidget()->keyPressEvent(event))
101  return true;
102 
103  QStringList actions;
104  bool handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
105 
106  for (int i = 0; i < actions.size() && !handled; i++)
107  {
108  QString action = actions[i];
109  handled = true;
110 
111  if (action == "MENU")
112  {
113 
114  }
115  else
116  handled = false;
117  }
118 
119  if (!handled && MythScreenType::keyPressEvent(event))
120  handled = true;
121 
122  return handled;
123 }
124 
126 {
127  if (!item)
128  return;
129 
130  auto *fileData = item->GetData().value<FileData*>();
131  if (!fileData)
132  return;
133 
134  if (fileData->directory)
135  {
136  if (fileData->filename == "..")
137  {
138  // move up on directory
139  int pos = m_curDirectory.lastIndexOf('/');
140  if (pos > 0)
141  m_curDirectory = m_curDirectory.left(pos);
142  else
143  m_curDirectory = "/";
144  }
145  else
146  {
147  if (!m_curDirectory.endsWith("/"))
148  m_curDirectory += "/";
149  m_curDirectory += fileData->filename;
150  }
151  updateFileList();
152  }
153  else
154  {
156  {
157  QString fullPath = m_curDirectory;
158  if (!fullPath.endsWith("/"))
159  fullPath += "/";
160  fullPath += fileData->filename;
161 
163  {
164  m_selectedList.removeAll(fullPath);
166  }
167  else
168  {
169  if (m_selectedList.indexOf(fullPath) == -1)
170  m_selectedList.append(fullPath);
172  }
173  }
174  }
175 }
176 
178 {
179  return m_curDirectory;
180 }
181 
183 {
185  updateFileList();
186 }
187 
189 {
190  // move up one directory
191  int pos = m_curDirectory.lastIndexOf('/');
192  if (pos > 0)
193  m_curDirectory = m_curDirectory.left(pos);
194  else
195  m_curDirectory = "/";
196 
197  updateFileList();
198 }
199 
201 {
202  m_curDirectory = qEnvironmentVariable("HOME");
203 
204  updateFileList();
205 }
206 
208 {
210  {
211  // loop though selected files and add them to the list
212 
213  // remove any items that have been removed from the list
214  QList<ArchiveItem *> tempAList;
215  for (auto *a : qAsConst(*m_archiveList))
216  {
217  if (a->type != "File")
218  continue;
219  if (std::none_of(m_selectedList.cbegin(), m_selectedList.cend(),
220  [a](const auto & f)
221  {return a->filename == f; } ))
222  tempAList.append(a);
223  }
224 
225  for (auto *x : qAsConst(tempAList))
226  m_archiveList->removeAll(x);
227 
228  // remove any items that are already in the list
229  QStringList tempSList;
230  for (const QString & f : qAsConst(m_selectedList))
231  {
232  auto namematch = [f](const auto *a){ return a->filename == f; };
233  if (std::any_of(m_archiveList->cbegin(), m_archiveList->cend(), namematch))
234  tempSList.append(f);
235  }
236 
237  for (const auto & name : qAsConst(tempSList))
238  m_selectedList.removeAll(name);
239 
240  // add all that are left
241  for (const auto & f : qAsConst(m_selectedList))
242  {
243  QFile file(f);
244  if (file.exists())
245  {
246  QString title = f;
247  int pos = f.lastIndexOf('/');
248  if (pos > 0)
249  title = f.mid(pos + 1);
250 
251  auto *a = new ArchiveItem;
252  a->type = "File";
253  a->title = title;
254  a->subtitle = "";
255  a->description = "";
256  a->startDate = "";
257  a->startTime = "";
258  a->size = (int64_t)file.size();
259  a->filename = f;
260  a->hasCutlist = false;
261  a->useCutlist = false;
262  a->duration = 0;
263  a->cutDuration = 0;
264  a->videoWidth = 0;
265  a->videoHeight = 0;
266  a->fileCodec = "";
267  a->videoCodec = "";
268  a->encoderProfile = nullptr;
269  a->editedDetails = false;
270  m_archiveList->append(a);
271  }
272  }
273  }
274  else
275  {
277  auto *fileData = item->GetData().value<FileData*>();
278 
280  {
281  if (!fileData->directory)
282  {
283  ShowOkPopup(tr("The selected item is not a directory!"));
284  return;
285  }
286 
287  if (fileData->filename != "..")
288  {
289  if (!m_curDirectory.endsWith("/"))
290  m_curDirectory += "/";
291  m_curDirectory += fileData->filename;
292  }
293  }
294  else
295  {
296  if (fileData->directory)
297  {
298  if (!m_curDirectory.endsWith("/"))
299  m_curDirectory += "/";
300  }
301  else
302  {
303  if (!m_curDirectory.endsWith("/"))
304  m_curDirectory += "/";
305  m_curDirectory += fileData->filename;
306  }
307  }
308  }
309 
311  emit haveResult(true);
312  else
313  emit haveResult(getSelected());
314  Close();
315 }
316 
318 {
320  emit haveResult(true);
321  else
322  emit haveResult(QString());
323  Close();
324 }
325 
327 {
328  if (!m_archiveList)
329  return;
330 
331  while (!m_selectedList.isEmpty())
332  m_selectedList.takeFirst();
333  m_selectedList.clear();
334 
335  for (const auto *a : qAsConst(*m_archiveList))
336  {
337  auto samename = [a](const auto *f)
338  { return f->filename == a->filename; };
339  auto f = std::find_if(m_fileData.cbegin(), m_fileData.cend(), samename);
340  if (f != m_fileData.cend())
341  {
342  if (m_selectedList.indexOf((*f)->filename) == -1)
343  m_selectedList.append((*f)->filename);
344  }
345  }
346 }
347 
349 {
350  if (!m_fileButtonList)
351  return;
352 
354  while (!m_fileData.isEmpty())
355  delete m_fileData.takeFirst();
356  m_fileData.clear();
357 
358  QDir d;
359 
360  d.setPath(m_curDirectory);
361  if (d.exists())
362  {
363  // first get a list of directory's in the current directory
364  QStringList filters;
365  filters << "*";
366  QFileInfoList list = d.entryInfoList(filters, QDir::Dirs, QDir::Name);
367 
368  for (const auto & fi : qAsConst(list))
369  {
370  if (fi.fileName() != ".")
371  {
372  auto *data = new FileData;
373  data->selected = false;
374  data->directory = true;
375  data->filename = fi.fileName();
376  data->size = 0;
377  m_fileData.append(data);
378 
379  // add a row to the MythUIButtonList
380  auto* item = new
381  MythUIButtonListItem(m_fileButtonList, data->filename);
382  item->setCheckable(false);
383  item->SetImage("ma_folder.png");
384  item->SetData(QVariant::fromValue(data));
385  }
386  }
387 
389  {
390  // second get a list of file's in the current directory
391  filters.clear();
392 #if QT_VERSION < QT_VERSION_CHECK(5,14,0)
393  filters = m_filemask.split(" ", QString::SkipEmptyParts);
394 #else
395  filters = m_filemask.split(" ", Qt::SkipEmptyParts);
396 #endif
397  list = d.entryInfoList(filters, QDir::Files, QDir::Name);
398  for (const auto & fi : qAsConst(list))
399  {
400  auto *data = new FileData;
401  data->selected = false;
402  data->directory = false;
403  data->filename = fi.fileName();
404  data->size = fi.size();
405  m_fileData.append(data);
406 
407  // add a row to the UIListBtnArea
408  auto* item =
409  new MythUIButtonListItem(m_fileButtonList, data->filename);
410  item->SetText(formatSize(data->size / 1024, 2), "size");
411 
413  {
414  item->setCheckable(true);
415 
416  QString fullPath = m_curDirectory;
417  if (!fullPath.endsWith("/"))
418  fullPath += "/";
419  fullPath += data->filename;
420 
421  if (m_selectedList.indexOf(fullPath) != -1)
422  {
423  item->setChecked(MythUIButtonListItem::FullChecked);
424  }
425  else
426  {
427  item->setChecked(MythUIButtonListItem::NotChecked);
428  }
429  }
430  else
431  item->setCheckable(false);
432 
433  item->SetData(QVariant::fromValue(data));
434  }
435  }
437  }
438  else
439  {
440  m_locationEdit->SetText("/");
441  LOG(VB_GENERAL, LOG_ERR,
442  "MythArchive: current directory does not exist!");
443  }
444 }
MythUIButton::Clicked
void Clicked()
FSTYPE_FILE
@ FSTYPE_FILE
Definition: fileselector.h:29
FileData::selected
bool selected
Definition: fileselector.h:21
formatSize
static QString formatSize(int64_t size, int prec)
Definition: recordingutils.cpp:22
FileSelector::backPressed
void backPressed(void)
Definition: fileselector.cpp:188
MythUIButtonList::GetItemCurrent
MythUIButtonListItem * GetItemCurrent() const
Definition: mythuibuttonlist.cpp:1590
mythuitext.h
FileData
Definition: fileselector.h:18
fileselector.h
FileSelector::itemClicked
void itemClicked(MythUIButtonListItem *item)
Definition: fileselector.cpp:125
mythdb.h
FileSelector::Create
bool Create(void) override
Definition: fileselector.cpp:37
MythScreenType::Close
virtual void Close()
Definition: mythscreentype.cpp:385
FileSelector::updateFileList
void updateFileList(void)
Definition: fileselector.cpp:348
FileSelector::homePressed
void homePressed(void)
Definition: fileselector.cpp:200
mythdialogbox.h
FileSelector::keyPressEvent
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
Definition: fileselector.cpp:98
MythUIButtonListItem::FullChecked
@ FullChecked
Definition: mythuibuttonlist.h:41
FileSelector::m_fileData
QList< FileData * > m_fileData
Definition: fileselector.h:80
LOG
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:23
MythUITextEdit::GetText
QString GetText(void) const
Definition: mythuitextedit.h:47
build_compdb.file
file
Definition: build_compdb.py:55
mythuibuttonlist.h
mythuiimage.h
FileSelector::m_backButton
MythUIButton * m_backButton
Definition: fileselector.h:91
FileSelector::m_titleText
MythUIText * m_titleText
Definition: fileselector.h:86
FileSelector::getSelected
QString getSelected(void)
Definition: fileselector.cpp:177
FSTYPE_DIRECTORY
@ FSTYPE_DIRECTORY
Definition: fileselector.h:30
MythScreenType::GetFocusWidget
MythUIType * GetFocusWidget(void) const
Definition: mythscreentype.cpp:112
FileSelector::cancelPressed
void cancelPressed(void)
Definition: fileselector.cpp:317
MythUIButtonListItem
Definition: mythuibuttonlist.h:34
MythUITextEdit::SetText
void SetText(const QString &text, bool moveCursor=true)
Definition: mythuitextedit.cpp:215
ArchiveItem::type
QString type
Definition: archiveutil.h:53
MythUIButtonList::itemClicked
void itemClicked(MythUIButtonListItem *item)
MythMainWindow::TranslateKeyPress
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
Definition: mythmainwindow.cpp:1102
archiveutil.h
MythScreenType::SetFocusWidget
bool SetFocusWidget(MythUIType *widget=nullptr)
Definition: mythscreentype.cpp:117
FileSelector::m_selectedList
QStringList m_selectedList
Definition: fileselector.h:81
MythScreenType::BuildFocusList
void BuildFocusList(void)
Definition: mythscreentype.cpp:205
FileSelector::m_filemask
QString m_filemask
Definition: fileselector.h:78
FileSelector::m_archiveList
QList< ArchiveItem * > * m_archiveList
Definition: fileselector.h:82
FileSelector::locationEditLostFocus
void locationEditLostFocus(void)
Definition: fileselector.cpp:182
FileSelector::m_locationEdit
MythUITextEdit * m_locationEdit
Definition: fileselector.h:88
MythUIButtonListItem::GetData
QVariant GetData()
Definition: mythuibuttonlist.cpp:3648
FileSelector::updateSelectedList
void updateSelectedList(void)
Definition: fileselector.cpp:326
UIUtilDisp::Assign
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27
FileSelector::m_okButton
MythUIButton * m_okButton
Definition: fileselector.h:89
FileSelector::OKPressed
void OKPressed(void)
Definition: fileselector.cpp:207
mythuihelper.h
FileSelector::~FileSelector
~FileSelector() override
Definition: fileselector.cpp:31
FileSelector::m_selectorType
FSTYPE m_selectorType
Definition: fileselector.h:77
MythScreenType::keyPressEvent
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
Definition: mythscreentype.cpp:397
mythuitextedit.h
XMLParseBase::LoadWindowFromXML
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
Definition: xmlparsebase.cpp:692
FileSelector::haveResult
void haveResult(bool ok)
MythUIText::SetText
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:133
MythUIButtonListItem::state
CheckState state() const
Definition: mythuibuttonlist.cpp:3602
mythcontext.h
MythUIButtonList::Reset
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
Definition: mythuibuttonlist.cpp:114
GetMythMainWindow
MythMainWindow * GetMythMainWindow(void)
Definition: mythmainwindow.cpp:101
build_compdb.action
action
Definition: build_compdb.py:9
FileSelector::m_curDirectory
QString m_curDirectory
Definition: fileselector.h:79
mythuibutton.h
FSTYPE_FILELIST
@ FSTYPE_FILELIST
Definition: fileselector.h:28
FileSelector::m_homeButton
MythUIButton * m_homeButton
Definition: fileselector.h:92
d
static const iso6937table * d
Definition: iso6937tables.cpp:1025
ArchiveItem
Definition: archiveutil.h:50
MythUIType::LosingFocus
void LosingFocus()
FileSelector::m_fileButtonList
MythUIButtonList * m_fileButtonList
Definition: fileselector.h:87
mythmainwindow.h
MythUIButtonListItem::setChecked
void setChecked(CheckState state)
Definition: mythuibuttonlist.cpp:3612
ShowOkPopup
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
Definition: mythdialogbox.cpp:558
FileSelector::m_cancelButton
MythUIButton * m_cancelButton
Definition: fileselector.h:90
MythUIButtonListItem::NotChecked
@ NotChecked
Definition: mythuibuttonlist.h:39