aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp
diff options
context:
space:
mode:
authorJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
committerJef <jef@targetspot.com>2024-09-24 08:54:57 -0400
commit20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp
parent537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff)
downloadwinamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp')
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp367
1 files changed, 367 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp
new file mode 100644
index 00000000..c19a64db
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/ExternalSamples.cpp
@@ -0,0 +1,367 @@
+/*
+ * ExternalSamples.cpp
+ * -------------------
+ * Purpose: Dialogs for locating missing external samples and handling modified samples
+ * 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 "Moddoc.h"
+#include "ExternalSamples.h"
+#include "FileDialog.h"
+#include "FolderScanner.h"
+#include "TrackerSettings.h"
+#include "Reporting.h"
+#include "resource.h"
+
+OPENMPT_NAMESPACE_BEGIN
+
+BEGIN_MESSAGE_MAP(MissingExternalSamplesDlg, ResizableDialog)
+ //{{AFX_MSG_MAP(ExternalSamplesDlg)
+ ON_NOTIFY(NM_DBLCLK, IDC_LIST1, &MissingExternalSamplesDlg::OnSetPath)
+ ON_COMMAND(IDC_BUTTON1, &MissingExternalSamplesDlg::OnScanFolder)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+void MissingExternalSamplesDlg::DoDataExchange(CDataExchange *pDX)
+{
+ ResizableDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_List);
+}
+
+
+MissingExternalSamplesDlg::MissingExternalSamplesDlg(CModDoc &modDoc, CWnd *parent)
+ : ResizableDialog(IDD_MISSINGSAMPLES, parent)
+ , m_modDoc(modDoc)
+ , m_sndFile(modDoc.GetSoundFile())
+{
+}
+
+
+BOOL MissingExternalSamplesDlg::OnInitDialog()
+{
+ ResizableDialog::OnInitDialog();
+
+ // Initialize table
+ const CListCtrlEx::Header headers[] =
+ {
+ { _T("Sample"), 128, LVCFMT_LEFT },
+ { _T("External Filename"), 308, LVCFMT_LEFT },
+ };
+ m_List.SetHeaders(headers);
+ m_List.SetExtendedStyle(m_List.GetExtendedStyle() | LVS_EX_FULLROWSELECT);
+
+ GenerateList();
+ SetWindowText((_T("Missing External Samples - ") + m_modDoc.GetPathNameMpt().GetFullFileName().AsNative()).c_str());
+
+ return TRUE;
+}
+
+
+void MissingExternalSamplesDlg::GenerateList()
+{
+ m_List.SetRedraw(FALSE);
+ m_List.DeleteAllItems();
+ CString s;
+ for(SAMPLEINDEX smp = 1; smp <= m_sndFile.GetNumSamples(); smp++)
+ {
+ if(m_sndFile.IsExternalSampleMissing(smp))
+ {
+ s.Format(_T("%02u: "), smp);
+ s += mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.GetSampleName(smp));
+ int insertAt = m_List.InsertItem(m_List.GetItemCount(), s);
+ if(insertAt == -1)
+ continue;
+ m_List.SetItemText(insertAt, 1, m_sndFile.GetSamplePath(smp).AsNative().c_str());
+ m_List.SetItemData(insertAt, smp);
+ }
+ }
+ m_List.SetRedraw(TRUE);
+
+ // Yay, we managed to find all samples!
+ if(!m_List.GetItemCount())
+ OnOK();
+}
+
+
+void MissingExternalSamplesDlg::OnSetPath(NMHDR *, LRESULT *)
+{
+ const int item = m_List.GetSelectionMark();
+ if(item == -1) return;
+ const SAMPLEINDEX smp = static_cast<SAMPLEINDEX>(m_List.GetItemData(item));
+
+ const mpt::PathString path = m_modDoc.GetSoundFile().GetSamplePath(smp);
+ FileDialog dlg = OpenFileDialog()
+ .ExtensionFilter("All Samples|*.wav;*.flac|All files(*.*)|*.*||"); // Only show samples that we actually can save as well.
+ if(TrackerSettings::Instance().previewInFileDialogs)
+ dlg.EnableAudioPreview();
+ if(path.empty())
+ dlg.WorkingDirectory(TrackerSettings::Instance().PathSamples.GetWorkingDir());
+ else
+ dlg.DefaultFilename(path);
+ if(!dlg.Show()) return;
+ TrackerSettings::Instance().PathSamples.SetWorkingDir(dlg.GetWorkingDirectory());
+
+ SetSample(smp, dlg.GetFirstFile());
+ m_modDoc.UpdateAllViews(nullptr, SampleHint(smp).Info().Names().Data());
+ GenerateList();
+}
+
+
+void MissingExternalSamplesDlg::OnScanFolder()
+{
+ if(m_isScanning)
+ {
+ m_isScanning = false;
+ return;
+ }
+
+ BrowseForFolder dlg(TrackerSettings::Instance().PathSamples.GetWorkingDir(), _T("Select a folder to search for missing samples..."));
+ if(dlg.Show())
+ {
+ TrackerSettings::Instance().PathSamples.SetWorkingDir(dlg.GetDirectory());
+
+ FolderScanner scan(dlg.GetDirectory(), FolderScanner::kOnlyFiles | FolderScanner::kFindInSubDirectories);
+ mpt::PathString fileName;
+
+ m_isScanning = true;
+ SetDlgItemText(IDC_BUTTON1, _T("&Cancel"));
+ GetDlgItem(IDOK)->EnableWindow(FALSE);
+ BeginWaitCursor();
+
+ DWORD64 lastTick = Util::GetTickCount64();
+ int foundFiles = 0;
+
+ bool anyMissing = true;
+ while(scan.Next(fileName) && m_isScanning && anyMissing)
+ {
+ anyMissing = false;
+ for(SAMPLEINDEX smp = 1; smp <= m_sndFile.GetNumSamples(); smp++)
+ {
+ if(m_sndFile.IsExternalSampleMissing(smp))
+ {
+ if(!mpt::PathString::CompareNoCase(m_sndFile.GetSamplePath(smp).GetFullFileName(), fileName.GetFullFileName()))
+ {
+ if(SetSample(smp, fileName))
+ {
+ foundFiles++;
+ }
+ } else
+ {
+ anyMissing = true;
+ }
+ }
+ }
+
+ const DWORD64 tick = Util::GetTickCount64();
+ if(tick < lastTick || tick > lastTick + 100)
+ {
+ lastTick = tick;
+ SetDlgItemText(IDC_STATIC1, fileName.AsNative().c_str());
+ MSG msg;
+ while(::PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
+ {
+ ::TranslateMessage(&msg);
+ ::DispatchMessage(&msg);
+ }
+ }
+ }
+ EndWaitCursor();
+ GetDlgItem(IDOK)->EnableWindow(TRUE);
+ SetDlgItemText(IDC_BUTTON1, _T("&Scan Folder..."));
+
+ m_modDoc.UpdateAllViews(nullptr, SampleHint().Info().Data().Names());
+
+ if(foundFiles)
+ {
+ SetDlgItemText(IDC_STATIC1, MPT_CFORMAT("{} sample paths were relocated.")(foundFiles));
+ } else
+ {
+ SetDlgItemText(IDC_STATIC1, _T("No matching sample names found."));
+ }
+ m_isScanning = false;
+ GenerateList();
+ }
+
+}
+
+
+bool MissingExternalSamplesDlg::SetSample(SAMPLEINDEX smp, const mpt::PathString &fileName)
+{
+ m_modDoc.GetSampleUndo().PrepareUndo(smp, sundo_replace, "Replace");
+ const mpt::PathString oldPath = m_sndFile.GetSamplePath(smp);
+ if(!m_sndFile.LoadExternalSample(smp, fileName))
+ {
+ Reporting::Information(_T("Unable to load sample:\n") + fileName.AsNative());
+ m_modDoc.GetSampleUndo().RemoveLastUndoStep(smp);
+ return false;
+ } else
+ {
+ // Maybe we just put the file into its regular place, in which case the module has not really been modified.
+ if(oldPath != fileName)
+ {
+ m_modDoc.SetModified();
+ }
+ return true;
+ }
+}
+
+
+BEGIN_MESSAGE_MAP(ModifiedExternalSamplesDlg, ResizableDialog)
+ //{{AFX_MSG_MAP(ExternalSamplesDlg)
+ ON_COMMAND(IDC_SAVE, &ModifiedExternalSamplesDlg::OnSaveSelected)
+ ON_COMMAND(IDC_CHECK1, &ModifiedExternalSamplesDlg::OnCheckAll)
+ ON_NOTIFY(LVN_ITEMCHANGED, IDC_LIST1, &ModifiedExternalSamplesDlg::OnSelectionChanged)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+void ModifiedExternalSamplesDlg::DoDataExchange(CDataExchange *pDX)
+{
+ ResizableDialog::DoDataExchange(pDX);
+ DDX_Control(pDX, IDC_LIST1, m_List);
+}
+
+
+ModifiedExternalSamplesDlg::ModifiedExternalSamplesDlg(CModDoc &modDoc, CWnd *parent)
+ : ResizableDialog(IDD_MODIFIEDSAMPLES, parent)
+ , m_modDoc(modDoc)
+ , m_sndFile(modDoc.GetSoundFile())
+{
+}
+
+
+BOOL ModifiedExternalSamplesDlg::OnInitDialog()
+{
+ ResizableDialog::OnInitDialog();
+
+ // Initialize table
+ const CListCtrlEx::Header headers[] =
+ {
+ {_T("Sample"), 120, LVCFMT_LEFT},
+ {_T("Status"), 54, LVCFMT_LEFT},
+ {_T("External Filename"), 262, LVCFMT_LEFT},
+ };
+ m_List.SetHeaders(headers);
+ m_List.SetExtendedStyle(m_List.GetExtendedStyle() | LVS_EX_FULLROWSELECT | LVS_EX_CHECKBOXES);
+
+ GenerateList();
+ SetWindowText((_T("Modified External Samples - ") + m_modDoc.GetPathNameMpt().GetFullFileName().AsNative()).c_str());
+
+ return TRUE;
+}
+
+
+void ModifiedExternalSamplesDlg::GenerateList()
+{
+ m_List.SetRedraw(FALSE);
+ m_List.DeleteAllItems();
+ CString s;
+ mpt::winstring status;
+ for(SAMPLEINDEX smp = 1; smp <= m_sndFile.GetNumSamples(); smp++)
+ {
+ if(!m_sndFile.GetSample(smp).uFlags[SMP_KEEPONDISK])
+ continue;
+
+ if(m_sndFile.GetSample(smp).uFlags[SMP_MODIFIED])
+ status = _T("modified");
+ else if(!m_sndFile.GetSamplePath(smp).IsFile())
+ status = _T("missing");
+ else
+ continue;
+
+ s.Format(_T("%02u: "), smp);
+ s += mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.GetSampleName(smp));
+ int insertAt = m_List.InsertItem(m_List.GetItemCount(), s);
+ if(insertAt == -1)
+ continue;
+ m_List.SetItemText(insertAt, 1, status.c_str());
+ m_List.SetItemText(insertAt, 2, m_sndFile.GetSamplePath(smp).AsNative().c_str());
+ m_List.SetCheck(insertAt, TRUE);
+ m_List.SetItemData(insertAt, smp);
+ }
+ m_List.SetRedraw(TRUE);
+
+ CheckDlgButton(IDC_CHECK1, BST_CHECKED);
+ OnSelectionChanged(nullptr, nullptr);
+
+ // Nothing modified?
+ if(!m_List.GetItemCount())
+ OnOK();
+}
+
+
+void ModifiedExternalSamplesDlg::OnCheckAll()
+{
+ const BOOL check = IsDlgButtonChecked(IDC_CHECK1) ? TRUE : FALSE;
+ const int count = m_List.GetItemCount();
+ for(int i = 0; i < count; i++)
+ {
+ m_List.SetCheck(i, check);
+ }
+}
+
+
+void ModifiedExternalSamplesDlg::OnSelectionChanged(NMHDR *, LRESULT *)
+{
+ int numChecked = 0;
+ const int count = m_List.GetItemCount();
+ for(int i = 0; i < count; i++)
+ {
+ if(m_List.GetCheck(i))
+ numChecked++;
+ }
+ const TCHAR *embedText, *saveText;
+ if(numChecked == count)
+ {
+ embedText = _T("&Embed All");
+ saveText = _T("&Save All");
+ } else if(!numChecked)
+ {
+ embedText = _T("&Embed None");
+ saveText = _T("&Save None");
+ } else
+ {
+ embedText = _T("&Embed Selected");
+ saveText = _T("&Save Selected");
+ }
+
+ GetDlgItem(IDOK)->SetWindowText(embedText);
+ GetDlgItem(IDC_SAVE)->SetWindowText(saveText);
+}
+
+
+void ModifiedExternalSamplesDlg::Execute(bool doSave)
+{
+ ScopedLogCapturer log(m_modDoc, _T("Modified Samples"), this);
+
+ bool ok = true;
+ const int count = m_List.GetItemCount();
+ for(int i = 0; i < count; i++)
+ {
+ if(!m_List.GetCheck(i))
+ continue;
+
+ SAMPLEINDEX smp = static_cast<SAMPLEINDEX>(m_List.GetItemData(i));
+ if(doSave)
+ {
+ ok &= m_modDoc.SaveSample(smp);
+ } else
+ {
+ m_sndFile.GetSample(smp).uFlags.reset(SMP_KEEPONDISK);
+ m_modDoc.SetModified();
+ }
+ }
+
+ if(ok)
+ ResizableDialog::OnOK();
+ else
+ ResizableDialog::OnCancel();
+}
+
+
+OPENMPT_NAMESPACE_END