]> icculus.org git repositories - taylor/freespace2.git/blob - src/fred2/messageeditordlg.cpp
fix issue with looping audio streams
[taylor/freespace2.git] / src / fred2 / messageeditordlg.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 /*
10  * $Logfile: /Freespace2/code/FRED2/MessageEditorDlg.cpp $
11  * $Revision$
12  * $Date$
13  * $Author$
14  *
15  * Old message editor dialog box handling code.  This was designed a LONG time ago
16  * and because so much changed, I created a new one from scratch instead.  This is
17  * only around just in case it might be useful.
18  *
19  * $Log$
20  * Revision 1.3  2002/06/09 04:41:16  relnev
21  * added copyright header
22  *
23  * Revision 1.2  2002/05/07 03:16:44  theoddone33
24  * The Great Newline Fix
25  *
26  * Revision 1.1.1.1  2002/05/03 03:28:08  root
27  * Initial import.
28  *
29  * 
30  * 2     10/07/98 6:28p Dave
31  * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
32  * Fred. Globalized mission and campaign file extensions. Removed Silent
33  * Threat specific code.
34  * 
35  * 1     10/07/98 3:01p Dave
36  * 
37  * 1     10/07/98 3:00p Dave
38  * 
39  * 26    4/07/98 10:51a Allender
40  * remove any allied from message senders.  Make heads for mission
41  * specific messages play appropriately
42  * 
43  * 25    1/07/98 5:58p Hoffoss
44  * Combined message editor into event editor.
45  * 
46  * 24    1/06/98 4:19p Hoffoss
47  * Made message editor accept returns instead of closing dialog.
48  * 
49  * 23    12/30/97 9:39a Allender
50  * minor fixups with message editing
51  * 
52  * 22    11/17/97 4:57p Allender
53  * added persona support in FreeSpace.  A couple of new messages for
54  * message.tbl which Dan didn't have
55  * 
56  * 21    10/16/97 8:54p Duncan
57  * Fixed bug in adding new message.
58  * 
59  * 20    10/14/97 10:31a Allender
60  * disable persona field for builtin messages
61  * 
62  * 19    10/13/97 11:37a Allender
63  * added personas to message editor in Fred
64  * 
65  * 18    10/10/97 6:21p Hoffoss
66  * Put in Fred support for training object list editing.
67  * 
68  * 17    10/08/97 7:52p Hoffoss
69  * Made renaming events update all sexp references to it (added a
70  * generalized function to replace all references to a name by argument
71  * type).
72  * 
73  * 16    10/08/97 4:41p Hoffoss
74  * Changed the way message editor works.  Each message is updated
75  * perminently when you switch messages (as if ok button was pressed).
76  * 
77  * 15    9/09/97 9:19a Hoffoss
78  * Fixed bug in Fred: messages shouldn't be send from the player to the
79  * player.
80  * 
81  * 14    8/08/97 3:29p Duncan
82  * Fixed bug with strings exceeding their limits.
83  * 
84  * 13    8/05/97 5:12p Jasen
85  * Added advanced_stricmp() function to handle NULL pointers gracefully,
86  * and utilized it in message editor query update function.
87  * 
88  * 12    8/01/97 3:47p Hoffoss
89  * Fixed bug where message editor believes modifications occured when
90  * nothing actually changed.
91  * 
92  * 11    7/24/97 4:34p Hoffoss
93  * Fixed omission bug.
94  * 
95  * 10    7/16/97 6:30p Hoffoss
96  * Added icons to sexp trees, mainly because I think they will be required
97  * for drag n drop.
98  * 
99  * 9     7/14/97 9:55p Hoffoss
100  * Making changes to message editor system.
101  * 
102  * 8     7/10/97 2:32p Hoffoss
103  * Made message editor dialog box modeless.
104  * 
105  * 7     7/02/97 5:09p Hoffoss
106  * Added browse buttons to message editor.
107  * 
108  * 6     5/20/97 2:28p Hoffoss
109  * Added message box queries for close window operation on all modal
110  * dialog boxes.
111  * 
112  * 5     4/17/97 2:01p Hoffoss
113  * All dialog box window states are saved between sessions now.
114  * 
115  * 4     4/01/97 5:15p Hoffoss
116  * Fixed errors in max length checks, renaming a wing now renames the
117  * ships in the wing as well, as it should.
118  * 
119  * 3     3/11/97 2:19p Hoffoss
120  * New message structure support for Fred.
121  * 
122  * 2     2/17/97 5:28p Hoffoss
123  * Checked RCS headers, added them were missing, changing description to
124  * something better, etc where needed.
125  *
126  * $NoKeywords: $
127  */
128
129 #include "stdafx.h"
130 #include "fred.h"
131 #include "messageeditordlg.h"
132 #include "freddoc.h"
133 #include "management.h"
134 #include "sexp_tree.h"
135 #include "eventeditor.h"
136 #include "missionmessage.h"
137
138 #ifdef _DEBUG
139 #define new DEBUG_NEW
140 #undef THIS_FILE
141 static char THIS_FILE[] = __FILE__;
142 #endif
143
144 CMessageEditorDlg *Message_editor_dlg = NULL;
145
146 /////////////////////////////////////////////////////////////////////////////
147 // CMessageEditorDlg dialog
148
149 CMessageEditorDlg::CMessageEditorDlg(CWnd* pParent /*=NULL*/)
150         : CDialog(CMessageEditorDlg::IDD, pParent)
151 {
152         //{{AFX_DATA_INIT(CMessageEditorDlg)
153         m_avi_filename = _T("");
154         m_wave_filename = _T("");
155         m_message_text = _T("");
156         m_message_name = _T("");
157         m_cur_msg = -1;
158         m_priority = -1;
159         m_sender = -1;
160         m_persona = -1;
161         //}}AFX_DATA_INIT
162
163         m_tree.link_modified(&modified);
164         modified = 0;
165         m_event_num = -1;
166 }
167
168 void CMessageEditorDlg::DoDataExchange(CDataExchange* pDX)
169 {
170         CDialog::DoDataExchange(pDX);
171         //{{AFX_DATA_MAP(CMessageEditorDlg)
172         DDX_Control(pDX, IDC_TREE, m_tree);
173         DDX_CBString(pDX, IDC_AVI_FILENAME, m_avi_filename);
174         DDX_CBString(pDX, IDC_WAVE_FILENAME, m_wave_filename);
175         DDX_Text(pDX, IDC_MESSAGE_TEXT, m_message_text);
176         DDX_Text(pDX, IDC_NAME, m_message_name);
177         DDX_LBIndex(pDX, IDC_MESSAGE_LIST, m_cur_msg);
178         DDX_CBIndex(pDX, IDC_PRIORITY, m_priority);
179         DDX_CBIndex(pDX, IDC_SENDER, m_sender);
180         DDX_CBIndex(pDX, IDC_PERSONA_NAME, m_persona);
181         //}}AFX_DATA_MAP
182         DDV_MaxChars(pDX, m_message_name, NAME_LENGTH - 1);
183         DDV_MaxChars(pDX, m_message_text, MESSAGE_LENGTH - 1);
184         DDV_MaxChars(pDX, m_avi_filename, MAX_FILENAME_LEN - 1);
185         DDV_MaxChars(pDX, m_wave_filename, MAX_FILENAME_LEN - 1);
186 }
187
188 BEGIN_MESSAGE_MAP(CMessageEditorDlg, CDialog)
189         //{{AFX_MSG_MAP(CMessageEditorDlg)
190         ON_LBN_SELCHANGE(IDC_MESSAGE_LIST, OnSelchangeMessageList)
191         ON_EN_UPDATE(IDC_NAME, OnUpdateName)
192         ON_BN_CLICKED(IDC_DELETE, OnDelete)
193         ON_BN_CLICKED(IDC_NEW, OnNew)
194         ON_WM_CLOSE()
195         ON_BN_CLICKED(IDC_BROWSE_AVI, OnBrowseAvi)
196         ON_BN_CLICKED(IDC_BROWSE_WAVE, OnBrowseWave)
197         ON_NOTIFY(NM_RCLICK, IDC_TREE, OnRclickTree)
198         ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_TREE, OnBeginlabeleditTree)
199         ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE, OnEndlabeleditTree)
200         ON_BN_CLICKED(ID_OK, OnOk)
201         //}}AFX_MSG_MAP
202 END_MESSAGE_MAP()
203
204 /////////////////////////////////////////////////////////////////////////////
205 // CMessageEditorDlg message handlers
206
207 BOOL CMessageEditorDlg::OnInitDialog() 
208 {
209         int i;
210         CListBox *list;
211         CComboBox *box;
212
213         CDialog::OnInitDialog();
214         theApp.init_window(&Messages_wnd_data, this);
215         m_tree.setup();
216
217         ((CEdit *) GetDlgItem(IDC_NAME))->LimitText(NAME_LENGTH - 1);
218         ((CEdit *) GetDlgItem(IDC_MESSAGE_TEXT))->LimitText(MESSAGE_LENGTH - 1);
219         ((CComboBox *) GetDlgItem(IDC_AVI_FILENAME))->LimitText(MAX_FILENAME_LEN - 1);
220         ((CComboBox *) GetDlgItem(IDC_WAVE_FILENAME))->LimitText(MAX_FILENAME_LEN - 1);
221
222         list = (CListBox *) GetDlgItem(IDC_MESSAGE_LIST);
223         list->ResetContent();
224         for (i=0; i<Num_messages; i++) {
225                 //SDL_assert(list->FindStringExact(-1, Messages[i].name) == CB_ERR);
226                 // mwa we should probably not include builtin messages into this list!
227                 list->AddString(Messages[i].name);
228         }
229
230         box = (CComboBox *) GetDlgItem(IDC_AVI_FILENAME);
231         for (i=0; i<Num_messages; i++)
232                 if (Messages[i].avi_info.name)
233                         if (box->FindStringExact(-1, Messages[i].avi_info.name) == CB_ERR)
234                                 box->AddString(Messages[i].avi_info.name);
235
236         box = (CComboBox *) GetDlgItem(IDC_WAVE_FILENAME);
237         for (i=0; i<Num_messages; i++)
238                 if (Messages[i].wave_info.name)
239                         if (box->FindStringExact(i, Messages[i].wave_info.name) == CB_ERR)
240                                 box->AddString(Messages[i].wave_info.name);
241
242         // add the persona names into the combo box
243         box = (CComboBox *)GetDlgItem(IDC_PERSONA_NAME);
244         box->ResetContent();
245         box->AddString("<None>");
246         for (i = 0; i < Num_personas; i++ )
247                 box->AddString( Personas[i].name );
248
249         box = (CComboBox *) GetDlgItem(IDC_SENDER);
250         for (i=0; i<MAX_SHIPS; i++)
251                 if ((Ships[i].objnum >= 0) && (Objects[Ships[i].objnum].type == OBJ_SHIP))
252                         box->AddString(Ships[i].ship_name);
253
254         for (i=0; i<MAX_WINGS; i++)
255                 if (Wings[i].wave_count)
256                         box->AddString(Wings[i].name);
257
258         box->AddString("<Any wingman>");
259
260         // MWA 4/7/98 -- removed any allied
261         //box->AddString("<Any allied>");
262
263         // set the first message to be the first non-builtin message (if it exists)
264         if ( Num_messages > Num_builtin_messages )
265                 m_cur_msg = Num_builtin_messages;
266         else if (Num_messages)
267                 m_cur_msg = 0;
268         else
269                 m_cur_msg = -1;
270
271         if (Num_messages >= MAX_MISSION_MESSAGES)
272                 GetDlgItem(IDC_NEW)->EnableWindow(FALSE);
273
274         update_cur_message();
275         return TRUE;
276 }
277
278 int CMessageEditorDlg::query_modified()
279 {
280         char *ptr, buf[MESSAGE_LENGTH];
281         int i;
282
283         UpdateData(TRUE);
284         if (modified)
285                 return 1;
286
287         if (m_cur_msg < 0)
288                 return 0;
289
290         ptr = (char *) (LPCTSTR) m_message_name;
291         for (i=0; i<Num_messages; i++)
292                 if ((i != m_cur_msg) && (!stricmp(ptr, Messages[i].name)))
293                         break;
294
295         if (i < Num_messages)
296                 if (stricmp(ptr, Messages[m_cur_msg].name))
297                         return 1;  // name is different and allowed to update
298
299         string_copy(buf, m_message_text, MESSAGE_LENGTH - 1);
300         if (stricmp(buf, Messages[m_cur_msg].message))
301                 return 1;
302
303         ptr = (char *) (LPCTSTR) m_avi_filename;
304         if (advanced_stricmp(ptr, Messages[m_cur_msg].avi_info.name))
305                 return 1;
306
307         ptr = (char *) (LPCTSTR) m_wave_filename;
308         if (advanced_stricmp(ptr, Messages[m_cur_msg].wave_info.name))
309                 return 1;
310
311         // check to see if persona changed.  use -1 since we stuck a "None" for persona
312         // at the beginning of the list.
313         if ( (m_persona - 1 ) != Messages[m_cur_msg].persona_index )
314                 return 1;
315
316         if (m_tree.query_false()) {
317                 if (m_event_num >= 0)
318                         return 1;
319
320         } else {
321                 if (m_event_num < 0)
322                         return 1;
323         }
324
325         return 0;
326 }
327
328 void CMessageEditorDlg::OnOK()
329 {
330 }
331
332 void CMessageEditorDlg::OnOk()
333 {
334         update(m_cur_msg);
335         theApp.record_window_data(&Messages_wnd_data, this);
336         delete Message_editor_dlg;
337         Message_editor_dlg = NULL;
338 }
339
340 void CMessageEditorDlg::OnCancel()
341 {
342         theApp.record_window_data(&Messages_wnd_data, this);
343         delete Message_editor_dlg;
344         Message_editor_dlg = NULL;
345 }
346
347 // load controls with structure data
348 void CMessageEditorDlg::update_cur_message()
349 {
350         int node, enable = TRUE, enable2 = TRUE;
351
352         if (m_cur_msg < 0)
353         {
354                 enable = enable2 = FALSE;
355                 m_message_name = _T("");
356                 m_message_text = _T("");
357                 m_avi_filename = _T("");
358                 m_wave_filename = _T("");
359                 m_tree.clear_tree();
360                 m_persona = 0;
361                 m_sender = m_priority = -1;
362
363         } else {
364                 m_message_name = Messages[m_cur_msg].name;
365                 m_message_text = Messages[m_cur_msg].message;
366                 if (Messages[m_cur_msg].avi_info.name)
367                         m_avi_filename = _T(Messages[m_cur_msg].avi_info.name);
368                 else
369                         m_avi_filename = _T("");
370
371                 if (Messages[m_cur_msg].wave_info.name)
372                         m_wave_filename = _T(Messages[m_cur_msg].wave_info.name);
373                 else
374                         m_wave_filename = _T("");
375
376                 // add persona id
377                 if ( Messages[m_cur_msg].persona_index != -1 )
378                         m_persona = Messages[m_cur_msg].persona_index + 1;              // add one for the "none" at the beginning of the list
379                 else
380                         m_persona = 0;
381
382                 m_event_num = find_event();
383                 if (m_event_num < 0) {
384                         node = -1;
385                         m_sender = m_priority = 0;
386
387                 } else
388                         node = CADR(Mission_events[m_event_num].formula);
389
390                 m_tree.load_tree(node, "false");
391         }
392
393         if (m_cur_msg < Num_builtin_messages)
394                 enable = FALSE;
395
396         GetDlgItem(IDC_NAME)->EnableWindow(enable);
397         GetDlgItem(IDC_MESSAGE_TEXT)->EnableWindow(enable);
398         GetDlgItem(IDC_AVI_FILENAME)->EnableWindow(enable);
399         GetDlgItem(IDC_WAVE_FILENAME)->EnableWindow(enable);
400         GetDlgItem(IDC_DELETE)->EnableWindow(enable);
401         GetDlgItem(IDC_TREE)->EnableWindow(enable2);
402         GetDlgItem(IDC_SENDER)->EnableWindow(enable2);
403         GetDlgItem(IDC_PRIORITY)->EnableWindow(enable2);
404         GetDlgItem(IDC_PERSONA_NAME)->EnableWindow(enable);
405         UpdateData(FALSE);
406 }
407
408 int CMessageEditorDlg::find_event()
409 {
410         char *str;
411         int i, formula, node;
412         CComboBox *box;
413
414         for (i=0; i<Num_mission_events; i++) {
415                 node = Mission_events[i].formula;
416                 if (find_operator(CTEXT(node)) == OP_WHEN) {
417                         node = CDR(node);
418                         formula = CAR(node);  // bool conditional
419                         if (CDR(CDR(node)) == -1) {  // only 1 action
420                                 node = CADR(node);
421                                 if ((find_operator(CTEXT(node)) == OP_SEND_MESSAGE) && !stricmp(CTEXT(CDR(CDR(CDR(node)))), m_message_name)) {
422                                         box = (CComboBox *) GetDlgItem(IDC_SENDER);
423                                         str = CTEXT(CDR(node));
424                                         m_sender = box->FindStringExact(-1, str);
425                                         if (m_sender == CB_ERR)
426                                                 m_sender = 0;
427
428                                         box = (CComboBox *) GetDlgItem(IDC_PRIORITY);
429                                         str = CTEXT(CDR(CDR(node)));
430                                         m_priority = box->FindStringExact(-1, str);
431                                         if (m_priority == CB_ERR)
432                                                 m_priority = 0;
433
434                                         return i;
435                                 }
436                         }
437                 }
438         }
439
440         m_sender = m_priority = 0;
441         return -1;
442 }
443
444 void CMessageEditorDlg::OnSelchangeMessageList() 
445 {
446         int old = m_cur_msg;
447         static flag = 0;
448
449         if (flag)
450                 return;
451
452         if (update(m_cur_msg)) {
453                 flag = 1;
454                 ((CListBox *) GetDlgItem(IDC_MESSAGE_LIST)) -> SetCurSel(old);
455                 m_cur_msg = old;
456                 flag = 0;
457                 return;
458         }
459
460         update_cur_message();
461 }
462
463 void CMessageEditorDlg::OnUpdateName() 
464 {
465 }
466
467 int CMessageEditorDlg::update(int num)
468 {
469         char *ptr, buf[4096];
470         int i, node, fnode;
471         CListBox *list;
472
473         UpdateData(TRUE);
474         if (num >= 0)
475         {
476                 ptr = (char *) (LPCTSTR) m_message_name;
477                 for (i=0; i<Num_messages; i++)
478                         if ((i != num) && (!stricmp(m_message_name, Messages[i].name)))
479                                 break;
480
481                 if (i == Num_messages) {  // update name if no conflicts, otherwise keep old name
482                         update_sexp_references(Messages[num].name, ptr, OPF_MESSAGE);
483                         string_copy(Messages[num].name, m_message_name, NAME_LENGTH - 1);
484
485                         list = (CListBox *) GetDlgItem(IDC_MESSAGE_LIST);
486                         list->DeleteString(num);
487                         list->InsertString(num, m_message_name);
488                 }
489
490                 string_copy(Messages[num].message, m_message_text, MESSAGE_LENGTH - 1);
491                 if (Messages[num].avi_info.name)
492                         free(Messages[num].avi_info.name);
493
494                 ptr = (char *) (LPCTSTR) m_avi_filename;
495                 if (!ptr || !strlen(ptr))
496                         Messages[num].avi_info.name = NULL;
497                 else
498                         Messages[num].avi_info.name = strdup(ptr);
499
500                 if (Messages[num].wave_info.name)
501                         free(Messages[num].wave_info.name);
502
503                 ptr = (char *) (LPCTSTR) m_wave_filename;
504                 if (!ptr || !strlen(ptr))
505                         Messages[num].wave_info.name = NULL;
506                 else
507                         Messages[num].wave_info.name = strdup(ptr);
508
509                 // update the persona to the message.  We subtract 1 for the "None" at the beginning of the combo
510                 // box list.
511                 Messages[num].persona_index = m_persona - 1;
512
513                 if (m_tree.query_false()) {
514                         if (m_event_num >= 0) {  // need to delete event
515                                 i = m_event_num;
516                                 free_sexp2(Mission_events[i].formula);
517                                 SDL_assert(i < Num_mission_events);
518                                 while (i < Num_mission_events - 1) {
519                                         Mission_events[i] = Mission_events[i + 1];
520                                         i++;
521                                 }
522
523                                 Num_mission_events--;
524                                 m_event_num = -1;
525                         }
526
527                 } else {
528                         if (m_event_num >= 0)
529                                 free_sexp2(Mission_events[m_event_num].formula);
530                         
531                         else {
532                                 if (Num_mission_events == MAX_MISSION_EVENTS) {
533                                         MessageBox("You have reached the limit on mission events.\n"
534                                                 "Can't add an event to send this message.");
535
536                                         goto exit;
537                                 }
538
539                                 SDL_assert(Num_mission_events < MAX_MISSION_EVENTS);
540                                 m_event_num = Num_mission_events++;
541                                 string_copy(Mission_events[m_event_num].name, m_message_name, NAME_LENGTH - 1);
542                                 Mission_events[m_event_num].repeat_count = 1;
543                                 Mission_events[m_event_num].interval = 1;
544                                 Mission_events[m_event_num].score = 0;
545                                 Mission_events[m_event_num].chain_delay = -1;
546                                 Mission_events[m_event_num].objective_text = NULL;
547                                 Mission_events[m_event_num].objective_key_text = NULL;
548                         }
549
550                         fnode = m_tree.save_tree();
551                         ptr = (char *) (LPCTSTR) m_message_name;
552                         node = alloc_sexp(ptr, SEXP_ATOM, SEXP_ATOM_STRING, -1, -1);
553                         ((CComboBox *) GetDlgItem(IDC_PRIORITY))->GetLBText(m_priority, buf);
554                         node = alloc_sexp(buf, SEXP_ATOM, SEXP_ATOM_STRING, -1, node);
555                         ((CComboBox *) GetDlgItem(IDC_SENDER))->GetLBText(m_sender, buf);
556                         node = alloc_sexp(buf, SEXP_ATOM, SEXP_ATOM_STRING, -1, node);
557                         node = alloc_sexp("send-message", SEXP_ATOM, SEXP_ATOM_OPERATOR, -1, node);
558                         node = alloc_sexp("", SEXP_LIST, SEXP_ATOM_LIST, node, -1);
559                         node = alloc_sexp("", SEXP_LIST, SEXP_ATOM_LIST, fnode, node);
560                         node = alloc_sexp("when", SEXP_ATOM, SEXP_ATOM_OPERATOR, -1, node);
561                         Mission_events[m_event_num].formula = node;
562                 }
563         }
564
565 exit:
566         if (query_modified())
567                 set_modified();
568
569         modified = 0;
570         return 0;
571 }
572
573 void CMessageEditorDlg::OnDelete() 
574 {
575         char buf[256];
576         int i;
577
578         SDL_assert((m_cur_msg >= 0) && (m_cur_msg < Num_messages));
579         if (Messages[m_cur_msg].avi_info.name)
580                 free(Messages[m_cur_msg].avi_info.name);
581         if (Messages[m_cur_msg].wave_info.name)
582                 free(Messages[m_cur_msg].wave_info.name);
583
584         ((CListBox *) GetDlgItem(IDC_MESSAGE_LIST))->DeleteString(m_cur_msg);
585         sprintf(buf, "<%s>", Messages[m_cur_msg].name);
586         update_sexp_references(Messages[m_cur_msg].name, buf, OPF_MESSAGE);
587
588         for (i=m_cur_msg; i<Num_messages-1; i++)
589                 Messages[i] = Messages[i + 1];
590
591         Num_messages--;
592         if (m_cur_msg >= Num_messages)
593                 m_cur_msg = Num_messages - 1;
594
595         GetDlgItem(IDC_NEW)->EnableWindow(TRUE);
596         modified = 1;
597         update_cur_message();
598 }
599
600 void CMessageEditorDlg::OnNew() 
601 {
602         if (update(m_cur_msg))
603                 return;
604
605         SDL_assert(Num_messages < MAX_MISSION_MESSAGES);
606         strcpy(Messages[Num_messages].name, "<new message>");
607         ((CListBox *) GetDlgItem(IDC_MESSAGE_LIST))->AddString("<new message>");
608
609         strcpy(Messages[Num_messages].message, "<put description here>");
610         Messages[Num_messages].avi_info.name = NULL;
611         Messages[Num_messages].wave_info.name = NULL;
612         Messages[Num_messages].persona_index = -1;
613         m_cur_msg = Num_messages++;
614         if (Num_messages >= MAX_MISSION_MESSAGES)
615                 GetDlgItem(IDC_NEW)->EnableWindow(FALSE);
616
617         modified = 1;
618         update_cur_message();
619 }
620
621 void CMessageEditorDlg::OnClose() 
622 {
623         int z;
624
625         modified = query_modified();
626         if (modified) {
627                 z = MessageBox("Do you want to keep your changes?", "Close", MB_ICONQUESTION | MB_YESNOCANCEL);
628                 if (z == IDCANCEL)
629                         return;
630
631                 if (z == IDYES) {
632                         OnOK();
633                         return;
634                 }
635         }
636         
637         theApp.record_window_data(&Messages_wnd_data, this);
638         delete Message_editor_dlg;
639         Message_editor_dlg = NULL;
640 }
641
642 void CMessageEditorDlg::OnBrowseAvi() 
643 {
644         CString name;   
645
646         UpdateData(TRUE);
647         CFileDialog dlg(TRUE, "ani", m_avi_filename, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
648                 "Ani Files (*.ani)|*.ani|Avi Files (*.avi)|*.avi|Both (*.ani, *.avi)|*.ani;*.avi||");
649
650         if (dlg.DoModal() == IDOK)
651         {
652                 m_avi_filename = dlg.GetFileName();
653                 UpdateData(FALSE);
654                 modified = 1;
655         }
656 }
657
658 void CMessageEditorDlg::OnBrowseWave() 
659 {
660         CString name;   
661
662         UpdateData(TRUE);
663         CFileDialog dlg(TRUE, "wav", m_wave_filename, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
664                 "Wave Files (*.wav)|*.wav||");
665
666         if (dlg.DoModal() == IDOK)
667         {
668                 m_wave_filename = dlg.GetFileName();
669                 UpdateData(FALSE);
670                 modified = 1;
671         }
672 }
673
674 void CMessageEditorDlg::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult) 
675 {
676         m_tree.right_clicked();
677         *pResult = 0;
678 }
679
680 void CMessageEditorDlg::OnBeginlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult) 
681 {
682         TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
683         CEdit *edit;
684
685         if (m_tree.edit_label(pTVDispInfo->item.hItem) == 1)    {
686                 *pResult = 0;
687                 modified = 1;
688                 edit = m_tree.GetEditControl();
689                 SDL_assert(edit);
690                 edit->SetLimitText(NAME_LENGTH - 1);
691
692         } else
693                 *pResult = 1;
694 }
695
696 void CMessageEditorDlg::OnEndlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult) 
697 {
698         TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
699
700         *pResult = m_tree.end_label_edit(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);
701 }
702