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