FS2_Open
Open source remastering of the Freespace 2 engine
modifyvariabledlg.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (C) Volition, Inc. 1999. All rights reserved.
3  *
4  * All source code herein is the property of Volition, Inc. You may not sell
5  * or otherwise commercially exploit the source or things you created based on the
6  * source.
7  *
8 */
9 
10 // ModifyVariableDlg.cpp : implementation file
11 //
12 
13 #include "stdafx.h"
14 #include "FRED.h"
15 #include "ModifyVariableDlg.h"
16 #include "parse/sexp.h"
17 
18 #ifdef _DEBUG
19 #undef THIS_FILE
20 static char THIS_FILE[] = __FILE__;
21 #endif
22 
23 #define NO_RESET_FOCUS 0
24 #define RESET_FOCUS 1
25 
26 
28 // CModifyVariableDlg dialog
29 
31  : CDialog(CModifyVariableDlg::IDD, pParent)
32 {
33  //{{AFX_DATA_INIT(CModifyVariableDlg)
34  m_default_value = _T("");
35  m_cur_variable_name = _T("");
36  //}}AFX_DATA_INIT
37 }
38 
39 
40 void CModifyVariableDlg::DoDataExchange(CDataExchange* pDX)
41 {
42  CDialog::DoDataExchange(pDX);
43  //{{AFX_DATA_MAP(CModifyVariableDlg)
45  DDV_MaxChars(pDX, m_default_value, 31);
47  DDV_MaxChars(pDX, m_cur_variable_name, 31);
48  //}}AFX_DATA_MAP
49 }
50 
51 
52 BEGIN_MESSAGE_MAP(CModifyVariableDlg, CDialog)
53  //{{AFX_MSG_MAP(CModifyVariableDlg)
54  ON_BN_CLICKED(ID_DELETE_VARIABLE, OnDeleteVariable)
55  ON_BN_CLICKED(IDC_TYPE_STRING, OnTypeString)
56  ON_BN_CLICKED(IDC_TYPE_NUMBER, OnTypeNumber)
57  ON_BN_CLICKED(IDC_TYPE_PLAYER_PERSISTENT, OnTypePlayerPersistent)
58  ON_BN_CLICKED(IDC_TYPE_CAMPAIGN_PERSISTENT, OnTypeCampaignPersistent)
59  ON_BN_CLICKED(IDC_TYPE_NETWORK_VARIABLE, OnTypeNetworkVariable)
60  ON_CBN_SELCHANGE(IDC_MODIFY_VARIABLE_NAME, OnSelchangeModifyVariableName)
61  ON_CBN_EDITCHANGE(IDC_MODIFY_VARIABLE_NAME, OnEditchangeModifyVariableName)
62  ON_EN_KILLFOCUS(IDC_MODIFY_DEFAULT_VALUE, OnKillfocusModifyDefaultValue)
63  ON_CBN_DROPDOWN(IDC_MODIFY_VARIABLE_NAME, OnDropdownModifyVariableName)
64  //}}AFX_MSG_MAP
65 END_MESSAGE_MAP()
66 
68 // CModifyVariableDlg message handlers
69 
70 // Maybe delete variable
71 void CModifyVariableDlg::OnDeleteVariable()
72 {
73  CString temp_name;
74  int rval;
75 
76  // Check for name change
77  CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
78  cbox->GetWindowText(temp_name);
79 
80  // Can't delete. Name has been changed
81  if ( stricmp(Sexp_variables[get_sexp_var_index()].variable_name, temp_name) ) {
82  MessageBox("Can not delete variable. Name has been changed.");
83  return;
84  }
85 
86  char message[128] = "Can not delete variable.";
87  if (!IsChangeSafe(message)) {
88  return;
89  }
90 
91  // maybe delete variable
92  rval = MessageBox("This will permanantly delete the variable. Do you want to continue?", NULL, MB_OKCANCEL);
93 
94  if (rval == IDOK) {
95  // delete variable and exit
96  m_deleted = true;
97  // next statement does UpdataData(TRUE);
98  CDialog::OnOK();
99  }
100 }
101 
102 // Karajorma - Checks whether it is safe to delete or modify this string
103 bool CModifyVariableDlg::IsChangeSafe(char *message)
104 {
105  // Can't as there are SEXPs using it.
106  int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
107  if (num_counts > 0) {
108  char buffer[256];
109  sprintf(buffer, "%s Used in %d SEXP(s).", message, num_counts);
110  MessageBox(buffer);
111  return false;
112  }
113 
114  // Can't as it is used in the team loadout
116  if (num_counts > 0) {
117  char buffer[256];
118  sprintf(buffer, "%s Used in %d location(s) in loadout.", message, num_counts);
119  MessageBox(buffer);
120  return false;
121  }
122 
123  return true;
124 }
125 
126 // Set type to string
128 {
129  // check if type actually modified
130  if (m_type_number == true) {
131 
132  // Don't allow type change if in use.
133  char message[128] = "Can not modify variable type.";
134  if (!IsChangeSafe(message)) {
135  m_type_number = true;
136  m_modified_type = false;
138  return;
139  }
140 
141  // keep track if type is really changed
142  if (m_modified_type == true) {
143  m_modified_type = false;
144  } else {
145  m_modified_type = true;
146  }
147  }
148  m_type_number = false;
150 }
151 
152 // Set type to number
154 {
155  // check if type actually modified
156  if (m_type_number == false) {
157 
158  // Don't allow type change if in use.
159  char message[128] = "Can not modify variable type.";
160  if (!IsChangeSafe(message)) {
161  m_type_number = false;
162  m_modified_type = false;
164  return;
165  }
166 
167  // keep track if type is really changed
168  if (m_modified_type == true) {
169  m_modified_type = false;
170  } else {
171  m_modified_type = true;
172  }
173  }
174  m_type_number = true;
176 }
177 
178 // set player persistence
180 {
181  m_type_player_persistent = ((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->GetCheck() ? true : false;
182 
183  // keep track if type is really changed (ugh - just force it to be always changed)
184  m_modified_persistence = true;
185 
188 
190 }
191 
192 // set campaign persistence
194 {
195  m_type_campaign_persistent = ((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->GetCheck() ? true : false;
196 
197  // keep track if type is really changed (ugh - just force it to be always changed)
198  m_modified_persistence = true;
199 
201  m_type_player_persistent = false;
202 
204 }
205 
207 {
208  m_type_network_variable = ((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->GetCheck() ? true : false;
209 
210  m_modified_type = true;
211 
213 }
214 
216 {
217  CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
218 
219  // get index of current selection
220  int index = cbox->GetCurSel();
221 
222  // check an item was actually selected, and not outside the box
223  if (index == CB_ERR) {
224  return;
225  }
226 
227  // check if another has been modified
229 
230  // Don't send message if changing to self
231  if (index != m_combo_last_modified_index) {
232  MessageBox("Can only modify one variable.");
233  }
234 
235  //reset focus to current
236  cbox->SetCurSel(m_combo_last_modified_index);
237  return;
238  }
239 
241 
242  // Get index into sexp_variables
243  int sexp_variable_index = get_sexp_var_index();
244 
245  // Set new type for selection
246  m_type_number = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NUMBER) != 0) ? true : false;
247  m_type_campaign_persistent = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_CAMPAIGN_PERSISTENT) != 0) ? true : false;
248  m_type_player_persistent = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_PLAYER_PERSISTENT) != 0) ? true : false;
249  m_type_network_variable = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NETWORK) != 0) ? true : false;
251 
252  // Set new default value for selection
253  if (sexp_variable_index > -1) {
254  CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
255  edit->SetWindowText(Sexp_variables[sexp_variable_index].text);
256  }
257 }
258 
259 // Check if variable name has changed from Sexp_variables[].varaible name
261 {
262  // Do string compare to check for change
263  CString temp_name;
264 
265  // Get current variable name
266  CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
267  cbox->GetWindowText(temp_name);
268 
269  // Check if variable name is modified
270  if ( strcmp(Sexp_variables[get_sexp_var_index()].variable_name, temp_name) ) {
271  m_modified_name = true;
272  } else {
273  m_modified_name = false;
274  }
275 }
276 
278 {
279  CDialog::OnInitDialog();
280 
281  int i, box_index;
282  // Init combo box and translation table from combo box to sexp_varaibles
283  CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
284  cbox->ResetContent();
285 
286  for (i=0; i<MAX_SEXP_VARIABLES; i++) {
288  }
289 
290  // initialize list -- Box is set to *not* sort
291  for (i=0; i<MAX_SEXP_VARIABLES; i++) {
293  box_index = cbox->AddString(Sexp_variables[i].variable_name);
294 
295  // check no error
296  if ( !((box_index == CB_ERR) || (box_index == CB_ERRSPACE)) ) {
297  m_translate_combo_to_sexp[box_index] = i;
298  }
299  }
300  }
301 
302  // Exit gracefully if nothing added to combo box
303  if (cbox->GetCount() == 0) {
304  Int3(); // this should not happen
305  OnCancel();
306  }
307 
308  int last_modified = 0;
309  // Set current variable
310  if (m_start_index > -1) {
311  for (i=0; i<MAX_SEXP_VARIABLES; i++) {
313  last_modified = i;
314  break;
315  }
316  }
317  }
318 
319  m_combo_last_modified_index = last_modified;
320  cbox->SetCurSel(last_modified);
321 
322  // Set the default value
323  if (m_translate_combo_to_sexp[last_modified] > -1) {
324  CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
325  edit->SetWindowText(Sexp_variables[m_translate_combo_to_sexp[last_modified]].text);
326  }
327 
328  // Set old variable name
330 
331  // Set type
332  m_type_number = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_NUMBER) != 0) ? true : false;
333  m_type_campaign_persistent = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_CAMPAIGN_PERSISTENT) != 0) ? true : false;
334  m_type_player_persistent = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_PLAYER_PERSISTENT) != 0) ? true : false;
335  m_type_network_variable = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_NETWORK) != 0) ? true : false;
337 
338  // keep track of changes
339  m_modified_name = false;
340  m_modified_value = false;
341  m_modified_type = false;
342  m_modified_persistence = false;
343  m_deleted = false;
344  m_do_modify = false;
345 
346  m_data_validated = false;
347  m_var_name_validated = false;
348 
349 
350  return TRUE; // return TRUE unless you set the focus to a control
351  // EXCEPTION: OCX Property Pages should return FALSE
352 }
353 
355 {
356  // get buttons
357  CButton *button_string = (CButton *) GetDlgItem(IDC_TYPE_STRING);
358  CButton *button_number = (CButton *) GetDlgItem(IDC_TYPE_NUMBER);
359 
360  // assign state
361  button_number->SetCheck( m_type_number);
362  button_string->SetCheck(!m_type_number);
363 
364  ((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->SetCheck(m_type_campaign_persistent);
365  ((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->SetCheck(m_type_player_persistent);
366  ((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->SetCheck(m_type_network_variable);
367 }
368 
370 {
371  CString temp_data;
372 
373  // Validate data
374  CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
375  edit->GetWindowText(temp_data);
376 
377  // validate data
378  validate_data(temp_data, RESET_FOCUS);
379  if (m_data_validated) {
380  // Don't get OnKillfocusModifyDefaultValue when ok
381  if (!m_modified_value) {
382  if ( strcmp(Sexp_variables[get_sexp_var_index()].text, temp_data) ) {
383  m_modified_value = true;
384  }
385  }
386 
387  // validate variable name
389  if (m_var_name_validated) {
390 
391  // maybe set m_do_modify -- this is needed. compare with OnCancel()
393  m_do_modify = true;
394  }
395  CDialog::OnOK();
396  }
397  }
398 }
399 
401 {
402  // Do string compare to check for change
403  CString temp_data;
404 
405  CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
406  edit->GetWindowText(temp_data);
407 
408  if ( strcmp(Sexp_variables[get_sexp_var_index()].text, temp_data) ) {
409  m_modified_value = true;
410  } else {
411  m_modified_value = false;
412  }
413 }
414 
415 // validate data
416 // check (1) zero length (2) invalid chars (3) value if numberf
417 void CModifyVariableDlg::validate_data(CString &temp_data, int set_focus)
418 {
419  // display invalid data message
420  bool message = false;
421  char message_text[256];
422 
423  // check length > 0
424  int length = strlen(temp_data);
425  if (length == 0) {
426  strcpy_s(message_text, "Invalid Default Value");
427  message = true;
428 
429  } else if (m_type_number) {
430  // check if string and str(atoi(stri)) are same
431  int temp_num = atoi(temp_data);
432  char buf[TOKEN_LENGTH];
433  sprintf(buf, "%d", temp_num);
434 
435  if ( stricmp(buf, temp_data) ) {
436  message = true;
437  strcpy_s(message_text, "Invalid Default Value");
438  } else {
439  message = false;
440  }
441  }
442 
443  // check for invalid characters
444  int rval = strcspn(temp_data, "@()");
445  if (rval != length) {
446  message = true;
447  sprintf(message_text, "Invalid char '%c' in Default Value", temp_data[rval]);
448  }
449 
450  // display message
451  if ( message ) {
452  m_data_validated = false;
453  MessageBox(message_text);
454 
455  // reset focus
456  if (set_focus == RESET_FOCUS) {
457  CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
458  edit->SetFocus();
459  edit->SetSel(0, -1);
460  }
461  }
462 
463  // string always ok, numbers if no message
465 }
466 
467 // validate variable name
468 // check (1) zero length (2) invalid chars (3) already in use
470 {
471  CString temp_name;
472  CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
473  cbox->GetWindowText(temp_name);
474 
475  int cur_sel = cbox->GetCurSel();
477 
478  // display invalid data message
479  bool message = false;
480  char message_text[256];
481 
482  // check length > 0
483  int length = strlen(temp_name);
484  if (length == 0) {
485  strcpy_s(message_text, "Invalid Variable Name");
486  message = true;
487  } else {
488 
489  // check for invalid characters
490  int rval = strcspn(temp_name, "@()");
491  if (rval != length) {
492  message = true;
493  sprintf(message_text, "Invalid char '%c' in Variable Name", temp_name[rval]);
494  } else {
495  int index = get_index_sexp_variable_name(temp_name);
496 
497  // if not a new name and not start name
498  if ( (index != -1) && (index != m_translate_combo_to_sexp[m_combo_last_modified_index]) ) {
499  message = true;
500  strcpy_s(message_text, "Variable Name already in use");
501  }
502  }
503  }
504 
505  // display message
506  if ( message ) {
507  MessageBox(message_text);
508 
509  // reset focus
510  if (set_focus == RESET_FOCUS) {
511  cbox->SetFocus();
512  }
513  }
514 
515  // set var_name_validated
517 }
518 
519 
521 {
523  Assert( (index >= 0) && (index < MAX_SEXP_VARIABLES) );
524 
525  return index;
526 }
527 
528 // Reset text in drop down list
530 {
531  CString temp_name;
532 
533  // Get current variable name
534  CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
535  cbox->GetWindowText(temp_name);
536 
537  // Reset combo box text
538  int rval;
539  rval = cbox->InsertString(m_combo_last_modified_index, temp_name);
540  if ( (rval == CB_ERR) || (rval == CB_ERRSPACE) ) {
541  AfxMessageBox("An internal error has occured.");
542  OnCancel();
543  }
544  cbox->DeleteString(m_combo_last_modified_index+1);
545 
546  cbox->SetCurSel(m_combo_last_modified_index);
547 }
#define MB_OKCANCEL
Definition: config.h:180
int i
Definition: multi_pxo.cpp:466
virtual BOOL OnInitDialog()
#define SEXP_VARIABLE_NETWORK
Definition: sexp.h:888
GLuint index
Definition: Glext.h:5608
Assert(pm!=NULL)
#define SEXP_VARIABLE_SET
Definition: sexp.h:903
#define TRUE
Definition: pstypes.h:399
virtual void DoDataExchange(CDataExchange *pDX)
sexp_variable Sexp_variables[MAX_SEXP_VARIABLES]
Definition: sexp.cpp:846
GLenum GLuint GLenum GLsizei const GLchar * message
Definition: Glext.h:5156
#define Int3()
Definition: pstypes.h:292
int get_index_sexp_variable_name(const char *text)
Definition: sexp.cpp:29324
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: Glext.h:7308
int m_translate_combo_to_sexp[MAX_SEXP_VARIABLES]
GLenum type
Definition: Gl.h:1492
int get_variable_count(const char *var_name)
Definition: sexp_tree.cpp:6143
#define IDC_TYPE_NUMBER
Definition: resource.h:226
#define RESET_FOCUS
afx_msg void OnTypePlayerPersistent()
afx_msg void OnSelchangeModifyVariableName()
afx_msg int get_sexp_var_index()
#define SEXP_VARIABLE_BLOCK
Definition: sexp.h:878
afx_msg void OnDropdownModifyVariableName()
sprintf(buf,"(%f,%f,%f)", v3->xyz.x, v3->xyz.y, v3->xyz.z)
afx_msg void validate_var_name(int set_focus)
afx_msg void OnTypeNetworkVariable()
GLuint buffer
Definition: Glext.h:5492
afx_msg void OnEditchangeModifyVariableName()
int type
Definition: sexp.h:1043
#define IDC_MODIFY_DEFAULT_VALUE
Definition: resource.h:986
afx_msg void OnKillfocusModifyDefaultValue()
int BOOL
Definition: config.h:80
#define TOKEN_LENGTH
Definition: globals.h:41
#define IDC_TYPE_NETWORK_VARIABLE
Definition: resource.h:1085
#define IDC_TYPE_STRING
Definition: resource.h:215
sexp_tree * m_p_sexp_tree
#define SEXP_VARIABLE_CAMPAIGN_PERSISTENT
Definition: sexp.h:886
#define IDC_TYPE_CAMPAIGN_PERSISTENT
Definition: resource.h:1076
afx_msg void set_variable_type()
int MessageBox(HWND h, const char *s1, const char *s2, int i)
#define ID_DELETE_VARIABLE
Definition: resource.h:6
GLenum GLuint GLenum GLsizei length
Definition: Glext.h:5156
#define IDC_TYPE_PLAYER_PERSISTENT
Definition: resource.h:1078
#define IDC_MODIFY_VARIABLE_NAME
Definition: resource.h:528
#define SEXP_VARIABLE_NUMBER
Definition: sexp.h:873
char variable_name[TOKEN_LENGTH]
Definition: sexp.h:1045
afx_msg void OnTypeNumber()
afx_msg void OnTypeString()
afx_msg void validate_data(CString &temp_data, int set_focus)
#define stricmp(s1, s2)
Definition: config.h:271
CModifyVariableDlg(CWnd *pParent=NULL)
#define MAX_SEXP_VARIABLES
Definition: sexp.h:23
int get_loadout_variable_count(int var_index)
Definition: sexp_tree.cpp:6166
#define strcpy_s(...)
Definition: safe_strings.h:67
#define SEXP_VARIABLE_PLAYER_PERSISTENT
Definition: sexp.h:883
afx_msg void OnTypeCampaignPersistent()