00001 #include <iostream>
00002 #include <cstdlib>
00003
00004
00005 #include <QKeyEvent>
00006
00007
00008 #include <mythdialogbox.h>
00009 #include <mythuitextedit.h>
00010 #include <mythuibuttonlist.h>
00011 #include <mythdb.h>
00012
00013
00014 #include "musiccommon.h"
00015 #include "searchview.h"
00016
00017 SearchView::SearchView(MythScreenStack *parent)
00018 :MusicCommon(parent, "searchview"),
00019 m_playTrack(false), m_fieldList(NULL), m_criteriaEdit(NULL),
00020 m_matchesText(NULL), m_tracksList(NULL)
00021 {
00022 m_currentView = MV_SEARCH;
00023 }
00024
00025 SearchView::~SearchView()
00026 {
00027 }
00028
00029 bool SearchView::Create(void)
00030 {
00031 bool err = false;
00032
00033
00034 err = LoadWindowFromXML("music-ui.xml", "searchview", this);
00035
00036 if (!err)
00037 return false;
00038
00039
00040 err = CreateCommon();
00041
00042
00043 UIUtilE::Assign(this, m_fieldList, "field_list", &err);
00044 UIUtilE::Assign(this, m_criteriaEdit, "criteria_edit", &err);
00045 UIUtilW::Assign(this, m_matchesText, "matches_text", &err);
00046 UIUtilE::Assign(this, m_tracksList, "tracks_list", &err);
00047
00048 if (err)
00049 {
00050 LOG(VB_GENERAL, LOG_ERR, "Cannot load screen 'searchview'");
00051 return false;
00052 }
00053
00054 BuildFocusList();
00055
00056 new MythUIButtonListItem(m_fieldList, tr("All Fields"),
00057 qVariantFromValue(0));
00058 new MythUIButtonListItem(m_fieldList, tr("Artist"),
00059 qVariantFromValue(1));
00060 new MythUIButtonListItem(m_fieldList, tr("Album"),
00061 qVariantFromValue(2));
00062 new MythUIButtonListItem(m_fieldList, tr("Title"),
00063 qVariantFromValue(3));
00064 new MythUIButtonListItem(m_fieldList, tr("Genre"),
00065 qVariantFromValue(4));
00066
00067
00068
00069 connect(m_fieldList, SIGNAL(itemSelected(MythUIButtonListItem*)),
00070 this, SLOT(fieldSelected(MythUIButtonListItem*)));
00071
00072 connect(m_tracksList, SIGNAL(itemClicked(MythUIButtonListItem*)),
00073 this, SLOT(trackClicked(MythUIButtonListItem*)));
00074
00075 connect(m_tracksList, SIGNAL(itemVisible(MythUIButtonListItem*)),
00076 this, SLOT(trackVisible(MythUIButtonListItem*)));
00077
00078 connect(m_criteriaEdit, SIGNAL(valueChanged()), this, SLOT(criteriaChanged()));
00079
00080 updateTracksList();
00081
00082 return true;
00083 }
00084
00085 void SearchView::customEvent(QEvent *event)
00086 {
00087 bool handled = false;
00088
00089 if (event->type() == MusicPlayerEvent::TrackRemovedEvent ||
00090 event->type() == MusicPlayerEvent::TrackAddedEvent)
00091 {
00092 MusicPlayerEvent *mpe = dynamic_cast<MusicPlayerEvent *>(event);
00093
00094 if (!mpe)
00095 return;
00096
00097 int trackID = mpe->TrackID;
00098
00099 for (int x = 0; x < m_tracksList->GetCount(); x++)
00100 {
00101 MythUIButtonListItem *item = m_tracksList->GetItemAt(x);
00102 Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
00103 if (mdata && (mdata->ID() == (Metadata::IdType) trackID || trackID == -1))
00104 {
00105 if (gPlayer->getPlaylist()->checkTrack(mdata->ID()))
00106 item->DisplayState("on", "selectedstate");
00107 else
00108 item->DisplayState("off", "selectedstate");
00109 }
00110 }
00111
00112
00113 MusicCommon::customEvent(event);
00114 handled = true;
00115
00116 if (m_playTrack)
00117 {
00118 m_playTrack = false;
00119
00120 if (event->type() == MusicPlayerEvent::TrackAddedEvent)
00121 {
00122
00123 m_currentPlaylist->SetItemCurrent(m_currentPlaylist->GetCount() - 1);
00124 playlistItemClicked(m_currentPlaylist->GetItemCurrent());
00125 }
00126 }
00127 }
00128 else if (event->type() == MusicPlayerEvent::AllTracksRemovedEvent)
00129 {
00130 for (int x = 0; x < m_tracksList->GetCount(); x++)
00131 {
00132 MythUIButtonListItem *item = m_tracksList->GetItemAt(x);
00133 if (item)
00134 item->DisplayState("off", "selectedstate");
00135 }
00136 }
00137 else if (event->type() == MusicPlayerEvent::MetadataChangedEvent)
00138 {
00139 MusicPlayerEvent *mpe = dynamic_cast<MusicPlayerEvent *>(event);
00140
00141 if (!mpe)
00142 return;
00143
00144 uint trackID = mpe->TrackID;
00145
00146 for (int x = 0; x < m_tracksList->GetCount(); x++)
00147 {
00148 MythUIButtonListItem *item = m_tracksList->GetItemAt(x);
00149 Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
00150 if (mdata && mdata->ID() == trackID)
00151 {
00152 MetadataMap metadataMap;
00153 mdata->toMap(metadataMap);
00154 item->SetTextFromMap(metadataMap);
00155 }
00156 }
00157
00158
00159
00160 }
00161 else if (event->type() == DialogCompletionEvent::kEventType)
00162 {
00163 DialogCompletionEvent *dce = static_cast<DialogCompletionEvent *>(event);
00164
00165
00166 if (dce->GetResult() < 0)
00167 return;
00168
00169 QString resultid = dce->GetId();
00170 QString resulttext = dce->GetResultText();
00171 if (resultid == "searchviewmenu")
00172 {
00173 if (resulttext == tr("Add To Playlist") || resulttext == tr("Remove From Playlist"))
00174 {
00175 if (GetFocusWidget() == m_tracksList)
00176 {
00177 MythUIButtonListItem *item = m_tracksList->GetItemCurrent();
00178 if (item)
00179 {
00180 m_playTrack = false;
00181 trackClicked(item);
00182 }
00183 }
00184 }
00185 else if (resulttext == tr("Add To Playlist And Play"))
00186 {
00187 if (GetFocusWidget() == m_tracksList)
00188 {
00189 MythUIButtonListItem *item = m_tracksList->GetItemCurrent();
00190 if (item)
00191 {
00192 m_playTrack = true;
00193 trackClicked(item);
00194 }
00195 }
00196 }
00197 else if (resulttext == tr("Search List..."))
00198 searchButtonList();
00199 }
00200 }
00201
00202 if (!handled)
00203 MusicCommon::customEvent(event);
00204 }
00205
00206 bool SearchView::keyPressEvent(QKeyEvent *event)
00207 {
00208 if (!m_moveTrackMode && GetFocusWidget() && GetFocusWidget()->keyPressEvent(event))
00209 return true;
00210
00211 bool handled = false;
00212 QStringList actions;
00213 handled = GetMythMainWindow()->TranslateKeyPress("Music", event, actions);
00214
00215 for (int i = 0; i < actions.size() && !handled; i++)
00216 {
00217 QString action = actions[i];
00218 handled = true;
00219
00220 if (action == "INFO" || action == "EDIT")
00221 {
00222 if (GetFocusWidget() == m_tracksList)
00223 {
00224 if (m_tracksList->GetItemCurrent())
00225 {
00226 Metadata *mdata = qVariantValue<Metadata*> (m_tracksList->GetItemCurrent()->GetData());
00227 if (mdata)
00228 {
00229 if (action == "INFO")
00230 showTrackInfo(mdata);
00231 else
00232 editTrackInfo(mdata);
00233 }
00234 }
00235 }
00236 else
00237 handled = false;
00238 }
00239 else if (action == "PLAY" || action == "PAUSE")
00240 {
00241 if (GetFocusWidget() == m_tracksList)
00242 {
00243 MythUIButtonListItem *item = m_tracksList->GetItemCurrent();
00244 if (item)
00245 {
00246 m_playTrack = true;
00247 trackClicked(item);
00248 }
00249 }
00250 else
00251 handled = false;
00252 }
00253 else
00254 handled = false;
00255 }
00256
00257 if (!handled && MusicCommon::keyPressEvent(event))
00258 handled = true;
00259
00260 if (!handled && MythScreenType::keyPressEvent(event))
00261 handled = true;
00262
00263 return handled;
00264 }
00265
00266 void SearchView::ShowMenu(void)
00267 {
00268 if (GetFocusWidget() == m_tracksList)
00269 {
00270 QString label = tr("Search Actions");
00271
00272 MythMenu *menu = new MythMenu(label, this, "searchviewmenu");
00273
00274 MythUIButtonListItem *item = m_tracksList->GetItemCurrent();
00275 if (item)
00276 {
00277 Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
00278 if (mdata)
00279 {
00280 if (gPlayer->getPlaylist()->checkTrack(mdata->ID()))
00281 menu->AddItem(tr("Remove From Playlist"));
00282 else
00283 {
00284 menu->AddItem(tr("Add To Playlist"));
00285 menu->AddItem(tr("Add To Playlist And Play"));
00286 }
00287 }
00288 }
00289
00290 if (GetFocusWidget() == m_tracksList || GetFocusWidget() == m_currentPlaylist)
00291 menu->AddItem(tr("Search List..."));
00292
00293 menu->AddItem(tr("More Options"), NULL, createMainMenu());
00294
00295 MythScreenStack *popupStack = GetMythMainWindow()->GetStack("popup stack");
00296
00297 MythDialogBox *menuPopup = new MythDialogBox(menu, popupStack, "actionmenu");
00298
00299 if (menuPopup->Create())
00300 popupStack->AddScreen(menuPopup);
00301 else
00302 delete menu;
00303 }
00304 else
00305 MusicCommon::ShowMenu();
00306 }
00307
00308 void SearchView::fieldSelected(MythUIButtonListItem *item)
00309 {
00310 (void) item;
00311 updateTracksList();
00312 }
00313
00314 void SearchView::criteriaChanged(void)
00315 {
00316 updateTracksList();
00317 }
00318
00319 void SearchView::updateTracksList(void)
00320 {
00321 m_tracksList->Reset();
00322
00323 MythUIButtonListItem *item = m_fieldList->GetItemCurrent();
00324
00325 if (!item)
00326 return;
00327
00328 QString searchStr = m_criteriaEdit->GetText();
00329 int field = item->GetData().toInt();
00330
00331 QString sql;
00332 MSqlQuery query(MSqlQuery::InitCon());
00333
00334 if (searchStr.isEmpty())
00335 {
00336 sql = "SELECT song_id "
00337 "FROM music_songs ";
00338
00339 query.prepare(sql);
00340 }
00341 else
00342 {
00343 switch(field)
00344 {
00345 case 1:
00346 {
00347 sql = "SELECT song_id "
00348 "FROM music_songs "
00349 "LEFT JOIN music_artists ON "
00350 " music_songs.artist_id=music_artists.artist_id "
00351 "WHERE music_artists.artist_name LIKE '%" + searchStr + "%' ";
00352 query.prepare(sql);
00353 break;
00354 }
00355 case 2:
00356 {
00357 sql = "SELECT song_id "
00358 "FROM music_songs "
00359 "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
00360 "WHERE music_albums.album_name LIKE '%" + searchStr + "%' ";
00361 query.prepare(sql);
00362 break;
00363 }
00364 case 3:
00365 {
00366 sql = "SELECT song_id "
00367 "FROM music_songs "
00368 "WHERE music_songs.name LIKE '%" + searchStr + "%' ";
00369 query.prepare(sql);
00370 break;
00371 }
00372 case 4:
00373 {
00374 sql = "SELECT song_id "
00375 "FROM music_songs "
00376 "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
00377 "WHERE music_genres.genre LIKE '%" + searchStr + "%' ";
00378 query.prepare(sql);
00379 break;
00380 }
00381 case 5:
00382 {
00383
00384 }
00385 case 0:
00386 default:
00387 {
00388 sql = "SELECT song_id "
00389 "FROM music_songs "
00390 "LEFT JOIN music_artists ON "
00391 " music_songs.artist_id=music_artists.artist_id "
00392 "LEFT JOIN music_albums ON music_songs.album_id=music_albums.album_id "
00393 "LEFT JOIN music_artists AS music_comp_artists ON "
00394 " music_albums.artist_id=music_comp_artists.artist_id "
00395 "LEFT JOIN music_genres ON music_songs.genre_id=music_genres.genre_id "
00396 "WHERE music_songs.name LIKE '%" + searchStr + "%' "
00397 "OR music_artists.artist_name LIKE '%" + searchStr + "%' "
00398 "OR music_albums.album_name LIKE '%" + searchStr + "%' "
00399 "OR music_genres.genre LIKE '%" + searchStr + "%' ";
00400
00401 query.prepare(sql);
00402 }
00403 }
00404 }
00405
00406 if (!query.exec() || !query.isActive())
00407 {
00408 MythDB::DBError("Search music database", query);
00409 return;
00410 }
00411
00412 while (query.next())
00413 {
00414 int trackid = query.value(0).toInt();
00415
00416 Metadata *mdata = gMusicData->all_music->getMetadata(trackid);
00417 if (mdata)
00418 {
00419 MythUIButtonListItem *newitem = new MythUIButtonListItem(m_tracksList, "");
00420 newitem->SetData(qVariantFromValue(mdata));
00421 MetadataMap metadataMap;
00422 mdata->toMap(metadataMap);
00423 newitem->SetTextFromMap(metadataMap);
00424
00425 if (gPlayer->getPlaylist()->checkTrack(mdata->ID()))
00426 newitem->DisplayState("on", "selectedstate");
00427 else
00428 newitem->DisplayState("off", "selectedstate");
00429
00430
00431 }
00432 }
00433
00434 trackVisible(m_tracksList->GetItemCurrent());
00435
00436 if (m_matchesText)
00437 m_matchesText->SetText(QString("%1").arg(m_tracksList->GetCount()));
00438 }
00439
00440 void SearchView::trackClicked(MythUIButtonListItem *item)
00441 {
00442 Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
00443 if (mdata)
00444 {
00445 if (gPlayer->getPlaylist()->checkTrack(mdata->ID()))
00446 gPlayer->getPlaylist()->removeTrack(mdata->ID());
00447 else
00448 gPlayer->getPlaylist()->addTrack(mdata->ID(), true);
00449 }
00450 }
00451
00452 void SearchView::trackVisible(MythUIButtonListItem *item)
00453 {
00454
00455 if (!item)
00456 return;
00457
00458 if (item->GetImage().isEmpty())
00459 {
00460 Metadata *mdata = qVariantValue<Metadata*> (item->GetData());
00461 if (mdata)
00462 {
00463 QString artFile = mdata->getAlbumArtFile();
00464 if (artFile.isEmpty())
00465 item->SetImage("mm_nothumb.png");
00466 else
00467 item->SetImage(mdata->getAlbumArtFile());
00468 }
00469 else
00470 item->SetImage("mm_nothumb.png");
00471 }
00472 }