00001 #include <mythtv/mythcontext.h>
00002 #include <mythtv/mythdbcon.h>
00003 #include <qdir.h>
00004 #include "editmetadata.h"
00005 #include "decoder.h"
00006 #include "genres.h"
00007 #include "metadata.h"
00008
00009 EditMetadataDialog::EditMetadataDialog(Metadata *source_metadata,
00010 MythMainWindow *parent,
00011 QString window_name,
00012 QString theme_filename,
00013 const char* name)
00014 :MythThemedDialog(parent, window_name, theme_filename, name)
00015 {
00016
00017 m_metadata = new Metadata(*source_metadata);
00018 m_sourceMetadata = source_metadata;
00019 albumArt = new AlbumArtImages(m_metadata);
00020 metadataOnly = false;
00021 setContext(1);
00022 wireUpTheme();
00023 fillWidgets();
00024 assignFirstFocus();
00025 }
00026
00027 EditMetadataDialog::~EditMetadataDialog()
00028 {
00029 delete m_metadata;
00030 delete albumArt;
00031 }
00032
00033 void EditMetadataDialog::fillWidgets()
00034 {
00035 if (album_edit)
00036 {
00037 album_edit->setText(m_metadata->Album());
00038 }
00039
00040 if (artist_edit)
00041 {
00042 artist_edit->setText(m_metadata->Artist());
00043 }
00044
00045 if (compilation_artist_edit)
00046 {
00047 compilation_artist_edit->setText(m_metadata->CompilationArtist());
00048 }
00049
00050 if (title_edit)
00051 {
00052 title_edit->setText(m_metadata->Title());
00053 }
00054
00055 if (genre_edit)
00056 {
00057 genre_edit->setText(m_metadata->Genre());
00058 }
00059
00060 if (year_edit)
00061 {
00062 QString s;
00063 s = s.setNum(m_metadata->Year());
00064 year_edit->setText(s);
00065 }
00066
00067 if (track_edit)
00068 {
00069 QString s;
00070 s = s.setNum(m_metadata->Track());
00071 track_edit->setText(s);
00072 }
00073
00074 if (playcount_text)
00075 {
00076 QString s;
00077 s = s.setNum(m_metadata->Playcount());
00078 playcount_text->SetText(s);
00079 }
00080
00081 if (lastplay_text)
00082 {
00083 QString timestamp = m_metadata->LastPlayStr();
00084
00085 if (timestamp.contains('-') < 1)
00086 {
00087 timestamp.insert(4, '-');
00088 timestamp.insert(7, '-');
00089 timestamp.insert(10, 'T');
00090 timestamp.insert(13, ':');
00091 timestamp.insert(16, ':');
00092 }
00093
00094 QDateTime dt = QDateTime::fromString(timestamp, Qt::ISODate);
00095 lastplay_text->SetText(dt.toString(gContext->GetSetting("dateformat") +
00096 " " + gContext->GetSetting("timeformat")));
00097 }
00098
00099 if (filename_text)
00100 {
00101 filename_text->SetText(m_metadata->Filename());
00102 }
00103
00104 if (rating_image)
00105 {
00106 rating_image->setRepeat(m_metadata->Rating());
00107 }
00108
00109 if (compilation_check)
00110 {
00111 compilation_check->setState(m_metadata->Compilation());
00112 }
00113
00114 if (coverart_grid)
00115 {
00116 updateImageGrid();
00117 }
00118 }
00119
00120 void EditMetadataDialog::gridItemChanged(ImageGridItem *item)
00121 {
00122 if (!item)
00123 return;
00124
00125 if (coverart_image)
00126 {
00127 AlbumArtImage *image = (AlbumArtImage*) item->data;
00128 if (image)
00129 {
00130 coverart_image->SetImage(image->filename);
00131 coverart_image->LoadImage();
00132 if (imagetype_text)
00133 imagetype_text->SetText(image->typeName);
00134 if (imagefilename_text)
00135 {
00136 QFileInfo fi(image->filename);
00137 imagefilename_text->SetText(fi.fileName());
00138 }
00139 }
00140 }
00141 }
00142
00143 void EditMetadataDialog::updateImageGrid()
00144 {
00145 QPtrList<AlbumArtImage> *albumArtList = albumArt->getImageList();
00146
00147 QSize size = coverart_grid->getImageItemSize();
00148
00149 for (uint x = 0; x < albumArtList->count(); x++)
00150 {
00151 if (albumArtList->at(x)->embedded)
00152 continue;
00153
00154 QPixmap *pixmap = createScaledPixmap(albumArtList->at(x)->filename,
00155 size.width(), size.height(),
00156 QImage::ScaleMin);
00157
00158 ImageGridItem *item = new ImageGridItem(albumArtList->at(x)->typeName,
00159 pixmap, false, (void*) albumArtList->at(x));
00160 coverart_grid->appendItem(item);
00161 }
00162
00163 coverart_grid->setItemCount(albumArtList->count());
00164 coverart_grid->recalculateLayout();
00165
00166 if (albumArtList->count() > 0)
00167 gridItemChanged(coverart_grid->getItemAt(0));
00168
00169 coverart_grid->refresh();
00170 }
00171
00172 QPixmap *EditMetadataDialog::createScaledPixmap(QString filename,
00173 int width, int height, QImage::ScaleMode mode)
00174 {
00175 QPixmap *pixmap = NULL;
00176
00177 if (filename != "")
00178 {
00179 QImage *img = gContext->LoadScaleImage(filename);
00180 if (!img)
00181 {
00182 VERBOSE(VB_IMPORTANT, QString("EditMetadataDialog: Failed to load image %1").arg(filename));
00183 return NULL;
00184 }
00185 else
00186 {
00187 pixmap = new QPixmap(img->smoothScale(width, height, mode));
00188 delete img;
00189 }
00190 }
00191
00192 return pixmap;
00193 }
00194
00195 void EditMetadataDialog::incRating(bool up_or_down)
00196 {
00197 if (up_or_down)
00198 m_metadata->incRating();
00199 else
00200 m_metadata->decRating();
00201
00202 fillWidgets();
00203 }
00204
00205 void EditMetadataDialog::keyPressEvent(QKeyEvent *e)
00206 {
00207 bool handled = false;
00208
00209 QStringList actions;
00210 gContext->GetMainWindow()->TranslateKeyPress("Global", e, actions);
00211
00212 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00213 {
00214 QString action = actions[i];
00215 handled = true;
00216
00217 if (action == "UP")
00218 {
00219 if (getCurrentFocusWidget() == coverart_grid)
00220 {
00221
00222 if (coverart_grid->handleKeyPress(action))
00223 return;
00224 }
00225 else
00226 nextPrevWidgetFocus(false);
00227 }
00228 else if (action == "DOWN")
00229 {
00230 if (getCurrentFocusWidget() == coverart_grid)
00231 {
00232
00233 if (coverart_grid->handleKeyPress(action))
00234 return;
00235 }
00236 else
00237 nextPrevWidgetFocus(true);
00238 }
00239 else if (action == "LEFT")
00240 {
00241 if (getCurrentFocusWidget() == rating_button)
00242 {
00243 rating_button->push();
00244 incRating(false);
00245 }
00246 else if (getCurrentFocusWidget() == compilation_check)
00247 {
00248 compilation_check->activate();
00249 }
00250 else
00251 nextPrevWidgetFocus(false);
00252 }
00253 else if (action == "RIGHT")
00254 {
00255 if (getCurrentFocusWidget() == rating_button)
00256 {
00257 rating_button->push();
00258 incRating(true);
00259 }
00260 else if (getCurrentFocusWidget() == compilation_check)
00261 {
00262 compilation_check->activate();
00263 }
00264 else
00265 nextPrevWidgetFocus(true);
00266 }
00267 else if (action == "SELECT")
00268 {
00269 activateCurrent();
00270 }
00271 else if (action == "MENU" && getContext() == 2)
00272 {
00273 showMenu();
00274 }
00275 else if (action == "0")
00276 {
00277 if (done_button)
00278 done_button->push();
00279 }
00280 else if (action == "1")
00281 {
00282 }
00283 else
00284 handled = false;
00285 }
00286
00287 if (!handled)
00288 MythThemedDialog::keyPressEvent(e);
00289 }
00290
00291 void EditMetadataDialog::wireUpTheme()
00292 {
00293 artist_edit = getUIRemoteEditType("artist_edit");
00294 if (artist_edit)
00295 {
00296 artist_edit->createEdit(this);
00297 connect(artist_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00298 }
00299
00300 compilation_artist_edit = getUIRemoteEditType("compilation_artist_edit");
00301 if (compilation_artist_edit)
00302 {
00303 compilation_artist_edit->createEdit(this);
00304 connect(compilation_artist_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00305 }
00306
00307 album_edit = getUIRemoteEditType("album_edit");
00308 if (album_edit)
00309 {
00310 album_edit->createEdit(this);
00311 connect(album_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00312 }
00313
00314 title_edit = getUIRemoteEditType("title_edit");
00315 if (title_edit)
00316 {
00317 title_edit->createEdit(this);
00318 connect(title_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00319 }
00320
00321 genre_edit = getUIRemoteEditType("genre_edit");
00322 if (genre_edit)
00323 {
00324 genre_edit->createEdit(this);
00325 connect(genre_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00326 }
00327
00328 year_edit = getUIRemoteEditType("year_edit");
00329 if (year_edit)
00330 {
00331 year_edit->createEdit(this);
00332 connect(year_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00333 }
00334
00335 track_edit = getUIRemoteEditType("track_edit");
00336 if (track_edit)
00337 {
00338 track_edit->createEdit(this);
00339 connect(track_edit, SIGNAL(loosingFocus()), this, SLOT(editLostFocus()));
00340 }
00341
00342 lastplay_text = getUITextType("lastplay_text");
00343 playcount_text = getUITextType("playcount_text");
00344 filename_text = getUITextType("filename_text");
00345 rating_image = getUIRepeatedImageType("rating_image");
00346
00347 compilation_check = getUICheckBoxType("compilation_check");
00348 if (compilation_check)
00349 {
00350 connect(compilation_check, SIGNAL(pushed(bool)), this, SLOT(checkClicked(bool)));
00351 }
00352
00353 searchartist_button = getUIPushButtonType("searchartist_button");
00354 if (searchartist_button)
00355 {
00356 connect(searchartist_button, SIGNAL(pushed()), this, SLOT(searchArtist()));
00357 }
00358
00359 searchcompilation_artist_button = getUIPushButtonType("searchcompilation_artist_button");
00360 if (searchcompilation_artist_button)
00361 {
00362 connect(searchcompilation_artist_button, SIGNAL(pushed()), this, SLOT(searchCompilationArtist()));
00363 }
00364
00365 searchalbum_button = getUIPushButtonType("searchalbum_button");
00366 if (searchalbum_button)
00367 {
00368 connect(searchalbum_button, SIGNAL(pushed()), this, SLOT(searchAlbum()));
00369 }
00370
00371 searchgenre_button = getUIPushButtonType("searchgenre_button");
00372 if (searchgenre_button)
00373 {
00374 connect(searchgenre_button, SIGNAL(pushed()), this, SLOT(searchGenre()));
00375 }
00376
00377 metadata_button = getUITextButtonType("metadata_button");
00378 if (metadata_button)
00379 {
00380 metadata_button->setText(tr("Track Info."));
00381 connect(metadata_button, SIGNAL(pushed()), this, SLOT(switchToMetadata()));
00382 }
00383
00384 albumart_button = getUITextButtonType("albumart_button");
00385 if (albumart_button)
00386 {
00387 albumart_button->setText(tr("Album Art"));
00388 connect(albumart_button, SIGNAL(pushed()), this, SLOT(switchToAlbumArt()));
00389 }
00390
00391 dbstatistics_button = getUITextButtonType("dbstats_button");
00392 if (dbstatistics_button)
00393 {
00394 dbstatistics_button->setText(tr("Statistics"));
00395 connect(dbstatistics_button, SIGNAL(pushed()), this, SLOT(switchToDBStats()));
00396 }
00397
00398 done_button = getUITextButtonType("done_button");
00399 if (done_button)
00400 {
00401 done_button->setText(tr("Done"));
00402 connect(done_button, SIGNAL(pushed()), this, SLOT(showSaveMenu()));
00403 }
00404
00405 coverart_image = getUIImageType("coverart_image");
00406 coverart_grid = getUIImageGridType("coverart_grid");
00407 if (coverart_grid)
00408 {
00409 connect(coverart_grid, SIGNAL(itemChanged(ImageGridItem *)),
00410 this, SLOT(gridItemChanged(ImageGridItem *)));
00411 }
00412
00413 imagetype_text = getUITextType("imagetype_text");
00414 imagefilename_text = getUITextType("imagefilename_text");
00415
00416 rating_button = getUISelectorType("rating_button");
00417 if (rating_button)
00418 {
00419
00420 }
00421
00422 buildFocusList();
00423 }
00424
00425 void EditMetadataDialog::switchToMetadata()
00426 {
00427 setContext(1);
00428
00429 updateForeground();
00430 buildFocusList();
00431 if (albumart_button)
00432 setCurrentFocusWidget(albumart_button);
00433 }
00434
00435 void EditMetadataDialog::switchToAlbumArt()
00436 {
00437 setContext(2);
00438
00439 updateForeground();
00440 buildFocusList();
00441 if (metadata_button)
00442 setCurrentFocusWidget(metadata_button);
00443 }
00444
00445 void EditMetadataDialog::switchToDBStats()
00446 {
00447 #if 0
00448 setContext(3);
00449
00450 updateForeground();
00451 buildFocusList();
00452 #endif
00453 }
00454
00455 void EditMetadataDialog::editLostFocus()
00456 {
00457 UIRemoteEditType *whichEditor = (UIRemoteEditType *) getCurrentFocusWidget();
00458
00459 if (whichEditor == album_edit)
00460 {
00461 m_metadata->setAlbum(album_edit->getText());
00462 }
00463 else if (whichEditor == artist_edit)
00464 {
00465 m_metadata->setArtist(artist_edit->getText());
00466 }
00467 else if (whichEditor == compilation_artist_edit)
00468 {
00469 m_metadata->setCompilationArtist(compilation_artist_edit->getText());
00470 }
00471 else if (whichEditor == title_edit)
00472 {
00473 m_metadata->setTitle(title_edit->getText());
00474 }
00475 else if (whichEditor == genre_edit)
00476 {
00477 m_metadata->setGenre(genre_edit->getText());
00478 }
00479 else if (whichEditor == year_edit)
00480 {
00481 m_metadata->setYear(year_edit->getText().toInt());
00482 }
00483 else if (whichEditor == track_edit)
00484 {
00485 m_metadata->setTrack(track_edit->getText().toInt());
00486 }
00487
00488 }
00489
00490 void EditMetadataDialog::checkClicked(bool state)
00491 {
00492 m_metadata->setCompilation(state);
00493 if (!state)
00494 {
00495 m_metadata->setCompilationArtist("");
00496
00497 if (compilation_artist_edit)
00498 {
00499 compilation_artist_edit->setText("");
00500 }
00501 }
00502 else
00503 {
00504 if (m_metadata->CompilationArtist().isEmpty())
00505 {
00506 m_metadata->setCompilationArtist(tr("Various Artists"));
00507
00508 if (compilation_artist_edit)
00509 {
00510 compilation_artist_edit->setText(tr("Various Artists"));
00511 }
00512 }
00513 }
00514 }
00515
00516 bool EditMetadataDialog::showList(QString caption, QString &value)
00517 {
00518 bool res = false;
00519
00520 MythSearchDialog *searchDialog = new MythSearchDialog(gContext->GetMainWindow(), "");
00521 searchDialog->setCaption(caption);
00522 searchDialog->setSearchText(value);
00523 searchDialog->setItems(searchList);
00524 DialogCode rescode = searchDialog->ExecPopupAtXY(-1, 8);
00525 if (kDialogCodeRejected != rescode)
00526 {
00527 value = searchDialog->getResult();
00528 res = true;
00529 }
00530
00531 searchDialog->deleteLater();
00532 setActiveWindow();
00533
00534 return res;
00535 }
00536
00537 void EditMetadataDialog::searchArtist()
00538 {
00539 QString s;
00540
00541 searchList = Metadata::fillFieldList("artist");
00542
00543 s = m_metadata->Artist();
00544 if (showList(tr("Select an Artist"), s))
00545 {
00546 m_metadata->setArtist(s);
00547 fillWidgets();
00548 }
00549 }
00550
00551 void EditMetadataDialog::searchCompilationArtist()
00552 {
00553 QString s;
00554
00555 searchList = Metadata::fillFieldList("compilation_artist");
00556
00557 s = m_metadata->CompilationArtist();
00558 if (showList(tr("Select a Compilation Artist"), s))
00559 {
00560 m_metadata->setCompilationArtist(s);
00561 fillWidgets();
00562 }
00563 }
00564
00565 void EditMetadataDialog::searchAlbum()
00566 {
00567 QString s;
00568
00569 searchList = Metadata::fillFieldList("album");
00570
00571 s = m_metadata->Album();
00572 if (showList(tr("Select an Album"), s))
00573 {
00574 m_metadata->setAlbum(s);
00575 fillWidgets();
00576 }
00577 }
00578
00579 void EditMetadataDialog::searchGenre()
00580 {
00581 QString s;
00582
00583
00584
00585
00586
00587
00588
00589
00590 searchList = Metadata::fillFieldList("genre");
00591
00592 s = m_metadata->Genre();
00593 if (showList(tr("Select a Genre"), s))
00594 {
00595 m_metadata->setGenre(s);
00596 fillWidgets();
00597 }
00598
00599 }
00600
00601 void EditMetadataDialog::closeDialog()
00602 {
00603 cancelPopup();
00604 reject();
00605 }
00606
00607 void EditMetadataDialog::showSaveMenu()
00608 {
00609 popup = new MythPopupBox(gContext->GetMainWindow(), "Menu");
00610
00611 QLabel *label = popup->addLabel(tr("Save Changes?"), MythPopupBox::Large, false);
00612 label->setAlignment(Qt::AlignCenter | Qt::WordBreak);
00613 QButton *topButton;
00614
00615 if (metadataOnly)
00616 {
00617 topButton = popup->addButton(tr("Save Changes"), this,
00618 SLOT(saveToMetadata()));
00619 }
00620 else
00621 {
00622 topButton = popup->addButton(tr("Save to Database Only"), this,
00623 SLOT(saveToDatabase()));
00624 if (!m_metadata->Filename().contains("://"))
00625 {
00626 popup->addButton(tr("Save to File Only"), this,
00627 SLOT(saveToFile()));
00628 popup->addButton(tr("Save to File and Database"), this,
00629 SLOT(saveAll()));
00630 }
00631 }
00632
00633 popup->addButton(tr("Exit/Do Not Save"), this,
00634 SLOT(closeDialog()));
00635
00636 popup->addButton(tr("Cancel"), this, SLOT(cancelPopup()));
00637
00638 popup->ShowPopup(this, SLOT(cancelPopup()));
00639
00640 topButton->setFocus();
00641 }
00642
00643 void EditMetadataDialog::cancelPopup(void)
00644 {
00645 if (popup)
00646 {
00647 popup->deleteLater();
00648 popup = NULL;
00649 setActiveWindow();
00650 }
00651 }
00652
00653 void EditMetadataDialog::saveToMetadata()
00654 {
00655 cancelPopup();
00656
00657 *m_sourceMetadata = m_metadata;
00658 accept();
00659 }
00660
00661 void EditMetadataDialog::saveToDatabase()
00662 {
00663 cancelPopup();
00664
00665 m_metadata->dumpToDatabase();
00666 *m_sourceMetadata = m_metadata;
00667 accept();
00668 }
00669
00670 void EditMetadataDialog::saveToFile()
00671 {
00672 cancelPopup();
00673
00674 if (!MythPopupBox::showOkCancelPopup(gContext->GetMainWindow(),
00675 "Save To File",
00676 tr("Are you sure you want to save the "
00677 "modified metadata to the file?"),
00678 false))
00679 {
00680 return;
00681 }
00682
00683 Decoder *decoder = Decoder::create(m_metadata->Filename(), NULL, NULL, true);
00684 if (decoder)
00685 {
00686 decoder->commitMetadata(m_metadata);
00687 delete decoder;
00688 }
00689 accept();
00690 }
00691
00692 void EditMetadataDialog::saveAll()
00693 {
00694 cancelPopup();
00695
00696 if (!MythPopupBox::showOkCancelPopup(gContext->GetMainWindow(),
00697 "Save To File",
00698 tr("Are you sure you want to save the "
00699 "modified metadata to the file?"),
00700 false))
00701 {
00702 return;
00703 }
00704
00705 Decoder *decoder = Decoder::create(m_metadata->Filename(), NULL, NULL, true);
00706 if (decoder)
00707 {
00708 decoder->commitMetadata(m_metadata);
00709 delete decoder;
00710 }
00711
00712 saveToDatabase();
00713 }
00714
00715 void EditMetadataDialog::showMenu()
00716 {
00717 if (coverart_grid->getItemCount() == 0)
00718 return;
00719
00720 MythPopupBox *menu = new MythPopupBox(gContext->GetMainWindow(), "menu");
00721
00722 QLabel *caption = menu->addLabel(tr("Change Image Type"), MythPopupBox::Medium);
00723 caption->setAlignment(Qt::AlignCenter);
00724
00725 menu->addButton(albumArt->getTypeName(IT_UNKNOWN));
00726 menu->addButton(albumArt->getTypeName(IT_FRONTCOVER));
00727 menu->addButton(albumArt->getTypeName(IT_BACKCOVER));
00728 menu->addButton(albumArt->getTypeName(IT_CD));
00729 menu->addButton(albumArt->getTypeName(IT_INLAY));
00730
00731 DialogCode ret = menu->ExecPopup();
00732 int res = MythDialog::CalcItemIndex(ret);
00733
00734 if ((IT_UNKNOWN <= res) && (res < IT_LAST))
00735 {
00736
00737 ImageGridItem *item = coverart_grid->getCurrentItem();
00738 if (item)
00739 {
00740 item->text = albumArt->getTypeName((ImageType) res);
00741 AlbumArtImage *image = (AlbumArtImage*) item->data;
00742 if (image)
00743 {
00744 image->imageType = (ImageType) res;
00745 image->typeName = item->text;
00746
00747
00748 albumArt->saveImageType(image->id, image->imageType);
00749
00750 gridItemChanged(item);
00751 }
00752 }
00753 }
00754
00755 menu->deleteLater();
00756 }
00757
00758 void EditMetadataDialog::setSaveMetadataOnly()
00759 {
00760 metadataOnly = true;
00761
00762 if (metadata_button)
00763 metadata_button->hide();
00764
00765 if (albumart_button)
00766 albumart_button->hide();
00767 }