00001
00002 #include <QDir>
00003 #include <QFontMetrics>
00004 #include <QApplication>
00005
00006
00007 #include <mythcontext.h>
00008 #include <mythdbcon.h>
00009 #include <audiooutput.h>
00010
00011
00012 #include "importmusic.h"
00013 #include "decoder.h"
00014 #include "genres.h"
00015 #include "metadata.h"
00016 #include "cdrip.h"
00017 #include "editmetadata.h"
00018 #include "musicplayer.h"
00019 #include "metaio.h"
00020 #include "musicutils.h"
00021
00022 #include <mythdialogbox.h>
00023 #include <mythuitext.h>
00024 #include <mythuiimage.h>
00025 #include <mythuicheckbox.h>
00026 #include <mythuitextedit.h>
00027 #include <mythuibutton.h>
00028 #include <mythuibuttonlist.h>
00029 #include <mythprogressdialog.h>
00030 #include <mythuifilebrowser.h>
00031 #include "mythlogging.h"
00032
00033 static bool copyFile(const QString &src, const QString &dst)
00034 {
00035 const int bufferSize = 16*1024;
00036
00037 QFile s(src);
00038 QFile d(dst);
00039 char buffer[bufferSize];
00040 int len;
00041
00042 if (!s.open(QIODevice::ReadOnly))
00043 return false;
00044
00045 if (!d.open(QIODevice::WriteOnly))
00046 {
00047 s.close();
00048 return false;
00049 }
00050
00051 len = s.read(buffer, bufferSize);
00052 do
00053 {
00054 d.write(buffer, len);
00055 len = s.read(buffer, bufferSize);
00056 } while (len > 0);
00057
00058 s.close();
00059 d.close();
00060
00061 return true;
00062 }
00063
00065
00066 FileScannerThread::FileScannerThread(ImportMusicDialog *parent) :
00067 MThread("FileScanner"), m_parent(parent)
00068 {
00069 }
00070
00071 void FileScannerThread::run()
00072 {
00073 RunProlog();
00074 m_parent->doScan();
00075 RunEpilog();
00076 }
00077
00079
00080
00081 ImportMusicDialog::ImportMusicDialog(MythScreenStack *parent) :
00082 MythScreenType(parent, "musicimportfiles"),
00083
00084 m_somethingWasImported(false),
00085 m_tracks(new vector<TrackInfo*>),
00086 m_currentTrack(0),
00087 m_playingMetaData(NULL),
00088
00089 m_locationEdit(NULL),
00090 m_locationButton(NULL),
00091 m_scanButton(NULL),
00092 m_coverartButton(NULL),
00093 m_filenameText(NULL),
00094 m_compartistText(NULL),
00095 m_artistText(NULL),
00096 m_albumText(NULL),
00097 m_titleText(NULL),
00098 m_genreText(NULL),
00099 m_yearText(NULL),
00100 m_trackText(NULL),
00101 m_nextButton(NULL),
00102 m_prevButton(NULL),
00103 m_currentText(NULL),
00104 m_statusText(NULL),
00105 m_playButton(NULL),
00106 m_addButton(NULL),
00107 m_addallnewButton(NULL),
00108 m_nextnewButton(NULL),
00109 m_compilationCheck(NULL),
00110 m_popupMenu(NULL),
00111
00112 m_defaultCompilation(false),
00113 m_defaultYear(0),
00114 m_defaultRating(0),
00115 m_haveDefaults(false)
00116 {
00117 }
00118
00119 ImportMusicDialog::~ImportMusicDialog()
00120 {
00121 if (gPlayer->getCurrentMetadata() && m_playingMetaData)
00122 {
00123 if (gPlayer->isPlaying() && gPlayer->getCurrentMetadata()->Filename() == m_playingMetaData->Filename())
00124 gPlayer->next();
00125 }
00126
00127 if (m_locationEdit)
00128 gCoreContext->SaveSetting("MythMusicLastImportDir", m_locationEdit->GetText());
00129
00130 delete m_tracks;
00131
00132
00133 if (m_somethingWasImported)
00134 emit importFinished();
00135 }
00136
00137 void ImportMusicDialog::fillWidgets()
00138 {
00139 if (!m_tracks->empty())
00140 {
00141
00142 m_currentText->SetText(QString("%1 of %2")
00143 .arg(m_currentTrack + 1).arg(m_tracks->size()));
00144
00145 Metadata *meta = m_tracks->at(m_currentTrack)->metadata;
00146 m_filenameText->SetText(meta->Filename());
00147 m_compilationCheck->SetCheckState(meta->Compilation());
00148 m_compartistText->SetText(meta->CompilationArtist());
00149 m_artistText->SetText(meta->Artist());
00150 m_albumText->SetText(meta->Album());
00151 m_titleText->SetText(meta->Title());
00152 m_genreText->SetText(meta->Genre());
00153 m_yearText->SetText(QString::number(meta->Year()));
00154 m_trackText->SetText(QString::number(meta->Track()));
00155 if (m_tracks->at(m_currentTrack)->isNewTune)
00156 {
00157 m_coverartButton->SetVisible(false);
00158 m_statusText->SetText(tr("New File"));
00159 }
00160 else
00161 {
00162 m_coverartButton->SetVisible(true);
00163 m_statusText->SetText(tr("Already in Database"));
00164 }
00165 }
00166 else
00167 {
00168
00169 m_currentText->SetText(tr("Not found"));
00170 m_filenameText->Reset();
00171 m_compilationCheck->SetCheckState(false);
00172 m_compartistText->Reset();
00173 m_artistText->Reset();
00174 m_albumText->Reset();
00175 m_titleText->Reset();
00176 m_genreText->Reset();
00177 m_yearText->Reset();
00178 m_trackText->Reset();
00179 m_statusText->Reset();
00180 m_coverartButton->SetVisible(false);
00181 }
00182 }
00183
00184 bool ImportMusicDialog::keyPressEvent(QKeyEvent *event)
00185 {
00186 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00187 return true;
00188
00189 bool handled = false;
00190 QStringList actions;
00191 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
00192
00193 for (int i = 0; i < actions.size() && !handled; i++)
00194 {
00195 QString action = actions[i];
00196 handled = true;
00197
00198 if (action == "LEFT")
00199 {
00200 m_prevButton->Push();
00201 }
00202 else if (action == "RIGHT")
00203 {
00204 m_nextButton->Push();
00205 }
00206 else if (action == "EDIT")
00207 {
00208 showEditMetadataDialog();
00209 }
00210 else if (action == "MENU")
00211 {
00212 showMenu();
00213 }
00214 else if (action == "ESCAPE" && !GetMythMainWindow()->IsExitingToMain())
00215 {
00216 bool found = false;
00217 if (!m_tracks->empty())
00218 {
00219 uint track = 0;
00220 while (track < m_tracks->size())
00221 {
00222 if (m_tracks->at(track)->isNewTune)
00223 {
00224 found = true;
00225 break;
00226 }
00227 track++;
00228 }
00229
00230 if (found)
00231 {
00232 QString msg = tr("You might have unsaved changes.\nAre you sure you want to exit this screen?");
00233 ShowOkPopup(msg, this, SLOT(doExit(bool)), true);
00234 }
00235 }
00236
00237 handled = found;
00238 }
00239 else if (action == "1")
00240 {
00241 setCompilation();
00242 }
00243 else if (action == "2")
00244 {
00245 setCompilationArtist();
00246 }
00247 else if (action == "3")
00248 {
00249 setArtist();
00250 }
00251 else if (action == "4")
00252 {
00253 setAlbum();
00254 }
00255 else if (action == "5")
00256 {
00257 setGenre();
00258 }
00259 else if (action == "6")
00260 {
00261 setYear();
00262 }
00263 else if (action == "7")
00264 {
00265 setRating();
00266 }
00267 else if (action == "8")
00268 {
00269 setTitleWordCaps();
00270 }
00271 else if (action == "9")
00272 {
00273 setTitleInitialCap();
00274 }
00275 else if (action == "0")
00276 {
00277 setTrack();
00278 }
00279 else
00280 handled = false;
00281 }
00282
00283 if (!handled && MythScreenType::keyPressEvent(event))
00284 handled = true;
00285
00286 return handled;
00287 }
00288
00289 bool ImportMusicDialog::Create()
00290 {
00291 if (!LoadWindowFromXML("music-ui.xml", "import_music", this))
00292 return false;
00293
00294 bool err = false;
00295 UIUtilE::Assign(this, m_locationEdit, "location", &err);
00296 UIUtilE::Assign(this, m_locationButton, "directoryfinder", &err);
00297 UIUtilE::Assign(this, m_scanButton, "scan", &err);
00298 UIUtilE::Assign(this, m_coverartButton, "coverart", &err);
00299 UIUtilE::Assign(this, m_filenameText, "filename", &err);
00300 UIUtilE::Assign(this, m_compartistText, "compartist", &err);
00301 UIUtilE::Assign(this, m_artistText, "artist", &err);
00302 UIUtilE::Assign(this, m_albumText, "album", &err);
00303 UIUtilE::Assign(this, m_titleText, "title", &err);
00304 UIUtilE::Assign(this, m_genreText, "genre", &err);
00305 UIUtilE::Assign(this, m_yearText, "year", &err);
00306 UIUtilE::Assign(this, m_trackText, "track", &err);
00307 UIUtilE::Assign(this, m_currentText, "position", &err);
00308 UIUtilE::Assign(this, m_statusText, "status", &err);
00309 UIUtilE::Assign(this, m_compilationCheck,"compilation", &err);
00310 UIUtilE::Assign(this, m_playButton, "play", &err);
00311 UIUtilE::Assign(this, m_nextnewButton, "nextnew", &err);
00312 UIUtilE::Assign(this, m_addButton, "add", &err);
00313 UIUtilE::Assign(this, m_addallnewButton, "addallnew", &err);
00314 UIUtilE::Assign(this, m_nextButton, "next", &err);
00315 UIUtilE::Assign(this, m_prevButton, "prev", &err);
00316
00317 if (err)
00318 {
00319 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'import_music'");
00320 return false;
00321 }
00322
00323 connect(m_prevButton, SIGNAL(Clicked()), SLOT(prevPressed()));
00324 connect(m_locationButton, SIGNAL(Clicked()), SLOT(locationPressed()));
00325 connect(m_scanButton, SIGNAL(Clicked()), SLOT(startScan()));
00326 connect(m_coverartButton, SIGNAL(Clicked()), SLOT(coverArtPressed()));
00327 connect(m_playButton, SIGNAL(Clicked()), SLOT(playPressed()));
00328 connect(m_nextnewButton, SIGNAL(Clicked()), SLOT(nextNewPressed()));
00329 connect(m_addButton, SIGNAL(Clicked()), SLOT(addPressed()));
00330 connect(m_addallnewButton, SIGNAL(Clicked()), SLOT(addAllNewPressed()));
00331 connect(m_nextButton, SIGNAL(Clicked()), SLOT(nextPressed()));
00332
00333 fillWidgets();
00334
00335 BuildFocusList();
00336
00337 m_locationEdit->SetText(gCoreContext->GetSetting("MythMusicLastImportDir", "/"));
00338
00339 return true;
00340 }
00341
00342 void ImportMusicDialog::doExit(bool ok)
00343 {
00344 if (ok)
00345 Close();
00346 }
00347
00348 void ImportMusicDialog::locationPressed()
00349 {
00350 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00351 MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, m_locationEdit->GetText());
00352
00353 fb->SetTypeFilter(QDir::AllDirs | QDir::Readable);
00354 if (fb->Create())
00355 {
00356 fb->SetReturnEvent(this, "locationchange");
00357 popupStack->AddScreen(fb);
00358 }
00359 else
00360 delete fb;
00361 }
00362
00363 void ImportMusicDialog::coverArtPressed()
00364 {
00365 showImportCoverArtDialog();
00366 }
00367
00368 void ImportMusicDialog::playPressed()
00369 {
00370 if (m_tracks->empty())
00371 return;
00372
00373 m_playingMetaData = m_tracks->at(m_currentTrack)->metadata;
00374
00375 gPlayer->playFile(*m_playingMetaData);
00376 }
00377
00378 void ImportMusicDialog::prevPressed()
00379 {
00380 if (m_currentTrack > 0)
00381 {
00382 m_currentTrack--;
00383 fillWidgets();
00384 }
00385 }
00386
00387 void ImportMusicDialog::nextPressed()
00388 {
00389 if (m_currentTrack < (int) m_tracks->size() - 1)
00390 {
00391 m_currentTrack++;
00392 fillWidgets();
00393 }
00394 }
00395
00396 void ImportMusicDialog::addPressed()
00397 {
00398 if (m_tracks->empty())
00399 return;
00400
00401 Metadata *meta = m_tracks->at(m_currentTrack)->metadata;
00402
00403
00404 if (m_tracks->at(m_currentTrack)->isNewTune)
00405 {
00406
00407 QString saveFilename = filenameFromMetadata(meta);
00408
00409
00410 QFileInfo fi(meta->Filename());
00411 saveFilename += "." + fi.suffix();
00412
00413
00414 if (!copyFile(meta->Filename(), gMusicData->musicDir + saveFilename))
00415 {
00416 ShowOkPopup(tr("Copy Failed\nCould not copy file to: %1")
00417 .arg(gMusicData->musicDir + saveFilename));
00418 return;
00419 }
00420
00421 meta->setFilename(saveFilename);
00422
00423
00424 if (m_tracks->at(m_currentTrack)->metadataHasChanged)
00425 {
00426 Decoder *decoder = Decoder::create(gMusicData->musicDir + saveFilename, NULL, NULL, true);
00427 if (decoder)
00428 {
00429 decoder->commitMetadata(meta);
00430 delete decoder;
00431 }
00432 }
00433
00434
00435 meta->dumpToDatabase();
00436
00437
00438 MetaIO *tagger = meta->getTagger();
00439 if (tagger && tagger->supportsEmbeddedImages())
00440 {
00441 AlbumArtList artList = tagger->getAlbumArtList(meta->Filename());
00442 meta->setEmbeddedAlbumArt(artList);
00443 meta->getAlbumArtImages()->dumpToDatabase();
00444 }
00445
00446 m_somethingWasImported = true;
00447
00448 m_tracks->at(m_currentTrack)->isNewTune =
00449 isNewTune(meta->Artist(), meta->Album(), meta->Title());
00450
00451
00452 fillWidgets();
00453 }
00454 else
00455 ShowOkPopup(tr("This track is already in the database"));
00456 }
00457
00458 void ImportMusicDialog::addAllNewPressed()
00459 {
00460 if (m_tracks->empty())
00461 return;
00462
00463 m_currentTrack = 0;
00464 int newCount = 0;
00465
00466 while (m_currentTrack < (int) m_tracks->size())
00467 {
00468 fillWidgets();
00469 qApp->processEvents();
00470
00471 if (m_tracks->at(m_currentTrack)->isNewTune)
00472 {
00473 addPressed();
00474 newCount++;
00475 }
00476
00477 qApp->processEvents();
00478
00479 m_currentTrack++;
00480 }
00481
00482 m_currentTrack--;
00483
00484 ShowOkPopup(tr("%1 new tracks were added to the database").arg(newCount));
00485 }
00486
00487 void ImportMusicDialog::nextNewPressed()
00488 {
00489 if (m_tracks->empty())
00490 return;
00491
00492 uint track = m_currentTrack + 1;
00493 while (track < m_tracks->size())
00494 {
00495 if (m_tracks->at(track)->isNewTune)
00496 {
00497 m_currentTrack = track;
00498 fillWidgets();
00499 break;
00500 }
00501 track++;
00502 }
00503 }
00504
00505 void ImportMusicDialog::startScan()
00506 {
00507 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00508 MythUIBusyDialog *busy =
00509 new MythUIBusyDialog(QObject::tr("Searching for music files"),
00510 popupStack,
00511 "scanbusydialog");
00512
00513 if (busy->Create())
00514 {
00515 popupStack->AddScreen(busy, false);
00516 }
00517 else
00518 {
00519 delete busy;
00520 busy = NULL;
00521 }
00522 FileScannerThread *scanner = new FileScannerThread(this);
00523 scanner->start();
00524
00525 while (!scanner->isFinished())
00526 {
00527 usleep(500);
00528 qApp->processEvents();
00529 }
00530
00531 delete scanner;
00532
00533 m_currentTrack = 0;
00534 fillWidgets();
00535
00536 if (busy)
00537 busy->Close();
00538 }
00539
00540 void ImportMusicDialog::doScan()
00541 {
00542 m_tracks->clear();
00543 m_sourceFiles.clear();
00544 QString location = m_locationEdit->GetText();
00545 scanDirectory(location, m_tracks);
00546 }
00547
00548 void ImportMusicDialog::scanDirectory(QString &directory, vector<TrackInfo*> *tracks)
00549 {
00550 QDir d(directory);
00551
00552 if (!d.exists())
00553 return;
00554
00555 const QFileInfoList list = d.entryInfoList();
00556 if (list.isEmpty())
00557 return;
00558
00559 QFileInfoList::const_iterator it = list.begin();
00560 const QFileInfo *fi;
00561
00562 while (it != list.end())
00563 {
00564 fi = &(*it);
00565 ++it;
00566 if (fi->fileName() == "." || fi->fileName() == "..")
00567 continue;
00568 QString filename = fi->absoluteFilePath();
00569 if (fi->isDir())
00570 scanDirectory(filename, tracks);
00571 else
00572 {
00573 Decoder *decoder = Decoder::create(filename, NULL, NULL, true);
00574 if (decoder)
00575 {
00576 Metadata *metadata = decoder->getMetadata();
00577 if (metadata)
00578 {
00579 TrackInfo * track = new TrackInfo;
00580 track->metadata = metadata;
00581 track->isNewTune = isNewTune(metadata->Artist(), metadata->Album(),
00582 metadata->Title());
00583 track->metadataHasChanged = false;
00584 tracks->push_back(track);
00585 m_sourceFiles.append(filename);
00586 }
00587
00588 delete decoder;
00589 }
00590 }
00591 }
00592 }
00593
00594 void ImportMusicDialog::showEditMetadataDialog()
00595 {
00596 if (m_tracks->empty())
00597 return;
00598
00599 Metadata *editMeta = m_tracks->at(m_currentTrack)->metadata;
00600
00601 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00602
00603 EditMetadataDialog *editDialog = new EditMetadataDialog(mainStack, editMeta);
00604 editDialog->setSaveMetadataOnly();
00605
00606 if (!editDialog->Create())
00607 {
00608 delete editDialog;
00609 return;
00610 }
00611
00612 connect(editDialog, SIGNAL(metadataChanged()), this, SLOT(metadataChanged()));
00613
00614 mainStack->AddScreen(editDialog);
00615 }
00616
00617 void ImportMusicDialog::metadataChanged(void)
00618 {
00619 Metadata *editMeta = m_tracks->at(m_currentTrack)->metadata;
00620 m_tracks->at(m_currentTrack)->metadataHasChanged = true;
00621 m_tracks->at(m_currentTrack)->isNewTune =
00622 isNewTune(editMeta->Artist(), editMeta->Album(), editMeta->Title());
00623 fillWidgets();
00624 }
00625
00626 void ImportMusicDialog::showMenu()
00627 {
00628 if (m_popupMenu)
00629 return;
00630
00631 if (m_tracks->empty())
00632 return;
00633
00634 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00635
00636 MythDialogBox *menu = new MythDialogBox("", popupStack, "importmusicmenu");
00637
00638 if (menu->Create())
00639 popupStack->AddScreen(menu);
00640 else
00641 {
00642 delete menu;
00643 return;
00644 }
00645
00646 menu->SetReturnEvent(this, "menu");
00647 menu->AddButton(tr("Save Defaults"), SLOT(saveDefaults()));
00648
00649 if (m_haveDefaults)
00650 {
00651 menu->AddButton(tr("Change Compilation Flag"), SLOT(setCompilation()));
00652 menu->AddButton(tr("Change Compilation Artist"),
00653 SLOT(setCompilationArtist()));
00654 menu->AddButton(tr("Change Artist"), SLOT(setArtist()));
00655 menu->AddButton(tr("Change Album"), SLOT(setAlbum()));
00656 menu->AddButton(tr("Change Genre"), SLOT(setGenre()));
00657 menu->AddButton(tr("Change Year"), SLOT(setYear()));
00658 menu->AddButton(tr("Change Rating"), SLOT(setRating()));
00659 }
00660 }
00661
00662 void ImportMusicDialog::saveDefaults(void)
00663 {
00664 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00665 m_defaultCompilation = data->Compilation();
00666 m_defaultCompArtist = data->CompilationArtist();
00667 m_defaultArtist = data->Artist();
00668 m_defaultAlbum = data->Album();
00669 m_defaultGenre = data->Genre();
00670 m_defaultYear = data->Year();
00671 m_defaultRating = data->Rating();
00672
00673 m_haveDefaults = true;
00674 }
00675
00676 void ImportMusicDialog::setCompilation(void)
00677 {
00678 if (!m_haveDefaults)
00679 return;
00680
00681 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00682
00683 if (m_defaultCompilation)
00684 {
00685 data->setCompilation(m_defaultCompilation);
00686 data->setCompilationArtist(m_defaultCompArtist);
00687 }
00688 else
00689 {
00690 data->setCompilation(m_defaultCompilation);
00691 data->setCompilationArtist(m_defaultArtist);
00692 }
00693
00694 fillWidgets();
00695 }
00696
00697 void ImportMusicDialog::setCompilationArtist(void)
00698 {
00699 if (!m_haveDefaults)
00700 return;
00701
00702 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00703 data->setCompilationArtist(m_defaultCompArtist);
00704
00705 fillWidgets();
00706 }
00707
00708 void ImportMusicDialog::setArtist(void)
00709 {
00710 if (!m_haveDefaults)
00711 return;
00712
00713 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00714 data->setArtist(m_defaultArtist);
00715
00716 m_tracks->at(m_currentTrack)->isNewTune =
00717 isNewTune(data->Artist(), data->Album(), data->Title());
00718
00719 fillWidgets();
00720 }
00721
00722 void ImportMusicDialog::setAlbum(void)
00723 {
00724 if (!m_haveDefaults)
00725 return;
00726
00727 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00728 data->setAlbum(m_defaultAlbum);
00729
00730 m_tracks->at(m_currentTrack)->isNewTune =
00731 isNewTune(data->Artist(), data->Album(), data->Title());
00732
00733 fillWidgets();
00734 }
00735
00736 void ImportMusicDialog::setYear(void)
00737 {
00738 if (!m_haveDefaults)
00739 return;
00740
00741 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00742 data->setYear(m_defaultYear);
00743
00744 fillWidgets();
00745 }
00746
00747 void ImportMusicDialog::setTrack(void)
00748 {
00749 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00750 data->setTrack(data->Track() + 100);
00751
00752 fillWidgets();
00753 }
00754
00755 void ImportMusicDialog::setGenre(void)
00756 {
00757 if (!m_haveDefaults)
00758 return;
00759
00760 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00761 data->setGenre(m_defaultGenre);
00762
00763 fillWidgets();
00764 }
00765
00766 void ImportMusicDialog::setRating(void)
00767 {
00768 if (!m_haveDefaults)
00769 return;
00770
00771 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00772 data->setRating(m_defaultRating);
00773 }
00774
00775 void ImportMusicDialog::setTitleInitialCap(void)
00776 {
00777 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00778 QString title = data->Title();
00779 bool bFoundCap = false;
00780
00781 for (int x = 0; x < title.length(); x++)
00782 {
00783 if (title[x].isLetter())
00784 {
00785 if (bFoundCap == false)
00786 {
00787 title[x] = title[x].toUpper();
00788 bFoundCap = true;
00789 }
00790 else
00791 title[x] = title[x].toLower();
00792 }
00793 }
00794
00795 data->setTitle(title);
00796 fillWidgets();
00797 }
00798
00799 void ImportMusicDialog::setTitleWordCaps(void)
00800 {
00801 Metadata *data = m_tracks->at(m_currentTrack)->metadata;
00802 QString title = data->Title();
00803 bool bInWord = false;
00804
00805 for (int x = 0; x < title.length(); x++)
00806 {
00807 if (title[x].isSpace())
00808 bInWord = false;
00809 else
00810 {
00811 if (title[x].isLetter())
00812 {
00813 if (!bInWord)
00814 {
00815 title[x] = title[x].toUpper();
00816 bInWord = true;
00817 }
00818 else
00819 title[x] = title[x].toLower();
00820 }
00821 }
00822 }
00823
00824 data->setTitle(title);
00825 fillWidgets();
00826 }
00827
00828 void ImportMusicDialog::showImportCoverArtDialog(void)
00829 {
00830 if (m_tracks->empty())
00831 return;
00832
00833 QFileInfo fi(m_sourceFiles.at(m_currentTrack));
00834
00835 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00836
00837 ImportCoverArtDialog *import = new ImportCoverArtDialog(mainStack,
00838 fi.absolutePath(),
00839 m_tracks->at(m_currentTrack)->metadata);
00840
00841 if (import->Create())
00842 mainStack->AddScreen(import);
00843 else
00844 delete import;
00845 }
00846
00847 void ImportMusicDialog::customEvent(QEvent *event)
00848 {
00849 if (event->type() == DialogCompletionEvent::kEventType)
00850 {
00851 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00852 if (dce->GetId() == "locationchange")
00853 {
00854 m_locationEdit->SetText(dce->GetResultText());
00855 startScan();
00856 }
00857 }
00858 }
00859
00861
00862 ImportCoverArtDialog::ImportCoverArtDialog(MythScreenStack *parent,
00863 const QString &sourceDir,
00864 Metadata *metadata) :
00865 MythScreenType(parent, "import_coverart"),
00866 m_sourceDir(sourceDir),
00867 m_metadata(metadata),
00868 m_currentFile(0),
00869
00870 m_filenameText(NULL),
00871 m_currentText(NULL),
00872 m_statusText(NULL),
00873 m_destinationText(NULL),
00874 m_coverartImage(NULL),
00875 m_typeList(NULL),
00876 m_nextButton(NULL),
00877 m_prevButton(NULL),
00878 m_copyButton(NULL),
00879 m_exitButton(NULL)
00880 {
00881 }
00882
00883 ImportCoverArtDialog::~ImportCoverArtDialog()
00884 {
00885
00886 }
00887
00888 bool ImportCoverArtDialog::keyPressEvent(QKeyEvent *event)
00889 {
00890 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00891 return true;
00892
00893 bool handled = false;
00894 QStringList actions;
00895 handled = GetMythMainWindow()->TranslateKeyPress("Global", event, actions);
00896
00897 for (int i = 0; i < actions.size() && !handled; i++)
00898 {
00899 QString action = actions[i];
00900 handled = true;
00901
00902 if (action == "LEFT")
00903 {
00904 m_prevButton->Push();
00905 }
00906 else if (action == "RIGHT")
00907 {
00908 m_nextButton->Push();
00909 }
00910 else
00911 handled = false;
00912 }
00913
00914 if (!handled && MythScreenType::keyPressEvent(event))
00915 handled = true;
00916
00917 return handled;
00918 }
00919
00920 bool ImportCoverArtDialog::Create()
00921 {
00922 if (!LoadWindowFromXML("music-ui.xml", "import_coverart", this))
00923 return false;
00924
00925 bool err = false;
00926 UIUtilE::Assign(this, m_filenameText, "file", &err);
00927 UIUtilE::Assign(this, m_currentText, "position", &err);
00928 UIUtilE::Assign(this, m_statusText, "status", &err);
00929 UIUtilE::Assign(this, m_destinationText, "destination", &err);
00930 UIUtilE::Assign(this, m_coverartImage, "coverart", &err);
00931 UIUtilE::Assign(this, m_copyButton, "copy", &err);
00932 UIUtilE::Assign(this, m_exitButton, "exit", &err);
00933 UIUtilE::Assign(this, m_prevButton, "prev", &err);
00934 UIUtilE::Assign(this, m_nextButton, "next", &err);
00935 UIUtilE::Assign(this, m_typeList, "type", &err);
00936
00937 if (err)
00938 {
00939 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'import_coverart'");
00940 return false;
00941 }
00942
00943 if (m_typeList)
00944 {
00945 new MythUIButtonListItem(m_typeList, tr("Front Cover"),
00946 qVariantFromValue(0));
00947 new MythUIButtonListItem(m_typeList, tr("Back Cover"),
00948 qVariantFromValue(1));
00949 new MythUIButtonListItem(m_typeList, tr("CD"),
00950 qVariantFromValue(2));
00951 new MythUIButtonListItem(m_typeList, tr("Inlay"),
00952 qVariantFromValue(3));
00953 new MythUIButtonListItem(m_typeList, tr("<Unknown>"),
00954 qVariantFromValue(4));
00955
00956 connect(m_typeList, SIGNAL(itemSelected(MythUIButtonListItem *)),
00957 SLOT(selectorChanged()));
00958 }
00959
00960 if (m_copyButton)
00961 connect(m_copyButton, SIGNAL(Clicked()), this, SLOT(copyPressed()));
00962
00963 if (m_exitButton)
00964 connect(m_exitButton, SIGNAL(Clicked()), this, SLOT(Close()));
00965
00966 if (m_prevButton)
00967 connect(m_prevButton, SIGNAL(Clicked()), this, SLOT(prevPressed()));
00968
00969 if (m_nextButton)
00970 connect(m_nextButton, SIGNAL(Clicked()), this, SLOT(nextPressed()));
00971
00972 BuildFocusList();
00973
00974 scanDirectory();
00975
00976 return true;
00977 }
00978
00979 void ImportCoverArtDialog::selectorChanged()
00980 {
00981 updateStatus();
00982 }
00983
00984 void ImportCoverArtDialog::copyPressed()
00985 {
00986 if (m_filelist.size() > 0)
00987 {
00988 if (!copyFile(m_filelist[m_currentFile], m_saveFilename))
00989 {
00990 ShowOkPopup(QString("Copy CoverArt Failed. \nCopying to %1")
00991 .arg(m_saveFilename));
00992 return;
00993 }
00994
00995 updateStatus();
00996 }
00997 }
00998
00999 void ImportCoverArtDialog::prevPressed()
01000 {
01001 if (m_currentFile > 0)
01002 {
01003 m_currentFile--;
01004 updateTypeSelector();
01005 updateStatus();
01006 }
01007 }
01008
01009 void ImportCoverArtDialog::nextPressed()
01010 {
01011 if (m_currentFile < (int) m_filelist.size() - 1)
01012 {
01013 m_currentFile++;
01014 updateTypeSelector();
01015 updateStatus();
01016 }
01017 }
01018
01019 void ImportCoverArtDialog::scanDirectory()
01020 {
01021 QDir d(m_sourceDir);
01022
01023 if (!d.exists())
01024 return;
01025
01026 QString nameFilter = gCoreContext->GetSetting("AlbumArtFilter",
01027 "*.png;*.jpg;*.jpeg;*.gif;*.bmp");
01028
01029 QFileInfoList list = d.entryInfoList(nameFilter.split(";"));
01030 if (list.isEmpty())
01031 return;
01032
01033 QFileInfoList::const_iterator it = list.begin();
01034 const QFileInfo *fi;
01035
01036 while (it != list.end())
01037 {
01038 fi = &(*it);
01039 ++it;
01040 if (fi->fileName() == "." || fi->fileName() == "..")
01041 continue;
01042 QString filename = fi->absoluteFilePath();
01043 if (!fi->isDir())
01044 {
01045 m_filelist.append(filename);
01046 }
01047 }
01048
01049 m_currentFile = 0;
01050 updateTypeSelector();
01051 updateStatus();
01052 }
01053
01054 void ImportCoverArtDialog::updateStatus()
01055 {
01056 if (m_filelist.size() > 0)
01057 {
01058 if (m_currentText)
01059 m_currentText->SetText(QString("%1 of %2").arg(m_currentFile + 1)
01060 .arg(m_filelist.size()));
01061 m_filenameText->SetText(m_filelist[m_currentFile]);
01062 m_coverartImage->SetFilename(m_filelist[m_currentFile]);
01063 m_coverartImage->Load();
01064
01065 QString saveFilename = gMusicData->musicDir + filenameFromMetadata(m_metadata, false);
01066 QFileInfo fi(saveFilename);
01067 QString saveDir = fi.absolutePath();
01068
01069 fi.setFile(m_filelist[m_currentFile]);
01070 switch (m_typeList->GetItemCurrent()->GetData().toInt())
01071 {
01072 case 0:
01073 saveFilename = "front." + fi.suffix();
01074 break;
01075 case 1:
01076 saveFilename = "back." + fi.suffix();
01077 break;
01078 case 2:
01079 saveFilename = "cd." + fi.suffix();
01080 break;
01081 case 3:
01082 saveFilename = "inlay." + fi.suffix();
01083 break;
01084 default:
01085 saveFilename = fi.fileName();
01086 }
01087
01088 m_saveFilename = saveDir + "/" + saveFilename;
01089 m_destinationText->SetText(m_saveFilename);
01090
01091 if (QFile::exists(m_saveFilename))
01092 m_statusText->SetText(tr("File Already Exists"));
01093 else
01094 m_statusText->SetText(tr("New File"));
01095 }
01096 else
01097 {
01098 if (m_currentText)
01099 m_currentText->Reset();
01100 m_statusText->Reset();
01101 m_filenameText->Reset();
01102 m_coverartImage->Reset();
01103 m_destinationText->Reset();
01104 }
01105 }
01106
01107 void ImportCoverArtDialog::updateTypeSelector()
01108 {
01109 if (m_filelist.size() == 0)
01110 return;
01111
01112 QString filename = m_filelist[m_currentFile];
01113 QFileInfo fi(filename);
01114 filename = fi.fileName();
01115
01116 if (filename.contains("front", Qt::CaseInsensitive) > 0)
01117 m_typeList->SetValue(tr("Front Cover"));
01118 else if (filename.contains("back", Qt::CaseInsensitive) > 0)
01119 m_typeList->SetValue(tr("Back Cover"));
01120 else if (filename.contains("inlay", Qt::CaseInsensitive) > 0)
01121 m_typeList->SetValue(tr("Inlay"));
01122 else if (filename.contains("cd", Qt::CaseInsensitive) > 0)
01123 m_typeList->SetValue(tr("CD"));
01124 else
01125 m_typeList->SetValue(tr("<Unknown>"));
01126 }