From: <man...@us...> - 2013-12-19 13:57:59
|
Revision: 3500 http://sourceforge.net/p/modplug/code/3500 Author: manxorist Date: 2013-12-19 13:57:47 +0000 (Thu, 19 Dec 2013) Log Message: ----------- [Ref] Move MakeGmTime back to misc_util.h . [Ref] Move FileHistory from CModDoc into CSoundFile. [New] libopenmpt: Add 'date' metadata for DMF and IT files. [Fix] xmp-openmpt: Set 'date' tag. [New] openmpt123: Display 'Date' and write tag via FLAC and libsndfile. [New] xmp-openmpt: Display Artist and Date in general info window. Modified Paths: -------------- trunk/OpenMPT/common/misc_util.cpp trunk/OpenMPT/common/misc_util.h trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp trunk/OpenMPT/libopenmpt/xmp-openmpt.cpp trunk/OpenMPT/mptrack/MPTrackUtil.cpp trunk/OpenMPT/mptrack/MPTrackUtil.h trunk/OpenMPT/mptrack/Moddoc.cpp trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/TrackerSettings.cpp trunk/OpenMPT/mptrack/dlg_misc.cpp trunk/OpenMPT/openmpt123/openmpt123.cpp trunk/OpenMPT/openmpt123/openmpt123_flac.hpp trunk/OpenMPT/openmpt123/openmpt123_sndfile.hpp trunk/OpenMPT/soundlib/ITTools.cpp trunk/OpenMPT/soundlib/ITTools.h trunk/OpenMPT/soundlib/Load_dmf.cpp trunk/OpenMPT/soundlib/Load_it.cpp trunk/OpenMPT/soundlib/Sndfile.cpp trunk/OpenMPT/soundlib/Sndfile.h trunk/OpenMPT/test/test.cpp Modified: trunk/OpenMPT/common/misc_util.cpp =================================================================== --- trunk/OpenMPT/common/misc_util.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/common/misc_util.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -15,7 +15,9 @@ #include <sstream> #include <string> +#include <time.h> + template<typename T> inline T ConvertStrToHelper(const std::string &str) { @@ -79,6 +81,47 @@ long double ConvertStrToLongDouble(const std::wstring &str) { return ConvertStrToHelper<long double>(str); } +namespace Util +{ + +time_t Util::MakeGmTime(tm *timeUtc) +//---------------------------------- +{ + #if MPT_COMPILER_MSVC + return _mkgmtime(timeUtc); + #else // !MPT_COMPILER_MSVC + // There is no portable way in C/C++ to convert between time_t and struct tm in UTC. + // Approximate it as good as possible without implementing full date handling logic. + // NOTE: + // This can be wrong for dates during DST switch. + if(!timeUtc) + { + return time_t(); + } + tm t = *timeUtc; + time_t localSinceEpoch = mktime(&t); + const tm * tmpLocal = localtime(&localSinceEpoch); + if(!tmpLocal) + { + return localSinceEpoch; + } + tm localTM = *tmpLocal; + const tm * tmpUTC = gmtime(&localSinceEpoch); + if(!tmpUTC) + { + return localSinceEpoch; + } + tm utcTM = *tmpUTC; + double offset = difftime(mktime(&localTM), mktime(&utcTM)); + double timeScaleFactor = difftime(2, 1); + time_t utcSinceEpoch = localSinceEpoch + Util::Round<time_t>(offset / timeScaleFactor); + return utcSinceEpoch; + #endif // MPT_COMPILER_MSVC +} + +} // namespace Util + + #ifdef MODPLUG_TRACKER namespace Util Modified: trunk/OpenMPT/common/misc_util.h =================================================================== --- trunk/OpenMPT/common/misc_util.h 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/common/misc_util.h 2013-12-19 13:57:47 UTC (rev 3500) @@ -18,6 +18,7 @@ #include <cstdlib> #include <string.h> +#include <time.h> #include "typedefs.h" @@ -402,6 +403,8 @@ namespace Util { + time_t MakeGmTime(tm *timeUtc); + // Minimum of 3 values template <class T> inline const T& Min(const T& a, const T& b, const T& c) {return std::min(std::min(a, b), c);} Modified: trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp =================================================================== --- trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/libopenmpt/libopenmpt_impl.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -642,6 +642,7 @@ retval.push_back("tracker"); retval.push_back("artist"); retval.push_back("title"); + retval.push_back("date"); retval.push_back("message"); retval.push_back("warnings"); return retval; @@ -661,6 +662,11 @@ return mod_string_to_utf8( m_sndFile->songArtist ); } else if ( key == std::string("title") ) { return mod_string_to_utf8( m_sndFile->GetTitle() ); + } else if ( key == std::string("date") ) { + if ( m_sndFile->GetFileHistory().empty() ) { + return std::string(); + } + return mod_string_to_utf8( m_sndFile->GetFileHistory()[m_sndFile->GetFileHistory().size() - 1].AsISO8601() ); } else if ( key == std::string("message") ) { std::string retval = m_sndFile->songMessage.GetFormatted( SongMessage::leLF ); if ( retval.empty() ) { Modified: trunk/OpenMPT/libopenmpt/xmp-openmpt.cpp =================================================================== --- trunk/OpenMPT/libopenmpt/xmp-openmpt.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/libopenmpt/xmp-openmpt.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -454,7 +454,7 @@ write_xmplay_tag( &tags[0], convert_to_native( mod.get_metadata("title") ) ); write_xmplay_tag( &tags[1], convert_to_native( mod.get_metadata("artist") ) ); write_xmplay_tag( &tags[2], convert_to_native( mod.get_metadata("xmplay-album") ) ); // todo, libopenmpt does not support that - write_xmplay_tag( &tags[3], convert_to_native( mod.get_metadata("xmplay-date") ) ); // todo, libopenmpt does not support that + write_xmplay_tag( &tags[3], convert_to_native( mod.get_metadata("date") ) ); write_xmplay_tag( &tags[4], convert_to_native( mod.get_metadata("xmplay-tracknumber") ) ); // todo, libopenmpt does not support that write_xmplay_tag( &tags[5], convert_to_native( mod.get_metadata("xmplay-genre") ) ); // todo, libopenmpt does not support that write_xmplay_tag( &tags[6], convert_to_native( mod.get_metadata("message") ) ); @@ -739,6 +739,18 @@ str << "\r" << "Format" << "\t" << sanitize_xmplay_info_string( self->mod->get_metadata("type") ) << " (" << sanitize_xmplay_info_string( self->mod->get_metadata("type_long") ) << ")" << "\r"; + bool metadatainfo = false; + if ( !self->mod->get_metadata("artist").empty() ) { + metadatainfo = true; + str << "Artist" << "\t" << sanitize_xmplay_info_string( self->mod->get_metadata("artist") ) << "\r"; + } + if ( !self->mod->get_metadata("date").empty() ) { + metadatainfo = true; + str << "Date" << "\t" << sanitize_xmplay_info_string( self->mod->get_metadata("date") ) << "\r"; + } + if ( metadatainfo ) { + str << "\r"; + } if ( !self->mod->get_metadata("container").empty() ) { str << "Container" << "\t" << sanitize_xmplay_info_string( self->mod->get_metadata("container") ) << " (" << sanitize_xmplay_info_string( self->mod->get_metadata("container_long") ) << ")" << "\r"; } Modified: trunk/OpenMPT/mptrack/MPTrackUtil.cpp =================================================================== --- trunk/OpenMPT/mptrack/MPTrackUtil.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/mptrack/MPTrackUtil.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -65,12 +65,6 @@ } -time_t Util::sdTime::MakeGmTime(tm& timeUtc) -{ - return _mkgmtime(&timeUtc); -} - - bool Util::sdOs::IsPathFileAvailable(const mpt::PathString &pszFilePath, FileMode fm) { return (_waccess(pszFilePath.AsNative().c_str(), fm) == 0); Modified: trunk/OpenMPT/mptrack/MPTrackUtil.h =================================================================== --- trunk/OpenMPT/mptrack/MPTrackUtil.h 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/mptrack/MPTrackUtil.h 2013-12-19 13:57:47 UTC (rev 3500) @@ -12,20 +12,12 @@ #include <string> -#include <time.h> LPCCH LoadResource(LPCTSTR lpName, LPCTSTR lpType, LPCCH& pData, size_t& nSize, HGLOBAL& hglob); std::string GetErrorMessage(DWORD nErrorCode); -namespace Util { namespace sdTime -{ - - time_t MakeGmTime(tm& timeUtc); - -}} // namespace Util::sdTime - namespace Util { namespace sdOs { /// Checks whether file or folder exists and whether it has the given mode. Modified: trunk/OpenMPT/mptrack/Moddoc.cpp =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/mptrack/Moddoc.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -140,7 +140,6 @@ // Set the creation date of this file (or the load time if we're loading an existing file) time(&m_creationTime); - m_FileHistory.clear(); m_bsInstrumentModified.reset(); Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/mptrack/Moddoc.h 2013-12-19 13:57:47 UTC (rev 3500) @@ -94,21 +94,6 @@ ///////////////////////////////////////////////////////////////////////// -// File edit history - -#define HISTORY_TIMER_PRECISION 18.2f - -//================ -struct FileHistory -//================ -{ - // Date when the file was loaded in the the tracker or created. - tm loadDate; - // Time the file was open in the editor, in 1/18.2th seconds (frequency of a standard DOS timer, to keep compatibility with Impulse Tracker easy). - uint32 openTime; -}; - -///////////////////////////////////////////////////////////////////////// // Split Keyboard Settings (pattern editor) //========================== @@ -193,7 +178,6 @@ CPatternUndo m_PatternUndo; CSampleUndo m_SampleUndo; SplitKeyboardSettings m_SplitKeyboardSettings; // this is maybe not the best place to keep them, but it should do the job - std::vector<FileHistory> m_FileHistory; // File edit history time_t m_creationTime; bool bModifiedAutosave; // Modified since last autosave? @@ -265,8 +249,6 @@ CSampleUndo &GetSampleUndo() { return m_SampleUndo; } SplitKeyboardSettings &GetSplitKeyboardSettings() { return m_SplitKeyboardSettings; } - std::vector<FileHistory> &GetFileHistory() { return m_FileHistory; } - const std::vector<FileHistory> &GetFileHistory() const { return m_FileHistory; } time_t GetCreationTime() const { return m_creationTime; } // operations Modified: trunk/OpenMPT/mptrack/TrackerSettings.cpp =================================================================== --- trunk/OpenMPT/mptrack/TrackerSettings.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/mptrack/TrackerSettings.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -288,7 +288,7 @@ lastUpdate.tm_year -= 1900; lastUpdate.tm_mon--; } - time_t outTime = Util::sdTime::MakeGmTime(lastUpdate); + time_t outTime = Util::MakeGmTime(&lastUpdate); if(outTime < 0) outTime = 0; CUpdateCheck::SetUpdateSettings ( Modified: trunk/OpenMPT/mptrack/dlg_misc.cpp =================================================================== --- trunk/OpenMPT/mptrack/dlg_misc.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/mptrack/dlg_misc.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -1065,11 +1065,11 @@ CString s; uint64 totalTime = 0; - const size_t num = m_pModDoc->GetFileHistory().size(); + const size_t num = m_pModDoc->GetrSoundFile().GetFileHistory().size(); for(size_t n = 0; n < num; n++) { - const FileHistory *hist = &(m_pModDoc->GetFileHistory().at(n)); + const FileHistory *hist = &(m_pModDoc->GetrSoundFile().GetFileHistory().at(n)); totalTime += hist->openTime; // Date @@ -1099,7 +1099,7 @@ SetWindowText(s); } // Enable or disable Clear button - GetDlgItem(IDC_BTN_CLEAR)->EnableWindow((m_pModDoc->GetFileHistory().empty()) ? FALSE : TRUE); + GetDlgItem(IDC_BTN_CLEAR)->EnableWindow((m_pModDoc->GetrSoundFile().GetFileHistory().empty()) ? FALSE : TRUE); return TRUE; @@ -1109,9 +1109,9 @@ void CEditHistoryDlg::OnClearHistory() //------------------------------------ { - if(m_pModDoc != nullptr && !m_pModDoc->GetFileHistory().empty()) + if(m_pModDoc != nullptr && !m_pModDoc->GetrSoundFile().GetFileHistory().empty()) { - m_pModDoc->GetFileHistory().clear(); + m_pModDoc->GetrSoundFile().GetFileHistory().clear(); m_pModDoc->SetModified(); OnInitDialog(); } Modified: trunk/OpenMPT/openmpt123/openmpt123.cpp =================================================================== --- trunk/OpenMPT/openmpt123/openmpt123.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/openmpt123/openmpt123.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -1233,6 +1233,7 @@ set_field( fields, "Container" ).ostream() << ( mod.get_metadata( "container" ).empty() ? std::string("none") : ( mod.get_metadata( "container" ) + " (" + mod.get_metadata( "container_long" ) + ")" ) ); set_field( fields, "Type" ).ostream() << mod.get_metadata( "type" ) << " (" << mod.get_metadata( "type_long" ) << ")"; set_field( fields, "Tracker" ).ostream() << mod.get_metadata( "tracker" ); + set_field( fields, "Date" ).ostream() << mod.get_metadata( "date" ); set_field( fields, "Artist" ).ostream() << mod.get_metadata( "artist" ); } if ( true ) { Modified: trunk/OpenMPT/openmpt123/openmpt123_flac.hpp =================================================================== --- trunk/OpenMPT/openmpt123/openmpt123_flac.hpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/openmpt123/openmpt123_flac.hpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -67,6 +67,7 @@ tags.clear(); tags.push_back( std::make_pair( "TITLE", metadata[ "title" ] ) ); tags.push_back( std::make_pair( "ARTIST", metadata[ "artist" ] ) ); + tags.push_back( std::make_pair( "DATE", metadata[ "date" ] ) ); tags.push_back( std::make_pair( "COMMENT", metadata[ "message" ] ) ); if ( !metadata[ "type" ].empty() && !metadata[ "tracker" ].empty() ) { tags.push_back( std::make_pair( "SOURCEMEDIA", std::string() + "'" + metadata[ "type" ] + "' tracked music file, made with '" + metadata[ "tracker" ] + "', rendered with '" + get_encoder_tag() + "'" ) ); Modified: trunk/OpenMPT/openmpt123/openmpt123_sndfile.hpp =================================================================== --- trunk/OpenMPT/openmpt123/openmpt123_sndfile.hpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/openmpt123/openmpt123_sndfile.hpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -177,6 +177,7 @@ void write_metadata( std::map<std::string,std::string> metadata ) { write_metadata_field( SF_STR_TITLE, metadata[ "title" ] ); write_metadata_field( SF_STR_ARTIST, metadata[ "artist" ] ); + write_metadata_field( SF_STR_DATE, metadata[ "date" ] ); write_metadata_field( SF_STR_COMMENT, metadata[ "message" ] ); write_metadata_field( SF_STR_SOFTWARE, append_software_tag( metadata[ "tracker" ] ) ); } Modified: trunk/OpenMPT/soundlib/ITTools.cpp =================================================================== --- trunk/OpenMPT/soundlib/ITTools.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/soundlib/ITTools.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -641,10 +641,6 @@ } -#ifdef MODPLUG_TRACKER - -#include "../mptrack/Moddoc.h" - // Convert all multi-byte numeric values to current platform's endianness or vice versa. void ITHistoryStruct::ConvertEndianness() //--------------------------------------- @@ -680,5 +676,3 @@ fattime = static_cast<uint16>((mptHistory.loadDate.tm_sec / 2) | (mptHistory.loadDate.tm_min << 5) | (mptHistory.loadDate.tm_hour << 11)); runtime = static_cast<uint32>(mptHistory.openTime * (18.2f / HISTORY_TIMER_PRECISION)); } - -#endif // MODPLUG_TRACKER Modified: trunk/OpenMPT/soundlib/ITTools.h =================================================================== --- trunk/OpenMPT/soundlib/ITTools.h 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/soundlib/ITTools.h 2013-12-19 13:57:47 UTC (rev 3500) @@ -297,9 +297,7 @@ STATIC_ASSERT(sizeof(ITSample) == 80); -#ifdef MODPLUG_TRACKER struct FileHistory; -#endif // MODPLUG_TRACKER // IT Header extension: Save history struct PACKED ITHistoryStruct @@ -308,8 +306,6 @@ uint16 fattime; // DOS / FAT time when the file was opened / created in the editor. uint32 runtime; // The time how long the file was open in the editor, in 1/18.2th seconds. (= ticks of the DOS timer) -#ifdef MODPLUG_TRACKER - // Convert all multi-byte numeric values to current platform's endianness or vice versa. void ConvertEndianness(); @@ -318,8 +314,6 @@ // Convert OpenMPT's internal edit history representation to an ITHistoryStruct void ConvertToIT(const FileHistory &mptHistory); -#endif // MODPLUG_TRACKER - }; STATIC_ASSERT(sizeof(ITHistoryStruct) == 8); Modified: trunk/OpenMPT/soundlib/Load_dmf.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_dmf.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/soundlib/Load_dmf.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -976,18 +976,13 @@ mpt::String::Read<mpt::String::spacePadded>(songName, fileHeader.songname); mpt::String::Read<mpt::String::spacePadded>(songArtist, fileHeader.composer); -#ifdef MODPLUG_TRACKER - if(GetpModDoc() != nullptr) - { - FileHistory mptHistory; - MemsetZero(mptHistory); - mptHistory.loadDate.tm_mday = Clamp(fileHeader.creationDay, uint8(0), uint8(31)); - mptHistory.loadDate.tm_mon = Clamp(fileHeader.creationMonth, uint8(1), uint8(12)) - 1; - mptHistory.loadDate.tm_year = fileHeader.creationYear; - GetpModDoc()->GetFileHistory().clear(); - GetpModDoc()->GetFileHistory().push_back(mptHistory); - } -#endif // MODPLUG_TRACKER + FileHistory mptHistory; + MemsetZero(mptHistory); + mptHistory.loadDate.tm_mday = Clamp(fileHeader.creationDay, uint8(0), uint8(31)); + mptHistory.loadDate.tm_mon = Clamp(fileHeader.creationMonth, uint8(1), uint8(12)) - 1; + mptHistory.loadDate.tm_year = fileHeader.creationYear; + m_FileHistory.clear(); + m_FileHistory.push_back(mptHistory); // Go through all chunks now ChunkReader chunkFile(file); Modified: trunk/OpenMPT/soundlib/Load_it.cpp =================================================================== --- trunk/OpenMPT/soundlib/Load_it.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/soundlib/Load_it.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -530,22 +530,14 @@ if(file.CanRead(nflt * sizeof(ITHistoryStruct)) && file.GetPosition() + nflt * sizeof(ITHistoryStruct) <= minPtr) { -#ifdef MODPLUG_TRACKER - if(GetpModDoc() != nullptr) + m_FileHistory.reserve(nflt); + for(size_t n = 0; n < nflt; n++) { - GetpModDoc()->GetFileHistory().reserve(nflt); - for(size_t n = 0; n < nflt; n++) - { - FileHistory mptHistory; - ITHistoryStruct itHistory; - file.Read(itHistory); - itHistory.ConvertToMPT(mptHistory); - GetpModDoc()->GetFileHistory().push_back(mptHistory); - } - } else -#endif // MODPLUG_TRACKER - { - file.Skip(nflt * sizeof(ITHistoryStruct)); + FileHistory mptHistory; + ITHistoryStruct itHistory; + file.Read(itHistory); + itHistory.ConvertToMPT(mptHistory); + m_FileHistory.push_back(mptHistory); } } else { @@ -1057,12 +1049,10 @@ uint32 SaveITEditHistory(const CSoundFile *pSndFile, FILE *f) //----------------------------------------------------------- { + size_t num = pSndFile->GetFileHistory().size(); #ifdef MODPLUG_TRACKER CModDoc *pModDoc = pSndFile->GetpModDoc(); - const size_t num = (pModDoc != nullptr) ? pModDoc->GetFileHistory().size() + 1 : 0; // + 1 for this session -#else - const size_t num = 0; - MPT_UNREFERENCED_PARAMETER(pSndFile); + num += (pModDoc != nullptr) ? 1 : 0; // + 1 for this session #endif // MODPLUG_TRACKER uint16 fnum = (uint16)MIN(num, uint16_max); // Number of entries that are actually going to be written @@ -1075,17 +1065,19 @@ SwapBytesLE(fnum); fwrite(&fnum, 2, 1, f); -#ifdef MODPLUG_TRACKER // Write history data const size_t start = (num > uint16_max) ? num - uint16_max : 0; for(size_t n = start; n < num; n++) { FileHistory mptHistory; - if(n < num - 1) +#ifdef MODPLUG_TRACKER + if(n < pSndFile->GetFileHistory().size()) +#endif // MODPLUG_TRACKER { // Previous timestamps - mptHistory = pModDoc->GetFileHistory().at(n); + mptHistory = pSndFile->GetFileHistory().at(n); +#ifdef MODPLUG_TRACKER } else { // Current ("new") timestamp @@ -1100,6 +1092,7 @@ pSndFile->AddToLog("localtime() returned nullptr."); mptHistory.openTime = (uint32)(difftime(time(nullptr), creationTime) * (double)HISTORY_TIMER_PRECISION); +#endif // MODPLUG_TRACKER } ITHistoryStruct itHistory; @@ -1107,7 +1100,6 @@ fwrite(&itHistory, 1, sizeof(itHistory), f); } -#endif // MODPLUG_TRACKER return bytes_written; } Modified: trunk/OpenMPT/soundlib/Sndfile.cpp =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/soundlib/Sndfile.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -23,6 +23,7 @@ #include "../common/StringFixer.h" #include "FileReader.h" #include <iostream> +#include <time.h> #ifndef NO_ARCHIVE_SUPPORT #include "../unarchiver/unarchiver.h" @@ -484,6 +485,74 @@ // -! NEW_FEATURE#0027 +std::string FileHistory::AsISO8601() const +//---------------------------------------- +{ + tm date = loadDate; + if(openTime > 0) + { + // Calculate the date when editing finished. + double openSeconds = (double)openTime / (double)HISTORY_TIMER_PRECISION; + tm tmpLoadDate = loadDate; + time_t loadDateSinceEpoch = Util::MakeGmTime(&tmpLoadDate); + double timeScaleFactor = difftime(2, 1); + time_t saveDateSinceEpoch = loadDateSinceEpoch + Util::Round<time_t>(openSeconds / timeScaleFactor); + const tm * tmpSaveDate = gmtime(&saveDateSinceEpoch); + if(tmpSaveDate) + { + date = *tmpSaveDate; + } + } + // We assume date in UTC here. + // This is not 100% correct because FileHistory does not contain complete timezone information. + // There are too many differences in supported format specifiers in strftime() + // and strftime does not support reduced precision ISO8601 at all. + // Just do the formatting ourselves. + std::string result; + std::string timezone = std::string("Z"); + if(date.tm_year == 0) + { + return result; + } + result += mpt::fmt::dec0<4>(date.tm_year + 1900); + if(date.tm_mon < 0 || date.tm_mon > 11) + { + return result; + } + result += std::string("-") + mpt::fmt::dec0<2>(date.tm_mon + 1); + if(date.tm_mday < 1 || date.tm_mday > 31) + { + return result; + } + result += std::string("-") + mpt::fmt::dec0<2>(date.tm_mday); + if(date.tm_hour == 0 && date.tm_min == 0 && date.tm_sec == 0) + { + return result; + } + if(date.tm_hour < 0 || date.tm_hour > 23) + { + return result; + } + if(date.tm_min < 0 || date.tm_min > 59) + { + return result; + } + result += std::string("T"); + if(date.tm_isdst > 0) + { + timezone = std::string("+01:00"); + } + result += mpt::fmt::dec0<2>(date.tm_hour) + std::string(":") + mpt::fmt::dec0<2>(date.tm_min); + if(date.tm_sec < 0 || date.tm_sec > 61) + { + return result + timezone; + } + result += std::string(":") + mpt::fmt::dec0<2>(date.tm_sec); + result += timezone; + return result; +} + + ////////////////////////////////////////////////////////// // CSoundFile @@ -620,6 +689,7 @@ songArtist.clear(); songMessage.clear(); madeWithTracker.clear(); + m_FileHistory.clear(); } @@ -927,6 +997,7 @@ songArtist.clear(); songMessage.clear(); madeWithTracker.clear(); + m_FileHistory.clear(); for(SAMPLEINDEX i = 1; i < MAX_SAMPLES; i++) { Modified: trunk/OpenMPT/soundlib/Sndfile.h =================================================================== --- trunk/OpenMPT/soundlib/Sndfile.h 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/soundlib/Sndfile.h 2013-12-19 13:57:47 UTC (rev 3500) @@ -195,6 +195,24 @@ #endif // MODPLUG_TRACKER +///////////////////////////////////////////////////////////////////////// +// File edit history + +#define HISTORY_TIMER_PRECISION 18.2f + +//================ +struct FileHistory +//================ +{ + // Date when the file was loaded in the the tracker or created. + tm loadDate; + // Time the file was open in the editor, in 1/18.2th seconds (frequency of a standard DOS timer, to keep compatibility with Impulse Tracker easy). + uint32 openTime; + // Return the date as a (possibly truncated if not enough precision is available) ISO 8601 formatted date. + std::string AsISO8601() const; +}; + + struct TimingInfo { double InputLatency; // seconds @@ -431,6 +449,12 @@ SongMessage songMessage; std::string madeWithTracker; +protected: + std::vector<FileHistory> m_FileHistory; // File edit history +public: + std::vector<FileHistory> &GetFileHistory() { return m_FileHistory; } + const std::vector<FileHistory> &GetFileHistory() const { return m_FileHistory; } + #ifdef MODPLUG_TRACKER // -> CODE#0023 // -> DESC="IT project files (.itp)" Modified: trunk/OpenMPT/test/test.cpp =================================================================== --- trunk/OpenMPT/test/test.cpp 2013-12-19 10:41:47 UTC (rev 3499) +++ trunk/OpenMPT/test/test.cpp 2013-12-19 13:57:47 UTC (rev 3500) @@ -1168,9 +1168,6 @@ void TestLoadMPTMFile(const CSoundFile &sndFile) //---------------------------------------------- { -#ifdef MODPLUG_TRACKER - const CModDoc *pModDoc = sndFile.GetpModDoc(); -#endif // MODPLUG_TRACKER // Global Variables VERIFY_EQUAL_NONCONT(sndFile.GetTitle(), "Test Module_____________X"); @@ -1192,10 +1189,9 @@ VERIFY_EQUAL_NONCONT(sndFile.m_dwCreatedWithVersion, MAKE_VERSION_NUMERIC(1, 19, 02, 05)); VERIFY_EQUAL_NONCONT(sndFile.m_nRestartPos, 1); -#ifdef MODPLUG_TRACKER // Edit history - VERIFY_EQUAL_NONCONT(pModDoc->GetFileHistory().size() > 0, true); - const FileHistory &fh = pModDoc->GetFileHistory().at(0); + VERIFY_EQUAL_NONCONT(sndFile.GetFileHistory().size() > 0, true); + const FileHistory &fh = sndFile.GetFileHistory().at(0); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_year, 111); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_mon, 5); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_mday, 14); @@ -1203,7 +1199,6 @@ VERIFY_EQUAL_NONCONT(fh.loadDate.tm_min, 8); VERIFY_EQUAL_NONCONT(fh.loadDate.tm_sec, 32); VERIFY_EQUAL_NONCONT((uint32)((double)fh.openTime / HISTORY_TIMER_PRECISION), 31); -#endif // MODPLUG_TRACKER // Macros VERIFY_EQUAL_NONCONT(sndFile.m_MidiCfg.GetParameteredMacroType(0), sfx_reso); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |