MythTV  0.26-pre
importmusic.cpp
Go to the documentation of this file.
00001 // qt
00002 #include <QDir>
00003 #include <QFontMetrics>
00004 #include <QApplication>
00005 
00006 // myth
00007 #include <mythcontext.h>
00008 #include <mythdbcon.h>
00009 #include <audiooutput.h>
00010 
00011 // mythmusic
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     // GUI stuff
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     // default metadata values
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     // do we need to do a resync
00133     if (m_somethingWasImported)
00134         emit importFinished();
00135 }
00136 
00137 void ImportMusicDialog::fillWidgets()
00138 {
00139     if (!m_tracks->empty())
00140     {
00141         // update current
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         // update current
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     // TODO Install a name filter on supported music formats
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     // is the current track a new file?
00404     if (m_tracks->at(m_currentTrack)->isNewTune)
00405     {
00406         // get the save filename - this also creates the correct directory stucture
00407         QString saveFilename = filenameFromMetadata(meta);
00408 
00409         // we need to manually copy the file extension
00410         QFileInfo fi(meta->Filename());
00411         saveFilename += "." + fi.suffix();
00412 
00413         // copy the file to the new location
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         // do we need to update the tags?
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         // update the database
00435         meta->dumpToDatabase();
00436 
00437         // read any embedded images from the tag
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         // update the UI
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     //  GUI stuff
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 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends