// LocalizerDlg.cpp : implementation file // #include "stdafx.h" #include "Localizer.h" #include "LocalizerDlg.h" #include using namespace Stuff; #define MISSIONSLOTSIZE 500 ///////////////////////////////////////////////////////////////////////////// // CAboutDlg dialog used for App About class CAboutDlg : public CDialog { public: CAboutDlg(); // Dialog Data //{{AFX_DATA(CAboutDlg) enum { IDD = IDD_ABOUTBOX }; //}}AFX_DATA // ClassWizard generated virtual function overrides //{{AFX_VIRTUAL(CAboutDlg) protected: virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support //}}AFX_VIRTUAL // Implementation protected: //{{AFX_MSG(CAboutDlg) //}}AFX_MSG DECLARE_MESSAGE_MAP() }; CAboutDlg::CAboutDlg() : CDialog(CAboutDlg::IDD) { //{{AFX_DATA_INIT(CAboutDlg) //}}AFX_DATA_INIT } void CAboutDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CAboutDlg) //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CAboutDlg, CDialog) //{{AFX_MSG_MAP(CAboutDlg) // No message handlers //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLocalizerDlg dialog CLocalizerDlg::CLocalizerDlg(CWnd* pParent /*=NULL*/) : CDialog(CLocalizerDlg::IDD, pParent) { //{{AFX_DATA_INIT(CLocalizerDlg) // NOTE: the ClassWizard will add member initialization here //}}AFX_DATA_INIT // Note that LoadIcon does not require a subsequent DestroyIcon in Win32 m_hIcon = AfxGetApp()->LoadIcon(IDR_MAINFRAME); LastRCSlot=-1; LastRCSearch=""; } void CLocalizerDlg::DoDataExchange(CDataExchange* pDX) { CDialog::DoDataExchange(pDX); //{{AFX_DATA_MAP(CLocalizerDlg) DDX_Control(pDX, IDC_MISLIST, m_MisList); //}}AFX_DATA_MAP } BEGIN_MESSAGE_MAP(CLocalizerDlg, CDialog) //{{AFX_MSG_MAP(CLocalizerDlg) ON_WM_SYSCOMMAND() ON_WM_PAINT() ON_WM_QUERYDRAGICON() ON_BN_CLICKED(IDC_LOCALIZE, OnLocalize) ON_BN_CLICKED(IDC_EXIT, OnExit) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CLocalizerDlg message handlers BOOL CLocalizerDlg::OnInitDialog() { CDialog::OnInitDialog(); // Add "About..." menu item to system menu. // IDM_ABOUTBOX must be in the system command range. ASSERT((IDM_ABOUTBOX & 0xFFF0) == IDM_ABOUTBOX); ASSERT(IDM_ABOUTBOX < 0xF000); CMenu* pSysMenu = GetSystemMenu(FALSE); if (pSysMenu != NULL) { CString strAboutMenu; strAboutMenu.LoadString(IDS_ABOUTBOX); if (!strAboutMenu.IsEmpty()) { pSysMenu->AppendMenu(MF_SEPARATOR); pSysMenu->AppendMenu(MF_STRING, IDM_ABOUTBOX, strAboutMenu); } } // Set the icon for this dialog. The framework does this automatically // when the application's main window is not a dialog SetIcon(m_hIcon, TRUE); // Set big icon SetIcon(m_hIcon, FALSE); // Set small icon // TODO: Add extra initialization here WIN32_FIND_DATA file_data; HANDLE mission_search = FindFirstFile("Content\\Missions\\*.*" , &file_data); if(mission_search != INVALID_HANDLE_VALUE) { do if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) { CString mis_name(file_data.cFileName); if(mis_name.CompareNoCase(".") && mis_name.CompareNoCase("..")) { m_MisList.AddString(file_data.cFileName); } } while (FindNextFile(mission_search,&file_data)); } for (int i = 0; i < m_MisList.GetCount(); i++) m_MisList.SetSel(i,true); return TRUE; // return TRUE unless you set the focus to a control } void CLocalizerDlg::OnSysCommand(UINT nID, LPARAM lParam) { if ((nID & 0xFFF0) == IDM_ABOUTBOX) { CAboutDlg dlgAbout; dlgAbout.DoModal(); } else { CDialog::OnSysCommand(nID, lParam); } } // If you add a minimize button to your dialog, you will need the code below // to draw the icon. For MFC applications using the document/view model, // this is automatically done for you by the framework. void CLocalizerDlg::OnPaint() { if (IsIconic()) { CPaintDC dc(this); // device context for painting SendMessage(WM_ICONERASEBKGND, (WPARAM) dc.GetSafeHdc(), 0); // Center icon in client rectangle int cxIcon = GetSystemMetrics(SM_CXICON); int cyIcon = GetSystemMetrics(SM_CYICON); CRect rect; GetClientRect(&rect); int x = (rect.Width() - cxIcon + 1) / 2; int y = (rect.Height() - cyIcon + 1) / 2; // Draw the icon dc.DrawIcon(x, y, m_hIcon); } else { CDialog::OnPaint(); } } // The system calls this to obtain the cursor to display while the user drags // the minimized window. HCURSOR CLocalizerDlg::OnQueryDragIcon() { return (HCURSOR) m_hIcon; } void CLocalizerDlg::OnOK() { // TODO: Add extra validation here } void CLocalizerDlg::OnCancel() { // TODO: Add extra cleanup here // CDialog::OnCancel(); } void CLocalizerDlg::OnLocalize() { LoadLangRC(); int selCount = m_MisList.GetSelCount(); int* selected = new int [selCount]; m_MisList.GetSelItems(selCount,selected); for (int i = 0; i < selCount; i++) { CString text; m_MisList.GetText(selected[i],text); Localize(text); } delete selected; SaveLangRC(); } void CLocalizerDlg::OnExit() { CDialog::OnOK(); } void CLocalizerDlg::Localize(CString &mis_name) { RemoveMission(mis_name); NextVal=FindSlotFor(mis_name); CString mis_path; CString contents_path; mis_path="Content\\Missions\\"+mis_name; contents_path=mis_path+"\\"+mis_name+".contents"; NotationFile contents_file(contents_path,NotationFile::Standard,true); NotationFile::PageIterator *entity_page_list = contents_file.MakePageIterator(); Check_Object(entity_page_list); Page *entity_page; bool dhiname; CString stringid; while ((entity_page = entity_page_list->ReadAndNext()) != NULL) { Check_Object(entity_page); if(entity_page->FindNote("DoesHaveInstanceName")) { entity_page->GetEntry("DoesHaveInstanceName",&dhiname); if(dhiname) { const char *ent_name; if(!entity_page->GetEntry("LocalizedInstanceName",&ent_name)) ent_name=entity_page->GetName(); stringid=AddLocalizedString(mis_name,ent_name,ent_name); stringid="$("+stringid+")"; entity_page->SetEntry("NameIndex",stringid); } } CString btname; btname=entity_page->GetName(); btname+="_"; const char *obj_text; if(entity_page->GetEntry("failtextstr",&obj_text) ) { stringid=AddLocalizedString(mis_name,btname+"failtext",obj_text); stringid="$("+stringid+")"; entity_page->SetEntry("failtext",stringid); } if(entity_page->GetEntry("succeedtextstr",&obj_text) ) { stringid=AddLocalizedString(mis_name,btname+"succeedtext",obj_text); stringid="$("+stringid+")"; entity_page->SetEntry("succeedtext",stringid); } if(entity_page->GetEntry("neutraltextstr",&obj_text) ) { stringid=AddLocalizedString(mis_name,btname+"neutraltext",obj_text); stringid="$("+stringid+")"; entity_page->SetEntry("neutraltext",stringid); } if(entity_page->GetEntry("descriptextstr",&obj_text) ) { stringid=AddLocalizedString(mis_name,btname+"descriptext",obj_text); stringid="$("+stringid+")"; entity_page->SetEntry("descriptext",stringid); } } contents_file.Save(); FileStream fstream; fstream.Open(contents_path,FileStream::WriteOnly); fstream<<"!Include=Content\\Defines\\MissionLang.defines\x0D\x0A"; fstream<<"!concatenate=no\x0D\x0A"; fstream<<"!preservecase=yes\x0D\x0A\x0D\x0A"; contents_file.Write(&fstream); fstream.Close(); RCFile.Insert(NextRCPos(),"\n"); } int CLocalizerDlg::NextRCPos() { int ststart=RCFile.Find("STRINGTABLE DISCARDABLE"); Verify(ststart>=0); ststart=RCFile.Find("END\n",ststart); Verify(ststart>=0); return ststart; } int CLocalizerDlg::NextHPos() { int strpos; strpos=HFile.Find("APSTUDIO_INVOKED"); Verify(strpos>=0); do strpos--; while(strpos>=0 && HFile[strpos]!='#'); Verify(strpos>=0); do strpos--; while(strpos>=0 && HFile[strpos]!='#'); if(strpos>=0) { strpos=HFile.Find('\n',strpos)+1; } else { strpos=0; } return strpos; } #define VALTAG1 "_APS_NEXT_RESOURCE_VALUE" #define VALTAG2 "_APS_NEXT_SYMED_VALUE" int CLocalizerDlg::NextHVal() { int strpos=HFile.Find(VALTAG1); Verify(strpos>=0); CString numstr; numstr=HFile.Mid(strpos+strlen(VALTAG1),HFile.Find('\n',strpos)); numstr.TrimLeft(); numstr.TrimRight(); Verify(numstr.GetLength()>0); return atoi(numstr); } void CLocalizerDlg::SetHNextVals() { int strpos; CString str; NextVal=GetHighestVal(); strpos=RemoveLineContaining(HFile,VALTAG1); Verify(strpos>=0); str.Format("#define %s\t\t%i\n",VALTAG1,NextVal); HFile.Insert(strpos,str); strpos=RemoveLineContaining(HFile,VALTAG2); Verify(strpos>=0); str.Format("#define %s\t\t%i\n",VALTAG2,NextVal); HFile.Insert(strpos,str); } CString CLocalizerDlg::AddLocalizedString(CString mis_name,CString usname,CString sname) { mis_name.MakeUpper(); usname.MakeUpper(); CString idname; if(sname.GetLength()==0) sname=" "; idname="IDS_LC_"+mis_name+"_"+usname; idname.Replace(' ','_'); CString str; // sname.Replace("\"","\\\""); sname.Replace("\"","'"); str.Format("\t%s \"%s\"\n",idname,sname); if(str.Find("MissionLang")>=0) str=" "; RCFile.Insert(NextRCPos(),str); int myval; myval=IdList.GetID(idname); if(myval<0) { myval=IdList.NextFreeId(NextVal); NextVal=myval+1; } str.Format("#define %s\t\t\t%i\n",idname,myval); HFile.Insert(NextHPos(),str); return idname; } void CLocalizerDlg::RemoveMission(CString &mis_name) { mis_name.MakeUpper(); while(RemoveRCEntry(RCFile,"IDS_LC_"+mis_name)>=0); while(RemoveLineContaining(HFile,"IDS_LC_"+mis_name)>=0); } void CLocalizerDlg::LocalizeAll() { LoadLangRC(); CString misname; WIN32_FIND_DATA file_data; HANDLE mission_search = FindFirstFile("Content\\Missions\\*.*" , &file_data); if(mission_search != INVALID_HANDLE_VALUE) { do if(file_data.dwFileAttributes&FILE_ATTRIBUTE_DIRECTORY) { CString mis_name(file_data.cFileName); if(mis_name.CompareNoCase(".") && mis_name.CompareNoCase("..")) { misname=CString(file_data.cFileName); Localize(misname); } } while (FindNextFile(mission_search,&file_data)); } SaveLangRC(); LocalizeCampaigns(); } void CLocalizerDlg::LocalizeCampaigns() { LoadLangRC(); RemoveMission(CString("Campaign")); NextVal=FindSlotFor("Campaign"); CString misname; WIN32_FIND_DATA file_data; HANDLE mission_search = FindFirstFile("Content\\Campaigns\\*.contents" , &file_data); if(mission_search != INVALID_HANDLE_VALUE) { do { LocalizeCampCon(file_data.cFileName); } while (FindNextFile(mission_search,&file_data)); } mission_search = FindFirstFile("Content\\Campaigns\\*.campaign" , &file_data); if(mission_search != INVALID_HANDLE_VALUE) { do { LocalizeCampCon(file_data.cFileName); } while (FindNextFile(mission_search,&file_data)); } SaveLangRC(); } void CLocalizerDlg::LocalizeCampCon(CString str) { CString contents_path="Content\\Campaigns\\"+str; NotationFile note_file(contents_path,NotationFile::Standard,true); NotationFile::PageIterator *pages=note_file.MakePageIterator(); Page *page; const char *text; CString stringid,btname; btname=str.Left(str.ReverseFind('.')); CString pname; while(page=pages->ReadAndNext()) { pname=page->GetName(); int loc=pname.ReverseFind('.'); if(loc>0) { pname=pname.Left(loc); } loc=pname.ReverseFind('\\'); if(loc>0) { pname=pname.Mid(loc+1); } if(page->GetEntry("DisplayNameText",&text)) { stringid=AddLocalizedString("Campaign",btname+pname+"DisplayName",text); stringid="$("+stringid+")"; page->SetEntry("DisplayNameIndex",stringid); } if(page->GetEntry("PointNameText",&text)) { stringid=AddLocalizedString("Campaign",btname+pname+"PointName",text); stringid="$("+stringid+")"; page->SetEntry("PointNameIndex",stringid); } if(page->GetEntry("RolloverText",&text)) { stringid=AddLocalizedString("Campaign",btname+pname+"Rollover",text); stringid="$("+stringid+")"; page->SetEntry("RolloverIndex",stringid); } if(page->GetEntry("RightClickText",&text)) { stringid=AddLocalizedString("Campaign",btname+pname+"RightClick",text); stringid="$("+stringid+")"; page->SetEntry("RightClickIndex",stringid); } } note_file.Save(); FileStream fstream; fstream.Open(contents_path,FileStream::WriteOnly); fstream<<"!Include=Content\\Defines\\MissionLang.defines\x0D\x0A"; fstream<<"!concatenate=no\x0D\x0A"; fstream<<"!preservecase=yes\x0D\x0A\x0D\x0A"; note_file.Write(&fstream); fstream.Close(); } int CLocalizerDlg::RemoveLineContaining(CString &base,CString contains) { int strpos=base.Find(contains); if(strpos>=0) { do strpos--; while(strpos>=0 && base[strpos]!='\n'); strpos++; int eol=base.Find('\n',strpos); if(eol<0) eol=base.GetLength(); base.Delete(strpos,(eol-strpos)+1); } return strpos; } int CLocalizerDlg::RemoveRCEntry(CString &base,CString contains) { int q=0; //if(base!=LastRCSearch) LastRCSlot=-1; int strpos=base.Find(contains); //LastRCSlot=strpos; //LastRCSearch=contains; if(strpos>=0) { do strpos--; while(strpos>=0 && base[strpos]!='\n'); strpos++; int endquote=base.Find('"',strpos); Verify(endquote>=0); do { endquote++; endquote=base.Find('"',endquote); endquote++; } while(base[endquote]=='"'); while(base[endquote]=='\n') endquote++; base.Delete(strpos,endquote-strpos); } return strpos; } void CLocalizerDlg::LoadLangRC() { DWORD bread; char *buf; int bufsize; HANDLE fhan; fhan=CreateFile("Code\\MissionLang\\MissionLangScript.rc",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); Verify(fhan!=INVALID_HANDLE_VALUE); bufsize=GetFileSize(fhan,NULL); buf=new char[bufsize+1]; ReadFile(fhan,buf,bufsize,&bread,NULL); CloseHandle(fhan); buf[bufsize]=0; RCFile=buf; Verify(RCFile.GetLength()==bufsize); delete buf; fhan=CreateFile("Code\\MissionLang\\resource.h",GENERIC_READ,FILE_SHARE_READ,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); Verify(fhan!=INVALID_HANDLE_VALUE); bufsize=GetFileSize(fhan,NULL); buf=new char[bufsize+1]; ReadFile(fhan,buf,bufsize,&bread,NULL); CloseHandle(fhan); buf[bufsize]=0; HFile=buf; Verify(HFile.GetLength()==bufsize); delete buf; NextVal=NextHVal(); RCFile.Replace("\x0D\x0A","\n"); HFile.Replace("\x0D\x0A","\n"); GetTagList(); } void CLocalizerDlg::GetTagList() { int lastpos=0; CString substr,numstr; int eof=HFile.Find("APSTUDIO_READONLY_SYMBOLS"); while(lastpos!=-1 && lastpos=0 && lastposReadAndNext()) != NULL) { Check_Object(entity_page); if(entity_page->FindNote("DoesHaveInstanceName")) { entity_page->GetEntry("DoesHaveInstanceName",&dhiname); if(dhiname) count++; } if(entity_page->FindNote("failtextstr") ) count++; if(entity_page->FindNote("succeedtextstr") ) count++; if(entity_page->FindNote("neutraltextstr") ) count++; if(entity_page->FindNote("descriptextstr") ) count++; } return count; } #define LOWESTVAL 2000 #define ENDDEFSECTION "#ifdef APSTUDIO_INVOKED" int CLocalizerDlg::FindSlotFor(CString misname) { NotationFile ldfile("Content\\Missions\\Localize.Info"); Page *page=ldfile.SetPage("MissionData"); Check_Object(page); bool found=false; int val,hival; hival=LOWESTVAL; Page::NoteIterator *notelist=page->MakeNoteIterator(); Check_Object(notelist); notelist->First(); Note *note; CString notename; while((note=(Note *)notelist->ReadAndNext()) && !found) { notename=note->GetName(); note->GetEntry(&val); hival=hival>val?hival:val; if(!notename.CompareNoCase(misname)) found=true; } if(!found) { val=hival+MISSIONSLOTSIZE; page->SetEntry(misname,val); } ldfile.Save(); return val; } int CLocalizerDlg::GetHighestVal() { int strpos,valcount,val; int veof=HFile.Find(ENDDEFSECTION); Verify(veof>=0); strpos=0; valcount=0; do { strpos=HFile.Find("#define",strpos)+1; valcount++; } while(strpos>-1 && strpos=0); strpos+=strlen("#define"); if(strposhighestval) highestval=valarray[val]; return highestval; } void CLocalizerDlg::SaveLangRC() { HANDLE fhan; DWORD bread; SetHNextVals(); RCFile.Replace("\n","\x0D\x0A"); HFile.Replace("\n","\x0D\x0A"); fhan=CreateFile("Code\\MissionLang\\MissionLangScript.rc",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); Verify(fhan!=INVALID_HANDLE_VALUE); WriteFile(fhan,RCFile.GetBuffer(0),RCFile.GetLength(),&bread,NULL); CloseHandle(fhan); fhan=CreateFile("Code\\MissionLang\\resource.h",GENERIC_WRITE,0,NULL,CREATE_ALWAYS,FILE_ATTRIBUTE_NORMAL,NULL); Verify(fhan!=INVALID_HANDLE_VALUE); WriteFile(fhan,HFile.GetBuffer(0),HFile.GetLength(),&bread,NULL); CloseHandle(fhan); } void TagList::AddTag(CString str,int id) { int curid=FindIDIndex(id); if(curid>=0 && Tags[curid]!=str) PAUSE(("ID %i already taken by %s",id,(LPCSTR)Tags[curid])); Tags[TagTot]=str; IDs[TagTot]=id; TagTot++; } int TagList::GetID(CString str) { int idx=FindStringIndex(str); if(idx<0) return idx; return IDs[idx]; } int TagList::FindStringIndex(CString str) { int i; for(i=0;i=0) start++; return start; }