bool ThemeManager::IsThemeSelectable( const RString &sThemeName ) { if( !DoesThemeExist(sThemeName) ) return false; return sThemeName.Left(1) != "_"; }
bool Steps::MakeValidEditDescription( RString &sPreferredDescription ) { if( int(sPreferredDescription.size()) > MAX_STEPS_DESCRIPTION_LENGTH ) { sPreferredDescription = sPreferredDescription.Left( MAX_STEPS_DESCRIPTION_LENGTH ); return true; } return false; }
bool IniFile::ReadFile( RageFileBasic &f ) { RString keyname; while( 1 ) { RString line; /* Read lines until we reach a line that doesn't end in a backslash */ while( true ) { RString s; switch( f.GetLine(s) ) { case -1: m_sError = f.GetError(); return false; case 0: return true; /* eof */ } utf8_remove_bom( s ); line += s; if( line.empty() || line[line.size()-1] != '\\' ) break; line.erase( line.end()-1 ); } if( line.size() == 0 ) continue; if( line[0] == '#' ) continue; /* comment */ if( line.size() > 1 && line[0] == '/' && line[1] == '/' ) continue; /* comment */ if( line[0] == '[' && line[line.size()-1] == ']' ) { /* New section. */ keyname = line.substr(1, line.size()-2); } else { /* New value. */ size_t iEqualIndex = line.find("="); if( iEqualIndex != string::npos ) { RString valuename = line.Left( (int) iEqualIndex ); RString value = line.Right( line.size()-valuename.size()-1 ); Trim( valuename ); if( keyname.size() && valuename.size() ) SetValue( keyname, valuename, value ); } } } }
void Resume::ReadVlcResumeFile() { Sleep(100); //wait for VLC to write file (TODO: make threaded) //get username TCHAR username[UNLEN + 1]; DWORD username_len = UNLEN + 1; GetUserName(username, &username_len); RString strTemp; RString strVlcFile; //build path to vlc info file RString strFilePath = _T("C:\\Users\\"); strFilePath += username; strFilePath += _T("\\AppData\\Roaming\\vlc\\vlc-qt-interface.ini"); //read VLC resume file into str if (!FileToString(strFilePath, strVlcFile)) return; if (GetFirstMatch(strVlcFile, _T("list=([^$]*?$)"), &strTemp)) { strTemp.Replace(_T(" "), _T("")); RArray<const TCHAR*> moviesTemp = SplitString(strTemp, _T(","), true); size = moviesTemp.GetSize(); if (size > MAX_SIZE) size = MAX_SIZE; for(int i=0; i<size; i++) { //remove % codes and turn + to space RString strTempMovie = URLDecode(moviesTemp[i]); //remove file:/// or file:// if (strTempMovie.Left(8) == _T("file:///")) strTempMovie = strTempMovie.Right(strTempMovie.GetLength() - 8); else strTempMovie = strTempMovie.Right(strTempMovie.GetLength() - 5); strTempMovie.Replace(_T("/"), _T("\\\\")); movies[i] = strTempMovie; } } if (GetFirstMatch(strVlcFile, _T("times=([^$]*?$)"), &strTemp)) { strTemp.Replace(_T(" "), _T("")); RArray<const TCHAR*> strTimes = SplitString(strTemp, _T(","), true); for(int i=0; i<strTimes.GetSize(); i++) times[i] = StringToNumber(strTimes[i])/1000; //milliseconds to seconds } UpdateResumeTimes(); }
static void FileNameToMetricsGroupAndElement( const RString &sFileName, RString &sMetricsGroupOut, RString &sElementOut ) { // split into class name and file name RString::size_type iIndexOfFirstSpace = sFileName.find(" "); if( iIndexOfFirstSpace == string::npos ) // no space { sMetricsGroupOut = ""; sElementOut = sFileName; } else { sMetricsGroupOut = sFileName.Left( iIndexOfFirstSpace ); sElementOut = sFileName.Right( sFileName.size() - iIndexOfFirstSpace - 1 ); } }
bool ActorUtil::GetAttrPath( const XNode *pNode, const RString &sName, RString &sOut ) { if( !pNode->GetAttrValue(sName, sOut) ) return false; bool bIsRelativePath = sOut.Left(1) != "/"; if( bIsRelativePath ) { RString sDir; if( !pNode->GetAttrValue("_Dir", sDir) ) { LOG->Warn( "Relative path \"%s\", but path is unknown", sOut.c_str() ); return false; } sOut = sDir+sOut; } return ActorUtil::ResolvePath( sOut, ActorUtil::GetWhere(pNode) ); }
void ParseFileName(RString_ strFileName, RString &strTitle, RString &strYear) { INT_PTR m, n; RString strTemp; strTitle = strFileName; strYear.Empty(); // only keep file name n = strTitle.ReverseFind(_T('\\')); if (n != -1) strTitle = strTitle.Mid(n + 1); //strTitle.MakeLower(); // strip file extension (max 4 chars) n = strTitle.ReverseFind(_T('.')); if (n != -1 && strTitle.GetLength() - n < 6) strTitle = strTitle.Left(n); // replace []{} by () strTitle.Replace(_T('['), _T('(')); strTitle.Replace(_T(']'), _T(')')); strTitle.Replace(_T('{'), _T('(')); strTitle.Replace(_T('}'), _T(')')); /* // replace anything not ,()0-9a-zA-Z by a space for (int i = 0; i < strTitle.GetLength(); i++) if (!(strTitle[i] == _T(',')) && !(strTitle[i] == _T('\'')) && !(strTitle[i] == _T('(')) && !(strTitle[i] == _T(')')) && !(strTitle[i] >= _T('0') && strTitle[i] <= _T('9')) && !(strTitle[i] >= _T('A') && strTitle[i] <= _T('Z')) && !(strTitle[i] >= _T('a') && strTitle[i] <= _T('z'))) *((LPTSTR)(LPCTSTR)strTitle + i) = _T(' '); */ // replace ._ by a space strTitle.Replace(_T('.'), _T(' ')); strTitle.Replace(_T('_'), _T(' ')); // remove redundant space while (strTitle.Replace(_T(" "), _T(" "))); strTitle.Trim(); // find year between (), strip anything following it for (n = 0; (n = strTitle.Find(_T('('), n)) != -1; n++) { if (n+5 < strTitle.GetLength() && strTitle[n+5] == _T(')')) { strTemp = strTitle.Mid(n+1, 4); if (StringToNumber(strTemp) > 1900) { strYear = strTemp; strTitle = strTitle.Left(n); break; } } } // remove anything between () for (m = 0, n = 0; (m = strTitle.Find(_T('('), n)) != -1 && (n = strTitle.Find(_T(')'), m)) != -1; m = 0, n = 0) strTitle = strTitle.Left(m) + strTitle.Mid(n+1); // find year not in (), but not as first word, strip anything following it strTitle.Replace(_T('('), _T(' ')); strTitle.Replace(_T(')'), _T(' ')); while (strTitle.Replace(_T(" "), _T(" "))); strTitle.Trim(); if (strYear.IsEmpty()) { m = 0; while (true) { if (m >= strTitle.GetLength()) break; n = strTitle.Find(_T(' '), m); if (n == -1) n = strTitle.GetLength(); if (m == n) {m = n + 1; continue;} if (n - m == 4) { strTemp = strTitle.Mid(m, n - m); if (StringToNumber(strTemp) > 1900 && m > 0) { strYear = strTemp; strTitle = strTitle.Left(m); break; } } m = n + 1; } } while (strTitle.Replace(_T(" "), _T(" "))); strTitle.Trim(); // place some literals in front if (strTitle.GetLength() > 5 && strTitle.Right(5) == _T(", the")) strTitle = _T("the ") + strTitle.Left(strTitle.GetLength() - 5); if (strTitle.GetLength() > 5 && strTitle.Right(5) == _T(", The")) strTitle = _T("The ") + strTitle.Left(strTitle.GetLength() - 5); if (strTitle.GetLength() > 3 && strTitle.Right(3) == _T(", a")) strTitle = _T("a ") + strTitle.Left(strTitle.GetLength() - 3); if (strTitle.GetLength() > 3 && strTitle.Right(3) == _T(", A")) strTitle = _T("A ") + strTitle.Left(strTitle.GetLength() - 3); strTitle.Replace(_T(','), _T(' ')); while (strTitle.Replace(_T(" "), _T(" "))); strTitle.Trim(); //TRACE0(_T("ParseFileName\n strFileName = ") + strFileName + _T("\n strTitle = ") + // strTitle + _T("\n strYear = ") + strYear + _T("\n")); }
/* mkdir -p. Doesn't fail if Path already exists and is a directory. */ bool CreateDirectories( RString Path ) { /* XXX: handle "//foo/bar" paths in Windows */ vector<RString> parts; RString curpath; /* If Path is absolute, add the initial slash ("ignore empty" will remove it). */ if( Path.Left(1) == "/" ) curpath = "/"; /* Ignore empty, so eg. "/foo/bar//baz" doesn't try to create "/foo/bar" twice. */ split( Path, "/", parts, true ); for(unsigned i = 0; i < parts.size(); ++i) { if( i ) curpath += "/"; curpath += parts[i]; #if defined(WIN32) if( curpath.size() == 2 && curpath[1] == ':' ) /* C: */ { /* Don't try to create the drive letter alone. */ continue; } #endif if( DoMkdir(curpath, 0777) == 0 ) continue; #if defined(WIN32) /* When creating a directory that already exists over Samba, Windows is * returning ENOENT instead of EEXIST. */ /* I can't reproduce this anymore. If we get ENOENT, log it but keep * going. */ if( errno == ENOENT ) { WARN( ssprintf("Couldn't create %s: %s", curpath.c_str(), strerror(errno)) ); errno = EEXIST; } #endif if( errno == EEXIST ) { /* Make sure it's a directory. */ struct stat st; if( DoStat(curpath, &st) != -1 && !(st.st_mode & S_IFDIR) ) { WARN( ssprintf("Couldn't create %s: path exists and is not a directory", curpath.c_str()) ); return false; } continue; // we expect to see this error } WARN( ssprintf("Couldn't create %s: %s", curpath.c_str(), strerror(errno)) ); return false; } return true; }
Actor *ActorUtil::LoadFromNode( const XNode* _pNode, Actor *pParentActor ) { ASSERT( _pNode != NULL ); XNode node = *_pNode; // Remove this in favor of using conditionals in Lua. -Chris // There are a number of themes out there that depend on this (including // sm-ssc default). Probably for the best to leave this in. -aj { bool bCond; if( node.GetAttrValue("Condition", bCond) && !bCond ) return NULL; } RString sClass; bool bHasClass = node.GetAttrValue( "Class", sClass ); if( !bHasClass ) bHasClass = node.GetAttrValue( "Type", sClass ); bool bLegacy = (node.GetAttr( "_LegacyXml" ) != NULL); if( !bHasClass && bLegacy ) sClass = GetLegacyActorClass( &node ); map<RString,CreateActorFn>::iterator iter = g_pmapRegistrees->find( sClass ); if( iter == g_pmapRegistrees->end() ) { RString sFile; if (bLegacy && node.GetAttrValue("File", sFile) && sFile != "") { RString sPath; // Handle absolute paths correctly if (sFile.Left(1) == "/") sPath = sFile; else sPath = Dirname(GetSourcePath(&node)) + sFile; if (ResolvePath(sPath, GetWhere(&node))) { Actor *pNewActor = MakeActor(sPath, pParentActor); if (pNewActor == NULL) return NULL; if (pParentActor) pNewActor->SetParent(pParentActor); pNewActor->LoadFromNode(&node); return pNewActor; } } // sClass is invalid RString sError = ssprintf( "%s: invalid Class \"%s\"", ActorUtil::GetWhere(&node).c_str(), sClass.c_str() ); LuaHelpers::ReportScriptError(sError); return new Actor; // Return a dummy object so that we don't crash in AutoActor later. } const CreateActorFn &pfn = iter->second; Actor *pRet = pfn(); if( pParentActor ) pRet->SetParent( pParentActor ); pRet->LoadFromNode( &node ); return pRet; }
void ScreenBookkeeping::UpdateView() { BookkeepingView view = m_vBookkeepingViews[m_iViewIndex]; { RString s; s += ALL_TIME.GetValue(); s += ssprintf( " %i\n", BOOKKEEPER->GetCoinsTotal() ); m_textAllTime.SetText( s ); } switch( view ) { case BookkeepingView_SongPlays: { Profile *pProfile = PROFILEMAN->GetMachineProfile(); vector<Song*> vpSongs; int iCount = 0; FOREACH_CONST( Song *, SONGMAN->GetAllSongs(), s ) { Song *pSong = *s; if( UNLOCKMAN->SongIsLocked(pSong) & ~LOCKED_DISABLED ) continue; iCount += pProfile->GetSongNumTimesPlayed( pSong ); vpSongs.push_back( pSong ); } m_textTitle.SetText( ssprintf(SONG_PLAYS.GetValue(), iCount) ); SongUtil::SortSongPointerArrayByNumPlays( vpSongs, pProfile, true ); const int iSongPerCol = 15; int iSongIndex = 0; for( int i=0; i<NUM_BOOKKEEPING_COLS; i++ ) { RString s; for( int j=0; j<iSongPerCol; j++ ) { if( iSongIndex < (int)vpSongs.size() ) { Song *pSong = vpSongs[iSongIndex]; int iCount = pProfile->GetSongNumTimesPlayed( pSong ); RString sTitle = ssprintf("%4d",iCount) + " " + pSong->GetDisplayFullTitle(); if( sTitle.length() > 22 ) sTitle = sTitle.Left(20) + "..."; s += sTitle + "\n"; iSongIndex++; } } m_textData[i].SetText( s ); m_textData[i].SetHorizAlign( align_left ); } } break; case BookkeepingView_LastDays: { m_textTitle.SetText( ssprintf(LAST_DAYS.GetValue(), NUM_LAST_DAYS) ); int coins[NUM_LAST_DAYS]; BOOKKEEPER->GetCoinsLastDays( coins ); int iTotalLast = 0; RString sTitle, sData; for( int i=0; i<NUM_LAST_DAYS; i++ ) { sTitle += LastDayToLocalizedString(i) + "\n"; sData += ssprintf("%d",coins[i]) + "\n"; iTotalLast += coins[i]; } sTitle += ALL_TIME.GetValue()+"\n"; sData += ssprintf("%i\n", iTotalLast); m_textData[0].SetText( "" ); m_textData[1].SetHorizAlign( align_left ); m_textData[1].SetText( sTitle ); m_textData[2].SetText( "" ); m_textData[3].SetHorizAlign( align_right ); m_textData[3].SetText( sData ); } break; case BookkeepingView_LastWeeks: { m_textTitle.SetText( ssprintf(LAST_WEEKS.GetValue(), NUM_LAST_WEEKS) ); int coins[NUM_LAST_WEEKS]; BOOKKEEPER->GetCoinsLastWeeks( coins ); RString sTitle, sData; for( int col=0; col<4; col++ ) { RString sTemp; for( int row=0; row<52/4; row++ ) { int week = row*4+col; sTemp += LastWeekToLocalizedString(week) + ssprintf(": %d",coins[week]) + "\n"; } m_textData[col].SetHorizAlign( align_left ); m_textData[col].SetText( sTemp ); } } break; case BookkeepingView_DayOfWeek: { m_textTitle.SetText( DAY_OF_WEEK ); int coins[DAYS_IN_WEEK]; BOOKKEEPER->GetCoinsByDayOfWeek( coins ); RString sTitle, sData; for( int i=0; i<DAYS_IN_WEEK; i++ ) { sTitle += DayOfWeekToString(i) + "\n"; sData += ssprintf("%d",coins[i]) + "\n"; } m_textData[0].SetText( "" ); m_textData[1].SetHorizAlign( align_left ); m_textData[1].SetText( sTitle ); m_textData[2].SetText( "" ); m_textData[3].SetHorizAlign( align_right ); m_textData[3].SetText( sData ); } break; case BookkeepingView_HourOfDay: { m_textTitle.SetText( HOUR_OF_DAY ); int coins[HOURS_IN_DAY]; BOOKKEEPER->GetCoinsByHour( coins ); RString sTitle1, sData1; for( int i=0; i<HOURS_IN_DAY/2; i++ ) { sTitle1 += HourInDayToLocalizedString(i) + "\n"; sData1 += ssprintf("%d",coins[i]) + "\n"; } RString sTitle2, sData2; for( int i=(HOURS_IN_DAY/2); i<HOURS_IN_DAY; i++ ) { sTitle2 += HourInDayToLocalizedString(i) + "\n"; sData2 += ssprintf("%d",coins[i]) + "\n"; } m_textData[0].SetHorizAlign( align_left ); m_textData[0].SetText( sTitle1 ); m_textData[1].SetHorizAlign( align_right ); m_textData[1].SetText( sData1 ); m_textData[2].SetHorizAlign( align_left ); m_textData[2].SetText( sTitle2 ); m_textData[3].SetHorizAlign( align_right ); m_textData[3].SetText( sData2 ); } break; default: ASSERT(0); } }
int _tmain(int argc, _TCHAR* argv[]) { _tsetlocale(LC_ALL, _T("")); // fixes VS11DP quirk // open csv file RCSVFileRO file; if (argc == 2) { if (!file.Open(CorrectPath(argv[1]))) {_putts(_T("Unable to open file: ") + CorrectPath(argv[1])); PAUSERETURN(-1);} } else if (argc == 1) { if (!file.Open(CorrectPath(_T("strings.csv")))) {_putts(_T("Please supply the name of CSV-file.")); PAUSERETURN(-2);} } else {_putts(_T("Invalid argument count.")); PAUSERETURN(-3);} if (file.GetLineCount() == 0) {_putts(_T("Empty file.")); PAUSERETURN(1);} if (file.GetLineCount() < 2) {_putts(_T("File must contain at least two lines.")); PAUSERETURN(-4);} if (file.GetFieldCount() < 2) {_putts(_T("File must contain at least two columns.")); PAUSERETURN(-5);} // generate header file contents RString str; str += _T("// strings.h : Defines the strings to be used throughout the application.\r\n"); str += _T("//\r\n"); str += _T("\r\n"); int n = 1000; int i, j; for (i = 1; i < file.GetLineCount(); i++) if (_tcscmp(file.GetField(i, 0), _T("")) != 0) str += RString(_T("#define ")) + file.GetField(i, 0) + _T(" ") + NumberToString(n++) + _T("\r\n"); str += _T("\r\n"); str += _T("inline void LoadStrings()\r\n"); str += _T("{\r\n"); str += _T("\tINT_PTR nLanguage;\r\n"); for (i = 1; i < file.GetFieldCount(); i++) { str += _T("\r\n"); str += (RString)_T("\tnLanguage = GetLangMgr()->GetLanguage(_T(\"") + file.GetField(0, i) + _T("\"));\r\n"); str += (RString)_T("\tif (nLanguage == -1)\r\n"); str += (RString)_T("\t\tnLanguage = GetLangMgr()->AddLanguage(_T(\"") + file.GetField(0, i) + _T("\"), _T(\"") + file.GetField(1, i) + _T("\"), _T(\"\"));\r\n\r\n"); for (j = 1; j < file.GetLineCount(); j++) { if (_tcscmp(file.GetField(j, 0), _T("")) == 0) continue; // skip empty ids str += (RString)_T("\tGetLangMgr()->SetString(nLanguage, ") + NumberToString(j-1) + _T(", _T(\"") + file.GetField(j, i) + _T("\"), false);\r\n"); } } str += _T("}\r\n"); // write to file RString strFilePath = CorrectPath(argc == 2 ? argv[1] : _T("strings.csv")); strFilePath = strFilePath.Left(strFilePath.ReverseFind(_T('\\'))+1) + _T("strings.h"); RArray<BYTE> data = StringToData(str, CHARSET_ANSI); if (!DataToFile(data, strFilePath)) {_tprintf(_T("Failed to open %s for writing.\n"), (LPCTSTR)strFilePath); PAUSERETURN(-6);} _tprintf(_T("Created %s succesfully.\n"), (LPCTSTR)strFilePath); PAUSERETURN(0); }
bool ThemeManager::IsThemeNameValid(RString const& name) { return name.Left(1) != "_"; }
void ParseFileName(RString_ strFileName, RString &strTitle, RString &strYear, INT_PTR &nSeason, INT_PTR &nEpisode, RString &strAirDate, BYTE &bType) { INT_PTR m, n; RString strTemp, strSeason, strEpisode; RString strYearTmp, strMonthTmp, strDayTmp; strTitle = strFileName; strYear.Empty(); // only keep file name n = strTitle.ReverseFind(_T('\\')); if (n != -1) strTitle = strTitle.Mid(n + 1); //strTitle.MakeLower(); // strip file extension (max 4 chars) n = strTitle.ReverseFind(_T('.')); if (n != -1 && strTitle.GetLength() - n < 6) strTitle = strTitle.Left(n); // replace []{} by () strTitle.Replace(_T('['), _T('(')); strTitle.Replace(_T(']'), _T(')')); strTitle.Replace(_T('{'), _T('(')); strTitle.Replace(_T('}'), _T(')')); /* // replace anything not ,()0-9a-zA-Z by a space for (int i = 0; i < strTitle.GetLength(); i++) if (!(strTitle[i] == _T(',')) && !(strTitle[i] == _T('\'')) && !(strTitle[i] == _T('(')) && !(strTitle[i] == _T(')')) && !(strTitle[i] >= _T('0') && strTitle[i] <= _T('9')) && !(strTitle[i] >= _T('A') && strTitle[i] <= _T('Z')) && !(strTitle[i] >= _T('a') && strTitle[i] <= _T('z'))) *((LPTSTR)(LPCTSTR)strTitle + i) = _T(' '); */ // remove urls RString strUrl; if (GetFirstMatch(strTitle, _T("([wW][wW][wW]\\.[^\\.]*?\\.[cC][oO][mM])"), &strUrl, NULL)) { m = strTitle.Find(strUrl, 0); if (m >= 0) strTitle = strTitle.Left(m) + strTitle.Right(strTitle.GetLength() - (m + strUrl.GetLength())); } // replace ._ -by a space strTitle.Replace(_T('.'), _T(' ')); strTitle.Replace(_T('_'), _T(' ')); strTitle.Replace(_T('-'), _T(' ')); // remove redundant space while (strTitle.Replace(_T(" "), _T(" "))); strTitle.Trim(); // find year between (), strip anything following it for (n = 0; (n = strTitle.Find(_T('('), n)) != -1; n++) { if (n + 5 < strTitle.GetLength() && strTitle[n + 5] == _T(')')) { strTemp = strTitle.Mid(n + 1, 4); if (StringToNumber(strTemp) > 1900) { strYear = strTemp; strTitle = strTitle.Left(n); break; } } } // remove anything between () for (m = 0, n = 0; (m = strTitle.Find(_T('('), n)) != -1 && (n = strTitle.Find(_T(')'), m)) != -1; m = 0, n = 0) strTitle = strTitle.Left(m) + strTitle.Mid(n + 1); // for TV shows. Find the season and episode and remove everything following it if (GetFirstMatch(strTitle, _T("([Ss]\\d?\\d[Ee]\\d?\\d)"), &strTemp, NULL)) { m = strTitle.Find(strTemp, 0); if (GetFirstMatch(strTemp, _T("[Ss](\\d?\\d)[Ee](\\d?\\d)"), &strSeason, &strEpisode, NULL)) { nSeason = StringToNumber(strSeason); nEpisode = StringToNumber(strEpisode); bType = DB_TYPE_TV; } if (m >= 0) strTitle = strTitle.Left(m); } // for TV shows by date and parse date aired if (GetFirstMatch(strTitle, _T("(\\d\\d\\d\\d) (\\d?\\d) (\\d?\\d)"), &strYearTmp, &strMonthTmp, &strDayTmp, NULL)) { const RString Month[12] = { _T("Jan"), _T("Feb"), _T("Mar"), _T("Apr"), _T("May"), _T("Jun"), _T("Jul"), _T("Aug"), _T("Sep"), _T("Oct"), _T("Nov"), _T("Dec") }; strAirDate = strDayTmp + _T(" ") + Month[StringToNumber(strMonthTmp) - 1] + _T(". ") + strYearTmp; bType = DB_TYPE_TV; } // find year not in (), but not as first word, strip anything following it strTitle.Replace(_T('('), _T(' ')); strTitle.Replace(_T(')'), _T(' ')); while (strTitle.Replace(_T(" "), _T(" "))); strTitle.Trim(); if (strYear.IsEmpty()) { m = 0; while (m < strTitle.GetLength()) { n = strTitle.Find(_T(' '), m); if (n == -1) n = strTitle.GetLength(); if (m == n) { m = n + 1; continue; } if (n - m == 4) { strTemp = strTitle.Mid(m, n - m); if (StringToNumber(strTemp) > 1900 && m > 0) { strYear = strTemp; strTitle = strTitle.Left(m); break; } } m = n + 1; } } // strip 'season[s] \\d' and anything following it RString strSeasons; if (GetFirstMatch(strTitle, _T("([Ss]eason[s]? ?\\d?\\d(?: ?- ?\\d?\\d)?)"), &strSeasons, NULL)) { m = strTitle.Find(strSeasons, 0); if (m >= 0) strTitle = strTitle.Left(m); bType = DB_TYPE_TV; } //Remove episode numbers of the form XXofYY - TODO: process to return episode number RString strOf; if (GetFirstMatch(strTitle, _T("(\\d?\\d[oO][fF]\\d?\\d)"), &strOf, NULL)) { m = strTitle.Find(strOf, 0); if (m > 0) strTitle = strTitle.Left(m); bType = DB_TYPE_TV; } // strip common movie descriptors and everything after static const RString strDescriptors[] = { _T("webrip"), _T("dvdrip"), _T("dvdscr"), _T("xvid"), _T("bdrip"), _T("brrip"), _T("hdtv"), _T("pdtv"), _T("box set"), _T("box-set"), _T("x264") }; foreach(strDescriptors, strD) { m = strTitle.FindNoCase(strD, 0); if (m > 0) strTitle = strTitle.Left(m); }