00001 #include <cstdlib>
00002
00003
00004 #include <QApplication>
00005 #include <QDir>
00006 #include <QFileInfo>
00007 #include <QVariant>
00008
00009
00010 #include <mythcontext.h>
00011 #include <mythdb.h>
00012 #include <mythuihelper.h>
00013 #include <mythuitext.h>
00014 #include <mythuitextedit.h>
00015 #include <mythuibutton.h>
00016 #include <mythuiimage.h>
00017 #include <mythuibuttonlist.h>
00018 #include <mythmainwindow.h>
00019 #include <mythdialogbox.h>
00020
00021
00022 #include "fileselector.h"
00023 #include "archiveutil.h"
00024
00026
00027 FileSelector::FileSelector(
00028 MythScreenStack *parent, QList<ArchiveItem *> *archiveList,
00029 FSTYPE type, const QString &startDir, const QString &filemask) :
00030 MythScreenType(parent, "FileSelector"),
00031 m_selectorType(type),
00032 m_filemask(filemask),
00033 m_curDirectory(startDir),
00034 m_archiveList(archiveList),
00035 m_titleText(NULL),
00036 m_fileButtonList(NULL),
00037 m_locationEdit(NULL),
00038 m_okButton(NULL),
00039 m_cancelButton(NULL),
00040 m_backButton(NULL),
00041 m_homeButton(NULL)
00042 {
00043 }
00044
00045 FileSelector::~FileSelector()
00046 {
00047 while (!m_fileData.isEmpty())
00048 delete m_fileData.takeFirst();
00049 }
00050
00051 bool FileSelector::Create(void)
00052 {
00053 bool foundtheme = false;
00054
00055
00056 foundtheme = LoadWindowFromXML("mytharchive-ui.xml", "file_selector", this);
00057
00058 if (!foundtheme)
00059 return false;
00060
00061 bool err = false;
00062 UIUtilW::Assign(this, m_titleText, "title_text");
00063 UIUtilE::Assign(this, m_fileButtonList, "filelist", &err);
00064 UIUtilE::Assign(this, m_locationEdit, "location_edit", &err);
00065 UIUtilE::Assign(this, m_backButton, "back_button", &err);
00066 UIUtilE::Assign(this, m_homeButton, "home_button", &err);
00067 UIUtilE::Assign(this, m_okButton, "ok_button", &err);
00068 UIUtilE::Assign(this, m_cancelButton, "cancel_button", &err);
00069
00070 if (err)
00071 {
00072 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'file_selector'");
00073 return false;
00074 }
00075
00076 if (m_titleText)
00077 {
00078 switch (m_selectorType)
00079 {
00080 case FSTYPE_FILE:
00081 m_titleText->SetText(tr("Find File"));
00082 break;
00083 case FSTYPE_DIRECTORY:
00084 m_titleText->SetText(tr("Find Directory"));
00085 break;
00086 default:
00087 m_titleText->SetText(tr("Find Files"));
00088 break;
00089 }
00090 }
00091
00092 connect(m_okButton, SIGNAL(Clicked()), this, SLOT(OKPressed()));
00093 connect(m_cancelButton, SIGNAL(Clicked()), this, SLOT(cancelPressed()));
00094
00095 connect(m_locationEdit, SIGNAL(LosingFocus()),
00096 this, SLOT(locationEditLostFocus()));
00097 m_locationEdit->SetText(m_curDirectory);
00098
00099 connect(m_backButton, SIGNAL(Clicked()), this, SLOT(backPressed()));
00100 connect(m_homeButton, SIGNAL(Clicked()), this, SLOT(homePressed()));
00101
00102 connect(m_fileButtonList, SIGNAL(itemClicked(MythUIButtonListItem *)),
00103 this, SLOT(itemClicked(MythUIButtonListItem *)));
00104
00105 BuildFocusList();
00106
00107 SetFocusWidget(m_fileButtonList);
00108
00109 updateSelectedList();
00110 updateFileList();
00111
00112 return true;
00113 }
00114
00115 bool FileSelector::keyPressEvent(QKeyEvent *event)
00116 {
00117 if (GetFocusWidget()->keyPressEvent(event))
00118 return true;
00119
00120 bool handled = false;
00121 QStringList actions;
00122 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
00123
00124 for (int i = 0; i < actions.size() && !handled; i++)
00125 {
00126 QString action = actions[i];
00127 handled = true;
00128
00129 if (action == "MENU")
00130 {
00131
00132 }
00133 else
00134 handled = false;
00135 }
00136
00137 if (!handled && MythScreenType::keyPressEvent(event))
00138 handled = true;
00139
00140 return handled;
00141 }
00142
00143 void FileSelector::itemClicked(MythUIButtonListItem *item)
00144 {
00145 if (!item)
00146 return;
00147
00148 FileData *fileData = qVariantValue<FileData*>(item->GetData());
00149
00150 if (fileData->directory)
00151 {
00152 if (fileData->filename == "..")
00153 {
00154
00155 int pos = m_curDirectory.lastIndexOf('/');
00156 if (pos > 0)
00157 m_curDirectory = m_curDirectory.left(pos);
00158 else
00159 m_curDirectory = "/";
00160 }
00161 else
00162 {
00163 if (!m_curDirectory.endsWith("/"))
00164 m_curDirectory += "/";
00165 m_curDirectory += fileData->filename;
00166 }
00167 updateFileList();
00168 }
00169 else
00170 {
00171 if (m_selectorType == FSTYPE_FILELIST)
00172 {
00173 QString fullPath = m_curDirectory;
00174 if (!fullPath.endsWith("/"))
00175 fullPath += "/";
00176 fullPath += fileData->filename;
00177
00178 if (item->state() == MythUIButtonListItem::FullChecked)
00179 {
00180 m_selectedList.removeAll(fullPath);
00181 item->setChecked(MythUIButtonListItem::NotChecked);
00182 }
00183 else
00184 {
00185 if (m_selectedList.indexOf(fullPath) == -1)
00186 m_selectedList.append(fullPath);
00187 item->setChecked(MythUIButtonListItem::FullChecked);
00188 }
00189 }
00190 }
00191 }
00192
00193 QString FileSelector::getSelected(void)
00194 {
00195 return m_curDirectory;
00196 }
00197
00198 void FileSelector::locationEditLostFocus()
00199 {
00200 m_curDirectory = m_locationEdit->GetText();
00201 updateFileList();
00202 }
00203
00204 void FileSelector::backPressed()
00205 {
00206
00207 int pos = m_curDirectory.lastIndexOf('/');
00208 if (pos > 0)
00209 m_curDirectory = m_curDirectory.left(pos);
00210 else
00211 m_curDirectory = "/";
00212
00213 updateFileList();
00214 }
00215
00216 void FileSelector::homePressed()
00217 {
00218 char *home = getenv("HOME");
00219 m_curDirectory = home;
00220
00221 updateFileList();
00222 }
00223
00224 void FileSelector::OKPressed()
00225 {
00226 if (m_selectorType == FSTYPE_FILELIST && m_archiveList)
00227 {
00228
00229 QString f;
00230 ArchiveItem *a;
00231
00232
00233 QList<ArchiveItem *> tempAList;
00234 for (int x = 0; x < m_archiveList->size(); x++)
00235 {
00236 a = m_archiveList->at(x);
00237 bool found = false;
00238
00239 for (int y = 0; y < m_selectedList.size(); y++)
00240 {
00241 f = m_selectedList.at(y);
00242 if (a->type != "File" || a->filename == f)
00243 {
00244 found = true;
00245 break;
00246 }
00247 }
00248
00249 if (!found)
00250 tempAList.append(a);
00251 }
00252
00253 for (int x = 0; x < tempAList.size(); x++)
00254 m_archiveList->removeAll(tempAList.at(x));
00255
00256
00257 QStringList tempSList;
00258 for (int x = 0; x < m_selectedList.size(); x++)
00259 {
00260 f = m_selectedList.at(x);
00261
00262 for (int y = 0; y < m_archiveList->size(); y++)
00263 {
00264 a = m_archiveList->at(y);
00265 if (a->filename == f)
00266 {
00267 tempSList.append(f);
00268 break;
00269 }
00270 }
00271 }
00272
00273 for (int x = 0; x < tempSList.size(); x++)
00274 m_selectedList.removeAll(tempSList.at(x));
00275
00276
00277 for (int x = 0; x < m_selectedList.size(); x++)
00278 {
00279 f = m_selectedList.at(x);
00280
00281 QFile file(f);
00282 if (file.exists())
00283 {
00284 QString title = f;
00285 int pos = f.lastIndexOf('/');
00286 if (pos > 0)
00287 title = f.mid(pos + 1);
00288
00289 a = new ArchiveItem;
00290 a->type = "File";
00291 a->title = title;
00292 a->subtitle = "";
00293 a->description = "";
00294 a->startDate = "";
00295 a->startTime = "";
00296 a->size = (int64_t)file.size();
00297 a->filename = f;
00298 a->hasCutlist = false;
00299 a->useCutlist = false;
00300 a->duration = 0;
00301 a->cutDuration = 0;
00302 a->videoWidth = 0;
00303 a->videoHeight = 0;
00304 a->fileCodec = "";
00305 a->videoCodec = "";
00306 a->encoderProfile = NULL;
00307 a->editedDetails = false;
00308 m_archiveList->append(a);
00309 }
00310 }
00311 }
00312 else
00313 {
00314 MythUIButtonListItem *item = m_fileButtonList->GetItemCurrent();
00315 FileData *fileData = qVariantValue<FileData*>(item->GetData());
00316
00317 if (m_selectorType == FSTYPE_DIRECTORY)
00318 {
00319 if (!fileData->directory)
00320 {
00321 ShowOkPopup(tr("The selected item is not a directory!"));
00322 return;
00323 }
00324
00325 if (fileData->filename != "..")
00326 {
00327 if (!m_curDirectory.endsWith("/"))
00328 m_curDirectory += "/";
00329 m_curDirectory += fileData->filename;
00330 }
00331 }
00332 else
00333 {
00334 if (fileData->directory)
00335 {
00336 if (!m_curDirectory.endsWith("/"))
00337 m_curDirectory += "/";
00338 }
00339 else
00340 {
00341 if (!m_curDirectory.endsWith("/"))
00342 m_curDirectory += "/";
00343 m_curDirectory += fileData->filename;
00344 }
00345 }
00346 }
00347
00348 if (m_selectorType == FSTYPE_FILELIST)
00349 emit haveResult(true);
00350 else
00351 emit haveResult(getSelected());
00352 Close();
00353 }
00354
00355 void FileSelector::cancelPressed()
00356 {
00357 if (m_selectorType == FSTYPE_FILELIST)
00358 emit haveResult(true);
00359 else
00360 emit haveResult("");
00361 Close();
00362 }
00363
00364 void FileSelector::updateSelectedList()
00365 {
00366 if (!m_archiveList)
00367 return;
00368
00369 while (!m_selectedList.isEmpty())
00370 m_selectedList.takeFirst();
00371 m_selectedList.clear();
00372
00373 FileData *f;
00374 ArchiveItem *a;
00375 for (int x = 0; x < m_archiveList->size(); x++)
00376 {
00377 a = m_archiveList->at(x);
00378 for (int y = 0; y < m_fileData.size(); y++)
00379 {
00380 f = m_fileData.at(y);
00381 if (f->filename == a->filename)
00382 {
00383 if (m_selectedList.indexOf(f->filename) == -1)
00384 m_selectedList.append(f->filename);
00385 break;
00386 }
00387 }
00388 }
00389 }
00390
00391 void FileSelector::updateFileList()
00392 {
00393 if (!m_fileButtonList)
00394 return;
00395
00396 m_fileButtonList->Reset();
00397 while (!m_fileData.isEmpty())
00398 delete m_fileData.takeFirst();
00399 m_fileData.clear();
00400
00401 QDir d;
00402
00403 d.setPath(m_curDirectory);
00404 if (d.exists())
00405 {
00406
00407 QStringList filters;
00408 filters << "*";
00409 QFileInfoList list = d.entryInfoList(filters, QDir::Dirs, QDir::Name);
00410 QFileInfo fi;
00411
00412 for (int x = 0; x < list.size(); x++)
00413 {
00414 fi = list.at(x);
00415 if (fi.fileName() != ".")
00416 {
00417 FileData *data = new FileData;
00418 data->selected = false;
00419 data->directory = true;
00420 data->filename = fi.fileName();
00421 data->size = 0;
00422 m_fileData.append(data);
00423
00424
00425 MythUIButtonListItem* item = new
00426 MythUIButtonListItem(m_fileButtonList, data->filename);
00427 item->setCheckable(false);
00428 item->SetImage("ma_folder.png");
00429 item->SetData(qVariantFromValue(data));
00430 }
00431 }
00432
00433 if (m_selectorType != FSTYPE_DIRECTORY)
00434 {
00435
00436 filters.clear();
00437 filters = m_filemask.split(" ", QString::SkipEmptyParts);
00438 list = d.entryInfoList(filters, QDir::Files, QDir::Name);
00439 for (int x = 0; x < list.size(); x++)
00440 {
00441 fi = list.at(x);
00442 FileData *data = new FileData;
00443 data->selected = false;
00444 data->directory = false;
00445 data->filename = fi.fileName();
00446 data->size = fi.size();
00447 m_fileData.append(data);
00448
00449
00450 MythUIButtonListItem* item =
00451 new MythUIButtonListItem(m_fileButtonList, data->filename);
00452 item->SetText(formatSize(data->size / 1024, 2), "size");
00453
00454 if (m_selectorType == FSTYPE_FILELIST)
00455 {
00456 item->setCheckable(true);
00457
00458 QString fullPath = m_curDirectory;
00459 if (!fullPath.endsWith("/"))
00460 fullPath += "/";
00461 fullPath += data->filename;
00462
00463 if (m_selectedList.indexOf(fullPath) != -1)
00464 {
00465 item->setChecked(MythUIButtonListItem::FullChecked);
00466 }
00467 else
00468 {
00469 item->setChecked(MythUIButtonListItem::NotChecked);
00470 }
00471 }
00472 else
00473 item->setCheckable(false);
00474
00475 item->SetData(qVariantFromValue(data));
00476 }
00477 }
00478 m_locationEdit->SetText(m_curDirectory);
00479 }
00480 else
00481 {
00482 m_locationEdit->SetText("/");
00483 LOG(VB_GENERAL, LOG_ERR,
00484 "MythArchive: current directory does not exist!");
00485 }
00486 }