00001
00002 #include <QKeyEvent>
00003
00004
00005 #include <mythcontext.h>
00006 #include <mythdbcon.h>
00007 #include <mythuihelper.h>
00008 #include <mythdirs.h>
00009 #include <mythdialogbox.h>
00010 #include <mythuitextedit.h>
00011 #include <mythuitext.h>
00012 #include <mythuibutton.h>
00013 #include <mythuicheckbox.h>
00014 #include <mythuistatetype.h>
00015 #include <mythuibuttonlist.h>
00016 #include <mythuispinbox.h>
00017 #include <mythuiimage.h>
00018 #include <mythuiwebbrowser.h>
00019 #include <mythuifilebrowser.h>
00020
00021
00022 #include "decoder.h"
00023 #include "genres.h"
00024 #include "metaio.h"
00025 #include "musicplayer.h"
00026 #include "musicutils.h"
00027
00028 #include "editmetadata.h"
00029
00030
00031 bool EditMetadataCommon::metadataOnly = false;
00032 Metadata *EditMetadataCommon::m_metadata = NULL;
00033 Metadata *EditMetadataCommon::m_sourceMetadata = NULL;
00034
00035 EditMetadataCommon::EditMetadataCommon(MythScreenStack *parent,
00036 Metadata *source_metadata,
00037 const QString &name) :
00038 MythScreenType(parent, name), m_doneButton(NULL)
00039 {
00040
00041 m_metadata = new Metadata(*source_metadata);
00042 m_sourceMetadata = source_metadata;
00043
00044 metadataOnly = false;
00045 }
00046
00047 EditMetadataCommon::EditMetadataCommon(MythScreenStack *parent,
00048 const QString &name) :
00049 MythScreenType(parent, name), m_doneButton(NULL)
00050 {
00051 }
00052
00053 EditMetadataCommon::~EditMetadataCommon()
00054 {
00055 }
00056
00057 bool EditMetadataCommon::CreateCommon(void)
00058 {
00059 bool err = false;
00060
00061 UIUtilE::Assign(this, m_doneButton, "donebutton", &err);
00062
00063 connect(m_doneButton, SIGNAL(Clicked()), SLOT(showSaveMenu()));
00064
00065 return err;
00066 }
00067
00068 bool EditMetadataCommon::keyPressEvent(QKeyEvent *event)
00069 {
00070 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00071 return true;
00072
00073 bool handled = false;
00074 QStringList actions;
00075 handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions);
00076
00077 for (int i = 0; i < actions.size() && !handled; i++)
00078 {
00079 QString action = actions[i];
00080 handled = true;
00081
00082 if (action == "ESCAPE")
00083 showSaveMenu();
00084 else
00085 handled = false;
00086 }
00087
00088 if (!handled && MythScreenType::keyPressEvent(event))
00089 handled = true;
00090
00091 return handled;
00092 }
00093
00094 void EditMetadataCommon::updateMetadata()
00095 {
00096 MythUITextEdit *edit = NULL;
00097
00098 edit = dynamic_cast<MythUITextEdit *>(GetChild("albumedit"));
00099 if (edit)
00100 m_metadata->setAlbum(edit->GetText());
00101
00102 edit = dynamic_cast<MythUITextEdit *>(GetChild("artistedit"));
00103 if (edit)
00104 m_metadata->setArtist(edit->GetText());
00105
00106 edit = dynamic_cast<MythUITextEdit *>(GetChild("compartistedit"));
00107 if (edit)
00108 m_metadata->setCompilationArtist(edit->GetText());
00109
00110 edit = dynamic_cast<MythUITextEdit *>(GetChild("titleedit"));
00111 if (edit)
00112 m_metadata->setTitle(edit->GetText());
00113
00114 edit = dynamic_cast<MythUITextEdit *>(GetChild("genreedit"));
00115 if (edit)
00116 m_metadata->setGenre(edit->GetText());
00117
00118 MythUISpinBox *spin = dynamic_cast<MythUISpinBox *>(GetChild("yearspin"));
00119 if (spin)
00120 m_metadata->setYear(spin->GetIntValue());
00121
00122 spin = dynamic_cast<MythUISpinBox *>(GetChild("tracknumspin"));
00123 if (spin)
00124 m_metadata->setTrack(spin->GetIntValue());
00125
00126 spin = dynamic_cast<MythUISpinBox *>(GetChild("ratingspin"));
00127 if (spin)
00128 m_metadata->setRating(spin->GetIntValue());
00129
00130 MythUICheckBox *check = dynamic_cast<MythUICheckBox *>(GetChild("compilationcheck"));
00131 if (check)
00132 m_metadata->setCompilation(check->GetBooleanCheckState());
00133 }
00134
00135 void EditMetadataCommon::showSaveMenu()
00136 {
00137 updateMetadata();
00138
00139 if (!hasMetadataChanged())
00140 {
00141 Close();
00142 return;
00143 }
00144
00145 QString label = tr("Save Changes?");
00146
00147 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00148
00149 MythDialogBox *menu = new MythDialogBox(label, popupStack, "savechangesmenu");
00150
00151 if (!menu->Create())
00152 {
00153 delete menu;
00154 return;
00155 }
00156
00157 menu->SetReturnEvent(this, "savechangesmenu");
00158
00159 if (metadataOnly)
00160 menu->AddButton(tr("Save Changes"), SLOT(saveToMetadata()));
00161 else
00162 menu->AddButton(tr("Save Changes"), SLOT(saveAll()));
00163
00164 menu->AddButton(tr("Exit/Do Not Save"), SLOT(cleanupAndClose()));
00165
00166 popupStack->AddScreen(menu);
00167 }
00168
00169 void EditMetadataCommon::cleanupAndClose(void)
00170 {
00171 if (m_metadata)
00172 {
00173 delete m_metadata;
00174 m_metadata = NULL;
00175 }
00176
00177 Close();
00178 }
00179
00180 void EditMetadataCommon::saveToMetadata()
00181 {
00182 *m_sourceMetadata = *m_metadata;
00183 emit metadataChanged();
00184 cleanupAndClose();
00185 }
00186
00187 void EditMetadataCommon::saveToDatabase()
00188 {
00189 m_metadata->setAlbumId(-1);
00190 m_metadata->setGenreId(-1);
00191 m_metadata->setArtistId(-1);
00192
00193 m_metadata->dumpToDatabase();
00194 *m_sourceMetadata = *m_metadata;
00195
00196 gPlayer->sendMetadataChangedEvent(m_sourceMetadata->ID());
00197 }
00198
00199 void EditMetadataCommon::saveAll()
00200 {
00201 if (GetMythDB()->GetNumSetting("AllowTagWriting", 0))
00202 {
00203 MetaIO *tagger = m_metadata->getTagger();
00204
00205 if (tagger)
00206 tagger->write(m_metadata);
00207 }
00208
00209 saveToDatabase();
00210
00211 cleanupAndClose();
00212 }
00213
00214 void EditMetadataCommon::setSaveMetadataOnly(void)
00215 {
00216 metadataOnly = true;
00217
00218 MythUIButton *albumartButton = dynamic_cast<MythUIButton *>(GetChild("albumart_button"));
00219 if (albumartButton)
00220 albumartButton->Hide();
00221 }
00222
00223 bool EditMetadataCommon::hasMetadataChanged(void)
00224 {
00225 bool changed = false;
00226
00227 changed |= (m_metadata->Album() != m_sourceMetadata->Album());
00228 changed |= (m_metadata->Artist() != m_sourceMetadata->Artist());
00229 changed |= (m_metadata->CompilationArtist() != m_sourceMetadata->CompilationArtist());
00230 changed |= (m_metadata->Title() != m_sourceMetadata->Title());
00231 changed |= (m_metadata->Genre() != m_sourceMetadata->Genre());
00232 changed |= (m_metadata->Year() != m_sourceMetadata->Year());
00233 changed |= (m_metadata->Track() != m_sourceMetadata->Track());
00234 changed |= (m_metadata->Compilation() != m_sourceMetadata->Compilation());
00235 changed |= (m_metadata->Rating() != m_sourceMetadata->Rating());
00236
00237 return changed;
00238 }
00239
00241 void EditMetadataCommon::searchForAlbumImages(void)
00242 {
00243 QString artist = m_metadata->Artist().replace(' ', '+');
00244 artist = QUrl::toPercentEncoding(artist, "+");
00245
00246 QString album = m_metadata->Album().replace(' ', '+');
00247 album = QUrl::toPercentEncoding(album, "+");
00248
00249 QUrl url("http://www.google.co.uk/images?q=" + artist + "+" + album, QUrl::TolerantMode);
00250
00251 QFileInfo fi(m_metadata->Filename());
00252
00253 GetMythMainWindow()->HandleMedia("WebBrowser", url.toString(), fi.canonicalPath() + '/', "front.jpg");
00254 }
00255
00256 void EditMetadataCommon::scanForImages(void)
00257 {
00258
00259 AlbumArtList *imageList = m_metadata->getAlbumArtImages()->getImageList();
00260 while (!imageList->isEmpty())
00261 {
00262 delete imageList->back();
00263 imageList->pop_back();
00264 }
00265
00266
00267 QFileInfo fi(m_metadata->Filename());
00268 QDir dir = fi.absoluteDir();
00269
00270 QString nameFilter = gCoreContext->GetSetting("AlbumArtFilter",
00271 "*.png;*.jpg;*.jpeg;*.gif;*.bmp");
00272 dir.setNameFilters(nameFilter.split(";"));
00273
00274 QStringList files = dir.entryList();
00275
00276 for (int x = 0; x < files.size(); x++)
00277 {
00278 AlbumArtImage *image = new AlbumArtImage();
00279
00280 image->filename = dir.absolutePath() + '/' + files.at(x);
00281 image->embedded = false;
00282 image->imageType = AlbumArtImages::guessImageType(image->filename);
00283 image->description = "";
00284 m_metadata->getAlbumArtImages()->addImage(image);
00285 }
00286
00287
00288 MetaIO *tagger = m_metadata->getTagger();
00289
00290 if (tagger->supportsEmbeddedImages())
00291 {
00292 AlbumArtList art = tagger->getAlbumArtList(m_metadata->Filename());
00293 for (int x = 0; x < art.count(); x++)
00294 {
00295 AlbumArtImage image = art.at(x);
00296 m_metadata->getAlbumArtImages()->addImage(image);
00297 }
00298 }
00299 }
00300
00302
00303
00304 EditMetadataDialog::EditMetadataDialog(MythScreenStack *parent, Metadata *source_metadata)
00305 : EditMetadataCommon(parent, source_metadata, "EditMetadataDialog")
00306 {
00307 gCoreContext->addListener(this);
00308 }
00309
00310 EditMetadataDialog::EditMetadataDialog(MythScreenStack *parent)
00311 : EditMetadataCommon(parent, "EditMetadataDialog")
00312 {
00313 gCoreContext->addListener(this);
00314 }
00315
00316 EditMetadataDialog::~EditMetadataDialog()
00317 {
00318 gCoreContext->removeListener(this);
00319 }
00320
00321 bool EditMetadataDialog::Create(void)
00322 {
00323 if (! LoadWindowFromXML("music-ui.xml", "editmetadata", this))
00324 return false;
00325
00326 bool err = CreateCommon();
00327
00328 UIUtilE::Assign(this, m_titleEdit, "titleedit", &err);
00329 UIUtilE::Assign(this, m_artistEdit, "artistedit", &err);
00330 UIUtilE::Assign(this, m_compArtistEdit, "compartistedit", &err);
00331 UIUtilE::Assign(this, m_albumEdit, "albumedit", &err);
00332 UIUtilE::Assign(this, m_genreEdit, "genreedit", &err);
00333
00334 UIUtilE::Assign(this, m_yearSpin, "yearspin", &err);
00335 UIUtilE::Assign(this, m_trackSpin, "tracknumspin", &err);
00336
00337 UIUtilE::Assign(this, m_searchArtistButton, "searchartistbutton", &err);
00338 UIUtilE::Assign(this, m_searchCompArtistButton, "searchcompartistbutton", &err);
00339 UIUtilE::Assign(this, m_searchAlbumButton, "searchalbumbutton", &err);
00340 UIUtilE::Assign(this, m_searchGenreButton, "searchgenrebutton", &err);
00341
00342 UIUtilW::Assign(this, m_artistIcon, "artisticon", &err);
00343 UIUtilW::Assign(this, m_albumIcon, "albumicon", &err);
00344 UIUtilW::Assign(this, m_genreIcon, "genreicon", &err);
00345
00346 UIUtilW::Assign(this, m_ratingState, "ratingstate", &err);
00347 UIUtilW::Assign(this, m_ratingSpin, "ratingspin", &err);
00348
00349 UIUtilW::Assign(this, m_incRatingButton, "incratingbutton", &err);
00350 UIUtilW::Assign(this, m_decRatingButton, "decratingbutton", &err);
00351
00352 UIUtilE::Assign(this, m_compilationCheck, "compilationcheck", &err);
00353
00354 UIUtilE::Assign(this, m_albumartButton, "albumartbutton", &err);
00355
00356 if (err)
00357 {
00358 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'editmetadata'");
00359 return false;
00360 }
00361
00362 m_yearSpin->SetRange(0, 9999, 1);
00363 m_trackSpin->SetRange(0, 9999, 1);
00364
00365 if (m_ratingSpin)
00366 {
00367 m_ratingSpin->SetRange(0, 10, 1);
00368 connect(m_ratingSpin, SIGNAL(itemSelected(MythUIButtonListItem*)),
00369 SLOT(ratingSpinChanged(MythUIButtonListItem*)));
00370 }
00371
00372 connect(m_artistEdit, SIGNAL(LosingFocus()), SLOT(artistLostFocus()));
00373 connect(m_albumEdit, SIGNAL(LosingFocus()), SLOT(albumLostFocus()));
00374 connect(m_genreEdit, SIGNAL(LosingFocus()), SLOT(genreLostFocus()));
00375
00376 connect(m_searchArtistButton, SIGNAL(Clicked()), SLOT(searchArtist()));
00377 connect(m_searchCompArtistButton, SIGNAL(Clicked()), SLOT(searchCompilationArtist()));
00378 connect(m_searchAlbumButton, SIGNAL(Clicked()), SLOT(searchAlbum()));
00379 connect(m_searchGenreButton, SIGNAL(Clicked()), SLOT(searchGenre()));
00380
00381 if (m_incRatingButton && m_decRatingButton)
00382 {
00383 connect(m_incRatingButton, SIGNAL(Clicked()), SLOT(incRating()));
00384 connect(m_decRatingButton, SIGNAL(Clicked()), SLOT(decRating()));
00385 }
00386
00387 connect(m_compilationCheck, SIGNAL(toggled(bool)), SLOT(checkClicked(bool)));
00388
00389 connect(m_albumartButton, SIGNAL(Clicked()), SLOT(switchToAlbumArt()));
00390
00391 fillWidgets();
00392
00393 BuildFocusList();
00394
00395 return true;
00396 }
00397
00398 void EditMetadataDialog::fillWidgets()
00399 {
00400 m_compArtistEdit->SetText(m_metadata->CompilationArtist());
00401 m_albumEdit->SetText(m_metadata->Album());
00402 m_artistEdit->SetText(m_metadata->Artist());
00403 m_genreEdit->SetText(m_metadata->Genre());
00404 m_titleEdit->SetText(m_metadata->Title());
00405 m_yearSpin->SetValue(m_metadata->Year());
00406 m_trackSpin->SetValue(m_metadata->Track());
00407 m_compilationCheck->SetCheckState(m_metadata->Compilation());
00408
00409 updateRating();
00410
00411 updateArtistImage();
00412 updateAlbumImage();
00413 updateGenreImage();
00414 }
00415
00416 void EditMetadataDialog::incRating(void)
00417 {
00418 m_metadata->incRating();
00419 updateRating();
00420 }
00421
00422 void EditMetadataDialog::decRating(void)
00423 {
00424 m_metadata->decRating();
00425 updateRating();
00426 }
00427
00428 void EditMetadataDialog::ratingSpinChanged(MythUIButtonListItem *item)
00429 {
00430 if (item)
00431 {
00432 int rating = qVariantValue<int>(item->GetData());
00433 m_metadata->setRating(rating);
00434
00435 if (m_ratingState)
00436 m_ratingState->DisplayState(QString("%1").arg(m_metadata->Rating()));
00437 }
00438 }
00439
00440 void EditMetadataDialog::updateRating(void)
00441 {
00442 if (m_ratingState)
00443 m_ratingState->DisplayState(QString("%1").arg(m_metadata->Rating()));
00444
00445 if (m_ratingSpin)
00446 m_ratingSpin->SetValue(m_metadata->Rating());
00447 }
00448
00449 bool EditMetadataDialog::keyPressEvent(QKeyEvent *event)
00450 {
00451 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00452 return true;
00453
00454 bool handled = false;
00455 QStringList actions;
00456 handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions);
00457
00458 for (int i = 0; i < actions.size() && !handled; i++)
00459 {
00460 QString action = actions[i];
00461 handled = true;
00462
00463 if (action == "THMBUP")
00464 incRating();
00465 else if (action == "THMBDOWN")
00466 decRating();
00467 else if (action == "MENU")
00468 showMenu();
00469 else
00470 handled = false;
00471 }
00472
00473 if (!handled && EditMetadataCommon::keyPressEvent(event))
00474 handled = true;
00475
00476 return handled;
00477 }
00478
00479 void EditMetadataDialog::showMenu(void )
00480 {
00481 QString label = tr("Options");
00482
00483 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00484
00485 MythDialogBox *menu = new MythDialogBox(label, popupStack, "optionsmenu");
00486
00487 if (!menu->Create())
00488 {
00489 delete menu;
00490 return;
00491 }
00492
00493 menu->SetReturnEvent(this, "optionsmenu");
00494
00495 menu->AddButton(tr("Edit Albumart Images"));
00496 menu->AddButton(tr("Search Internet For Artist Image"));
00497 menu->AddButton(tr("Search Internet For Album Image"));
00498 menu->AddButton(tr("Search Internet For Genre Image"));
00499 menu->AddButton(tr("Check Track Length"));
00500
00501 popupStack->AddScreen(menu);
00502 }
00503
00504 void EditMetadataDialog::switchToAlbumArt()
00505 {
00506 updateMetadata();
00507
00508 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00509
00510 EditAlbumartDialog *editDialog = new EditAlbumartDialog(mainStack);
00511
00512 if (!editDialog->Create())
00513 {
00514 delete editDialog;
00515 return;
00516 }
00517
00518 mainStack->AddScreen(editDialog);
00519
00520 Close();
00521 }
00522
00523 void EditMetadataDialog::checkClicked(bool state)
00524 {
00525 if (!state)
00526 {
00527 if (m_compArtistEdit)
00528 m_compArtistEdit->SetText(m_metadata->Artist());
00529 }
00530 else
00531 {
00532 if (m_compArtistEdit->GetText().isEmpty() || m_compArtistEdit->GetText() == m_artistEdit->GetText())
00533 {
00534 if (m_compArtistEdit)
00535 m_compArtistEdit->SetText(tr("Various Artists"));
00536 }
00537 }
00538 }
00539
00540 void EditMetadataDialog::searchArtist()
00541 {
00542 QString msg = tr("Select an Artist");
00543 QStringList searchList = Metadata::fillFieldList("artist");
00544 QString s = m_metadata->Artist();
00545
00546 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00547 MythUISearchDialog *searchDlg = new MythUISearchDialog(popupStack, msg, searchList, false, s);
00548
00549 if (!searchDlg->Create())
00550 {
00551 delete searchDlg;
00552 return;
00553 }
00554
00555 connect(searchDlg, SIGNAL(haveResult(QString)), SLOT(setArtist(QString)));
00556
00557 popupStack->AddScreen(searchDlg);
00558 }
00559
00560 void EditMetadataDialog::setArtist(QString artist)
00561 {
00562 m_artistEdit->SetText(artist);
00563 updateArtistImage();
00564 }
00565
00566 void EditMetadataDialog::updateArtistImage(void)
00567 {
00568 QString artist = m_artistEdit->GetText();
00569
00570 QString file;
00571
00572 if (m_artistIcon)
00573 {
00574 file = findIcon("artist", artist.toLower());
00575 if (!file.isEmpty())
00576 {
00577 m_artistIcon->SetFilename(file);
00578 m_artistIcon->Load();
00579 }
00580 else
00581 m_artistIcon->Reset();
00582 }
00583 }
00584
00585 void EditMetadataDialog::searchCompilationArtist()
00586 {
00587 QString msg = tr("Select a Compilation Artist");
00588 QStringList searchList = Metadata::fillFieldList("compilation_artist");
00589 QString s = m_metadata->CompilationArtist();
00590
00591 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00592 MythUISearchDialog *searchDlg = new MythUISearchDialog(popupStack, msg, searchList, false, s);
00593
00594 if (!searchDlg->Create())
00595 {
00596 delete searchDlg;
00597 return;
00598 }
00599
00600 connect(searchDlg, SIGNAL(haveResult(QString)), SLOT(setCompArtist(QString)));
00601
00602 popupStack->AddScreen(searchDlg);
00603 }
00604
00605 void EditMetadataDialog::setCompArtist(QString compArtist)
00606 {
00607 m_compArtistEdit->SetText(compArtist);
00608 }
00609
00610 void EditMetadataDialog::searchAlbum()
00611 {
00612 QString msg = tr("Select an Album");
00613 QStringList searchList = Metadata::fillFieldList("album");
00614 QString s = m_metadata->Album();
00615
00616 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00617 MythUISearchDialog *searchDlg = new MythUISearchDialog(popupStack, msg, searchList, false, s);
00618
00619 if (!searchDlg->Create())
00620 {
00621 delete searchDlg;
00622 return;
00623 }
00624
00625 connect(searchDlg, SIGNAL(haveResult(QString)), SLOT(setAlbum(QString)));
00626
00627 popupStack->AddScreen(searchDlg);
00628 }
00629
00630 void EditMetadataDialog::setAlbum(QString album)
00631 {
00632 m_albumEdit->SetText(album);
00633 updateAlbumImage();
00634 }
00635
00636 void EditMetadataDialog::updateAlbumImage(void)
00637 {
00638 QString file;
00639
00640 if (m_albumIcon)
00641 {
00642 file = m_metadata->getAlbumArtFile();
00643 if (!file.isEmpty())
00644 {
00645 m_albumIcon->SetFilename(file);
00646 m_albumIcon->Load();
00647 }
00648 else
00649 m_albumIcon->Reset();
00650 }
00651 }
00652
00653 void EditMetadataDialog::searchGenre()
00654 {
00655 QString msg = tr("Select a Genre");
00656 QStringList searchList = Metadata::fillFieldList("genre");
00657
00658
00659
00660
00661
00662
00663
00664
00665 QString s = m_metadata->Genre();
00666
00667 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00668 MythUISearchDialog *searchDlg = new MythUISearchDialog(popupStack, msg, searchList, false, s);
00669
00670 if (!searchDlg->Create())
00671 {
00672 delete searchDlg;
00673 return;
00674 }
00675
00676 connect(searchDlg, SIGNAL(haveResult(QString)), SLOT(setGenre(QString)));
00677
00678 popupStack->AddScreen(searchDlg);
00679 }
00680
00681 void EditMetadataDialog::setGenre(QString genre)
00682 {
00683 m_genreEdit->SetText(genre);
00684 updateGenreImage();
00685 }
00686
00687 void EditMetadataDialog::updateGenreImage(void)
00688 {
00689 QString genre = m_genreEdit->GetText();
00690 QString file;
00691
00692 if (m_genreIcon)
00693 {
00694 file = findIcon("genre", genre.toLower());
00695 if (!file.isEmpty())
00696 {
00697 m_genreIcon->SetFilename(file);
00698 m_genreIcon->Load();
00699 }
00700 else
00701 m_genreIcon->Reset();
00702 }
00703 }
00704
00705 void EditMetadataDialog::artistLostFocus(void)
00706 {
00707 updateArtistImage();
00708 }
00709
00710 void EditMetadataDialog::albumLostFocus(void)
00711 {
00712 updateAlbumImage();
00713 }
00714
00715 void EditMetadataDialog::genreLostFocus(void)
00716 {
00717 updateGenreImage();
00718 }
00719
00721 void EditMetadataDialog::searchForGenreImages(void)
00722 {
00723 QString genre= m_metadata->Genre().replace(' ', '+');
00724 genre = QUrl::toPercentEncoding(genre, "+");
00725
00726 QUrl url("http://www.flickr.com/search/groups/?w=908425%40N22&m=pool&q=" + genre, QUrl::TolerantMode);
00727
00728 QString cleanName = fixFilename(m_metadata->Genre().toLower());
00729 QString file = GetConfDir() + QString("/MythMusic/Icons/%1/%2.jpg").arg("genre").arg(cleanName);
00730
00731 QFileInfo fi(file);
00732 GetMythMainWindow()->HandleMedia("WebBrowser", url.toString(), fi.absolutePath() + '/', fi.fileName());
00733 }
00734
00736 void EditMetadataDialog::searchForArtistImages(void)
00737 {
00738 QString artist = m_metadata->Artist().replace(' ', '+');
00739 artist = QUrl::toPercentEncoding(artist, "+");
00740
00741 QUrl url("http://www.google.co.uk/images?q=" + artist, QUrl::TolerantMode);
00742
00743 QString cleanName = fixFilename(m_metadata->Artist().toLower());
00744 QString file = GetConfDir() + QString("/MythMusic/Icons/%1/%2.jpg").arg("artist").arg(cleanName);
00745
00746 QFileInfo fi(file);
00747 GetMythMainWindow()->HandleMedia("WebBrowser", url.toString(), fi.absolutePath() + '/', fi.fileName());
00748 }
00749
00750 void EditMetadataDialog::customEvent(QEvent *event)
00751 {
00752 if (event->type() == DialogCompletionEvent::kEventType)
00753 {
00754 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
00755
00756
00757 if (dce->GetResult() < 0)
00758 return;
00759
00760 QString resultid = dce->GetId();
00761 QString resulttext = dce->GetResultText();
00762
00763
00764 if (resultid == "optionsmenu")
00765 {
00766 if (resulttext == tr("Edit Albumart Images"))
00767 switchToAlbumArt();
00768 else if (resulttext == tr("Search Internet For Genre Image"))
00769 {
00770 updateMetadata();
00771 searchForGenreImages();
00772 }
00773 else if (resulttext == tr("Search Internet For Artist Image"))
00774 {
00775 updateMetadata();
00776 searchForArtistImages();
00777 }
00778 else if (resulttext == tr("Search Internet For Album Image"))
00779 {
00780 updateMetadata();
00781 searchForAlbumImages();
00782 }
00783 else if (resulttext == tr("Check Track Length"))
00784 {
00785 int length = calcTrackLength(m_metadata->Filename());
00786
00787 if (length != m_metadata->Length() / 1000)
00788 {
00789 int oldLength = m_metadata->Length() / 1000;
00790
00791
00792 m_metadata->setLength(length * 1000);
00793
00794
00795 m_sourceMetadata->setLength(length * 1000);
00796 m_sourceMetadata->dumpToDatabase();
00797
00798
00799 gPlayer->sendMetadataChangedEvent(m_sourceMetadata->ID());
00800
00801
00802 MusicPlayerEvent me(MusicPlayerEvent::TrackChangeEvent, gPlayer->getCurrentTrackPos());
00803 gPlayer->dispatch(me);
00804
00805 ShowOkPopup(QString("Updated track length to %1 seconds\nwas %2 seconds").arg(length).arg(oldLength));
00806 }
00807 }
00808 }
00809 }
00810 else if (event->type() == MythEvent::MythEventMessage)
00811 {
00812 MythEvent *me = (MythEvent *)event;
00813 QStringList tokens = me->Message().split(" ", QString::SkipEmptyParts);
00814
00815 if (!tokens.isEmpty())
00816 {
00817 if (tokens[0] == "BROWSER_DOWNLOAD_FINISHED")
00818 {
00819 scanForImages();
00820
00821
00822 updateAlbumImage();
00823 updateArtistImage();
00824 updateGenreImage();
00825
00826 m_metadata->getAlbumArtImages()->dumpToDatabase();
00827
00828 MetadataPtrList *allMusic = gMusicData->all_music->getAllMetadata();
00829 for (int x = 0; x < allMusic->count(); x++)
00830 {
00831 if ((allMusic->at(x)->ID() == m_sourceMetadata->ID()) ||
00832 (allMusic->at(x)->getDirectoryId() == m_sourceMetadata->getDirectoryId()))
00833 {
00834 allMusic->at(x)->reloadAlbumArtImages();
00835 gPlayer->sendAlbumArtChangedEvent(allMusic->at(x)->ID());
00836 }
00837 }
00838 }
00839 }
00840 }
00841 }
00842
00844
00845
00846 EditAlbumartDialog::EditAlbumartDialog(MythScreenStack *parent)
00847 : EditMetadataCommon(parent, "EditAlbumartDialog")
00848 {
00849 m_albumArtChanged = false;
00850 m_albumArt = m_metadata->getAlbumArtImages();
00851
00852 gCoreContext->addListener(this);
00853 }
00854
00855 EditAlbumartDialog::~EditAlbumartDialog()
00856 {
00857
00858 if (m_albumArtChanged)
00859 {
00860 m_albumArt->dumpToDatabase();
00861
00862
00863 MetadataPtrList *allMusic = gMusicData->all_music->getAllMetadata();
00864 for (int x = 0; x < allMusic->count(); x++)
00865 {
00866 if ((allMusic->at(x)->ID() == m_sourceMetadata->ID()) ||
00867 (allMusic->at(x)->getDirectoryId() == m_sourceMetadata->getDirectoryId()))
00868 {
00869 allMusic->at(x)->reloadAlbumArtImages();
00870 gPlayer->sendAlbumArtChangedEvent(allMusic->at(x)->ID());
00871 }
00872 }
00873 }
00874
00875 gCoreContext->removeListener(this);
00876 }
00877
00878 bool EditAlbumartDialog::Create(void)
00879 {
00880 if (! LoadWindowFromXML("music-ui.xml", "editalbumart", this))
00881 return false;
00882
00883 bool err = CreateCommon();
00884
00885 UIUtilE::Assign(this, m_coverartList, "coverartlist", &err);
00886 UIUtilE::Assign(this, m_imagetypeText, "imagetypetext", &err);
00887 UIUtilE::Assign(this, m_imagefilenameText, "imagefilenametext", &err);
00888 UIUtilE::Assign(this, m_coverartImage, "coverartimage", &err);
00889
00890 UIUtilE::Assign(this, m_metadataButton, "metadatabutton", &err);
00891
00892 if (err)
00893 {
00894 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'editalbumart'");
00895 return false;
00896 }
00897
00898 updateImageGrid();
00899
00900 connect(m_coverartList, SIGNAL(itemSelected(MythUIButtonListItem*)),
00901 this, SLOT(gridItemChanged(MythUIButtonListItem*)));
00902
00903 connect(m_metadataButton, SIGNAL(Clicked()), SLOT(switchToMetadata()));
00904
00905 BuildFocusList();
00906
00907 return true;
00908 }
00909
00910 void EditAlbumartDialog::gridItemChanged(MythUIButtonListItem *item)
00911 {
00912 if (!item)
00913 return;
00914
00915 if (m_coverartImage)
00916 {
00917 AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData());
00918 if (image)
00919 {
00920 m_coverartImage->SetFilename(image->filename);
00921 m_coverartImage->Load();
00922 if (m_imagetypeText)
00923 m_imagetypeText->SetText(AlbumArtImages::getTypeName(image->imageType));
00924 if (m_imagefilenameText)
00925 {
00926 QFileInfo fi(image->filename);
00927 m_imagefilenameText->SetText(fi.fileName());
00928 }
00929 }
00930 }
00931 }
00932
00933 void EditAlbumartDialog::updateImageGrid(void)
00934 {
00935 AlbumArtList *albumArtList = m_albumArt->getImageList();
00936
00937 m_coverartList->Reset();
00938
00939 for (int x = 0; x < albumArtList->size(); x++)
00940 {
00941 MythUIButtonListItem *item =
00942 new MythUIButtonListItem(m_coverartList,
00943 AlbumArtImages::getTypeName(albumArtList->at(x)->imageType),
00944 qVariantFromValue(albumArtList->at(x)));
00945 item->SetImage(albumArtList->at(x)->filename);
00946 QString state = albumArtList->at(x)->embedded ? "tag" : "file";
00947 item->DisplayState(state, "locationstate");
00948 }
00949 }
00950
00951 bool EditAlbumartDialog::keyPressEvent(QKeyEvent *event)
00952 {
00953 if (GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00954 return true;
00955
00956 bool handled = false;
00957 QStringList actions;
00958 handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions);
00959
00960 for (int i = 0; i < actions.size() && !handled; i++)
00961 {
00962 QString action = actions[i];
00963 handled = true;
00964
00965 if (action == "MENU")
00966 showMenu();
00967 else if (action == "INFO")
00968 showTypeMenu();
00969 else if (action == "ESCAPE")
00970 showSaveMenu();
00971 else
00972 handled = false;
00973 }
00974
00975 if (!handled && MythScreenType::keyPressEvent(event))
00976 handled = true;
00977
00978 return handled;
00979 }
00980
00981 void EditAlbumartDialog::switchToMetadata(void)
00982 {
00983 MythScreenStack *mainStack = GetMythMainWindow()->GetMainStack();
00984
00985 EditMetadataDialog *editDialog = new EditMetadataDialog(mainStack);
00986
00987 if (!editDialog->Create())
00988 {
00989 delete editDialog;
00990 return;
00991 }
00992
00993 mainStack->AddScreen(editDialog);
00994
00995 Close();
00996 }
00997
00998 void EditAlbumartDialog::showTypeMenu(bool changeType)
00999 {
01000 if (changeType && m_coverartList->GetCount() == 0)
01001 return;
01002
01003 QString label;
01004
01005 if (changeType)
01006 label = tr("Change Image Type");
01007 else
01008 label = tr("What image type do you want to use for this image?");
01009
01010 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
01011
01012 MythDialogBox *menu = new MythDialogBox(label, popupStack, "typemenu");
01013
01014 if (!menu->Create())
01015 {
01016 delete menu;
01017 return;
01018 }
01019
01020 ImageType imageType = IT_UNKNOWN;
01021 if (changeType)
01022 menu->SetReturnEvent(this, "changetypemenu");
01023 else
01024 {
01025 menu->SetReturnEvent(this, "asktypemenu");
01026 imageType = AlbumArtImages::guessImageType(m_imageFilename);
01027 }
01028
01029 menu->AddButton(m_albumArt->getTypeName(IT_UNKNOWN), qVariantFromValue((int)IT_UNKNOWN), false, (imageType == IT_UNKNOWN));
01030 menu->AddButton(m_albumArt->getTypeName(IT_FRONTCOVER), qVariantFromValue((int)IT_FRONTCOVER), false, (imageType == IT_FRONTCOVER));
01031 menu->AddButton(m_albumArt->getTypeName(IT_BACKCOVER), qVariantFromValue((int)IT_BACKCOVER), false, (imageType == IT_BACKCOVER));
01032 menu->AddButton(m_albumArt->getTypeName(IT_CD), qVariantFromValue((int)IT_CD), false, (imageType == IT_CD));
01033 menu->AddButton(m_albumArt->getTypeName(IT_INLAY), qVariantFromValue((int)IT_INLAY), false, (imageType == IT_INLAY));
01034 menu->AddButton(m_albumArt->getTypeName(IT_ARTIST), qVariantFromValue((int)IT_ARTIST), false, (imageType == IT_ARTIST));
01035
01036 popupStack->AddScreen(menu);
01037 }
01038
01039 void EditAlbumartDialog::showMenu(void )
01040 {
01041 QString label = tr("Options");
01042
01043 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
01044
01045 MythDialogBox *menu = new MythDialogBox(label, popupStack, "optionsmenu");
01046
01047 if (!menu->Create())
01048 {
01049 delete menu;
01050 return;
01051 }
01052
01053 menu->SetReturnEvent(this, "optionsmenu");
01054
01055 menu->AddButton(tr("Edit Metadata"));
01056 menu->AddButton(tr("Rescan For Images"));
01057 menu->AddButton(tr("Search Internet For Images"));
01058
01059 if (m_coverartList->GetItemCurrent())
01060 {
01061 menu->AddButton(tr("Change Image Type"), NULL, true);
01062
01063 if (GetMythDB()->GetNumSetting("AllowTagWriting", 0))
01064 {
01065 MythUIButtonListItem *item = m_coverartList->GetItemCurrent();
01066 if (item)
01067 {
01068 AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData());
01069 if (image)
01070 {
01071 if (!image->embedded)
01072 {
01073 if (m_metadata->getTagger()->supportsEmbeddedImages())
01074 menu->AddButton(tr("Copy Selected Image To Tag"));
01075 }
01076 else
01077 {
01078 if (m_metadata->getTagger()->supportsEmbeddedImages())
01079 menu->AddButton(tr("Remove Selected Image From Tag"));
01080 }
01081 }
01082 }
01083 }
01084 }
01085
01086 if (GetMythDB()->GetNumSetting("AllowTagWriting", 0))
01087 {
01088 if (m_metadata->getTagger()->supportsEmbeddedImages())
01089 menu->AddButton(tr("Copy Image To Tag"));
01090 }
01091
01092 popupStack->AddScreen(menu);
01093 }
01094
01095 void EditAlbumartDialog::customEvent(QEvent *event)
01096 {
01097 if (event->type() == DialogCompletionEvent::kEventType)
01098 {
01099 DialogCompletionEvent *dce = (DialogCompletionEvent*)(event);
01100
01101
01102 if (dce->GetResult() < 0)
01103 return;
01104
01105 QString resultid = dce->GetId();
01106 QString resulttext = dce->GetResultText();
01107
01108 if (resultid == "changetypemenu")
01109 {
01110 int type = dce->GetData().toInt();
01111
01112 if ((type >= IT_UNKNOWN) && (type < IT_LAST))
01113 {
01114
01115 MythUIButtonListItem *item = m_coverartList->GetItemCurrent();
01116 if (item)
01117 {
01118 item->SetText(m_albumArt->getTypeName((ImageType) type));
01119 AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData());
01120 if (image)
01121 {
01122 AlbumArtImage oldImage = *image;
01123
01124 image->imageType = (ImageType) type;
01125
01126 if (image->imageType == oldImage.imageType)
01127 return;
01128
01129
01130 if (image->embedded)
01131 {
01132
01133 image->filename = QString(GetConfDir() + "/MythMusic/AlbumArt/%1-%2.jpg")
01134 .arg(m_metadata->ID())
01135 .arg(AlbumArtImages::getTypeFilename(image->imageType));
01136
01137 if (image->filename != oldImage.filename && QFile::exists(oldImage.filename))
01138 {
01139
01140 QFile::remove(image->filename);
01141
01142 QFile::rename(oldImage.filename, image->filename);
01143
01144
01145 GetMythUI()->RemoveFromCacheByFile(image->filename);
01146 }
01147
01148
01149 MetaIO *tagger = m_metadata->getTagger();
01150
01151 if (tagger && tagger->supportsEmbeddedImages())
01152 {
01153 if (!tagger->changeImageType(m_metadata->Filename(), &oldImage, image->imageType))
01154 LOG(VB_GENERAL, LOG_INFO, "EditAlbumartDialog: failed to change image type");
01155 }
01156 }
01157 else
01158 {
01159 QFileInfo fi(oldImage.filename);
01160
01161
01162 image->filename = QString(fi.absolutePath() + "/%1.jpg")
01163 .arg(AlbumArtImages::getTypeFilename(image->imageType));
01164
01165 if (image->filename != oldImage.filename && QFile::exists(oldImage.filename))
01166 {
01167
01168 QFile::remove(image->filename);
01169
01170 QFile::rename(oldImage.filename, image->filename);
01171
01172
01173 GetMythUI()->RemoveFromCacheByFile(image->filename);
01174 }
01175 }
01176
01177 m_albumArtChanged = true;
01178
01179 gridItemChanged(item);
01180 }
01181 }
01182 }
01183 }
01184 else if (resultid == "asktypemenu")
01185 {
01186 int type = dce->GetData().toInt();
01187
01188 if ((type >= IT_UNKNOWN) && (type < IT_LAST))
01189 copyImageToTag((ImageType) type);
01190 }
01191 else if (resultid == "optionsmenu")
01192 {
01193 if (resulttext == tr("Edit Metadata"))
01194 switchToMetadata();
01195 else if (resulttext == tr("Rescan For Images"))
01196 rescanForImages();
01197 else if (resulttext == tr("Search Internet For Images"))
01198 searchForAlbumImages();
01199 else if (resulttext == tr("Change Image Type"))
01200 showTypeMenu();
01201 else if (resulttext == tr("Copy Selected Image To Tag"))
01202 copySelectedImageToTag();
01203 else if (resulttext == tr("Remove Selected Image From Tag"))
01204 removeSelectedImageFromTag();
01205 else if (resulttext == tr("Copy Image To Tag"))
01206 startCopyImageToTag();
01207 }
01208 else if (resultid == "imagelocation")
01209 {
01210 m_imageFilename = resulttext;
01211
01212
01213 QFileInfo fi(m_imageFilename);
01214 gCoreContext->SaveSetting("MusicLastImageLocation", fi.canonicalPath());
01215
01216 showTypeMenu(false);
01217 }
01218 }
01219 else if (event->type() == MythEvent::MythEventMessage)
01220 {
01221 MythEvent *me = (MythEvent *)event;
01222 QStringList tokens = me->Message().split(" ", QString::SkipEmptyParts);
01223
01224 if (!tokens.isEmpty())
01225 {
01226 if (tokens[0] == "BROWSER_DOWNLOAD_FINISHED")
01227 rescanForImages();
01228 }
01229 }
01230 }
01231
01233 void EditAlbumartDialog::rescanForImages(void)
01234 {
01235
01236 scanForImages();
01237
01238 updateImageGrid();
01239
01240 if (m_albumArt->getImageCount() > 0)
01241 m_albumArtChanged = true;
01242 }
01243
01244 void EditAlbumartDialog::startCopyImageToTag(void)
01245 {
01246 QString lastLocation = gCoreContext->GetSetting("MusicLastImageLocation", "/");
01247
01248 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
01249 MythUIFileBrowser *fb = new MythUIFileBrowser(popupStack, lastLocation);
01250
01251 fb->SetTypeFilter(QDir::AllDirs | QDir::Files | QDir::Readable);
01252
01253 QStringList filters;
01254 filters << "*.png" << "*.jpg" << "*.jpeg" << "*.gif";
01255 fb->SetNameFilter(filters);
01256
01257 if (fb->Create())
01258 {
01259 fb->SetReturnEvent(this, "imagelocation");
01260 popupStack->AddScreen(fb);
01261 }
01262 else
01263 delete fb;
01264 }
01265
01266 void EditAlbumartDialog::copyImageToTag(ImageType imageType)
01267 {
01268 AlbumArtImage image;
01269 image.filename = m_imageFilename;
01270 image.imageType = imageType;
01271
01272 doCopyImageToTag(&image);
01273 }
01274
01275 void EditAlbumartDialog::copySelectedImageToTag(void)
01276 {
01277 MythUIButtonListItem *item = m_coverartList->GetItemCurrent();
01278 if (item)
01279 {
01280 AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData());
01281 if (image)
01282 doCopyImageToTag(image);
01283 }
01284 }
01285
01286 void EditAlbumartDialog::removeSelectedImageFromTag(void)
01287 {
01288 MythUIButtonListItem *item = m_coverartList->GetItemCurrent();
01289 if (item)
01290 {
01291 AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData());
01292 if (image)
01293 {
01294 QString msg = tr("Are you sure you want to permanently remove this image from the tag?");
01295 ShowOkPopup(msg, this, SLOT(doRemoveImageFromTag(bool)), true);
01296 }
01297 }
01298 }
01299
01300 void EditAlbumartDialog::doRemoveImageFromTag(bool doIt)
01301 {
01302 if (!doIt)
01303 return;
01304
01305 MythUIButtonListItem *item = m_coverartList->GetItemCurrent();
01306 if (item)
01307 {
01308 AlbumArtImage *image = qVariantValue<AlbumArtImage*> (item->GetData());
01309 if (image)
01310 {
01311 MetaIO *tagger = m_metadata->getTagger();
01312
01313 if (!tagger->supportsEmbeddedImages())
01314 {
01315 LOG(VB_GENERAL, LOG_ERR, "EditAlbumartDialog: asked to remove an image from the tag "
01316 "but the tagger doesn't support it!");
01317 return;
01318 }
01319
01320 if (!tagger->removeAlbumArt(m_metadata->Filename(), image))
01321 LOG(VB_GENERAL, LOG_ERR, "EditAlbumartDialog: failed to remove album art from tag");
01322 else
01323 LOG(VB_GENERAL, LOG_INFO, "EditAlbumartDialog: album art removed from tag");
01324
01325 removeCachedImage(image);
01326 rescanForImages();
01327 }
01328 }
01329 }
01330
01331 void EditAlbumartDialog::doCopyImageToTag(const AlbumArtImage *image)
01332 {
01333 MetaIO *tagger = m_metadata->getTagger();
01334
01335 if (!tagger->supportsEmbeddedImages())
01336 {
01337 LOG(VB_GENERAL, LOG_ERR, "EditAlbumartDialog: asked to write album art to the tag "
01338 "but the tagger does't support it!");
01339 return;
01340 }
01341
01342 if (!tagger->writeAlbumArt(m_metadata->Filename(), image))
01343 LOG(VB_GENERAL, LOG_ERR, "EditAlbumartDialog: failed to write album art to tag");
01344 else
01345 LOG(VB_GENERAL, LOG_INFO, "EditAlbumartDialog: album art written to tag");
01346
01347 removeCachedImage(image);
01348
01349 rescanForImages();
01350 }
01351
01352 void EditAlbumartDialog::removeCachedImage(const AlbumArtImage *image)
01353 {
01354 if (!image->embedded)
01355 return;
01356
01357 QString imageFilename = QString(GetConfDir() + "/MythMusic/AlbumArt/%1-%2.jpg")
01358 .arg(m_metadata->ID()).arg(AlbumArtImages::getTypeFilename(image->imageType));
01359
01360 if (QFile::exists(imageFilename))
01361 QFile::remove(imageFilename);
01362
01363 GetMythUI()->RemoveFromCacheByFile(imageFilename);
01364 }