]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/modifyvariabledlg.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / modifyvariabledlg.cpp
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
6  * the source.
7  */
8
9 // ModifyVariableDlg.cpp : implementation file
10 //
11
12 #include "stdafx.h"
13 #include "fred.h"
14 #include "modifyvariabledlg.h"
15 #include "sexp.h"
16
17 #ifdef _DEBUG
18 #define new DEBUG_NEW
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
27 /////////////////////////////////////////////////////////////////////////////
28 // CModifyVariableDlg dialog
29
30 CModifyVariableDlg::CModifyVariableDlg(CWnd* pParent /*=NULL*/)
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)
44         DDX_Text(pDX, IDC_MODIFY_DEFAULT_VALUE, m_default_value);
45         DDV_MaxChars(pDX, m_default_value, 31);
46         DDX_CBString(pDX, IDC_MODIFY_VARIABLE_NAME, m_cur_variable_name);
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_CBN_SELCHANGE(IDC_MODIFY_VARIABLE_NAME, OnSelchangeModifyVariableName)
58         ON_CBN_EDITCHANGE(IDC_MODIFY_VARIABLE_NAME, OnEditchangeModifyVariableName)
59         ON_EN_KILLFOCUS(IDC_MODIFY_DEFAULT_VALUE, OnKillfocusModifyDefaultValue)
60         ON_CBN_DROPDOWN(IDC_MODIFY_VARIABLE_NAME, OnDropdownModifyVariableName)
61         //}}AFX_MSG_MAP
62 END_MESSAGE_MAP()
63
64 /////////////////////////////////////////////////////////////////////////////
65 // CModifyVariableDlg message handlers
66
67 // Maybe delete variable
68 void CModifyVariableDlg::OnDeleteVariable() 
69 {
70         CString temp_name;
71         int rval;
72
73         // Check for name change
74         CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
75         cbox->GetWindowText(temp_name);
76
77         // Can't delete. Name has been changed
78         if ( stricmp(Sexp_variables[get_sexp_var_index()].variable_name, temp_name) ) {
79                 MessageBox("Can not delete variable.  Name has been changed.");
80                 return;
81         }
82
83         int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
84         if (num_counts > 0) {
85                 char buffer[256];
86                 sprintf(buffer, "Can not delete variable.  Used in %d location(s).", num_counts);
87                 MessageBox(buffer);
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 // Set type to string
103 void CModifyVariableDlg::OnTypeString() 
104 {
105         // check if type actually modified
106         if (m_type_number == true) {
107
108                 // Don't allow type change if in use.
109                 int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
110                 if (num_counts > 0) {
111                         char buffer[256];
112                         sprintf(buffer, "Can not modify variable type.  Used in %d location(s).", num_counts);
113                         MessageBox(buffer);
114
115                         m_type_number = true;
116                         m_modified_type = false;
117                         set_variable_type();
118                         return;
119                 }
120
121                 // keep track if type is really changed
122                 if (m_modified_type == true) {
123                         m_modified_type = false;
124                 } else {
125                         m_modified_type = true;
126                 }
127         }
128         m_type_number = false;
129         set_variable_type();
130 }
131
132 // Set type to number
133 void CModifyVariableDlg::OnTypeNumber() 
134 {
135         // check if type actually modified
136         if (m_type_number == false) {
137
138                 // Don't allow type change if in use.
139                 int num_counts = m_p_sexp_tree->get_variable_count(Sexp_variables[get_sexp_var_index()].variable_name);
140                 if (num_counts > 0) {
141                         char buffer[256];
142                         sprintf(buffer, "Can not modify variable type.  Used in %d location(s).", num_counts);
143                         MessageBox(buffer);
144
145                         m_type_number = false;
146                         m_modified_type = false;
147                         set_variable_type();
148                         return;
149                 }
150
151                 // keep track if type is really changed
152                 if (m_modified_type == true) {
153                         m_modified_type = false;
154                 } else {
155                         m_modified_type = true;
156                 }
157         }
158         m_type_number = true;
159         set_variable_type();
160 }
161
162 #pragma warning (push)
163 #pragma warning( disable : 4800 ) // Disable "forcing value to bool 'true' or 'false'"
164
165 void CModifyVariableDlg::OnSelchangeModifyVariableName()
166 {
167         CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
168
169         // get index of current selection
170         int index = cbox->GetCurSel();
171
172         // check an item was actually selected, and not outside the box
173         if (index == CB_ERR) {
174                 return;
175         }
176
177         // check if another has been modified
178         if (m_modified_type || m_modified_name || m_modified_value) {
179                 
180                 // Don't send message if changing to self
181                 if (index != m_combo_last_modified_index) {
182                         MessageBox("Can only modify one variable.");
183                 }
184
185                 //reset focus to current
186                 cbox->SetCurSel(m_combo_last_modified_index);
187                 return;
188         }
189
190         m_combo_last_modified_index = index;
191
192         // Get index into sexp_variables
193         int sexp_variable_index = get_sexp_var_index();
194         
195         // Set new type for selection
196         m_type_number = (bool) (Sexp_variables[sexp_variable_index].type & SEXP_VARIABLE_NUMBER);
197         set_variable_type();
198
199         // Set new default value for selection
200         if (sexp_variable_index > -1) {
201                 CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
202                 edit->SetWindowText(Sexp_variables[sexp_variable_index].text);
203         }
204 }
205 #pragma warning (pop)
206
207 // Check if variable name has changed from Sexp_variables[].varaible name
208 void CModifyVariableDlg::OnEditchangeModifyVariableName() 
209 {
210         // Do string compare to check for change
211         CString temp_name;
212
213         // Get current variable name
214         CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
215         cbox->GetWindowText(temp_name);
216
217         // Check if variable name is modified
218         if ( strcmp(Sexp_variables[get_sexp_var_index()].variable_name, temp_name) ) {
219                 m_modified_name = true;
220         } else {
221                 m_modified_name = false;
222         }
223 }
224
225
226 #pragma warning (push)
227 #pragma warning( disable : 4800 ) // Disable "forcing value to bool 'true' or 'false'"
228
229 BOOL CModifyVariableDlg::OnInitDialog() 
230 {
231         CDialog::OnInitDialog();
232
233         int i, box_index;
234         // Init combo box and translation table from combo box to sexp_varaibles
235         CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
236         cbox->ResetContent();
237
238         for (i=0; i<MAX_SEXP_VARIABLES; i++) {
239                 m_traslate_combo_to_sexp[i] = -1;
240         }
241
242         // initialize list -- Box is set to *not* sort
243         for (i=0; i<MAX_SEXP_VARIABLES; i++) {
244                 if (Sexp_variables[i].type & SEXP_VARIABLE_SET) {
245                         box_index = cbox->AddString(Sexp_variables[i].variable_name);
246                         
247                         // check no error
248                         if ( !((box_index == CB_ERR) || (box_index == CB_ERRSPACE)) ) {
249                                 m_traslate_combo_to_sexp[box_index] = i;
250                         }
251                 }
252         }
253         
254         // Exit gracefully if nothing added to combo box
255         if (cbox->GetCount() == 0) {
256                 Int3(); // this should not happen
257                 OnCancel();
258         }
259
260         int last_modified = 0;
261         // Set current variable
262         if (m_start_index > -1) {
263                 for (i=0; i<MAX_SEXP_VARIABLES; i++) {
264                         if (m_traslate_combo_to_sexp[i] == m_start_index) {
265                                 last_modified = i;
266                                 break;
267                         }
268                 }
269         }
270
271         m_combo_last_modified_index = last_modified;
272         cbox->SetCurSel(last_modified);
273
274         // Set the default value
275         if (m_traslate_combo_to_sexp[last_modified] > -1) {
276                 CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
277                 edit->SetWindowText(Sexp_variables[m_traslate_combo_to_sexp[last_modified]].text);
278         }
279
280         // Set old variable name
281         m_old_var_name = Sexp_variables[m_traslate_combo_to_sexp[last_modified]].variable_name;
282         
283         // Set type
284         m_type_number = (Sexp_variables[last_modified].type & SEXP_VARIABLE_NUMBER);
285         set_variable_type();
286
287         // keep track of changes
288         m_modified_name  = false;
289         m_modified_value = false;
290         m_modified_type  = false;
291         m_deleted                 = false;
292         m_do_modify               = false;
293
294         m_data_validated                = false;
295         m_var_name_validated = false;
296
297
298         return TRUE;  // return TRUE unless you set the focus to a control
299                       // EXCEPTION: OCX Property Pages should return FALSE
300 }
301 #pragma warning (pop)
302
303
304 void CModifyVariableDlg::set_variable_type()
305 {
306         // get buttons
307         CButton *button_string = (CButton *) GetDlgItem(IDC_TYPE_STRING);
308         CButton *button_number = (CButton *) GetDlgItem(IDC_TYPE_NUMBER);
309
310         // assign state
311         button_number->SetCheck( m_type_number);
312         button_string->SetCheck(!m_type_number);
313 }
314
315 void CModifyVariableDlg::OnOK() 
316 {
317         CString temp_data;
318
319         // Validate data
320         CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
321         edit->GetWindowText(temp_data);
322
323         // validate data
324         validate_data(temp_data, RESET_FOCUS);
325         if (m_data_validated) {
326                 // Dont get OnKillfocusModifyDefaultValue when ok
327                 if (!m_modified_value) {
328                         if ( strcmp(Sexp_variables[get_sexp_var_index()].text, temp_data) ) {
329                                 m_modified_value = true;
330                         }
331                 }
332
333                 // validate variable name
334                 validate_var_name(RESET_FOCUS);
335                 if (m_var_name_validated) {
336
337                         // maybe set m_do_modify -- this is needed. compare with OnCancel()
338                         if (m_modified_name || m_modified_value || m_modified_type) {
339                                 m_do_modify = true;
340                         }
341                         CDialog::OnOK();
342                 }
343         }
344 }
345
346 void CModifyVariableDlg::OnKillfocusModifyDefaultValue() 
347 {
348         // Do string compare to check for change
349         CString temp_data;
350
351         CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
352         edit->GetWindowText(temp_data);
353
354         if ( strcmp(Sexp_variables[get_sexp_var_index()].text, temp_data) ) {
355                 m_modified_value = true;
356         } else {
357                 m_modified_value = false;
358         }
359 }
360
361 // validate data
362 // check (1)  zero length (2) invalid chars (3) value if numberf
363 void CModifyVariableDlg::validate_data(CString &temp_data, int set_focus)
364 {
365         // display invalid data message
366         bool message = false;
367         char message_text[256];
368
369         // check length > 0
370         int length  = strlen(temp_data);
371         if (length == 0) {
372                 strcpy(message_text, "Invalid  Default Value");
373                 message = true;
374
375         } else if (m_type_number) {
376                 // check if string and str(atoi(stri)) are same
377                 int temp_num = atoi(temp_data);
378                 char buf[TOKEN_LENGTH];
379                 sprintf(buf, "%d", temp_num);
380
381                 if ( stricmp(buf, temp_data) ) {
382                         message = true;
383                         strcpy(message_text, "Invalid  Default Value");
384                 } else {
385                         message = false;
386                 }
387         }
388
389         // check for invalid characters
390         int rval = strcspn(temp_data, "@()");
391         if (rval != length) {
392                 message = true;
393                 sprintf(message_text, "Invalid char '%c' in Default Value", temp_data[rval]);
394         }
395
396         // display message
397         if ( message ) {
398                 m_data_validated = false;
399                 MessageBox(message_text);
400
401                 // reset focus
402                 if (set_focus == RESET_FOCUS) {
403                         CEdit *edit = (CEdit *) GetDlgItem(IDC_MODIFY_DEFAULT_VALUE);
404                         edit->SetFocus();
405                         edit->SetSel(0, -1);
406                 }
407         }
408
409         // string always ok, numbers if no message
410         m_data_validated = !message;
411 }
412
413 // validate variable name
414 // check (1) zero length (2) invalid chars (3) already in use
415 void CModifyVariableDlg::validate_var_name(int set_focus)
416 {
417         CString temp_name;
418         CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
419         cbox->GetWindowText(temp_name);
420
421         int cur_sel = cbox->GetCurSel();
422         m_old_var_name = Sexp_variables[m_traslate_combo_to_sexp[cur_sel]].variable_name;
423
424         // display invalid data message
425         bool message = false;
426         char message_text[256];
427
428         // check length > 0
429         int length  = strlen(temp_name);
430         if (length == 0) {
431                 strcpy(message_text, "Invalid Variable Name");
432                 message = true;
433         } else {
434
435                 // check for invalid characters
436                 int rval = strcspn(temp_name, "@()");
437                 if (rval != length) {
438                         message = true;
439                         sprintf(message_text, "Invalid char '%c' in Variable Name", temp_name[rval]);
440                 } else {
441                         int index = get_index_sexp_variable_name(temp_name);
442
443                         // if not a new name and not start name
444                         if ( (index != -1) && (index != m_traslate_combo_to_sexp[m_combo_last_modified_index]) ) {
445                                 message = true;
446                                 strcpy(message_text, "Variable Name already in use");
447                         }
448                 }
449         }
450
451         // display message
452         if ( message ) {
453                 MessageBox(message_text);
454
455                 // reset focus
456                 if (set_focus == RESET_FOCUS) {
457                         cbox->SetFocus();
458                 }
459         }
460
461         // set var_name_validated
462         m_var_name_validated = !message;
463 }
464
465
466 int CModifyVariableDlg::get_sexp_var_index()
467 {
468         int index = m_traslate_combo_to_sexp[m_combo_last_modified_index];
469         SDL_assert( (index >= 0) && (index < MAX_SEXP_VARIABLES) );
470
471         return index;
472 }
473
474 // Reset text in drop down list
475 void CModifyVariableDlg::OnDropdownModifyVariableName() 
476 {
477         CString temp_name;
478
479         // Get current variable name
480         CComboBox *cbox = (CComboBox *) GetDlgItem(IDC_MODIFY_VARIABLE_NAME);
481         cbox->GetWindowText(temp_name);
482
483         // Reset combo box text
484         int rval;
485         rval = cbox->InsertString(m_combo_last_modified_index, temp_name);
486         if ( (rval == CB_ERR) || (rval == CB_ERRSPACE) ) {
487                 AfxMessageBox("An internal error has occured.");
488                 OnCancel();
489         }
490         cbox->DeleteString(m_combo_last_modified_index+1);
491
492         cbox->SetCurSel(m_combo_last_modified_index);
493 }
494