// ChildFrm.cpp : implementation of the CChildFrame class // #include "stdafx.h" #include "ContentTrack.h" #include "ChildFrm.h" #include "ContentTrackDoc.h" #include "ContentTrackView.h" #include "NodeDataValueFileDoc.h" #include "nodeobjectreferenceview1.h" #include "findview.h" #include "UnusedFilesView.h" #include "MissingFilesView.h" #include "DirectoryView.h" #include "WizCopyMission.h" #include "WizPageProject.h" #include "WizPageMission.h" #include "DlgCreateMap.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif extern CString ReplaceNoCase(CString input,CString strOld,CString strNew,int *pCount = NULL); ///////////////////////////////////////////////////////////////////////////// // CChildFrame IMPLEMENT_DYNCREATE(CChildFrame, CMDIChildWnd) BEGIN_MESSAGE_MAP(CChildFrame, CMDIChildWnd) //{{AFX_MSG_MAP(CChildFrame) ON_COMMAND(ID_REFERENCES, OnReferences) ON_COMMAND(ID_FILE_NEW, OnFileNew) ON_COMMAND(ID_FIND, OnFind) ON_COMMAND(ID_MISSINGFILES, OnMissingfiles) ON_COMMAND(ID_UNUSEDFILES, OnUnusedfiles) ON_COMMAND(ID_WIZ_COPYMISSION, OnWizCopymission) ON_COMMAND(ID_DIRECTORY, OnDirectory) ON_COMMAND(ID_WIZ_CREATEMAP, OnWizCreatemap) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CChildFrame construction/destruction CChildFrame::CChildFrame() { // TODO: add member initialization code here } CChildFrame::~CChildFrame() { } BOOL CChildFrame::PreCreateWindow(CREATESTRUCT& cs) { // TODO: Modify the Window class or styles here by modifying // the CREATESTRUCT cs if( !CMDIChildWnd::PreCreateWindow(cs) ) return FALSE; return TRUE; } ///////////////////////////////////////////////////////////////////////////// // CChildFrame diagnostics #ifdef _DEBUG void CChildFrame::AssertValid() const { CMDIChildWnd::AssertValid(); } void CChildFrame::Dump(CDumpContext& dc) const { CMDIChildWnd::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CChildFrame message handlers void CChildFrame::OnReferences() { // Create a new view of this document that contains a tree of the references from the selected node /* CNodeDataValueFileDoc *pDoc = (CNodeDataValueFileDoc *)GetActiveDocument(); CTreeCtrl *pCtrl = &this->GetTreeCtrl(); pDoc->GetNode()->ViewNode(pCtrl,NULL,2); CView *pView = GetActiveView(); // If the view is a splitter window then */ /*m_wndSplitter.SplitColumn(1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CView),CSize(100,100),NULL); m_wndSplitter.RecalcLayout();*/ CCreateContext cc; memset(&cc, sizeof(cc), 0); cc.m_pNewViewClass = RUNTIME_CLASS(CNodeObjectReferenceView); cc.m_pCurrentDoc = GetActiveDocument(); cc.m_pNewDocTemplate = cc.m_pCurrentDoc ? cc.m_pCurrentDoc->GetDocTemplate() : NULL; cc.m_pCurrentFrame = this; m_wndSplitter.DeleteView(0,1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CNodeObjectReferenceView),CSize(0,0),&cc); m_wndSplitter.SetActivePane(0,1); // initialize the view CView *pView = (CView *)m_wndSplitter.GetPane(0,1); if (pView) pView->OnInitialUpdate(); m_wndSplitter.RecalcLayout(); // recompute layout //m_wndSplitter.RedrawWindow(); } BOOL CChildFrame::OnCreateClient(LPCREATESTRUCT lpcs, CCreateContext* pContext) { if (m_wndSplitter.CreateStatic(this,1,2)) { m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(300,100),pContext); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CContentTrackView),CSize(10,10),pContext); return TRUE; } return FALSE; /* if (m_wndSplitter.Create(this,2,2,CSize(10,10),pContext)) { m_wndSplitter.SetRowInfo(0,200,10); m_wndSplitter.SetColumnInfo(0,200,10); return true; } return false; /* m_wndSplitter.CreateView(0,0,pContext->m_pNewViewClass,CSize(10,10),pContext); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CView),CSize(10,10),pContext); m_wndSplitter.CreateView(1,0,RUNTIME_CLASS(CView),CSize(10,10),pContext); m_wndSplitter.CreateView(1,1,RUNTIME_CLASS(CView),CSize(10,10),pContext); //m_wndSplitter.RecalcLayout();*/ // return CMDIChildWnd::OnCreateClient(lpcs, pContext); } void CChildFrame::OnFileNew() { CDocTemplate *pDocTemplate = (CDocTemplate *) ((CContentTrackApp *)AfxGetApp())->m_mapTemplates[ID_FILE_OPEN]; pDocTemplate->OpenDocumentFile(NULL); } void CChildFrame::OnFind() { CCreateContext cc; memset(&cc, sizeof(cc), 0); cc.m_pNewViewClass = RUNTIME_CLASS(CFindView); cc.m_pCurrentDoc = GetActiveDocument(); cc.m_pNewDocTemplate = cc.m_pCurrentDoc ? cc.m_pCurrentDoc->GetDocTemplate() : NULL; cc.m_pCurrentFrame = this; m_wndSplitter.DeleteView(0,1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CFindView),CSize(0,0),&cc); m_wndSplitter.SetActivePane(0,1); // initialize the view CView *pView = (CView *)m_wndSplitter.GetPane(0,1); if (pView) pView->OnInitialUpdate(); m_wndSplitter.RecalcLayout(); // recompute layout } void CChildFrame::OnMissingfiles() { CCreateContext cc; memset(&cc, sizeof(cc), 0); cc.m_pNewViewClass = RUNTIME_CLASS(CMissingFilesView); cc.m_pCurrentDoc = GetActiveDocument(); cc.m_pNewDocTemplate = cc.m_pCurrentDoc ? cc.m_pCurrentDoc->GetDocTemplate() : NULL; cc.m_pCurrentFrame = this; m_wndSplitter.DeleteView(0,1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CMissingFilesView),CSize(0,0),&cc); m_wndSplitter.SetActivePane(0,1); // initialize the view CView *pView = (CView *)m_wndSplitter.GetPane(0,1); if (pView) pView->OnInitialUpdate(); m_wndSplitter.RecalcLayout(); // recompute layout } void CChildFrame::OnUnusedfiles() { CCreateContext cc; memset(&cc, sizeof(cc), 0); cc.m_pNewViewClass = RUNTIME_CLASS(CUnusedFilesView); cc.m_pCurrentDoc = GetActiveDocument(); cc.m_pNewDocTemplate = cc.m_pCurrentDoc ? cc.m_pCurrentDoc->GetDocTemplate() : NULL; cc.m_pCurrentFrame = this; m_wndSplitter.DeleteView(0,1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CUnusedFilesView),CSize(0,0),&cc); m_wndSplitter.SetActivePane(0,1); // initialize the view CView *pView = (CView *)m_wndSplitter.GetPane(0,1); if (pView) pView->OnInitialUpdate(); m_wndSplitter.RecalcLayout(); // recompute layout } // Add all the other "stuff" to resources.build - buildings, vehicles, etc... int AddResources(CNodeDisk *pNode,CStringList *pList) { int count = 0; static CStringList staticList; static int firsttime = 1; if (firsttime) { firsttime = 0; // This is the first time, so initialize the staticList staticList.RemoveAll(); staticList.AddHead("players\\"); staticList.AddHead("maps\\"); staticList.AddHead("buildings\\"); staticList.AddHead("weapons\\"); staticList.AddHead("weaponsubsystems\\"); staticList.AddHead("mechs\\"); staticList.AddHead("vehicles\\"); staticList.AddHead("dropzones\\"); } //if (pNode->IsFile()) { //CNodeDataValueFile *pFile = (CNodeDataValueFile *)pNode; CNodeDisk *pDisk = pNode;//->GetNodeDisk(); if (pDisk) { CString strPath = pDisk->GetPath(); if (strPath.GetLength()) { if (strPath[0] == '\\') strPath.Delete(0,1); //strPath.MakeLower(); CString ext = strPath.Right(5); //if (ext == CString(".data")) if (0 == strnicmp(ext,".data",5)) { if (strnicmp(strPath,"content\\",8)==0) strPath.Delete(0,8); CString path = strPath; int index = path.Find('\\',0); if (index>=0) { path = path.Left(index+1); path.MakeLower(); if (staticList.Find(path)) { if (NULL == pList->Find(strPath)) { pList->AddHead(strPath); count++; } } } } } } } POSITION pos = pNode->GetFirstChild(); while (pos) { CNodeObject *pChild = pNode->GetNextChild(pos); if ((pChild->GetClassID() == CLASS_CNODEDISKFILE) || (pChild->GetClassID() == CLASS_CNODEDISKDIRECTORY)) count += AddResources((CNodeDisk *)pChild,pList); } return count; } int VisitFiles(CNodeObject *pNode) { int count = 0; if (NULL == pNode) return 0; if (pNode->GetClassID() == CLASS_CNODEDISKDIRECTORY) { POSITION pos = pNode->GetFirstChild(); while (pos) { CNodeObject *pChild = pNode->GetNextChild(pos); count += VisitFiles(pChild); } } if (pNode->GetClassID() == CLASS_CNODEDISKFILE) { pNode->SetVisit(VISIT_FLAG1); count++; } return count; } void CChildFrame::OnWizCopymission() { CWizCopyMission dlg("Copy Mission Wizard",AfxGetMainWnd()); dlg.SetWizardMode(); CWizPageMission page1; dlg.AddPage(&page1); CWizPageProject page2; dlg.AddPage(&page2); if (ID_WIZFINISH == dlg.DoModal()) { CNodeObject *pNode = NULL; // Visit flags are used during cloning and should be cleared before we procede dlg.m_pSrcDoc->GetRootNode()->ResetVisitAll(); // Cloning flags used to show if we can copy this file dlg.m_pDstDoc->GetRootNode()->ResetVisitAll(); // Cloning flags used to show if this file has already been processed static int check1 = 1; if (check1) { // Mark the selected directories as Copy-Able POSITION pos = dlg.m_listCopyDir.GetHeadPosition(); while (pos) { //CObject *pObj = dlg.m_listCopyDir.GetNext(pos); CNodeObject *pChild = (CNodeObject *)dlg.m_listCopyDir.GetNext(pos);; VisitFiles(pChild); } CString str = "content\\textures\\maps\\"+dlg.m_strName; CNodeDisk *pTDisk = dlg.m_pSrcDoc->FindDirectoryNode(str); VisitFiles(pTDisk); } // Copy the data CNodeDataValueFileProject *pSrcProject = dlg.m_pSrcDoc->GetNodeProject(); CNodeDataValueFileProject *pDstProject = dlg.m_pDstDoc->GetNodeProject(); pNode = pSrcProject->CreateChild(pSrcProject,KEYTYPE_NOTE,"content\\"+dlg.m_strMission); pSrcProject->AddChild(pNode); // Copy the TCTD.INI specifically CNodeObject *pNodeTct = pSrcProject->CreateChild(pSrcProject,KEYTYPE_NOTE,"content\\maps\\"+dlg.m_strName+"\\tctd.ini"); pSrcProject->AddChild(pNodeTct); SetCurrentDirectory(dlg.m_pDstDoc->GetRootDir()); // Find the resource.build file in the destination. It can only be a direct child of the project CNodeDisk *pDiskResource = dlg.m_pDstDoc->FindDirectoryNode("content\\resources.build"); if (NULL == pDiskResource) { // Create destination resources.build // Content directory is assumed when using the rootnode pDiskResource = dlg.m_pDstDoc->GetRootNode()->DiskCopyFile("","resources.build"); } // This should copy/merge the files and add to destination project root CString strMission = dlg.m_strMission; CString newName; CString oldName; if (dlg.m_bRename) { newName = dlg.m_strRename; oldName = dlg.m_strName; int rcount;// = strMission.Replace(oldName,newName); CString output = ReplaceNoCase(strMission,oldName,newName,&rcount); if (rcount) { int x=1; } strMission = output; } CNodeObject *pCloneTct = dlg.m_pDstDoc->_OnEditPaste(pNodeTct,oldName,newName); CNodeObject *pClone = dlg.m_pDstDoc->_OnEditPaste(pNode,oldName,newName); // Update resources.build // First update the file static int check2 = 1; CStringList dataList,resList,addList,editorList; // dataList are the data members found in copy process // reslist are the dataList members found in the source resources.build // - dataList items are removed as they are added to resList // addList are the resList items that exist in the destination resources.build // - resList items are removed as they are added to addList // - the remaining reslist is the stuff to add to the destination resources.build // and should have 0 items if there is a rename in the same project int rescount = AddResources(dlg.m_pDstDoc->GetRootNode(),&dataList); // Copy this list cuz we do the same thing with resources as editor.build (sort of) editorList.AddHead(&dataList); // TODO: Remove the items in dataList that do not exist in the source resources.build { NotationFile notefile(*pSrcProject->GetRootPath()+"\\content\\resources.build"); Page *page = notefile.SetPage("resources\\main"); if (page) { Check_Object(page); Page::NoteIterator *entries = page->MakeNoteIterator(); Check_Object(entries); Note *entry; // Enumerate the entries in the section while ((entry = entries->ReadAndNext()) != NULL) { Check_Object(entry); CString key(entry->GetName()); //key.MakeLower(); const char *value; entry->GetEntry(&value); CString name1(value); CString name2(strMission); if (key == "data") { POSITION pos = dataList.Find(name1); if (pos) { CString data = dataList.GetAt(pos); resList.AddHead(data); dataList.RemoveAt(pos); } } } delete entries; } notefile.IgnoreChanges(); } // resources.build is not already loaded so we have to scan it manually if (gos_DoesFileExist("content\\resources.build")) { bool bFoundMap = false; bool bFoundMission =false; int resaddcount = 0; NotationFile notefile("content\\resources.build"); Page *page = notefile.SetPage("resources\\main"); if (page) { Check_Object(page); Page::NoteIterator *entries = page->MakeNoteIterator(); Check_Object(entries); Note *entry; // Enumerate the entries in the section while ((entry = entries->ReadAndNext()) != NULL) { Check_Object(entry); CString key(entry->GetName()); //key.MakeLower(); const char *value; entry->GetEntry(&value); CString name1(value); CString name2(strMission); //name1.MakeLower(); //name2.MakeLower(); if (0 == strnicmp(key,"instance",8)) //if (key == "instance") { //if (name1 == name2) if (0==strnicmp(name1,name2,name1.GetLength())) { bFoundMission = true; } } else if (key == "data") { // Map should be added automatically { POSITION pos = resList.Find(name1); if (pos) { resaddcount++; CString data = resList.GetAt(pos); addList.AddHead(data); resList.RemoveAt(pos); } } } } delete entries; if (!bFoundMission) { page->AppendEntry("instance",strMission); } // Only add entries to a new resources.build if it exists in the old one if (dlg.m_pDstDoc != dlg.m_pSrcDoc) { POSITION pos = resList.GetHeadPosition(); while (pos) { CString str = resList.GetNext(pos); page->AppendEntry("data",str); } } else { Verify(resList.GetCount() == 0); } if (!bFoundMap || !bFoundMission || (resaddcount>0)) { if (IDYES == MessageBox("Overwrite Resources.build?","Copy Mission",MB_YESNO)) { CString fname("content\\resources.build"); DWORD attrib = ::GetFileAttributes(fname); if (-1 != attrib) { if (attrib & FILE_ATTRIBUTE_READONLY) { attrib &= ~FILE_ATTRIBUTE_READONLY; ::SetFileAttributes(fname,attrib); } } notefile.Save(); } else notefile.IgnoreChanges(); } } else { // Error with setpage Verify(false); } } else { // Missing file!! Verify(false); } // Update the contenttracker if (pDiskResource->IsLoaded()) { // If we already loaded this file, we need to update the Node with the new data //Verify(false); } //CStringList edList; // TODO: find or create the destination editor.contents CNodeDisk *pSrcEditor = dlg.m_pSrcDoc->FindDirectoryNode("content\\editor\\editor.contents"); if (pSrcEditor) { // The source has an editor.contents //Verify(false); // Any model in the source's editor.content that was touched by the copy, copy it to editor.contents // Search the copy node for any notation file with a ".data" on the name. Split the path, // if the fname of the path exists in the editor.contents as a page title, copy that page NotationFile notefile(pSrcEditor->GetRootPath()+pSrcEditor->GetPath()); NotationFile::PageIterator *pages = notefile.MakePageIterator(); Check_Object(pages); Page *page; CNodeDisk *pEditor = dlg.m_pDstDoc->GetRootNode()->DiskCopyFile("","editor\\editor.contents"); NotationFile destfile(dlg.m_pDstDoc->GetRootDir()+pEditor->GetPath()); while (page = pages->ReadAndNext()) { CString name = page->GetName(); POSITION pos = editorList.Find(name); if (pos) { editorList.RemoveAt(pos); Page *destpage = destfile.SetPage(name); destpage->DeleteAllNotes(); Page::NoteIterator *notes = page->MakeNoteIterator(); Check_Object(notes); Note *note; notes->Last(); while (note = notes->ReadAndPrevious()) { const char *entry; note->GetEntry(&entry); destpage->AppendEntry(note->GetName(),entry); } delete notes; } } delete pages; notefile.IgnoreChanges(); destfile.Save(); } CNodeDisk *pDstEditor = dlg.m_pDstDoc->FindDirectoryNode("content\\editor\\editor.contents"); if (pDstEditor) { //dlg.m_pDstDoc->_OnEditPaste(pDstEditor,oldName,newName); } // ** We may want to remove these children from the project... or not dlg.m_pSrcDoc->UpdateAllViews(NULL,NULL,NULL); dlg.m_pDstDoc->UpdateAllViews(NULL,NULL,NULL); } } void CChildFrame::OnDirectory() { CCreateContext cc; memset(&cc, sizeof(cc), 0); cc.m_pNewViewClass = RUNTIME_CLASS(CDirectoryView); cc.m_pCurrentDoc = GetActiveDocument(); cc.m_pNewDocTemplate = cc.m_pCurrentDoc ? cc.m_pCurrentDoc->GetDocTemplate() : NULL; cc.m_pCurrentFrame = this; m_wndSplitter.DeleteView(0,1); m_wndSplitter.CreateView(0,1,RUNTIME_CLASS(CDirectoryView),CSize(0,0),&cc); m_wndSplitter.SetActivePane(0,1); // initialize the view CView *pView = (CView *)m_wndSplitter.GetPane(0,1); if (pView) pView->OnInitialUpdate(); m_wndSplitter.RecalcLayout(); // recompute layout } int VisitTreeFiles(CNodeObject *pNode); void CChildFrame::OnWizCreatemap() { CDlgCreateMap dlg; if (dlg.DoModal() == IDOK) { CString oldName; oldName.Format("%dkcontentmap",dlg.m_iSize); CString newName = dlg.m_strName; CNodeDataValueFileDoc *pDstDoc = (CNodeDataValueFileDoc *)this->GetActiveDocument(); CNodeDataValueFileProject *pDstProject = pDstDoc->GetNodeProject(); CDocTemplate *pDocTemplate = (CDocTemplate *) ((CContentTrackApp *)AfxGetApp())->m_mapTemplates[ID_FILE_OPEN]; CContentTrackApp *pApp = (CContentTrackApp *)AfxGetApp(); CString str = pApp->m_strRunDir+"\\template\\template.contenttrack"; CDocument *pNewDoc = pDocTemplate->OpenDocumentFile(str); VERIFY(pNewDoc->IsKindOf(RUNTIME_CLASS(CNodeDataValueFileDoc))); CNodeDataValueFileDoc *pSrcDoc = (CNodeDataValueFileDoc *)pNewDoc; CNodeDataValueFileProject *pSrcProject = pSrcDoc->GetNodeProject(); { CNodeObject *pSrcNode = pSrcProject->CreateChild(pSrcProject,KEYTYPE_NOTE,"content\\maps\\"+oldName+"\\"+oldName+".instance"); pSrcProject->AddChild(pSrcNode); VisitTreeFiles(pSrcNode); CNodeObject *pClone = pDstDoc->_OnEditPaste(pSrcNode,oldName,newName); } { CNodeObject *pSrcNode = pSrcProject->CreateChild(pSrcProject,KEYTYPE_ERF,"content\\skies\\"+oldName+"_sky\\"+oldName+"_sky.erf"); pSrcProject->AddChild(pSrcNode); VisitTreeFiles(pSrcNode); CNodeObject *pClone = pDstDoc->_OnEditPaste(pSrcNode,oldName,newName); } { CNodeObject *pSrcNode = pSrcProject->CreateChild(pSrcProject,KEYTYPE_NOTE,"content\\textures\\composttexture\\"+oldName+".index.tcf"); pSrcProject->AddChild(pSrcNode); VisitTreeFiles(pSrcNode); CNodeObject *pClone = pDstDoc->_OnEditPaste(pSrcNode,oldName,newName); } //pSrcProject->AddChild(pSrcNode); pSrcDoc->UpdateAllViews(NULL,NULL,NULL); pDstDoc->UpdateAllViews(NULL,NULL,NULL); } }