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