From f4136bcdcabcc6bcc5a8be345291a854e4fe5e8f Mon Sep 17 00:00:00 2001 From: kervala Date: Sat, 20 Feb 2016 19:12:55 +0100 Subject: [PATCH] Music player can now handle unicode filenames and m3u8 playlists, issue #261 --- .../client/src/interface_v3/music_player.cpp | 284 +++++++++--------- 1 file changed, 149 insertions(+), 135 deletions(-) diff --git a/code/ryzom/client/src/interface_v3/music_player.cpp b/code/ryzom/client/src/interface_v3/music_player.cpp index 39aeea825..ece6f0d43 100644 --- a/code/ryzom/client/src/interface_v3/music_player.cpp +++ b/code/ryzom/client/src/interface_v3/music_player.cpp @@ -196,162 +196,176 @@ public: InitMouseWithCursor (true); Driver->showCursor (true); - if (false) //supportUnicode()) + bool oggSupported = false; + bool mp3Supported = false; + + for(uint i = 0; i < extensions.size(); ++i) { + if (extensions[i] == "ogg") + { + oggSupported = true; + } + else if (extensions[i] == "mp3") + { + mp3Supported = true; + } } - else + + std::vector filters; + + // supported formats + filters.push_back("All Supported Files"); // TODO: translate + + std::string filter; + if (mp3Supported) filter += "*.mp3;*.mp2;*.mp1;"; + if (oggSupported) filter += "*.ogg;"; + filter += "*.m3u;*.m3u8"; + + filters.push_back(filter); + + // mp3 format + if (mp3Supported) { - bool oggSupported = false; - bool mp3Supported = false; + filters.push_back("MPEG Audio Files (*.mp3;*.mp2;*.mp1)"); + filters.push_back("*.mp3;*.mp2;*.mp1"); + } - for(uint i = 0; i < extensions.size(); ++i) + // ogg format + if (oggSupported) + { + filters.push_back("Vorbis Files (*.ogg)"); + filters.push_back("*.ogg"); + } + + // playlist + filters.push_back("Playlist Files (*.m3u;*.m3u8)"); + filters.push_back("*.m3u;*.m3u8"); + + // all files + filters.push_back("All Files (*.*)"); + filters.push_back("*.*"); + + filters.push_back(""); + + static wchar_t szFilter[1024] = { '\0' }; + + uint offset = 0; + + for(uint i = 0; i < filters.size(); ++i) + { + wcscpy(szFilter + offset, utf8ToWide(filters[i])); + + // move offset to string length + 1 for \0 + offset += filters[i].length() + 1; + } + + // Filename buffer + wchar_t buffer[1024]; + buffer[0]=0; + + OPENFILENAMEW ofn; + memset (&ofn, 0, sizeof(OPENFILENAME)); + ofn.lStructSize = sizeof(OPENFILENAME); + ofn.hwndOwner = Driver ? Driver->getDisplay():NULL; + ofn.hInstance = HInstance; + ofn.lpstrFilter = szFilter; + ofn.nFilterIndex = 0; + ofn.lpstrFile = buffer; + ofn.nMaxFile = sizeof(buffer); + ofn.lpstrTitle = (wchar_t*)NLMISC::CI18N::get("uiPlaySongs").c_str(); + ofn.Flags = OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_EXPLORER; + + if (Driver) + Driver->beginDialogMode(); + + if (GetOpenFileNameW (&ofn)) + { + bool useUtf8 = false; + + // Skip the directory name + const wchar_t *bufferPtr = buffer; + + // Multi filename ? + string path; + if (ofn.nFileOffset>wcslen(buffer)) { - if (extensions[i] == "ogg") - { - oggSupported = true; - } - else if (extensions[i] == "mp3") - { - mp3Supported = true; - } + // Backup the path and point to the next filename + path = wideToUtf8(buffer); + path += "\\"; + bufferPtr += wcslen(bufferPtr)+1; } - std::vector filters; - - // supported formats - filters.push_back("All Supported Files"); - - std::string filter; - if (mp3Supported) filter += "*.mp3;*.mp2;*.mp1;"; - if (oggSupported) filter += "*.ogg;"; - filter += "*.m3u"; - - filters.push_back(filter); - - // mp3 format - if (mp3Supported) + // Get selected files and playlists + std::vector filenames; + std::vector playlists; + while (*bufferPtr) { - filters.push_back("MPEG Audio Files (*.mp3;*.mp2;*.mp1)"); - filters.push_back("*.mp3;*.mp2;*.mp1"); - } - - // ogg format - if (oggSupported) - { - filters.push_back("Vorbis Files (*.ogg)"); - filters.push_back("*.ogg"); - } - - // playlist - filters.push_back("Playlist Files (*.m3u)"); - filters.push_back("*.m3u"); - - // all files - filters.push_back("All Files (*.*)"); - filters.push_back("*.*"); - - filters.push_back(""); - - static char szFilter[1024] = { '\0' }; - - uint offset = 0; - - for(uint i = 0; i < filters.size(); ++i) - { - strcpy(szFilter + offset, filters[i].c_str()); - - // move offset to string length + 1 for \0 - offset += filters[i].length() + 1; - } - - // Filename buffer - char buffer[65535]; - buffer[0]=0; - - OPENFILENAME ofn; - memset (&ofn, 0, sizeof(OPENFILENAME)); - ofn.lStructSize = sizeof(OPENFILENAME); - ofn.hwndOwner = Driver ? Driver->getDisplay():NULL; - ofn.hInstance = HInstance; - ofn.lpstrFilter = szFilter; - ofn.nFilterIndex = 0; - ofn.lpstrFile = buffer; - ofn.nMaxFile = sizeof(buffer); - ofn.lpstrTitle = "Play songs"; - ofn.Flags = OFN_OVERWRITEPROMPT|OFN_ALLOWMULTISELECT|OFN_ENABLESIZING|OFN_EXPLORER; - - if (Driver) - Driver->beginDialogMode(); - - if (GetOpenFileName (&ofn)) - { - // Skip the directory name - const char *bufferPtr = buffer; - - // Multi filename ? - string path; - if (ofn.nFileOffset>strlen(buffer)) + // Concat the directory name with the filename + std::string ext = toLower(CFile::getExtension(wideToUtf8(bufferPtr))); + if (ext == "m3u" || ext == "m3u8") { - // Backup the path and point to the next filename - path = buffer; - path += "\\"; - bufferPtr+=strlen(bufferPtr)+1; + playlists.push_back (path + wideToUtf8(bufferPtr)); + } + else + { + filenames.push_back (path + wideToUtf8(bufferPtr)); } - // Get selected files and playlists - std::vector filenames; - std::vector playlists; - while (*bufferPtr) - { - // Concat the directory name with the filename - if (toLower(CFile::getExtension(bufferPtr)) == "m3u") - playlists.push_back (path+bufferPtr); - else - filenames.push_back (path+bufferPtr); - bufferPtr+=strlen(bufferPtr)+1; - } + bufferPtr += wcslen(bufferPtr) + 1; + } - // Sort songs by filename - sort (filenames.begin(), filenames.end()); + // Sort songs by filename + sort (filenames.begin(), filenames.end()); - // Add playlist - uint i; - for (i=0; i= 3 && memcmp(line, utf8Header, 3) == 0) + useUtf8 = true; + + if (!useUtf8) lineStr = ucstring(line).toUtf8(); + + if (lineStr[0] != '#') + filenames.push_back (CPath::makePathAbsolute(lineStr, basePlaylist)); } + fclose (file); } - - // Build the songs array - std::vector songs; - for (i=0; igetMixer()->getSongTitle(filenames[i], song.Title); - songs.push_back (song); - } - - MusicPlayer.playSongs(songs); } - if (Driver) - Driver->endDialogMode(); + // Build the songs array + std::vector songs; + for (i=0; igetMixer()->getSongTitle(filenames[i], song.Title); + songs.push_back (song); + } + + MusicPlayer.playSongs(songs); } + if (Driver) + Driver->endDialogMode(); + // Restore mouse InitMouseWithCursor (wasHardware); Driver->showCursor (wasHardware);