2 * Copyright (C) Volition, Inc. 1999. All rights reserved.
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
10 * $Logfile: /Freespace2/code/FRED2/DebriefingEditorDlg.cpp $
15 * Debriefing editor dialog. Used to edit mission debriefings of course.
18 * Revision 1.3 2002/06/09 04:41:16 relnev
19 * added copyright header
21 * Revision 1.2 2002/05/07 03:16:44 theoddone33
22 * The Great Newline Fix
24 * Revision 1.1.1.1 2002/05/03 03:28:08 root
28 * 2 10/07/98 6:28p Dave
29 * Initial checkin. Renamed all relevant stuff to be Fred2 instead of
30 * Fred. Globalized mission and campaign file extensions. Removed Silent
31 * Threat specific code.
33 * 1 10/07/98 3:01p Dave
35 * 1 10/07/98 3:00p Dave
37 * 20 7/07/98 2:09p Hoffoss
38 * Fixed bug where sexp for debriefing stages get cleared when inserting
41 * 19 4/30/98 8:23p John
42 * Fixed some bugs with Fred caused by my new cfile code.
44 * 18 4/22/98 9:56a Sandeep
46 * 17 4/20/98 4:40p Hoffoss
47 * Added a button to 4 editors to play the chosen wave file.
49 * 16 4/17/98 1:41p Allender
50 * took out function calls in NDEBUG mode
52 * 15 4/06/98 10:43a John
53 * Fixed bugs with inserting/deleting stages
55 * 14 4/03/98 12:39p Hoffoss
56 * Changed starting directory for browse buttons in several editors.
58 * 13 4/03/98 11:34a John
59 * Fixed the stuff I broke in Fred from the new breifing
61 * 12 3/17/98 2:06p Hoffoss
62 * Made enter key not close the dialog box (default windows behavior, even
63 * when no ok button. Talk about stupid. :)
65 * 11 2/09/98 9:25p Allender
66 * team v team support. multiple pools and breifings
68 * 10 2/04/98 4:32p Allender
69 * support for multiple briefings and debriefings. Changes to mission
70 * type (now a bitfield). Bitfield defs for multiplayer modes
72 * 9 1/02/98 3:29p Duncan
73 * Fixed bug with sexp tree freeing.
75 * 8 11/10/97 12:09p Johnson
76 * Fixed sexp free error in debriefing editor.
78 * 7 11/10/97 11:58a Johnson
79 * Added support to debriefing editor for "press cancel to go to reference
82 * 6 10/28/97 6:07p Jasen
83 * Added some debugging code to detect sexp leaks. Looks there are some I
84 * will need to investigate more.
86 * 5 10/27/97 2:06p Hoffoss
87 * Fixed editor to allow correct character limit for recommendation text.
89 * 4 10/14/97 12:06p Hoffoss
90 * Recoded debriefing editor to utilize new format.
92 * 3 10/14/97 10:35a Hoffoss
93 * Hacked the hell out of this file to allow Fred to compile for now.
94 * Next step is to fix it all.
96 * 2 7/08/97 2:03p Hoffoss
97 * Debriefing editor coded and implemented.
103 #include <mmsystem.h>
105 #include "debriefingeditordlg.h"
107 #include "missionbriefcommon.h"
112 #define new DEBUG_NEW
114 static char THIS_FILE[] = __FILE__;
117 /////////////////////////////////////////////////////////////////////////////
118 // debriefing_editor_dlg dialog
120 debriefing_editor_dlg::debriefing_editor_dlg(CWnd* pParent /*=NULL*/)
121 : CDialog(debriefing_editor_dlg::IDD, pParent)
123 //{{AFX_DATA_INIT(debriefing_editor_dlg)
126 m_stage_title = _T("");
128 m_current_debriefing = -1;
134 select_sexp_node = -1;
137 void debriefing_editor_dlg::DoDataExchange(CDataExchange* pDX)
139 CDialog::DoDataExchange(pDX);
140 //{{AFX_DATA_MAP(debriefing_editor_dlg)
141 DDX_Control(pDX, IDC_TREE, m_tree);
142 DDX_Text(pDX, IDC_TEXT, m_text);
143 DDX_Text(pDX, IDC_VOICE, m_voice);
144 DDX_Text(pDX, IDC_STAGE_TITLE, m_stage_title);
145 DDX_Text(pDX, IDC_REC_TEXT, m_rec_text);
148 DDV_MaxChars(pDX, m_text, MAX_BRIEF_LEN - 1);
149 DDV_MaxChars(pDX, m_voice, MAX_FILENAME_LEN - 1);
150 DDV_MaxChars(pDX, m_rec_text, MAX_RECOMMENDATION_LEN - 1);
153 BEGIN_MESSAGE_MAP(debriefing_editor_dlg, CDialog)
154 //{{AFX_MSG_MAP(debriefing_editor_dlg)
155 ON_BN_CLICKED(IDC_NEXT, OnNext)
156 ON_BN_CLICKED(IDC_PREV, OnPrev)
157 ON_BN_CLICKED(IDC_BROWSE, OnBrowse)
158 ON_BN_CLICKED(IDC_ADD_STAGE, OnAddStage)
159 ON_BN_CLICKED(IDC_DELETE_STAGE, OnDeleteStage)
160 ON_BN_CLICKED(IDC_INSERT_STAGE, OnInsertStage)
161 ON_NOTIFY(NM_RCLICK, IDC_TREE, OnRclickTree)
162 ON_NOTIFY(TVN_BEGINLABELEDIT, IDC_TREE, OnBeginlabeleditTree)
163 ON_NOTIFY(TVN_ENDLABELEDIT, IDC_TREE, OnEndlabeleditTree)
166 ON_BN_CLICKED(IDC_PLAY, OnPlay)
170 /////////////////////////////////////////////////////////////////////////////
171 // debriefing_editor_dlg message handlers
173 void debriefing_editor_dlg::OnInitMenu(CMenu* pMenu)
178 // disable any items we should disable
179 m = pMenu->GetSubMenu(0);
181 // uncheck all menu items
182 for (i = 0; i < Num_teams; i++ )
183 m->CheckMenuItem( i, MF_BYPOSITION | MF_UNCHECKED );
185 for ( i = Num_teams; i < MAX_TEAMS; i++ )
186 m->EnableMenuItem(i, MF_BYPOSITION | MF_GRAYED);
189 // put a check next to the currently selected item
190 m->CheckMenuItem(m_current_debriefing, MF_BYPOSITION | MF_CHECKED );
192 CDialog::OnInitMenu(pMenu);
195 BOOL debriefing_editor_dlg::OnInitDialog()
199 CDialog::OnInitDialog();
200 m_play_bm.LoadBitmap(IDB_PLAY);
201 ((CButton *) GetDlgItem(IDC_PLAY)) -> SetBitmap(m_play_bm);
203 m_current_debriefing = 0;
206 Debriefing = &Debriefings[m_current_debriefing];
208 m_tree.link_modified(&modified); // provide way to indicate trees are modified in dialog
209 n = m_tree.select_sexp_node = select_sexp_node;
210 select_sexp_node = -1;
212 for (i=0; i<Debriefing->num_stages; i++)
213 if (query_node_in_sexp(n, Debriefing->stages[i].formula))
216 if (i < Debriefing->num_stages) {
219 GetDlgItem(IDC_TREE) -> SetFocus();
220 m_tree.hilite_item(m_tree.select_sexp_node);
229 // hard coded stuff to deal with the multiple briefings per mission.
234 void debriefing_editor_dlg::update_data(int update)
236 int enable, save_debriefing;
239 save_debriefing = m_current_debriefing;
244 // based on the game type, enable the multiple briefings combo box (or disable it)
246 // set up the pointer to the briefing that we are editing
247 if ( save_debriefing != m_current_debriefing )
248 Debriefing = &Debriefings[save_debriefing];
250 Debriefing = &Debriefings[m_current_debriefing];
252 if (m_last_stage >= 0) {
253 ptr = &Debriefing->stages[m_last_stage];
254 if (ptr->formula >= 0)
255 free_sexp2(ptr->formula);
257 ptr->formula = m_tree.save_tree();
258 deconvert_multiline_string(ptr->new_text, m_text, MAX_DEBRIEF_LEN);
259 deconvert_multiline_string(ptr->new_recommendation_text, m_rec_text, MAX_RECOMMENDATION_LEN);
260 string_copy(ptr->voice, m_voice, MAX_FILENAME_LEN);
263 // now get new stage data
264 if ((m_cur_stage >= 0) && (m_cur_stage < Debriefing->num_stages)) {
265 ptr = &Debriefing->stages[m_cur_stage];
266 m_stage_title.Format("Stage %d of %d", m_cur_stage + 1, Debriefing->num_stages);
267 m_tree.load_tree(ptr->formula);
268 m_text = convert_multiline_string(ptr->new_text);
269 m_rec_text = convert_multiline_string(ptr->new_recommendation_text);
270 m_voice = ptr->voice;
274 m_stage_title = _T("No stages");
283 if (m_cur_stage == Debriefing->num_stages - 1)
284 GetDlgItem(IDC_NEXT) -> EnableWindow(FALSE);
286 GetDlgItem(IDC_NEXT) -> EnableWindow(enable);
289 GetDlgItem(IDC_PREV) -> EnableWindow(enable);
291 GetDlgItem(IDC_PREV) -> EnableWindow(FALSE);
293 if (Debriefing->num_stages >= MAX_DEBRIEF_STAGES)
294 GetDlgItem(IDC_ADD_STAGE) -> EnableWindow(FALSE);
296 GetDlgItem(IDC_ADD_STAGE) -> EnableWindow(TRUE);
298 if (Debriefing->num_stages) {
299 GetDlgItem(IDC_DELETE_STAGE) -> EnableWindow(enable);
300 GetDlgItem(IDC_INSERT_STAGE) -> EnableWindow(enable);
303 GetDlgItem(IDC_DELETE_STAGE) -> EnableWindow(FALSE);
304 GetDlgItem(IDC_INSERT_STAGE) -> EnableWindow(FALSE);
307 GetDlgItem(IDC_VOICE) -> EnableWindow(enable);
308 GetDlgItem(IDC_BROWSE) -> EnableWindow(enable);
309 GetDlgItem(IDC_TEXT) -> EnableWindow(enable);
310 GetDlgItem(IDC_REC_TEXT) -> EnableWindow(enable);
311 GetDlgItem(IDC_TREE) -> EnableWindow(enable);
313 m_last_stage = m_cur_stage;
317 count_free_sexp_nodes();
321 void debriefing_editor_dlg::OnNext()
327 void debriefing_editor_dlg::OnPrev()
333 void debriefing_editor_dlg::OnBrowse()
340 if (The_mission.game_type & MISSION_TYPE_TRAINING)
341 z = cfile_push_chdir(CF_TYPE_VOICE_TRAINING);
343 z = cfile_push_chdir(CF_TYPE_VOICE_DEBRIEFINGS);
345 CFileDialog dlg(TRUE, "wav", NULL, OFN_HIDEREADONLY | OFN_FILEMUSTEXIST | OFN_NOCHANGEDIR,
346 "Wave Files (*.wav)|*.wav||");
348 if (dlg.DoModal() == IDOK) {
349 m_voice = dlg.GetFileName();
357 void debriefing_editor_dlg::OnAddStage()
361 if (Debriefing->num_stages >= MAX_DEBRIEF_STAGES)
364 m_cur_stage = i = Debriefing->num_stages++;
365 copy_stage(i - 1, i, 1);
369 void debriefing_editor_dlg::OnDeleteStage()
376 SDL_assert(Debriefing->num_stages);
380 for (i=z+1; i<Debriefing->num_stages; i++) {
381 copy_stage(i, i - 1);
384 Debriefing->num_stages--;
386 if (m_cur_stage >= Debriefing->num_stages)
387 m_cur_stage = Debriefing->num_stages - 1;
392 void debriefing_editor_dlg::OnInsertStage()
396 if (Debriefing->num_stages >= MAX_DEBRIEF_STAGES)
399 if (!Debriefing->num_stages) {
407 for (i=Debriefing->num_stages; i>z; i--) {
408 copy_stage(i - 1, i);
411 Debriefing->num_stages++;
412 copy_stage(z, z + 1);
413 Debriefing->stages[z].formula = -1;
418 void debriefing_editor_dlg::copy_stage(int from, int to, int clear_formula)
420 if ((from < 0) || (from >= Debriefing->num_stages)) {
421 strcpy(Debriefing->stages[to].new_text, "<Text here>");
422 strcpy(Debriefing->stages[to].voice, "none.wav");
423 Debriefing->stages[to].formula = -1;
429 Debriefing->stages[to].formula = -1;
431 Debriefing->stages[to].formula = Debriefing->stages[from].formula;
433 strcpy( Debriefing->stages[to].new_text, Debriefing->stages[from].new_text );
434 strcpy( Debriefing->stages[to].voice, Debriefing->stages[from].voice );
435 strcpy( Debriefing->stages[to].new_recommendation_text, Debriefing->stages[from].new_recommendation_text );
438 void debriefing_editor_dlg::OnRclickTree(NMHDR* pNMHDR, LRESULT* pResult)
440 m_tree.right_clicked();
444 void debriefing_editor_dlg::OnBeginlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult)
446 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
448 if (m_tree.edit_label(pTVDispInfo->item.hItem) == 1) {
456 void debriefing_editor_dlg::OnEndlabeleditTree(NMHDR* pNMHDR, LRESULT* pResult)
458 TV_DISPINFO* pTVDispInfo = (TV_DISPINFO*)pNMHDR;
460 *pResult = m_tree.end_label_edit(pTVDispInfo->item.hItem, pTVDispInfo->item.pszText);
463 void debriefing_editor_dlg::OnClose()
470 void debriefing_editor_dlg::OnOK()
474 BOOL debriefing_editor_dlg::OnCommand(WPARAM wParam, LPARAM lParam)
478 // deal with figuring out menu stuff
480 if ( (id >= ID_TEAM_1) && (id < ID_TEAM_3) ) {
483 // set the current debriefing
484 m_current_debriefing = id - ID_TEAM_1;
486 // put user back at first stage for this team (or no current stage is there are none).
487 Debriefing = &Debriefings[m_current_debriefing];
488 if ( Debriefing->num_stages > 0 )
497 return CDialog::OnCommand(wParam, lParam);
500 BOOL debriefing_editor_dlg::DestroyWindow()
502 m_play_bm.DeleteObject();
503 return CDialog::DestroyWindow();
506 void debriefing_editor_dlg::OnPlay()
508 char path[MAX_PATH_LEN + 1];
509 GetDlgItem(IDC_VOICE)->GetWindowText(m_voice);
512 cf_find_file_location((char *) (LPCSTR) m_voice, CF_TYPE_ANY, path, &size, &offset );
514 PlaySound(path, NULL, SND_ASYNC | SND_FILENAME);