375 lines
9.2 KiB
C++
375 lines
9.2 KiB
C++
/*
|
|
** Command & Conquer Renegade(tm)
|
|
** Copyright 2025 Electronic Arts Inc.
|
|
**
|
|
** This program is free software: you can redistribute it and/or modify
|
|
** it under the terms of the GNU General Public License as published by
|
|
** the Free Software Foundation, either version 3 of the License, or
|
|
** (at your option) any later version.
|
|
**
|
|
** This program is distributed in the hope that it will be useful,
|
|
** but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
** GNU General Public License for more details.
|
|
**
|
|
** You should have received a copy of the GNU General Public License
|
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
// EditStringDialog.cpp : implementation file
|
|
//
|
|
|
|
#include "stdafx.h"
|
|
#include "leveledit.h"
|
|
#include "editstringdialog.h"
|
|
#include "translateobj.h"
|
|
#include "definitionclassids.h"
|
|
#include "presetmgr.h"
|
|
#include "preset.h"
|
|
|
|
|
|
#ifdef _DEBUG
|
|
#define new DEBUG_NEW
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// Local prototypes
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
bool Is_Valid_ID_Char (char ch);
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// EditStringDialogClass
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
EditStringDialogClass::EditStringDialogClass(CWnd* pParent /*=NULL*/)
|
|
: m_Object (NULL),
|
|
CDialog(EditStringDialogClass::IDD, pParent)
|
|
{
|
|
//{{AFX_DATA_INIT(EditStringDialogClass)
|
|
// NOTE: the ClassWizard will add member initialization here
|
|
//}}AFX_DATA_INIT
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// DoDataExchange
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
EditStringDialogClass::DoDataExchange (CDataExchange* pDX)
|
|
{
|
|
CDialog::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(EditStringDialogClass)
|
|
// NOTE: the ClassWizard will add DDX and DDV calls here
|
|
//}}AFX_DATA_MAP
|
|
return ;
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(EditStringDialogClass, CDialog)
|
|
//{{AFX_MSG_MAP(EditStringDialogClass)
|
|
//}}AFX_MSG_MAP
|
|
END_MESSAGE_MAP()
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnInitDialog
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
BOOL
|
|
EditStringDialogClass::OnInitDialog (void)
|
|
{
|
|
CDialog::OnInitDialog ();
|
|
|
|
//
|
|
// Get information about the location where we want to create the
|
|
// sound preset picker control
|
|
//
|
|
HWND placeholder_wnd = ::GetDlgItem (m_hWnd, IDC_SOUND_PRESET_EDIT);
|
|
CRect rect;
|
|
::GetWindowRect (placeholder_wnd, &rect);
|
|
ScreenToClient (&rect);
|
|
::DestroyWindow (placeholder_wnd);
|
|
|
|
//
|
|
// Create the preset picker control
|
|
//
|
|
m_PresetPicker.Create_Picker (WS_CHILD | WS_TABSTOP | WS_VISIBLE, rect, this, 101);
|
|
m_PresetPicker.Set_Read_Only (true);
|
|
|
|
//
|
|
// Configure the preset picker control
|
|
//
|
|
m_PresetPicker.Set_Class_ID (CLASSID_SOUND);
|
|
if (m_Object != NULL && m_Object->Get_Sound_ID () > 0) {
|
|
PresetClass *preset = PresetMgrClass::Find_Preset (m_Object->Get_Sound_ID ());
|
|
m_PresetPicker.Set_Preset (preset);
|
|
}
|
|
|
|
//
|
|
// Fill in the text controls
|
|
//
|
|
if (m_Object != NULL) {
|
|
CString text = m_Object->Get_English_String ();
|
|
Convert_Newline_To_Chars (text);
|
|
|
|
SetDlgItemText (IDC_CODEID_EDIT, m_Object->Get_ID_Desc ());
|
|
SetDlgItemText (IDC_STRING_EDIT, text);
|
|
SetDlgItemText (IDC_ANIMATION_NAME_EDIT, m_Object->Get_Animation_Name ());
|
|
|
|
//
|
|
// Select the string so the user can readily modify its contents
|
|
//
|
|
::SetFocus (::GetDlgItem (m_hWnd, IDC_STRING_EDIT));
|
|
SendDlgItemMessage (IDC_STRING_EDIT, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
|
|
|
|
} else {
|
|
SetDlgItemText (IDC_CODEID_EDIT, "IDS_");
|
|
|
|
//
|
|
// Select the CODE ID so the user can enter a valid ID
|
|
//
|
|
::SetFocus (::GetDlgItem (m_hWnd, IDC_CODEID_EDIT));
|
|
SendDlgItemMessage (IDC_CODEID_EDIT, EM_SETSEL, (WPARAM)0, (LPARAM)-1);
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Convert_Newline_To_Chars
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
EditStringDialogClass::Convert_Newline_To_Chars (CString &string)
|
|
{
|
|
CString retval;
|
|
|
|
//
|
|
// Take a guess as to how large to make the final string
|
|
//
|
|
int count = string.GetLength ();
|
|
|
|
//
|
|
// Copy characters between the strings
|
|
//
|
|
for (int index = 0; index < count; index ++) {
|
|
|
|
if (string[index] == '\n') {
|
|
retval += "\\n";
|
|
} else if (string[index] == '\t') {
|
|
retval += "\\t";
|
|
} else {
|
|
retval += string[index];
|
|
}
|
|
}
|
|
|
|
string = retval;
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Convert_Chars_To_Newline
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
EditStringDialogClass::Convert_Chars_To_Newline (CString &string)
|
|
{
|
|
CString retval;
|
|
|
|
//
|
|
// Take a guess as to how large to make the final string
|
|
//
|
|
int count = string.GetLength ();
|
|
//retval.GetBufferSetLength (count);
|
|
|
|
//
|
|
// Copy characters between the strings
|
|
//
|
|
for (int index = 0; index < count; index ++) {
|
|
|
|
if (index + 1 < count && string[index] == '\\' && string[index + 1] == 'n') {
|
|
retval += '\n';
|
|
index ++;
|
|
} else if (index + 1 < count && string[index] == '\\' && string[index + 1] == 't') {
|
|
retval += '\t';
|
|
index ++;
|
|
} else {
|
|
retval += string[index];
|
|
}
|
|
}
|
|
|
|
string = retval;
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// OnOK
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
void
|
|
EditStringDialogClass::OnOK (void)
|
|
{
|
|
if (Validate_ID ()) {
|
|
|
|
//
|
|
// Create a new translation object (if necessary)
|
|
//
|
|
if (m_Object == NULL) {
|
|
m_Object = new TDBObjClass;
|
|
}
|
|
|
|
//
|
|
// Read the strings the user entered
|
|
//
|
|
CString code_id;
|
|
GetDlgItemText (IDC_CODEID_EDIT, code_id);
|
|
|
|
CString text;
|
|
GetDlgItemText (IDC_STRING_EDIT, text);
|
|
Convert_Chars_To_Newline (text);
|
|
|
|
CString anim_name;
|
|
GetDlgItemText (IDC_ANIMATION_NAME_EDIT, anim_name);
|
|
|
|
//
|
|
// Pass the new strings onto the translation object
|
|
//
|
|
m_Object->Set_ID_Desc (code_id);
|
|
m_Object->Set_English_String (text);
|
|
m_Object->Set_Animation_Name (anim_name);
|
|
|
|
//
|
|
// Pass the sound preset ID onto the translation object
|
|
//
|
|
int sound_id = -1;
|
|
PresetClass *sound_preset = m_PresetPicker.Get_Preset ();
|
|
if (sound_preset != NULL) {
|
|
sound_id = sound_preset->Get_ID ();
|
|
}
|
|
m_Object->Set_Sound_ID (sound_id);
|
|
|
|
CDialog::OnOK ();
|
|
}
|
|
return ;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Validate_ID
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
bool
|
|
EditStringDialogClass::Validate_ID (void)
|
|
{
|
|
bool retval = false;
|
|
|
|
//
|
|
// Get the string ID from the control
|
|
//
|
|
CString code_id;
|
|
GetDlgItemText (IDC_CODEID_EDIT, code_id);
|
|
|
|
//
|
|
// Validate the ID
|
|
//
|
|
return Validate_String_ID (m_hWnd, code_id);
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Validate_String_ID
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
bool
|
|
Validate_String_ID (HWND wnd, const char *string_id)
|
|
{
|
|
bool retval = false;
|
|
CString code_id = string_id;
|
|
|
|
if (code_id.GetLength () == 0) {
|
|
|
|
//
|
|
// Warn the user they need to enter some ID
|
|
//
|
|
::MessageBox (wnd, "Please enter a descriptive token for the code identifier.", "Invalid Code ID", MB_ICONERROR | MB_OK);
|
|
|
|
} else if (code_id.GetLength () < 4) {
|
|
|
|
//
|
|
// Warn the user they should enter a descriptive name
|
|
//
|
|
::MessageBox (wnd, "Code identifier is too short. Please enter a more descriptive token for the code identifier.", "Invalid Code ID", MB_ICONERROR | MB_OK);
|
|
|
|
} else if (code_id[0] < 0x41 || code_id[0] > 0x7A || (code_id[0] >= 0x5B && code_id[0] <= 0x60)) {
|
|
|
|
//
|
|
// Warn the user the name must start with a character
|
|
//
|
|
::MessageBox (wnd, "The code identifier must begin with a character (not a number), please enter a valid identifier.", "Invalid Code ID", MB_ICONERROR | MB_OK);
|
|
|
|
} else {
|
|
|
|
//
|
|
// Check each character in the string to make sure its exceptable
|
|
//
|
|
int count = code_id.GetLength ();
|
|
bool is_valid = true;
|
|
for (int index = 1; is_valid && index < count; index ++) {
|
|
is_valid &= Is_Valid_ID_Char (code_id[index]);
|
|
}
|
|
|
|
if (is_valid == false) {
|
|
|
|
//
|
|
// Warn the user that the code ID contains an illegal character
|
|
//
|
|
::MessageBox (wnd, "The code identifier can only contain characters (a-z, A-Z), numbers (0-9), and the underscore character (_), please enter a valid identifier.", "Invalid Code ID", MB_ICONERROR | MB_OK);
|
|
|
|
} else {
|
|
retval = true;
|
|
}
|
|
}
|
|
|
|
|
|
return retval;
|
|
}
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
//
|
|
// Is_Valid_ID_Char
|
|
//
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
bool
|
|
Is_Valid_ID_Char (char ch)
|
|
{
|
|
bool is_valid = false;
|
|
|
|
//
|
|
// The character if valid if its either a character, a number, or an underscore
|
|
//
|
|
is_valid |= (ch >= '0' && ch <= '9');
|
|
is_valid |= (ch >= 'A' && ch <= 'Z');
|
|
is_valid |= (ch >= 'a' && ch <= 'z');
|
|
is_valid |= (ch == '_');
|
|
|
|
return is_valid;
|
|
}
|
|
|