// NodeDataValueFileDoc.cpp : implementation file // #include "stdafx.h" #include "ContentTrack.h" #include "NodeDataValueFileDoc.h" #include "DialogPasteRename.h" #include #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE static char THIS_FILE[] = __FILE__; #endif CString g_szbrowsepath; int CALLBACK BrowseCallbackProc(HWND hWnd, UINT uMsg, LPARAM lParam, LPARAM lpData) { RECT rect; // //Center the browse dialog on the screen... // switch (uMsg) { case BFFM_INITIALIZED: { SendMessage(hWnd,BFFM_SETSELECTION,TRUE,(LPARAM)(LPCTSTR)g_szbrowsepath); if (GetWindowRect(hWnd, &rect)) { SetWindowPos(hWnd, HWND_TOP, (GetSystemMetrics(SM_CXSCREEN) - (rect.right - rect.left)) >> 1, (GetSystemMetrics(SM_CYSCREEN) - (rect.bottom - rect.top)) >> 1, 0, 0, SWP_NOSIZE); } } } return 0; } CString BrowseDirectory(const char *strCurrent,CWnd *pWnd) { CString str; TCHAR szBuffer[MAX_PATH]; LPITEMIDLIST pidlBrowse,pidlRoot; BROWSEINFO bi; LPMALLOC lpMalloc; SHGetMalloc(&lpMalloc); ASSERT(lpMalloc); bi.hwndOwner = pWnd->GetSafeHwnd(); // Get the ID for the "My Computer" root folder SHGetSpecialFolderLocation(pWnd->GetSafeHwnd(),CSIDL_DRIVES,&pidlRoot); bi.pidlRoot = pidlRoot; bi.pszDisplayName = szBuffer; // Localize the descriptive text bi.lpszTitle = "Select a MW4 Game Root folder. This folder should should have a Contents subdirectory."; // BIF_EDITBOX and BIF_VALIDATE are for versions 4.71 and later, they // might be ignored by older versions bi.ulFlags = BIF_RETURNONLYFSDIRS | BIF_STATUSTEXT;// | BIF_EDITBOX;// | BIF_USENEWUI;// | BIF_VALIDATE; bi.lParam = (LPARAM)pWnd; bi.iImage = NULL; bi.lpfn = BrowseCallbackProc; bi.lParam = (LPARAM)strCurrent; g_szbrowsepath = strCurrent; // //Call the Windows shell folder browsing routine... // pidlBrowse = SHBrowseForFolder(&bi); if (NULL != pidlBrowse) { if (SHGetPathFromIDList(pidlBrowse, szBuffer)) { if ('\\' == szBuffer[lstrlen(szBuffer)-1]) szBuffer[lstrlen(szBuffer)-1] = '\0'; str = CString(szBuffer); } else str = ""; // //Free up shell memory used... // lpMalloc->Free(pidlBrowse); } else str = ""; lpMalloc->Free(pidlRoot); lpMalloc->Release(); return str; } ///////////////////////////////////////////////////////////////////////////// // CNodeDataValueFileDoc IMPLEMENT_DYNCREATE(CNodeDataValueFileDoc, CContentTrackDoc) CNodeDataValueFileDoc::CNodeDataValueFileDoc() { m_pNodeDataValueFileProject = NULL; m_pNodeDirectory = NULL; m_pActiveChild = NULL; m_iReplaceAll = -1; } BOOL CNodeDataValueFileDoc::OnNewDocument() { if (!CContentTrackDoc::OnNewDocument()) return FALSE; /* CFileDialog dlg(false,"*.project",NULL,OFN_HIDEREADONLY | OFN_OVERWRITEPROMPT,"*.project",NULL); if (IDOK == dlg.DoModal()) { m_pNodeDataValueFileProject = new CNodeDataValueFileProject(NULL,dlg.GetPathName()); return TRUE; }*/ char buf[MAX_PATH]; GetCurrentDirectory(MAX_PATH,buf); CString path = BrowseDirectory(buf,NULL); if (path.GetLength()) { CString contentpath = path+"\\content"; DWORD attrib = ::GetFileAttributes(contentpath); if (-1 == attrib) { // File does not exist CString str = "Game root folder "+path+" does not have a Contents directory. Do you want to continue? A Contents directory will be created."; if (IDNO == MessageBox(NULL,str,"Create New Workspace",MB_YESNO)) return false; } // Scan the content directory SetCurrentDirectory(path); m_strRoot = path; // Scan the content directory CreateDirectory(contentpath,NULL); CFrameWnd *pFrame = (CFrameWnd *)AfxGetMainWnd(); pFrame->SetMessageText("Scanning Content directory..."); this->m_pNodeDirectory = new CNodeDiskDirectory(NULL,/*path+"\\*/"content"); m_pNodeDataValueFileProject = new CNodeDataValueFileProject(this,path); m_pNodeDirectory->SetParentNode(m_pNodeDataValueFileProject); return TRUE; } return FALSE; } CNodeDataValueFileDoc::~CNodeDataValueFileDoc() { if (m_pNodeDataValueFileProject) delete m_pNodeDataValueFileProject; m_pNodeDataValueFileProject = NULL; if (m_pNodeDirectory) delete m_pNodeDirectory; m_pNodeDirectory = NULL; } BEGIN_MESSAGE_MAP(CNodeDataValueFileDoc, CContentTrackDoc) //{{AFX_MSG_MAP(CNodeDataValueFileDoc) ON_COMMAND(ID_ADDROOT, OnAddroot) ON_COMMAND(ID_FILE_SAVE, OnFileSave) ON_COMMAND(ID_FILE_SAVE_AS, OnFileSaveAs) ON_COMMAND(ID_EDIT_COPY, OnEditCopy) ON_COMMAND(ID_EDIT_PASTE, OnEditPaste) ON_COMMAND(ID_EDIT_PASTE_RENAME, OnEditPasteRename) //}}AFX_MSG_MAP END_MESSAGE_MAP() ///////////////////////////////////////////////////////////////////////////// // CNodeDataValueFileDoc diagnostics #ifdef _DEBUG void CNodeDataValueFileDoc::AssertValid() const { CContentTrackDoc::AssertValid(); } void CNodeDataValueFileDoc::Dump(CDumpContext& dc) const { CContentTrackDoc::Dump(dc); } #endif //_DEBUG ///////////////////////////////////////////////////////////////////////////// // CNodeDataValueFileDoc serialization void CNodeDataValueFileDoc::Serialize(CArchive& ar) { if (ar.IsStoring()) { // TODO: add storing code here } else { // TODO: add loading code here } } ///////////////////////////////////////////////////////////////////////////// // CNodeDataValueFileDoc commands extern int IdentifyFileType(CString path); BOOL CNodeDataValueFileDoc::OnOpenDocument(LPCTSTR lpszPathName) { // if (!CContentTrackDoc::OnOpenDocument(lpszPathName)) // return FALSE; CFrameWnd *pFrame = (CFrameWnd *)AfxGetMainWnd(); if (this->m_pNodeDataValueFileProject) { this->m_pActiveChild = NULL; pFrame->SetMessageText("Updating..."); m_pNodeDataValueFileProject->Update(); m_pNodeDataValueFileProject->ResetVisitAll(); this->UpdateAllViews(NULL,NULL,NULL); pFrame->SetMessageText("Ready."); //TODO: Clear the dirty bits return TRUE; } NotationFile notefile(lpszPathName); Page *page = notefile.GetPage("Project"); if (NULL == page) return FALSE; Check_Object(page); const char *path; if (!page->GetEntry("Path",&path)) return FALSE; SetCurrentDirectory(path); m_strRoot = path; // Scan the content directory CreateDirectory(CString(path)+"\\content",NULL); pFrame->SetMessageText("Scanning Content directory..."); this->m_pNodeDirectory = new CNodeDiskDirectory(NULL,/*CString(path)+"\\*/"content"); m_pNodeDataValueFileProject = new CNodeDataValueFileProject(this,path); m_pNodeDirectory->SetParentNode(m_pNodeDataValueFileProject); page = notefile.GetPage("Roots"); 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); if (0 == (strnicmp(entry->GetName(),"Path",4))) { const char *newpath; entry->GetEntry(&newpath); CString fullpath = CString(path)+"\\"+newpath; CNodeObject *pNode = CNodeData::CreateChild(m_pNodeDataValueFileProject,IdentifyFileType(fullpath),newpath); m_pNodeDataValueFileProject->AddChild(pNode); } } Check_Object(entries); delete entries; } return TRUE; } CNodeDisk *CNodeDataValueFileDoc::FindDirectoryNode(CString strName) { return FindDirectoryNode(strName,GetRootNode()); } CNodeDisk *CNodeDataValueFileDoc::FindDirectoryNode(CString strName,CNodeDisk *pNode) { #if 0 if (strName.GetLength() ==0) return NULL; if (strName[0] == '\\') strName.Delete(0,1); CString strDir = pNode->GetName(); int iLen = strDir.GetLength(); if (strnicmp(strDir,strName,iLen)==0) { strName.Delete(0,iLen); if (strName.IsEmpty()) // we found it return pNode; strName.Delete(0,1); POSITION pos = pNode->GetFirstChild(); while (pos) { if (out_pos) *out_pos = pos; CNodeDisk *pChild = (CNodeDisk *)pNode->GetNextChild(pos); CNodeDisk *pRet = FindDirectoryNode(strName,pChild,out_pos); if (pRet) return pRet; } } return NULL; #endif char *src_name = (char *)(LPCTSTR)strName; // int src_size = strName.GetLength(); char dir_name[MAX_PATH]; //char *dir_name = (char *)(LPCTSTR)pNode->GetName(); pNode->GetName(dir_name,MAX_PATH); // int dir_size = pNode->GetName().GetLength(); // this isn't really necessary since the last character in src_name is '\0' // and the loop below will exit there too // if (src_size < dir_size) // return NULL; //for (int x=0;xGetFirstChild(); while (pos) { CNodeDisk *pChild = (CNodeDisk *)pNode->GetNextChild(pos); CNodeDisk *pRet = FindDirectoryNode(src_name,pChild); if (pRet) return pRet; } } // We found some other characters in the name, so it doesn't match. return NULL; } // Means the names match and we found the right node return pNode; } void CNodeDataValueFileDoc::OnAddroot() { CFileDialog dlg(true); CString str; this->m_pNodeDataValueFileProject->GetName(str); dlg.m_ofn.lpstrInitialDir = str; if (IDOK == dlg.DoModal()) { //m_pNodeDataValueFileProject = new CNodeDataValueFileProject(NULL,dlg.GetPathName()); CString path = dlg.GetPathName(); CString dir; m_pNodeDataValueFileProject->GetName(dir); if (strnicmp(dir,path,dir.GetLength())) { // Error - the new root file must be in a subdir of the project path MessageBox(NULL,"Error: The new root file must be in a subdir of the project path!","Error",MB_OK); return; } CString newpath = path.Right(path.GetLength()-dir.GetLength()-1); SetCurrentDirectory(dir); CNodeObject *pNode = CNodeData::CreateChild(m_pNodeDataValueFileProject,IdentifyFileType(path),newpath); m_pNodeDataValueFileProject->AddChild(pNode); // m_pNodeDataValueFileProject->Update(); this->UpdateAllViews(NULL,NULL,NULL); } } void CNodeDataValueFileDoc::OnFileSave() { CString fname = GetPathName(); if (0 == fname.GetLength()) { OnFileSaveAs(); return; } NotationFile notefile; Page *page = notefile.AddPage("Project"); CString str; m_pNodeDataValueFileProject->GetName(str); page->AppendEntry("Path",str); page = notefile.AddPage("Roots"); POSITION pos = m_pNodeDataValueFileProject->GetFirstChild(); while (pos) { CNodeObject *pnode = m_pNodeDataValueFileProject->GetNextChild(pos); CString str; pnode->GetName(str); page->AppendEntry("Path",str); } notefile.SaveAs(GetPathName()); } void CNodeDataValueFileDoc::OnFileSaveAs() { CFileDialog dlg(false); if (IDOK == dlg.DoModal()) { this->SetPathName(dlg.GetPathName()); OnFileSave(); } } void CNodeDataValueFileDoc::OnEditCopy() { ((CContentTrackApp *)AfxGetApp())->m_pNodeSelected = m_pActiveChild; } void CNodeDataValueFileDoc::OnEditPaste() { CNodeObject *pSelected = ((CContentTrackApp *)AfxGetApp())->m_pNodeSelected; CNodeObject *pClone = _OnEditPaste(pSelected); if (pClone) this->UpdateAllViews(NULL,NULL,NULL); } CNodeObject *CNodeDataValueFileDoc::_OnEditPaste(CNodeObject *pSelected,CString oldName,CString newName) { this->m_iReplaceAll = -1; // Paste the copied node as a child of the selected node CNodeObject *pChild = m_pActiveChild?m_pActiveChild:this->GetNodeProject(); CNodeObject *pClone = NULL; if (pSelected&&pChild) { pClone = pSelected->Clone(pChild,oldName,newName); pChild->AddChild(pClone); this->GetRootNode()->ResetVisitAll(); } return pClone; } int VisitTreeFiles(CNodeObject *pNode) { int count = 0; if (NULL == pNode) return 0; bool bvisited = false; if (pNode->IsFile()) { CNodeDisk *pDisk= ((CNodeDataValueFile*)pNode)->GetNodeDisk(); bvisited = pDisk->GetVisit(VISIT_FLAG1); if (!bvisited) { pDisk->SetVisit(VISIT_FLAG1); count++; } } if (!bvisited) { POSITION pos = pNode->GetFirstChild(); while (pos) { CNodeObject *pChild = pNode->GetNextChild(pos); count += VisitTreeFiles(pChild); } } return count; } void CNodeDataValueFileDoc::OnEditPasteRename() { CNodeObject *pSelected = ((CContentTrackApp *)AfxGetApp())->m_pNodeSelected; CDialogPasteRename dlg; if (pSelected&&(IDOK == dlg.DoModal())) { CString newName = dlg.m_strNew; CString oldName = dlg.m_strOld; CNodeObject *pNode = pSelected; while (pNode && (!pNode->IsFile())) pNode = pNode->GetParentNode(); VisitTreeFiles(pNode); CNodeObject *pClone = _OnEditPaste(pSelected,oldName,newName); this->UpdateAllViews(NULL,NULL,NULL); } }