deargui-vpl/ref/virtools/Samples/Behaviors/SelectionSetManager/SelectionSetManager.cpp

3820 lines
113 KiB
C++

/**
@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 <sys/stat.h>
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;i<sets.Size();++i)
{
SelectionSetData* data = GetSelectionSetData(sets[i]);
if (data)
CheckRelativePath(data->m_Path,TRUE);
}
}
return TRUE;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void SelectionSetManager::CKGroupToCKIDArray(XArray<CKGroup*>* iObjects,XArray<CK_ID>* oIDs)
{
oIDs->Reserve(iObjects->Size()+1);
XArray<CKGroup*>::Iterator it1 = iObjects->Begin();
XArray<CKGroup*>::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 (iOption<GetIncludeSelectionSetSaveOptionDescCount())
{
m_IncludeSelectionSetSaveOption = iOption;
m_Context->SendInterfaceMessage(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<CK_ID>& oSelectionSets,BOOL iSortedByPriority)
{
XArray<CKGroup*> 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<CKGroup*>& 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<CKGroup*> sets;
GetSelectionSets(sets);
BOOL changed=TRUE;
XString finalPath = data->m_Path ;
int finalIndex=0;
while (changed)
{
changed=FALSE;
XArray<CKGroup*>::Iterator it1 = sets.Begin();
XArray<CKGroup*>::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<CKGroup*> selectionSets;
GetSelectionSets(selectionSets);
XArray<CKGroup*>::Iterator it1 = selectionSets.Begin();
XArray<CKGroup*>::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<CKGroup*> sets;
GetSelectionSets(sets);
XArray<CKGroup*>::Iterator it1 = sets.Begin();
XArray<CKGroup*>::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,&currentPath);
//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<CK_ID> 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;i<grpCount;++i)
{
//read set data
SelectionSetData* data = new SelectionSetData;
data->LoadDataFromChunk(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;j<objCount;++j)
{
CK_ID id = iChunk->ReadObjectID();
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<CKGroup*>* iSets)
{
SelectionSetData emptyData;
XArray<CKGroup*> 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;i<selectionSets.Size();++i)
{
CKGroup* grp = selectionSets[i];
//write selection set data
SelectionSetData* data = (SelectionSetData*)grp->GetAppData();
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;j<grpObjectCount;++j)
{
CKBeObject* obj = grp->GetObject(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<CKGroup*> &iGrps,int iPriority)
{
XArray<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CK_ID> 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<CKGroup*> &iGrps)
{
BOOL change=FALSE;
XArray<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CK_ID> 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;i<length;i++)
currentPath[i]=0;
}
}
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)
SetSelectionSetPath(iGrp,currentPath);
#endif
return CK_OK;
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
void SelectionSetManager::CloseExternalFileSets()
{
#ifdef USE_VERSIONCONTROL
if (!m_VCI || !m_VCI->m_OnPreClose)
return;
#endif
XArray<CKGroup*> selectionSets;
GetSelectionSets(selectionSets);
XArray<CKGroup*>::Iterator it1 = selectionSets.Begin();
XArray<CKGroup*>::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<CKGroup*> &iGrps)
{
//parse sets
XArray<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CKObject*> groupChildrenCopy;
groupChildrenCopy.Resize(count);
for (int i=0;i<count;++i)
groupChildrenCopy[i]=grp->GetObject(i);
//parse group children
XArray<CKObject*>::Iterator git1 = groupChildrenCopy.Begin();
XArray<CKObject*>::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<CKObject*> 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;i<objectCount;++i)// per object
{
CK_ID id = iChunk->ReadObjectID();// 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<CKObject*> 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;i<count;++i)
{
CKObject* obj = iGrp->GetObject(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<CKObject*>::Iterator it1 = rebuild.Begin();
XArray<CKObject*>::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<CKGroup*> &iGrps,ESetFieldChange iChange,SelectionSetData::FSetFlags iDataFlags,BOOL iNotify,FSetPart iViewFlags)
{
XArray<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CK_ID> 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<CKGroup*> &iGrps,ESetFieldChange iChange)
{
return SetField(iGrps,iChange,SelectionSetData::fSetFlags_LoadWithCmo,TRUE,fSetPart_LoadWithCmo);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
CKERROR SelectionSetManager::SetSaveWithCmo(XArray<CKGroup*> &iGrps,ESetFieldChange iChange)
{
return SetField(iGrps,iChange,SelectionSetData::fSetFlags_SaveWithCmo,TRUE,fSetPart_SaveWithCmo);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
CKERROR SelectionSetManager::SetLoadMode(XArray<CKGroup*> &iGrps,ESetFieldChange iChange)
{
return SetField(iGrps,iChange,SelectionSetData::fSetFlags_ReplaceAndShare,TRUE,fSetPart_LoadMode);
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
CKERROR SelectionSetManager::SetRebuildHierarchy(XArray<CKGroup*> &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;i<count;++i)
{
WebSet& webset = m_WebDownloadSets[i];
if (webset.webHandle==webHandle)
{
oSet = webset.grp;
return webset.state;
}
}
return eSetLoad_InvalidParameter;
}
void SelectionSetManager::WebDownloadSet()
{
int count = m_WebDownloadSets.Size();
for (int i=0;i<count;++i)
{
WebSet& webset = m_WebDownloadSets[i];
{
CWebServerManager* webmgr = (CWebServerManager*)m_Context->GetManagerByGuid(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;i<count;++i)
{
CKObject* obj = ioGrp->GetObject(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<CKGroup*> 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<CKScene*> scenes;
XArray<CKPlace*> 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<CKScene*>::Iterator its = scenes.Begin();
while (its!=scenes.End())
level->AddScene(*its++);
XArray<CKPlace*>::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<CKGroup*> 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<CKGroup*> &iGrps,BOOL iDeleteGroup)
{
XArray<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::Iterator it2 = iGrps.End();
while (it1!=it2)
{
CKGroup* iGrp = *it1++;
XArray<CK_ID> 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;i<count;++i)
{
CKBeObject* beo = iGrp->GetObject(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;i<iGrp->GetObjectCount();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<CKGroup*> sets;
GetSelectionSets(sets);
XArray<CKGroup*>::Iterator it1 = sets.Begin();
XArray<CKGroup*>::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+1<name.Length())
val = atoi(&name[p+1]);
if (val>maxcount) 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<CKGroup*> sets;
GetSelectionSets(sets);
return sets.Size();
}
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
CKGroup* SelectionSetManager::GetSelectionSet(int iIndex)
{
XArray<CKGroup*> sets;
GetSelectionSets(sets);
if (iIndex>=0 && iIndex<sets.Size())
return sets[iIndex];
return 0;
}
CKERROR SelectionSetManager::EditSetPriority(XArray<CKGroup*> &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<CKGroup*> &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<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CK_ID> 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; i<count; ++i)
{
CKObject* obj = m_Context->GetObject(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<CKGroup*> 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<CKGroup*> 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<CKGroup*>::Iterator it1 = sets.Begin();
XArray<CKGroup*>::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;i<grp->GetObjectCount();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;i<grp->GetObjectCount();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<CKGroup*> sets;
GetSelectionSets(sets,TRUE);
SelectionSetData emptyData;
//check if there are external sets
XArray<CKGroup*>::Iterator it1 = sets.Begin();
XArray<CKGroup*>::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<CKGroup*> 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<CKGroup*>::Iterator it1 = sets.Begin();
XArray<CKGroup*>::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;i<grp->GetObjectCount();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;i<count;++i)
{
CK_ID paramid = m_SelectionSetParams[i];
CKParameter* p = (CKParameter*)m_Context->GetObject(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;i<count;++i)
{
CK_ID paramid = iChunk->ReadObjectID();
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<CK_ID>::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<XString,CK_ID> 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<CKGroup*> 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;i<count;++i)
{
CKObject* obj = iGrp->GetObject(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<CKGroup*> 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<CKGroup*> &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<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CK_ID> 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<CKGroup*> &iGrps)
{
BOOL change=FALSE;
XArray<CKGroup*>::Iterator it1 = iGrps.Begin();
XArray<CKGroup*>::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<CK_ID> 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