/** * Called when the material name has changed * @param pMaterial The material that was deleted. * @param oldName The old name of the material. */ void MaterialTreeView::MV_OnMaterialNameChanged( MaterialDoc *pMaterial, const char *oldName ) { CTreeCtrl &tree = GetTreeCtrl(); if( !internalChange ) { //Delete the old tree item HTREEITEM *item = NULL; materialToTree.Get( oldName, &item ); CTreeCtrl &tree = GetTreeCtrl(); HTREEITEM tempItem = *item; CleanLookupTrees( tempItem ); tree.DeleteItem( tempItem ); //Now add it back idStrList list( 1024 ); idMaterial *mat = pMaterial->renderMaterial; idStr temp; if( treeWithFile ) { idStr filename = mat->GetFileName(); filename.StripPath(); temp = idStr( mat->GetFileName() ) + "/" + idStr( mat->GetName() ) + "|" + filename; } else { temp = mat->GetName(); } list.Append( temp ); AddStrList( NULL, &list, treeWithFile ); //Keep the items sorted //item = NULL; materialToTree.Get( pMaterial->name.c_str(), &item ); if( *item ) { CTreeCtrl &tree = GetTreeCtrl(); HTREEITEM parent = tree.GetParentItem( *item ); tree.SortChildren( parent ); } MV_OnMaterialChange( pMaterial ); } }
/** * Cleans the lookup tables for the provided item and all children. * @param item The item to start from */ void MaterialTreeView::CleanLookupTrees(HTREEITEM item) { idStr qt = GetQuicktreePath(item); quickTree.Remove(qt); CTreeCtrl& tree = GetTreeCtrl(); //Clean special lookup tables DWORD type = tree.GetItemData(item); if(type == TYPE_FILE) { idStr file = GetMediaPath(item, TYPE_FILE); fileToTree.Remove(file); } else if(type == TYPE_MATERIAL) { idStr name = GetMediaPath(item, TYPE_MATERIAL); materialToTree.Remove(name); } //Clean all my children if(tree.ItemHasChildren(item)) { HTREEITEM childItem = tree.GetChildItem(item); while(childItem != NULL) { CleanLookupTrees(childItem); childItem = tree.GetNextSiblingItem(childItem); } } }
/** * Renames a material folder. * @param item The folder tree item. * @param name The new name of the material folder. */ void MaterialTreeView::RenameFolder( HTREEITEM item, const char *name ) { CTreeCtrl &tree = GetTreeCtrl(); //Clean up the quicktree with the current tree before we allow the edit to commit CleanLookupTrees( item ); //Store some data so the we can make the appropriate changes after the commit renamedFolder = item; affectedMaterials.Clear(); GetMaterialPaths( renamedFolder, &affectedMaterials ); tree.SetItemText( item, name ); PostMessage( MSG_RENAME_FOLDER_COMPLETE ); }
/** * Makes sure that a rename operation can be performed after a label edit is complete and * performs the folder or material rename. */ void MaterialTreeView::OnTvnEndlabeledit( NMHDR *pNMHDR, LRESULT *pResult ) { LPNMTVDISPINFO pTVDispInfo = reinterpret_cast<LPNMTVDISPINFO>( pNMHDR ); *pResult = 0; if( pTVDispInfo->item.pszText ) { //Convert any edited text to lower case to keep the name canonical idStr newLabel = pTVDispInfo->item.pszText; newLabel.ToLower(); strncpy( pTVDispInfo->item.pszText, newLabel.c_str(), pTVDispInfo->item.cchTextMax ); CTreeCtrl &tree = GetTreeCtrl(); DWORD type = tree.GetItemData( pTVDispInfo->item.hItem ); if( type == TYPE_MATERIAL ) { MaterialDoc *pMaterial = materialDocManager->GetCurrentMaterialDoc(); //Remove our old quick lookup value materialToTree.Remove( pMaterial->name.c_str() ); //Generate the new name idStr material; HTREEITEM parent = tree.GetParentItem( pTVDispInfo->item.hItem ); DWORD parentType = tree.GetItemData( parent ); if( parentType == TYPE_MATERIAL_FOLDER ) { //Need to include the material folder material = GetMediaPath( parent, TYPE_MATERIAL_FOLDER ); material += "/"; } material += pTVDispInfo->item.pszText; if( declManager->FindMaterial( material, false ) ) { //Can't rename because it conflicts with an existing file MessageBox( "Unable to rename material because it conflicts with another material", "Error" ); } else { //Add it to our quick lookup materialToTree.Set( material, pTVDispInfo->item.hItem ); //Finally make the change internalChange = true; pMaterial->SetMaterialName( material ); internalChange = false; renamedFolder = pTVDispInfo->item.hItem; PostMessage( MSG_RENAME_MATERIAL_COMPLETE ); *pResult = 1; } } else if( type == TYPE_MATERIAL_FOLDER ) { //Clean up the quicktree with the current tree before we allow the edit to commit CleanLookupTrees( pTVDispInfo->item.hItem ); //Store some data so the we can make the appropriate changes after the commit renamedFolder = pTVDispInfo->item.hItem; affectedMaterials.Clear(); GetMaterialPaths( renamedFolder, &affectedMaterials ); PostMessage( MSG_RENAME_FOLDER_COMPLETE ); RenameMaterialFolderModifier *mod = new RenameMaterialFolderModifier( materialDocManager, pTVDispInfo->item.pszText, this, pTVDispInfo->item.hItem, tree.GetItemText( pTVDispInfo->item.hItem ) ); materialDocManager->AddMaterialUndoModifier( mod ); *pResult = 1; } } }
/** * Called when a file has been reloaded * @param filename The file that was reloaded. */ void MaterialTreeView::MV_OnFileReload( const char *filename ) { HTREEITEM *fileItem = NULL; fileToTree.Get( filename, &fileItem ); HTREEITEM item = *fileItem; CTreeCtrl &tree = GetTreeCtrl(); CleanLookupTrees( item ); tree.DeleteItem( item ); BuildMaterialList( treeWithFile, filename ); //Resort the parent to make sure the file is back where it was HTREEITEM *newItem = NULL; fileToTree.Get( filename, &newItem ); if( *newItem ) { CTreeCtrl &tree = GetTreeCtrl(); HTREEITEM parent = tree.GetParentItem( *newItem ); tree.SortChildren( parent ); } }
/** * Deletes a given folder. * @param item The folder to delete. * @param addUndo True if this operation can be undone. */ void MaterialTreeView::DeleteFolder( HTREEITEM item, bool addUndo ) { CTreeCtrl &tree = GetTreeCtrl(); idList<MaterialTreeItem_t> materialsToDelete; //Get the complete list of materials to delete GetMaterialPaths( item, &materialsToDelete ); idStrList affectedMaterials; //Now delete the materials for( int i = 0; i < materialsToDelete.Num(); i++ ) { affectedMaterials.Append( materialsToDelete[i].materialName ); const idMaterial *material = declManager->FindMaterial( materialsToDelete[i].materialName ); MaterialDoc *pMaterial = NULL; pMaterial = materialDocManager->CreateMaterialDoc( const_cast<idMaterial *>( material ) ); materialDocManager->DeleteMaterial( pMaterial, false ); } //Make our undo modifier if( addUndo ) { DeleteMaterialFolderModifier *mod = new DeleteMaterialFolderModifier( materialDocManager, tree.GetItemText( item ), this, tree.GetParentItem( item ), &affectedMaterials ); materialDocManager->AddMaterialUndoModifier( mod ); } //Now clean up the folders and quicktree CleanLookupTrees( item ); //Remove any folders that were there tree.DeleteItem( item ); }