3820 lines
113 KiB
C++
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,¤tPath);
|
|
|
|
//WaitCursor hourglass;
|
|
//AfxGetMainWnd()->RedrawWindow();
|
|
|
|
#ifndef VIRTOOLS_RUNTIME_VERSION
|
|
|
|
//save old file in .bak+number
|
|
if (m_BackupOnSaveSet)
|
|
{
|
|
if (PathFileExists(currentPath.CStr()))
|
|
{
|
|
XString newpath=currentPath;
|
|
newpath+=".bak";
|
|
MoveFileEx(currentPath.CStr(),newpath.CStr(),MOVEFILE_REPLACE_EXISTING);
|
|
}
|
|
}
|
|
#endif
|
|
|
|
CKDependencies* dep = &m_SaveSetDependencies;
|
|
SelectionSetData* data = GetSelectionSetData(iGrp);
|
|
if (data)
|
|
{
|
|
#ifdef SELECTIONSET_USE_DEPENDENCIES
|
|
if (data->m_SaveDependencies.Size())
|
|
dep = &data->m_SaveDependencies;
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
XString str;
|
|
str.Format(STR_SETNOTSAVED,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET);
|
|
m_Context->OutputToConsole(str.Str(),FALSE);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
//create array of objects to save
|
|
CKObjectArray * arrayToSave = CreateCKObjectArray();
|
|
|
|
//arrayToSave->InsertRear(iGrp);
|
|
if(iGrp->GetObjectCount()==0)
|
|
{
|
|
XString str;
|
|
str.Format(STR_SETNOTSAVED,iGrp->GetName()?iGrp->GetName():STR_UNNAMEDSET);
|
|
m_Context->OutputToConsole(str.Str(),FALSE);
|
|
return TRUE;
|
|
}
|
|
|
|
//save hierarchy for rebuild
|
|
CKInterfaceObjectManager * iom = 0;
|
|
if (data->HasFlags(SelectionSetData::fSetFlags_RebuildHierarchy))
|
|
{
|
|
if (iom = (CKInterfaceObjectManager*) m_Context->CreateObject(CKCID_INTERFACEOBJECTMANAGER))
|
|
{
|
|
iom->SetGuid(LOADSAVEGUID_SELECTIONSETDATA);
|
|
arrayToSave->InsertRear(iom);
|
|
CKStateChunk* chunk=CreateCKStateChunk(CKCID_OBJECT);
|
|
chunk->StartWrite();
|
|
SaveRebuildHierarchyFromChunk(iGrp,chunk);
|
|
chunk->CloseChunk();
|
|
iom->AddStateChunk(chunk);
|
|
}
|
|
}
|
|
|
|
#ifdef USE_VERSIONCONTROL
|
|
//source control presave
|
|
if (m_VCI && m_VCI->m_OnPreSave)
|
|
{
|
|
const char* file = currentPath.CStr();
|
|
m_VCI->m_OnPreSave(&file,1);
|
|
}
|
|
#endif
|
|
|
|
#pragma todo("option de hide / show graph")
|
|
/*
|
|
BOOL oldhidegraph = CUIKSchematicEditor::AreGraphsHidden();
|
|
CUIKSchematicEditor::SaveScriptIndex(FALSE);//save script index only if composition
|
|
CUIKSchematicEditor::HideGraphs(FALSE);//prevent schematic editor at least
|
|
CKERROR res = SendCuikNotification(NULL,CUIK_NOTIFICATION_PRESAVELEVEL,(DWORD)arrayToSave);//send notif so that all chunk are deleted
|
|
*/
|
|
CKERROR res = m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_PRESAVELEVEL,(DWORD)arrayToSave,0);
|
|
if (res!=CKERR_NOTIFICATIONNOTHANDLED && res<0)
|
|
{
|
|
m_Context->OutputToConsole(STR_PRESAVEERROR,TRUE);
|
|
DeleteCKObjectArray(arrayToSave);
|
|
return FALSE;
|
|
}
|
|
|
|
iGrp->ModifyObjectFlags(0,CK_OBJECT_NOTTOBESAVED); //force save the selection set group
|
|
CKERROR error=SaveGroup(iGrp,currentPath.CStr(),dep,arrayToSave); //save
|
|
iGrp->ModifyObjectFlags(CK_OBJECT_NOTTOBESAVED,0); //unflag
|
|
|
|
m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_POSTSAVELEVEL,(DWORD)arrayToSave,0);
|
|
//CUIKSchematicEditor::HideGraphs(oldhidegraph);//restore
|
|
|
|
if (error!=0)//error check
|
|
{
|
|
if (oErrorLog)
|
|
{
|
|
XString buffer;
|
|
buffer.Format(STR_SAVEERROR,CKErrorToString(error));
|
|
buffer.Format("%s (%s)",buffer.CStr(),data->m_Path.CStr());
|
|
if ((*oErrorLog).Length()>0)
|
|
(*oErrorLog)+="\n";
|
|
(*oErrorLog)+=buffer;
|
|
}
|
|
else
|
|
{
|
|
XString buffer;
|
|
buffer.Format(STR_SAVEERROR,CKErrorToString(error));
|
|
m_Context->OutputToConsole(buffer.Str(),TRUE);
|
|
}
|
|
DeleteCKObjectArray(arrayToSave);
|
|
return FALSE;
|
|
}
|
|
#ifndef VIRTOOLS_RUNTIME_VERSION
|
|
else//no error
|
|
{
|
|
m_LastSavedSetID = iGrp->GetID();
|
|
DWORD param2=MAKELPARAM(1,fSetPart_LastSaved);
|
|
m_Context->SendInterfaceMessage(CKUIM_SENDNOTIFICATION2,CUIK_NOTIFICATION_SELECTIONSETS_MODIFIED,(DWORD)&m_LastSavedSetID,param2);
|
|
}
|
|
#endif
|
|
#ifdef USE_VERSIONCONTROL
|
|
//source control postsave
|
|
if (!error && m_VCI && m_VCI->m_OnPostSave)
|
|
{
|
|
const char* file = currentPath.CStr();
|
|
m_VCI->m_OnPostSave(&file,1);
|
|
}
|
|
#endif
|
|
|
|
DeleteCKObjectArray(arrayToSave);
|
|
if (iom)
|
|
m_Context->DestroyObject(iom,CK_DESTROY_TEMPOBJECT);
|
|
|
|
return TRUE;
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
BOOL SelectionSetManager::LoadSelectionSetFromChunk(CKStateChunk* iChunk,BOOL iFromCMO)
|
|
{
|
|
if (!iChunk)
|
|
return FALSE;
|
|
|
|
//read version
|
|
m_Version = 0;
|
|
if (iChunk->SeekIdentifier(SELECTIONSETMANAGER_CHUNK_VERSIONIDENTIFIER))
|
|
{
|
|
m_Version= iChunk->ReadInt();
|
|
}
|
|
else
|
|
return FALSE; //obsolete file
|
|
|
|
if (iChunk->SeekIdentifier(SELECTIONSETMANAGER_CHUNK_SAVEIDENTIFIER))
|
|
{
|
|
XString errorLog;
|
|
XArray<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
|