You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
473 lines
9.8 KiB
473 lines
9.8 KiB
//========= Copyright Valve Corporation, All rights reserved. ============// |
|
// |
|
// Purpose: |
|
// |
|
//=============================================================================// |
|
#include "cbase.h" |
|
#include "workspace.h" |
|
#include <KeyValues.h> |
|
#include "project.h" |
|
#include "vstdlib/random.h" |
|
#include "cmdlib.h" |
|
#include "FileSystem_Tools.h" |
|
#include "utlbuffer.h" |
|
#include "workspacemanager.h" |
|
#include "workspacebrowser.h" |
|
#include "soundbrowser.h" |
|
#include "wavebrowser.h" |
|
|
|
CWorkspace::CWorkspace( char const *filename ) |
|
{ |
|
m_szVSSUserName[ 0 ] = 0; |
|
m_szVSSProject[ 0 ] = 0; |
|
|
|
Q_strncpy( m_szFile, filename, sizeof( m_szFile ) ); |
|
// By default, name is the same as the filename |
|
Q_FileBase( m_szFile, m_szName, sizeof( m_szName ) ); |
|
m_bDirty = false; |
|
LoadFromFile(); |
|
} |
|
|
|
CWorkspace::~CWorkspace() |
|
{ |
|
while ( m_Projects.Count() > 0 ) |
|
{ |
|
CProject *p = m_Projects[ 0 ]; |
|
m_Projects.Remove( 0 ); |
|
delete p; |
|
} |
|
} |
|
|
|
char const *CWorkspace::GetName() const |
|
{ |
|
return m_szName; |
|
} |
|
|
|
bool CWorkspace::IsDirty( void ) const |
|
{ |
|
int c = GetProjectCount(); |
|
for ( int i = 0; i < c; i++ ) |
|
{ |
|
CProject *p = GetProject( i ); |
|
Assert( p ); |
|
if ( p->IsDirty() ) |
|
return true; |
|
} |
|
|
|
return m_bDirty; |
|
} |
|
|
|
void CWorkspace::SetDirty( bool dirty ) |
|
{ |
|
m_bDirty = dirty; |
|
} |
|
|
|
int CWorkspace::GetProjectCount() const |
|
{ |
|
return m_Projects.Count(); |
|
} |
|
|
|
CProject *CWorkspace::GetProject( int index ) const |
|
{ |
|
if ( index < 0 || index >= m_Projects.Count() ) |
|
return NULL; |
|
return m_Projects[ index ]; |
|
} |
|
|
|
void CWorkspace::RemoveProject( CProject *project ) |
|
{ |
|
if ( m_Projects.Find( project ) == m_Projects.InvalidIndex() ) |
|
return; |
|
|
|
m_Projects.FindAndRemove( project ); |
|
SetDirty( true ); |
|
} |
|
|
|
|
|
void CWorkspace::AddProject( CProject *project ) |
|
{ |
|
SetDirty( true ); |
|
|
|
Assert( m_Projects.Find( project ) == m_Projects.InvalidIndex() ); |
|
|
|
m_Projects.AddToTail( project ); |
|
} |
|
|
|
CProject *CWorkspace::FindProjectFile( char const *filename ) const |
|
{ |
|
int c = GetProjectCount(); |
|
for ( int i = 0 ; i < c; i++ ) |
|
{ |
|
CProject *p = GetProject( i ); |
|
Assert( p ); |
|
if ( !Q_stricmp( p->GetFileName(), filename ) ) |
|
return p; |
|
} |
|
return NULL; |
|
} |
|
|
|
void CWorkspace::LoadFromFile() |
|
{ |
|
KeyValues *kv = new KeyValues( m_szName ); |
|
if ( kv->LoadFromFile( filesystem, m_szFile ) ) |
|
{ |
|
for ( KeyValues *proj = kv->GetFirstSubKey(); proj; proj = proj->GetNextKey() ) |
|
{ |
|
// Add named projects |
|
if ( !Q_stricmp( proj->GetName(), "project" ) ) |
|
{ |
|
bool expanded = false; |
|
char filename[ 256 ]; |
|
filename[0] = 0; |
|
|
|
for ( KeyValues *sub = proj->GetFirstSubKey(); sub; sub = sub->GetNextKey() ) |
|
{ |
|
if ( !Q_stricmp( sub->GetName(), "file" ) ) |
|
{ |
|
Q_strcpy( filename, sub->GetString() ); |
|
continue; |
|
} |
|
else if ( !Q_stricmp( sub->GetName(), "expanded" ) ) |
|
{ |
|
expanded = sub->GetInt() ? true : false; |
|
continue; |
|
} |
|
else |
|
{ |
|
Assert( 0 ); |
|
} |
|
} |
|
|
|
CProject *p = new CProject( this, filename ); |
|
p->SetExpanded( expanded ); |
|
p->SetDirty( false ); |
|
m_Projects.AddToTail( p ); |
|
|
|
continue; |
|
} |
|
else if ( !Q_stricmp( proj->GetName(), "vss_username" ) ) |
|
{ |
|
SetVSSUserName( proj->GetString() ); |
|
|
|
Con_Printf( "VSS User: '%s'\n", GetVSSUserName() ); |
|
continue; |
|
} |
|
else if ( !Q_stricmp( proj->GetName(), "vss_project" ) ) |
|
{ |
|
SetVSSProject( proj->GetString() ); |
|
|
|
Con_Printf( "VSS Project: '%s'\n", GetVSSProject() ); |
|
continue; |
|
} |
|
else if ( !Q_stricmp( proj->GetName(), "window" ) ) |
|
{ |
|
SetDirty( true ); |
|
|
|
char const *windowname = proj->GetString( "windowname", "" ); |
|
if ( !Q_stricmp( windowname, "workspace" ) ) |
|
{ |
|
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager()->GetBrowser() ); |
|
continue; |
|
} |
|
else if ( !Q_stricmp( windowname, "soundbrowser" ) ) |
|
{ |
|
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager()->GetSoundBrowser() ); |
|
continue; |
|
} |
|
else if ( !Q_stricmp( windowname, "wavebrowser" ) ) |
|
{ |
|
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager()->GetWaveBrowser() ); |
|
continue; |
|
} |
|
else if ( !Q_stricmp( windowname, "main" ) ) |
|
{ |
|
SceneManager_LoadWindowPositions( proj, GetWorkspaceManager() ); |
|
continue; |
|
} |
|
else |
|
{ |
|
Assert( 0 ); |
|
} |
|
} |
|
|
|
Assert( 0 ); |
|
} |
|
} |
|
kv->deleteThis(); |
|
} |
|
|
|
static void SaveWindowPositions( CUtlBuffer& buf, char const *windowname, mxWindow *wnd ) |
|
{ |
|
buf.Printf( "\t\"window\"\n" ); |
|
buf.Printf( "\t{\n" ); |
|
buf.Printf( "\t\twindowname\t\"%s\"\n", windowname ); |
|
|
|
SceneManager_SaveWindowPositions( buf, 2, wnd ); |
|
|
|
buf.Printf( "\t}\n" ); |
|
} |
|
|
|
void CWorkspace::SaveToFile() |
|
{ |
|
SetDirty( false ); |
|
|
|
CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER ); |
|
|
|
buf.Printf( "%s\n{\n", GetName() ); |
|
|
|
// walk projects |
|
int c = GetProjectCount(); |
|
for ( int i = 0; i < c; i++ ) |
|
{ |
|
CProject *p = GetProject( i ); |
|
Assert( p ); |
|
|
|
buf.Printf( "\t\"project\"\n" ); |
|
buf.Printf( "\t{\n" ); |
|
buf.Printf( "\t\t\"expanded\"\t\"%i\"\n", p->IsExpanded() ); |
|
buf.Printf( "\t\t\"file\"\t\"%s\"\n", p->GetFileName() ); |
|
buf.Printf( "\t}\n" ); |
|
|
|
p->SaveChanges(); |
|
} |
|
|
|
buf.Printf( "\t\"vss_username\"\t\"%s\"\n", GetVSSUserName() ); |
|
buf.Printf( "\t\"vss_project\"\t\"%s\"\n", GetVSSProject() ); |
|
|
|
// Save window positions |
|
SaveWindowPositions( buf, "main", GetWorkspaceManager() ); |
|
|
|
SaveWindowPositions( buf, "workspace", GetWorkspaceManager()->GetBrowser() ); |
|
SaveWindowPositions( buf, "soundbrowser", GetWorkspaceManager()->GetSoundBrowser() ); |
|
SaveWindowPositions( buf, "wavebrowser", GetWorkspaceManager()->GetWaveBrowser() ); |
|
|
|
buf.Printf( "}\n" ); |
|
|
|
if ( filesystem->FileExists( m_szFile ) && !filesystem->IsFileWritable( m_szFile ) ) |
|
{ |
|
int retval = mxMessageBox( NULL, va( "Check out '%s'?", m_szFile ), g_appTitle, MX_MB_YESNOCANCEL ); |
|
if ( retval != 0 ) |
|
return; |
|
|
|
VSS_Checkout( m_szFile ); |
|
|
|
if ( !filesystem->IsFileWritable( m_szFile ) ) |
|
{ |
|
mxMessageBox( NULL, va( "Unable to check out'%s'!!!", m_szFile ), g_appTitle, MX_MB_OK ); |
|
return; |
|
} |
|
} |
|
|
|
// Write it out baby |
|
FileHandle_t fh = filesystem->Open( m_szFile, "wt" ); |
|
if (fh) |
|
{ |
|
filesystem->Write( buf.Base(), buf.TellPut(), fh ); |
|
filesystem->Close(fh); |
|
} |
|
else |
|
{ |
|
Con_Printf( "CWorkspace::SaveToFile: Unable to write file %s!!!\n", m_szFile ); |
|
} |
|
} |
|
|
|
void CWorkspace::SaveChanges() |
|
{ |
|
if ( !IsDirty() ) |
|
return; |
|
|
|
SaveToFile(); |
|
} |
|
|
|
|
|
void CWorkspace::ValidateTree( mxTreeView *tree, mxTreeViewItem *parent ) |
|
{ |
|
CUtlVector< mxTreeViewItem * > m_KnownItems; |
|
|
|
int c = GetProjectCount(); |
|
CProject *proj; |
|
for ( int i = 0; i < c; i++ ) |
|
{ |
|
proj = GetProject( i ); |
|
if ( !proj ) |
|
continue; |
|
|
|
char sz[ 256 ]; |
|
if ( proj->GetComments() && proj->GetComments()[0] ) |
|
{ |
|
Q_snprintf( sz, sizeof( sz ), "%s : %s", proj->GetName(), proj->GetComments() ); |
|
} |
|
else |
|
{ |
|
Q_strncpy( sz, proj->GetName(), sizeof( sz ) ); |
|
} |
|
|
|
mxTreeViewItem *spot = proj->FindItem( tree, parent ); |
|
if ( !spot ) |
|
{ |
|
spot = tree->add( parent, sz ); |
|
} |
|
|
|
m_KnownItems.AddToTail( spot ); |
|
|
|
proj->SetOrdinal ( i ); |
|
|
|
tree->setLabel( spot, sz ); |
|
|
|
tree->setImages( spot, proj->GetIconIndex(), proj->GetIconIndex() ); |
|
tree->setUserData( spot, proj ); |
|
//tree->setOpen( spot, proj->IsExpanded() ); |
|
|
|
proj->ValidateTree( tree, spot ); |
|
} |
|
|
|
// Now check for dangling items |
|
mxTreeViewItem *start = tree->getFirstChild( parent ); |
|
while ( start ) |
|
{ |
|
mxTreeViewItem *next = tree->getNextChild( start ); |
|
|
|
if ( m_KnownItems.Find( start ) == m_KnownItems.InvalidIndex() ) |
|
{ |
|
tree->remove( start ); |
|
} |
|
|
|
start = next; |
|
} |
|
|
|
tree->sortTree( parent, true, CWorkspaceBrowser::CompareFunc, 0 ); |
|
} |
|
|
|
bool CWorkspace::CanClose( void ) |
|
{ |
|
if ( !IsDirty() ) |
|
return true; |
|
|
|
int retval = mxMessageBox( NULL, va( "Save changes to workspace '%s'?", GetName() ), g_appTitle, MX_MB_YESNOCANCEL ); |
|
if ( retval == 2 ) |
|
return false; |
|
|
|
if ( retval == 0 ) |
|
{ |
|
SaveChanges(); |
|
} |
|
|
|
return true; |
|
} |
|
|
|
char const *CWorkspace::GetVSSUserName() const |
|
{ |
|
return m_szVSSUserName; |
|
} |
|
|
|
char const *CWorkspace::GetVSSProject() const |
|
{ |
|
return m_szVSSProject; |
|
} |
|
|
|
void CWorkspace::SetVSSUserName( char const *username ) |
|
{ |
|
Q_strncpy( m_szVSSUserName, username, sizeof( m_szVSSUserName ) ); |
|
} |
|
|
|
void CWorkspace::SetVSSProject( char const *projectname ) |
|
{ |
|
Q_strncpy( m_szVSSProject, projectname, sizeof( m_szVSSProject ) ); |
|
while ( Q_strlen( m_szVSSProject ) > 0 ) |
|
{ |
|
if ( m_szVSSProject[ Q_strlen( m_szVSSProject ) - 1 ] == '/' || |
|
m_szVSSProject[ Q_strlen( m_szVSSProject ) - 1 ] == '\\' ) |
|
{ |
|
m_szVSSProject[ Q_strlen( m_szVSSProject ) - 1 ] = 0; |
|
} |
|
else |
|
{ |
|
break; |
|
} |
|
} |
|
} |
|
|
|
void CWorkspace::Checkout( bool updatestateicons /*= true*/ ) |
|
{ |
|
VSS_Checkout( GetFileName(), updatestateicons ); |
|
} |
|
|
|
void CWorkspace::Checkin(bool updatestateicons /*= true*/) |
|
{ |
|
VSS_Checkin( GetFileName(), updatestateicons ); |
|
} |
|
|
|
bool CWorkspace::IsCheckedOut() const |
|
{ |
|
return filesystem->IsFileWritable( GetFileName() ); |
|
} |
|
|
|
int CWorkspace::GetIconIndex() const |
|
{ |
|
if ( IsCheckedOut() ) |
|
{ |
|
return IMAGE_WORKSPACE_CHECKEDOUT; |
|
} |
|
else |
|
{ |
|
return IMAGE_WORKSPACE; |
|
} |
|
} |
|
|
|
void CWorkspace::MoveChildUp( ITreeItem *child ) |
|
{ |
|
int c = GetProjectCount(); |
|
for ( int i = 1; i < c; i++ ) |
|
{ |
|
CProject *p = GetProject( i ); |
|
if ( p != child ) |
|
continue; |
|
|
|
CProject *prev = GetProject( i - 1 ); |
|
// Swap |
|
m_Projects[ i - 1 ] = p; |
|
m_Projects[ i ] = prev; |
|
return; |
|
} |
|
} |
|
|
|
void CWorkspace::MoveChildDown( ITreeItem *child ) |
|
{ |
|
int c = GetProjectCount(); |
|
for ( int i = 0; i < c - 1; i++ ) |
|
{ |
|
CProject *p = GetProject( i ); |
|
if ( p != child ) |
|
continue; |
|
|
|
CProject *next = GetProject( i + 1 ); |
|
// Swap |
|
m_Projects[ i ] = next; |
|
m_Projects[ i + 1 ] = p; |
|
return; |
|
} |
|
} |
|
|
|
bool CWorkspace::IsChildFirst( ITreeItem *child ) |
|
{ |
|
int idx = m_Projects.Find( (CProject *)child ); |
|
if ( idx == m_Projects.InvalidIndex() ) |
|
return false; |
|
|
|
if ( idx != 0 ) |
|
return false; |
|
|
|
return true; |
|
} |
|
|
|
bool CWorkspace::IsChildLast( ITreeItem *child ) |
|
{ |
|
int idx = m_Projects.Find( (CProject *)child ); |
|
if ( idx == m_Projects.InvalidIndex() ) |
|
return false; |
|
|
|
if ( idx != m_Projects.Count() - 1 ) |
|
return false; |
|
|
|
return true; |
|
} |