Ticket #2598: cdstore.3.patch
File cdstore.3.patch, 41.6 KB (added by , 17 years ago) |
---|
-
mythtv/libs/libmyth/generictree.h
29 29 30 30 GenericTree *findLeaf(int ordering_index = -1); 31 31 32 GenericTree* findNode(QValueList<int> route_of_branches); 33 GenericTree* recursiveNodeFinder(QValueList<int> route_of_branches); 34 bool checkNode(QValueList<int> route_of_branches); 32 /** \brief Traverse using the given path. 35 33 34 C should be a container of items that can be looked up using 35 GenericTree::getChild. Ie. QValueList<int> or a QStringList. 36 37 Recursively move through children who has the keys identified 38 by path. For each element in path, find the child by calling 39 GenericTree::getChild, and move to the next branch. 40 41 If the route fails at some point, typically if the path 42 specifies a child that doesn't exist, the function will stop 43 and return NULL. Otherwise, once the end of the path is 44 reached, that node is returned. 45 46 \param path a container of elements that specifies a path. 47 \returns The destination, NULL if path did not exist. 48 */ 49 template<typename C> 50 GenericTree* findNode(const C &path) 51 { 52 GenericTree *result = this; 53 for (typename C::const_iterator it = path.begin(); 54 result && it != path.end(); ++it) 55 result = result->getChild(*it); 56 return result; 57 } 58 59 /** \brief Detect if a given node is in a given path beneath this node. 60 61 C should be a container of items that can be looked up using 62 GenericTree::getChild. Ie. QValueList<int> or a QStringList. 63 64 Traverses the specified path and checks if node is in the 65 path. If the path does not exist, the method will return 66 false. If the end of the path is reached and node wasn't 67 encounter, the method will return false. 68 69 \param node the node to look for in the path. 70 \param path a container of elements that specifies a path. 71 \returns true if the node was found in the path, false if not 72 or if the path is invalid. 73 */ 74 template<typename C> 75 bool isNodeInPath (GenericTree *node, const C &path) 76 { 77 GenericTree *climber = this; 78 for (typename C::const_iterator it = path.begin(); 79 climber && climber != node && it != path.end(); ++it) 80 climber = climber->getChild(*it); 81 return climber && climber == node; 82 } 83 84 36 85 GenericTree *nextSibling(int number_down, int ordering_index = -1); 37 86 GenericTree *prevSibling(int number_up, int ordering_index = -1); 38 87 … … 42 91 GenericTree *getChildAt(uint reference, int ordering_index = -1); 43 92 GenericTree *getChildByName(const QString &a_name); 44 93 GenericTree *getChildByInt(int an_int); 94 GenericTree *getChild(int an_int) { return getChildByInt (an_int); } 95 GenericTree *getChild(const QString &a_name) { return getChildByName (a_name); } 45 96 46 97 QPtrList<GenericTree> *getAllChildren(int ordering_index = -1); 47 98 -
mythtv/libs/libmyth/uitypes.cpp
3288 3288 bins = 0; 3289 3289 bin_corners.clear(); 3290 3290 screen_corners.clear(); 3291 route_to_active.clear();3292 3291 resized_highlight_images.setAutoDelete(true); 3293 3292 my_tree_data = NULL; 3294 3293 current_node = NULL; … … 3831 3830 } 3832 3831 } 3833 3832 3834 QValueList <int> *UIManagedTreeListType::getRouteToActive()3833 QValueList <int> UIManagedTreeListType::getRouteToActive() 3835 3834 { 3835 QValueList<int> route_to_active; 3836 3836 if (active_node) 3837 3837 { 3838 route_to_active.clear();3839 3838 GenericTree *climber = active_node; 3840 3839 3841 3840 route_to_active.push_front(climber->getInt()); 3842 while( (climber = climber->getParent()) )3841 while( (climber = climber->getParent()) && climber->getParent ()) 3843 3842 { 3844 3843 route_to_active.push_front(climber->getInt()); 3845 3844 } 3846 return &route_to_active;3847 3845 } 3848 return NULL;3846 return route_to_active; 3849 3847 } 3850 3848 3851 3849 QStringList UIManagedTreeListType::getRouteToCurrent() … … 3855 3853 { 3856 3854 GenericTree *climber = current_node; 3857 3855 route_to_current.push_front(climber->getString()); 3858 while( (climber = climber->getParent()) )3856 while( (climber = climber->getParent()) && climber->getParent ()) 3859 3857 { 3860 3858 route_to_current.push_front(climber->getString()); 3861 3859 } -
mythtv/libs/libmyth/generictree.cpp
175 175 return this; 176 176 } 177 177 178 GenericTree* GenericTree::findNode(QValueList<int> route_of_branches)179 {180 // Starting from *this* node (which will often be root) find a set of181 // branches that have id's that match the collection passed in182 // route_of_branches. Return the end point of those branches (which will183 // often be a leaf node).184 //185 // In practical terms, mythmusic will use this to force the playback186 // screen's ManagedTreeList to move to a given track in a given playlist187 188 return recursiveNodeFinder(route_of_branches);189 }190 191 GenericTree* GenericTree::recursiveNodeFinder(QValueList<int> route_of_branches)192 {193 if (checkNode(route_of_branches))194 return this;195 else196 {197 QPtrListIterator<GenericTree> it(*m_subnodes);198 GenericTree *child;199 200 while ((child = it.current()) != 0)201 {202 GenericTree *sub_checker;203 sub_checker = child->recursiveNodeFinder(route_of_branches);204 if (sub_checker)205 return sub_checker;206 else207 ++it;208 }209 }210 211 return NULL;212 }213 214 bool GenericTree::checkNode(QValueList<int> route_of_branches)215 {216 bool found_it = true;217 GenericTree *parent_finder = this;218 219 // FIXME: slow220 221 for (int i = route_of_branches.count() - 1; i > -1 && found_it; --i)222 {223 if (!(parent_finder->getInt() == (*route_of_branches.at(i))))224 found_it = false;225 226 if (i > 0)227 {228 if (parent_finder->getParent())229 parent_finder = parent_finder->getParent();230 else231 found_it = false;232 }233 }234 235 return found_it;236 }237 238 178 int GenericTree::getChildPosition(GenericTree *child, int ordering_index) 239 179 { 240 180 if (ordering_index == -1) -
mythtv/libs/libmyth/uitypes.h
1054 1054 void assignTreeData(GenericTree *a_tree); 1055 1055 void moveToNode(QValueList<int> route_of_branches); 1056 1056 void moveToNodesFirstChild(QValueList<int> route_of_branchs); 1057 QValueList <int> *getRouteToActive();1057 QValueList <int> getRouteToActive(); 1058 1058 QStringList getRouteToCurrent(); 1059 1059 bool tryToSetActive(QValueList <int> route); 1060 1060 bool tryToSetCurrent(QStringList route); … … 1140 1140 QPixmap right_arrow_image; 1141 1141 QPtrList<QPixmap> resized_highlight_images; 1142 1142 QMap<int, QPixmap*> highlight_map; 1143 QValueList <int> route_to_active;1144 1143 bool show_whole_tree; 1145 1144 bool scrambled_parents; 1146 1145 bool color_selectables; -
mythtv/libs/libmyth/mythmediamonitor.cpp
888 888 .arg(MythMediaDevice::MediaStatusStrings[pMedia->getStatus()]) 889 889 .arg(MythMediaDevice::MediaStatusStrings[oldStatus])); 890 890 891 // This gets called from outside the main thread so we need 892 // to post an event back to the main thread. 893 // We're only going to pass up events for useable media... 894 if (pMedia->getStatus() == MEDIASTAT_USEABLE || 895 pMedia->getStatus() == MEDIASTAT_MOUNTED) 896 { 897 VERBOSE(VB_IMPORTANT, "Posting MediaEvent"); 898 QApplication::postEvent((QObject*)gContext->GetMainWindow(), 899 new MediaEvent(oldStatus, pMedia)); 900 } 901 else if (pMedia->getStatus() == MEDIASTAT_OPEN || 891 VERBOSE(VB_IMPORTANT, "Posting MediaEvent"); 892 QApplication::postEvent((QObject*)gContext->GetMainWindow(), 893 new MediaEvent(oldStatus, pMedia)); 894 895 if (pMedia->getStatus() == MEDIASTAT_OPEN || 902 896 pMedia->getStatus() == MEDIASTAT_UNPLUGGED) 903 897 { 904 898 pMedia->clearData(); 905 899 } 900 901 return; 906 902 } -
mythtv/libs/libmyth/mythcdrom-linux.cpp
124 124 //cout << "Tray open or no disc" << endl; 125 125 m_MediaType = MEDIATYPE_UNKNOWN; 126 126 return setStatus(MEDIASTAT_OPEN, OpenedHere); 127 break;128 127 case CDS_NO_INFO: 129 128 case CDS_DRIVE_NOT_READY: 130 129 //cout << "No info or drive not ready" << endl; -
mythplugins/mythmusic/mythmusic/playbackbox.cpp
26 26 #include "mainvisual.h" 27 27 #include "smartplaylist.h" 28 28 #include "search.h" 29 #include "treebuilders.h" 29 30 31 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 33 typedef enum 34 { 35 ACTIVE_PLAY_QUEUE = 0 36 } PathID; 37 38 QValueList<int> setPathTo(QValueList<int> &path, PathID p) 39 { 40 path.clear(); 41 switch (p) 42 { 43 case ACTIVE_PLAY_QUEUE: 44 path.append(1); // All My Playlists 45 path.append(0); // Active play Queue 46 break; 47 } 48 return path; 49 } 50 51 QValueList<int> setPathTo(QValueList<int> &path, GenericTree *node) 52 { 53 path.clear(); 54 while (node->getParent()) 55 { 56 path.prepend (node->getInt()); 57 node = node->getParent(); 58 } 59 return path; 60 } 61 62 QValueList<int> getPathTo(PathID p) 63 { 64 QValueList<int> result; 65 return setPathTo(result, p); 66 } 67 68 QValueList<int> getPathTo(GenericTree *node) 69 { 70 QValueList<int> result; 71 return setPathTo(result, node); 72 } 73 74 // . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 75 30 76 PlaybackBoxMusic::PlaybackBoxMusic(MythMainWindow *parent, QString window_name, 31 77 QString theme_filename, 32 78 PlaylistsContainer *the_playlists, … … 67 113 68 114 menufilters = gContext->GetNumSetting("MusicMenuFilters", 0); 69 115 70 cd_reader_thread = NULL; 71 cd_watcher = NULL; 72 scan_for_cd = gContext->GetNumSetting("AutoPlayCD", 0); 116 bool check_cd = gContext->GetNumSetting("AutoLookupCD", 0); 73 117 74 118 // Set our pointers the playlists and the metadata containers 75 119 … … 124 168 else 125 169 setRepeatMode(REPEAT_OFF); 126 170 171 store_manager = NULL; 172 if (check_cd) { 173 store_manager = new StoreManager; 174 connect(store_manager, SIGNAL(storeDetected(Store*)), 175 this, SLOT(storeDetected(Store*))); 176 connect(store_manager, SIGNAL(storeRemoved(Store*)), 177 this, SLOT(storeRemoved(Store*))); 178 connect(store_manager, SIGNAL(storeLoading(Store*)), 179 this, SLOT(storeLoading(Store*))); 180 connect(store_manager, SIGNAL(storeReady(Store*)), 181 this, SLOT(storeReady(Store*))); 182 } 183 127 184 // Set some button values 128 185 129 186 if (!keyboard_accelerators) … … 225 282 progress = NULL; 226 283 } 227 284 228 if ( cd_reader_thread)285 if (store_manager) 229 286 { 230 cd_watcher->stop(); 231 cd_reader_thread->wait(); 232 delete cd_reader_thread; 287 disconnect(store_manager, SIGNAL(storeDetected(Store*)), 288 this, SLOT(storeDetected(Store*))); 289 disconnect(store_manager, SIGNAL(storeRemoved(Store*)), 290 this, SLOT(storeRemoved(Store*))); 291 disconnect(store_manager, SIGNAL(storeLoading(Store*)), 292 this, SLOT(storeLoading(Store*))); 293 disconnect(store_manager, SIGNAL(storeReady(Store*)), 294 this, SLOT(storeReady(Store*))); 295 store_manager->deleteLater(); 233 296 } 234 297 235 298 if (playlist_tree) … … 254 317 lcd->switchToTime(); 255 318 } 256 319 257 bool PlaybackBoxMusic::onMediaEvent(MythMediaDevice *)320 bool PlaybackBoxMusic::onMediaEvent(MythMediaDevice *device) 258 321 { 259 return scan_for_cd; 322 if (store_manager) 323 return store_manager->onMediaEvent(device); 324 return false; 260 325 } 261 326 262 327 void PlaybackBoxMusic::keyPressEvent(QKeyEvent *e) … … 512 577 513 578 playlist_popup->addButton(tr("Search"), this, 514 579 SLOT(showSearchDialog())); 515 playlist_popup->addButton(tr("From CD"), this, 516 SLOT(fromCD())); 580 if (!stores.empty()) 581 playlist_popup->addButton(tr("From CD"), this, 582 SLOT(fromCD())); 583 517 584 playlist_popup->addButton(tr("All Tracks"), this, 518 585 SLOT(allTracks())); 519 586 if (curMeta) … … 556 623 { 557 624 if (!playlist_popup) 558 625 return; 559 560 updatePlaylistFromCD(); 626 if(all_music->getCDTrackCount()) { 627 visual_mode_timer->stop(); 628 629 all_playlists->getActive()->ripOutAllCDTracksNow(); 630 all_playlists->getActive()->fillSongsFromCD(); 631 postUpdate(); 632 } 633 561 634 closePlaylistPopup(); 562 635 } 563 636 … … 669 742 // store path to current track 670 743 if (curMeta) 671 744 { 672 QValueList <int> *a_route; 673 a_route = music_tree_list->getRouteToActive(); 674 branches_to_current_node = *a_route; 745 branches_to_current_node = music_tree_list->getRouteToActive(); 675 746 curTrackID = curMeta->ID(); 676 747 } 677 748 else 678 749 { 679 750 // No current metadata, so when we come back we'll try and play the 680 751 // first thing on the active queue 681 branches_to_current_node.clear(); 682 branches_to_current_node.append(0); // Root node 683 branches_to_current_node.append(1); // We're on a playlist (not "My Music") 684 branches_to_current_node.append(0); // Active play Queue 752 setPathTo(branches_to_current_node, ACTIVE_PLAY_QUEUE); 685 753 curTrackID = 0; 686 754 } 687 755 … … 785 853 786 854 void PlaybackBoxMusic::playFirstTrack() 787 855 { 788 QValueList <int> branches_to_current_node;789 790 856 stop(); 791 857 wipeTrackInfo(); 792 branches_to_current_node.clear(); 793 branches_to_current_node.append(0); // Root node 794 branches_to_current_node.append(1); // We're on a playlist (not "My Music") 795 branches_to_current_node.append(0); // Active play Queue 796 music_tree_list->moveToNodesFirstChild(branches_to_current_node); 858 music_tree_list->moveToNodesFirstChild(getPathTo(ACTIVE_PLAY_QUEUE)); 797 859 } 798 860 799 void PlaybackBoxMusic::updatePlaylistFromCD()800 {801 if (!cd_reader_thread)802 {803 cd_reader_thread = new ReadCDThread(all_playlists, all_music);804 cd_reader_thread->start();805 }806 807 if (!cd_watcher)808 {809 cd_watcher = new QTimer(this);810 connect(cd_watcher, SIGNAL(timeout()), this, SLOT(occasionallyCheckCD()));811 cd_watcher->start(1000);812 }813 814 }815 816 861 void PlaybackBoxMusic::postUpdate() 817 862 { 818 QValueList <int> branches_to_current_node;819 820 863 if (visual_mode_delay > 0) 821 864 visual_mode_timer->start(visual_mode_delay * 1000); 822 865 … … 825 868 stop(); 826 869 wipeTrackInfo(); 827 870 828 // move to first track in list 829 branches_to_current_node.clear(); 830 branches_to_current_node.append(0); // Root node 831 branches_to_current_node.append(1); // We're on a playlist (not "My Music") 832 branches_to_current_node.append(0); // Active play Queue 833 music_tree_list->moveToNodesFirstChild(branches_to_current_node); 871 music_tree_list->moveToNodesFirstChild(getPathTo(ACTIVE_PLAY_QUEUE)); 834 872 music_tree_list->refresh(); 835 873 } 836 874 837 void PlaybackBoxMusic::occasionallyCheckCD()838 {839 if (cd_reader_thread->getLock()->locked())840 return;841 842 if (!scan_for_cd) {843 cd_watcher->stop();844 delete cd_watcher;845 cd_watcher = NULL;846 847 cd_reader_thread->wait();848 delete cd_reader_thread;849 cd_reader_thread = NULL;850 }851 852 if (!scan_for_cd || cd_reader_thread->statusChanged())853 {854 all_playlists->clearCDList();855 all_playlists->getActive()->ripOutAllCDTracksNow();856 857 if(all_music->getCDTrackCount()) {858 visual_mode_timer->stop();859 860 all_playlists->getActive()->removeAllTracks();861 all_playlists->getActive()->fillSongsFromCD();862 863 postUpdate();864 }865 }866 867 if (scan_for_cd && !cd_reader_thread->running())868 cd_reader_thread->start();869 }870 871 875 void PlaybackBoxMusic::updatePlaylistFromSmartPlaylist() 872 876 { 873 877 doUpdatePlaylist(""); … … 927 931 928 932 if (tree_is_done) 929 933 { 930 if (scan_for_cd)931 updatePlaylistFromCD();932 933 934 music_tree_list->showWholeTree(show_whole_tree); 934 QValueList <int> branches_to_current_node; 935 branches_to_current_node.append(0); // Root node 936 branches_to_current_node.append(1); // We're on a playlist (not "My Music") 937 branches_to_current_node.append(0); // Active play Queue 938 music_tree_list->moveToNodesFirstChild(branches_to_current_node); 935 music_tree_list->moveToNodesFirstChild(getPathTo(ACTIVE_PLAY_QUEUE)); 939 936 music_tree_list->refresh(); 940 937 if (show_whole_tree) 941 938 setContext(1); … … 947 944 if (curMeta) 948 945 updateTrackInfo(curMeta); 949 946 947 if (store_manager) 948 store_manager->reemitReadyStores(); 949 950 950 return; // Do not restart Timer 951 951 } 952 952 else … … 1576 1576 1577 1577 void PlaybackBoxMusic::constructPlaylistTree() 1578 1578 { 1579 if (playlist_tree) 1580 delete playlist_tree; 1579 if (!playlist_tree) { 1580 playlist_tree = new GenericTree(tr("playlist root"), 0); 1581 playlist_tree->setAttribute(0, 0); 1582 playlist_tree->setAttribute(1, 0); 1583 playlist_tree->setAttribute(2, 0); 1584 playlist_tree->setAttribute(3, 0); 1585 } else { 1586 if (playlist_tree->getChild("All My Playlists")) { 1587 playlist_tree->removeNode(playlist_tree->getChild("All My Playlists")); 1588 } 1589 if (playlist_tree->getChild("All My Music")) { 1590 playlist_tree->removeNode(playlist_tree->getChild("All My Music")); 1591 } 1592 } 1581 1593 1582 playlist_tree = new GenericTree(tr("playlist root"), 0);1583 playlist_tree->setAttribute(0, 0);1584 playlist_tree->setAttribute(1, 0);1585 playlist_tree->setAttribute(2, 0);1586 playlist_tree->setAttribute(3, 0);1587 1588 1594 // We ask the playlist object to write out the whole tree (all playlists 1589 1595 // and all music). It will set attributes for nodes in the tree, such as 1590 1596 // whether a node is selectable, how it can be ordered (normal, random, … … 1592 1598 1593 1599 all_playlists->writeTree(playlist_tree); 1594 1600 music_tree_list->assignTreeData(playlist_tree); 1601 playlist_tree->reorderSubnodes(1); 1595 1602 tree_is_done = true; 1596 1603 } 1597 1604 … … 1603 1610 1604 1611 if (curMeta) 1605 1612 { 1606 QValueList <int> *a_route; 1607 a_route = music_tree_list->getRouteToActive(); 1608 branches_to_current_node = *a_route; 1613 branches_to_current_node = music_tree_list->getRouteToActive(); 1609 1614 } 1610 1615 else 1611 1616 { 1612 1617 // No current metadata, so when we come back we'll try and play the 1613 1618 // first thing on the active queue 1614 1615 branches_to_current_node.clear(); 1616 branches_to_current_node.append(0); // Root node 1617 branches_to_current_node.append(1); // We're on a playlist (not "My Music") 1618 branches_to_current_node.append(0); // Active play Queue 1619 setPathTo(branches_to_current_node, ACTIVE_PLAY_QUEUE); 1619 1620 } 1620 1621 1621 1622 visual_mode_timer->stop(); … … 1637 1638 { 1638 1639 stop(); 1639 1640 wipeTrackInfo(); 1640 branches_to_current_node.clear(); 1641 branches_to_current_node.append(0); // Root node 1642 branches_to_current_node.append(1); // We're on a playlist (not "My Music") 1643 branches_to_current_node.append(0); // Active play Queue 1644 music_tree_list->moveToNodesFirstChild(branches_to_current_node); 1641 music_tree_list->moveToNodesFirstChild(getPathTo(ACTIVE_PLAY_QUEUE)); 1645 1642 } 1646 1643 music_tree_list->refresh(); 1647 1644 } … … 2135 2132 return (res >= 0); 2136 2133 } 2137 2134 2135 void PlaybackBoxMusic::storeDetected(Store *store) 2136 { 2137 (void)store; 2138 } 2138 2139 2140 void PlaybackBoxMusic::storeRemoved(Store *store) 2141 { 2142 if (!stores.contains(store)) 2143 return; 2144 2145 DeviceInfo &devinfo = stores[store]; 2146 2147 // If we're showing the store or playing something off it, stop/move away. 2148 if (playlist_tree->isNodeInPath(devinfo.tree_node, music_tree_list->getRouteToActive())) 2149 stop(); 2150 if (playlist_tree->isNodeInPath(devinfo.tree_node, music_tree_list->getRouteToCurrent())) 2151 music_tree_list->moveToNode(getPathTo(ACTIVE_PLAY_QUEUE)); 2152 2153 // Remove the tree info and the devinfo object. 2154 playlist_tree->removeNode(devinfo.tree_node); 2155 delete devinfo.music_node; 2156 stores.remove(store); 2157 store->removeref(); 2158 2159 // Refresh the tree, rerun constructPlayList to ensure that 2160 // any playlist showing CD entries are redrawn. 2161 all_music->clearCDData(); 2162 all_playlists->clearCDList(); 2163 constructPlaylistTree(); 2164 2165 music_tree_list->refresh(); 2166 } 2167 2168 void PlaybackBoxMusic::storeLoading(Store *store) 2169 { 2170 (void)store; 2171 } 2172 2173 void PlaybackBoxMusic::storeReady(Store *store) 2174 { 2175 store->addref(); 2176 2177 VERBOSE(VB_GENERAL, QString("Store '%1' ready with %2 tracks"). 2178 arg(store->getTitle()).arg(store->getMetadataList().count())); 2179 2180 QPtrListIterator<Metadata> it(store->getMetadataList()); 2181 while (*it) { 2182 all_music->addCDTrack(*it); 2183 ++it; 2184 } 2185 all_music->setCDTitle(store->getTitle()); 2186 2187 MusicNode *node = new MusicNode(store->getName(), "title"); 2188 MusicTreeBuilder *builder = MusicTreeBuilder::createBuilder("title"); 2189 builder->makeTree(node, store->getMetadataList()); 2190 2191 DeviceInfo devinfo; 2192 devinfo.music_node = node; 2193 devinfo.tree_node = node->writeTree(playlist_tree, playlist_tree->childCount()); 2194 stores[store] = devinfo; 2195 2196 if (gContext->GetNumSetting("AutoPlayCD", 0)) 2197 music_tree_list->moveToNode(getPathTo(devinfo.tree_node->getChildAt(0))); 2198 2199 playlist_tree->reorderSubnodes(1); 2200 music_tree_list->refresh(); 2201 } 2202 -
mythplugins/mythmusic/mythmusic/mythmusic.pro
36 36 HEADERS += goom/ifs.h goom/lines.h goom/mythgoom.h goom/drawmethods.h 37 37 HEADERS += goom/mmx.h goom/mathtools.h goom/tentacle3d.h goom/v3d.h 38 38 HEADERS += editmetadata.h smartplaylist.h search.h genres.h 39 HEADERS += treebuilders.h 39 HEADERS += treebuilders.h storemanager.h cdstore.h 40 40 41 41 SOURCES += cddecoder.cpp cdrip.cpp decoder.cpp 42 42 SOURCES += flacdecoder.cpp flacencoder.cpp maddecoder.cpp main.cpp … … 51 51 SOURCES += goom/ifs.c goom/ifs_display.c goom/lines.c goom/surf3d.c 52 52 SOURCES += goom/zoom_filter_mmx.c goom/zoom_filter_xmmx.c goom/mythgoom.cpp 53 53 SOURCES += avfdecoder.cpp editmetadata.cpp smartplaylist.cpp search.cpp 54 SOURCES += treebuilders.cpp 54 SOURCES += treebuilders.cpp storemanager.cpp cdstore.cpp -
mythplugins/mythmusic/mythmusic/metadata.cpp
950 950 { 951 951 if( (*anit).Track() == an_id * -1) 952 952 { 953 a_label = QString("CD: %1 ~ %2 - %3").arg((*anit). FormatArtist()).arg((*anit).Track()).arg((*anit).FormatTitle());953 a_label = QString("CD: %1 ~ %2 - %3").arg((*anit).Track()).arg((*anit).FormatArtist()).arg((*anit).FormatArtist()); 954 954 *error_flag = false; 955 955 return a_label; 956 956 } … … 1168 1168 1169 1169 } 1170 1170 1171 voidMusicNode::writeTree(GenericTree *tree_to_write_to, int a_counter)1171 GenericTree* MusicNode::writeTree(GenericTree *tree_to_write_to, int a_counter) 1172 1172 { 1173 1173 1174 GenericTree *sub_node = tree_to_write_to->addNode(my_title );1174 GenericTree *sub_node = tree_to_write_to->addNode(my_title, a_counter); 1175 1175 sub_node->setAttribute(0, 0); 1176 1176 sub_node->setAttribute(1, a_counter); 1177 1177 sub_node->setAttribute(2, rand()); … … 1231 1231 ++another_counter; 1232 1232 ++iter; 1233 1233 } 1234 1235 return sub_node; 1234 1236 } 1235 1237 1236 1238 -
mythplugins/mythmusic/mythmusic/cddecoder.h
24 24 25 25 int getNumTracks(void); 26 26 int getNumCDAudioTracks(void); 27 void setDevice (const QString &dev); 27 28 28 29 Metadata *getMetadata(int track); 29 30 Metadata *getMetadata(void); -
mythplugins/mythmusic/mythmusic/playlist.cpp
28 28 { 29 29 if (cd_flag) 30 30 { 31 int val = (index_value < 0) ? -index_value : index_value; 32 label = all_available_music->getLabel(val, &bad_reference); 31 label = all_available_music->getLabel(index_value, &bad_reference); 33 32 return; 34 33 } 35 34 … … 237 236 238 237 void PlaylistsContainer::clearCDList() 239 238 { 239 QPtrListIterator<Playlist> it(*all_other_playlists); 240 while (*it) { 241 (*it)->ripOutAllCDTracksNow(); 242 ++it; 243 } 244 active_playlist->ripOutAllCDTracksNow(); 245 backup_playlist->ripOutAllCDTracksNow(); 240 246 cd_playlist.clear(); 241 247 } 242 248 -
mythplugins/mythmusic/mythmusic/databasebox.h
4 4 #include <qwidget.h> 5 5 #include <qdialog.h> 6 6 #include <qstringlist.h> 7 #include <qthread.h>8 7 #include <qtimer.h> 9 8 #include <qptrlist.h> 10 9 11 10 #include "metadata.h" 12 11 #include "playlist.h" 12 #include "storemanager.h" 13 13 #include <mythtv/mythwidgets.h> 14 14 #include <mythtv/lcddevice.h> 15 15 #include <mythtv/uilistbtntype.h> 16 #include <mythtv/mythobservable.h> 17 #include <mythtv/mythmedia.h> 16 18 17 19 class TreeCheckItem; 20 class CDManager; 18 21 19 class ReadCDThread : public QThread20 {21 public:22 23 ReadCDThread(PlaylistsContainer *all_the_playlist, AllMusic *all_the_music);24 virtual void run();25 bool statusChanged(){return cd_status_changed;}26 QMutex *getLock(){return &music_lock;}27 28 private:29 30 AllMusic* all_music;31 PlaylistsContainer* the_playlists;32 bool cd_status_changed;33 QMutex music_lock;34 };35 36 22 class DatabaseBox : public MythThemedDialog 37 23 { 38 24 Q_OBJECT 25 typedef QValueList<MythMediaDevice*> MythMediaPtrList; 39 26 public: 40 27 DatabaseBox(PlaylistsContainer *all_playlists, 41 28 AllMusic *music_ptr, MythMainWindow *parent, … … 46 33 void dealWithTracks(PlaylistItem *item_ptr); 47 34 void setCDTitle(const QString& title); 48 35 void fillCD(void); 36 bool onMediaEvent(MythMediaDevice *dev); 49 37 50 38 protected slots: 51 39 void selected(UIListGenericTree *); … … 74 62 void CreateCDMP3(); 75 63 void BlankCDRW(); 76 64 65 void storeDetected(Store*); 66 void storeRemoved(Store*); 67 void storeLoading(Store*); 68 void storeReady(Store*); 69 77 70 private: 78 71 void doSelected(UIListGenericTree *, bool cd_flag); 79 72 void doPlaylistPopup(TreeCheckItem *item_ptr); 80 73 void doActivePopup(PlaylistTitle *item_ptr); 81 74 void checkParent(UIListGenericTree *); 82 75 83 76 void checkTree(UIListGenericTree *startingpoint = NULL); 84 77 QPixmap getPixmap(QString &level); 85 78 … … 105 98 106 99 MythPopupBox *error_popup; 107 100 108 ReadCDThread *cd_reader_thread; 109 QTimer *cd_watcher; 110 bool cd_checking_flag; 101 StoreManager *store_manager; 111 102 112 103 QTimer *fill_list_timer; 113 104 int wait_counter; 114 105 int numb_wait_dots; 115 106 116 107 QStringList treelevels; 117 118 108 QPtrList<UITextType> m_lines; 119 109 }; 120 110 -
mythplugins/mythmusic/mythmusic/metadata.h
219 219 QString getTitle(){return my_title;} 220 220 void printYourself(int indent_amount); // debugging 221 221 void putYourselfOnTheListView(TreeCheckItem *parent, bool show_node); 222 void writeTree(GenericTree *tree_to_write_to, int a_counter); 222 /** \brief Write the node, it's leafs and children into a GenericTree. 223 224 Creates a new node in tree_to_write_to with the music nodes 225 title, then recursively adds all leaves and subnodes. Subnodes 226 are added with recursive calls to writeTree, with a a_counter 227 value of zero and incremented by one for each iteration. 228 229 The call returns a pointer to the node added to tree_to_write_to. 230 231 \param tree_to_write_to the GenericTree to write to 232 \param a_counter value to set the new nodes 2nd attribute 233 \returns the node created 234 */ 235 GenericTree*writeTree(GenericTree *tree_to_write_to, int a_counter); 223 236 void sort(); 224 237 void setPlayCountMin(int tmp_min) { playcountMin = tmp_min; } 225 238 void setPlayCountMax(int tmp_max) { playcountMax = tmp_max; } -
mythplugins/mythmusic/mythmusic/databasebox.cpp
13 13 #include "metadata.h" 14 14 #include "databasebox.h" 15 15 #include "treecheckitem.h" 16 #include "cddecoder.h"17 16 #include "playlist.h" 17 #include "storemanager.h" 18 18 19 19 #include <mythtv/dialogbox.h> 20 20 #include <mythtv/mythcontext.h> 21 21 #include <mythtv/lcddevice.h> 22 22 #include <mythtv/uitypes.h> 23 23 #include <mythtv/uilistbtntype.h> 24 #include <mythtv/mythmedia.h> 25 #include <mythtv/mythmediamonitor.h> 24 26 25 27 DatabaseBox::DatabaseBox(PlaylistsContainer *all_playlists, 26 28 AllMusic *music_ptr, MythMainWindow *parent, … … 38 40 } 39 41 all_music = music_ptr; 40 42 41 // Do we check the CD? 42 cd_checking_flag = false; 43 cd_checking_flag = gContext->GetNumSetting("AutoLookupCD"); 44 43 bool check_cd = gContext->GetNumSetting("AutoLookupCD"); 45 44 QString treelev = gContext->GetSetting("TreeLevels", "artist album title"); 46 45 QStringList treelevels = QStringList::split(" ", treelev.lower()); 47 46 … … 98 97 rootNode = new UIListGenericTree(NULL, "Root Music Node"); 99 98 100 99 allmusic = new TreeCheckItem(rootNode, tr("All My Music"), "genre", 0); 101 if (c d_checking_flag)102 cditem = new CDCheckItem(rootNode, tr("Blechy Blech Blah"), "cd", 0);100 if (check_cd) 101 cditem = new CDCheckItem(rootNode, all_music->getCDTitle (), "cd", 0); 103 102 alllists = new TreeCheckItem(rootNode, tr("All My Playlists"), "genre", 0); 104 103 allcurrent = new PlaylistTitle(rootNode, tr("Active Play Queue")); 105 104 106 105 tree->SetTree(rootNode); 107 106 108 cd_reader_thread = NULL; 109 if (cd_checking_flag) 110 { 111 // Start the CD checking thread, and set up a timer to make it check 112 // occasionally 107 store_manager = NULL; 108 if (check_cd) { 109 store_manager = new StoreManager; 113 110 114 cd_reader_thread = new ReadCDThread(the_playlists, all_music); 111 connect(store_manager, SIGNAL(storeDetected(Store*)), 112 this, SLOT(storeDetected(Store*))); 113 connect(store_manager, SIGNAL(storeRemoved(Store*)), 114 this, SLOT(storeRemoved(Store*))); 115 connect(store_manager, SIGNAL(storeLoading(Store*)), 116 this, SLOT(storeLoading(Store*))); 117 connect(store_manager, SIGNAL(storeReady(Store*)), 118 this, SLOT(storeReady(Store*))); 115 119 116 // filling initialy before thread running 117 fillCD(); 118 119 cd_reader_thread->start(); 120 121 cd_watcher = new QTimer(this); 122 connect(cd_watcher, SIGNAL(timeout()), this, SLOT(occasionallyCheckCD())); 123 cd_watcher->start(1000); // Every second? 120 store_manager->reemitReadyStores(); 124 121 } 125 122 126 123 // Set a timer to keep redoing the fillList stuff until the metadata and 127 124 // playlist loading threads are done 128 125 … … 135 132 136 133 DatabaseBox::~DatabaseBox() 137 134 { 138 if ( cd_reader_thread)135 if (store_manager) 139 136 { 140 cd_watcher->stop(); 141 142 cd_reader_thread->wait(); 143 delete cd_reader_thread; 137 disconnect(store_manager, SIGNAL(storeDetected(Store*)), 138 this, SLOT(storeDetected(Store*))); 139 disconnect(store_manager, SIGNAL(storeRemoved(Store*)), 140 this, SLOT(storeRemoved(Store*))); 141 disconnect(store_manager, SIGNAL(storeLoading(Store*)), 142 this, SLOT(storeLoading(Store*))); 143 disconnect(store_manager, SIGNAL(storeReady(Store*)), 144 this, SLOT(storeReady(Store*))); 145 store_manager->deleteLater(); 144 146 } 145 147 146 148 all_music->resetListings(); … … 211 213 showWaiting(); 212 214 } 213 215 214 void DatabaseBox::occasionallyCheckCD()215 {216 if (cd_reader_thread->getLock()->locked())217 return;218 219 if (cd_reader_thread->statusChanged())220 {221 if (active_playlist)222 {223 active_playlist->ripOutAllCDTracksNow();224 fillCD();225 }226 }227 if (!cd_reader_thread->running())228 cd_reader_thread->start();229 }230 231 216 void DatabaseBox::copyNewPlaylist() 232 217 { 233 218 if (!active_popup) … … 429 414 delete record_progress; 430 415 } 431 416 417 void DatabaseBox::storeDetected(Store *store) 418 { 419 store->addref(); 420 } 421 422 void DatabaseBox::storeRemoved(Store *store) 423 { 424 all_music->clearCDData(); 425 the_playlists->clearCDList(); 426 fillCD(); 427 store->removeref(); 428 } 429 430 void DatabaseBox::storeLoading(Store *store) 431 { 432 (void)store; 433 } 434 435 void DatabaseBox::storeReady(Store *store) 436 { 437 all_music->setCDTitle(store->getTitle()); 438 439 Metadata *track; 440 QPtrListIterator<Metadata> it(store->getMetadataList()); 441 while ((track = it.current()) != 0) { 442 all_music->addCDTrack(track); 443 ++it; 444 } 445 446 fillCD(); 447 } 448 432 449 void DatabaseBox::deletePlaylist() 433 450 { 434 451 if (!playlist_popup) … … 492 509 493 510 void DatabaseBox::fillCD(void) 494 511 { 495 QMutexLocker locker(cd_reader_thread->getLock());496 497 512 if (cditem) 498 513 { 499 514 … … 554 569 } 555 570 556 571 tree->Redraw(); 572 tree->enter (); 557 573 } 558 574 } 559 575 576 bool DatabaseBox::onMediaEvent(MythMediaDevice *device) 577 { 578 if (store_manager) 579 return store_manager->onMediaEvent(device); 580 return false; 581 } 582 560 583 void DatabaseBox::doMenus(UIListGenericTree *item) 561 584 { 562 585 if (dynamic_cast<CDCheckItem*>(item)) … … 765 788 cerr << "databasebox.o: That's odd ... there's something I don't " 766 789 "recognize on a ListView" << endl; 767 790 } 791 tree->MoveDown(); 768 792 } 769 793 770 794 … … 1223 1247 cditem->setText(title); 1224 1248 } 1225 1249 1226 ReadCDThread::ReadCDThread(PlaylistsContainer *all_the_playlists,1227 AllMusic *all_the_music)1228 {1229 the_playlists = all_the_playlists;1230 all_music = all_the_music;1231 cd_status_changed = false;1232 }1233 1250 1234 void ReadCDThread::run()1235 {1236 // lock all_music and cd_status_changed while running thread1237 QMutexLocker locker(getLock());1238 1239 CdDecoder *decoder = new CdDecoder("cda", NULL, NULL, NULL);1240 int tracknum = decoder->getNumCDAudioTracks();1241 1242 bool redo = false;1243 1244 if (tracknum != all_music->getCDTrackCount())1245 {1246 cd_status_changed = true;1247 VERBOSE(VB_IMPORTANT, QString("Set cd_status_changed to true"));1248 }1249 else1250 cd_status_changed = false;1251 1252 if (tracknum == 0)1253 {1254 // No CD, or no recognizable CD1255 all_music->clearCDData();1256 the_playlists->clearCDList();1257 }1258 else if (tracknum > 0)1259 {1260 // Check the last track to see if it's differen than whatever it was1261 // before1262 Metadata *checker = decoder->getLastMetadata();1263 if (checker)1264 {1265 if (!all_music->checkCDTrack(checker))1266 {1267 redo = true;1268 cd_status_changed = true;1269 all_music->clearCDData();1270 the_playlists->clearCDList();1271 }1272 else1273 cd_status_changed = false;1274 delete checker;1275 }1276 else1277 {1278 cerr << "databasebox.o: The cddecoder said it had audio tracks, "1279 "but it won't tell me about them" << endl;1280 }1281 }1282 1283 int tracks = decoder->getNumTracks();1284 bool setTitle = false;1285 1286 for (int actual_tracknum = 1;1287 redo && actual_tracknum <= tracks; actual_tracknum++)1288 {1289 Metadata *track = decoder->getMetadata(actual_tracknum);1290 if (track)1291 {1292 all_music->addCDTrack(track);1293 1294 if (!setTitle)1295 {1296 1297 QString parenttitle = " ";1298 if (track->FormatArtist().length() > 0)1299 {1300 parenttitle += track->FormatArtist();1301 parenttitle += " ~ ";1302 }1303 1304 if (track->Album().length() > 0)1305 parenttitle += track->Album();1306 else1307 {1308 parenttitle = " " + QObject::tr("Unknown");1309 cerr << "databasebox.o: Couldn't find your CD. It may not "1310 "be in the freedb database." << endl;1311 cerr << " More likely, however, is that you "1312 "need to delete ~/.cddb and" << endl;1313 cerr << " ~/.cdserverrc and restart "1314 "mythmusic. Have a nice day." << endl;1315 }1316 all_music->setCDTitle(parenttitle);1317 setTitle = true;1318 }1319 delete track;1320 }1321 }1322 1323 delete decoder;1324 }1325 -
mythplugins/mythmusic/mythmusic/playbackbox.h
14 14 #include "playlist.h" 15 15 #include "editmetadata.h" 16 16 #include "databasebox.h" 17 #include "storemanager.h" 17 18 18 19 class Output; 19 20 class Decoder; 20 21 21 22 class PlaybackBoxMusic : public MythThemedDialog 22 23 { 23 Q_OBJECT 24 Q_OBJECT; 24 25 25 26 public: 26 27 … … 77 78 void toggleFullBlankVisualizer(); 78 79 void end(); 79 80 80 void occasionallyCheckCD();81 82 81 // popup menu 83 82 void showMenu(); 84 83 void closePlaylistPopup(); … … 93 92 bool getInsertPLOptions(InsertPLOption &insertOption, 94 93 PlayPLOption &playOption, bool &bRemoveDups); 95 94 95 void storeDetected(Store*); 96 void storeRemoved(Store*); 97 void storeLoading(Store*); 98 void storeReady(Store*); 99 96 100 signals: 97 101 98 102 void dummy(); // debugging … … 104 108 void updatePlaylistFromSmartPlaylist(); 105 109 void doUpdatePlaylist(QString whereClause); 106 110 void CycleVisualizer(void); 107 void updatePlaylistFromCD(void);108 111 void setTrackOnLCD(Metadata *mdata); 109 112 void updateTrackInfo(Metadata *mdata); 110 113 void openOutputDevice(void); … … 151 154 152 155 bool menufilters; 153 156 154 ReadCDThread *cd_reader_thread; 155 QTimer *cd_watcher; 156 bool cd_checking_flag; 157 bool scan_for_cd; 157 StoreManager *store_manager; 158 struct DeviceInfo 159 { 160 MusicNode *music_node; 161 GenericTree *tree_node; 162 }; 163 typedef QMap<Store*, DeviceInfo> StoreToInfo; 164 /** Mapping from a MythMediaDevice to the MusicNode that contains 165 * the contents, the GenericTree node that was inserted into \p 166 * playlist_tree and the metadata pointers. 167 */ 168 StoreToInfo stores; 158 169 159 170 MainVisual *mainvisual; 160 171 … … 164 175 QTimer *lcd_update_timer; 165 176 QTimer *banner_timer; 166 177 int visualizer_status; 167 168 178 bool showrating; 169 179 bool vis_is_big; 170 180 bool tree_is_done; -
mythplugins/mythmusic/mythmusic/cddecoder.cpp
310 310 return retval; 311 311 } 312 312 313 void CdDecoder::setDevice(const QString &dev) 314 { 315 devicename = dev; 316 } 317 313 318 Metadata* CdDecoder::getMetadata(int track) 314 319 { 315 320 settracknum = track;