File: modifyvariabledlg.cpp

package info (click to toggle)
freespace2 3.7.4%2Brepack-1.1
  • links: PTS, VCS
  • area: non-free
  • in suites: bullseye
  • size: 22,268 kB
  • sloc: cpp: 393,535; ansic: 4,106; makefile: 1,091; xml: 181; sh: 137
file content (547 lines) | stat: -rw-r--r-- 15,287 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
/*
 * Copyright (C) Volition, Inc. 1999.  All rights reserved.
 *
 * All source code herein is the property of Volition, Inc. You may not sell 
 * or otherwise commercially exploit the source or things you created based on the 
 * source.
 *
*/

// ModifyVariableDlg.cpp : implementation file
//

#include "stdafx.h"
#include "FRED.h"
#include "ModifyVariableDlg.h"
#include "parse/sexp.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

#define	NO_RESET_FOCUS	0
#define	RESET_FOCUS		1


/////////////////////////////////////////////////////////////////////////////
// CModifyVariableDlg dialog

CModifyVariableDlg::CModifyVariableDlg(CWnd* pParent /*=NULL*/)
	: CDialog(CModifyVariableDlg::IDD, pParent)
{
	//{{AFX_DATA_INIT(CModifyVariableDlg)
	m_default_value = _T("");
	m_cur_variable_name = _T("");
	//}}AFX_DATA_INIT
}


void CModifyVariableDlg::DoDataExchange(CDataExchange* pDX)
{
	CDialog::DoDataExchange(pDX);
	//{{AFX_DATA_MAP(CModifyVariableDlg)
	DDX_Text(pDX, IDC_MODIFY_DEFAULT_VALUE, m_default_value);
	DDV_MaxChars(pDX, m_default_value, 31);
	DDX_CBString(pDX, IDC_MODIFY_VARIABLE_NAME, m_cur_variable_name);
	DDV_MaxChars(pDX, m_cur_variable_name, 31);
	//}}AFX_DATA_MAP
}


BEGIN_MESSAGE_MAP(CModifyVariableDlg, CDialog)
	//{{AFX_MSG_MAP(CModifyVariableDlg)
	ON_BN_CLICKED(ID_DELETE_VARIABLE, OnDeleteVariable)
	ON_BN_CLICKED(IDC_TYPE_STRING, OnTypeString)
	ON_BN_CLICKED(IDC_TYPE_NUMBER, OnTypeNumber)
	ON_BN_CLICKED(IDC_TYPE_PLAYER_PERSISTENT, OnTypePlayerPersistent)
	ON_BN_CLICKED(IDC_TYPE_CAMPAIGN_PERSISTENT, OnTypeCampaignPersistent)
	ON_BN_CLICKED(IDC_TYPE_NETWORK_VARIABLE, OnTypeNetworkVariable)
	ON_CBN_SELCHANGE(IDC_MODIFY_VARIABLE_NAME, OnSelchangeModifyVariableName)
	ON_CBN_EDITCHANGE(IDC_MODIFY_VARIABLE_NAME, OnEditchangeModifyVariableName)
	ON_EN_KILLFOCUS(IDC_MODIFY_DEFAULT_VALUE, OnKillfocusModifyDefaultValue)
	ON_CBN_DROPDOWN(IDC_MODIFY_VARIABLE_NAME, OnDropdownModifyVariableName)
	//}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CModifyVariableDlg message handlers

// Maybe delete variable
void CModifyVariableDlg::OnDeleteVariable() 
{
	CString temp_name;
	int rval;

	// Check for name change
	CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
	cbox->GetWindowText(temp_name);

	// Can't delete. Name has been changed
	if ( stricmp(Sexp_variables[get_sexp_var_index()].variable_name, temp_name) ) {
		MessageBox("Can not delete variable.  Name has been changed.");
		return;
	}
	
	char message[128] = "Can not delete variable.";
	if (!IsChangeSafe(message))	{
		return;
	}

	// maybe delete variable
	rval = MessageBox("This will permanantly delete the variable.  Do you want to continue?", NULL, MB_OKCANCEL);

	if (rval == IDOK) {
		// delete variable and exit
		m_deleted = true;
		// next statement does UpdataData(TRUE);
		CDialog::OnOK();
	}
}

// Karajorma - Checks whether it is safe to delete or modify this string
bool CModifyVariableDlg::IsChangeSafe(char *message)
{
	// Can't as there are SEXPs using it. 
	int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
	if (num_counts > 0) {
		char buffer[256];
		sprintf(buffer, "%s Used in %d SEXP(s).", message, num_counts);
		MessageBox(buffer);
		return false;
	}
	
	// Can't as it is used in the team loadout
	num_counts = m_p_sexp_tree->get_loadout_variable_count(get_sexp_var_index());
	if (num_counts > 0) {
		char buffer[256];
		sprintf(buffer, "%s Used in %d location(s) in loadout.", message, num_counts);
		MessageBox(buffer);
		return false;
	}

	return true;
}

// Set type to string
void CModifyVariableDlg::OnTypeString() 
{
	// check if type actually modified
	if (m_type_number == true) {

		// Don't allow type change if in use.		
		char message[128] = "Can not modify variable type.";
		if (!IsChangeSafe(message))	{
			m_type_number = true;
			m_modified_type = false;
			set_variable_type();
			return;
		}

		// keep track if type is really changed
		if (m_modified_type == true) {
			m_modified_type = false;
		} else {
			m_modified_type = true;
		}
	}
	m_type_number = false;
	set_variable_type();
}

// Set type to number
void CModifyVariableDlg::OnTypeNumber() 
{
	// check if type actually modified
	if (m_type_number == false) {
		
		// Don't allow type change if in use.			
		char message[128] = "Can not modify variable type.";
		if (!IsChangeSafe(message))	{
			m_type_number = false;
			m_modified_type = false;
			set_variable_type();
			return;
		}

		// keep track if type is really changed
		if (m_modified_type == true) {
			m_modified_type = false;
		} else {
			m_modified_type = true;
		}
	}
	m_type_number = true;
	set_variable_type();
}

// set player persistence
void CModifyVariableDlg::OnTypePlayerPersistent()
{
	m_type_player_persistent = ((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->GetCheck() ? true : false;

	// keep track if type is really changed (ugh - just force it to be always changed)
	m_modified_persistence = true;

	if (m_type_player_persistent)
		m_type_campaign_persistent = false;

	set_variable_type();
}

// set campaign persistence
void CModifyVariableDlg::OnTypeCampaignPersistent()
{
	m_type_campaign_persistent = ((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->GetCheck() ? true : false;

	// keep track if type is really changed (ugh - just force it to be always changed)
	m_modified_persistence = true;

	if (m_type_campaign_persistent)
		m_type_player_persistent = false;

	set_variable_type();
}

void CModifyVariableDlg::OnTypeNetworkVariable()
{
	m_type_network_variable = ((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->GetCheck() ? true : false;

	m_modified_type = true; 

	set_variable_type();
}

void CModifyVariableDlg::OnSelchangeModifyVariableName()
{
	CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);

	// get index of current selection
	int index = cbox->GetCurSel();

	// check an item was actually selected, and not outside the box
	if (index == CB_ERR) {
		return;
	}

	// check if another has been modified
	if (m_modified_type || m_modified_persistence || m_modified_name || m_modified_value) {
		
		// Don't send message if changing to self
		if (index != m_combo_last_modified_index) {
			MessageBox("Can only modify one variable.");
		}

		//reset focus to current
		cbox->SetCurSel(m_combo_last_modified_index);
		return;
	}

	m_combo_last_modified_index = index;

	// Get index into sexp_variables
	int sexp_variable_index = get_sexp_var_index();
	
	// Set new type for selection
	m_type_number = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NUMBER) != 0) ? true : false;
	m_type_campaign_persistent = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_CAMPAIGN_PERSISTENT) != 0) ? true : false;
	m_type_player_persistent = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_PLAYER_PERSISTENT) != 0) ? true : false;
	m_type_network_variable = ((Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NETWORK) != 0) ? true : false;
	set_variable_type();

	// Set new default value for selection
	if (sexp_variable_index > -1) {
		CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
		edit->SetWindowText(Sexp_variables[sexp_variable_index].text);
	}
}

// Check if variable name has changed from Sexp_variables[].varaible name
void CModifyVariableDlg::OnEditchangeModifyVariableName() 
{
	// Do string compare to check for change
	CString temp_name;

	// Get current variable name
	CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
	cbox->GetWindowText(temp_name);

	// Check if variable name is modified
	if ( strcmp(Sexp_variables[get_sexp_var_index()].variable_name, temp_name) ) {
		m_modified_name = true;
	} else {
		m_modified_name = false;
	}
}

BOOL CModifyVariableDlg::OnInitDialog() 
{
	CDialog::OnInitDialog();

	int i, box_index;
	// Init combo box and translation table from combo box to sexp_varaibles
	CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
	cbox->ResetContent();

	for (i=0; i<MAX_SEXP_VARIABLES; i++) {
		m_translate_combo_to_sexp[i] = -1;
	}

	// initialize list -- Box is set to *not* sort
	for (i=0; i<MAX_SEXP_VARIABLES; i++) {
		if ((Sexp_variables[i].type & SEXP_VARIABLE_SET) && !(Sexp_variables[i].type & SEXP_VARIABLE_BLOCK)){
			box_index = cbox->AddString(Sexp_variables[i].variable_name);
			
			// check no error
			if ( !((box_index == CB_ERR) || (box_index == CB_ERRSPACE)) ) {
				m_translate_combo_to_sexp[box_index] = i;
			}
		}
	}
	
	// Exit gracefully if nothing added to combo box
	if (cbox->GetCount() == 0) {
		Int3();	// this should not happen
		OnCancel();
	}

	int last_modified = 0;
	// Set current variable
	if (m_start_index > -1) {
		for (i=0; i<MAX_SEXP_VARIABLES; i++) {
			if (m_translate_combo_to_sexp[i] == m_start_index) {
				last_modified = i;
				break;
			}
		}
	}

	m_combo_last_modified_index = last_modified;
	cbox->SetCurSel(last_modified);

	// Set the default value
	if (m_translate_combo_to_sexp[last_modified] > -1) {
		CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
		edit->SetWindowText(Sexp_variables[m_translate_combo_to_sexp[last_modified]].text);
	}

	// Set old variable name
	m_old_var_name = Sexp_variables[m_translate_combo_to_sexp[last_modified]].variable_name;
	
	// Set type
	m_type_number = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_NUMBER) != 0) ? true : false;
	m_type_campaign_persistent = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_CAMPAIGN_PERSISTENT) != 0) ? true : false;
	m_type_player_persistent = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_PLAYER_PERSISTENT) != 0) ? true : false;
	m_type_network_variable = ((Sexp_variables[last_modified].type & SEXP_VARIABLE_NETWORK) != 0) ? true : false;
	set_variable_type();

	// keep track of changes
	m_modified_name  = false;
	m_modified_value = false;
	m_modified_type  = false;
	m_modified_persistence = false;
	m_deleted		  = false;
	m_do_modify		  = false;

	m_data_validated		= false;
	m_var_name_validated = false;


	return TRUE;  // return TRUE unless you set the focus to a control
	              // EXCEPTION: OCX Property Pages should return FALSE
}

void CModifyVariableDlg::set_variable_type()
{
	// get buttons
	CButton *button_string = (CButton *) GetDlgItem(IDC_TYPE_STRING);
	CButton *button_number = (CButton *) GetDlgItem(IDC_TYPE_NUMBER);

	// assign state
	button_number->SetCheck( m_type_number);
	button_string->SetCheck(!m_type_number);

	((CButton *) GetDlgItem(IDC_TYPE_CAMPAIGN_PERSISTENT))->SetCheck(m_type_campaign_persistent);
	((CButton *) GetDlgItem(IDC_TYPE_PLAYER_PERSISTENT))->SetCheck(m_type_player_persistent);
	((CButton *) GetDlgItem(IDC_TYPE_NETWORK_VARIABLE))->SetCheck(m_type_network_variable);
}

void CModifyVariableDlg::OnOK() 
{
	CString temp_data;

	// Validate data
	CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
	edit->GetWindowText(temp_data);

	// validate data
	validate_data(temp_data, RESET_FOCUS);
	if (m_data_validated) {
		// Don't get OnKillfocusModifyDefaultValue when ok
		if (!m_modified_value) {
			if ( strcmp(Sexp_variables[get_sexp_var_index()].text, temp_data) ) {
				m_modified_value = true;
			}
		}

		// validate variable name
		validate_var_name(RESET_FOCUS);
		if (m_var_name_validated) {

			// maybe set m_do_modify -- this is needed. compare with OnCancel()
			if (m_modified_name || m_modified_persistence || m_modified_value || m_modified_type) {
				m_do_modify = true;
			}
			CDialog::OnOK();
		}
	}
}

void CModifyVariableDlg::OnKillfocusModifyDefaultValue() 
{
	// Do string compare to check for change
	CString temp_data;

	CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
	edit->GetWindowText(temp_data);

	if ( strcmp(Sexp_variables[get_sexp_var_index()].text, temp_data) ) {
		m_modified_value = true;
	} else {
		m_modified_value = false;
	}
}

// validate data
// check (1)  zero length (2) invalid chars (3) value if numberf
void CModifyVariableDlg::validate_data(CString &temp_data, int set_focus)
{
	// display invalid data message
	bool message = false;
	char message_text[256];

	// check length > 0
	int length  = strlen(temp_data);
	if (length == 0) {
		strcpy_s(message_text, "Invalid  Default Value");
		message = true;

	} else if (m_type_number) {
		// check if string and str(atoi(stri)) are same
		int temp_num = atoi(temp_data);
		char buf[TOKEN_LENGTH];
		sprintf(buf, "%d", temp_num);

		if ( stricmp(buf, temp_data) ) {
			message = true;
			strcpy_s(message_text, "Invalid  Default Value");
		} else {
			message = false;
		}
	}

	// check for invalid characters
	int rval = strcspn(temp_data, "@()");
	if (rval != length) {
		message = true;
		sprintf(message_text, "Invalid char '%c' in Default Value", temp_data[rval]);
	}

	// display message
	if ( message ) {
		m_data_validated = false;
		MessageBox(message_text);

		// reset focus
		if (set_focus == RESET_FOCUS) {
			CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
			edit->SetFocus();
			edit->SetSel(0, -1);
		}
	}

	// string always ok, numbers if no message
	m_data_validated = !message;
}

// validate variable name
// check (1) zero length (2) invalid chars (3) already in use
void CModifyVariableDlg::validate_var_name(int set_focus)
{
	CString temp_name;
	CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
	cbox->GetWindowText(temp_name);

	int cur_sel = cbox->GetCurSel();
	m_old_var_name = Sexp_variables[m_translate_combo_to_sexp[cur_sel]].variable_name;

	// display invalid data message
	bool message = false;
	char message_text[256];

	// check length > 0
	int length  = strlen(temp_name);
	if (length == 0) {
		strcpy_s(message_text, "Invalid Variable Name");
		message = true;
	} else {

		// check for invalid characters
		int rval = strcspn(temp_name, "@()");
		if (rval != length) {
			message = true;
			sprintf(message_text, "Invalid char '%c' in Variable Name", temp_name[rval]);
		} else {
			int index = get_index_sexp_variable_name(temp_name);

			// if not a new name and not start name
			if ( (index != -1) && (index != m_translate_combo_to_sexp[m_combo_last_modified_index]) ) {
				message = true;
				strcpy_s(message_text, "Variable Name already in use");
			}
		}
	}

	// display message
	if ( message ) {
		MessageBox(message_text);

		// reset focus
		if (set_focus == RESET_FOCUS) {
			cbox->SetFocus();
		}
	}

	// set var_name_validated
	m_var_name_validated = !message;
}


int CModifyVariableDlg::get_sexp_var_index()
{
	int index = m_translate_combo_to_sexp[m_combo_last_modified_index];
	Assert( (index >= 0) && (index < MAX_SEXP_VARIABLES) );

	return index;
}

// Reset text in drop down list
void CModifyVariableDlg::OnDropdownModifyVariableName() 
{
	CString temp_name;

	// Get current variable name
	CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
	cbox->GetWindowText(temp_name);

	// Reset combo box text
	int rval;
	rval = cbox->InsertString(m_combo_last_modified_index, temp_name);
	if ( (rval == CB_ERR) || (rval == CB_ERRSPACE) ) {
		AfxMessageBox("An internal error has occured.");
		OnCancel();
	}
	cbox->DeleteString(m_combo_last_modified_index+1);

	cbox->SetCurSel(m_combo_last_modified_index);
}