/* ** AreaEditor - a program for editing SMAUG and ROM area files. ** Author: Nick Gammon ** http://www.gammon.com.au/ ** See Copyright Notice at the end of AreaEditor.h */ #include "stdafx.h" #include "AreaEditor.h" #include "MainFrm.h" #include "SocialsListDlg.h" void CAreaEditorApp::fread_social (CFileRead & FileRead) { CString buf; CString word; bool fMatch; CSocial * social; social = new CSocial; m_SocialList.AddTail (social); while (true) { word = FileRead.fread_word (); fMatch = FALSE; switch ( UPPER(word[0]) ) { case '*': fMatch = TRUE; FileRead.fread_to_eol (); break; case 'C': KEY( "CharNoArg", social->char_no_arg, FileRead.fread_string () ); KEY( "CharFound", social->char_found, FileRead.fread_string () ); KEY( "CharAuto", social->char_auto, FileRead.fread_string () ); break; case 'E': if (word == "End" ) { if ( !social->name ) ThrowErrorException( "Name not found"); if ( !social->char_no_arg ) ThrowErrorException( "CharNoArg not found"); return; } break; case 'N': KEY( "Name", social->name, FileRead.fread_string () ); break; case 'O': KEY( "OthersNoArg", social->others_no_arg, FileRead.fread_string () ); KEY( "OthersFound", social->others_found, FileRead.fread_string () ); KEY( "OthersAuto", social->others_auto, FileRead.fread_string () ); break; case 'V': KEY( "VictFound", social->vict_found, FileRead.fread_string () ); break; } if ( !fMatch ) ThrowErrorException ("No match: %s", (LPCTSTR) word); } } // end of CAreaEditorApp::fread_social void CAreaEditorApp::LoadSocials (const CString strFileName) { CWaitCursor wait; try { CFileRead FileRead; // Open socials file CFile fSocials (strFileName, CFile::modeRead|CFile::shareDenyWrite); CArchive ar(&fSocials, CArchive::load); FileRead.Init ("Loading socials", &ar); try { while (true) { char letter; CString word; letter = FileRead.fread_letter(); if ( letter == '*' ) { FileRead.fread_to_eol (); continue; } if ( letter != '#' ) ThrowErrorException ( "# not found."); word = FileRead.fread_word (); if (word == "SOCIAL") { fread_social (FileRead); continue; } else if (word == "END") break; else ThrowErrorException ( "Bad section."); } // end of read loop } // end of try block catch(CException* e) { FileRead.Wrapup (); DeleteSocials (); // error on load - don't keep half of them e->ReportError (); ::AfxMessageBox (CFormat ("Error occurred in file %s at (line %ld) \"%s\"", (LPCTSTR) strFileName, FileRead.GetLineNumber (), (LPCTSTR) FileRead.GetLastLineRead ()), MB_ICONINFORMATION); e->Delete(); ar.Close(); return; } ar.Close(); FileRead.Wrapup (); } catch(CException* e) { ::AfxMessageBox ( CFormat ("Unable to open socials file: %s", (LPCTSTR) strFileName), MB_ICONEXCLAMATION); e->Delete(); return; } SortSocials (); } void CAreaEditorApp::OnSocialsLoad() { CFileDialog dlg(TRUE, // TRUE for FileOpen "dat", // default extension "socials.dat", // initial file name OFN_HIDEREADONLY|OFN_FILEMUSTEXIST, "Socials files (*.dat)|*.dat||"); dlg.m_ofn.lpstrTitle = "Select socials file"; if (dlg.DoModal() != IDOK) return; LoadSocials (dlg.GetPathName()); } void CAreaEditorApp::OnSocialsClose() { if (m_bSocialsDirty) { int iResponse = ::AfxMessageBox ("Socials file has changed. Save it?", MB_YESNOCANCEL | MB_ICONQUESTION); if (iResponse == IDCANCEL) return; if (iResponse == IDYES) OnSocialsSave (); } DeleteSocials (); } void CAreaEditorApp::OnUpdateSocialsClose(CCmdUI* pCmdUI) { pCmdUI->Enable (!m_SocialList.IsEmpty ()); } void CAreaEditorApp::OnUpdateSocialsLoad(CCmdUI* pCmdUI) { pCmdUI->Enable (m_SocialList.IsEmpty ()); } void CAreaEditorApp::OnSocialsSave() { CFileDialog dlg(FALSE, // FALSE for FileSave "dat", // default extension "socials.dat", OFN_HIDEREADONLY|OFN_OVERWRITEPROMPT|OFN_PATHMUSTEXIST, "Data files (*.dat)|*.dat||", &Frame); dlg.m_ofn.lpstrTitle = "Socials file"; if (dlg.DoModal() != IDOK) return; try { POSITION socialPos; CSocial * social; CFile f (dlg.GetPathName(), CFile::modeCreate|CFile::modeWrite|CFile::shareExclusive); CArchive ar(&f, CArchive::store); for (socialPos = App.m_SocialList.GetHeadPosition (); socialPos; ) { social = App.m_SocialList.GetNext (socialPos); ar.WriteString ("#SOCIAL" ENDLINE); // these two lines are required ar.WriteString (CFormat ("Name %s~" ENDLINE, (LPCTSTR) social->name)); ar.WriteString (CFormat ("CharNoArg %s~" ENDLINE, (LPCTSTR) social->char_no_arg)); // these are optional if (!social->others_no_arg.IsEmpty ()) ar.WriteString (CFormat ("OthersNoArg %s~" ENDLINE, (LPCTSTR) social->others_no_arg)); if (!social->char_found.IsEmpty ()) ar.WriteString (CFormat ("CharFound %s~" ENDLINE, (LPCTSTR) social->char_found)); if (!social->others_found.IsEmpty ()) ar.WriteString (CFormat ("OthersFound %s~" ENDLINE, (LPCTSTR) social->others_found)); if (!social->vict_found.IsEmpty ()) ar.WriteString (CFormat ("VictFound %s~" ENDLINE, (LPCTSTR) social->vict_found)); if (!social->char_auto.IsEmpty ()) ar.WriteString (CFormat ("CharAuto %s~" ENDLINE, (LPCTSTR) social->char_auto)); if (!social->others_auto.IsEmpty ()) ar.WriteString (CFormat ("OthersAuto %s~" ENDLINE, (LPCTSTR) social->others_auto)); ar.WriteString ("End" ENDLINE); // end of this social ar.WriteString (ENDLINE); // blank line } // end of each social ar.WriteString ("#END" ENDLINE); // socials file terminator ar.Close (); } catch (CException* e) { e->ReportError(); e->Delete(); } m_bSocialsDirty = false; } void CAreaEditorApp::OnUpdateSocialsSave(CCmdUI* pCmdUI) { pCmdUI->Enable (!m_SocialList.IsEmpty () && m_bSocialsDirty); } void CAreaEditorApp::DeleteSocials (void) { // ======================================================================== // delete all socials for (POSITION socialPos = m_SocialList.GetHeadPosition (); socialPos; ) delete m_SocialList.GetNext (socialPos); m_SocialList.RemoveAll (); // pointers are deleted, remove list items m_bSocialsDirty = false; } void CMainFrame::OnSocialsEdit() { CSocialsListDlg dlg; dlg.DoModal (); } void CMainFrame::OnUpdateSocialsEdit(CCmdUI* pCmdUI) { pCmdUI->Enable (!App.m_SocialList.IsEmpty ()); } int CompareSocial (const void * elem1, const void * elem2) { // ah yes, *this* line was fun to get working :) return (*((CSocial **) elem1))->name.CompareNoCase ((*((CSocial **) elem2))->name); } void CAreaEditorApp::SortSocials (void) { POSITION socialPos; CTypedPtrArray <CPtrArray, CSocial*> CSocialsArray; int iCount = App.m_SocialList.GetCount (); int i; try { CSocialsArray.SetSize (iCount); // extract pointers into a simple array for (i = 0, socialPos = m_SocialList.GetHeadPosition (); socialPos; i++) CSocialsArray.SetAt (i, m_SocialList.GetNext (socialPos)); // sort the array qsort (CSocialsArray.GetData (), iCount, sizeof (CSocial *), CompareSocial); // get rid of old list m_SocialList.RemoveAll (); // re-add in sorted order for (i = 0; i < iCount; i++) m_SocialList.AddTail (CSocialsArray [i]); } // end of try block catch(CException* e) { e->ReportError (); e->Delete(); } }