241 lines
6.8 KiB
C++
241 lines
6.8 KiB
C++
/*
|
|
* ModDocTemplate.cpp
|
|
* ------------------
|
|
* Purpose: CDocTemplate and CModDocManager specialization for CModDoc.
|
|
* Notes : (currently none)
|
|
* Authors: OpenMPT Devs
|
|
* The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
|
|
*/
|
|
|
|
|
|
#include "stdafx.h"
|
|
#include "FolderScanner.h"
|
|
#include "Mainfrm.h"
|
|
#include "Moddoc.h"
|
|
#include "ModDocTemplate.h"
|
|
#include "Reporting.h"
|
|
#include "SelectPluginDialog.h"
|
|
#include "../soundlib/plugins/PluginManager.h"
|
|
|
|
OPENMPT_NAMESPACE_BEGIN
|
|
|
|
|
|
#ifdef MPT_ALL_LOGGING
|
|
#define DDEDEBUG
|
|
#endif
|
|
|
|
|
|
CDocument *CModDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL addToMru, BOOL makeVisible)
|
|
{
|
|
const mpt::PathString filename = (lpszPathName ? mpt::PathString::FromCString(lpszPathName) : mpt::PathString());
|
|
|
|
// First, remove document from MRU list.
|
|
if(addToMru)
|
|
{
|
|
theApp.RemoveMruItem(filename);
|
|
}
|
|
|
|
CDocument *pDoc = CMultiDocTemplate::OpenDocumentFile(filename.empty() ? nullptr : filename.ToCString().GetString(), addToMru, makeVisible);
|
|
if(pDoc)
|
|
{
|
|
CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
|
|
if (pMainFrm) pMainFrm->OnDocumentCreated(static_cast<CModDoc *>(pDoc));
|
|
} else if(!filename.empty() && CMainFrame::GetMainFrame() && addToMru)
|
|
{
|
|
// Opening the document failed
|
|
CMainFrame::GetMainFrame()->UpdateMRUList();
|
|
}
|
|
return pDoc;
|
|
}
|
|
|
|
|
|
CDocument *CModDocTemplate::OpenTemplateFile(const mpt::PathString &filename, bool isExampleTune)
|
|
{
|
|
CDocument *doc = OpenDocumentFile(filename.ToCString(), isExampleTune ? TRUE : FALSE, TRUE);
|
|
if(doc)
|
|
{
|
|
CModDoc *modDoc = static_cast<CModDoc *>(doc);
|
|
// Clear path so that saving will not take place in templates/examples folder.
|
|
modDoc->ClearFilePath();
|
|
if(!isExampleTune)
|
|
{
|
|
CMultiDocTemplate::SetDefaultTitle(modDoc);
|
|
m_nUntitledCount++;
|
|
// Name has changed...
|
|
CMainFrame::GetMainFrame()->UpdateTree(modDoc, GeneralHint().General());
|
|
|
|
// Reset edit history for template files
|
|
CSoundFile &sndFile = modDoc->GetSoundFile();
|
|
sndFile.GetFileHistory().clear();
|
|
sndFile.m_dwCreatedWithVersion = Version::Current();
|
|
sndFile.m_dwLastSavedWithVersion = Version();
|
|
sndFile.m_modFormat = ModFormatDetails();
|
|
sndFile.m_songArtist = TrackerSettings::Instance().defaultArtist;
|
|
if(sndFile.GetType() != MOD_TYPE_MPT)
|
|
{
|
|
// Always enforce most compatible playback for legacy module types
|
|
sndFile.m_playBehaviour = sndFile.GetDefaultPlaybackBehaviour(sndFile.GetType());
|
|
}
|
|
doc->UpdateAllViews(nullptr, UpdateHint().ModType().AsLPARAM());
|
|
} else
|
|
{
|
|
// Remove extension from title, so that saving the file will not suggest a filename like e.g. "example.it.it".
|
|
const CString title = modDoc->GetTitle();
|
|
const int dotPos = title.ReverseFind(_T('.'));
|
|
if(dotPos >= 0)
|
|
{
|
|
modDoc->SetTitle(title.Left(dotPos));
|
|
}
|
|
}
|
|
}
|
|
return doc;
|
|
}
|
|
|
|
|
|
void CModDocTemplate::AddDocument(CDocument *doc)
|
|
{
|
|
CMultiDocTemplate::AddDocument(doc);
|
|
m_documents.insert(static_cast<CModDoc *>(doc));
|
|
}
|
|
|
|
|
|
void CModDocTemplate::RemoveDocument(CDocument *doc)
|
|
{
|
|
CMultiDocTemplate::RemoveDocument(doc);
|
|
m_documents.erase(static_cast<CModDoc *>(doc));
|
|
}
|
|
|
|
|
|
bool CModDocTemplate::DocumentExists(const CModDoc *doc) const
|
|
{
|
|
return m_documents.count(const_cast<CModDoc *>(doc)) != 0;
|
|
}
|
|
|
|
|
|
CDocument *CModDocManager::OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU)
|
|
{
|
|
const mpt::PathString filename = (lpszFileName ? mpt::PathString::FromCString(lpszFileName) : mpt::PathString());
|
|
|
|
if(filename.IsDirectory())
|
|
{
|
|
FolderScanner scanner(filename, FolderScanner::kOnlyFiles | FolderScanner::kFindInSubDirectories);
|
|
mpt::PathString file;
|
|
CDocument *pDoc = nullptr;
|
|
while(scanner.Next(file))
|
|
{
|
|
pDoc = OpenDocumentFile(file.ToCString(), bAddToMRU);
|
|
}
|
|
return pDoc;
|
|
}
|
|
|
|
if(const auto fileExt = filename.GetFileExt(); !mpt::PathString::CompareNoCase(fileExt, P_(".dll")) || !mpt::PathString::CompareNoCase(fileExt, P_(".vst3")))
|
|
{
|
|
if(auto plugManager = theApp.GetPluginManager(); plugManager != nullptr)
|
|
{
|
|
if(auto plugLib = plugManager->AddPlugin(filename, TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes); plugLib != nullptr)
|
|
{
|
|
if(!CSelectPluginDlg::VerifyPlugin(plugLib, nullptr))
|
|
{
|
|
plugManager->RemovePlugin(plugLib);
|
|
}
|
|
return nullptr;
|
|
}
|
|
}
|
|
}
|
|
|
|
CDocument *pDoc = CDocManager::OpenDocumentFile(lpszFileName, bAddToMRU);
|
|
if(pDoc == nullptr && !filename.empty())
|
|
{
|
|
if(!filename.IsFile())
|
|
{
|
|
Reporting::Error(MPT_CFORMAT("Unable to open \"{}\": file does not exist.")(filename.ToCString()));
|
|
theApp.RemoveMruItem(filename);
|
|
CMainFrame::GetMainFrame()->UpdateMRUList();
|
|
} else
|
|
{
|
|
// Case: Valid path but opening failed.
|
|
const int numDocs = theApp.GetOpenDocumentCount();
|
|
Reporting::Notification(MPT_CFORMAT("Opening \"{}\" failed. This can happen if "
|
|
"no more modules can be opened or if the file type was not "
|
|
"recognised (currently there {} {} document{} open).")(
|
|
filename.ToCString(), (numDocs == 1) ? CString(_T("is")) : CString(_T("are")), numDocs, (numDocs == 1) ? CString(_T("")) : CString(_T("s"))));
|
|
}
|
|
}
|
|
return pDoc;
|
|
}
|
|
|
|
|
|
BOOL CModDocManager::OnDDECommand(LPTSTR lpszCommand)
|
|
{
|
|
BOOL bResult, bActivate;
|
|
#ifdef DDEDEBUG
|
|
MPT_LOG_GLOBAL(LogDebug, "DDE", U_("OnDDECommand: ") + mpt::ToUnicode(mpt::winstring(lpszCommand)));
|
|
#endif
|
|
// Handle any DDE commands recognized by your application
|
|
// and return TRUE. See implementation of CWinApp::OnDDEComand
|
|
// for example of parsing the DDE command string.
|
|
bResult = FALSE;
|
|
bActivate = FALSE;
|
|
if ((lpszCommand) && lpszCommand[0] && (theApp.m_pMainWnd))
|
|
{
|
|
std::size_t len = _tcslen(lpszCommand);
|
|
std::vector<TCHAR> s(lpszCommand, lpszCommand + len + 1);
|
|
|
|
len--;
|
|
while((len > 0) && _tcschr(_T("(){}[]\'\" "), s[len]))
|
|
{
|
|
s[len--] = 0;
|
|
}
|
|
TCHAR *pszCmd = s.data();
|
|
while (pszCmd[0] == _T('[')) pszCmd++;
|
|
TCHAR *pszData = pszCmd;
|
|
while ((pszData[0] != _T('(')) && (pszData[0]))
|
|
{
|
|
if (((BYTE)pszData[0]) <= (BYTE)' ') *pszData = 0;
|
|
pszData++;
|
|
}
|
|
while ((*pszData) && (_tcschr(_T("(){}[]\'\" "), *pszData)))
|
|
{
|
|
*pszData = 0;
|
|
pszData++;
|
|
}
|
|
// Edit/Open
|
|
if ((!lstrcmpi(pszCmd, _T("Edit")))
|
|
|| (!lstrcmpi(pszCmd, _T("Open"))))
|
|
{
|
|
if (pszData[0])
|
|
{
|
|
bResult = TRUE;
|
|
bActivate = TRUE;
|
|
OpenDocumentFile(pszData);
|
|
}
|
|
} else
|
|
// New
|
|
if (!lstrcmpi(pszCmd, _T("New")))
|
|
{
|
|
OpenDocumentFile(_T(""));
|
|
bResult = TRUE;
|
|
bActivate = TRUE;
|
|
}
|
|
#ifdef DDEDEBUG
|
|
MPT_LOG_GLOBAL(LogDebug, "DDE", MPT_UFORMAT("{}({})")(mpt::winstring(pszCmd), mpt::winstring(pszData)));
|
|
#endif
|
|
if ((bActivate) && (theApp.m_pMainWnd->m_hWnd))
|
|
{
|
|
if (theApp.m_pMainWnd->IsIconic()) theApp.m_pMainWnd->ShowWindow(SW_RESTORE);
|
|
theApp.m_pMainWnd->SetActiveWindow();
|
|
}
|
|
}
|
|
// Return FALSE for any DDE commands you do not handle.
|
|
#ifdef DDEDEBUG
|
|
if (!bResult)
|
|
{
|
|
MPT_LOG_GLOBAL(LogDebug, "DDE", U_("WARNING: failure in CModDocManager::OnDDECommand()"));
|
|
}
|
|
#endif
|
|
return bResult;
|
|
}
|
|
|
|
|
|
OPENMPT_NAMESPACE_END
|