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 <libmythbase/mythdb.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;
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
95bool 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 }
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{
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
197}
198
200{
201 m_curDirectory = qEnvironmentVariable("HOME");
202
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 {
438 LOG(VB_GENERAL, LOG_ERR,
439 "MythArchive: current directory does not exist!");
440 }
441}
QString m_filemask
Definition: fileselector.h:78
MythUIButton * m_okButton
Definition: fileselector.h:89
QString getSelected(void)
void updateSelectedList(void)
MythUIButtonList * m_fileButtonList
Definition: fileselector.h:87
void cancelPressed(void)
QString m_curDirectory
Definition: fileselector.h:79
MythUIText * m_titleText
Definition: fileselector.h:86
void backPressed(void)
void homePressed(void)
QStringList m_selectedList
Definition: fileselector.h:81
void haveResult(bool ok)
MythUIButton * m_homeButton
Definition: fileselector.h:92
void OKPressed(void)
FSTYPE m_selectorType
Definition: fileselector.h:77
MythUITextEdit * m_locationEdit
Definition: fileselector.h:88
void updateFileList(void)
bool Create(void) override
bool keyPressEvent(QKeyEvent *e) override
Key event handler.
void locationEditLostFocus(void)
void itemClicked(MythUIButtonListItem *item)
QList< ArchiveItem * > * m_archiveList
Definition: fileselector.h:82
QList< FileData * > m_fileData
Definition: fileselector.h:80
~FileSelector() override
MythUIButton * m_backButton
Definition: fileselector.h:91
MythUIButton * m_cancelButton
Definition: fileselector.h:90
bool TranslateKeyPress(const QString &Context, QKeyEvent *Event, QStringList &Actions, bool AllowJumps=true)
Get a list of actions for a keypress in the given context.
void BuildFocusList(void)
MythUIType * GetFocusWidget(void) const
bool keyPressEvent(QKeyEvent *event) override
Key event handler.
bool SetFocusWidget(MythUIType *widget=nullptr)
virtual void Close()
CheckState state() const
void setChecked(CheckState state)
MythUIButtonListItem * GetItemCurrent() const
void Reset() override
Reset the widget to it's original state, should not reset changes made by the theme.
void itemClicked(MythUIButtonListItem *item)
void Clicked()
QString GetText(void) const
void SetText(const QString &text, bool moveCursor=true)
virtual void SetText(const QString &text)
Definition: mythuitext.cpp:115
void LosingFocus(void)
static bool LoadWindowFromXML(const QString &xmlfile, const QString &windowname, MythUIType *parent)
@ FSTYPE_FILELIST
Definition: fileselector.h:28
@ FSTYPE_DIRECTORY
Definition: fileselector.h:30
@ FSTYPE_FILE
Definition: fileselector.h:29
static const iso6937table * d
MythConfirmationDialog * ShowOkPopup(const QString &message, bool showCancel)
Non-blocking version of MythPopupBox::showOkPopup()
#define LOG(_MASK_, _LEVEL_, _QSTRING_)
Definition: mythlogging.h:39
MythMainWindow * GetMythMainWindow(void)
MBASE_PUBLIC QString formatKBytes(int64_t sizeKB, int prec=1)
Definition: stringutil.cpp:357
QString type
Definition: archiveutil.h:53
bool selected
Definition: fileselector.h:21
static bool Assign(ContainerType *container, UIType *&item, const QString &name, bool *err=nullptr)
Definition: mythuiutils.h:27