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