00001
00002 #include <cstdlib>
00003
00004
00005 #include <iostream>
00006 using namespace std;
00007
00008
00009 #include <qapplication.h>
00010 #include <qregexp.h>
00011
00012
00013 #include <mythtv/mythcontext.h>
00014 #include <mythtv/mythwidgets.h>
00015 #include <mythtv/lcddevice.h>
00016 #include <mythtv/mythmedia.h>
00017 #include <mythtv/audiooutput.h>
00018 #include <mythtv/compat.h>
00019
00020
00021 #include "metadata.h"
00022 #include "constants.h"
00023 #include "streaminput.h"
00024 #include "decoder.h"
00025 #include "playbackbox.h"
00026 #include "databasebox.h"
00027 #include "mainvisual.h"
00028 #include "smartplaylist.h"
00029 #include "search.h"
00030
00031 #ifndef USING_MINGW
00032 #include "cddecoder.h"
00033 #endif // USING_MINGW
00034
00035 PlaybackBoxMusic::PlaybackBoxMusic(MythMainWindow *parent, QString window_name,
00036 QString theme_filename, const QString &dev, const char *name)
00037
00038 : MythThemedDialog(parent, window_name, theme_filename, name)
00039 {
00040
00041 mainvisual = NULL;
00042 visual_mode_timer = NULL;
00043 lcd_update_timer = NULL;
00044 waiting_for_playlists_timer = NULL;
00045 speed_scroll_timer = NULL;
00046 playlist_popup = NULL;
00047 progress = NULL;
00048
00049 gPlayer->setListener(this);
00050
00051 tree_is_done = false;
00052 first_playlist_check = true;
00053 outputBufferSize = 256;
00054 currentTime = 0;
00055 maxTime = 0;
00056 scrollCount = 0;
00057 scrollingDown = false;
00058 setContext(0);
00059 visual_mode_timer = new QTimer(this);
00060 speed_scroll_timer = new QTimer(this);
00061 connect(speed_scroll_timer, SIGNAL(timeout()), this, SLOT(resetScrollCount()));
00062
00063 visualizer_status = 0;
00064 curMeta = NULL;
00065 curSmartPlaylistCategory = "";
00066 curSmartPlaylistName = "";
00067
00068 menufilters = gContext->GetNumSetting("MusicMenuFilters", 0);
00069
00070 cd_reader_thread = NULL;
00071 cd_watcher = NULL;
00072 scan_for_cd = gContext->GetNumSetting("AutoPlayCD", 0);
00073 m_CDdevice = dev;
00074
00075
00076
00077 show_whole_tree = gContext->GetNumSetting("ShowWholeTree", 1);
00078 keyboard_accelerators = gContext->GetNumSetting("KeyboardAccelerators", 1);
00079 if (!keyboard_accelerators)
00080 show_whole_tree = false;
00081
00082 showrating = gContext->GetNumSetting("MusicShowRatings", 0);
00083 listAsShuffled = gContext->GetNumSetting("ListAsShuffled", 0);
00084 cycle_visualizer = gContext->GetNumSetting("VisualCycleOnSongChange", 0);
00085 show_album_art = gContext->GetNumSetting("VisualAlbumArtOnSongChange", 0);
00086 random_visualizer = gContext->GetNumSetting("VisualRandomize", 0);
00087
00088 m_pushedButton = NULL;
00089
00090
00091
00092
00093 wireUpTheme();
00094
00095
00096
00097 volume_control = false;
00098 volume_display_timer = new QTimer(this);
00099 if (gContext->GetNumSetting("MythControlsVolume", 0))
00100 {
00101 volume_control = true;
00102 }
00103 volume_display_timer->start(2000, true);
00104 connect(volume_display_timer, SIGNAL(timeout()),
00105 this, SLOT(hideVolume()));
00106
00107 setShuffleMode(gPlayer->getShuffleMode());
00108
00109 resumemode = gPlayer->getResumeMode();
00110
00111 setRepeatMode(gPlayer->getRepeatMode());
00112
00113
00114
00115 if (!keyboard_accelerators)
00116 {
00117 if (pledit_button)
00118 pledit_button->setText(tr("Edit Playlist"));
00119 if (vis_button)
00120 vis_button->setText(tr("Visualize"));
00121 if (!assignFirstFocus())
00122 {
00123 VERBOSE(VB_IMPORTANT, "playbackbox.o: Could not find a button to "
00124 "assign focus to. What's in your theme?");
00125 exit(0);
00126 }
00127 }
00128 else
00129 {
00130 if (pledit_button)
00131 pledit_button->setText(tr("3 Edit Playlist"));
00132 if (vis_button)
00133 vis_button->setText(tr("4 Visualize"));
00134 }
00135
00136 if (class LCD *lcd = LCD::Get())
00137 {
00138
00139 QPtrList<LCDTextItem> textItems;
00140 textItems.setAutoDelete(true);
00141
00142 textItems.append(new LCDTextItem(1, ALIGN_CENTERED, "Please Wait",
00143 "Generic"));
00144 lcd->switchToGeneric(&textItems);
00145 }
00146
00147
00148
00149
00150
00151
00152
00153 waiting_for_playlists_timer = new QTimer(this);
00154 connect(waiting_for_playlists_timer, SIGNAL(timeout()), this,
00155 SLOT(checkForPlaylists()));
00156 waiting_for_playlists_timer->start(50, TRUE);
00157
00158
00159
00160 mainvisual = new MainVisual(this);
00161 if (visual_blackhole)
00162 mainvisual->setGeometry(visual_blackhole->getScreenArea());
00163 else
00164 mainvisual->setGeometry(screenwidth + 10, screenheight + 10, 160, 160);
00165 mainvisual->show();
00166
00167 gPlayer->setVisual(mainvisual);
00168
00169 fullscreen_blank = false;
00170
00171 visual_modes = QStringList::split(';', gContext->GetSetting("VisualMode"));
00172 if (!visual_modes.count())
00173 visual_modes.push_front("Blank");
00174
00175 current_visual = random_visualizer ? rand() % visual_modes.count() : 0;
00176
00177 QString visual_delay = gContext->GetSetting("VisualModeDelay");
00178 bool delayOK;
00179 visual_mode_delay = visual_delay.toInt(&delayOK);
00180 if (!delayOK)
00181 visual_mode_delay = 0;
00182 if (visual_mode_delay > 0)
00183 {
00184 visual_mode_timer->start(visual_mode_delay * 1000);
00185 connect(visual_mode_timer, SIGNAL(timeout()), this, SLOT(visEnable()));
00186 }
00187 visualizer_status = 1;
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197 mainvisual->setVisual("Blank");
00198
00199
00200
00201 updateForeground();
00202
00203 if (class LCD *lcd = LCD::Get())
00204 {
00205 lcd->switchToTime();
00206 }
00207 }
00208
00209 PlaybackBoxMusic::~PlaybackBoxMusic(void)
00210 {
00211 if (progress)
00212 {
00213 progress->Close();
00214 progress->deleteLater();
00215 progress = NULL;
00216 }
00217
00218 if (cd_reader_thread)
00219 {
00220 cd_watcher->stop();
00221 cd_reader_thread->wait();
00222 delete cd_reader_thread;
00223 }
00224
00225 if (class LCD *lcd = LCD::Get())
00226 lcd->switchToTime();
00227
00228 gMusicData->all_music->save();
00229 gPlayer->refreshMetadata();
00230 }
00231
00232 bool PlaybackBoxMusic::onMediaEvent(MythMediaDevice*)
00233 {
00234 return scan_for_cd;
00235 }
00236
00237 void PlaybackBoxMusic::resetScrollCount()
00238 {
00239 scrollCount = 0;
00240 scrollingDown = false;
00241 }
00242
00243 void PlaybackBoxMusic::keyPressEvent(QKeyEvent *e)
00244 {
00245 bool handled = false;
00246
00247 resetTimer();
00248
00249 QStringList actions;
00250 gContext->GetMainWindow()->TranslateKeyPress("Music", e, actions, true);
00251
00252 int scrollAmt = 1;
00253
00254 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00255 {
00256 QString action = actions[i];
00257 handled = true;
00258
00259 if (action == "NEXTTRACK")
00260 {
00261 if (next_button)
00262 next_button->push();
00263 else
00264 next();
00265 }
00266 else if (action == "PREVTRACK")
00267 {
00268 if (prev_button)
00269 prev_button->push();
00270 else
00271 previous();
00272 }
00273 else if (action == "FFWD")
00274 {
00275 if (ff_button)
00276 ff_button->push();
00277 else
00278 seekforward();
00279 }
00280 else if (action == "RWND")
00281 {
00282 if (rew_button)
00283 rew_button->push();
00284 else
00285 seekback();
00286 }
00287 else if (action == "PAUSE")
00288 {
00289 if (gPlayer->isPlaying())
00290 {
00291 if (pause_button)
00292 pause_button->push();
00293 else
00294 pause();
00295 }
00296 else
00297 {
00298 if (play_button)
00299 play_button->push();
00300 else
00301 play();
00302 }
00303 }
00304 else if (action == "PLAY")
00305 {
00306 if (play_button)
00307 play_button->push();
00308 else
00309 play();
00310 }
00311 else if (action == "STOP")
00312 {
00313 if (stop_button)
00314 stop_button->push();
00315 else
00316 stop();
00317 currentTime = 0;
00318 }
00319 else if (action == "THMBUP")
00320 increaseRating();
00321 else if (action == "THMBDOWN")
00322 decreaseRating();
00323 else if (action == "1")
00324 {
00325 if (shuffle_button)
00326 shuffle_button->push();
00327 else
00328 toggleShuffle();
00329 }
00330 else if (action == "2")
00331 {
00332 if (repeat_button)
00333 repeat_button->push();
00334 else
00335 toggleRepeat();
00336 }
00337 else if (action == "3")
00338 {
00339 if (pledit_button)
00340 pledit_button->push();
00341 else
00342 editPlaylist();
00343 }
00344 else if (action == "CYCLEVIS")
00345 {
00346 CycleVisualizer();
00347 bannerEnable(tr("Visualization: ") + visual_modes[current_visual], 4000);
00348 }
00349 else if (action == "BLANKSCR")
00350 toggleFullBlankVisualizer();
00351 else if (action == "VOLUMEDOWN")
00352 changeVolume(false);
00353 else if (action == "VOLUMEUP")
00354 changeVolume(true);
00355 else if (action == "SPEEDDOWN")
00356 changeSpeed(false);
00357 else if (action == "SPEEDUP")
00358 changeSpeed(true);
00359 else if (action == "MUTE")
00360 toggleMute();
00361 else if (action == "MENU" && visualizer_status != 2)
00362 {
00363 menufilters = false;
00364 showMenu();
00365 }
00366 else if (action == "FILTER" && visualizer_status != 2)
00367 {
00368 menufilters = true;
00369 showMenu();
00370 }
00371 else if (action == "INFO")
00372 if (visualizer_status == 2)
00373 bannerToggle(curMeta);
00374 else
00375 showEditMetadataDialog();
00376 else if (action == "ESCAPE" && visualizer_status != 2)
00377 {
00378 if (!gPlayer->isPlaying() || m_parent->IsExitingToMain())
00379 {
00380 gPlayer->savePosition();
00381 stopAll();
00382 done(kDialogCodeAccepted);
00383 }
00384 else
00385 {
00386 DialogBox *dialog = new DialogBox(gContext->GetMainWindow(),
00387 tr("Exiting Music Player\n"
00388 "Do you want to continue playing in the background?"));
00389 dialog->AddButton(tr("No - Exit, Stop Playing"));
00390 dialog->AddButton(tr("Yes - Exit, Continue Playing"));
00391 dialog->AddButton(tr("Cancel"));
00392 int res = dialog->exec();
00393 dialog->deleteLater();
00394
00395 if (res == kDialogCodeButton0)
00396 {
00397 gPlayer->savePosition();
00398 stopAll();
00399 done(kDialogCodeAccepted);
00400 }
00401 else if (res == kDialogCodeButton1)
00402 {
00403 gPlayer->setListener(NULL);
00404 gPlayer->setVisual(NULL);
00405 done(kDialogCodeAccepted);
00406 }
00407 else
00408 handled = true;
00409 }
00410 }
00411 else
00412 handled = false;
00413 }
00414
00415 if (handled)
00416 return;
00417
00418 if (visualizer_status == 2)
00419 {
00420 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00421 {
00422 QString action = actions[i];
00423 if (action == "ESCAPE" || action == "4")
00424 {
00425 visualizer_status = 1;
00426
00427 mainvisual->setVisual("Blank");
00428 if (visual_blackhole)
00429 mainvisual->setGeometry(visual_blackhole->getScreenArea());
00430 else
00431 mainvisual->setGeometry(screenwidth + 10,
00432 screenheight + 10,
00433 160, 160);
00434 setUpdatesEnabled(true);
00435 mainvisual->setVisual(visual_modes[current_visual]);
00436 bannerDisable();
00437
00438 if (!m_parent->IsExitingToMain())
00439 handled = true;
00440 }
00441 else
00442 {
00443
00444 if (mainvisual->visual())
00445 mainvisual->visual()->handleKeyPress(action);
00446 }
00447 }
00448 }
00449 else if (keyboard_accelerators)
00450 {
00451 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00452 {
00453 QString action = actions[i];
00454 handled = true;
00455
00456 if (action == "UP")
00457 {
00458 if (scrollingDown)
00459 resetScrollCount();
00460
00461 scrollCount++;
00462 if (scrollCount > 19 && scrollCount < 30)
00463 scrollAmt = 10;
00464 else if (scrollCount > 29)
00465 scrollAmt = 30;
00466
00467 if (!music_tree_list->moveUpByAmount(scrollAmt, true) && scrollAmt > 1)
00468 resetScrollCount();
00469
00470 speed_scroll_timer->stop();
00471 speed_scroll_timer->start(300, true);
00472
00473 }
00474 else if (action == "DOWN")
00475 {
00476 if (!scrollingDown)
00477 {
00478 resetScrollCount();
00479 scrollingDown = true;
00480 }
00481
00482 scrollCount++;
00483 if (scrollCount > 19 && scrollCount < 30)
00484 scrollAmt = 5;
00485 else if (scrollCount > 29)
00486 scrollAmt = 30;
00487
00488 if (!music_tree_list->moveDownByAmount(scrollAmt, true) && scrollCount > 1)
00489 resetScrollCount();
00490
00491 speed_scroll_timer->stop();
00492 speed_scroll_timer->start(300, true);
00493 }
00494 else if (action == "LEFT")
00495 music_tree_list->popUp();
00496 else if (action == "RIGHT")
00497 music_tree_list->pushDown();
00498 else if (action == "4")
00499 {
00500 if (vis_button)
00501 vis_button->push();
00502 else
00503 visEnable();
00504 }
00505 else if (action == "SELECT")
00506 {
00507 music_tree_list->select();
00508 if (visualizer_status > 0 && cycle_visualizer)
00509 CycleVisualizer();
00510 }
00511 else if (action == "REFRESH")
00512 {
00513 music_tree_list->syncCurrentWithActive();
00514 music_tree_list->forceLastBin();
00515 music_tree_list->refresh();
00516 }
00517 else if (action == "PAGEUP")
00518 music_tree_list->pageUp();
00519 else if (action == "PAGEDOWN")
00520 music_tree_list->pageDown();
00521 else if (action == "INCSEARCH")
00522 music_tree_list->incSearchStart();
00523 else if (action == "INCSEARCHNEXT")
00524 music_tree_list->incSearchNext();
00525 }
00526 }
00527 else
00528 {
00529 for (unsigned int i = 0; i < actions.size() && !handled; i++)
00530 {
00531 QString action = actions[i];
00532 handled = true;
00533
00534 if (action == "UP" || action == "LEFT")
00535 nextPrevWidgetFocus(false);
00536 else if (action == "DOWN" || action == "RIGHT")
00537 nextPrevWidgetFocus(true);
00538 else if (action == "SELECT")
00539 {
00540 activateCurrent();
00541 music_tree_list->syncCurrentWithActive();
00542 }
00543 else
00544 handled = false;
00545 }
00546 }
00547 }
00548
00549 void PlaybackBoxMusic::handlePush(QString buttonname)
00550 {
00551 if (m_pushedButton)
00552 m_pushedButton->unPush();
00553
00554 if (buttonname == "play_button")
00555 {
00556 play();
00557 m_pushedButton = play_button;
00558 }
00559 else if (buttonname == "pause_button")
00560 {
00561 pause();
00562 m_pushedButton = pause_button;
00563 }
00564 else if (buttonname == "stop_button")
00565 {
00566 stop();
00567 m_pushedButton = stop_button;
00568 }
00569 }
00570
00571 void PlaybackBoxMusic::showMenu()
00572 {
00573 if (playlist_popup)
00574 return;
00575
00576 playlist_popup = new MythPopupBox(gContext->GetMainWindow(),
00577 "playlist_popup");
00578
00579 if (menufilters)
00580 {
00581 QLabel *caption = playlist_popup->addLabel(tr("Change Filter"), MythPopupBox::Large);
00582 caption->setAlignment(Qt::AlignCenter);
00583 }
00584
00585 QButton *button = playlist_popup->addButton(tr("Smart playlists"), this,
00586 SLOT(showSmartPlaylistDialog()));
00587
00588 QLabel *splitter = playlist_popup->addLabel(" ", MythPopupBox::Small);
00589 splitter->setLineWidth(2);
00590 splitter->setFrameShape(QFrame::HLine);
00591 splitter->setFrameShadow(QFrame::Sunken);
00592 splitter->setMaximumHeight((int) (5 * hmult));
00593 splitter->setMaximumHeight((int) (5 * hmult));
00594
00595 playlist_popup->addButton(tr("Search"), this,
00596 SLOT(showSearchDialog()));
00597 playlist_popup->addButton(tr("From CD"), this,
00598 SLOT(fromCD()));
00599 playlist_popup->addButton(tr("All Tracks"), this,
00600 SLOT(allTracks()));
00601 if (curMeta)
00602 {
00603 playlist_popup->addButton(tr("Tracks by current Artist"), this,
00604 SLOT(byArtist()));
00605 playlist_popup->addButton(tr("Tracks from current Album"), this,
00606 SLOT(byAlbum()));
00607 playlist_popup->addButton(tr("Tracks from current Genre"), this,
00608 SLOT(byGenre()));
00609 playlist_popup->addButton(tr("Tracks from current Year"), this,
00610 SLOT(byYear()));
00611 playlist_popup->addButton(tr("Tracks with same Title"), this,
00612 SLOT(byTitle()));
00613 }
00614
00615 playlist_popup->ShowPopup(this, SLOT(closePlaylistPopup()));
00616
00617 button->setFocus();
00618 }
00619
00620 void PlaybackBoxMusic::closePlaylistPopup()
00621 {
00622 if (!playlist_popup)
00623 return;
00624
00625 playlist_popup->hide();
00626 playlist_popup->deleteLater();
00627 playlist_popup = NULL;
00628 }
00629
00630 void PlaybackBoxMusic::allTracks()
00631 {
00632 if (!playlist_popup)
00633 return;
00634
00635 closePlaylistPopup();
00636 updatePlaylistFromQuickPlaylist("ORDER BY music_artists.artist_name, album_name, track");
00637 }
00638
00639 void PlaybackBoxMusic::fromCD()
00640 {
00641 if (!playlist_popup)
00642 return;
00643
00644 updatePlaylistFromCD();
00645 closePlaylistPopup();
00646 }
00647
00648 void PlaybackBoxMusic::showSmartPlaylistDialog()
00649 {
00650 if (!playlist_popup)
00651 return;
00652
00653
00654 gMusicData->all_music->save();
00655
00656 closePlaylistPopup();
00657
00658 SmartPlaylistDialog dialog(gContext->GetMainWindow(), "smartplaylistdialog");
00659 dialog.setSmartPlaylist(curSmartPlaylistCategory, curSmartPlaylistName);
00660
00661 DialogCode res = dialog.ExecPopup();
00662
00663 if (kDialogCodeRejected != res)
00664 {
00665 dialog.getSmartPlaylist(curSmartPlaylistCategory, curSmartPlaylistName);
00666 updatePlaylistFromSmartPlaylist();
00667 }
00668 }
00669
00670 void PlaybackBoxMusic::showSearchDialog()
00671 {
00672 if (!playlist_popup)
00673 return;
00674
00675 closePlaylistPopup();
00676
00677 SearchDialog dialog(gContext->GetMainWindow(), "searchdialog");
00678
00679 DialogCode res = dialog.ExecPopupAtXY(-1, 20);
00680
00681 if (kDialogCodeRejected != res)
00682 {
00683 QString whereClause;
00684 dialog.getWhereClause(whereClause);
00685 updatePlaylistFromQuickPlaylist(whereClause);
00686 }
00687 }
00688
00689 void PlaybackBoxMusic::byArtist()
00690 {
00691 if (!playlist_popup || !curMeta)
00692 return;
00693
00694 QString value = formattedFieldValue(curMeta->Artist().utf8());
00695 QString whereClause = "WHERE music_artists.artist_name = " + value +
00696 " ORDER BY album_name, track";
00697
00698 closePlaylistPopup();
00699 updatePlaylistFromQuickPlaylist(whereClause);
00700 }
00701
00702 void PlaybackBoxMusic::byAlbum()
00703 {
00704 if (!playlist_popup || !curMeta)
00705 return;
00706
00707 QString value = formattedFieldValue(curMeta->Album().utf8());
00708 QString whereClause = "WHERE album_name = " + value +
00709 " ORDER BY track";
00710 closePlaylistPopup();
00711 updatePlaylistFromQuickPlaylist(whereClause);
00712 }
00713
00714 void PlaybackBoxMusic::byGenre()
00715 {
00716 if (!playlist_popup || !curMeta)
00717 return;
00718
00719 QString value = formattedFieldValue(curMeta->Genre().utf8());
00720 QString whereClause = "WHERE genre = " + value +
00721 " ORDER BY music_artists.artist_name, album_name, track";
00722 closePlaylistPopup();
00723 updatePlaylistFromQuickPlaylist(whereClause);
00724 }
00725
00726 void PlaybackBoxMusic::byYear()
00727 {
00728 if (!playlist_popup || !curMeta)
00729 return;
00730
00731 QString value = formattedFieldValue(curMeta->Year());
00732 QString whereClause = "WHERE music_songs.year = " + value +
00733 " ORDER BY music_artists.artist_name, album_name, track";
00734 closePlaylistPopup();
00735 updatePlaylistFromQuickPlaylist(whereClause);
00736 }
00737
00738 void PlaybackBoxMusic::byTitle()
00739 {
00740 if (!playlist_popup || !curMeta)
00741 return;
00742
00743 QString value = formattedFieldValue(curMeta->Title().utf8());
00744 QString whereClause = "WHERE music_songs.name = " + value +
00745 " ORDER BY music_artists.artist_name, album_name, track";
00746 closePlaylistPopup();
00747 updatePlaylistFromQuickPlaylist(whereClause);
00748 }
00749
00750 void PlaybackBoxMusic::updatePlaylistFromQuickPlaylist(QString whereClause)
00751 {
00752 doUpdatePlaylist(whereClause);
00753 }
00754
00755 void PlaybackBoxMusic::doUpdatePlaylist(QString whereClause)
00756 {
00757 bool bRemoveDups;
00758 InsertPLOption insertOption;
00759 PlayPLOption playOption;
00760 int curTrackID, trackCount;
00761
00762 if (!menufilters && !getInsertPLOptions(insertOption, playOption, bRemoveDups))
00763 return;
00764
00765 QValueList <int> branches_to_current_node;
00766 trackCount = music_tree_list->getCurrentNode()->siblingCount();
00767
00768
00769 if (curMeta)
00770 {
00771 QValueList <int> *a_route;
00772 a_route = music_tree_list->getRouteToActive();
00773 branches_to_current_node = *a_route;
00774 curTrackID = curMeta->ID();
00775 }
00776 else
00777 {
00778
00779
00780 branches_to_current_node.clear();
00781 branches_to_current_node.append(0);
00782 branches_to_current_node.append(1);
00783 branches_to_current_node.append(0);
00784 curTrackID = 0;
00785 }
00786
00787 visual_mode_timer->stop();
00788
00789 if (whereClause != "")
00790 {
00791
00792 if (menufilters)
00793 gMusicData->all_playlists->getActive()->fillSonglistFromQuery(
00794 whereClause, false, PL_FILTERONLY, curTrackID);
00795 else
00796 gMusicData->all_playlists->getActive()->fillSonglistFromQuery(
00797 whereClause, bRemoveDups, insertOption, curTrackID);
00798 }
00799 else
00800 {
00801
00802 if (menufilters)
00803 gMusicData->all_playlists->getActive()->fillSonglistFromSmartPlaylist(
00804 curSmartPlaylistCategory, curSmartPlaylistName,
00805 false, PL_FILTERONLY, curTrackID);
00806 else
00807 {
00808 gMusicData->all_playlists->getActive()->fillSonglistFromSmartPlaylist(
00809 curSmartPlaylistCategory, curSmartPlaylistName,
00810 bRemoveDups, insertOption, curTrackID);
00811 }
00812 }
00813
00814 if (visual_mode_delay > 0)
00815 visual_mode_timer->start(visual_mode_delay * 1000);
00816
00817 constructPlaylistTree();
00818
00819 if (!menufilters)
00820 {
00821 switch (playOption)
00822 {
00823 case PL_CURRENT:
00824
00825 if (!music_tree_list->tryToSetActive(branches_to_current_node))
00826 playFirstTrack();
00827 break;
00828
00829 case PL_FIRST:
00830 playFirstTrack();
00831 break;
00832
00833 case PL_FIRSTNEW:
00834 {
00835 switch (insertOption)
00836 {
00837 case PL_REPLACE:
00838 playFirstTrack();
00839 break;
00840
00841 case PL_INSERTATEND:
00842 {
00843 GenericTree *node = NULL;
00844 pause();
00845 if (music_tree_list->tryToSetActive(branches_to_current_node))
00846 {
00847 node = music_tree_list->getCurrentNode()->getParent();
00848 if (node)
00849 {
00850 node = node->getChildAt((uint) trackCount);
00851 }
00852 }
00853
00854 if (node)
00855 {
00856 music_tree_list->setCurrentNode(node);
00857 music_tree_list->select();
00858 }
00859 else
00860 playFirstTrack();
00861
00862 break;
00863 }
00864
00865 case PL_INSERTAFTERCURRENT:
00866 pause();
00867 if (music_tree_list->tryToSetActive(branches_to_current_node))
00868 next();
00869 else
00870 playFirstTrack();
00871 break;
00872
00873 default:
00874 playFirstTrack();
00875 }
00876
00877 break;
00878 }
00879 }
00880 }
00881
00882 music_tree_list->refresh();
00883 }
00884
00885 void PlaybackBoxMusic::playFirstTrack()
00886 {
00887 QValueList <int> branches_to_current_node;
00888
00889 stop();
00890 wipeTrackInfo();
00891 branches_to_current_node.clear();
00892 branches_to_current_node.append(0);
00893 branches_to_current_node.append(1);
00894 branches_to_current_node.append(0);
00895 music_tree_list->moveToNodesFirstChild(branches_to_current_node);
00896 }
00897
00898 void PlaybackBoxMusic::updatePlaylistFromCD()
00899 {
00900 if (!cd_reader_thread)
00901 {
00902 cd_reader_thread = new ReadCDThread(m_CDdevice);
00903 cd_reader_thread->start();
00904 }
00905
00906 if (!cd_watcher)
00907 {
00908 cd_watcher = new QTimer(this);
00909 connect(cd_watcher, SIGNAL(timeout()), this, SLOT(occasionallyCheckCD()));
00910 cd_watcher->start(1000);
00911 }
00912
00913 }
00914
00915 void PlaybackBoxMusic::postUpdate()
00916 {
00917 QValueList <int> branches_to_current_node;
00918
00919 if (visual_mode_delay > 0)
00920 visual_mode_timer->start(visual_mode_delay * 1000);
00921
00922 constructPlaylistTree();
00923
00924 stop();
00925 wipeTrackInfo();
00926
00927
00928 branches_to_current_node.clear();
00929 branches_to_current_node.append(0);
00930 branches_to_current_node.append(1);
00931 branches_to_current_node.append(0);
00932 music_tree_list->moveToNodesFirstChild(branches_to_current_node);
00933 music_tree_list->refresh();
00934 }
00935
00936 void PlaybackBoxMusic::occasionallyCheckCD()
00937 {
00938 if (cd_reader_thread->getLock()->locked())
00939 return;
00940
00941 if (!scan_for_cd)
00942 {
00943 cd_watcher->stop();
00944 delete cd_watcher;
00945 cd_watcher = NULL;
00946
00947 cd_reader_thread->wait();
00948 delete cd_reader_thread;
00949 cd_reader_thread = NULL;
00950 }
00951
00952 if (!scan_for_cd || cd_reader_thread->statusChanged())
00953 {
00954 gMusicData->all_playlists->clearCDList();
00955 gMusicData->all_playlists->getActive()->ripOutAllCDTracksNow();
00956
00957 if (gMusicData->all_music->getCDTrackCount())
00958 {
00959 visual_mode_timer->stop();
00960
00961 gMusicData->all_playlists->getActive()->removeAllTracks();
00962 gMusicData->all_playlists->getActive()->fillSongsFromCD();
00963
00964 }
00965
00966 postUpdate();
00967 }
00968
00969 if (scan_for_cd && !cd_reader_thread->running())
00970 cd_reader_thread->start();
00971 }
00972
00973 void PlaybackBoxMusic::updatePlaylistFromSmartPlaylist()
00974 {
00975 doUpdatePlaylist("");
00976 }
00977
00978 void PlaybackBoxMusic::showEditMetadataDialog()
00979 {
00980 if (!curMeta)
00981 {
00982 return;
00983 }
00984
00985
00986
00987 GenericTree *node = music_tree_list->getCurrentNode();
00988 Metadata *editMeta = gMusicData->all_music->getMetadata( node->getInt() );
00989
00990 if (!editMeta)
00991 return;
00992
00993 EditMetadataDialog editDialog(editMeta, gContext->GetMainWindow(),
00994 "edit_metadata", "music-", "edit metadata");
00995 if (kDialogCodeRejected != editDialog.exec())
00996 {
00997 MythBusyDialog *busy = new MythBusyDialog(
00998 QObject::tr("Rebuilding music tree"));
00999 busy->start();
01000
01001 mainvisual->deleteMetadata();
01002
01003
01004 QValueList <int> branches_to_current_node;
01005
01006 QValueList <int> *a_route;
01007 a_route = music_tree_list->getRouteToActive();
01008 branches_to_current_node = *a_route;
01009
01010
01011 gMusicData->all_music->save();
01012 gMusicData->all_music->startLoading();
01013 while (!gMusicData->all_music->doneLoading())
01014 {
01015 qApp->processEvents();
01016 usleep(50000);
01017 }
01018 gMusicData->all_playlists->postLoad();
01019
01020 constructPlaylistTree();
01021
01022 if (music_tree_list->tryToSetActive(branches_to_current_node))
01023 {
01024
01025 }
01026 else
01027 {
01028
01029 stop();
01030 wipeTrackInfo();
01031 branches_to_current_node.clear();
01032 branches_to_current_node.append(0);
01033 branches_to_current_node.append(1);
01034 branches_to_current_node.append(0);
01035 music_tree_list->moveToNodesFirstChild(branches_to_current_node);
01036 }
01037
01038 GenericTree *node = music_tree_list->getCurrentNode();
01039 curMeta = gMusicData->all_music->getMetadata(node->getInt());
01040 updateTrackInfo(curMeta);
01041 mainvisual->setMetadata(curMeta);
01042
01043 setShuffleMode(gPlayer->getShuffleMode());
01044
01045 music_tree_list->refresh();
01046
01047 busy->Close();
01048 busy->deleteLater();
01049 }
01050 }
01051
01052 void PlaybackBoxMusic::checkForPlaylists()
01053 {
01054
01055
01056 if (first_playlist_check)
01057 {
01058 first_playlist_check = false;
01059 repaint();
01060 }
01061 else
01062 {
01063 if (gMusicData->all_playlists->doneLoading() &&
01064 gMusicData->all_music->doneLoading())
01065 {
01066 if (progress)
01067 {
01068 progress->Close();
01069 progress->deleteLater();
01070 progress = NULL;
01071 progress_type = kProgressNone;
01072 }
01073
01074 if (tree_is_done)
01075 {
01076 if (scan_for_cd)
01077 updatePlaylistFromCD();
01078
01079 music_tree_list->showWholeTree(show_whole_tree);
01080 QValueList <int> branches_to_current_node;
01081 branches_to_current_node.append(0);
01082 branches_to_current_node.append(1);
01083 branches_to_current_node.append(0);
01084
01085 if (gPlayer->isPlaying())
01086 {
01087 restorePosition(gPlayer->getRouteToCurrent());
01088 }
01089 else
01090 {
01091 if (resumemode > MusicPlayer::RESUME_OFF)
01092 restorePosition(gContext->GetSetting("MusicBookmark", ""));
01093 else
01094 music_tree_list->moveToNodesFirstChild(branches_to_current_node);
01095 }
01096
01097 music_tree_list->refresh();
01098 if (show_whole_tree)
01099 setContext(1);
01100 else
01101 setContext(2);
01102 updateForeground();
01103 mainvisual->setVisual(visual_modes[current_visual]);
01104
01105 if (curMeta)
01106 updateTrackInfo(curMeta);
01107
01108 return;
01109 }
01110 else
01111 {
01112 constructPlaylistTree();
01113 }
01114 }
01115 else
01116 {
01117 if (!gMusicData->all_music->doneLoading())
01118 {
01119
01120
01121 if (gMusicData->all_music->count() >= 250)
01122 {
01123 if (!progress)
01124 {
01125 progress = new MythProgressDialog(
01126 QObject::tr("Loading Music"), gMusicData->all_music->count());
01127 progress_type = kProgressMusic;
01128 }
01129 progress->setProgress(gMusicData->all_music->countLoaded());
01130 }
01131 }
01132 else if (progress_type == kProgressMusic)
01133 {
01134 if (progress)
01135 {
01136 progress->Close();
01137 progress->deleteLater();
01138 }
01139 progress = NULL;
01140 progress_type = kProgressNone;
01141 }
01142 }
01143 }
01144
01145 waiting_for_playlists_timer->start(100, TRUE);
01146 }
01147
01148 void PlaybackBoxMusic::changeVolume(bool up_or_down)
01149 {
01150 if (volume_control && gPlayer->getOutput())
01151 {
01152 if (up_or_down)
01153 gPlayer->getOutput()->AdjustCurrentVolume(2);
01154 else
01155 gPlayer->getOutput()->AdjustCurrentVolume(-2);
01156 showVolume(true);
01157 }
01158 }
01159
01160 void PlaybackBoxMusic::changeSpeed(bool up_or_down)
01161 {
01162 if (gPlayer->getOutput())
01163 {
01164 if (up_or_down)
01165 gPlayer->incSpeed();
01166 else
01167 gPlayer->decSpeed();
01168 showSpeed(true);
01169 }
01170 }
01171
01172 void PlaybackBoxMusic::toggleMute()
01173 {
01174 if (volume_control && gPlayer->getOutput())
01175 {
01176 gPlayer->getOutput()->ToggleMute();
01177 showVolume(true);
01178 }
01179 }
01180
01181 void PlaybackBoxMusic::showProgressBar()
01182 {
01183 if (progress_bar)
01184 {
01185 progress_bar->SetTotal(maxTime);
01186 progress_bar->SetUsed(currentTime);
01187 }
01188 }
01189
01190 void PlaybackBoxMusic::showVolume(bool on_or_off)
01191 {
01192 float volume_level;
01193 if (speed_status && speed_status->getOrder() != -1)
01194 {
01195 speed_status->SetOrder(-1);
01196 speed_status->refresh();
01197 }
01198
01199 if (volume_control && gPlayer->getOutput())
01200 {
01201 if (volume_status)
01202 {
01203 if (on_or_off)
01204 {
01205 volume_status->SetUsed(gPlayer->getOutput()->GetCurrentVolume());
01206 volume_status->SetOrder(0);
01207 volume_status->refresh();
01208 volume_display_timer->start(2000, true);
01209 if (class LCD *lcd = LCD::Get())
01210 lcd->switchToVolume("Music");
01211
01212 if (gPlayer->getOutput()->GetMute())
01213 volume_level = 0.0;
01214 else
01215 volume_level = (float)gPlayer->getOutput()->GetCurrentVolume() /
01216 (float)100;
01217
01218 if (class LCD *lcd = LCD::Get())
01219 lcd->setVolumeLevel(volume_level);
01220 }
01221 else
01222 {
01223 if (volume_status->getOrder() != -1)
01224 {
01225 volume_status->SetOrder(-1);
01226 volume_status->refresh();
01227 }
01228
01229 if (curMeta)
01230 setTrackOnLCD(curMeta);
01231 }
01232 }
01233 }
01234 }
01235
01236 void PlaybackBoxMusic::showSpeed(bool on_or_off)
01237 {
01238 if (speed_status)
01239 {
01240 if (volume_status && (volume_status->getOrder() != -1))
01241 {
01242 volume_status->SetOrder(-1);
01243 volume_status->refresh();
01244 }
01245
01246 if (on_or_off)
01247 {
01248 QString speed_text;
01249 float playSpeed = gPlayer->getSpeed();
01250 speed_text.sprintf("x%4.2f",playSpeed);
01251 speed_status->SetText(speed_text);
01252 speed_status->SetOrder(0);
01253 speed_status->refresh();
01254 volume_display_timer->start(2000, true);
01255 }
01256 }
01257
01258 if (class LCD *lcd = LCD::Get())
01259 {
01260 QString speed_text;
01261 float playSpeed = gPlayer->getSpeed();
01262 speed_text.sprintf("x%4.2f", playSpeed);
01263 speed_text = tr("Speed: ") + speed_text;
01264 QPtrList<LCDTextItem> textItems;
01265 textItems.setAutoDelete(true);
01266 textItems.append(new LCDTextItem(lcd->getLCDHeight() / 2, ALIGN_CENTERED,
01267 speed_text, "Generic", false));
01268 lcd->switchToGeneric(&textItems);
01269 }
01270 }
01271
01272 void PlaybackBoxMusic::resetTimer()
01273 {
01274 if (visual_mode_delay > 0)
01275 visual_mode_timer->changeInterval(visual_mode_delay * 1000);
01276 }
01277
01278 void PlaybackBoxMusic::play()
01279 {
01280 if (gPlayer->isPlaying())
01281 gPlayer->stop();
01282
01283 if (curMeta)
01284 playfile = curMeta->Filename();
01285 else
01286 {
01287
01288 wipeTrackInfo();
01289 return;
01290 }
01291
01292 if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
01293 {
01294 gPlayer->pause();
01295 return;
01296 }
01297
01298 gPlayer->setCurrentNode(music_tree_list->getCurrentNode());
01299 gPlayer->playFile(playfile);
01300
01301 currentTime = 0;
01302
01303 mainvisual->setDecoder(gPlayer->getDecoder());
01304 mainvisual->setOutput(gPlayer->getOutput());
01305 mainvisual->setMetadata(curMeta);
01306
01307 if (gPlayer->isPlaying())
01308 {
01309 if (resumemode == MusicPlayer::RESUME_EXACT &&
01310 gContext->GetNumSetting("MusicBookmarkPosition", 0) > 0)
01311 {
01312 seek(gContext->GetNumSetting("MusicBookmarkPosition", 0));
01313 gContext->SaveSetting("MusicBookmarkPosition", 0);
01314 }
01315 }
01316
01317 bannerEnable(curMeta, show_album_art);
01318 }
01319
01320 void PlaybackBoxMusic::visEnable()
01321 {
01322 if (!visualizer_status != 2 && gPlayer->isPlaying())
01323 {
01324 setUpdatesEnabled(false);
01325 mainvisual->setGeometry(0, 0, screenwidth, screenheight);
01326 visualizer_status = 2;
01327 }
01328
01329 bannerDisable();
01330 }
01331
01332 void PlaybackBoxMusic::bannerEnable(QString text, int millis)
01333 {
01334 if (visualizer_status != 2)
01335 return;
01336
01337 mainvisual->showBanner(text, millis);
01338 }
01339
01340 void PlaybackBoxMusic::bannerEnable(Metadata *mdata, bool fullScreen)
01341 {
01342 mainvisual->showBanner(mdata, fullScreen, visualizer_status, 8000);
01343 }
01344
01345 void PlaybackBoxMusic::bannerToggle(Metadata *mdata)
01346 {
01347 if (mainvisual->bannerIsShowing())
01348 bannerDisable();
01349 else
01350 bannerEnable(mdata, false);
01351 }
01352
01353 void PlaybackBoxMusic::bannerDisable()
01354 {
01355 mainvisual->hideBanner();
01356 }
01357
01358 void PlaybackBoxMusic::CycleVisualizer()
01359 {
01360
01361
01362 if (visual_modes.count() > 1 && visualizer_status > 0)
01363 {
01364 if (random_visualizer)
01365 {
01366 unsigned int next_visualizer;
01367
01368
01369 do
01370 next_visualizer = rand() % visual_modes.count();
01371 while (next_visualizer == current_visual);
01372 current_visual = next_visualizer;
01373 }
01374 else
01375 {
01376
01377 current_visual = (current_visual + 1) % visual_modes.count();
01378 }
01379
01380
01381 resetTimer();
01382 mainvisual->setVisual("Blank");
01383 mainvisual->setVisual(visual_modes[current_visual]);
01384 }
01385 else if (visual_modes.count() == 1 && visual_modes[current_visual] == "AlbumArt" &&
01386 visualizer_status > 0)
01387 {
01388
01389
01390
01391 resetTimer();
01392 mainvisual->setVisual("Blank");
01393 mainvisual->setVisual(visual_modes[current_visual]);
01394 }
01395 }
01396
01397 void PlaybackBoxMusic::setTrackOnLCD(Metadata *mdata)
01398 {
01399 LCD *lcd = LCD::Get();
01400 if (!lcd || !mdata)
01401 return;
01402
01403
01404 lcd->switchToMusic(mdata->Artist(),
01405 mdata->Album(),
01406 mdata->Title());
01407 }
01408
01409 void PlaybackBoxMusic::pause(void)
01410 {
01411 gPlayer->pause();
01412 }
01413
01414 void PlaybackBoxMusic::stop(void)
01415 {
01416 gPlayer->stop();
01417
01418 mainvisual->setDecoder(0);
01419 mainvisual->setOutput(0);
01420 mainvisual->deleteMetadata();
01421
01422 QString time_string = getTimeString(maxTime, 0);
01423
01424 if (time_text)
01425 time_text->SetText(time_string);
01426 if (info_text)
01427 info_text->SetText("");
01428 }
01429
01430 void PlaybackBoxMusic::stopAll()
01431 {
01432 if (class LCD *lcd = LCD::Get())
01433 {
01434 lcd->switchToTime();
01435 }
01436
01437 mainvisual->setDecoder(0);
01438 mainvisual->setOutput(0);
01439 mainvisual->deleteMetadata();
01440
01441 gPlayer->stop(true);
01442 }
01443
01444 void PlaybackBoxMusic::previous()
01445 {
01446 if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_ALL)
01447 {
01448 if (music_tree_list->prevActive(true, show_whole_tree))
01449 music_tree_list->activate();
01450 }
01451 else
01452 {
01453 if (music_tree_list->prevActive(false, show_whole_tree))
01454 music_tree_list->activate();
01455 }
01456
01457 if (visualizer_status > 0 && cycle_visualizer)
01458 CycleVisualizer();
01459 }
01460
01461 void PlaybackBoxMusic::next()
01462 {
01463 if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_ALL)
01464 {
01465
01466
01467
01468 if (music_tree_list->nextActive(true, show_whole_tree))
01469 music_tree_list->activate();
01470 else
01471 end();
01472 }
01473 else
01474 {
01475 if (music_tree_list->nextActive(false, show_whole_tree))
01476 music_tree_list->activate();
01477 else
01478 end();
01479 }
01480
01481 if (visualizer_status > 0 && cycle_visualizer)
01482 CycleVisualizer();
01483 }
01484
01485 void PlaybackBoxMusic::nextAuto()
01486 {
01487 if (gPlayer->getRepeatMode() == MusicPlayer::REPEAT_TRACK)
01488 play();
01489 else
01490 next();
01491 }
01492
01493 void PlaybackBoxMusic::seekforward()
01494 {
01495 int nextTime = currentTime + 5;
01496 if (nextTime > maxTime)
01497 nextTime = maxTime;
01498 seek(nextTime);
01499 }
01500
01501 void PlaybackBoxMusic::seekback()
01502 {
01503 int nextTime = currentTime - 5;
01504 if (nextTime < 0)
01505 nextTime = 0;
01506 seek(nextTime);
01507 }
01508
01509 void PlaybackBoxMusic::seek(int pos)
01510 {
01511 if (gPlayer->getOutput())
01512 {
01513 gPlayer->getOutput()->Reset();
01514 gPlayer->getOutput()->SetTimecode(pos*1000);
01515
01516 if (gPlayer->getDecoder() && gPlayer->getDecoder()->running())
01517 {
01518 gPlayer->getDecoder()->lock();
01519 gPlayer->getDecoder()->seek(pos);
01520
01521 if (mainvisual)
01522 {
01523 mainvisual->mutex()->lock();
01524 mainvisual->prepare();
01525 mainvisual->mutex()->unlock();
01526 }
01527
01528 gPlayer->getDecoder()->unlock();
01529 }
01530
01531 if (!gPlayer->isPlaying())
01532 {
01533 currentTime = pos;
01534 if (time_text)
01535 time_text->SetText(getTimeString(pos, maxTime));
01536
01537 showProgressBar();
01538
01539 if (class LCD *lcd = LCD::Get())
01540 {
01541 float percent_heard = maxTime <= 0 ? 0.0 : ((float)pos /
01542 (float)maxTime);
01543
01544 QString lcd_time_string = getTimeString(pos, maxTime);
01545
01546
01547 if (lcd_time_string.length() > lcd->getLCDWidth())
01548 lcd_time_string.remove(' ');
01549
01550 lcd->setMusicProgress(lcd_time_string, percent_heard);
01551 }
01552 }
01553 }
01554 }
01555
01556 void PlaybackBoxMusic::setShuffleMode(MusicPlayer::ShuffleMode mode)
01557 {
01558 MusicPlayer::ShuffleMode shufflemode = mode;
01559 QString state;
01560
01561 switch (shufflemode)
01562 {
01563 case MusicPlayer::SHUFFLE_INTELLIGENT:
01564 state = tr("Smart");
01565 if (class LCD *lcd = LCD::Get())
01566 lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_SMART);
01567 break;
01568 case MusicPlayer::SHUFFLE_RANDOM:
01569 state = tr("Rand");
01570 if (class LCD *lcd = LCD::Get())
01571 lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_RAND);
01572 break;
01573 case MusicPlayer::SHUFFLE_ALBUM:
01574 state = tr("Album");
01575 if (class LCD *lcd = LCD::Get())
01576 lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ALBUM);
01577 break;
01578 case MusicPlayer::SHUFFLE_ARTIST:
01579 state = tr("Artist");
01580 if (class LCD *lcd = LCD::Get())
01581 lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_ARTIST);
01582 break;
01583 default:
01584 state = tr("None");
01585 if (class LCD *lcd = LCD::Get())
01586 lcd->setMusicShuffle(LCD::MUSIC_SHUFFLE_NONE);
01587 break;
01588 }
01589
01590 if (shuffle_state_text)
01591 shuffle_state_text->SetText(state);
01592
01593 if(shuffle_button)
01594 {
01595 if (keyboard_accelerators)
01596 shuffle_button->setText(QString("1 %1: %2").arg(tr("Shuffle"))
01597 .arg(state));
01598 else
01599 shuffle_button->setText(QString("%1: %2").arg(tr("Shuffle"))
01600 .arg(state));
01601 }
01602
01603 bannerEnable(QString("%1: %2").arg(tr("Shuffle")).arg(state), 4000);
01604
01605 if (shufflemode != MusicPlayer::SHUFFLE_OFF)
01606 music_tree_list->scrambleParents(true);
01607 else
01608 music_tree_list->scrambleParents(false);
01609
01610 music_tree_list->setTreeOrdering(shufflemode + 1);
01611 if (listAsShuffled)
01612 music_tree_list->setVisualOrdering(shufflemode + 1);
01613 else
01614 music_tree_list->setVisualOrdering(1);
01615 music_tree_list->refresh();
01616
01617 if (gPlayer->isPlaying())
01618 setTrackOnLCD(curMeta);
01619 }
01620
01621 void PlaybackBoxMusic::toggleShuffle(void)
01622 {
01623 setShuffleMode(gPlayer->toggleShuffleMode());
01624 }
01625
01626 void PlaybackBoxMusic::increaseRating()
01627 {
01628 if(!curMeta)
01629 return;
01630
01631
01632
01633
01634 if (showrating)
01635 {
01636 curMeta->incRating();
01637 if (ratings_image)
01638 ratings_image->setRepeat(curMeta->Rating());
01639 }
01640 }
01641
01642 void PlaybackBoxMusic::decreaseRating()
01643 {
01644 if(!curMeta)
01645 return;
01646
01647 if (showrating)
01648 {
01649 curMeta->decRating();
01650 if (ratings_image)
01651 ratings_image->setRepeat(curMeta->Rating());
01652 }
01653 }
01654
01655 void PlaybackBoxMusic::setRepeatMode(MusicPlayer::RepeatMode mode)
01656 {
01657 MusicPlayer::RepeatMode repeatmode = mode;
01658 QString state;
01659
01660 switch (repeatmode)
01661 {
01662 case MusicPlayer::REPEAT_ALL:
01663 state = tr("All");
01664 if (class LCD *lcd = LCD::Get())
01665 lcd->setMusicRepeat (LCD::MUSIC_REPEAT_ALL);
01666 break;
01667 case MusicPlayer::REPEAT_TRACK:
01668 state = tr("Track");
01669 if (class LCD *lcd = LCD::Get())
01670 lcd->setMusicRepeat (LCD::MUSIC_REPEAT_TRACK);
01671 break;
01672 default:
01673 state = tr("None");
01674 if (class LCD *lcd = LCD::Get())
01675 lcd->setMusicRepeat (LCD::MUSIC_REPEAT_NONE);
01676 break;
01677 }
01678
01679 if (repeat_state_text)
01680 repeat_state_text->SetText(state);
01681
01682
01683 if(repeat_button)
01684 {
01685 if (keyboard_accelerators)
01686 repeat_button->setText(QString("2 %1: %2").arg(tr("Repeat"))
01687 .arg(state));
01688 else
01689 repeat_button->setText(QString("%1: %2").arg(tr("Repeat"))
01690 .arg(state));
01691 }
01692
01693 bannerEnable(QString("%1: %2").arg(tr("Repeat")).arg(state), 4000);
01694 }
01695
01696 void PlaybackBoxMusic::savePosition(uint position)
01697 {
01698 QValueList <int> branches_to_current_node;
01699
01700 if (curMeta)
01701 {
01702 QValueList <int> *a_route;
01703 a_route = music_tree_list->getRouteToActive();
01704 branches_to_current_node = *a_route;
01705 }
01706 else
01707 {
01708 branches_to_current_node.clear();
01709 branches_to_current_node.append(0);
01710 branches_to_current_node.append(1);
01711 branches_to_current_node.append(0);
01712 position = 0;
01713 }
01714
01715 QString s = "";
01716 QValueListIterator <int> it;
01717 for (it = branches_to_current_node.begin(); it != branches_to_current_node.end(); ++it)
01718 s += "," + QString::number(*it);
01719
01720 s.remove(0, 1);
01721
01722 gContext->SaveSetting("MusicBookmark", s);
01723 gContext->SaveSetting("MusicBookmarkPosition", position);
01724 }
01725
01726 void PlaybackBoxMusic::restorePosition(const QString &position)
01727 {
01728 QValueList <int> branches_to_current_node;
01729
01730 if (position != "")
01731 {
01732 QStringList list = QStringList::split(",", position);
01733
01734 for (QStringList::Iterator it = list.begin(); it != list.end(); ++it)
01735 branches_to_current_node.append((*it).toInt());
01736
01737 if (!show_whole_tree)
01738 {
01739
01740
01741
01742 if (branches_to_current_node[0] == 0 &&
01743 branches_to_current_node[1] == 1 &&
01744 branches_to_current_node[2] == 0)
01745 {
01746 if (music_tree_list->tryToSetActive(branches_to_current_node))
01747 {
01748 if (gPlayer->isPlaying())
01749 {
01750 GenericTree *node = music_tree_list->getCurrentNode();
01751 if (node)
01752 {
01753 curMeta = gMusicData->all_music->getMetadata(node->getInt());
01754 updateTrackInfo(curMeta);
01755
01756 maxTime = curMeta->Length() / 1000;
01757
01758 QString time_string = getTimeString(maxTime, 0);
01759
01760 mainvisual->setDecoder(gPlayer->getDecoder());
01761 mainvisual->setOutput(gPlayer->getOutput());
01762 mainvisual->setMetadata(curMeta);
01763 bannerEnable(curMeta, show_album_art);
01764 }
01765 }
01766 else
01767 music_tree_list->select();
01768 return;
01769 }
01770 }
01771 }
01772 else
01773 {
01774
01775 if (music_tree_list->tryToSetActive(branches_to_current_node))
01776 {
01777 if (gPlayer->isPlaying())
01778 {
01779 GenericTree *node = music_tree_list->getCurrentNode();
01780 if (node)
01781 {
01782 curMeta = gMusicData->all_music->getMetadata(node->getInt());
01783 updateTrackInfo(curMeta);
01784
01785 maxTime = curMeta->Length() / 1000;
01786
01787 QString time_string = getTimeString(maxTime, 0);
01788
01789 mainvisual->setDecoder(gPlayer->getDecoder());
01790 mainvisual->setOutput(gPlayer->getOutput());
01791 mainvisual->setMetadata(curMeta);
01792 bannerEnable(curMeta, show_album_art);
01793 }
01794 }
01795 else
01796 music_tree_list->select();
01797
01798 return;
01799 }
01800 }
01801 }
01802
01803 branches_to_current_node.clear();
01804 branches_to_current_node.append(0);
01805 branches_to_current_node.append(1);
01806 branches_to_current_node.append(0);
01807 music_tree_list->moveToNodesFirstChild(branches_to_current_node);
01808 }
01809
01810 void PlaybackBoxMusic::toggleRepeat()
01811 {
01812 setRepeatMode(gPlayer->toggleRepeatMode());
01813 }
01814
01815 void PlaybackBoxMusic::constructPlaylistTree()
01816 {
01817 GenericTree *active_playlist_node = gPlayer->constructPlaylist();
01818 GenericTree *playlist_tree = gPlayer->getPlaylistTree();
01819
01820 music_tree_list->assignTreeData(playlist_tree);
01821 music_tree_list->setCurrentNode(active_playlist_node);
01822 tree_is_done = true;
01823 }
01824
01825 void PlaybackBoxMusic::editPlaylist()
01826 {
01827
01828
01829 QValueList <int> branches_to_current_node;
01830
01831 if (curMeta)
01832 {
01833 QValueList <int> *a_route;
01834 a_route = music_tree_list->getRouteToActive();
01835 branches_to_current_node = *a_route;
01836 }
01837 else
01838 {
01839
01840
01841
01842 branches_to_current_node.clear();
01843 branches_to_current_node.append(0);
01844 branches_to_current_node.append(1);
01845 branches_to_current_node.append(0);
01846 }
01847
01848 visual_mode_timer->stop();
01849 DatabaseBox dbbox(gContext->GetMainWindow(), m_CDdevice,
01850 "music_select", "music-", "database box");
01851
01852 if (cd_watcher)
01853 cd_watcher->stop();
01854
01855 dbbox.exec();
01856 if (visual_mode_delay > 0)
01857 visual_mode_timer->start(visual_mode_delay * 1000);
01858
01859
01860
01861
01862 constructPlaylistTree();
01863 if (music_tree_list->tryToSetActive(branches_to_current_node))
01864 {
01865 music_tree_list->syncCurrentWithActive();
01866
01867 }
01868 else
01869 {
01870 stop();
01871 wipeTrackInfo();
01872 branches_to_current_node.clear();
01873 branches_to_current_node.append(0);
01874 branches_to_current_node.append(1);
01875 branches_to_current_node.append(0);
01876 music_tree_list->moveToNodesFirstChild(branches_to_current_node);
01877 }
01878 music_tree_list->refresh();
01879
01880 if (scan_for_cd && cd_watcher)
01881 cd_watcher->start(1000);
01882 }
01883
01884 void PlaybackBoxMusic::customEvent(QCustomEvent *event)
01885 {
01886 switch ((int)event->type())
01887 {
01888 case OutputEvent::Playing:
01889 {
01890 if (curMeta)
01891 updateTrackInfo(curMeta);
01892 statusString = tr("Playing stream.");
01893 break;
01894 }
01895
01896 case OutputEvent::Buffering:
01897 {
01898 statusString = tr("Buffering stream.");
01899 break;
01900 }
01901
01902 case OutputEvent::Paused:
01903 {
01904 statusString = tr("Stream paused.");
01905 break;
01906 }
01907
01908 case OutputEvent::Info:
01909 {
01910 OutputEvent *oe = (OutputEvent *) event;
01911
01912 int rs;
01913 currentTime = rs = oe->elapsedSeconds();
01914
01915 QString time_string = getTimeString(rs, maxTime);
01916
01917 showProgressBar();
01918
01919 if (curMeta)
01920 {
01921 if (class LCD *lcd = LCD::Get())
01922 {
01923 float percent_heard = maxTime<=0?0.0:((float)rs /
01924 (float)curMeta->Length()) * 1000.0;
01925
01926 QString lcd_time_string = time_string;
01927
01928
01929 if (time_string.length() > lcd->getLCDWidth())
01930 lcd_time_string.remove(' ');
01931
01932 lcd->setMusicProgress(lcd_time_string, percent_heard);
01933 }
01934 }
01935
01936 QString info_string;
01937
01938
01939 if (oe->bitrate() < 2000)
01940 {
01941 info_string.sprintf("%d "+tr("kbps")+ " %.1f "+ tr("kHz")+ " %s "+ tr("ch"),
01942 oe->bitrate(), float(oe->frequency()) / 1000.0,
01943 oe->channels() > 1 ? "2" : "1");
01944 }
01945 else
01946 {
01947 info_string.sprintf("%.1f "+ tr("kHz")+ " %s "+ tr("ch"),
01948 float(oe->frequency()) / 1000.0,
01949 oe->channels() > 1 ? "2" : "1");
01950 }
01951
01952 if (curMeta)
01953 {
01954 if (time_text)
01955 time_text->SetText(time_string);
01956 if (info_text)
01957 info_text->SetText(info_string);
01958 if (current_visualization_text)
01959 {
01960 current_visualization_text->SetText(visual_modes[current_visual]);
01961 current_visualization_text->refresh();
01962 }
01963 }
01964
01965 break;
01966 }
01967 case OutputEvent::Error:
01968 {
01969 statusString = tr("Output error.");
01970
01971 OutputEvent *aoe = (OutputEvent *) event;
01972
01973 VERBOSE(VB_IMPORTANT, QString("%1 %2").arg(statusString)
01974 .arg(*aoe->errorMessage()));
01975 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
01976 statusString,
01977 QString("MythMusic has encountered the following error:\n%1")
01978 .arg(*aoe->errorMessage()));
01979 stopAll();
01980
01981 break;
01982 }
01983 case DecoderEvent::Stopped:
01984 {
01985 statusString = tr("Stream stopped.");
01986
01987 break;
01988 }
01989 case DecoderEvent::Finished:
01990 {
01991 statusString = tr("Finished playing stream.");
01992 nextAuto();
01993 break;
01994 }
01995 case DecoderEvent::Error:
01996 {
01997 stop();
01998
01999 QApplication::sendPostedEvents();
02000
02001 statusString = tr("Decoder error.");
02002
02003 DecoderEvent *dxe = (DecoderEvent *) event;
02004
02005 VERBOSE(VB_IMPORTANT, QString("%1 %2").arg(statusString)
02006 .arg(*dxe->errorMessage()));
02007 MythPopupBox::showOkPopup(gContext->GetMainWindow(),
02008 statusString,
02009 QString("MythMusic has encountered the following error:\n%1")
02010 .arg(*dxe->errorMessage()));
02011 break;
02012 }
02013 }
02014
02015 QWidget::customEvent(event);
02016 }
02017
02018 void PlaybackBoxMusic::wipeTrackInfo()
02019 {
02020 if (title_text)
02021 title_text->SetText("");
02022 if (artist_text)
02023 artist_text->SetText("");
02024 if (album_text)
02025 album_text->SetText("");
02026 if (time_text)
02027 time_text->SetText("");
02028 if (info_text)
02029 info_text->SetText("");
02030 if (ratings_image)
02031 ratings_image->setRepeat(0);
02032 if (current_visualization_text)
02033 current_visualization_text->SetText("");
02034
02035 if (albumart_image)
02036 wipeAlbumArt();
02037 }
02038
02039 void PlaybackBoxMusic::updateTrackInfo(Metadata *mdata)
02040 {
02041 if (title_text)
02042 title_text->SetText(mdata->FormatTitle());
02043 if (artist_text)
02044 artist_text->SetText(mdata->FormatArtist());
02045 if (album_text)
02046 album_text->SetText(mdata->Album());
02047 if (albumart_image)
02048 showAlbumArtImage(mdata);
02049
02050 if (showrating)
02051 {
02052 if (ratings_image)
02053 ratings_image->setRepeat(mdata->Rating());
02054 }
02055
02056 setTrackOnLCD(mdata);
02057 }
02058
02059 void PlaybackBoxMusic::showAlbumArtImage(Metadata *mdata)
02060 {
02061 if (!albumart_image || !mdata)
02062 return;
02063
02064 QSize img_size = albumart_image->GetSize(true);
02065
02066 QImage albumArt = mdata->getAlbumArt();
02067
02068 if (!albumArt.isNull())
02069 {
02070
02071 albumArt = albumArt.smoothScale(img_size.width(), img_size.height(), QImage::ScaleMin);
02072 QPixmap img(albumArt);
02073 albumart_image->SetImage(img);
02074 albumart_image->refresh();
02075 }
02076 else
02077 {
02078 albumart_image->SetImage("mm_nothumb.png");
02079 albumart_image->LoadImage();
02080 }
02081 }
02082
02083 void PlaybackBoxMusic::wipeAlbumArt()
02084 {
02085 if (albumart_image)
02086 albumart_image->ResetImage();
02087 }
02088
02089 void PlaybackBoxMusic::handleTreeListSignals(int node_int, IntVector *attributes)
02090 {
02091 if (attributes->size() < 4)
02092 {
02093 VERBOSE(VB_IMPORTANT, "playbackbox.o: Worringly, a managed tree "
02094 "list is handing back item attributes of the wrong size");
02095 return;
02096 }
02097
02098 if (attributes->at(0) == 1 && !show_whole_tree)
02099 {
02100
02101 GenericTree *node = music_tree_list->getCurrentNode();
02102 if (node && node->getAttribute(0) == 0)
02103 {
02104
02105 Playlist *playlist = gMusicData->all_playlists->getPlaylist(node->getInt());
02106 if (playlist)
02107 {
02108 gMusicData->all_playlists->getActive()->fillSongsFromSonglist(
02109 playlist->getSonglist(), false);
02110
02111 constructPlaylistTree();
02112
02113
02114 playFirstTrack();
02115 return;
02116 }
02117 }
02118 }
02119
02120 if (attributes->at(0) == 1)
02121 {
02122
02123
02124 GenericTree *currentnode = music_tree_list->getCurrentNode();
02125 GenericTree *activenode = currentnode;
02126 if (currentnode && currentnode->childCount() > 0)
02127 {
02128 music_tree_list->syncCurrentWithActive();
02129 activenode = music_tree_list->getCurrentNode();
02130 }
02131
02132 curMeta = gMusicData->all_music->getMetadata(node_int);
02133
02134 updateTrackInfo(curMeta);
02135
02136 maxTime = curMeta->Length() / 1000;
02137
02138 QString time_string = getTimeString(maxTime, 0);
02139
02140 if (gPlayer->getOutput() && gPlayer->getOutput()->GetPause())
02141 {
02142 gPlayer->stop();
02143 }
02144 if (m_pushedButton && m_pushedButton->Name() == "play_button")
02145 {
02146
02147 play();
02148 }
02149 else if (play_button)
02150 play_button->push();
02151 else
02152 play();
02153
02154 if (activenode != currentnode)
02155 music_tree_list->setCurrentNode(currentnode);
02156
02157 }
02158 else
02159 {
02160 curMeta = NULL;
02161 wipeTrackInfo();
02162 }
02163 }
02164
02165
02166 void PlaybackBoxMusic::toggleFullBlankVisualizer()
02167 {
02168 if (fullscreen_blank)
02169 {
02170 fullscreen_blank = false;
02171
02172
02173
02174
02175
02176
02177 if(visual_blackhole)
02178 mainvisual->setGeometry(visual_blackhole->getScreenArea());
02179 else
02180 mainvisual->setGeometry(screenwidth + 10, screenheight + 10,
02181 160, 160);
02182 mainvisual->setVisual(visual_modes[current_visual]);
02183 bannerDisable();
02184 visualizer_status = 1;
02185 if(visual_mode_delay > 0)
02186 {
02187 visual_mode_timer->start(visual_mode_delay * 1000);
02188 }
02189 if (current_visualization_text)
02190 {
02191 current_visualization_text->SetText(visual_modes[current_visual]);
02192 current_visualization_text->refresh();
02193 }
02194 setUpdatesEnabled(true);
02195 }
02196 else
02197 {
02198
02199
02200
02201
02202 fullscreen_blank = true;
02203 mainvisual->setVisual("Blank");
02204 mainvisual->setGeometry(0, 0, screenwidth, screenheight);
02205 visualizer_status = 2;
02206 visual_mode_timer->stop();
02207 setUpdatesEnabled(false);
02208 bannerDisable();
02209 }
02210 }
02211
02212 void PlaybackBoxMusic::end()
02213 {
02214 stop();
02215
02216 if (class LCD *lcd = LCD::Get())
02217 lcd->switchToTime ();
02218 }
02219
02220 void PlaybackBoxMusic::wireUpTheme()
02221 {
02222
02223
02224
02225 music_tree_list = getUIManagedTreeListType("musictreelist");
02226 if (!music_tree_list)
02227 {
02228 VERBOSE(VB_IMPORTANT, "playbackbox.o: Couldn't find a music tree list "
02229 "in your theme");
02230 exit(0);
02231 }
02232 connect(music_tree_list, SIGNAL(nodeSelected(int, IntVector*)),
02233 this, SLOT(handleTreeListSignals(int, IntVector*)));
02234
02235
02236 title_text = getUITextType("title_text");
02237 artist_text = getUITextType("artist_text");
02238 time_text = getUITextType("time_text");
02239 info_text = getUITextType("info_text");
02240 album_text = getUITextType("album_text");
02241 ratings_image = getUIRepeatedImageType("ratings_image");
02242 current_visualization_text = getUITextType("current_visualization_text");
02243 progress_bar = getUIStatusBarType("progress_bar");
02244 volume_status = getUIStatusBarType("volume_status");
02245 if (volume_status)
02246 {
02247 volume_status->SetTotal(100);
02248 volume_status->SetOrder(-1);
02249 }
02250 speed_status = getUITextType("speed_status");
02251 if (speed_status)
02252 {
02253 speed_status->SetText("");
02254 speed_status->SetOrder(-1);
02255 }
02256
02257 visual_blackhole = getUIBlackHoleType("visual_blackhole");
02258
02259 albumart_image = getUIImageType("albumart");
02260
02261
02262 prev_button = getUIPushButtonType("prev_button");
02263 if (prev_button)
02264 connect(prev_button, SIGNAL(pushed()), this, SLOT(previous()));
02265
02266 rew_button = getUIPushButtonType("rew_button");
02267 if (rew_button)
02268 connect(rew_button, SIGNAL(pushed()), this, SLOT(seekback()));
02269
02270 pause_button = getUIPushButtonType("pause_button");
02271 pause_button->setLockOn();
02272 if (pause_button)
02273 connect(pause_button, SIGNAL(pushed(QString)), this,
02274 SLOT(handlePush(QString)));
02275
02276 play_button = getUIPushButtonType("play_button");
02277 play_button->setLockOn();
02278 if (play_button)
02279 connect(play_button, SIGNAL(pushed(QString)), this,
02280 SLOT(handlePush(QString)));
02281
02282 stop_button = getUIPushButtonType("stop_button");
02283 stop_button->setLockOn();
02284 if (stop_button)
02285 connect(stop_button, SIGNAL(pushed(QString)), this,
02286 SLOT(handlePush(QString)));
02287
02288 ff_button = getUIPushButtonType("ff_button");
02289 if (ff_button)
02290 connect(ff_button, SIGNAL(pushed()), this, SLOT(seekforward()));
02291
02292 next_button = getUIPushButtonType("next_button");
02293 if (next_button)
02294 connect(next_button, SIGNAL(pushed()), this, SLOT(next()));
02295
02296 shuffle_button = getUITextButtonType("shuffle_button");
02297 if (shuffle_button)
02298 connect(shuffle_button, SIGNAL(pushed()), this, SLOT(toggleShuffle()));
02299
02300 shuffle_state_text = getUITextType("shuffle_state");
02301
02302 repeat_button = getUITextButtonType("repeat_button");
02303 if (repeat_button)
02304 connect(repeat_button, SIGNAL(pushed()), this, SLOT(toggleRepeat()));
02305
02306 repeat_state_text = getUITextType("repeat_state");
02307
02308 pledit_button = getUITextButtonType("pledit_button");
02309 if (pledit_button)
02310 connect(pledit_button, SIGNAL(pushed()), this, SLOT(editPlaylist()));
02311
02312 vis_button = getUITextButtonType("vis_button");
02313 if (vis_button)
02314 connect(vis_button, SIGNAL(pushed()), this, SLOT(visEnable()));
02315 }
02316
02317 bool PlaybackBoxMusic::getInsertPLOptions(InsertPLOption &insertOption,
02318 PlayPLOption &playOption, bool &bRemoveDups)
02319 {
02320 MythPopupBox *popup = new MythPopupBox(gContext->GetMainWindow(),
02321 "playlist_popup");
02322
02323 QLabel *caption = popup->addLabel(tr("Update Playlist Options"), MythPopupBox::Medium);
02324 caption->setAlignment(Qt::AlignCenter);
02325
02326 QButton *button = popup->addButton(tr("Replace"));
02327 popup->addButton(tr("Insert after current track"));
02328 popup->addButton(tr("Append to end"));
02329 button->setFocus();
02330
02331 QLabel *splitter = popup->addLabel(" ", MythPopupBox::Small);
02332 splitter->setLineWidth(2);
02333 splitter->setFrameShape(QFrame::HLine);
02334 splitter->setFrameShadow(QFrame::Sunken);
02335 splitter->setMinimumHeight((int) (25 * hmult));
02336 splitter->setMaximumHeight((int) (25 * hmult));
02337
02338
02339 MythComboBox *playCombo = NULL;
02340 if (gPlayer->getShuffleMode() == MusicPlayer::SHUFFLE_OFF)
02341 {
02342 playCombo = new MythComboBox(false, popup, "play_combo" );
02343 playCombo->insertItem(tr("Continue playing current track"));
02344 playCombo->insertItem(tr("Play first track"));
02345 playCombo->insertItem(tr("Play first new track"));
02346 playCombo->setBackgroundOrigin(ParentOrigin);
02347 popup->addWidget(playCombo);
02348 }
02349
02350 MythCheckBox *dupsCheck = new MythCheckBox(popup);
02351 dupsCheck->setText(tr("Remove Duplicates"));
02352 dupsCheck->setChecked(false);
02353 dupsCheck->setBackgroundOrigin(ParentOrigin);
02354 popup->addWidget(dupsCheck);
02355
02356 DialogCode res = popup->ExecPopup();
02357 switch (res)
02358 {
02359 case kDialogCodeButton0:
02360 insertOption = PL_REPLACE;
02361 break;
02362 case kDialogCodeButton1:
02363 insertOption = PL_INSERTAFTERCURRENT;
02364 break;
02365 case kDialogCodeButton2:
02366 insertOption = PL_INSERTATEND;
02367 break;
02368 case kDialogCodeRejected:
02369 default:
02370 popup->deleteLater();
02371 return false;
02372 }
02373
02374 bRemoveDups = dupsCheck->isChecked();
02375
02376
02377
02378
02379 if (gPlayer->getShuffleMode() == MusicPlayer::SHUFFLE_OFF)
02380 {
02381 switch (playCombo->currentItem())
02382 {
02383 case 0:
02384 playOption = PL_CURRENT;
02385 break;
02386 case 1:
02387 playOption = PL_FIRST;
02388 break;
02389 case 2:
02390 playOption = PL_FIRSTNEW;
02391 break;
02392 default:
02393 playOption = PL_CURRENT;
02394 }
02395 }
02396 else
02397 playOption = PL_CURRENT;
02398
02399 popup->deleteLater();
02400
02401 return true;
02402 }
02403
02404 QString PlaybackBoxMusic::getTimeString(int exTime, int maxTime)
02405 {
02406 QString time_string;
02407
02408 int eh = exTime / 3600;
02409 int em = (exTime / 60) % 60;
02410 int es = exTime % 60;
02411
02412 int maxh = maxTime / 3600;
02413 int maxm = (maxTime / 60) % 60;
02414 int maxs = maxTime % 60;
02415
02416 if (maxTime <= 0)
02417 {
02418 if (eh > 0)
02419 time_string.sprintf("%d:%02d:%02d", eh, em, es);
02420 else
02421 time_string.sprintf("%02d:%02d", em, es);
02422 }
02423 else
02424 {
02425 if (maxh > 0)
02426 time_string.sprintf("%d:%02d:%02d / %02d:%02d:%02d", eh, em,
02427 es, maxh, maxm, maxs);
02428 else
02429 time_string.sprintf("%02d:%02d / %02d:%02d", em, es, maxm,
02430 maxs);
02431 }
02432
02433 return time_string;
02434 }