00001 #include <cstdlib>
00002
00003 #include <qdir.h>
00004 #include <qapplication.h>
00005 #include <qfileinfo.h>
00006 #include <qsqldatabase.h>
00007
00008
00009 #include <mythtv/mythcontext.h>
00010 #include <mythtv/mythdbcon.h>
00011 #include <mythtv/uitypes.h>
00012
00013
00014 #include "fileselector.h"
00015 #include "archiveutil.h"
00016
00018
00019 FileSelector::FileSelector(FSTYPE type, const QString &startDir,
00020 const QString &filemask, MythMainWindow *parent,
00021 const QString &window_name, const QString &theme_filename,
00022 const char *name)
00023 :MythThemedDialog(parent, window_name, theme_filename, name)
00024 {
00025 m_selectorType = type;
00026 m_filemask = filemask;
00027 m_curDirectory = startDir;
00028 wireUpTheme();
00029 }
00030
00031 FileSelector::~FileSelector()
00032 {
00033 }
00034
00035 QString FileSelector::getSelected(void)
00036 {
00037 return m_curDirectory;
00038 }
00039
00040 void FileSelector::keyPressEvent(QKeyEvent *e)
00041 {
00042 bool handled = false;
00043
00044 QStringList actions;
00045 gContext->GetMainWindow()->TranslateKeyPress("Global", e, actions);
00046
00047 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00048 {
00049 QString action = actions[i];
00050 handled = true;
00051
00052 if (action == "SELECT")
00053 {
00054 if (getCurrentFocusWidget() == m_fileList)
00055 {
00056 UIListBtnTypeItem *item = m_fileList->GetItemCurrent();
00057 FileData *fileData = (FileData*)item->getData();
00058
00059 if (fileData->directory)
00060 {
00061 if (fileData->filename == "..")
00062 {
00063
00064 int pos = m_curDirectory.findRev('/');
00065 if (pos > 0)
00066 m_curDirectory = m_curDirectory.left(pos);
00067 else
00068 m_curDirectory = "/";
00069 }
00070 else
00071 {
00072 if (!m_curDirectory.endsWith("/"))
00073 m_curDirectory += "/";
00074 m_curDirectory += fileData->filename;
00075 }
00076 updateFileList();
00077 }
00078 else
00079 {
00080 if (m_selectorType == FSTYPE_FILELIST)
00081 {
00082 QString fullPath = m_curDirectory;
00083 if (!fullPath.endsWith("/"))
00084 fullPath += "/";
00085 fullPath += fileData->filename;
00086
00087 if (item->state() == UIListBtnTypeItem::FullChecked)
00088 {
00089 m_selectedList.remove(fullPath);
00090 item->setChecked(UIListBtnTypeItem::NotChecked);
00091 }
00092 else
00093 {
00094 if (m_selectedList.findIndex(fullPath) == -1)
00095 m_selectedList.append(fullPath);
00096 item->setChecked(UIListBtnTypeItem::FullChecked);
00097 }
00098
00099 m_fileList->refresh();
00100 }
00101 }
00102 }
00103 else
00104 activateCurrent();
00105 }
00106 else if (action == "PAUSE")
00107 {
00108 }
00109 else if (action == "UP")
00110 {
00111 if (getCurrentFocusWidget() == m_fileList)
00112 {
00113 m_fileList->MoveUp(UIListBtnType::MoveItem);
00114 m_fileList->refresh();
00115 }
00116 else
00117 nextPrevWidgetFocus(false);
00118 }
00119 else if (action == "DOWN")
00120 {
00121 if (getCurrentFocusWidget() == m_fileList)
00122 {
00123 m_fileList->MoveDown(UIListBtnType::MoveItem);
00124 m_fileList->refresh();
00125 }
00126 else
00127 nextPrevWidgetFocus(true);
00128 }
00129 else if (action == "LEFT")
00130 {
00131 nextPrevWidgetFocus(false);
00132 }
00133 else if (action == "RIGHT")
00134 {
00135 nextPrevWidgetFocus(true);
00136 }
00137 else if (action == "PAGEUP")
00138 {
00139 if (getCurrentFocusWidget() == m_fileList)
00140 {
00141 m_fileList->MoveUp(UIListBtnType::MovePage);
00142 m_fileList->refresh();
00143 }
00144 }
00145 else if (action == "PAGEDOWN")
00146 {
00147 if (getCurrentFocusWidget() == m_fileList)
00148 {
00149 m_fileList->MoveDown(UIListBtnType::MovePage);
00150 m_fileList->refresh();
00151 }
00152 }
00153 else
00154 handled = false;
00155 }
00156
00157 if (!handled)
00158 MythThemedDialog::keyPressEvent(e);
00159 }
00160
00161 void FileSelector::wireUpTheme()
00162 {
00163 m_fileList = getUIListBtnType("filelist");
00164
00165 m_locationEdit = getUIRemoteEditType("location_edit");
00166 if (m_locationEdit)
00167 {
00168 m_locationEdit->createEdit(this);
00169 connect(m_locationEdit, SIGNAL(loosingFocus()),
00170 this, SLOT(locationEditLostFocus()));
00171 }
00172
00173
00174 m_okButton = getUITextButtonType("ok_button");
00175 if (m_okButton)
00176 {
00177 m_okButton->setText(tr("OK"));
00178 connect(m_okButton, SIGNAL(pushed()), this, SLOT(OKPressed()));
00179 }
00180
00181
00182 m_cancelButton = getUITextButtonType("cancel_button");
00183 if (m_cancelButton)
00184 {
00185 m_cancelButton->setText(tr("Cancel"));
00186 connect(m_cancelButton, SIGNAL(pushed()), this, SLOT(cancelPressed()));
00187 }
00188
00189
00190 m_backButton = getUITextButtonType("back_button");
00191 if (m_backButton)
00192 {
00193 m_backButton->setText(tr("Back"));
00194 connect(m_backButton, SIGNAL(pushed()), this, SLOT(backPressed()));
00195 }
00196
00197
00198 m_homeButton = getUITextButtonType("home_button");
00199 if (m_homeButton)
00200 {
00201 m_homeButton->setText(tr("Home"));
00202 connect(m_homeButton, SIGNAL(pushed()), this, SLOT(homePressed()));
00203 }
00204
00205 if (!m_fileList || !m_locationEdit || !m_backButton || !m_okButton
00206 || !m_cancelButton || !m_homeButton)
00207 {
00208 cout << "FileSelector: Your theme is missing some UI elements! Bailing out." << endl;
00209 QTimer::singleShot(100, this, SLOT(reject()));
00210 }
00211
00212
00213 m_directoryPixmap = gContext->LoadScalePixmap("ma_folder.png");
00214
00215 buildFocusList();
00216 assignFirstFocus();
00217 updateSelectedList();
00218 updateFileList();
00219 }
00220
00221 void FileSelector::locationEditLostFocus()
00222 {
00223 m_curDirectory = m_locationEdit->getText();
00224 updateFileList();
00225 }
00226
00227 void FileSelector::backPressed()
00228 {
00229
00230 int pos = m_curDirectory.findRev('/');
00231 if (pos > 0)
00232 m_curDirectory = m_curDirectory.left(pos);
00233 else
00234 m_curDirectory = "/";
00235
00236 updateFileList();
00237 }
00238
00239 void FileSelector::homePressed()
00240 {
00241 char *home = getenv("HOME");
00242 m_curDirectory = home;
00243
00244 updateFileList();
00245 }
00246
00247 void FileSelector::OKPressed()
00248 {
00249 if (m_selectorType == FSTYPE_FILELIST)
00250 {
00251
00252 MSqlQuery query(MSqlQuery::InitCon());
00253 query.prepare("DELETE FROM archiveitems WHERE type = 'File'");
00254 query.exec();
00255
00256
00257 QString s;
00258 QStringList::iterator it;
00259 for (it = m_selectedList.begin(); it != m_selectedList.end(); ++it)
00260 {
00261 s = (*it);
00262
00263 QFile file(s);
00264 if (file.exists())
00265 {
00266 QString title = s;
00267 int pos = s.findRev('/');
00268 if (pos > 0)
00269 title = s.mid(pos + 1);
00270
00271 query.prepare("INSERT INTO archiveitems (type, title, subtitle,"
00272 "description, startdate, starttime, size, filename, hascutlist) "
00273 "VALUES(:TYPE, :TITLE, :SUBTITLE, :DESCRIPTION, :STARTDATE, "
00274 ":STARTTIME, :SIZE, :FILENAME, :HASCUTLIST);");
00275 query.bindValue(":TYPE", "File");
00276 query.bindValue(":TITLE", title);
00277 query.bindValue(":SUBTITLE", "");
00278 query.bindValue(":DESCRIPTION", "");
00279 query.bindValue(":STARTDATE", "");
00280 query.bindValue(":STARTTIME", "");
00281 query.bindValue(":SIZE", (long long)file.size());
00282 query.bindValue(":FILENAME", s);
00283 query.bindValue(":HASCUTLIST", 0);
00284 if (!query.exec())
00285 MythContext::DBError("archive item insert", query);
00286 }
00287 }
00288 }
00289 else
00290 {
00291 UIListBtnTypeItem *item = m_fileList->GetItemCurrent();
00292 FileData *fileData = (FileData*)item->getData();
00293
00294 if (m_selectorType == FSTYPE_DIRECTORY)
00295 {
00296 if (!fileData->directory)
00297 {
00298 MythPopupBox::showOkPopup(gContext->GetMainWindow(), tr("Myth Archive"),
00299 tr("The selected item is not a directory!"));
00300 return;
00301 }
00302
00303 if (fileData->filename != "..")
00304 {
00305 if (!m_curDirectory.endsWith("/"))
00306 m_curDirectory += "/";
00307 m_curDirectory += fileData->filename;
00308 }
00309 }
00310 else
00311 {
00312 if (fileData->directory)
00313 {
00314 if (!m_curDirectory.endsWith("/"))
00315 m_curDirectory += "/";
00316 }
00317 else
00318 {
00319 if (!m_curDirectory.endsWith("/"))
00320 m_curDirectory += "/";
00321 m_curDirectory += fileData->filename;
00322 }
00323 }
00324 }
00325
00326 done(Accepted);
00327 }
00328
00329 void FileSelector::cancelPressed()
00330 {
00331 reject();
00332 }
00333
00334 void FileSelector::updateSelectedList()
00335 {
00336 m_selectedList.clear();
00337 MSqlQuery query(MSqlQuery::InitCon());
00338 query.prepare("SELECT filename FROM archiveitems WHERE type = 'File'");
00339 query.exec();
00340 if (query.isActive() && query.numRowsAffected())
00341 {
00342 while (query.next())
00343 {
00344 QString filename = QString::fromUtf8(query.value(0).toString());
00345 if (m_selectedList.findIndex(filename) == -1)
00346 m_selectedList.append(filename);
00347 }
00348 }
00349 }
00350
00351 void FileSelector::updateFileList()
00352 {
00353 if (!m_fileList)
00354 return;
00355
00356 m_fileList->Reset();
00357 m_fileData.clear();
00358 QDir d;
00359
00360 d.setPath(m_curDirectory);
00361 if (d.exists())
00362 {
00363
00364 const QFileInfoList *list = d.entryInfoList("*", QDir::Dirs, QDir::Name);
00365 QFileInfoListIterator it(*list);
00366 QFileInfo *fi;
00367
00368 while ( (fi = it.current()) != 0 )
00369 {
00370 if (fi->fileName() != ".")
00371 {
00372 FileData *data = new FileData;
00373 data->selected = false;
00374 data->directory = true;
00375 data->filename = fi->fileName();
00376 data->size = 0;
00377 m_fileData.append(data);
00378
00379
00380 UIListBtnTypeItem* item = new UIListBtnTypeItem(
00381 m_fileList, data->filename);
00382 item->setCheckable(false);
00383 item->setPixmap(m_directoryPixmap);
00384 item->setData(data);
00385 }
00386 ++it;
00387 }
00388
00389 if (m_selectorType != FSTYPE_DIRECTORY)
00390 {
00391
00392 list = d.entryInfoList(m_filemask, QDir::Files, QDir::Name);
00393 it = QFileInfoListIterator(*list);
00394
00395 while ( (fi = it.current()) != 0 )
00396 {
00397 FileData *data = new FileData;
00398 data->selected = false;
00399 data->directory = false;
00400 data->filename = fi->fileName();
00401 data->size = fi->size();
00402 m_fileData.append(data);
00403
00404 UIListBtnTypeItem* item = new UIListBtnTypeItem(
00405 m_fileList,
00406 data->filename + " (" + formatSize(data->size / 1024, 2) + ")");
00407
00408 if (m_selectorType == FSTYPE_FILELIST)
00409 {
00410 item->setCheckable(true);
00411
00412
00413
00414 QString fullPath = m_curDirectory;
00415 if (!fullPath.endsWith("/"))
00416 fullPath += "/";
00417 fullPath += data->filename;
00418
00419 if (m_selectedList.findIndex(fullPath) != -1)
00420 {
00421 item->setChecked(UIListBtnTypeItem::FullChecked);
00422 }
00423 else
00424 {
00425 item->setChecked(UIListBtnTypeItem::NotChecked);
00426 }
00427 }
00428 else
00429 item->setCheckable(false);
00430
00431 item->setData(data);
00432
00433 ++it;
00434 }
00435 }
00436 m_locationEdit->setText(m_curDirectory);
00437 }
00438 else
00439 {
00440 m_locationEdit->setText("/");
00441 cout << "MythArchive: current directory does not exist!" << endl;
00442 }
00443
00444 m_fileList->refresh();
00445 }