diff options
author | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
---|---|---|
committer | Jef <jef@targetspot.com> | 2024-09-24 08:54:57 -0400 |
commit | 20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (patch) | |
tree | 12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/PatternFindReplaceDlg.cpp | |
parent | 537bcbc86291b32fc04ae4133ce4d7cac8ebe9a7 (diff) | |
download | winamp-20d28e80a5c861a9d5f449ea911ab75b4f37ad0d.tar.gz |
Initial community commit
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/PatternFindReplaceDlg.cpp')
-rw-r--r-- | Src/external_dependencies/openmpt-trunk/mptrack/PatternFindReplaceDlg.cpp | 952 |
1 files changed, 952 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/PatternFindReplaceDlg.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/PatternFindReplaceDlg.cpp new file mode 100644 index 00000000..ff1977c8 --- /dev/null +++ b/Src/external_dependencies/openmpt-trunk/mptrack/PatternFindReplaceDlg.cpp @@ -0,0 +1,952 @@ +/* + * PatternFindReplaceDlg.cpp + * ------------------------- + * Purpose: The find/replace dialog for pattern data. + * Notes : (currently none) + * Authors: Olivier Lapicque + * OpenMPT Devs + * The OpenMPT source code is released under the BSD license. Read LICENSE for more details. + */ + + +#include "stdafx.h" +#include "Mptrack.h" +#include "Mainfrm.h" +#include "View_pat.h" +#include "PatternFindReplace.h" +#include "PatternFindReplaceDlg.h" + + +OPENMPT_NAMESPACE_BEGIN + +// CFindRangeDlg: Find a range of values. + +class CFindRangeDlg : public CDialog +{ +public: + enum DisplayMode + { + kDecimal, + kHex, + kNotes, + }; +protected: + CComboBox m_cbnMin, m_cbnMax; + int m_minVal, m_minDefault; + int m_maxVal, m_maxDefault; + DisplayMode m_displayMode; + +public: + CFindRangeDlg(CWnd *parent, int minVal, int minDefault, int maxVal, int maxDefault, DisplayMode displayMode) : CDialog(IDD_FIND_RANGE, parent) + , m_minVal(minVal) + , m_minDefault(minDefault) + , m_maxVal(maxVal) + , m_maxDefault(maxDefault) + , m_displayMode(displayMode) + { } + + int GetMinVal() const { return m_minVal; } + int GetMaxVal() const { return m_maxVal; } + +protected: + virtual void DoDataExchange(CDataExchange* pDX) + { + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO1, m_cbnMin); + DDX_Control(pDX, IDC_COMBO2, m_cbnMax); + } + + virtual BOOL OnInitDialog() + { + CDialog::OnInitDialog(); + + if(m_displayMode == kNotes) + { + AppendNotesToControl(m_cbnMin, static_cast<ModCommand::NOTE>(m_minVal), static_cast<ModCommand::NOTE>(m_maxVal)); + AppendNotesToControl(m_cbnMax, static_cast<ModCommand::NOTE>(m_minVal), static_cast<ModCommand::NOTE>(m_maxVal)); + } else + { + m_cbnMin.InitStorage(m_minVal - m_maxVal + 1, 4); + m_cbnMax.InitStorage(m_minVal - m_maxVal + 1, 4); + const TCHAR *formatString; + if(m_displayMode == kHex && m_maxVal <= 0x0F) + formatString = _T("%01X"); + else if(m_displayMode == kHex) + formatString = _T("%02X"); + else + formatString = _T("%d"); + for(int i = m_minVal; i <= m_maxVal; i++) + { + TCHAR s[16]; + wsprintf(s, formatString, i); + m_cbnMin.SetItemData(m_cbnMin.AddString(s), i); + m_cbnMax.SetItemData(m_cbnMax.AddString(s), i); + } + } + if(m_minDefault < m_minVal || m_minDefault > m_maxDefault) + { + m_minDefault = m_minVal; + m_maxDefault = m_maxVal; + } + m_cbnMin.SetCurSel(m_minDefault - m_minVal); + m_cbnMax.SetCurSel(m_maxDefault - m_minVal); + + return TRUE; + } + + virtual void OnOK() + { + CDialog::OnOK(); + m_minVal = static_cast<int>(m_cbnMin.GetItemData(m_cbnMin.GetCurSel())); + m_maxVal = static_cast<int>(m_cbnMax.GetItemData(m_cbnMax.GetCurSel())); + if(m_maxVal < m_minVal) + std::swap(m_minVal, m_maxVal); + } +}; + + +BEGIN_MESSAGE_MAP(CFindReplaceTab, CPropertyPage) + ON_CBN_SELCHANGE(IDC_COMBO1, &CFindReplaceTab::OnNoteChanged) + ON_CBN_SELCHANGE(IDC_COMBO2, &CFindReplaceTab::OnInstrChanged) + ON_CBN_SELCHANGE(IDC_COMBO3, &CFindReplaceTab::OnVolCmdChanged) + ON_CBN_SELCHANGE(IDC_COMBO4, &CFindReplaceTab::OnVolumeChanged) + ON_CBN_SELCHANGE(IDC_COMBO5, &CFindReplaceTab::OnEffectChanged) + ON_CBN_SELCHANGE(IDC_COMBO6, &CFindReplaceTab::OnParamChanged) + ON_CBN_SELCHANGE(IDC_COMBO7, &CFindReplaceTab::OnPCParamChanged) + + ON_CBN_EDITCHANGE(IDC_COMBO4, &CFindReplaceTab::OnVolumeChanged) + ON_CBN_EDITCHANGE(IDC_COMBO6, &CFindReplaceTab::OnParamChanged) + + ON_COMMAND(IDC_CHECK1, &CFindReplaceTab::OnCheckNote) + ON_COMMAND(IDC_CHECK2, &CFindReplaceTab::OnCheckInstr) + ON_COMMAND(IDC_CHECK3, &CFindReplaceTab::OnCheckVolCmd) + ON_COMMAND(IDC_CHECK4, &CFindReplaceTab::OnCheckVolume) + ON_COMMAND(IDC_CHECK5, &CFindReplaceTab::OnCheckEffect) + ON_COMMAND(IDC_CHECK6, &CFindReplaceTab::OnCheckParam) + + ON_COMMAND(IDC_CHECK7, &CFindReplaceTab::OnCheckChannelSearch) +END_MESSAGE_MAP() + + +void CFindReplaceTab::DoDataExchange(CDataExchange* pDX) +{ + CDialog::DoDataExchange(pDX); + DDX_Control(pDX, IDC_COMBO1, m_cbnNote); + DDX_Control(pDX, IDC_COMBO2, m_cbnInstr); + DDX_Control(pDX, IDC_COMBO3, m_cbnVolCmd); + DDX_Control(pDX, IDC_COMBO4, m_cbnVolume); + DDX_Control(pDX, IDC_COMBO5, m_cbnCommand); + DDX_Control(pDX, IDC_COMBO6, m_cbnParam); + DDX_Control(pDX, IDC_COMBO7, m_cbnPCParam); +} + + +BOOL CFindReplaceTab::OnInitDialog() +{ + CString s; + + CPropertyPage::OnInitDialog(); + // Search flags + FlagSet<FindReplace::Flags> flags = m_isReplaceTab ? m_settings.replaceFlags : m_settings.findFlags; + + COMBOBOXINFO info; + info.cbSize = sizeof(info); + if(m_cbnVolume.GetComboBoxInfo(&info)) + { + ::SetWindowLong(info.hwndItem, GWL_STYLE, ::GetWindowLong(info.hwndItem, GWL_STYLE) | ES_NUMBER); + ::SendMessage(info.hwndItem, EM_SETLIMITTEXT, 4, 0); + } + if(m_cbnParam.GetComboBoxInfo(&info)) + { + // Might need to enter hex values + //::SetWindowLong(info.hwndItem, GWL_STYLE, ::GetWindowLong(info.hwndItem, GWL_STYLE) | ES_NUMBER); + ::SendMessage(info.hwndItem, EM_SETLIMITTEXT, 4, 0); + } + + CheckDlgButton(IDC_CHECK1, flags[FindReplace::Note] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK2, flags[FindReplace::Instr] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK3, flags[FindReplace::VolCmd | FindReplace::PCParam] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK4, flags[FindReplace::Volume | FindReplace::PCValue] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK5, flags[FindReplace::Command] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK6, flags[FindReplace::Param] ? BST_CHECKED : BST_UNCHECKED); + if(m_isReplaceTab) + { + CheckDlgButton(IDC_CHECK7, flags[FindReplace::Replace] ? BST_CHECKED : BST_UNCHECKED); + CheckDlgButton(IDC_CHECK8, flags[FindReplace::ReplaceAll] ? BST_CHECKED : BST_UNCHECKED); + } else + { + CheckDlgButton(IDC_CHECK7, flags[FindReplace::InChannels] ? BST_CHECKED : BST_UNCHECKED); + int nButton = IDC_RADIO1; + if(flags[FindReplace::FullSearch]) + nButton = IDC_RADIO2; + else if(flags[FindReplace::InPatSelection]) + nButton = IDC_RADIO3; + + CheckRadioButton(IDC_RADIO1, IDC_RADIO3, nButton); + GetDlgItem(IDC_RADIO3)->EnableWindow(flags[FindReplace::InPatSelection] ? TRUE : FALSE); + SetDlgItemInt(IDC_EDIT1, m_settings.findChnMin + 1); + SetDlgItemInt(IDC_EDIT2, m_settings.findChnMax + 1); + static_cast<CSpinButtonCtrl *>(GetDlgItem(IDC_SPIN1))->SetRange32(1, m_sndFile.GetNumChannels()); + static_cast<CSpinButtonCtrl *>(GetDlgItem(IDC_SPIN2))->SetRange32(1, m_sndFile.GetNumChannels()); + + // Pre-fill with selected pattern data + if(!flags[FindReplace::Note] && m_initialValues.note != NOTE_NONE) + { + m_settings.findNoteMin = m_settings.findNoteMax = m_initialValues.note; + } + if(!flags[FindReplace::Instr] && m_initialValues.instr != 0) + { + m_settings.findInstrMin = m_settings.findInstrMax = m_initialValues.instr; + } + if(IsPCEvent()) + { + if(!flags[FindReplace::PCParam] && m_initialValues.GetValueVolCol() != 0) + m_settings.findParamMin = m_settings.findParamMax = m_initialValues.GetValueVolCol(); + if(!flags[FindReplace::PCValue] && m_initialValues.GetValueEffectCol() != 0) + m_settings.findVolumeMin = m_settings.findVolumeMax = m_initialValues.GetValueEffectCol(); + } else + { + if(!flags[FindReplace::VolCmd] && m_initialValues.volcmd != VOLCMD_NONE) + m_settings.findVolCmd = m_initialValues.volcmd; + if(!flags[FindReplace::Volume] && m_initialValues.volcmd != VOLCMD_NONE) + m_settings.findVolumeMin = m_settings.findVolumeMax = m_initialValues.vol; + if(!flags[FindReplace::Command] && m_initialValues.command != CMD_NONE) + m_settings.findCommand = m_initialValues.command; + if(!flags[FindReplace::Param] && m_initialValues.command != CMD_NONE) + m_settings.findParamMin = m_settings.findParamMax = m_initialValues.param; + } + } + + // Note + { + int sel = -1; + m_cbnNote.SetRedraw(FALSE); + m_cbnNote.InitStorage(150, 6); + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("...")), NOTE_NONE); + if (m_isReplaceTab) + { + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("note -1")), kReplaceNoteMinusOne); + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("note +1")), kReplaceNotePlusOne); + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("-1 oct")), kReplaceNoteMinusOctave); + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("+1 oct")), kReplaceNotePlusOctave); + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("Transpose...")), kReplaceRelative); + if(m_settings.replaceNoteAction == FindReplace::ReplaceRelative) + { + switch(m_settings.replaceNote) + { + case -1: sel = 1; break; + case 1: sel = 2; break; + case FindReplace::ReplaceOctaveDown: sel = 3; break; + case FindReplace::ReplaceOctaveUp : sel = 4; break; + default: sel = 5; break; + } + } + } else + { + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("any")), kFindAny); + m_cbnNote.SetItemData(m_cbnNote.AddString(_T("Range...")), kFindRange); + if(m_settings.findNoteMin == NOTE_MIN && m_settings.findNoteMax == NOTE_MAX) + sel = 1; + else if(m_settings.findNoteMin < m_settings.findNoteMax) + sel = 2; + } + AppendNotesToControlEx(m_cbnNote, m_sndFile); + + if(sel == -1) + { + DWORD_PTR searchNote = m_isReplaceTab ? m_settings.replaceNote : m_settings.findNoteMin; + int ncount = m_cbnNote.GetCount(); + for(int i = 0; i < ncount; i++) if(searchNote == m_cbnNote.GetItemData(i)) + { + sel = i; + break; + } + } + m_cbnNote.SetCurSel(sel); + m_cbnNote.SetRedraw(TRUE); + } + + // Volume Command + m_cbnVolCmd.SetRedraw(FALSE); + m_cbnVolCmd.InitStorage(m_effectInfo.GetNumVolCmds(), 15); + m_cbnVolCmd.SetItemData(m_cbnVolCmd.AddString(_T(" None")), (DWORD_PTR)-1); + UINT count = m_effectInfo.GetNumVolCmds(); + for (UINT n=0; n<count; n++) + { + if(m_effectInfo.GetVolCmdInfo(n, &s) && !s.IsEmpty()) + { + m_cbnVolCmd.SetItemData(m_cbnVolCmd.AddString(s), n); + } + } + m_cbnVolCmd.SetCurSel(0); + UINT fxndx = m_effectInfo.GetIndexFromVolCmd(m_isReplaceTab ? m_settings.replaceVolCmd : m_settings.findVolCmd); + for (UINT i=0; i<=count; i++) if (fxndx == m_cbnVolCmd.GetItemData(i)) + { + m_cbnVolCmd.SetCurSel(i); + break; + } + m_cbnVolCmd.SetRedraw(TRUE); + m_cbnVolCmd.ShowWindow(SW_SHOW); + m_cbnPCParam.ShowWindow(SW_HIDE); + + // Command + { + m_cbnCommand.SetRedraw(FALSE); + m_cbnCommand.InitStorage(m_effectInfo.GetNumEffects(), 20); + m_cbnCommand.SetItemData(m_cbnCommand.AddString(_T(" None")), (DWORD_PTR)-1); + count = m_effectInfo.GetNumEffects(); + for (UINT n=0; n<count; n++) + { + if(m_effectInfo.GetEffectInfo(n, &s, true) && !s.IsEmpty()) + { + m_cbnCommand.SetItemData(m_cbnCommand.AddString(s), n); + } + } + m_cbnCommand.SetCurSel(0); + fxndx = m_effectInfo.GetIndexFromEffect(m_isReplaceTab ? m_settings.replaceCommand : m_settings.findCommand, static_cast<ModCommand::PARAM>(m_isReplaceTab ? m_settings.replaceParam : m_settings.findParamMin)); + for (UINT i=0; i<=count; i++) if (fxndx == m_cbnCommand.GetItemData(i)) + { + m_cbnCommand.SetCurSel(i); + break; + } + m_cbnCommand.SetRedraw(TRUE); + } + UpdateInstrumentList(); + UpdateVolumeList(); + UpdateParamList(); + OnCheckChannelSearch(); + return TRUE; +} + + +bool CFindReplaceTab::IsPCEvent() const +{ + if(m_isReplaceTab) + { + if(ModCommand::IsPcNote(static_cast<ModCommand::NOTE>(m_settings.replaceNote))) + return true; + else if(m_settings.replaceFlags[FindReplace::Note]) + return false; + // If we don't replace the note, still show the PC-related settings if we search for PC events. + } + return ModCommand::IsPcNote(m_settings.findNoteMin); +} + + +void CFindReplaceTab::UpdateInstrumentList() +{ + const bool isPCEvent = IsPCEvent(); + if(m_cbnInstr.GetCount() != 0 && !!GetWindowLongPtr(m_cbnInstr.m_hWnd, GWLP_USERDATA) == isPCEvent) + return; + SetWindowLongPtr(m_cbnInstr.m_hWnd, GWLP_USERDATA, isPCEvent); + + int oldSelection = (m_isReplaceTab ? m_settings.replaceInstr : m_settings.findInstrMin); + int sel = (oldSelection == 0) ? 0 : -1; + m_cbnInstr.SetRedraw(FALSE); + m_cbnInstr.ResetContent(); + m_cbnInstr.InitStorage((isPCEvent ? MAX_MIXPLUGINS : MAX_INSTRUMENTS) + 3, 32); + m_cbnInstr.SetItemData(m_cbnInstr.AddString(_T("..")), 0); + if (m_isReplaceTab) + { + m_cbnInstr.SetItemData(m_cbnInstr.AddString(isPCEvent ? _T("Plugin -1") : _T("Instrument -1")), kReplaceInstrumentMinusOne); + m_cbnInstr.SetItemData(m_cbnInstr.AddString(isPCEvent ? _T("Plugin +1") : _T("Instrument +1")), kReplaceInstrumentPlusOne); + m_cbnInstr.SetItemData(m_cbnInstr.AddString(_T("Other...")), kReplaceRelative); + if(m_settings.replaceInstrAction == FindReplace::ReplaceRelative) + { + switch(m_settings.replaceInstr) + { + case -1: sel = 1; break; + case 1: sel = 2; break; + default: sel = 3; break; + } + } + } else + { + m_cbnInstr.SetItemData(m_cbnInstr.AddString(_T("Range...")), kFindRange); + if(m_settings.findInstrMin < m_settings.findInstrMax) + sel = 1; + } + if(sel == -1) + sel = m_cbnInstr.GetCount() + oldSelection - 1; + if(isPCEvent) + { + AddPluginNamesToCombobox(m_cbnInstr, m_sndFile.m_MixPlugins, false); + } else + { + CString s; + for(INSTRUMENTINDEX n = 1; n < MAX_INSTRUMENTS; n++) + { + s.Format(_T("%03d:"), n); + if(m_sndFile.GetNumInstruments()) + s += mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.GetInstrumentName(n)); + else + s += mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.m_szNames[n]); + m_cbnInstr.SetItemData(m_cbnInstr.AddString(s), n); + } + } + m_cbnInstr.SetCurSel(sel); + m_cbnInstr.SetRedraw(TRUE); + m_cbnInstr.Invalidate(FALSE); +} + + +void CFindReplaceTab::UpdateParamList() +{ + const bool isPCEvent = IsPCEvent(); + if(m_cbnInstr.GetCount() == 0 || !!GetWindowLongPtr(m_cbnInstr.m_hWnd, GWLP_USERDATA) != isPCEvent) + { + SetWindowLongPtr(m_cbnInstr.m_hWnd, GWLP_USERDATA, isPCEvent); + } + + int effectIndex = static_cast<int>(m_cbnCommand.GetItemData(m_cbnCommand.GetCurSel())); + ModCommand::PARAM n = 0; // unused parameter adjustment + ModCommand::COMMAND cmd = m_effectInfo.GetEffectFromIndex(effectIndex, n); + const UINT mask = m_effectInfo.GetEffectMaskFromIndex(effectIndex); + if(m_isReplaceTab) + m_settings.replaceCommand = cmd; + else + m_settings.findCommand = cmd; + + // Update Param range + const bool isExtended = m_effectInfo.IsExtendedEffect(effectIndex); + int sel = -1; + int oldcount = m_cbnParam.GetCount(); + int newcount = isExtended ? 16 : 256; + if(oldcount) + oldcount -= m_isReplaceTab ? 2 : 1; + + auto findParam = m_isReplaceTab ? m_settings.replaceParam : m_settings.findParamMin; + if(isExtended) + { + findParam &= 0x0F; + if(!m_isReplaceTab && !IsDlgButtonChecked(IDC_CHECK6)) + { + m_settings.findParamMin = (m_settings.findParamMin & 0x0F) | mask; + m_settings.findParamMax = (m_settings.findParamMax & 0x0F) | mask; + } else if(m_isReplaceTab) + { + m_settings.replaceParam |= mask; + } + } + + if(oldcount != newcount) + { + TCHAR s[16]; + int newpos; + if(oldcount && m_cbnParam.GetCurSel() != CB_ERR) + newpos = static_cast<int>(m_cbnParam.GetItemData(m_cbnParam.GetCurSel())); + else + newpos = findParam; + Limit(newpos, 0, newcount - 1); + m_cbnParam.SetRedraw(FALSE); + m_cbnParam.ResetContent(); + m_cbnParam.InitStorage(newcount + 2, 4); + + if(m_isReplaceTab) + { + wsprintf(s, _T("+ %d"), m_settings.replaceParam); + m_cbnParam.SetItemData(m_cbnParam.AddString(s), kReplaceRelative); + wsprintf(s, _T("* %d%%"), m_settings.replaceParam); + m_cbnParam.SetItemData(m_cbnParam.AddString(s), kReplaceMultiply); + if(m_settings.replaceParamAction == FindReplace::ReplaceRelative) + sel = 0; + else if(m_settings.replaceParamAction == FindReplace::ReplaceMultiply) + sel = 1; + + m_settings.replaceParam = newpos; + if(isExtended) + { + m_settings.replaceParam = (m_settings.replaceParam & 0x0F) | mask; + } + } else + { + m_cbnParam.SetItemData(m_cbnParam.AddString(_T("Range")), kFindRange); + if(m_settings.findParamMin < m_settings.findParamMax) + sel = 0; + } + + if(sel == -1) + sel = m_cbnParam.GetCount() + newpos; + for(int param = 0; param < newcount; param++) + { + wsprintf(s, (newcount == 256) ? _T("%02X") : _T("%X"), param); + int i = m_cbnParam.AddString(s); + m_cbnParam.SetItemData(i, param); + } + m_cbnParam.SetCurSel(sel); + m_cbnParam.SetRedraw(TRUE); + m_cbnParam.Invalidate(FALSE); + } +} + + +void CFindReplaceTab::UpdateVolumeList() +{ + TCHAR s[256]; + const bool isPCEvent = IsPCEvent(); + + BOOL enable = isPCEvent ? FALSE : TRUE; + GetDlgItem(IDC_CHECK5)->EnableWindow(enable); + GetDlgItem(IDC_CHECK6)->EnableWindow(enable); + m_cbnCommand.EnableWindow(enable); + m_cbnParam.EnableWindow(enable); + + // Update plugin parameter list + int plug = static_cast<int>(m_cbnInstr.GetItemData(m_cbnInstr.GetCurSel())); + if(isPCEvent && (m_cbnPCParam.GetCount() == 0 || GetWindowLongPtr(m_cbnPCParam.m_hWnd, GWLP_USERDATA) != plug)) + { + SetWindowLongPtr(m_cbnPCParam.m_hWnd, GWLP_USERDATA, plug); + + CheckDlgButton(IDC_CHECK5, BST_UNCHECKED); + CheckDlgButton(IDC_CHECK6, BST_UNCHECKED); + + int sel = m_isReplaceTab ? m_settings.replaceParam : m_settings.findParamMin; + plug--; + m_cbnPCParam.SetRedraw(FALSE); + m_cbnPCParam.ResetContent(); + if(plug >= 0 && plug < MAX_MIXPLUGINS && m_sndFile.m_MixPlugins[plug].pMixPlugin != nullptr) + { + AddPluginParameternamesToCombobox(m_cbnPCParam, *m_sndFile.m_MixPlugins[plug].pMixPlugin); + } else + { + m_cbnPCParam.InitStorage(ModCommand::maxColumnValue, 20); + for(int i = 0; i < ModCommand::maxColumnValue; i++) + { + wsprintf(s, _T("%02u: Parameter %02u"), static_cast<unsigned int>(i), static_cast<unsigned int>(i)); + m_cbnPCParam.SetItemData(m_cbnPCParam.AddString(s), i); + } + } + m_cbnPCParam.SetCurSel(sel); + m_cbnPCParam.SetRedraw(TRUE); + m_cbnPCParam.Invalidate(FALSE); + } + + m_cbnVolCmd.ShowWindow(isPCEvent ? SW_HIDE : SW_SHOW); + m_cbnPCParam.ShowWindow(isPCEvent ? SW_SHOW : SW_HIDE); + + int rangeMin, rangeMax, curVal; + + if(isPCEvent) + { + rangeMin = 0; + rangeMax = ModCommand::maxColumnValue; + curVal = (m_isReplaceTab ? m_settings.replaceVolume : m_settings.findVolumeMin); + } else + { + int effectIndex = static_cast<int>(m_cbnVolCmd.GetItemData(m_cbnVolCmd.GetCurSel())); + ModCommand::VOLCMD cmd = m_effectInfo.GetVolCmdFromIndex(effectIndex); + if(m_isReplaceTab) + m_settings.replaceVolCmd = cmd; + else + m_settings.findVolCmd = cmd; + + // Update Param range + ModCommand::VOL volMin, volMax; + if(!m_effectInfo.GetVolCmdInfo(effectIndex, nullptr, &volMin, &volMax)) + { + volMin = 0; + volMax = 64; + } + rangeMin = volMin; + rangeMax = volMax; + curVal = (m_isReplaceTab ? m_settings.replaceVolume : m_settings.findVolumeMin); + } + + int oldcount = m_cbnVolume.GetCount(); + int newcount = rangeMax - rangeMin + 1; + if (oldcount != newcount) + { + int sel = -1; + int newpos; + if (oldcount) + newpos = static_cast<int>(m_cbnVolume.GetItemData(m_cbnVolume.GetCurSel())); + else + newpos = curVal; + Limit(newpos, 0, newcount - 1); + m_cbnVolume.SetRedraw(FALSE); + m_cbnVolume.ResetContent(); + m_cbnVolume.InitStorage(newcount + 2, 4); + if(m_isReplaceTab) + { + wsprintf(s, _T("+ %d"), m_settings.replaceVolume); + m_cbnVolume.SetItemData(m_cbnVolume.AddString(s), kReplaceRelative); + wsprintf(s, _T("* %d%%"), m_settings.replaceVolume); + m_cbnVolume.SetItemData(m_cbnVolume.AddString(s), kReplaceMultiply); + if(m_settings.replaceVolumeAction == FindReplace::ReplaceRelative) + sel = 0; + else if(m_settings.replaceVolumeAction == FindReplace::ReplaceMultiply) + sel = 1; + } else + { + m_cbnVolume.SetItemData(m_cbnVolume.AddString(_T("Range...")), kFindRange); + if(m_settings.findVolumeMin < m_settings.findVolumeMax) + sel = 0; + } + + if(sel == -1) + sel = m_cbnVolume.GetCount() + newpos - rangeMin; + for (int vol = rangeMin; vol <= rangeMax; vol++) + { + wsprintf(s, (rangeMax < 10 || rangeMax > 99) ? _T("%d") : _T("%02d"), vol); + int i = m_cbnVolume.AddString(s); + m_cbnVolume.SetItemData(i, vol); + } + m_cbnVolume.SetCurSel(sel); + m_cbnVolume.SetRedraw(TRUE); + m_cbnVolume.Invalidate(FALSE); + } +} + + +void CFindReplaceTab::OnNoteChanged() +{ + CheckOnChange(IDC_CHECK1); + int item = static_cast<int>(m_cbnNote.GetItemData(m_cbnNote.GetCurSel())); + if(m_isReplaceTab) + { + m_settings.replaceNoteAction = FindReplace::ReplaceRelative; + switch(item) + { + case kReplaceNoteMinusOne: m_settings.replaceNote = -1; break; + case kReplaceNotePlusOne: m_settings.replaceNote = 1; break; + case kReplaceNoteMinusOctave: m_settings.replaceNote = FindReplace::ReplaceOctaveDown; break; + case kReplaceNotePlusOctave: m_settings.replaceNote = FindReplace::ReplaceOctaveUp; break; + + case kReplaceRelative: + { + CInputDlg dlg(this, _T("Custom Transpose Amount:"), -120, 120, m_settings.replaceNote); + if(dlg.DoModal() == IDOK) + { + m_settings.replaceNote = dlg.resultAsInt; + } else + { + // TODO undo selection + } + } + break; + + default: + m_settings.replaceNote = item; + m_settings.replaceNoteAction = FindReplace::ReplaceValue; + } + } else + { + if(item == kFindRange) + { + CFindRangeDlg dlg(this, NOTE_MIN, m_settings.findNoteMin, NOTE_MAX, m_settings.findNoteMax, CFindRangeDlg::kNotes); + if(dlg.DoModal() == IDOK) + { + m_settings.findNoteMin = static_cast<ModCommand::NOTE>(dlg.GetMinVal()); + m_settings.findNoteMax = static_cast<ModCommand::NOTE>(dlg.GetMaxVal()); + } + } else if(item == kFindAny) + { + m_settings.findNoteMin = NOTE_MIN; + m_settings.findNoteMax = NOTE_MAX; + } else + { + m_settings.findNoteMin = m_settings.findNoteMax = static_cast<ModCommand::NOTE>(item); + } + } + UpdateInstrumentList(); + UpdateVolumeList(); +} + + +void CFindReplaceTab::OnInstrChanged() +{ + CheckOnChange(IDC_CHECK2); + int item = static_cast<int>(m_cbnInstr.GetItemData(m_cbnInstr.GetCurSel())); + if(m_isReplaceTab) + { + m_settings.replaceInstrAction = FindReplace::ReplaceRelative; + switch(item) + { + case kReplaceInstrumentMinusOne: m_settings.replaceInstr = -1; break; + case kReplaceInstrumentPlusOne: m_settings.replaceInstr = 1; break; + + case kReplaceRelative: + { + CInputDlg dlg(this, _T("Custom Replacement Amount:"), -255, 255, m_settings.replaceInstr); + if(dlg.DoModal() == IDOK) + { + m_settings.replaceInstrAction = FindReplace::ReplaceRelative; + m_settings.replaceInstr = dlg.resultAsInt; + } else + { + // TODO undo selection + } + } + break; + + default: + m_settings.replaceInstrAction = FindReplace::ReplaceValue; + m_settings.replaceInstr = item; + break; + } + } else + { + if(item == kFindRange) + { + CFindRangeDlg dlg(this, 1, m_settings.findInstrMin, MAX_INSTRUMENTS - 1, m_settings.findInstrMax, CFindRangeDlg::kDecimal); + if(dlg.DoModal() == IDOK) + { + m_settings.findInstrMin = static_cast<ModCommand::INSTR>(dlg.GetMinVal()); + m_settings.findInstrMax = static_cast<ModCommand::INSTR>(dlg.GetMaxVal()); + } + } else + { + m_settings.findInstrMin = m_settings.findInstrMax = static_cast<ModCommand::INSTR>(item); + } + } + if(IsPCEvent()) + UpdateVolumeList(); +} + + +void CFindReplaceTab::RelativeOrMultiplyPrompt(CComboBox &comboBox, FindReplace::ReplaceMode &action, int &value, int range, bool isHex) +{ + int sel = comboBox.GetCurSel(); + int item = static_cast<int>(comboBox.GetItemData(sel)); + + if(sel == CB_ERR) + { + item = 0; + CString s; + comboBox.GetWindowText(s); + s.TrimLeft(); + if(s.GetLength() >= 1) + { + TCHAR first = s[0]; + if(first == _T('+')) + { + item = kReplaceRelative; + sel = 0; + } else if(first == _T('*')) + { + item = kReplaceMultiply; + sel = 1; + } + } + if(!item) + { + if(isHex) + { + int len = ::GetWindowTextLengthA(m_cbnParam); + std::string sHex(len, 0); + ::GetWindowTextA(m_cbnParam, &sHex[0], len + 1); + item = mpt::String::Parse::HexToUnsignedInt(sHex); + } else + { + item = ConvertStrTo<int>(s); + } + } + } + + if(item == kReplaceRelative || item == kReplaceMultiply) + { + const TCHAR *prompt, *format; + FindReplace::ReplaceMode act; + if(item == kReplaceRelative) + { + act = FindReplace::ReplaceRelative; + prompt = _T("Amount to add or subtract:"); + format = _T("+ %d"); + } else + { + act = FindReplace::ReplaceMultiply; + prompt = _T("Multiply by percentage:"); + format = _T("* %d%%"); + } + + range *= 100; + CInputDlg dlg(this, prompt, -range, range, value); + if(dlg.DoModal() == IDOK) + { + value = dlg.resultAsInt; + action = act; + + TCHAR s[32]; + wsprintf(s, format, value); + comboBox.DeleteString(sel); + comboBox.InsertString(sel, s); + comboBox.SetItemData(sel, item); + comboBox.SetCurSel(sel); + } else + { + // TODO undo selection + } + } else + { + action = FindReplace::ReplaceValue; + value = item; + } +} + + +void CFindReplaceTab::OnVolumeChanged() +{ + CheckOnChange(IDC_CHECK4); + int item = m_cbnVolume.GetCurSel(); + if(item != CB_ERR) + item = static_cast<int>(m_cbnVolume.GetItemData(item)); + else + item = GetDlgItemInt(IDC_COMBO4); + + int rangeMax = IsPCEvent() ? ModCommand::maxColumnValue : 64; + if(m_isReplaceTab) + { + RelativeOrMultiplyPrompt(m_cbnVolume, m_settings.replaceVolumeAction, m_settings.replaceVolume, rangeMax, false); + } else + { + if(item == kFindRange) + { + CFindRangeDlg dlg(this, 0, m_settings.findVolumeMin, rangeMax, m_settings.findVolumeMax, CFindRangeDlg::kDecimal); + if(dlg.DoModal() == IDOK) + { + m_settings.findVolumeMin = dlg.GetMinVal(); + m_settings.findVolumeMax = dlg.GetMaxVal(); + } else + { + // TODO undo selection + } + } else + { + m_settings.findVolumeMin = m_settings.findVolumeMax = item; + } + } +} + + +void CFindReplaceTab::OnParamChanged() +{ + CheckOnChange(IDC_CHECK6); + int item = m_cbnParam.GetCurSel(); + if(item != CB_ERR) + { + item = static_cast<int>(m_cbnParam.GetItemData(item)); + } else + { + int len = ::GetWindowTextLengthA(m_cbnParam); + std::string s(len, 0); + ::GetWindowTextA(m_cbnParam, &s[0], len + 1); + item = mpt::String::Parse::HexToUnsignedInt(s); + } + + // Apply parameter value mask if required (e.g. SDx has mask D0). + int effectIndex = static_cast<int>(m_cbnCommand.GetItemData(m_cbnCommand.GetCurSel())); + UINT mask = (effectIndex > -1) ? m_effectInfo.GetEffectMaskFromIndex(effectIndex) : 0; + + if(m_isReplaceTab) + { + RelativeOrMultiplyPrompt(m_cbnParam, m_settings.replaceParamAction, m_settings.replaceParam, 256, true); + if(m_settings.replaceParamAction == FindReplace::ReplaceValue && effectIndex > -1) + { + m_settings.replaceParam |= mask; + } + } else + { + if(item == kFindRange) + { + CFindRangeDlg dlg(this, 0, m_settings.findParamMin & ~mask, m_cbnParam.GetCount() - 2, m_settings.findParamMax & ~mask, CFindRangeDlg::kHex); + if(dlg.DoModal() == IDOK) + { + m_settings.findParamMin = dlg.GetMinVal() | mask; + m_settings.findParamMax = dlg.GetMaxVal() | mask; + } else + { + // TODO undo selection + } + } else + { + m_settings.findParamMin = m_settings.findParamMax = (item | mask); + } + } +} + + +void CFindReplaceTab::OnPCParamChanged() +{ + CheckOnChange(IDC_CHECK3); + int item = static_cast<int>(m_cbnPCParam.GetItemData(m_cbnPCParam.GetCurSel())); + + if(m_isReplaceTab) + { + RelativeOrMultiplyPrompt(m_cbnPCParam, m_settings.replaceParamAction, m_settings.replaceParam, 256, false); + } else + { + if(item == kFindRange) + { + CFindRangeDlg dlg(this, 0, m_settings.findParamMin, ModCommand::maxColumnValue, m_settings.findParamMax, CFindRangeDlg::kDecimal); + if(dlg.DoModal() == IDOK) + { + m_settings.findParamMin = dlg.GetMinVal(); + m_settings.findParamMax = dlg.GetMaxVal(); + } else + { + // TODO undo selection + } + } else + { + m_settings.findParamMin = m_settings.findParamMax = item; + } + } +} + + +void CFindReplaceTab::OnCheckChannelSearch() +{ + if (!m_isReplaceTab) + { + BOOL b = IsDlgButtonChecked(IDC_CHECK7); + GetDlgItem(IDC_EDIT1)->EnableWindow(b); + GetDlgItem(IDC_SPIN1)->EnableWindow(b); + GetDlgItem(IDC_EDIT2)->EnableWindow(b); + GetDlgItem(IDC_SPIN2)->EnableWindow(b); + } +} + + +void CFindReplaceTab::OnOK() +{ + // Search flags + FlagSet<FindReplace::Flags> &flags = m_isReplaceTab ? m_settings.replaceFlags : m_settings.findFlags; + flags.reset(); + flags.set(FindReplace::Note, !!IsDlgButtonChecked(IDC_CHECK1)); + flags.set(FindReplace::Instr, !!IsDlgButtonChecked(IDC_CHECK2)); + if(IsPCEvent()) + { + flags.set(FindReplace::PCParam, !!IsDlgButtonChecked(IDC_CHECK3)); + flags.set(FindReplace::PCValue, !!IsDlgButtonChecked(IDC_CHECK4)); + } else + { + flags.set(FindReplace::VolCmd, !!IsDlgButtonChecked(IDC_CHECK3)); + flags.set(FindReplace::Volume, !!IsDlgButtonChecked(IDC_CHECK4)); + flags.set(FindReplace::Command, !!IsDlgButtonChecked(IDC_CHECK5)); + flags.set(FindReplace::Param, !!IsDlgButtonChecked(IDC_CHECK6)); + } + if(m_isReplaceTab) + { + flags.set(FindReplace::Replace, !!IsDlgButtonChecked(IDC_CHECK7)); + flags.set(FindReplace::ReplaceAll, !!IsDlgButtonChecked(IDC_CHECK8)); + } else + { + flags.set(FindReplace::InChannels, !!IsDlgButtonChecked(IDC_CHECK7)); + flags.set(FindReplace::FullSearch, !!IsDlgButtonChecked(IDC_RADIO2)); + flags.set(FindReplace::InPatSelection, !!IsDlgButtonChecked(IDC_RADIO3)); + } + + // Min/Max channels + if (!m_isReplaceTab) + { + m_settings.findChnMin = static_cast<CHANNELINDEX>(GetDlgItemInt(IDC_EDIT1) - 1); + m_settings.findChnMax = static_cast<CHANNELINDEX>(GetDlgItemInt(IDC_EDIT2) - 1); + if (m_settings.findChnMax < m_settings.findChnMin) + { + std::swap(m_settings.findChnMin, m_settings.findChnMax); + } + } + CPropertyPage::OnOK(); +} + +OPENMPT_NAMESPACE_END |