1
0

ModDocTemplate.cpp 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240
  1. /*
  2. * ModDocTemplate.cpp
  3. * ------------------
  4. * Purpose: CDocTemplate and CModDocManager specialization for CModDoc.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "FolderScanner.h"
  11. #include "Mainfrm.h"
  12. #include "Moddoc.h"
  13. #include "ModDocTemplate.h"
  14. #include "Reporting.h"
  15. #include "SelectPluginDialog.h"
  16. #include "../soundlib/plugins/PluginManager.h"
  17. OPENMPT_NAMESPACE_BEGIN
  18. #ifdef MPT_ALL_LOGGING
  19. #define DDEDEBUG
  20. #endif
  21. CDocument *CModDocTemplate::OpenDocumentFile(LPCTSTR lpszPathName, BOOL addToMru, BOOL makeVisible)
  22. {
  23. const mpt::PathString filename = (lpszPathName ? mpt::PathString::FromCString(lpszPathName) : mpt::PathString());
  24. // First, remove document from MRU list.
  25. if(addToMru)
  26. {
  27. theApp.RemoveMruItem(filename);
  28. }
  29. CDocument *pDoc = CMultiDocTemplate::OpenDocumentFile(filename.empty() ? nullptr : filename.ToCString().GetString(), addToMru, makeVisible);
  30. if(pDoc)
  31. {
  32. CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
  33. if (pMainFrm) pMainFrm->OnDocumentCreated(static_cast<CModDoc *>(pDoc));
  34. } else if(!filename.empty() && CMainFrame::GetMainFrame() && addToMru)
  35. {
  36. // Opening the document failed
  37. CMainFrame::GetMainFrame()->UpdateMRUList();
  38. }
  39. return pDoc;
  40. }
  41. CDocument *CModDocTemplate::OpenTemplateFile(const mpt::PathString &filename, bool isExampleTune)
  42. {
  43. CDocument *doc = OpenDocumentFile(filename.ToCString(), isExampleTune ? TRUE : FALSE, TRUE);
  44. if(doc)
  45. {
  46. CModDoc *modDoc = static_cast<CModDoc *>(doc);
  47. // Clear path so that saving will not take place in templates/examples folder.
  48. modDoc->ClearFilePath();
  49. if(!isExampleTune)
  50. {
  51. CMultiDocTemplate::SetDefaultTitle(modDoc);
  52. m_nUntitledCount++;
  53. // Name has changed...
  54. CMainFrame::GetMainFrame()->UpdateTree(modDoc, GeneralHint().General());
  55. // Reset edit history for template files
  56. CSoundFile &sndFile = modDoc->GetSoundFile();
  57. sndFile.GetFileHistory().clear();
  58. sndFile.m_dwCreatedWithVersion = Version::Current();
  59. sndFile.m_dwLastSavedWithVersion = Version();
  60. sndFile.m_modFormat = ModFormatDetails();
  61. sndFile.m_songArtist = TrackerSettings::Instance().defaultArtist;
  62. if(sndFile.GetType() != MOD_TYPE_MPT)
  63. {
  64. // Always enforce most compatible playback for legacy module types
  65. sndFile.m_playBehaviour = sndFile.GetDefaultPlaybackBehaviour(sndFile.GetType());
  66. }
  67. doc->UpdateAllViews(nullptr, UpdateHint().ModType().AsLPARAM());
  68. } else
  69. {
  70. // Remove extension from title, so that saving the file will not suggest a filename like e.g. "example.it.it".
  71. const CString title = modDoc->GetTitle();
  72. const int dotPos = title.ReverseFind(_T('.'));
  73. if(dotPos >= 0)
  74. {
  75. modDoc->SetTitle(title.Left(dotPos));
  76. }
  77. }
  78. }
  79. return doc;
  80. }
  81. void CModDocTemplate::AddDocument(CDocument *doc)
  82. {
  83. CMultiDocTemplate::AddDocument(doc);
  84. m_documents.insert(static_cast<CModDoc *>(doc));
  85. }
  86. void CModDocTemplate::RemoveDocument(CDocument *doc)
  87. {
  88. CMultiDocTemplate::RemoveDocument(doc);
  89. m_documents.erase(static_cast<CModDoc *>(doc));
  90. }
  91. bool CModDocTemplate::DocumentExists(const CModDoc *doc) const
  92. {
  93. return m_documents.count(const_cast<CModDoc *>(doc)) != 0;
  94. }
  95. CDocument *CModDocManager::OpenDocumentFile(LPCTSTR lpszFileName, BOOL bAddToMRU)
  96. {
  97. const mpt::PathString filename = (lpszFileName ? mpt::PathString::FromCString(lpszFileName) : mpt::PathString());
  98. if(filename.IsDirectory())
  99. {
  100. FolderScanner scanner(filename, FolderScanner::kOnlyFiles | FolderScanner::kFindInSubDirectories);
  101. mpt::PathString file;
  102. CDocument *pDoc = nullptr;
  103. while(scanner.Next(file))
  104. {
  105. pDoc = OpenDocumentFile(file.ToCString(), bAddToMRU);
  106. }
  107. return pDoc;
  108. }
  109. if(const auto fileExt = filename.GetFileExt(); !mpt::PathString::CompareNoCase(fileExt, P_(".dll")) || !mpt::PathString::CompareNoCase(fileExt, P_(".vst3")))
  110. {
  111. if(auto plugManager = theApp.GetPluginManager(); plugManager != nullptr)
  112. {
  113. if(auto plugLib = plugManager->AddPlugin(filename, TrackerSettings::Instance().BrokenPluginsWorkaroundVSTMaskAllCrashes); plugLib != nullptr)
  114. {
  115. if(!CSelectPluginDlg::VerifyPlugin(plugLib, nullptr))
  116. {
  117. plugManager->RemovePlugin(plugLib);
  118. }
  119. return nullptr;
  120. }
  121. }
  122. }
  123. CDocument *pDoc = CDocManager::OpenDocumentFile(lpszFileName, bAddToMRU);
  124. if(pDoc == nullptr && !filename.empty())
  125. {
  126. if(!filename.IsFile())
  127. {
  128. Reporting::Error(MPT_CFORMAT("Unable to open \"{}\": file does not exist.")(filename.ToCString()));
  129. theApp.RemoveMruItem(filename);
  130. CMainFrame::GetMainFrame()->UpdateMRUList();
  131. } else
  132. {
  133. // Case: Valid path but opening failed.
  134. const int numDocs = theApp.GetOpenDocumentCount();
  135. Reporting::Notification(MPT_CFORMAT("Opening \"{}\" failed. This can happen if "
  136. "no more modules can be opened or if the file type was not "
  137. "recognised (currently there {} {} document{} open).")(
  138. filename.ToCString(), (numDocs == 1) ? CString(_T("is")) : CString(_T("are")), numDocs, (numDocs == 1) ? CString(_T("")) : CString(_T("s"))));
  139. }
  140. }
  141. return pDoc;
  142. }
  143. BOOL CModDocManager::OnDDECommand(LPTSTR lpszCommand)
  144. {
  145. BOOL bResult, bActivate;
  146. #ifdef DDEDEBUG
  147. MPT_LOG_GLOBAL(LogDebug, "DDE", U_("OnDDECommand: ") + mpt::ToUnicode(mpt::winstring(lpszCommand)));
  148. #endif
  149. // Handle any DDE commands recognized by your application
  150. // and return TRUE. See implementation of CWinApp::OnDDEComand
  151. // for example of parsing the DDE command string.
  152. bResult = FALSE;
  153. bActivate = FALSE;
  154. if ((lpszCommand) && lpszCommand[0] && (theApp.m_pMainWnd))
  155. {
  156. std::size_t len = _tcslen(lpszCommand);
  157. std::vector<TCHAR> s(lpszCommand, lpszCommand + len + 1);
  158. len--;
  159. while((len > 0) && _tcschr(_T("(){}[]\'\" "), s[len]))
  160. {
  161. s[len--] = 0;
  162. }
  163. TCHAR *pszCmd = s.data();
  164. while (pszCmd[0] == _T('[')) pszCmd++;
  165. TCHAR *pszData = pszCmd;
  166. while ((pszData[0] != _T('(')) && (pszData[0]))
  167. {
  168. if (((BYTE)pszData[0]) <= (BYTE)' ') *pszData = 0;
  169. pszData++;
  170. }
  171. while ((*pszData) && (_tcschr(_T("(){}[]\'\" "), *pszData)))
  172. {
  173. *pszData = 0;
  174. pszData++;
  175. }
  176. // Edit/Open
  177. if ((!lstrcmpi(pszCmd, _T("Edit")))
  178. || (!lstrcmpi(pszCmd, _T("Open"))))
  179. {
  180. if (pszData[0])
  181. {
  182. bResult = TRUE;
  183. bActivate = TRUE;
  184. OpenDocumentFile(pszData);
  185. }
  186. } else
  187. // New
  188. if (!lstrcmpi(pszCmd, _T("New")))
  189. {
  190. OpenDocumentFile(_T(""));
  191. bResult = TRUE;
  192. bActivate = TRUE;
  193. }
  194. #ifdef DDEDEBUG
  195. MPT_LOG_GLOBAL(LogDebug, "DDE", MPT_UFORMAT("{}({})")(mpt::winstring(pszCmd), mpt::winstring(pszData)));
  196. #endif
  197. if ((bActivate) && (theApp.m_pMainWnd->m_hWnd))
  198. {
  199. if (theApp.m_pMainWnd->IsIconic()) theApp.m_pMainWnd->ShowWindow(SW_RESTORE);
  200. theApp.m_pMainWnd->SetActiveWindow();
  201. }
  202. }
  203. // Return FALSE for any DDE commands you do not handle.
  204. #ifdef DDEDEBUG
  205. if (!bResult)
  206. {
  207. MPT_LOG_GLOBAL(LogDebug, "DDE", U_("WARNING: failure in CModDocManager::OnDDECommand()"));
  208. }
  209. #endif
  210. return bResult;
  211. }
  212. OPENMPT_NAMESPACE_END