// BuildFromXML methods should always return a BlockFile, not NULL, // even if the result is flawed (e.g., refers to nonexistent file), // as testing will be done in DirManager::ProjectFSCK(). BlockFile *PCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs) { wxFileName summaryFileName; wxFileName aliasFileName; int aliasStart=0, aliasLen=0, aliasChannel=0; float min = 0.0f, max = 0.0f, rms = 0.0f; double dblValue; long nValue; while(*attrs) { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; if (!value) break; const wxString strValue = value; if (!wxStricmp(attr, wxT("summaryfile")) && // Can't use XMLValueChecker::IsGoodFileName here, but do part of its test. XMLValueChecker::IsGoodFileString(strValue) && (strValue.Length() + 1 + dm.GetProjectDataDir().Length() <= PLATFORM_MAX_PATH)) { if (!dm.AssignFile(summaryFileName, strValue, false)) // Make sure summaryFileName is back to uninitialized state so we can detect problem later. summaryFileName.Clear(); } else if (!wxStricmp(attr, wxT("aliasfile"))) { if (XMLValueChecker::IsGoodPathName(strValue)) aliasFileName.Assign(strValue); else if (XMLValueChecker::IsGoodFileName(strValue, dm.GetProjectDataDir())) // Allow fallback of looking for the file name, located in the data directory. aliasFileName.Assign(dm.GetProjectDataDir(), strValue); else if (XMLValueChecker::IsGoodPathString(strValue)) // If the aliased file is missing, we failed XMLValueChecker::IsGoodPathName() // and XMLValueChecker::IsGoodFileName, because both do existence tests, // but we want to keep the reference to the missing file because it's a good path string. aliasFileName.Assign(strValue); } else if (XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) { // integer parameters if (!wxStricmp(attr, wxT("aliasstart")) && (nValue >= 0)) aliasStart = nValue; else if (!wxStricmp(attr, wxT("aliaslen")) && (nValue >= 0)) aliasLen = nValue; else if (!wxStricmp(attr, wxT("aliaschannel")) && XMLValueChecker::IsValidChannel(aliasChannel)) aliasChannel = nValue; else if (!wxStricmp(attr, wxT("min"))) min = nValue; else if (!wxStricmp(attr, wxT("max"))) max = nValue; else if (!wxStricmp(attr, wxT("rms")) && (nValue >= 0)) rms = nValue; } // mchinen: the min/max can be (are?) doubles as well, so handle those cases. // Vaughan: The code to which I added the XMLValueChecker checks // used wxAtoi to convert the string to an int. // So it's possible some prior project formats used ints (?), so am keeping // those above, but yes, we need to handle floats. else if (XMLValueChecker::IsGoodString(strValue) && Internat::CompatibleToDouble(strValue, &dblValue)) { // double parameters if (!wxStricmp(attr, wxT("min"))) min = dblValue; else if (!wxStricmp(attr, wxT("max"))) max = dblValue; else if (!wxStricmp(attr, wxT("rms")) && (dblValue >= 0.0)) rms = dblValue; } } return new PCMAliasBlockFile(summaryFileName, aliasFileName, aliasStart, aliasLen, aliasChannel, min, max, rms); }
//============================================================================= // Function: CompareFcn // Purpose: Used to sort the NN list alphabetically, case insensitive. //============================================================================= static int CompareFcn(const wxString& first, const wxString& second) { return wxStricmp(first.c_str(), second.c_str()); } // CompareFcn
//============================================================================= // Function: BuildRemoteList // Purpose: Append Network Neighborhood items to the list. // Notes: - Mounted gets transalated into Connected. FilteredAdd is told // to ignore the Mounted flag since we need to handle it in a weird // way manually. // - The resulting list is sorted alphabetically. //============================================================================= static bool BuildRemoteList(wxArrayString& list, NETRESOURCE* pResSrc, unsigned flagsSet, unsigned flagsUnset) { // NN query depends on dynamically loaded library. if (!s_pWNetOpenEnum || !s_pWNetEnumResource || !s_pWNetCloseEnum) { wxLogError(_("Failed to load mpr.dll.")); return false; } // Don't waste time doing the work if the flags conflict. if (flagsSet & wxFS_VOL_MOUNTED && flagsUnset & wxFS_VOL_MOUNTED) return false; //---------------------------------------------- // Generate the list according to the flags set. //---------------------------------------------- BuildListFromNN(list, pResSrc, flagsSet, flagsUnset); list.Sort(CompareFcn); //------------------------------------------------------------------------- // If mounted only is requested, then we only need one simple pass. // Otherwise, we need to build a list of all NN volumes and then apply the // list of mounted drives to it. //------------------------------------------------------------------------- if (!(flagsSet & wxFS_VOL_MOUNTED)) { // generate. wxArrayString mounted; BuildListFromNN(mounted, pResSrc, flagsSet | wxFS_VOL_MOUNTED, flagsUnset & ~wxFS_VOL_MOUNTED); mounted.Sort(CompareFcn); // apply list from bottom to top to preserve indexes if removing items. ssize_t iList = list.GetCount()-1; for (ssize_t iMounted = mounted.GetCount()-1; iMounted >= 0 && iList >= 0; iMounted--) { int compare; wxString all(list[iList]); wxString mount(mounted[iMounted]); while (compare = wxStricmp(list[iList].c_str(), mounted[iMounted].c_str()), compare > 0 && iList >= 0) { iList--; all = list[iList]; } if (compare == 0) { // Found the element. Remove it or mark it mounted. if (flagsUnset & wxFS_VOL_MOUNTED) list.RemoveAt(iList); else s_fileInfo[list[iList]].m_flags |= wxFS_VOL_MOUNTED; } iList--; } } return true; } // BuildRemoteList
/// Constructs a ODDecodeBlockFile from the xml output of WriteXML. /// Also schedules the ODDecodeBlockFile for OD loading. // BuildFromXML methods should always return a BlockFile, not NULL, // even if the result is flawed (e.g., refers to nonexistent file), // as testing will be done in DirManager::ProjectFSCK(). BlockFilePtr ODDecodeBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs) { wxFileNameWrapper summaryFileName; wxFileNameWrapper audioFileName; sampleCount aliasStart = 0; size_t aliasLen = 0; int aliasChannel=0; long nValue; long long nnValue; unsigned int decodeType=0; while(*attrs) { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; if (!value) break; const wxString strValue = value; if (!wxStricmp(attr, wxT("summaryfile")) && // Can't use XMLValueChecker::IsGoodFileName here, but do part of its test. XMLValueChecker::IsGoodFileString(strValue) && (strValue.Length() + 1 + dm.GetProjectDataDir().Length() <= PLATFORM_MAX_PATH)) { if (!dm.AssignFile(summaryFileName, strValue, false)) // Make sure summaryFileName is back to uninitialized state so we can detect problem later. summaryFileName.Clear(); } else if( !wxStricmp(attr, wxT("audiofile")) ) { if (XMLValueChecker::IsGoodPathName(strValue)) audioFileName.Assign(strValue); else if (XMLValueChecker::IsGoodFileName(strValue, dm.GetProjectDataDir())) // Allow fallback of looking for the file name, located in the data directory. audioFileName.Assign(dm.GetProjectDataDir(), strValue); else if (XMLValueChecker::IsGoodPathString(strValue)) // If the file is missing, we failed XMLValueChecker::IsGoodPathName() // and XMLValueChecker::IsGoodFileName, because both do existence tests, // but we want to keep the reference to the file because it's a good path string. audioFileName.Assign(strValue); } else if ( !wxStricmp(attr, wxT("aliasstart")) ) { if (XMLValueChecker::IsGoodInt64(strValue) && strValue.ToLongLong(&nnValue) && (nnValue >= 0)) aliasStart = nnValue; } else if (XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) { // integer parameters if (!wxStricmp(attr, wxT("aliaslen")) && (nValue >= 0)) aliasLen = nValue; else if (!wxStricmp(attr, wxT("aliaschannel")) && XMLValueChecker::IsValidChannel(aliasChannel)) aliasChannel = nValue; else if( !wxStricmp(attr, wxT("decodetype")) ) decodeType = nValue; } } return make_blockfile<ODDecodeBlockFile> (std::move(summaryFileName), std::move(audioFileName), aliasStart, aliasLen, aliasChannel, decodeType, 0, 0, 0, false); }
void wxFileData::ReadData() { if (IsDrive()) { m_size = 0; return; } #if defined(__DOS__) || (defined(__WINDOWS__) && !defined(__WXWINCE__)) || defined(__OS2__) // c:\.. is a drive don't stat it if ((m_fileName == wxT("..")) && (m_filePath.length() <= 5)) { m_type = is_drive; m_size = 0; return; } #endif // __DOS__ || __WINDOWS__ #ifdef __WXWINCE__ // WinCE DWORD fileAttribs = GetFileAttributes(m_filePath.fn_str()); m_type |= (fileAttribs & FILE_ATTRIBUTE_DIRECTORY) != 0 ? is_dir : 0; wxString p, f, ext; wxSplitPath(m_filePath, & p, & f, & ext); if (wxStricmp(ext, wxT("exe")) == 0) m_type |= is_exe; // Find out size m_size = 0; HANDLE fileHandle = CreateFile(m_filePath.fn_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); if (fileHandle != INVALID_HANDLE_VALUE) { m_size = GetFileSize(fileHandle, 0); CloseHandle(fileHandle); } m_dateTime = wxFileModificationTime(m_filePath); #else // OTHER PLATFORMS wxStructStat buff; #if defined(__UNIX__) && (!defined( __OS2__ ) && !defined(__VMS)) lstat( m_filePath.fn_str(), &buff ); m_type |= S_ISLNK( buff.st_mode ) != 0 ? is_link : 0; #else // no lstat() // only translate to file charset if we don't go by our // wxStat implementation #ifndef wxNEED_WX_UNISTD_H wxStat( m_filePath.fn_str() , &buff ); #else wxStat( m_filePath, &buff ); #endif #endif m_type |= (buff.st_mode & S_IFDIR) != 0 ? is_dir : 0; m_type |= (buff.st_mode & wxS_IXUSR) != 0 ? is_exe : 0; m_size = buff.st_size; m_dateTime = buff.st_mtime; #endif // __WXWINCE__ #if defined(__UNIX__) m_permissions.Printf(_T("%c%c%c%c%c%c%c%c%c"), buff.st_mode & wxS_IRUSR ? _T('r') : _T('-'), buff.st_mode & wxS_IWUSR ? _T('w') : _T('-'), buff.st_mode & wxS_IXUSR ? _T('x') : _T('-'), buff.st_mode & wxS_IRGRP ? _T('r') : _T('-'), buff.st_mode & wxS_IWGRP ? _T('w') : _T('-'), buff.st_mode & wxS_IXGRP ? _T('x') : _T('-'), buff.st_mode & wxS_IROTH ? _T('r') : _T('-'), buff.st_mode & wxS_IWOTH ? _T('w') : _T('-'), buff.st_mode & wxS_IXOTH ? _T('x') : _T('-')); #elif defined(__WIN32__) DWORD attribs = ::GetFileAttributes(m_filePath.c_str()); if (attribs != (DWORD)-1) { m_permissions.Printf(_T("%c%c%c%c"), attribs & FILE_ATTRIBUTE_ARCHIVE ? _T('A') : _T(' '), attribs & FILE_ATTRIBUTE_READONLY ? _T('R') : _T(' '), attribs & FILE_ATTRIBUTE_HIDDEN ? _T('H') : _T(' '), attribs & FILE_ATTRIBUTE_SYSTEM ? _T('S') : _T(' ')); } #endif // try to get a better icon if (m_image == wxFileIconsTable::file) { if (m_fileName.Find(wxT('.'), true) != wxNOT_FOUND) { m_image = wxTheFileIconsTable->GetIconID( m_fileName.AfterLast(wxT('.'))); } else if (IsExe()) { m_image = wxFileIconsTable::executable; } } }
/// Constructs a ODPCMAliasBlockFile from the xml output of WriteXML. /// Also schedules the ODPCMAliasBlockFile for OD loading. BlockFile *ODPCMAliasBlockFile::BuildFromXML(DirManager &dm, const wxChar **attrs) { wxFileName summaryFileName; wxFileName aliasFileName; int aliasStart=0, aliasLen=0, aliasChannel=0; float min=0, max=0, rms=0; long nValue; while(*attrs) { const wxChar *attr = *attrs++; const wxChar *value = *attrs++; if (!value) break; const wxString strValue = value; if( !wxStricmp(attr, wxT("summaryfile")) ) { // Can't use XMLValueChecker::IsGoodFileName here, but do part of its test. if (!XMLValueChecker::IsGoodFileString(strValue)) return NULL; #ifdef _WIN32 if (strValue.Length() + 1 + dm.GetProjectDataDir().Length() > MAX_PATH) return NULL; #endif dm.AssignFile(summaryFileName,value,FALSE); } else if( !wxStricmp(attr, wxT("aliasfile")) ) { if (XMLValueChecker::IsGoodPathName(strValue)) aliasFileName.Assign(strValue); else if (XMLValueChecker::IsGoodFileName(strValue, dm.GetProjectDataDir())) // Allow fallback of looking for the file name, located in the data directory. aliasFileName.Assign(dm.GetProjectDataDir(), strValue); else return NULL; } else if (XMLValueChecker::IsGoodInt(strValue) && strValue.ToLong(&nValue)) { // integer parameters if( !wxStricmp(attr, wxT("aliasstart")) ) aliasStart = nValue; else if( !wxStricmp(attr, wxT("aliaslen")) ) aliasLen = nValue; else if( !wxStricmp(attr, wxT("aliaschannel")) ) aliasChannel = nValue; //The folowing attributes don't exist yet - not quite sure what to do with them yet. // else if( !wxStricmp(attr, wxT("min")) ) // min = nValue; // else if( !wxStricmp(attr, wxT("max")) ) // max = nValue; // else if( !wxStricmp(attr, wxT("rms")) ) // rms = nValue; } } //file doesn't exist, but IsGoodFileName Checks that it does - maybe we should have a different method to check for valid names? if ( /*!XMLValueChecker::IsGoodFileName(summaryFileName.GetFullName(), summaryFileName.GetPath(wxPATH_GET_VOLUME)) || */ !XMLValueChecker::IsGoodFileName(aliasFileName.GetFullName(), aliasFileName.GetPath(wxPATH_GET_VOLUME)) || (aliasLen <= 0) || (aliasLen < 0.0) || !XMLValueChecker::IsValidChannel(aliasChannel) || (rms < 0.0)) return NULL; //TODO: schedule for OD Loading return new ODPCMAliasBlockFile(summaryFileName, aliasFileName, aliasStart, aliasLen, aliasChannel); }
/*static*/ int cbTreeCtrl::filesSortNameOnly(const ProjectFile* arg1, const ProjectFile* arg2) { if (arg1 && arg2) return wxStricmp(arg1->file.GetFullName(), arg2->file.GetFullName()); return 0; }
bool DirManager::HandleXMLTag(const wxChar *tag, const wxChar **attrs) { if( mLoadingTarget == NULL ) return false; BlockFile* pBlockFile = NULL; if( !wxStricmp(tag, wxT("silentblockfile")) ) { // Silent blocks don't actually have a file associated, so // we don't need to worry about the hash table at all *mLoadingTarget = SilentBlockFile::BuildFromXML(*this, attrs); return true; } else if ( !wxStricmp(tag, wxT("simpleblockfile")) ) pBlockFile = SimpleBlockFile::BuildFromXML(*this, attrs); else if( !wxStricmp(tag, wxT("pcmaliasblockfile")) ) pBlockFile = PCMAliasBlockFile::BuildFromXML(*this, attrs); else if( !wxStricmp(tag, wxT("blockfile")) || !wxStricmp(tag, wxT("legacyblockfile")) ) { // Support Audacity version 1.1.1 project files int i=0; bool alias = false; while(attrs[i]) { if (!wxStricmp(attrs[i], wxT("alias"))) { if (wxAtoi(attrs[i+1])==1) alias = true; } i++; if (attrs[i]) i++; } if (alias) pBlockFile = LegacyAliasBlockFile::BuildFromXML(projFull, attrs); else pBlockFile = LegacyBlockFile::BuildFromXML(projFull, attrs, mLoadingBlockLen, mLoadingFormat); } else return false; if ((pBlockFile == NULL) || // Check the length here so we don't have to do it in each BuildFromXML method. ((mMaxSamples > -1) && // is initialized (pBlockFile->GetLength() > mMaxSamples))) { delete pBlockFile; return false; } else *mLoadingTarget = pBlockFile; // // If the block we loaded is already in the hash table, then the // object we just loaded is a duplicate, so we delete it and // return a reference to the existing object instead. // wxString name = (*mLoadingTarget)->GetFileName().GetName(); BlockFile *retrieved = blockFileHash[name]; if (retrieved) { // Lock it in order to delete it safely, i.e. without having // it delete the file, too... (*mLoadingTarget)->Lock(); delete (*mLoadingTarget); Ref(retrieved); // Add one to its reference count *mLoadingTarget = retrieved; return true; } // This is a new object blockFileHash[name]=*mLoadingTarget; // MakeBlockFileName wasn't used so we must add the directory // balancing information BalanceInfoAdd(name); return true; }
extern MFolder *CreateFolderTreeEntry(MFolder *parent, const String& name, MFolderType folderType, long folderFlags, const String& path, bool notify) { // construct the full name by prepending the parent name (if we have parent // and its name is non empty - only root entry is empty) String fullname; if ( parent && parent->GetType() != MF_ROOT ) { fullname << parent->GetFullName() << _T('/'); } fullname << name; MFolder *folder = MFolder::Create(fullname, folderType); if ( folder == NULL ) { wxLogError(_("Cannot create a folder '%s'.\n" "Maybe a folder of this name already exists?"), fullname.c_str()); return NULL; } Profile_obj profile(folder->GetFullName()); profile->writeEntry(MP_FOLDER_PATH, path); // copy folder flags from its parent folder->SetFlags(folderFlags); // special IMAP hack: in IMAP, the entry with empty folder name and the // special folder INBOX are equivalent (i.e. if you don't specify any // folder name you get INBOX) so it doesn't make sense to have both an // entry for IMAP server (path == "") and INBOX on it // // the solution we adopt is to disable the IMAP server folder when IMAP // Inbox is created to clear the confusion between the two // // of course, if the user really wants to open it he can always clear the // "can't be opened" flag in the folder properties dialog... if ( folderType == MF_IMAP ) { MFolder_obj folderParent(folder->GetParent()); // are we're the child of the IMAP server entry? if ( folderParent && folderParent->GetType() == MF_IMAP && folderParent->GetPath().empty() ) { // yes, now check if we're INBOX if ( path.empty() || !wxStricmp(path, _T("INBOX")) ) { // INBOX created, so disable the parent folderParent->AddFlags(MF_FLAGS_NOSELECT); // should we do MailFolder::CloseFolder(folderParent)? } } } // notify the others about new folder creation unless expliticly disabled if ( notify ) { MEventManager::Send( new MEventFolderTreeChangeData(fullname, MEventFolderTreeChangeData::Create) ); } return folder; }
bool DirManager::HandleXMLTag(const char *tag, const char **attrs) { if( mLoadingTarget == NULL ) return false; if( !wxStricmp(tag, "silentblockfile") ) { // Silent blocks don't actually have a file associated, so // we don't need to worry about the hash table at all *mLoadingTarget = SilentBlockFile::BuildFromXML(projFull, attrs); return true; } else if ( !wxStricmp(tag, "simpleblockfile") ) *mLoadingTarget = SimpleBlockFile::BuildFromXML(projFull, attrs); else if( !wxStricmp(tag, "pcmaliasblockfile") ) *mLoadingTarget = PCMAliasBlockFile::BuildFromXML(projFull, attrs); else if( !wxStricmp(tag, "blockfile") || !wxStricmp(tag, "legacyblockfile") ) { // Support Audacity version 1.1.1 project files int i=0; bool alias = false; while(attrs[i]) { if (!wxStricmp(attrs[i], "alias")) { if (atoi(attrs[i+1])==1) alias = true; } i++; if (attrs[i]) i++; } if (alias) *mLoadingTarget = LegacyAliasBlockFile::BuildFromXML(projFull, attrs); else *mLoadingTarget = LegacyBlockFile::BuildFromXML(projFull, attrs, mLoadingBlockLen, mLoadingFormat); } else return false; // // If the block we loaded is already in the hash table, then the // object we just loaded is a duplicate, so we delete it and // return a reference to the existing object instead. // wxString name = (*mLoadingTarget)->GetFileName().GetName(); BlockFile *retrieved = (BlockFile *) blockFileHash->Get(name); if (retrieved) { // Lock it in order to delete it safely, i.e. without having // it delete the file, too... (*mLoadingTarget)->Lock(); delete (*mLoadingTarget); Ref(retrieved); // Add one to its reference count *mLoadingTarget = retrieved; return true; } // This is a new object blockFileHash->Put( name, (wxObject*) *mLoadingTarget ); CheckHashTableSize(); return true; }
void RegRichTextCtrl::WhatBasicRegister( const char *RegNames, int val, Context &ctx ) { if ( 0 == wxStricmp(RegNames, wxT("EAX")) ) ctx.Eax = val; else if ( 0 == wxStricmp(RegNames, wxT("ECX")) ) ctx.Ecx = val; else if ( 0 == wxStricmp(RegNames, wxT("EDX")) ) ctx.Edx = val; else if ( 0 == wxStricmp(RegNames, wxT("EBX")) ) ctx.Ebx = val; else if ( 0 == wxStricmp(RegNames, wxT("ESP")) ) ctx.Esp = val; else if ( 0 == wxStricmp(RegNames, wxT("EBP")) ) ctx.Ebp = val; else if ( 0 == wxStricmp(RegNames, wxT("ESI")) ) ctx.Esi = val; else if ( 0 == wxStricmp(RegNames, wxT("EDI")) ) ctx.Edi = val; else if ( 0 == wxStricmp(RegNames, wxT("EIP")) ) ctx.Eip = val; else if ( 0 == wxStricmp(RegNames, wxT("ES")) ) ctx.SegEs = val; else if ( 0 == wxStricmp(RegNames, wxT("CS")) ) ctx.SegCs = val; else if ( 0 == wxStricmp(RegNames, wxT("SS")) ) ctx.SegSs = val; else if ( 0 == wxStricmp(RegNames, wxT("DS")) ) ctx.SegDs = val; else if ( 0 == wxStricmp(RegNames, wxT("FS")) ) ctx.SegFs = val; else if ( 0 == wxStricmp(RegNames, wxT("GS")) ) ctx.SegGs = val; }
static int CompareGameListItems(const GameListItem* iso1, const GameListItem* iso2, long sortData = CGameListCtrl::COLUMN_TITLE) { int t = 1; if (sortData < 0) { t = -1; sortData = -sortData; } switch (sortData) { case CGameListCtrl::COLUMN_TITLE: if (!strcasecmp(iso1->GetName().c_str(), iso2->GetName().c_str())) { if (iso1->GetUniqueID() != iso2->GetUniqueID()) return t * (iso1->GetUniqueID() > iso2->GetUniqueID() ? 1 : -1); if (iso1->GetRevision() != iso2->GetRevision()) return t * (iso1->GetRevision() > iso2->GetRevision() ? 1 : -1); if (iso1->GetDiscNumber() != iso2->GetDiscNumber()) return t * (iso1->GetDiscNumber() > iso2->GetDiscNumber() ? 1 : -1); wxString iso1_filename = wxFileNameFromPath(iso1->GetFileName()); wxString iso2_filename = wxFileNameFromPath(iso2->GetFileName()); if (iso1_filename != iso2_filename) return t * wxStricmp(iso1_filename, iso2_filename); } return strcasecmp(iso1->GetName().c_str(), iso2->GetName().c_str()) * t; case CGameListCtrl::COLUMN_MAKER: return strcasecmp(iso1->GetCompany().c_str(), iso2->GetCompany().c_str()) * t; case CGameListCtrl::COLUMN_FILENAME: return wxStricmp(wxFileNameFromPath(iso1->GetFileName()), wxFileNameFromPath(iso2->GetFileName())) * t; case CGameListCtrl::COLUMN_ID: return strcasecmp(iso1->GetUniqueID().c_str(), iso2->GetUniqueID().c_str()) * t; case CGameListCtrl::COLUMN_COUNTRY: if (iso1->GetCountry() > iso2->GetCountry()) return 1 * t; if (iso1->GetCountry() < iso2->GetCountry()) return -1 * t; return 0; case CGameListCtrl::COLUMN_SIZE: if (iso1->GetFileSize() > iso2->GetFileSize()) return 1 * t; if (iso1->GetFileSize() < iso2->GetFileSize()) return -1 * t; return 0; case CGameListCtrl::COLUMN_PLATFORM: if (iso1->GetPlatform() > iso2->GetPlatform()) return 1 * t; if (iso1->GetPlatform() < iso2->GetPlatform()) return -1 * t; return 0; case CGameListCtrl::COLUMN_EMULATION_STATE: { const int nState1 = iso1->GetEmuState(), nState2 = iso2->GetEmuState(); if (nState1 > nState2) return 1 * t; if (nState1 < nState2) return -1 * t; else return 0; } break; } return 0; }