mirror of
https://github.com/celisej567/source-engine.git
synced 2026-01-03 05:49:41 +03:00
1
This commit is contained in:
473
utils/scenemanager/workspace.cpp
Normal file
473
utils/scenemanager/workspace.cpp
Normal file
@@ -0,0 +1,473 @@
|
||||
//========= 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;
|
||||
}
|
||||
Reference in New Issue
Block a user