/** @file SelectionSetManager.cpp Selection Sets related functions. @COPYRIGHT @author Thomas Vissieres */ //////////////////////////////////////////////////////////////////////////////// // includes //////////////////////////////////////////////////////////////////////////////// #include "stdafx.h" #include "SelectionSetManager.h" #include "CKObjectManager.h" #include "CUIKNotifications.h" #ifndef macintosh #include "shlwapi.h"//for PathFileExists #include "Set_FileDialog.h" #else #include "UDisk.h" #include BOOL PathFileExists(const char* iPath) { struct stat result; char posix[_MAX_PATH]; UDisk::HFSToPosix(iPath,posix); int res = stat(posix,&result); return stat(posix,&result)==noErr; } #endif #include "VEP_VersionControlInfo.h" //version control #include "CKRenderContext.h" #include "SelectionSetParam.h" #define WEBDOWNLOAD //webdownload #ifdef WEBDOWNLOAD #if !defined(macintosh) #include "windows.h" #include "Wininet.h" #endif #include "WebServerManager.h" #include "WebManager.h" #endif //#include "CuikFileDialog.H" //#include "CUIKPluginManager.h" //#include "VEP_VersionControlInfo.h" //#include "MultiParamEditDlg.h" //#include "CUIKSchematicEditor.h" //#include "CheckForUnusedObjectsDlg.h" //tool func BOOL IsLocalPath(XString& path) { #ifndef macintosh if (path.Length()>4) if (path[1]==':') // C:\ - return TRUE; #else if (path.Length()>0) if (path[0]==DIRECTORY_SEP_CHAR) return TRUE; #endif return FALSE; } BOOL IsLocalPath(SelectionSetData* data) { if (data) return IsLocalPath(data->m_Path); return FALSE; } //////////////////////////////////////////////////////////////////////////////// // chunk identifiers //////////////////////////////////////////////////////////////////////////////// //#define RenderNow() (CKRenderContext*)m_Context->GetObject(m_RenderContext)->Render(); #define RenderNow() m_Context->SendInterfaceMessage(CKUIM_RENDERNOW,0,0); //////////////////////////////////////////////////////////////////////////////// // chunk identifiers //////////////////////////////////////////////////////////////////////////////// #define SELECTIONSET_CHUNK_SAVE_IDENTIFIER 0x0654f98ab #define SELECTIONSET_CHUNK_REBUILDHIERARCHY_IDENTIFIER 0x0654f98ad #define SELECTIONSET_DEPENDENCIES_CHUNK_SAVE_IDENTIFIER 0x0654f98ac #define SELECTIONSET_CHUNK_SAVEPARAMETERS_IDENTIFIER 0x0654f98ae //////////////////////////////////////////////////////////////////////////////// // message strings //////////////////////////////////////////////////////////////////////////////// #define STR_VIRTOOLS_SELECTIONSET_FILTER "Virtools SelectionSet (*.nmo)\0*.nmo\0\0" #define STR_SELECTIONSET_EXT "nmo" #define STR_SELECTIONSET_EXT2 "*.nmo" #define STR_SAVESETDLGTITLE "Save Selection Set <%s> as" #define STR_SETNOTSAVED "Selection Set <%s> was not saved as nmo because it is empty" #define STR_PRESAVEERROR "SelectionSet : presave error" #define STR_SAVEERROR "SelectionSet : save error" #define STR_LOADERROR "SelectionSet : load error" #define STR_LOADWARNING "Load External Selection Sets Warning" #define STR_SAVEWARNING "Save External Selection Sets Warning" #define STR_RUNTIMEWARNING "warning! This file contains runtime building blocks.\nPlease install the corresponding authoring building blocks,\nor you won't be able to save your modifications." #define STR_LOADINGFILE "Loading File" #define STR_PLEASAVEGROUP "Please save external set by saving the selection set group\n when manually imported, or within the composition" //#define STR_SELECTIONSET "Selection Set" #define STR_OBJECTS_REMOVED_ON_RELOAD "Objects were removed during reload,\nwould you like to check the unused object explorer?" #define STR_SETNOTUNLOADED "Selection Set <%s> was not unloaded because not saved" #define STR_UNNAMEDSET "Unnamed Set" #ifdef USE_DEPENDENCIES #define FILE_DEPENDENCIES_INI "SelSetDep.ini" #endif #define STR_SETENUM_NAME "Selection Set Flag" #define STR_EDITSETFLAGS "Edit " STR_SETENUM_NAME #define STR_PRIORITY "Priority" #define STR_EDITSETPRIORITY "Edit Set Priority" //option////////////////////////////////////////////////////////////////////////////// #define STR_INCLUDEOPTION0 "Outside composition" #define STR_INCLUDEOPTION1 "Inside composition" #define STR_INCLUDEOPTION2 "Force Outside composition" #define STR_INCLUDEOPTION3 "Force Inside composition" //extern CUIKLanguageManager theLM; //extern CUIKApp theCUIKApp; //extern CUIKCKObjectSaver theCUIKCKObjectSaver; //extern CuikPluginManager g_cuikPluginManager; //using namespace VirtoolsExternalPlugin; //using namespace CKControl; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetData::LoadDataFromChunk(CKStateChunk* iChunk,int iVersion) { if (iVersion>=2) { iChunk->ReadString(m_Name); m_Flags = iChunk->ReadDword(); iChunk->ReadString(m_Path); m_Priority = iChunk->ReadInt(); } else if (iVersion>=1) { iChunk->ReadString(m_Name); m_Flags = iChunk->ReadDword(); iChunk->ReadString(m_Path); m_Priority = iChunk->ReadInt(); #ifdef SELECTIONSET_USE_DEPENDENCIES GetSelectionSetManagerMacro(m_Context)->LoadDependenciesFromChunk(&m_SaveDependencies,iChunk);//read dependencies #else //fake buffer read int size = iChunk->ReadInt(); void* buffer=0; iChunk->ReadBuffer(&buffer); DWORD dw = iChunk->ReadDword(); CKDeletePointer(buffer); #endif } else//beta { m_Flags = iChunk->ReadDword(); iChunk->ReadString(m_Path); m_Priority = iChunk->ReadInt(); #ifdef SELECTIONSET_USE_DEPENDENCIES GetSelectionSetManagerMacro(m_Context)->LoadDependenciesFromChunk(&m_SaveDependencies,iChunk);//read dependencies #else //fake buffer read int size = iChunk->ReadInt(); void* buffer=0; iChunk->ReadBuffer(&buffer); DWORD dw = iChunk->ReadDword(); CKDeletePointer(buffer); #endif } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetData::CheckSaveExternal(SelectionSetManager* iSetMgr) { //remove the temp external flag ModifyFlags(0,fSetFlags_Temp_External); //check if we add fSetFlags_Temp_External according to pref BOOL external = FALSE; switch (iSetMgr->m_IncludeSelectionSetSaveOption) { case SelectionSetManager::eReferencesOriginalFiles: if (m_Flags & fSetFlags_ForceSaveAsExternal) external = TRUE; else if (m_Flags & fSetFlags_ForceSaveAsInternal) external = FALSE; else external = TRUE; break; case SelectionSetManager::eIncludeOriginalFiles: if (m_Flags & fSetFlags_ForceSaveAsExternal) external = TRUE; else if (m_Flags & fSetFlags_ForceSaveAsInternal) external = FALSE; else external = FALSE; break; case SelectionSetManager::eForceReferencesOriginalFiles: external = TRUE; break; case SelectionSetManager::eForceIncludeOriginalFiles: external = FALSE; break; } if (external) ModifyFlags(fSetFlags_Temp_External); return external; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetData::SaveDataInChunk(CKStateChunk* iChunk) { iChunk->WriteString(m_Name.CStr()); iChunk->WriteDword(m_Flags & ~fSetFlags_Temp_NotToSave); iChunk->WriteString(m_Path.CStr()); iChunk->WriteInt(m_Priority); #ifdef SELECTIONSET_USE_DEPENDENCIES GetSelectionSetManagerMacro(m_Context)->SaveDependenciesInChunk(&m_SaveDependencies,iChunk);//save dependencies #endif return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // SELECTION SET MANAGER //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// SelectionSetManager::SelectionSetManager(CKContext* iContext) : CKBaseManager(iContext,SELECTIONSETMANAGER_GUID,"SelectionSetManager") { //default options m_IncludeSelectionSetSaveOption = 1; //m_SaveExternalSetsOnCmoSave = 1; m_BackupOnSaveSet = 1; m_LastSavedSetID = 0; m_VCI = 0; m_LoadChunk = 0; m_Flags = 0; m_Context->RegisterNewManager(this); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// SelectionSetManager::~SelectionSetManager() { } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::UpdateLastDir(ELoadingMode iMode,CKSTRING iFilename) { XString oldDir = m_LastDir; BOOL updateLastDir = TRUE; switch(iMode) { case eUseLastLoadedCMO: m_LastDir = m_Context->GetLastCmoLoaded(); if (m_LastDir.Length()==0) { if (m_Context->m_LoadedFile && m_Context->m_LoadedFile->m_FileName) { m_LastFile = m_Context->m_LoadedFile->m_FileName; int dirIndex = m_LastFile.RFind(DIRECTORY_SEP_CHAR); if (dirIndex!=XString::NOTFOUND) { m_LastFile = m_LastFile.Substring(dirIndex+1,0); } } } break; case eUseLastSavedCMO: { XString lastCmo = m_Context->GetLastFileSaved(); CKPathSplitter sp(lastCmo.Str()); if(stricmp(sp.GetExtension(),".cmo")==0 || stricmp(sp.GetExtension(),".vmo")==0) m_LastDir = lastCmo; else return FALSE; } break; case ePostClearAll: m_LastDir = ""; return FALSE; case eUseParam: if (iFilename) { CKPathSplitter sp(iFilename); if(stricmp(sp.GetExtension(),".cmo")==0 || stricmp(sp.GetExtension(),".vmo")==0) m_LastDir = iFilename; else return FALSE; } else { m_LastDir = ""; return TRUE; } break; default: return TRUE; } //remove filename & keep only directory if (updateLastDir && m_LastDir.Length() && oldDir!=m_LastDir) { int dirIndex = m_LastDir.RFind(DIRECTORY_SEP_CHAR); if (dirIndex!=XString::NOTFOUND) { m_LastDir = m_LastDir.Substring(0,dirIndex+1); } //check external path to change them to relative path or not SelectionSetArray sets; GetSelectionSets(sets); for (int i=0;im_Path,TRUE); } } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::CKGroupToCKIDArray(XArray* iObjects,XArray* oIDs) { oIDs->Reserve(iObjects->Size()+1); XArray::Iterator it1 = iObjects->Begin(); XArray::Iterator it2 = iObjects->End(); while (it1!=it2) { CKObject* obj = *it1++; if (obj) oIDs->PushBack(obj->GetID()); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int SelectionSetManager::GetIncludeSelectionSetSaveOption() { return m_IncludeSelectionSetSaveOption; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::SetIncludeSelectionSetSaveOption(int iOption) { if (iOptionSendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_REFRESHVARIABLEMANAGER,0); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int SelectionSetManager::GetIncludeSelectionSetSaveOptionDescCount() { return eSelectionSetFlagsCount; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// char* SelectionSetManager::GetIncludeSelectionSetSaveOptionDesc(int i) { switch (i) { case eReferencesOriginalFiles: return STR_INCLUDEOPTION0; case eIncludeOriginalFiles: return STR_INCLUDEOPTION1; case eForceReferencesOriginalFiles: return STR_INCLUDEOPTION2; case eForceIncludeOriginalFiles: return STR_INCLUDEOPTION3; } return 0; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int SetCompareFunc(const void *elem1, const void *elem2 ) { CKGroup* grp1 = *(CKGroup**)elem1; CKGroup* grp2 = *(CKGroup**)elem2; int p1 = 0; int p2 = 0; SelectionSetData* data = (SelectionSetData*)grp1->GetAppData();//GetSelectionSetManagerMacro(m_Context)->GetSelectionSetData(grp1); if (data) p1 = data->m_Priority; data = (SelectionSetData*)grp2->GetAppData(); if (data) p2 = data->m_Priority; return p2-p1; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::GetSelectionSets(XArray& oSelectionSets,BOOL iSortedByPriority) { XArray sets; GetSelectionSets(sets,iSortedByPriority); CKGroupToCKIDArray(&sets,&oSelectionSets); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::GetSelectionSetByName(char* iName) { if (!iName) return 0; SelectionSetArray sets; GetSelectionSets(sets); SelectionSetIT it1=sets.Begin(),it2=sets.End(); while (it1!=it2) { CKGroup* grp = *it1++; if (grp->GetName()) if (stricmp(iName,grp->GetName())==0) return grp; } return 0; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::GetSelectionSets(XArray& oSelectionSets,BOOL iSortedByPriority) { CKLevel* level = m_Context->GetCurrentLevel(); if (!level) return; CKScene* scene = level->GetLevelScene(); if (!scene) return; XObjectPointerArray groupList = scene->ComputeObjectList(CKCID_GROUP); for (CKObject** oit = groupList.Begin(); oit != groupList.End(); ++oit) { CKGroup* grp=(CKGroup*)*oit; if (CheckIsSelectionSet(grp)) oSelectionSets.PushBack(grp); } if (iSortedByPriority) oSelectionSets.Sort(SetCompareFunc); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::AddObjectsToSet(CKGroup* iGrp,CKObjectArray* iArray) { if (!CheckIsSelectionSet(iGrp)) return FALSE; if (iGrp && iArray) { for (iArray->Reset();!iArray->EndOfList();iArray->Next()) { CKObject* obj = iArray->GetData(m_Context); if (CKIsChildClassOf(obj,CKCID_BEOBJECT)) iGrp->AddObject((CKBeObject*)obj); } return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::AddObjectsToSet(CKGroup* iGrp,XObjectArray* iArray) { if (!CheckIsSelectionSet(iGrp)) return FALSE; if (iGrp && iArray) { XObjectArray::Iterator it1 = iArray->Begin(); XObjectArray::Iterator it2 = iArray->End(); while (it1!=it2) { CKObject* obj = m_Context->GetObject(*it1++); iGrp->AddObject((CKBeObject*)obj); } return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::CreateSelectionSet(CKGroup* iGrp,XString* iPath) { if (!CKIsChildClassOf(iGrp,CKCID_GROUP)) return 0; iGrp->ModifyObjectFlags(CK_OBJECT_NOTTOBELISTEDANDSAVED|CK_OBJECT_SELECTIONSET,0); if (iPath && iPath->Length()) SetSelectionSetPath(iGrp,*iPath); //flag as loaded { SelectionSetArray sets; sets.PushBack(iGrp); SetField(sets,eSetField_Add,SelectionSetData::fSetFlags_Loaded,FALSE,fSetPart_LoadState); } #ifndef VIRTOOLS_RUNTIME_VERSION //notify interface { CK_ID id = iGrp->GetID(); WORD parts = fSetPart_Content|fSetPart_LoadState; if (iPath) parts |= fSetPart_Path; DWORD lparam = MAKELPARAM(1,parts); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&id,lparam); } #endif return iGrp; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::CreateSelectionSet(XString* iName,XString* iPath,BOOL iNotify,BOOL iLoaded) { CKLevel* level = m_Context->GetCurrentLevel(); //get unique name XString name; if (iName) name = *iName; else name = "New SelectionSet"; GetUniqueSelectionSetName(0,&name); CKGroup* group=(CKGroup*)m_Context->CreateObject(CKCID_GROUP,name.Str()); if (!group) return 0; group->ModifyObjectFlags(CK_OBJECT_NOTTOBELISTEDANDSAVED|CK_OBJECT_SELECTIONSET,0); ModifyFlags(fSetMgrFlags_LoadingSet); if (level) level->AddObject(group); ModifyFlags(0,fSetMgrFlags_LoadingSet); if (iPath && iPath->Length()) SetSelectionSetPath(group,*iPath); if (iLoaded) //flag as loaded { SelectionSetArray sets; sets.PushBack(group); SetField(sets,eSetField_Add,SelectionSetData::fSetFlags_Loaded,FALSE,fSetPart_LoadState); } #ifndef VIRTOOLS_RUNTIME_VERSION if (iNotify) { CK_ID id = group->GetID(); WORD parts = fSetPart_Content; if (iPath) parts |= fSetPart_Path; if (iLoaded) parts |= fSetPart_LoadState; DWORD lparam = MAKELPARAM(1,parts); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&id,lparam); } #endif return group; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::CreateSelectionSet(XObjectArray* iArray,XString* iName,XString* iPath,BOOL iNotify,BOOL iLoaded) { CKGroup* group = CreateSelectionSet(iName,iPath,FALSE,iLoaded); if (group && iArray) { AddObjectsToSet(group,iArray); #ifndef VIRTOOLS_RUNTIME_VERSION if (iNotify) { CK_ID id=group->GetID(); DWORD lparam = MAKELPARAM(1,fSetPart_Content); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&id,lparam); } #endif } return group; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::CreateSelectionSet(CKObjectArray* iArray,XString* iName,XString* iPath,BOOL iNotify,BOOL iLoaded) { CKGroup* group = CreateSelectionSet(iName,iPath,FALSE,iLoaded); if (group && iArray) { AddObjectsToSet(group,iArray); #ifndef VIRTOOLS_RUNTIME_VERSION if (iNotify) { CK_ID id=group->GetID(); DWORD lparam = MAKELPARAM(1,fSetPart_Content); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&id,lparam); } #endif } return group; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::GetSelectionSetShortPath(CK_ID iGrpId,XString& oPath) { CKGroup* grp = (CKGroup*)m_Context->GetObject(iGrpId); return GetSelectionSetShortPath(grp,oPath); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::GetSelectionSetShortPath(CKGroup* iGrp,XString& oPath) { if (!CheckIsSelectionSet(iGrp)) return FALSE; SelectionSetData* data = (SelectionSetData*)iGrp->GetAppData(); if (data) { oPath = data->m_Path; //check if path is relative or not and change it accordingly (remove common part with cmo if exists) return ((oPath.Length()>4)?TRUE:FALSE); // 4 => ".nmo" } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::GetSelectionSetPath(SelectionSetData* data,XString& oPath) { if (data) { oPath = data->m_Path; //check if path is relative or not and change it accordingly (remove common part with cmo if exists) if (oPath.Length()>4) { if (!IsLocalPath(oPath)) { oPath = m_LastDir + oPath; } XString folderPath = oPath; int rindex = oPath.RFind(DIRECTORY_SEP_CHAR); if (rindex!=XString::NOTFOUND) folderPath = oPath.Substring(0,rindex); return PathFileExists(folderPath.CStr()); } } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::GetSelectionSetPath(CKGroup* iGrp,XString& oPath) { if (!CheckIsSelectionSet(iGrp)) return FALSE; SelectionSetData* data = (SelectionSetData*)iGrp->GetAppData(); return GetSelectionSetPath(data,oPath); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::GetSelectionSetPath(CK_ID iGrpId,XString& oPath) { CKGroup* grp = (CKGroup*)m_Context->GetObject(iGrpId); return GetSelectionSetPath(grp,oPath); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::CheckRelativePath(XString& ioPath,BOOL iCompress) { //check if path is relative or not and change it accordingly (remove common part with cmo if exists) if (m_LastDir.Length() && ioPath.Contains(m_LastDir)) { if (iCompress) ioPath = ioPath.Substring(m_LastDir.Length());//reduce path return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SetSelectionSetPath(CKGroup* iGrp,XString& iPath) { if (!CheckIsSelectionSet(iGrp)) return FALSE; XString oldPath; if (GetSelectionSetPath(iGrp,oldPath)) { if (oldPath==iPath) return TRUE; } SelectionSetData* data = CreateSelectionSetData(iGrp); if (data) { data->m_Path = iPath; //check if path is relative or not and change it accordingly (remove common part with cmo if exists) CheckRelativePath(data->m_Path,TRUE); //prevent use of an existing path !! XArray sets; GetSelectionSets(sets); BOOL changed=TRUE; XString finalPath = data->m_Path ; int finalIndex=0; while (changed) { changed=FALSE; XArray::Iterator it1 = sets.Begin(); XArray::Iterator it2 = sets.End(); while (it1!=it2) { CKGroup* grp = *it1++; if (grp==iGrp) continue; SelectionSetData* grpData = GetSelectionSetData(grp); if (grpData && finalPath==grpData->m_Path) { changed=TRUE; finalIndex++; finalPath = data->m_Path; finalPath += finalIndex; break; } } } if (finalIndex>0 && data) data->m_Path = finalPath; //prevent use of an existing path !! //notify selection set path has been changed #ifndef VIRTOOLS_RUNTIME_VERSION CK_ID id = iGrp->GetID(); DWORD param2 = MAKELPARAM(1,fSetPart_Path); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&id,param2); #endif return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SetSelectionSetPath(CKGroup* iGrp,const char* iPath) { XString path; if (iPath) path=iPath; return SetSelectionSetPath(iGrp,path); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SetSelectionSetPath(CK_ID iGrpId,const char* iPath) { CKGroup* grp = (CKGroup*)m_Context->GetObject(iGrpId); XString path; if (iPath) path=iPath; return SetSelectionSetPath(grp,path); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::CheckIsSelectionSet(CKObject* iObj) { DWORD flags=CK_OBJECT_NOTTOBELISTEDANDSAVED|CK_OBJECT_SELECTIONSET; if ( !CKIsChildClassOf(iObj,CKCID_GROUP) || ((iObj->GetObjectFlags() & flags)!=flags) ) return 0; return (CKGroup*)iObj; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// SelectionSetData* SelectionSetManager::CreateSelectionSetData(CKGroup* iGrp) { if (!CheckIsSelectionSet(iGrp)) return 0; SelectionSetData* data = (SelectionSetData*)iGrp->GetAppData(); if (!data) { data = new SelectionSetData; iGrp->SetAppData((void*)data); } return data; } BOOL SelectionSetManager::SetSelectionSetData(CKGroup* iGrp,SelectionSetData* iData) { SelectionSetData* data = (SelectionSetData*)iGrp->GetAppData(); if (data==iData) //no data change return TRUE; if (data) delete data; iGrp->SetAppData((void*)iData); iGrp->ModifyObjectFlags(CK_OBJECT_NOTTOBELISTEDANDSAVED|CK_OBJECT_SELECTIONSET,0); return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// SelectionSetData* SelectionSetManager::GetSelectionSetData(CKGroup* iGrp) { if (!CheckIsSelectionSet(iGrp)) return 0; SelectionSetData* data = (SelectionSetData*)iGrp->GetAppData(); return data; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::DeleteSelectionSetData(CKGroup* iGrp) { if (!CheckIsSelectionSet(iGrp)) return FALSE; SelectionSetData* data = (SelectionSetData*)iGrp->GetAppData(); if (data) { delete data; iGrp->SetAppData(0); } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::ClearSelectionSetsDatas() { XArray selectionSets; GetSelectionSets(selectionSets); XArray::Iterator it1 = selectionSets.Begin(); XArray::Iterator it2 = selectionSets.End(); while (it1!=it2) { CKGroup* grp = *it1++; DeleteSelectionSetData(grp); } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::ModifySetFlags(CKGroup* iGrp,DWORD iAdded,DWORD iRemoved) { if (!CheckIsSelectionSet(iGrp)) return FALSE; if (!iAdded && !iRemoved) return FALSE; SelectionSetData* data = CreateSelectionSetData(iGrp); if (data) { data->m_Flags &= ~iRemoved; data->m_Flags |= iAdded; return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// DWORD SelectionSetManager::GetSetFlags(CKGroup* iGrp) { SelectionSetData* data = GetSelectionSetData(iGrp); if (data) return data->m_Flags; return 0; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SetSelectionSetPath(CK_ID iGrpId,XString& iPath) { CKGroup* grp = (CKGroup*)m_Context->GetObject(iGrpId); return SetSelectionSetPath(grp,iPath); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::CheckAllSelectionSetPath() { XArray sets; GetSelectionSets(sets); XArray::Iterator it1 = sets.Begin(); XArray::Iterator it2 = sets.End(); while (it1!=it2) { BOOL ok = CheckAndAskSelectionSetPath(*it1++,FALSE); if (!ok) return FALSE; } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::CheckAndAskSelectionSetPath(CKGroup* iGrp,BOOL iForceNewPath,XString* oCurrentPath) { SelectionSetData* data = GetSelectionSetData(iGrp); SelectionSetData emptyData; if (!data) data=&emptyData; BOOL dialog=TRUE; XString currentPath; BOOL pathOk = GetSelectionSetPath(iGrp,currentPath); if (!iForceNewPath && pathOk) { dialog = FALSE; } if (!iForceNewPath && !data->CheckSaveExternal(this)) { if (oCurrentPath) *oCurrentPath = currentPath; return TRUE; } #ifndef VIRTOOLS_RUNTIME_VERSION if (dialog) { if (currentPath.Length()==0) { currentPath=m_LastDir;//m_LastCmoSavedDir;//theCUIKApp.GetLevelSaveLoadDirectory(); //currentPath=theCUIKApp.GetNMODirectory(); //currentPath+="*.nmo"; } XString title; title.Format(STR_SAVESETDLGTITLE,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET); BOOL ok = FileDialog(FALSE,STR_SELECTIONSET_EXT,currentPath.CStr(),title.CStr(),OFN_OVERWRITEPROMPT,STR_VIRTOOLS_SELECTIONSET_FILTER,currentPath); if (ok) { //currentPath=fdlg.m_ofn.lpstrFile; //SetSelectionSetPath(obj->GetID(),currentPath); //save path SetSelectionSetPath(iGrp,currentPath); } else return FALSE; } #endif if (oCurrentPath) *oCurrentPath = currentPath; return TRUE;//there was a dialog, we suppose the path is ok } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SaveSelectionSet(CKGroup* iGrp,BOOL iForceNewPath,XString* oErrorLog) { //not allowed for runtime player if (m_Context->IsRunTime()) return FALSE; if (!CheckIsSelectionSet(iGrp)) return FALSE; if(iGrp->GetObjectCount()==0) { XString str; str.Format(STR_SETNOTSAVED,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET); m_Context->OutputToConsole(str.Str(),FALSE); return TRUE; } /* WebManager* wm = (WebManager *) m_Context->GetManagerByGuid(WEB_MANAGER2_GUID); if(wm) { XString currentUrl; wm->GetCurrentUrl(currentUrl); if (currentUrl.Length()) //we are on the web return FALSE; //not allowed to save while on the web } */ XString currentPath; BOOL ok = CheckAndAskSelectionSetPath(iGrp,iForceNewPath,¤tPath); //WaitCursor hourglass; //AfxGetMainWnd()->RedrawWindow(); #ifndef VIRTOOLS_RUNTIME_VERSION //save old file in .bak+number if (m_BackupOnSaveSet) { if (PathFileExists(currentPath.CStr())) { XString newpath=currentPath; newpath+=".bak"; MoveFileEx(currentPath.CStr(),newpath.CStr(),MOVEFILE_REPLACE_EXISTING); } } #endif CKDependencies* dep = &m_SaveSetDependencies; SelectionSetData* data = GetSelectionSetData(iGrp); if (data) { #ifdef SELECTIONSET_USE_DEPENDENCIES if (data->m_SaveDependencies.Size()) dep = &data->m_SaveDependencies; #endif } else { XString str; str.Format(STR_SETNOTSAVED,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET); m_Context->OutputToConsole(str.Str(),FALSE); return FALSE; } //create array of objects to save CKObjectArray * arrayToSave = CreateCKObjectArray(); //arrayToSave->InsertRear(iGrp); if(iGrp->GetObjectCount()==0) { XString str; str.Format(STR_SETNOTSAVED,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET); m_Context->OutputToConsole(str.Str(),FALSE); return TRUE; } //save hierarchy for rebuild CKInterfaceObjectManager * iom = 0; if (data->HasFlags(SelectionSetData::fSetFlags_RebuildHierarchy)) { if (iom = (CKInterfaceObjectManager*) m_Context->CreateObject(CKCID_INTERFACEOBJECTMANAGER)) { iom->SetGuid(LOADSAVEGUID_SELECTIONSETDATA); arrayToSave->InsertRear(iom); CKStateChunk* chunk=CreateCKStateChunk(CKCID_OBJECT); chunk->StartWrite(); SaveRebuildHierarchyFromChunk(iGrp,chunk); chunk->CloseChunk(); iom->AddStateChunk(chunk); } } #ifdef USE_VERSIONCONTROL //source control presave if (m_VCI && m_VCI->m_OnPreSave) { const char* file = currentPath.CStr(); m_VCI->m_OnPreSave(&file,1); } #endif #pragma todo("option de hide / show graph") /* BOOL oldhidegraph = CUIKSchematicEditor::AreGraphsHidden(); CUIKSchematicEditor::SaveScriptIndex(FALSE);//save script index only if composition CUIKSchematicEditor::HideGraphs(FALSE);//prevent schematic editor at least CKERROR res = SendCuikNotification(NULL,CUIK_NOTIFICATION_PRESAVELEVEL,(DWORD)arrayToSave);//send notif so that all chunk are deleted */ CKERROR res = m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_PRESAVELEVEL,(DWORD)arrayToSave,0); if (res!=CKERR_NOTIFICATIONNOTHANDLED && res<0) { m_Context->OutputToConsole(STR_PRESAVEERROR,TRUE); DeleteCKObjectArray(arrayToSave); return FALSE; } iGrp->ModifyObjectFlags(0,CK_OBJECT_NOTTOBESAVED); //force save the selection set group CKERROR error=SaveGroup(iGrp,currentPath.CStr(),dep,arrayToSave); //save iGrp->ModifyObjectFlags(CK_OBJECT_NOTTOBESAVED,0); //unflag m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_POSTSAVELEVEL,(DWORD)arrayToSave,0); //CUIKSchematicEditor::HideGraphs(oldhidegraph);//restore if (error!=0)//error check { if (oErrorLog) { XString buffer; buffer.Format(STR_SAVEERROR,CKErrorToString(error)); buffer.Format("%s (%s)",buffer.CStr(),data->m_Path.CStr()); if ((*oErrorLog).Length()>0) (*oErrorLog)+="\n"; (*oErrorLog)+=buffer; } else { XString buffer; buffer.Format(STR_SAVEERROR,CKErrorToString(error)); m_Context->OutputToConsole(buffer.Str(),TRUE); } DeleteCKObjectArray(arrayToSave); return FALSE; } #ifndef VIRTOOLS_RUNTIME_VERSION else//no error { m_LastSavedSetID = iGrp->GetID(); DWORD param2=MAKELPARAM(1,fSetPart_LastSaved); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&m_LastSavedSetID,param2); } #endif #ifdef USE_VERSIONCONTROL //source control postsave if (!error && m_VCI && m_VCI->m_OnPostSave) { const char* file = currentPath.CStr(); m_VCI->m_OnPostSave(&file,1); } #endif DeleteCKObjectArray(arrayToSave); if (iom) m_Context->DestroyObject(iom,CK_DESTROY_TEMPOBJECT); return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::LoadSelectionSetFromChunk(CKStateChunk* iChunk,BOOL iFromCMO) { if (!iChunk) return FALSE; //read version m_Version = 0; if (iChunk->SeekIdentifier(SELECTIONSETMANAGER_CHUNK_VERSIONIDENTIFIER)) { m_Version= iChunk->ReadInt(); } else return FALSE; //obsolete file if (iChunk->SeekIdentifier(SELECTIONSETMANAGER_CHUNK_SAVEIDENTIFIER)) { XString errorLog; XArray setgrpCreated; //Get 3dView combo box for selection set //CUIK3DView* view = (CUIK3DView*)GetCurrentView(); //CUIKComboBox* cb = (CUIKComboBox*)view->GetWindow()->GetGraphicItemObject(CUIK_3DVIEW_GI_SELECTIONGROUPSCOMBO); //if (cb) { //create selection sets int grpCount = iChunk->ReadInt(); for (int i=0;iLoadDataFromChunk(iChunk,m_Version); if (m_Version==0)//beta old code, read set name iChunk->ReadString(data->m_Name); //create set /*OLD CODE CKGroup* grp = CreateSelectionSet(&grpName,0,FALSE); SetSelectionSetData(grp,data); */ CKGroup* grp = 0; ModifyFlags(fSetMgrFlags_LoadingSet); //read internal set if (!data->HasFlags(SelectionSetData::fSetFlags_Temp_External)) { CKGroup* setgrp = CreateSelectionSet(&data->m_Name,0,FALSE,TRUE); //internal = loaded data->ModifyFlags(SelectionSetData::fSetFlags_Loaded); //internal set has to be loaded setgrpCreated.PushBack(setgrp->GetID()); SetSelectionSetData(setgrp,data); //read objects int objCount = iChunk->ReadInt(); for (int j=0;jReadObjectID(); CKBeObject* beo = (CKBeObject*)m_Context->GetObject(id); if (CKIsChildClassOf(beo,CKCID_BEOBJECT)) setgrp->AddObject(beo); } } else //read external set { if (iFromCMO && !data->HasFlags(SelectionSetData::fSetFlags_LoadWithCmo)) { //cmo loading, and flag tell us not to load the file //=>create an empty selection set & associate it with the data CKGroup* setgrp = CreateSelectionSet(&data->m_Name,0,FALSE,FALSE);//external & load with cmo = !loaded SetSelectionSetData(setgrp,data); if (setgrp) setgrpCreated.PushBack(setgrp->GetID()); } else { //load file, which contains the group (which is _the_ selection set) CKGroup* setgrp = 0; //ModifyFlags(fSetMgrFlags_SkipNextLoadSave);//removed and put inside loadselectionset ESetLoadResult res = LoadSelectionSet(setgrp,data,FALSE,FALSE,&errorLog); //ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave); //if (setgrp) //do not do that : on level->addobject(setgrp), all objects have already been dispatched (except scenes btw) // setgrpCreated.PushBack(setgrp->GetID()); if (data->HasFlags(SelectionSetData::fSetFlags_Temp_Recreated))//the group had no name so it has been recreated in order to correct user's error { if (setgrp) setgrpCreated.PushBack(setgrp->GetID()); else assert(0);//set was not created, there is a problem here data->ModifyFlags(0,SelectionSetData::fSetFlags_Temp_Recreated); } else if (!setgrp) { assert(0);//set was not created, there is a problem here } } } ModifyFlags(0,fSetMgrFlags_LoadingSet); } if (grpCount>0 && setgrpCreated.Size()) { #ifndef VIRTOOLS_RUNTIME_VERSION DWORD param2=MAKELPARAM(setgrpCreated.Size(),fSetPart_All); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)setgrpCreated.Begin(),param2); #endif RenderNow(); } } if (errorLog.Length()) { m_Context->OutputToConsole(STR_LOADWARNING,FALSE); m_Context->OutputToConsole(errorLog.Str(),TRUE); } return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SaveSelectionSetInChunk(CKStateChunk* iChunk,BOOL iFromCMO,XArray* iSets) { SelectionSetData emptyData; XArray selectionSets; if (iSets) //use send sets selectionSets.Swap(*iSets); else GetSelectionSets(selectionSets); if (selectionSets.Size()>0) { if (!iChunk) { CKStateChunk* chunk=CreateCKStateChunk(CKCID_OBJECT); } //write version iChunk->WriteIdentifier(SELECTIONSETMANAGER_CHUNK_VERSIONIDENTIFIER); iChunk->WriteInt(SELECTIONSETMANAGER_SAVEVERSION); iChunk->WriteIdentifier(SELECTIONSETMANAGER_CHUNK_SAVEIDENTIFIER); iChunk->WriteInt(selectionSets.Size());//write selection set count for (int i=0;iGetAppData(); if (!data) data = &emptyData; //update data name data->m_Name = grp->GetName(); //check externality BOOL external = data->CheckSaveExternal(this); if (external) { BOOL ok = CheckAndAskSelectionSetPath(grp,FALSE); } //save set data data->SaveDataInChunk(iChunk); if (external) { //do nothing //do not save external sets here, it will be done during _postsave callback } else { //write objects int grpObjectCount=grp->GetObjectCount(); iChunk->WriteInt(grpObjectCount);//write grp object count for (int j=0;jGetObject(j); iChunk->WriteObjectID(obj->GetID());//write grp object id } } } } if (iSets) selectionSets.Swap(*iSets); //restore iSets just in case return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SetSetPriority(XArray &iGrps,int iPriority) { XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = CreateSelectionSetData(grp); if (data) data->m_Priority=iPriority; } if (iGrps.Size()>0) { #ifndef VIRTOOLS_RUNTIME_VERSION XArray ids; CKGroupToCKIDArray(&iGrps,&ids); DWORD param2=MAKELPARAM(ids.Size(),fSetPart_Priority); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)ids.Begin(),param2); #endif return CK_OK; } return CKERR_INVALIDPARAMETER; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::RemoveSetPath(XArray &iGrps) { BOOL change=FALSE; XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); if (data && data->m_Path.Length()) { data->m_Path=""; change=TRUE; } } if (change) { #ifndef VIRTOOLS_RUNTIME_VERSION XArray ids; CKGroupToCKIDArray(&iGrps,&ids); DWORD param2=MAKELPARAM(ids.Size(),fSetPart_Path); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)ids.Begin(),param2); #endif return CK_OK; } return CKERR_INVALIDPARAMETER; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::EditSetPath(CKGroup* iGrp) { #if defined(WIN32) && !defined(VIRTOOLS_RUNTIME_VERSION) if (!CheckIsSelectionSet(iGrp)) return CKERR_INVALIDPARAMETER; XString currentPath; GetSelectionSetPath(iGrp,currentPath); if (currentPath.Length()==0) { currentPath=m_LastDir;//m_LastCmoSavedDir;//theCUIKApp.GetLevelSaveLoadDirectory(); //currentPath+="*.nmo"; } else { int index=currentPath.RFind('.'); if (index!=XString::NOTFOUND) { int length = currentPath.Length(); for (int i=index;iGetName()?iGrp->GetName():STR_UNNAMEDSET); BOOL ok = FileDialog(FALSE,STR_SELECTIONSET_EXT,currentPath.CStr(),title.CStr(),OFN_OVERWRITEPROMPT,STR_VIRTOOLS_SELECTIONSET_FILTER,currentPath); if (ok) SetSelectionSetPath(iGrp,currentPath); #endif return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::CloseExternalFileSets() { #ifdef USE_VERSIONCONTROL if (!m_VCI || !m_VCI->m_OnPreClose) return; #endif XArray selectionSets; GetSelectionSets(selectionSets); XArray::Iterator it1 = selectionSets.Begin(); XArray::Iterator it2 = selectionSets.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); if (!data) continue; BOOL external = data->CheckSaveExternal(this); if (!external) continue; XString path; if (GetSelectionSetPath(grp,path)) { const char* file = path.CStr(); #ifdef USE_VERSIONCONTROL m_VCI->m_OnPreClose(&file,1); #endif } } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::GetLastSavedSet() { CKGroup* grp = (CKGroup*)m_Context->GetObject(m_LastSavedSetID); if (CheckIsSelectionSet(grp)) return grp; m_LastSavedSetID = 0; return 0; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::SaveLastSavedSet() { return SaveSelectionSet(GetLastSavedSet(),FALSE); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::CompactSets(XArray &iGrps) { //parse sets XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKDependencies* dep = &m_SaveSetDependencies; CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); #ifdef USE_DEPENCENCIES if (data) if (data->m_SaveDependencies.Size()) dep = &data->m_SaveDependencies; #endif int count = grp->GetObjectCount(); XArray groupChildrenCopy; groupChildrenCopy.Resize(count); for (int i=0;iGetObject(i); //parse group children XArray::Iterator git1 = groupChildrenCopy.Begin(); XArray::Iterator git2 = groupChildrenCopy.End(); while (git1!=git2) { CKObject* obj = *git1++; CKDependenciesContext dep_ctx(m_Context); dep_ctx.SetOperationMode(CK_DEPENDENCIES_SAVE); dep_ctx.StartDependencies(dep); obj->PrepareDependencies(dep_ctx); XObjectArray array = dep_ctx.FillDependencies(); dep_ctx.StopDependencies(); //parse dependencies, check if belong to grp, //if belong to grp, mark it to remove it from group XObjectArray::Iterator dit1 = array.Begin(); XObjectArray::Iterator dit2 = array.End(); while (dit1!=dit2) { CKObject* depobj = m_Context->GetObject(*dit1++); if (depobj==obj) continue; grp->RemoveObject((CKBeObject*)depobj); } } } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// struct ParentChildrenRebuildData { CKObject* object; CKObject* parent; //XArray children; ParentChildrenRebuildData(): object(0),parent(0) {} }; //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //format = // //identifier //object count with hierarchy to update // per object // obj id // parent name BOOL SelectionSetManager::LoadRebuildHierarchyFromChunk(CKGroup* iGrp,CKStateChunk* iChunk) { if (!iGrp || !iChunk) return FALSE; if (iChunk->SeekIdentifier(SELECTIONSET_CHUNK_REBUILDHIERARCHY_IDENTIFIER))//identifier { CKObjectManager* omgr = m_Context->m_ObjectManager; int objectCount = iChunk->ReadInt();//object count with hierarchy to update for (int i=0;iReadObjectID();// obj id CKObject* obj = m_Context->GetObject(id); CK_CLASSID classid = 0; CK3dEntity* ent3 = 0; CK2dEntity* ent2 = 0; if (CKIsChildClassOf(obj,CKCID_3DENTITY)) { classid = CKCID_3DENTITY; ent3 = (CK3dEntity*)obj; } else if (CKIsChildClassOf(obj,CKCID_2DENTITY)) { classid = CKCID_2DENTITY; ent2 = (CK2dEntity*)obj; } XString parentName; iChunk->ReadString(parentName);// parent name if (classid) { CKObject* parent = omgr->GetObjectByNameAndParentClass(parentName.Str(),classid); if (ent3) ent3->SetParent((CK3dEntity*)parent); else if (ent2) ent2->SetParent((CK2dEntity*)parent); } } return TRUE; } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //format = // //identifier //object count with hierarchy to update // per object // obj id // parent name BOOL SelectionSetManager::SaveRebuildHierarchyFromChunk(CKGroup* iGrp,CKStateChunk* iChunk) { XArray rebuild; SelectionSetData* data = GetSelectionSetData(iGrp); if (data->HasFlags(SelectionSetData::fSetFlags_RebuildHierarchy)) { //check if there is some hierarchy objects not in group int count = iGrp->GetObjectCount(); for (int i=0;iGetObject(i); if (CKIsChildClassOf(obj,CKCID_3DENTITY)) { CK3dEntity* parent = ((CK3dEntity*)obj)->GetParent(); if (parent) if (!iGrp->IsObjectUsed(parent,CKCID_BEOBJECT)) { rebuild.PushBack(obj); rebuild.PushBack(parent); } } else if (CKIsChildClassOf(obj,CKCID_2DENTITY)) { CK2dEntity* parent = ((CK2dEntity*)obj)->GetParent(); if (parent) if (!iGrp->IsObjectUsed(parent,CKCID_BEOBJECT)) { rebuild.PushBack(obj); rebuild.PushBack(parent); } } } if (rebuild.Size()) { iChunk->WriteIdentifier(SELECTIONSET_CHUNK_REBUILDHIERARCHY_IDENTIFIER);//identifier iChunk->WriteInt(rebuild.Size()/2);//object count with hierarchy to update XArray::Iterator it1 = rebuild.Begin(); XArray::Iterator it2 = rebuild.End(); while (it1!=it2)// per object { CKObject* obj = *it1++; CKObject* parent = *it1++; iChunk->WriteObjectID(obj->GetID());// obj id iChunk->WriteString(parent->GetName());// parent name } return TRUE; } } return FALSE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SetField(XArray &iGrps,ESetFieldChange iChange,SelectionSetData::FSetFlags iDataFlags,BOOL iNotify,FSetPart iViewFlags) { XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKGroup* grp = *it1++; if (CheckIsSelectionSet(grp)) { SelectionSetData* data = CreateSelectionSetData(grp); if (data) { switch (iChange) { case eSetField_Toggle: if (data->HasFlags(iDataFlags)) data->ModifyFlags(0,iDataFlags); else data->ModifyFlags(iDataFlags); break; case eSetField_Remove: data->ModifyFlags(0,iDataFlags); break; case eSetField_Add: data->ModifyFlags(iDataFlags); break; } } } } #ifndef VIRTOOLS_RUNTIME_VERSION if (iNotify && iGrps.Size()>0) { XArray ids; CKGroupToCKIDArray(&iGrps,&ids); DWORD param2=MAKELPARAM(ids.Size(),iViewFlags); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)ids.Begin(),param2); } #endif return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SetLoadWithCmo(XArray &iGrps,ESetFieldChange iChange) { return SetField(iGrps,iChange,SelectionSetData::fSetFlags_LoadWithCmo,TRUE,fSetPart_LoadWithCmo); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SetSaveWithCmo(XArray &iGrps,ESetFieldChange iChange) { return SetField(iGrps,iChange,SelectionSetData::fSetFlags_SaveWithCmo,TRUE,fSetPart_SaveWithCmo); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SetLoadMode(XArray &iGrps,ESetFieldChange iChange) { return SetField(iGrps,iChange,SelectionSetData::fSetFlags_ReplaceAndShare,TRUE,fSetPart_LoadMode); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SetRebuildHierarchy(XArray &iGrps,ESetFieldChange iChange) { return SetField(iGrps,iChange,SelectionSetData::fSetFlags_RebuildHierarchy,TRUE,fSetPart_RebuildHierarchy); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int SelectionSetManager::GetLastWebDownloadSetHandle() { if (m_WebDownloadSets.Size()>0) return m_WebDownloadSets.Back().webHandle; return -1; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ESetLoadResult SelectionSetManager::GetWebDownloadSetState(int webHandle,CKGroup*& oSet) { int count = m_WebDownloadSets.Size(); for (int i=0;iGetManagerByGuid(WEB_SERVER_MANAGER_GUID); XDWORD current = 0; XDWORD max = 0; if (webset.state==eSetLoad_WebDownload)//check if loading only switch (webmgr->GetRequestState(webset.webHandle)) { case CWebServerManager::WSMDR_INITIALE: case CWebServerManager::WSMDR_DOWNLOADING: webset.state = eSetLoad_WebDownload; break; case CWebServerManager::WSMDR_FINISHED: { XString filename = webmgr->GetRequestData(webset.webHandle); webmgr->EndDownloadRequest(webset.webHandle); if (webset.grp) SetSelectionSetPath(webset.grp,filename.CStr()); else if (webset.data) webset.data->m_Path = filename; ModifyFlags(fSetMgrFlags_NoWebDownloadCheck); ESetLoadResult res = LoadSelectionSet(webset.grp,webset.data,webset.dyn,webset.manual); ModifyFlags(0,fSetMgrFlags_NoWebDownloadCheck); if (res==eSetLoad_Success) { webset.state = eSetLoad_Success; break; } webset.state = eSetLoad_Failed; break; } case CWebServerManager::WSMDR_FAILED: webmgr->EndDownloadRequest(webset.webHandle); webset.state = eSetLoad_Failed; break; } } } } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// ESetLoadResult SelectionSetManager::LoadSelectionSet(CKGroup*& ioGrp,BOOL iDynamic,BOOL iUserManualReload,XString* oErrorLog) { ioGrp = CheckIsSelectionSet(ioGrp); if (ioGrp) { SelectionSetData* data = GetSelectionSetData(ioGrp); if (data) return LoadSelectionSet(ioGrp,data,iDynamic,iUserManualReload,oErrorLog); } return eSetLoad_Failed; } ESetLoadResult SelectionSetManager::LoadSelectionSet(CKGroup*& ioGrp,SelectionSetData* data,BOOL iDynamic,BOOL iUserManualReload,XString* oErrorLog) { //check if group is selection set & check data ioGrp = CheckIsSelectionSet(ioGrp); if (!data && ioGrp) data = GetSelectionSetData(ioGrp); BOOL keep_grp_not_dynamic = FALSE; if (iDynamic && ioGrp) keep_grp_not_dynamic = TRUE; //check path XString currentPath; if (!data || !GetSelectionSetPath(data,currentPath)) return eSetLoad_Failed; if (currentPath.Length()==0) return eSetLoad_Failed; CheckRelativePath(data->m_Path,TRUE); BOOL FileAlreadyDwnloaded = VxFileExist(currentPath.CStr()); //check if we have to download from web #ifdef WEBDOWNLOAD BOOL a = !HasFlags(fSetMgrFlags_NoWebDownloadCheck) ; BOOL b = !IsLocalPath(data); if ( a && b && !FileAlreadyDwnloaded) { WebManager* wm = (WebManager *) m_Context->GetManagerByGuid(WEB_MANAGER2_GUID); if(wm) { XString currentUrl; wm->GetCurrentUrl(currentUrl); //check if we are not in local file:// BOOL local = FALSE; if (currentUrl.Length()>7) { char savedchar = currentUrl[7]; currentUrl[7]=0; local = strcmp(currentUrl.CStr(),"file://") ? FALSE:TRUE; currentUrl[7]=savedchar; } if (!local && currentUrl.Length()) //we are on the web { CWebServerManager* webmgr = (CWebServerManager*)m_Context->GetManagerByGuid(WEB_SERVER_MANAGER_GUID); //do not use currentPath there cause this will use the temporary folder concatenated WebHandle handle = webmgr->DownloadFile(data->m_Path.CStr(),10000,TRUE); if (handle) { m_WebDownloadSets.Expand(1); WebSet& webset = m_WebDownloadSets.Back(); webset.grp = ioGrp; webset.data = data; webset.webHandle = handle; webset.dyn=iDynamic; webset.manual=iUserManualReload; webset.state=eSetLoad_WebDownload; return eSetLoad_WebDownload; } return eSetLoad_Failed; } } } #endif #ifdef USE_VERSIONCONTROL //ask to get latest version if (m_VCI && m_VCI->m_GetLatestVersion) { const char* file = currentPath.CStr(); m_VCI->m_GetLatestVersion(&file,1,TRUE);//true means dependency file } #endif //check set working mode : ignore & noshare(default) or replace & share DWORD loadingFlags = 0; BOOL check4ObsoleteObjects = FALSE; if (data->HasFlags(SelectionSetData::fSetFlags_ReplaceAndShare)) { //on load replace & share allowed //need to store group previous object list //to delete old objects no more present //change loading flags so to only replace shared objects loadingFlags = CK_LOAD_REPLACEALL_WITHSCRIPT|CK_LOAD_CHECKDUPLICATES|CK_LOAD_DODIALOG; //store old objects list if (ioGrp) { m_NotToSaveObjectList.Clear(); int i,count=ioGrp->GetObjectCount(); for (i=0;iGetObject(i); m_NotToSaveObjectList.PushBack(obj->GetID()); } check4ObsoleteObjects = TRUE; } } else //Ignore & noshare, meaning -> unload & reload { if (ioGrp) { //backup data as they will be deleted at the same time as the group SelectionSetData* newData = new SelectionSetData; *newData = *data; XArray sets; sets.PushBack(ioGrp); //save parameters pointing on this group RemapSelectionSetParameters(ioGrp,FALSE); UnloadSets(sets,TRUE); //true->delete group too, data is now invalid data=newData; } } //load file & check old runtime flag CKObjectArray* liste = CreateCKObjectArray(); if (!liste) return eSetLoad_Failed; #pragma todo("loading dialog there?") //begin dialog - m_Context->SendInterfaceMessage(CKUIM_PROGRESSDIALOG); // STR_LOADINGFILE BOOL runtime=m_Context->IsRunTime(); if (iDynamic) loadingFlags |= CK_LOAD_AS_DYNAMIC_OBJECT; ModifyFlags(fSetMgrFlags_SkipNextLoadSave);//added here because load/save cmo=>no flag, load/save set CKERROR error=m_Context->Load(currentPath.Str(),liste,(CK_LOAD_FLAGS)loadingFlags); ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave); //end dialog //check for load errors if (error!=0) { if (oErrorLog) { XString buffer; buffer=STR_LOADERROR; buffer.Format("%s (%s)",buffer.CStr(),data->m_Path.CStr()); if ((*oErrorLog).Length()>0) (*oErrorLog)+="\n"; (*oErrorLog)+=buffer; } else { XString buffer=STR_LOADERROR; buffer += " - "; buffer += currentPath.Str(); m_Context->OutputToConsole(buffer.Str(),TRUE); } DeleteCKObjectArray(liste); return eSetLoad_Failed; } //check runtime flags if (!runtime && m_Context->IsRunTime()) m_Context->OutputToConsole(STR_RUNTIMEWARNING,TRUE); //load nmo as selection set CKLevel* level = m_Context->GetCurrentLevel(); //prepare dependencies for loaded file XObjectArray loadDepArray;//array of all dependencies for loaded file CKGroup* setgrp = 0; XArray scenes; XArray places; for (liste->Reset();!liste->EndOfList();liste->Next()) { CKObject* obj = liste->GetData(m_Context); if (CKIsChildClassOf(obj,CKCID_GROUP))// && (obj->GetObjectFlags() & CK_OBJECT_SELECTIONSET) ) { setgrp = (CKGroup*)obj;//set is last grp in list (from observation) } else if(CKIsChildClassOf(obj,CKCID_SCENE)) { scenes.PushBack((CKScene*)obj); } else if(CKIsChildClassOf(obj,CKCID_PLACE)) { places.PushBack((CKPlace*)obj); } else if (CKIsChildClassOf(obj,CKCID_BEOBJECT)) { loadDepArray.PushBack(obj->GetID()); } //some data else if (CKIsChildClassOf(obj,CKCID_INTERFACEOBJECTMANAGER)) { CKInterfaceObjectManager* iom = (CKInterfaceObjectManager*)obj; if (iom->GetGuid()==LOADSAVEGUID_SELECTIONSETDATA) { CKStateChunk* chunk = iom->GetChunk(0); chunk->StartRead(); LoadRebuildHierarchyFromChunk(setgrp,chunk); chunk->CloseChunk(); } else { CKDWORD error = m_Context->SendInterfaceMessage(CUIKM_INTERFACEOBJECTMANAGER_LOADED,iom->GetID(),iDynamic); } m_Context->DestroyObject(iom,CK_DESTROY_TEMPOBJECT); } } if (!setgrp) { //warn the user he should modify the external set by saving the group / within the composition //=> save the group & not only the objects, even if it still works. It's bad m_Context->OutputToConsole(STR_PLEASAVEGROUP,TRUE); //try to repair things.. setgrp = CreateSelectionSet(&(data->m_Name),0,FALSE); //and readd objects to the group XObjectArray::Iterator it1 = loadDepArray.Begin(); XObjectArray::Iterator it2 = loadDepArray.End(); while (it1!=it2) setgrp->AddObject((CKBeObject*)m_Context->GetObject(*it1++)); data->ModifyFlags(SelectionSetData::fSetFlags_Temp_Recreated,0); } if (keep_grp_not_dynamic && setgrp->IsDynamic()) { m_Context->m_ObjectManager->UnSetDynamic(setgrp); } //check name { CKSTRING name = setgrp->GetName(); if (data->m_Name.Length() && name && data->m_Name!=name) setgrp->SetName(data->m_Name.Str()); } //set setgrp data SetSelectionSetData(setgrp,data); //set is loaded => flag it data->ModifyFlags(SelectionSetData::fSetFlags_Loaded); //remap parameters that may point on this set RemapSelectionSetParameters(setgrp,TRUE); if (level) { XArray::Iterator its = scenes.Begin(); while (its!=scenes.End()) level->AddScene(*its++); XArray::Iterator itp = places.Begin(); while (itp!=places.End()) level->AddPlace(*itp++); ModifyFlags(fSetMgrFlags_LoadingSet); level->AddObject(setgrp); ModifyFlags(0,fSetMgrFlags_LoadingSet); } //////////////////////////////////////////////////////////////////////////////////////////// if (check4ObsoleteObjects) { //Now compare loadDepArray with m_NotToSaveObjectList (which contains the set's previous content //if an objects belong to m_NotToSaveObjectList and not to loadDepArray then delete it XObjectArray toDeleteList; XObjectArray::Iterator it1 = m_NotToSaveObjectList.Begin(); XObjectArray::Iterator it2 = m_NotToSaveObjectList.End(); while (it1!=it2) { CK_ID id = *it1++; if (!loadDepArray.IsHere(id)) toDeleteList.PushBack(id); } if (toDeleteList.Size()) { XObjectArray dependArray; #ifndef VIRTOOLS_RUNTIME_VERSION CKDWORD res = m_Context->SendInterfaceMessage(CKUIM_MESSAGEBOX,(CKDWORD)STR_SELECTIONSET,(CKDWORD)STR_OBJECTS_REMOVED_ON_RELOAD,1); if (res==IDYES) #endif { SelectionSetData* data = GetSelectionSetData(ioGrp); CKDependenciesContext depctx(m_Context); #ifdef SELECTIONSET_USE_DEPENDENCIES if (data && data->m_SaveDependencies.Size()) depctx.StartDependencies(&data->m_SaveDependencies); else #endif depctx.StartDependencies(&m_SaveSetDependencies); XObjectArray::Iterator it1 = toDeleteList.Begin(); XObjectArray::Iterator it2 = toDeleteList.End(); while (it1!=it2) { CK_ID id = *it1++; CKObject* obj = m_Context->GetObject(id); obj->PrepareDependencies(depctx); } dependArray = depctx.FillDependencies(); } m_Context->DestroyObjects(toDeleteList.Begin(),toDeleteList.Size()); //offer to open unused object explorer here if objects were deleted #ifndef VIRTOOLS_RUNTIME_VERSION if (res==IDYES) { //ask to open unused object explorer in interface m_Context->SendInterfaceMessage(CKUIM_OPEN_UNUSED_OBJECTS_EXPLORER,(CKDWORD)&dependArray,0); } #endif } } //compact on load, optional if (m_CompactSetOnLoad) { XArray grps; grps.PushBack(setgrp); CompactSets(grps); } //to send to those who dont want to hav the notif (OBJECT_CREATED), like schematic, cos of addtoscene m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_PRECKFILELOADED,(DWORD)liste); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_CKFILELOADED,(DWORD)liste); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_HIERARCHY_CHANGED,(DWORD)liste); DeleteCKObjectArray(liste); if (iUserManualReload) { if (data->HasFlags(SelectionSetData::fSetFlags_Temp_Recreated)) { #ifndef VIRTOOLS_RUNTIME_VERSION DWORD param2=MAKELPARAM(1,fSetPart_All); CK_ID id = setgrp->GetID(); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&id,param2); #endif data->ModifyFlags(0,SelectionSetData::fSetFlags_Temp_Recreated); } RenderNow(); m_Context->SendInterfaceMessage(CKUIM_SETPROJECTMODIFIED,1,0); } m_NotToSaveObjectList.Clear(); ioGrp = setgrp; //update output grp return eSetLoad_Success; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::UnloadSets(XArray &iGrps,BOOL iDeleteGroup) { XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKGroup* iGrp = *it1++; XArray array; CKDependencies* dep = &m_SaveSetDependencies; SelectionSetData* data = GetSelectionSetData(iGrp); #ifdef SELECTIONSET_USE_DEPENDENCIES if (data && data->m_SaveDependencies.Size()) dep = &data->m_SaveDependencies; #endif //check if set has a path and existing file.nmo before unload XString path; BOOL pathok = GetSelectionSetPath(iGrp,path); if (pathok) { pathok = PathFileExists(path.CStr()); } if (pathok) { int count = iGrp->GetObjectCount(); for (int i=0;iGetObject(i); array.PushBack(beo->GetID()); } if (iDeleteGroup) { array.PushBack(iGrp->GetID()); //DeleteSelectionSetData(iGrp); useless cause done in notification } data->ModifyFlags(0,SelectionSetData::fSetFlags_Loaded|SelectionSetData::fSetFlags_SaveWithCmo); //flag as unloaded //if unloaded, it must not be saved on cmo save anymore !! } else { XString str; str.Format(STR_SETNOTUNLOADED,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET); m_Context->OutputToConsole(str.Str(),TRUE); } m_Context->DestroyObjects(array.Begin(),array.Size(),0,dep); } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SaveGroup(CKGroup* iGrp,const char* iPath,CKDependencies* iDep,CKObjectArray* iToAppend) { if (!iGrp || !iPath) return CK_OK; BOOL dynamic = FALSE; if (iGrp->IsDynamic()) dynamic = TRUE; CKDependenciesContext dependencies_ctx(m_Context); dependencies_ctx.SetOperationMode(CK_DEPENDENCIES_SAVE); dependencies_ctx.StartDependencies(iDep); //We scan the group and fill the dependencies context for (int i=0;iGetObjectCount();i++) { CKBeObject* object = iGrp->GetObject(i); object->PrepareDependencies(dependencies_ctx); } // Build a list of id to save XObjectArray dependencies_list = dependencies_ctx.FillDependencies(); dependencies_list.PushBack(iGrp->GetID());//add group at the end //copy list of objects in ckobjectarray CKObjectArray* listToSave = CreateCKObjectArray(); XObjectArray::Iterator it1 = dependencies_list.Begin(); XObjectArray::Iterator it2 = dependencies_list.End(); if (dynamic) { while (it1!=it2) { CKObject* object = m_Context->GetObject(*it1); object->ModifyObjectFlags(0,CK_OBJECT_DYNAMIC); listToSave->InsertRear(*it1++); } } else while (it1!=it2) { //CKObject* object = m_Context->GetObject(*it1); listToSave->InsertRear(*it1++); } //Now we save the array CKERROR err = CK_OK; if (listToSave->GetCount()) { //listToSave->InsertRear(iom); listToSave->Append(iToAppend); /* CKFile *file=m_Context->CreateCKFile(); if (!file) return CKERR_OUTOFMEMORY; if (file) { file->StartSave((CKSTRING)iPath,0); file->SaveObjects(listToSave,0); err=file->EndSave(); } m_Context->DeleteCKFile(file); */ //cette merde de code sauve de toute facon avec CK_STATESAVE_ALL et il faut pas CKPluginManager* pluginManager = CKGetPluginManager(); /* not enough to keep interface scripts, should be used before loading maybe BOOL isInInterfaceMode = m_Context->IsInInterfaceMode(); if (!isInInterfaceMode) m_Context->SetInterfaceMode(TRUE); */ ModifyFlags(fSetMgrFlags_SkipNextLoadSave); err = pluginManager->Save(m_Context,(CKSTRING)iPath,listToSave,0,NULL); ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave); /* if (!isInInterfaceMode) m_Context->SetInterfaceMode(FALSE); */ } if (dynamic) { it1 = dependencies_list.Begin(); while (it1!=it2) { CKObject* object = m_Context->GetObject(*it1++); object->ModifyObjectFlags(CK_OBJECT_DYNAMIC,0); } } DeleteCKObjectArray(listToSave); return err; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::GetUniqueSelectionSetName(CKGroup* iGrp,XString* ioName,BOOL iSetName,BOOL iSendNotification) { if (!ioName || (iSetName && !iGrp)) return FALSE; XString baseName = *ioName; int maxcount = -1; //occurence of basename int index = baseName.RFind('.'); if (index!=XString::NOTFOUND) { baseName = baseName.Substring(0,index); } BOOL needChange = FALSE; XArray sets; GetSelectionSets(sets); XArray::Iterator it1 = sets.Begin(); XArray::Iterator it2 = sets.End(); while (it1!=it2) { CKGroup* tmpGrp = *it1++; if (tmpGrp!=iGrp && *ioName==tmpGrp->GetName()) { needChange = TRUE; break; } } if (needChange) { it1 = sets.Begin(); while (it1!=it2) { CKGroup* tmpGrp = *it1++; if (tmpGrp!=iGrp) { XString tmpName = tmpGrp->GetName(); index = tmpName.RFind('.'); XString tmpBaseName = tmpName; if (index!=XString::NOTFOUND) tmpBaseName = tmpName.Substring(0,index); if (tmpBaseName==baseName) { //look extension to see max count XString name=tmpGrp->GetName(); if (!name.Length()) continue; name.ToLower(); int p=name.Length(); while (p>0) { char ch=name[--p]; if (ch<'0' || ch>'9') break; //{ name.Delete(0,p+1); break; } } int val=0; if (p+1maxcount) maxcount=val; } } } maxcount++; if (maxcount>0) { ioName->Format("%s.%04d",baseName.CStr(),maxcount); } } if (iGrp && iSetName) { iGrp->SetName(ioName->Str()); if (iSendNotification) m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_OBJECTRENAMED,iGrp->GetID()); } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// int SelectionSetManager::GetSelectionSetCount() { XArray sets; GetSelectionSets(sets); return sets.Size(); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKGroup* SelectionSetManager::GetSelectionSet(int iIndex) { XArray sets; GetSelectionSets(sets); if (iIndex>=0 && iIndex &iGrps) { if (iGrps.Size()==0) return CKERR_INVALIDPARAMETER; if (!CheckIsSelectionSet(iGrps[0])) return CKERR_INVALIDPARAMETER; int priority=0; SelectionSetData* data = GetSelectionSetData(iGrps[0]); if (data) priority=data->m_Priority; CKParameter* pparam = m_Context->CreateCKParameterLocal(STR_PRIORITY,CKPGUID_INT); if (!pparam) return CKERR_INVALIDPARAMETER; pparam->SetValue(&priority,FALSE); CK_ID id = pparam->GetID(); CKERROR res = CK_OK; #ifndef VIRTOOLS_RUNTIME_VERSION res = m_Context->SendInterfaceMessage(CKUIM_EDITOBJECT,(DWORD)&id,1,(DWORD)STR_EDITSETPRIORITY); if (res ==IDOK) #endif { pparam->GetValue(&priority); SetSetPriority(iGrps,priority); } m_Context->DestroyObject(id,CK_DESTROY_NONOTIFY|CK_DESTROY_FREEID); return res; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::EditSetFlags(XArray &iGrps) { if (iGrps.Size()==0) return CKERR_INVALIDPARAMETER; if (!CheckIsSelectionSet(iGrps[0])) return CKERR_INVALIDPARAMETER; SelectionSetData* data = CreateSelectionSetData(iGrps[0]); if (data) { CKParameter* pparam= m_Context->CreateCKParameterLocal(STR_SETENUM_NAME,CKPGUID_SETENUM); if (!pparam) return CKERR_INVALIDPARAMETER; int value = data->m_Flags & 0x03; pparam->SetValue(&value); CK_ID id = pparam->GetID(); CKERROR res = CK_OK; #ifndef VIRTOOLS_RUNTIME_VERSION res = m_Context->SendInterfaceMessage(CKUIM_EDITOBJECT,(DWORD)&id,1,(DWORD)STR_EDITSETFLAGS); if (res ==IDOK) #endif { pparam->GetValue(&value); XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = CreateSelectionSetData(grp); if (data) { data->m_Flags &= ~3; data->m_Flags |= value; } } #ifndef VIRTOOLS_RUNTIME_VERSION if (iGrps.Size()>0) { XArray ids; CKGroupToCKIDArray(&iGrps,&ids); DWORD param2=MAKELPARAM(ids.Size(),fSetPart_Options); m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)ids.Begin(),param2); } #endif } m_Context->DestroyObject(id,CK_DESTROY_NONOTIFY|CK_DESTROY_FREEID); return res; } return CKERR_INVALIDPARAMETER; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // CK CALLBACKS //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::OnCKInit() { if (m_Context==0) return CKERR_INVALIDPARAMETER; //create flag parameter for SetProperties/GetProperties BBs { CKParameterManager* pm = m_Context->GetParameterManager(); #ifdef ENABLE_REPLACE_AND_SHARE pm->RegisterNewFlags(PARAMGUID_SETPROPERTIES,"SelectionSet Properties","Priority=1,External=2,Loaded=4,Hierarchy Rebuild=8,Path=16,Load with cmo=32,Save with cmo=64,Load Mode=128"); #else pm->RegisterNewFlags(PARAMGUID_SETPROPERTIES,"SelectionSet Properties","Priority=1,External=2,Loaded=4,Hierarchy Rebuild=8,Path=16,Load with cmo=32,Save with cmo=64"); #endif // We hide the parameters (structures and flags) CKParameterTypeDesc* param_type = pm->GetParameterTypeDescription(PARAMGUID_SETPROPERTIES); if (param_type) param_type->dwFlags|=CKPARAMETERTYPE_HIDDEN; } //get version control if available m_Context->SendInterfaceMessage(CKUIM_GETVERSIONCONTROLINFO,(DWORD)&m_VCI,0); m_Version = SELECTIONSETMANAGER_SAVEVERSION; //init global dependencies //CKCopyDefaultClassDependencies(m_ReloadSetDependencies,CK_DEPENDENCIES_DELETE); //CKCopyDefaultClassDependencies(m_PreSaveCmoDependencies,CK_DEPENDENCIES_DELETE); CKCopyDefaultClassDependencies(m_SaveSetDependencies,CK_DEPENDENCIES_COPY); BINDREP(m_Context,"File Options/Selection Sets Reference",&m_IncludeSelectionSetSaveOption,1,VxVar::NATIVECOMPOSITIONBOUND,"enum:0=References Original Files;1=Includes Original Files;2=Force References Original Files;3=Force Includes Original Files","Global Selection Sets saving options."); //BINDREP(m_Context,"File Options/Selection Sets Save",&m_SaveExternalSetsOnCmoSave,1,VxVar::NATIVECOMPOSITIONBOUND,"enum:0=Do not save sets on cmo save;1=Save sets on cmo save","Save external selection sets on cmo save option."); BINDREP(m_Context,"File Options/Selection Sets Save Backup",&m_BackupOnSaveSet,0,VxVar::NATIVECOMPOSITIONBOUND,"enum:0=Do not backup;1=Backup","Backup old file when saving selection set option."); BINDREP(m_Context,"File Options/Selection Sets Compact on Load",&m_CompactSetOnLoad,0,VxVar::NATIVECOMPOSITIONBOUND,"bool:","External loaded sets will be compacted, that is only objects without parent, according to dependencies, will be listed.") m_SaveSetDependencies[CKCID_MESH] |= CK_DEPENDENCIES_DESTROY_MESH_MATERIAL; m_SaveSetDependencies[CKCID_3DENTITY] |= CK_DEPENDENCIES_DESTROY_3DENTITY_MESH| CK_DEPENDENCIES_DESTROY_3DENTITY_CHILDREN| CK_DEPENDENCIES_DESTROY_3DENTITY_ANIMATIONS; m_SaveSetDependencies[CKCID_MATERIAL] |= CK_DEPENDENCIES_DESTROY_MATERIAL_TEXTURE; m_SaveSetDependencies[CKCID_SPRITE3D] |= CK_DEPENDENCIES_DESTROY_SPRITE3D_MATERIAL; m_SaveSetDependencies[CKCID_TARGETCAMERA] |= CK_DEPENDENCIES_DESTROY_TARGETCAMERA_TARGET; m_SaveSetDependencies[CKCID_TARGETLIGHT] |= CK_DEPENDENCIES_DESTROY_TARGETLIGHT_TARGET; if (CKGetClassCount()>CKCID_VIDEO) m_SaveSetDependencies[CKCID_VIDEO] |= 1; #ifdef SELECTIONSET_USE_DEPENDENCIES //load global dependencies XString filename = GetVirtoolsDirectory(); filename += "\\" FILE_DEPENDENCIES_INI; CKStateChunk* chunk = CreateCKStateChunk(CKCID_OBJECT); if (ReadChunkFromFile(chunk,filename)) { chunk->StartRead(); if (chunk->SeekIdentifier(SELECTIONSET_DEPENDENCIES_CHUNK_SAVE_IDENTIFIER)) { //LoadDependenciesFromChunk(&m_ReloadSetDependencies,chunk); //LoadDependenciesFromChunk(&m_PreSaveCmoDependencies,iChunk); LoadDependenciesFromChunk(&m_SaveSetDependencies,chunk); } chunk->CloseChunk(); } DeleteCKStateChunk(chunk); #endif CKParameterManager* pMgr=m_Context->GetParameterManager(); if (pMgr) { CKERROR error = pMgr->RegisterNewEnum(CKPGUID_SETENUM,STR_EDITSETFLAGS, "Use Global Options=0,Force Save As External=1,Force Save As Internal=2"); if (error==CK_OK) { CKParameterTypeDesc* desc = pMgr->GetParameterTypeDescription(CKPGUID_SETENUM); desc->dwFlags |= CKPARAMETERTYPE_HIDDEN; } } //create backup chunk m_LoadChunk = CreateCKStateChunk(CKCID_OBJECT); //create parameter that can list selectionset (groups not to be listed & save) in dev's ui RegisterCKSelectionSetParameter(m_Context); //vsl bind Bind(); return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::OnCKEnd() { if (m_Context==0) return CKERR_INVALIDPARAMETER; CKParameterManager* pm = m_Context->GetParameterManager(); if (pm) pm->UnRegisterParameterType(PARAMGUID_SETPROPERTIES); UnRegisterCKSelectionSetParameter(m_Context); //vsl unbind UnBind(); if (m_LoadChunk) DeleteCKStateChunk(m_LoadChunk); m_LoadChunk = 0; CKParameterManager* pMgr=m_Context->GetParameterManager(); if (pMgr) { CKERROR error = pMgr->UnRegisterParameterType(CKPGUID_SETENUM); } UNBIND(m_Context,"File Options/Selection Sets Reference"); //UNBIND(m_Context,"File Options/Selection Sets Save"); UNBIND(m_Context,"File Options/Selection Sets Save Backup"); UNBIND(m_Context,"File Options/Selection Sets Compact on Load"); #ifdef SELECTIONSET_USE_DEPENDENCIES //save global dependencies XString filename = GetVirtoolsDirectory(); filename += "\\" FILE_DEPENDENCIES_INI; CKStateChunk* chunk = CreateCKStateChunk(CKCID_OBJECT); chunk->StartWrite(); chunk->WriteIdentifier(SELECTIONSET_DEPENDENCIES_CHUNK_SAVE_IDENTIFIER); //SaveDependenciesInChunk(&m_ReloadSetDependencies,chunk); //SaveDependenciesInChunk(&m_PreSaveCmoDependencies,iChunk); SaveDependenciesInChunk(&m_SaveSetDependencies,chunk); chunk->CloseChunk(); SaveChunkInFile(chunk,filename); DeleteCKStateChunk(chunk); #endif m_SaveSetDependencies.Clear(); return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::PostProcess() { if (m_WebDownloadSets.Size()) { WebDownloadSet(); } return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::PreClearAll() { CloseExternalFileSets(); ClearSelectionSetsDatas(); return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SequenceAddedToScene(CKScene *scn,CK_ID *objids,int count) { if (HasFlags(fSetMgrFlags_LoadingSet|fSetMgrFlags_SkipNextLoadSave)) //if skip or loading set, skip return CK_OK; for (int i=count-1;i>=0;i--) { CKObject* obj = m_Context->GetObject(objids[i]); //if loaded a group flagged as selection set //outside from the SelectionSetManager::LoadSelectionSet functions if (CKIsChildClassOf(obj,CKCID_GROUP) && (obj->GetObjectFlags() & CK_OBJECT_SELECTIONSET)) { XString fname; if (m_LastFile.Length()) fname = m_LastFile; CreateSelectionSet((CKGroup*)obj,&fname); return CK_OK; } } return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::SequenceToBeDeleted(CK_ID *objids,int count) { if (objids==0 || count==0) return CK_OK; for (int i=0; iGetObject(objids[i]); if (CKIsChildClassOf(obj,CKCID_GROUP)) { if (DeleteSelectionSetData((CKGroup*)obj))//check if selection set is done inside { //RemapSelectionSetParameters((CKGroup*)obj,FALSE); //not usefull there, because mapping name is used only on loading (unload destroy then reload) } } } return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKStateChunk* SelectionSetManager::SaveData(CKFile* SavedFile) { //skip if not cmo/vmo BOOL cmo = UpdateLastDir(eUseParam,SavedFile->m_FileName); if (!cmo) { ModifyFlags(fSetMgrFlags_SkipNextLoadSave); return 0; } XArray selectionSets; GetSelectionSets(selectionSets); if (selectionSets.Size()>0) { CKStateChunk* chunk=CreateCKStateChunk(CKCID_OBJECT,SavedFile); chunk->StartWrite(); SaveSelectionSetInChunk(chunk,TRUE,&selectionSets); SaveSelectionSetParameters(chunk); chunk->CloseChunk(); return chunk; } return 0; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::LoadData(CKStateChunk *chunk,CKFile* LoadedFile) { //skip if not cmo/vmo BOOL cmo = UpdateLastDir(eUseParam,LoadedFile->m_FileName); if (!cmo) { ModifyFlags(fSetMgrFlags_SkipNextLoadSave); return 0; } /* //won't work cause after LoadData, //Scene::Load is called, and removes all objects from scene before reloading them from a chunk //to create objects, create them in postload chunk->StartRead(); if (LoadSelectionSetFromChunk(chunk,TRUE)) return CK_OK; return CKERR_INVALIDPARAMETER; */ //save chunk buffer (and clear chunk buffer at the same time, not time wasted to copy) //chunk will be deleted after this :LoadData if (!m_LoadChunk) { assert(0);//should never go here, chunk is create once & for all and OnCKInit m_LoadChunk = CreateCKStateChunk(CKCID_OBJECT); } if (m_LoadChunk) { m_LoadChunk->Clear(); m_LoadChunk->m_Parser = chunk->m_Parser; chunk->m_Parser = NULL; m_LoadChunk->m_ChunkVersion = chunk->m_ChunkVersion; m_LoadChunk->m_DataVersion = chunk->m_DataVersion; m_LoadChunk->m_Options = chunk->m_Options; m_LoadChunk->m_File = chunk->m_File; m_LoadChunk->m_Buffer.Swap(chunk->m_Buffer); } return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::PreSave() { //HACK into CK2 to know the filename if (m_Context->m_LoadedFile && m_Context->m_LoadedFile->m_FileName) { BOOL cmo = UpdateLastDir(eUseParam,m_Context->m_LoadedFile->m_FileName); if (!cmo) { ModifyFlags(fSetMgrFlags_SkipNextLoadSave); return 0; } } //skip this presave, if this flag is set (have been set cause we are saving selection set) if (HasFlags(fSetMgrFlags_SkipNextLoadSave)) { return CK_OK; } #pragma todo("voir le presave pr le mode share&replace") //return PreSave2(); XArray sets; GetSelectionSets(sets); SelectionSetData emptyData; int externalSetsCount=0; //the dependencies CKDependenciesContext dep_ctx(m_Context); dep_ctx.SetOperationMode(CK_DEPENDENCIES_SAVE); #ifdef SELECTIONSET_USE_DEPENDENCIES CKDependencies *dep = 0; #else CKDependencies *dep = &m_SaveSetDependencies; dep_ctx.StartDependencies(dep); #endif BOOL shareSet = FALSE; //used to know if there is a non emtpy set in "Share & Replace" mode //check if there are external sets XArray::Iterator it1 = sets.Begin(); XArray::Iterator it2 = sets.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); if (!data) data = &emptyData; BOOL external = data->CheckSaveExternal(this); if (external) { externalSetsCount++; #ifdef SELECTIONSET_USE_DEPENDENCIES //choose dependencies if (data->m_SaveDependencies.Size()) { if (dep) dep_ctx.StopDependencies(); dep = &data->m_SaveDependencies; dep_ctx.StartDependencies(dep); } else if (dep!=&m_SaveSetDependencies) { if (dep) dep_ctx.StopDependencies(); dep = &m_SaveSetDependencies; dep_ctx.StartDependencies(dep); } #endif if (data->HasFlags(SelectionSetData::fSetFlags_ReplaceAndShare)) //special for replace & share sets { //flag group objects immediatly & prepare dependencies //add object to not to save list //We scan the group and fill the dependencies context if (grp->GetObjectCount()) shareSet=TRUE; for (int i=0;iGetObjectCount();i++) { //do this to store all dependencies CKBeObject* object = grp->GetObject(i); CK_ID id = object->GetID(); object->PrepareDependencies(dep_ctx); //flag this object as selection set objects object->ModifyObjectFlags(CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET,0); } } else //ignore & no share sets, just prepare dependencies { //add object to not to save list //We scan the group and fill the dependencies context for (int i=0;iGetObjectCount();i++) { //do this to store all dependencies CKBeObject* object = grp->GetObject(i); CK_ID id = object->GetID(); object->PrepareDependencies(dep_ctx); } } } } //check for shared objects if (shareSet) { } //external sets detected, now get all dependencies & flag them as "not to be saved" if (externalSetsCount>0) { //do this to get all dependencies m_NotToSaveObjectList = dep_ctx.FillDependencies(); XObjectArray::Iterator it1 = m_NotToSaveObjectList.Begin(); XObjectArray::Iterator it2 = m_NotToSaveObjectList.End(); while (it1!=it2) { //modify objects flags so not to save them CK_ID id = *it1++; CKObject* obj = m_Context->GetObject(id); if (obj && !(obj->GetObjectFlags() & CK_OBJECT_NOTTOBESAVED) ) { //add CK_OBJECT_SELECTIONSET in order memorize that this object's flags has been changed obj->ModifyObjectFlags(CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET,0); } } } return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::PostSave() { if (HasFlags(fSetMgrFlags_SkipNextLoadSave)) { ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave); return CK_OK; } //skip if not cmo/vmo UpdateLastDir(eUseLastSavedCMO); //store if there is external sets BOOL external = (m_NotToSaveObjectList.Size()>0)?TRUE:FALSE; XObjectArray::Iterator it1 = m_NotToSaveObjectList.Begin(); XObjectArray::Iterator it2 = m_NotToSaveObjectList.End(); while (it1!=it2) { CK_ID id = *it1++; CKObject* obj = m_Context->GetObject(id); if (obj && (obj->GetObjectFlags() & CK_OBJECT_SELECTIONSET) ) { //remove flags obj->ModifyObjectFlags(0,CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET|CK_OBJECT_LOADREPLACINGOBJECT|CK_OBJECT_LOADSKIPBEOBJECT); } } XString errorLog; //clear arrays m_NotToSaveObjectList.Clear(); BOOL warning_externalset_unsaved = FALSE; //save external sets if (external/* && m_SaveExternalSetsOnCmoSave*/) { XArray sets; GetSelectionSets(sets,TRUE); SelectionSetData emptyData; //check if there are external sets XArray::Iterator it1 = sets.Begin(); XArray::Iterator it2 = sets.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); if (!data) data = &emptyData; BOOL external = data->CheckSaveExternal(this); if (external) { if (data->HasFlags(SelectionSetData::fSetFlags_SaveWithCmo))//must have flag fSetFlags_SaveWithCmo { //ModifyFlags(fSetMgrFlags_SkipNextLoadSave); SaveSelectionSet(grp,FALSE,&errorLog); //ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave); } else if (data->HasFlags(SelectionSetData::fSetFlags_Loaded))//loaded set not saved warning_externalset_unsaved = TRUE; } } } if (errorLog.Length()) { m_Context->OutputToConsole(STR_SAVEWARNING,FALSE); m_Context->OutputToConsole(errorLog.Str(),TRUE); } if (warning_externalset_unsaved) { } return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* CKERROR SelectionSetManager::PreLoad() { int toto=0; return CK_OK; } */ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::PostLoad() { if (HasFlags(fSetMgrFlags_SkipNextLoadSave)) { ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave); return CK_OK; } //skip if not cmo/vmo UpdateLastDir(eUseLastLoadedCMO); if (m_LoadChunk && m_LoadChunk->GetDataSize()) { //done in LoadSelectionSetFromChunk before each set load : //ModifyFlags(fSetMgrFlags_SkipNextLoadSave); //prevent future postload calls //because LoadSelectionSetFromChunk //-> may loads external nmo //no call to loaddata, but call to manager::postload int datasize = m_LoadChunk->GetDataSize(); m_LoadChunk->StartRead(); BOOL ok = LoadSelectionSetFromChunk(m_LoadChunk,TRUE); LoadSelectionSetParameters(m_LoadChunk); m_LoadChunk->Clear(); datasize = m_LoadChunk->GetDataSize(); ModifyFlags(0,fSetMgrFlags_SkipNextLoadSave);//restore for future postload calls if (ok) return CK_OK; return CKERR_INVALIDPARAMETER; } return CK_OK; } CKERROR SelectionSetManager::PostClearAll() { UpdateLastDir(ePostClearAll); return CK_OK; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::PreSave2() { XArray sets; //list of selection sets SelectionSetData emptyData; //empty data used for sets without data int externalSetsCount=0; //external sets count BOOL shareSet = FALSE; //used to know if there is a non emtpy set in "Share & Replace" mode XObjectArray listNotToSave; //list of objects not to be saved GetSelectionSets(sets); //check if there are external sets XArray::Iterator it1 = sets.Begin(); XArray::Iterator it2 = sets.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); if (!data) data = &emptyData; BOOL external = data->CheckSaveExternal(this); if (external) { externalSetsCount++; //the dependencies CKDependenciesContext dep_ctx(m_Context); dep_ctx.SetOperationMode(CK_DEPENDENCIES_SAVE); CKDependencies* dep=0; //dependencies used per set #ifdef SELECTIONSET_USE_DEPENDENCIES //choose dependencies if (data->m_SaveDependencies.Size()) { dep = &data->m_SaveDependencies; dep_ctx.StartDependencies(dep); } else if (dep!=&m_SaveSetDependencies) { dep = &m_SaveSetDependencies; dep_ctx.StartDependencies(dep); } #else dep = &m_SaveSetDependencies; dep_ctx.StartDependencies(dep); #endif //get all set's objects with their dependencies for (int i=0;iGetObjectCount();i++) { //do this to store all dependencies CKBeObject* object = grp->GetObject(i); CK_ID id = object->GetID(); object->PrepareDependencies(dep_ctx); } //get object list and flag it XObjectArray array = dep_ctx.FillDependencies();//get these objects in array dep_ctx.StopDependencies(); if (data->HasFlags(SelectionSetData::fSetFlags_ReplaceAndShare)) //special for replace & share sets { //flag group objects immediatly & prepare dependencies if (array.Size()) shareSet=TRUE; //flag this object as selection set objects XObjectArray::Iterator it1 = array.Begin(); XObjectArray::Iterator it2 = array.End(); while (it1!=it2) { //modify objects flags so not to save them CK_ID id = *it1++; CKObject* object = m_Context->GetObject(id); object->ModifyObjectFlags(CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET|CK_OBJECT_LOADREPLACINGOBJECT,0); if (object->GetObjectFlags() & CK_OBJECT_LOADSKIPBEOBJECT) {//warning this objects belong to a "Ignore & not share" set ! } } } else //ignore & no share sets, just prepare dependencies { XObjectArray::Iterator it1 = array.Begin(); XObjectArray::Iterator it2 = array.End(); while (it1!=it2) { //modify objects flags so not to save them CK_ID id = *it1++; CKObject* object = m_Context->GetObject(id); object->ModifyObjectFlags(CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET|CK_OBJECT_LOADSKIPBEOBJECT,0); if (object->GetObjectFlags() & CK_OBJECT_LOADREPLACINGOBJECT) {//warning this objects belong to a "Replace & share" set ! } } } //add this list in global not to save list m_NotToSaveObjectList += array; } } //check for shared objects if (shareSet && externalSetsCount>0 && m_NotToSaveObjectList.Size()) { const XObjectPointerArray& listArray = m_Context->GetObjectListByType(CKCID_DATAARRAY,TRUE); const XObjectPointerArray& listGroup = m_Context->GetObjectListByType(CKCID_GROUP,TRUE); const XObjectPointerArray& list2d = m_Context->GetObjectListByType(CKCID_2DENTITY,TRUE); const XObjectPointerArray& list3d = m_Context->GetObjectListByType(CKCID_3DENTITY,TRUE); CKDependencies savedep; CKCopyDefaultClassDependencies(savedep,CK_DEPENDENCIES_SAVE); const XObjectPointerArray* lists[4]; lists[0] = &listArray; lists[1] = &listGroup; lists[2] = &list2d; lists[3] = &list3d; for (int i=0;i<4;++i) { XObjectPointerArray::Iterator it1,it2; it1 = lists[i]->Begin(); it2 = lists[i]->End(); while (it1!=it2) { CKObject* obj = *it1++; if ( (obj->GetObjectFlags() & (CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET))==0) {//this objects is to be saved in cmo CKDependenciesContext dep_ctx(m_Context); dep_ctx.SetOperationMode(CK_DEPENDENCIES_SAVE); //dep_ctx.StartDependencies(&savedep); dep_ctx.StartDependencies(&m_SaveSetDependencies); obj->PrepareDependencies(dep_ctx); XObjectArray depList = dep_ctx.FillDependencies(); //now parse dependencies and check for shared objects XObjectArray::Iterator dit1 = depList.Begin(); XObjectArray::Iterator dit2 = depList.End(); while (dit1!=dit2) { CK_ID id = *dit1++; CKObject* dobj = m_Context->GetObject(id); DWORD flags = dobj->GetObjectFlags(); if ( (flags & (CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET|CK_OBJECT_LOADREPLACINGOBJECT) ) == (CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET|CK_OBJECT_LOADREPLACINGOBJECT) ) {//this objects has been flagged as not to be saved from a SHARED set, is shared , so unflag it for cmo to be able to save it dobj->ModifyObjectFlags(0,CK_OBJECT_NOTTOBESAVED|CK_OBJECT_SELECTIONSET|CK_OBJECT_LOADREPLACINGOBJECT); } } dep_ctx.StopDependencies(); } } } } return TRUE; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// // CK PARAMETER SELECTIONSET //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::RegisterSelectionSetParameter(CKParameter* iParam) { m_SelectionSetParams.PushBack(iParam->GetID()); } void SelectionSetManager::UnRegisterSelectionSetParameter(CK_ID iID) { m_SelectionSetParams.Remove(iID); } void SelectionSetManager::SaveSelectionSetParameters(CKStateChunk* iChunk) { int count = m_SelectionSetParams.Size(),realCount = 0; if (count<=0) return; iChunk->WriteIdentifier(SELECTIONSET_CHUNK_SAVEPARAMETERS_IDENTIFIER); int countPosition = iChunk->GetCurrentPos(); //bookmark iChunk->WriteInt(count); for (int i=0;iGetObject(paramid); if (CKIsChildClassOf(p,CKCID_PARAMETER)) { CKObject* obj = p->GetValueObject(); if (CKIsChildClassOf(obj,CKCID_GROUP) && obj->GetName()) { iChunk->WriteObjectID(paramid); iChunk->WriteString(obj->GetName()); realCount++; } } } int lastPosition = iChunk->GetCurrentPos(); //bookmark iChunk->Goto(countPosition); iChunk->WriteInt(realCount);//update count iChunk->Goto(lastPosition); } void SelectionSetManager::LoadSelectionSetParameters(CKStateChunk* iChunk) { if (iChunk->SeekIdentifier(SELECTIONSET_CHUNK_SAVEPARAMETERS_IDENTIFIER)) { SelectionSetArray sets; GetSelectionSets(sets); int count = iChunk->ReadInt(); for (int i=0;iReadObjectID(); XString str; iChunk->ReadString(str); CKParameter* p = (CKParameter*)m_Context->GetObject(paramid); if (CKIsChildClassOf(p,CKCID_PARAMETER)) { SelectionSetIT setit1 = sets.Begin(); SelectionSetIT setit2 = sets.End(); while (setit1!=setit2) { CKGroup* set = *setit1++; if (CKSTRING name = set->GetName()) { if (str==name) { CK_ID setid = set->GetID(); p->SetValue(&setid); break; } } } } } } } void SelectionSetManager::RemapSelectionSetParameters(CKGroup* iGrp,BOOL iCreated) { if (!iCreated) m_params2remap.Clear(); if (!CKIsChildClassOf(iGrp,CKCID_GROUP)) return; CK_ID grpID = iGrp->GetID(); XArray::Iterator it1,it2; if (iCreated) { it1 = m_params2remap.Begin(); it2 = m_params2remap.End(); while (it1!=it2) { CK_ID paramid = *it1++; CKParameter* p = (CKParameter*)m_Context->GetObject(paramid); if (CKIsChildClassOf(p,CKCID_PARAMETER)) p->SetValue(&grpID); } } else { it1 = m_SelectionSetParams.Begin(); it2 = m_SelectionSetParams.End(); while (it1!=it2) { CK_ID paramid = *it1++; CKParameter* p = (CKParameter*)m_Context->GetObject(paramid); if (!CKIsChildClassOf(p,CKCID_PARAMETER)) continue; CK_ID objid = 0; if (CK_OK==p->GetValue(&objid) && objid==grpID)//if refers to deleted group { CKObject* obj = m_Context->GetObject(objid); if (obj) { CK_ID id0 = 0; p->SetValue(&id0); m_params2remap.PushBack(paramid); } } } } /* MapID2StringIT it1 = m_MapParam2SetName.Begin(),it2=m_MapParam2SetName.End(); while (it1!=it2) { CK_ID paramid = it1++.GetKey(); CKParameter* p = (CKParameter*)m_Context->GetObject(paramid); if (!CKIsChildClassOf(p,CKCID_PARAMETER)) continue; if (iCreated) //group created, check if group name = param's value saved name & remap { XString& paramname = m_MapParam2SetName[paramid]; if (paramname==iGrp->GetName()) { p->SetValue(&grpID); } } else //group delete save group name in map { CK_ID objid = 0; if (CK_OK==p->GetValue(&objid) && objid==grpID)//if refers to deleted group { CKObject* obj = m_Context->GetObject(objid); if (obj) { CK_ID i d0 = 0; p->SetValue(&id0); m_MapParam2SetName[paramid] = obj->GetName(); } } } } */ } XHashTable m_MapParam2SetName; //**************************************************************************************** #ifdef EXCLUDED_CODE//**************************************************************************************** //**************************************************************************************** //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// BOOL SelectionSetManager::ReloadSelectionSet(CKGroup* iGrp,BOOL iUserManualReload,XString* oErrorLog) { if (!CKIsChildClassOf(iGrp,CKCID_GROUP)) return FALSE; XString currentPath; if (!GetSelectionSetPath(iGrp,currentPath)) return FALSE; if (currentPath.Length()==0) return FALSE; //ask to get latest version VersionControlInfo* vci = g_cuikPluginManager.GetVersionControlInterface(); if (vci && vci->m_GetLatestVersion) { const char* file = currentPath.CStr(); vci->m_GetLatestVersion(&file,1,TRUE);//true means dependency file } XArray sets; sets.PushBack(iGrp); UnloadSets(sets); /*USED TO RELOAD WITHOUT UNLOADING SET //store old objects list m_NotToSaveObjectList.Clear(); int i,count=iGrp->GetObjectCount(); for (i=0;iGetObject(i); m_NotToSaveObjectList.PushBack(obj->GetID()); } */ CKObjectArray* liste = CreateCKObjectArray(); if (!liste) return FALSE; CMessageDlg* loadStepDlg=new CMessageDlg; loadStepDlg->Create(); loadStepDlg->SetMessage(CUIKLM_FILEIO_DIALOGS_LOADINGFILE); BOOL runtime=m_Context->IsRunTime(); //USED TO RELOAD WITHOUT UNLOADING SET: replace //DWORD loadingFlags = CK_LOAD_REPLACEALL_WITHSCRIPT|CK_LOAD_CHECKDUPLICATES|CK_LOAD_DODIALOG; DWORD loadingFlags = 0; CKERROR error=m_Context->Load(currentPath.Str(),liste,(CK_LOAD_FLAGS)(loadingFlags)); delete loadStepDlg; loadStepDlg=NULL; if (error!=0) { if (oErrorLog) { XString buffer; SelectionSetData* data = GetSelectionSetData(iGrp); buffer=CUIKLM_FILEIO_ERRORS_LOADFAILED; buffer.Format("%s (%s)",buffer.CStr(),data?data->m_Path:"no path"); if ((*oErrorLog).Length()>0) (*oErrorLog)+="\n"; (*oErrorLog)+=buffer; } else { XString buffer=CUIKLM_FILEIO_ERRORS_LOADFAILED; NeMoMessageBox(buffer.Str(),currentPath.Str(),NMM_OK,NMI_WARNING); } //CUIKFlashBomb(); DeleteCKObjectArray(liste); return FALSE; } if (!runtime && m_Context->IsRunTime()) { NeMoMessageBox(CUIKLM_FILEIO_ERRORS_WARNINGTHISFILECONTAINSRU,currentPath.Str(),NMM_OK,NMI_WARNING); } //load nmo as selection set CKLevel* level = m_Context->GetCurrentLevel(); //prepare dependencies for loaded file XObjectArray loadDepArray;//array of all dependencies for loaded file CKGroup* setgrp = 0; for (liste->Reset();!liste->EndOfList();liste->Next()) { CKObject* obj = liste->GetData(m_Context); if (CKIsChildClassOf(obj,CKCID_GROUP))// && (obj->GetObjectFlags() & CK_OBJECT_SELECTIONSET) ) { setgrp = (CKGroup*)obj; } if (CKIsChildClassOf(obj,CKCID_BEOBJECT)) { //object was not in group, this is a new object loadDepArray.PushBack(obj->GetID()); } //some data else if (CKIsChildClassOf(obj,CKCID_INTERFACEOBJECTMANAGER)) { CKInterfaceObjectManager* iom = (CKInterfaceObjectManager*)obj; if (iom->GetGuid()==LOADSAVEGUID_SELECTIONSETDATA) { CKStateChunk* chunk = iom->GetChunk(0); chunk->StartRead(); LoadRebuildHierarchyFromChunk(iGrp,chunk); chunk->CloseChunk(); } m_Context->DestroyObject(iom,CK_DESTROY_TEMPOBJECT); } } //set setgrp data //SetSelectionSetData(setgrp,data); if (level) level->AddObject(setgrp); /*USED TO RELOAD WITHOUT UNLOADING SET //Now compare loadDepArray with m_NotToSaveObjectList (which contains the set's previous content //if an objects belong to m_NotToSaveObjectList and not to loadDepArray then delete it XObjectArray toDeleteList; XObjectArray::Iterator it1 = m_NotToSaveObjectList.Begin(); XObjectArray::Iterator it2 = m_NotToSaveObjectList.End(); while (it1!=it2) { CK_ID id = *it1++; if (!loadDepArray.IsHere(id)) toDeleteList.PushBack(id); } if (toDeleteList.Size()) { int res = NeMoMessageBox("Objects were removed during reload,\nwould you like to check the unused object explorer?", "Selection Set",NMM_YESNO,NMI_WARNING); XObjectArray dependArray; if (res==IDYES) { SelectionSetData* data = GetSelectionSetData(iGrp); CKDependenciesContext depctx(m_Context); if (data && data->m_SaveDependencies.Size()) depctx.StartDependencies(&data->m_SaveDependencies); else depctx.StartDependencies(&m_SaveSetDependencies); XObjectArray::Iterator it1 = toDeleteList.Begin(); XObjectArray::Iterator it2 = toDeleteList.End(); while (it1!=it2) { CK_ID id = *it1++; CKObject* obj = m_Context->GetObject(id); obj->PrepareDependencies(depctx); } dependArray = depctx.FillDependencies(); } m_Context->DestroyObjects(toDeleteList.Begin(),toDeleteList.Size()); //offer to open unused object explorer here if objects were deleted if (res==IDYES) { CheckForUnusedObjectsDlg dlg; dlg.m_objectsToDeleteToCheck=&dependArray; dlg.DoModal(); } } */ if (m_CompactSetOnLoad) { XArray grps; grps.PushBack(iGrp); CompactSets(grps); } //to send to those who dont want to hav the notif (OBJECT_CREATED), like schematic, cos of addtoscene SendCuikNotification(NULL,CUIK_NOTIFICATION_PRECKFILELOADED,(DWORD)liste); SendCuikNotification(NULL,CUIK_NOTIFICATION_CKFILELOADED,(DWORD)liste); SendCuikNotification(NULL,CUIK_NOTIFICATION_HIERARCHY_CHANGED,(DWORD)liste); DeleteCKObjectArray(liste); if (iUserManualReload) { CuikDoOneRender(); SetProjectModified(TRUE); } m_NotToSaveObjectList.Clear(); return TRUE; } #endif //**************************************************************************************** #ifdef SELECTIONSET_USE_DEPENDENCIES//***************************************************************** //**************************************************************************************** //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::EditSaveSetDependencies() { EditDependencies("Selection Set Save Dependencies","Save Dependencies",&m_SaveSetDependencies); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::EditReloadDependencies() { //EditDependencies("Selection Set Reload Dependencies","Reload Dependencies",&m_ReloadSetDependencies); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// /* void SelectionSetManager::EditPreSaveDependencies() { EditDependencies("Selection Set Exclusion on CMO save Dependencies","Exclusion Dependencies",&m_PreSaveCmoDependencies); } */ //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::EditSetSaveDependencies(XArray &iGrps) { if (iGrps.Size()==0) return CKERR_INVALIDPARAMETER; CKGroup* iGrp = iGrps[0]; if (!CheckIsSelectionSet(iGrp)) return CKERR_INVALIDPARAMETER; SelectionSetData* data = CreateSelectionSetData(iGrp); if (data) { if (data->m_SaveDependencies.Size()==0) { CKCopyDefaultClassDependencies(data->m_SaveDependencies,CK_DEPENDENCIES_COPY); data->m_SaveDependencies[CKCID_MESH] |= CK_DEPENDENCIES_DESTROY_MESH_MATERIAL; data->m_SaveDependencies[CKCID_3DENTITY] |= CK_DEPENDENCIES_DESTROY_3DENTITY_MESH| CK_DEPENDENCIES_DESTROY_3DENTITY_CHILDREN| CK_DEPENDENCIES_DESTROY_3DENTITY_ANIMATIONS; data->m_SaveDependencies[CKCID_MATERIAL] |= CK_DEPENDENCIES_DESTROY_MATERIAL_TEXTURE; data->m_SaveDependencies[CKCID_SPRITE3D] |= CK_DEPENDENCIES_DESTROY_SPRITE3D_MATERIAL; data->m_SaveDependencies[CKCID_TARGETCAMERA] |= CK_DEPENDENCIES_DESTROY_TARGETCAMERA_TARGET; data->m_SaveDependencies[CKCID_TARGETLIGHT] |= CK_DEPENDENCIES_DESTROY_TARGETLIGHT_TARGET; data->m_SaveDependencies[CKCID_VIDEO] |= 1; } XString grpname = STR_UNNAMEDSET; if (iGrp && iGrp->GetName()) grpname = iGrp->GetName(); XString title; title.Format("Selection Set <%> Save Dependencies",grpname.CStr()); CKERROR res = EditDependencies(title.CStr(),"Save Dependencies",&(data->m_SaveDependencies)); if (res==IDOK) { XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); it1++;//skip 1st set while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data2 = CreateSelectionSetData(grp); if (data2) { data2->m_SaveDependencies = data->m_SaveDependencies; } } if (iGrps.Size()>0) { XArray ids; CKGroupToCKIDArray(&iGrps,&ids); DWORD param2=MAKELPARAM(ids.Size(),fSetPart_Dependencies); SendCuikNotification(0,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)ids.Begin(),param2); } } return res; } return CKERR_INVALIDPARAMETER; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::RemoveSetSaveDependencies(XArray &iGrps) { BOOL change=FALSE; XArray::Iterator it1 = iGrps.Begin(); XArray::Iterator it2 = iGrps.End(); while (it1!=it2) { CKGroup* grp = *it1++; SelectionSetData* data = GetSelectionSetData(grp); if (data) { data->m_SaveDependencies.m_Flags= (CK_DEPENDENCIES_FLAGS)0; data->m_SaveDependencies.Clear(); change=TRUE; } } if (change) { XArray ids; CKGroupToCKIDArray(&iGrps,&ids); DWORD param2=MAKELPARAM(ids.Size(),fSetPart_Dependencies); SendCuikNotification(0,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)ids.Begin(),param2); return CK_OK; } return CKERR_INVALIDPARAMETER; } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::SaveDependenciesInChunk(CKDependencies* iDep,CKStateChunk* iChunk) { int size = iDep->Size(); iChunk->WriteInt(size); iChunk->WriteBuffer(size*sizeof(CKDWORD),iDep->Begin()); iChunk->WriteDword(iDep->m_Flags); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// void SelectionSetManager::LoadDependenciesFromChunk(CKDependencies* iDep,CKStateChunk* iChunk) { int size = iChunk->ReadInt(); void* buffer=0; iChunk->ReadBuffer(&buffer); DWORD dw = iChunk->ReadDword(); if (iDep) { iDep->m_Flags = (CK_DEPENDENCIES_FLAGS)dw; if (size) { //copy buffer iDep->Resize(size); memcpy(iDep->Begin(),buffer,size*sizeof(CKDWORD)); } } CKDeletePointer(buffer); } //////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////// CKERROR SelectionSetManager::EditDependencies(const char* iDialogTitle,const char* iDepName,CKDependencies* iDep) { if (!iDep) return -1; CKParameter* depparam = GetInterfaceParameter((char*)iDepName,CKPGUID_COPYDEPENDENCIES); if (!depparam) return CUIKERR_GENERICFAILURE; CKDependencies* dep = NULL; depparam->GetValue((void*)&dep,FALSE); *dep = *iDep; MultiParamEditDlg dlg(m_Context,AfxGetMainWnd()); if (iDialogTitle) dlg.SetTitle((char*)iDialogTitle); dlg.AddParameter(depparam); CKERROR res = dlg.DoModal(); if (res ==IDOK) { *iDep = *dep; } FreeInterfaceParameter(depparam); return res ; } #endif