summaryrefslogtreecommitdiff
path: root/utils/scenemanager/workspacemanager.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'utils/scenemanager/workspacemanager.cpp')
-rw-r--r--utils/scenemanager/workspacemanager.cpp2004
1 files changed, 2004 insertions, 0 deletions
diff --git a/utils/scenemanager/workspacemanager.cpp b/utils/scenemanager/workspacemanager.cpp
new file mode 100644
index 0000000..c866f04
--- /dev/null
+++ b/utils/scenemanager/workspacemanager.cpp
@@ -0,0 +1,2004 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// Purpose:
+//
+// $NoKeywords: $
+//
+//=============================================================================//
+#include "cbase.h"
+#include "workspacemanager.h"
+#include "workspacebrowser.h"
+#include "workspace.h"
+#include "statuswindow.h"
+#include "SoundEmitterSystem/isoundemittersystembase.h"
+#include "drawhelper.h"
+#include "InputProperties.h"
+#include "filesystem.h"
+#include "cmdlib.h"
+#include "project.h"
+#include "scene.h"
+#include <KeyValues.h>
+#include "utlbuffer.h"
+#include "iscenemanagersound.h"
+#include "soundentry.h"
+#include "vcdfile.h"
+#include "soundbrowser.h"
+#include "wavebrowser.h"
+#include "VSSProperties.h"
+#include "resource.h"
+#include "soundproperties.h"
+#include "waveproperties.h"
+#include "wavefile.h"
+#include "ifileloader.h"
+#include "MultipleRequest.h"
+#include <vgui/ILocalize.h>
+#include "tier3/tier3.h"
+
+char g_appTitle[] = "Source Engine SceneManager";
+static char g_appTitleFmt[] = "%s - SceneManager Workspace (%s)";
+static char g_appTitleFmtModified[] = "%s * - SceneManager Workspace (%s)";
+
+#define RECENT_FILES_FILE "scenemanager.rf"
+
+enum
+{
+ // Menu options
+ IDC_WSM_FILE_EXIT = 1000,
+
+ IDC_WSM_FILE_WS_NEW,
+ IDC_WSM_FILE_WS_OPEN,
+ IDC_WSM_FILE_WS_CLOSE,
+ IDC_WSM_FILE_WS_SAVE,
+
+ IDC_WSM_FILE_WS_REFRESH,
+
+ IDC_WSM_FILE_WS_VSSPROPERTIES,
+ IDC_WSM_FILE_WS_CHECKOUT,
+ IDC_WSM_FILE_WS_CHECKIN,
+
+ IDC_WSM_FILE_SCENE_NEW, // + prompt for add to active project
+
+ IDC_WSM_PROJECT_PRJ_NEW, // + Prompt for add to workspace
+
+ IDC_WSM_PROJECT_PRJ_INSERT,
+ IDC_WSM_PROJECT_PRJ_REMOVE,
+ IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS,
+
+ IDC_WSM_PROJECT_SCENE_NEW,
+ IDC_WSM_SCENE_REMOVE,
+
+ IDC_WSM_SOUNDENTRY_PLAY,
+ IDC_WSM_SOUNDENTRY_TOGGLEVOICEDUCK,
+ IDC_WSM_SOUNDENTRY_EDITTEXT,
+ IDC_WSM_SOUNDENTRY_SHOWINBROWSERS,
+ IDC_WSM_SOUNDENTRY_PROPERTIES,
+
+ IDC_WSM_SCENE_VCD_ADD,
+ IDC_WSM_SCENE_VCD_REMOVE,
+ IDC_WSM_SCENE_EDIT_COMMENTS,
+
+ IDC_WSM_VCD_EDIT_COMMENTS,
+
+ IDC_WSM_SELECTION_CHECKOUT,
+ IDC_WSM_SELECTION_CHECKIN,
+
+ IDC_WSM_SELECTION_MOVEUP,
+ IDC_WSM_SELECTION_MOVEDOWN,
+
+ IDC_WSM_WAVEFILE_PROPERTIES,
+
+ // Controls
+ IDC_WS_BROWSER,
+ IDC_WS_SOUNDBROWSER,
+ IDC_WS_WAVEBROWSER,
+
+ // These should be the final entriex
+ IDC_WSM_FILE_RECENT_WORKSPACE_START = 1500,
+ IDC_WSM_FILE_RECENT_WORKSPACE_END = 1510,
+
+ IDC_WSM_OPTIONS_LANGUAGESTART = 1600,
+ IDC_WSM_OPTIONS_LANGUAGEEND = 1600 + CC_NUM_LANGUAGES,
+};
+
+static CWorkspaceManager *g_pManager = NULL;
+CWorkspaceManager *GetWorkspaceManager()
+{
+ Assert( g_pManager );
+ return g_pManager;
+}
+
+class CWorkspaceWorkArea : public mxWindow
+{
+public:
+ CWorkspaceWorkArea( mxWindow *parent )
+ : mxWindow( parent, 0, 0, 0, 0, "" )
+ {
+ SceneManager_AddWindowStyle( this, WS_VISIBLE | WS_CLIPCHILDREN | WS_CLIPSIBLINGS );
+ }
+
+ virtual void redraw()
+ {
+ CDrawHelper helper( this, RGB( 200, 200, 200 ) );
+ }
+};
+
+CWorkspaceManager::CWorkspaceManager()
+ : mxWindow (0, 0, 0, 0, 0, g_appTitle, mxWindow::Normal)
+{
+ m_lEnglishCaptionsFileChangeTime = -1L;
+ m_nLanguageId = CC_ENGLISH;
+
+ g_pManager = this;
+
+ g_pStatusWindow = new CStatusWindow( this, 0, 0, 1024, 150, "" );
+ g_pStatusWindow->setVisible( true );
+
+ m_pWorkArea = new CWorkspaceWorkArea( this );
+
+ Con_Printf( "Initializing\n" );
+
+ Con_Printf( "CSoundEmitterSystemBase::Init()\n" );
+
+ m_nRecentMenuItems = 0;
+
+ // create menu stuff
+ m_pMenuBar = new mxMenuBar (this);
+ m_pFileMenu = new mxMenu ();
+ m_pProjectMenu = new mxMenu ();
+ m_pOptionsMenu = new mxMenu();
+
+ {
+ m_pMenuCloseCaptionLanguages = new mxMenu();
+
+ for ( int i = 0; i < CC_NUM_LANGUAGES; i++ )
+ {
+ int id = IDC_WSM_OPTIONS_LANGUAGESTART + i;
+ m_pMenuCloseCaptionLanguages->add( CSentence::NameForLanguage( i ), id );
+ }
+ // Check the first item
+ m_pMenuCloseCaptionLanguages->setChecked( IDC_WSM_OPTIONS_LANGUAGESTART + CC_ENGLISH, true );
+ m_pOptionsMenu->addMenu( "CC Language", m_pMenuCloseCaptionLanguages );
+
+ }
+
+ m_pMenuBar->addMenu ("File", m_pFileMenu );
+ m_pMenuBar->addMenu( "Project", m_pProjectMenu );
+ m_pMenuBar->addMenu ( "Options", m_pOptionsMenu );
+
+ CreateFileMenu( m_pFileMenu );
+ CreateProjectMenu( m_pProjectMenu );
+
+ setMenuBar ( m_pMenuBar );
+
+ Con_Printf( "Creating browser\n" );
+
+ m_pBrowser = new CWorkspaceBrowser( m_pWorkArea, this, IDC_WS_BROWSER );
+
+ m_pSoundBrowser = NULL;
+ m_pWaveBrowser = NULL;
+
+ int w = 1280;
+ setBounds (10, 10, w, 960);
+
+ setVisible (true);
+
+ Con_Printf( "Creating wave browser\n" );
+
+ m_pWaveBrowser = new CWaveBrowser( m_pWorkArea, this, IDC_WS_WAVEBROWSER );
+
+ Con_Printf( "Creating sound browser\n" );
+
+ m_pSoundBrowser = new CSoundBrowser( m_pWorkArea, this, IDC_WS_SOUNDBROWSER );
+
+ GetBrowser()->SetWorkspace( NULL );
+
+ // See if command line requested workspace
+
+ // Default layout
+ PerformLayout( true );
+
+ LoadRecentFilesMenuFromDisk();
+}
+
+CWorkspaceManager::~CWorkspaceManager()
+{
+}
+
+bool CWorkspaceManager::Closing()
+{
+ Con_Printf( "Checking for sound script changes...\n" );
+
+ MultipleRequestChangeContext();
+
+ // Save any changed sound script files
+ int c = g_pSoundEmitterSystem->GetNumSoundScripts();
+ for ( int i = 0; i < c; i++ )
+ {
+ if ( !g_pSoundEmitterSystem->IsSoundScriptDirty( i ) )
+ continue;
+
+ char const *scriptname = g_pSoundEmitterSystem->GetSoundScriptName( i );
+ if ( !scriptname )
+ continue;
+
+ Assert( filesystem->FileExists( scriptname ) );
+
+ bool save = true;
+
+ if ( filesystem->FileExists( scriptname ) )
+ {
+ if ( !filesystem->IsFileWritable( scriptname ) )
+ {
+ int retval = MultipleRequest( va( "Check out '%s'?", scriptname ));
+ // Cancel
+ if ( retval == 2 )
+ return false;
+
+ if ( retval == 0 )
+ {
+ VSS_Checkout( scriptname );
+
+ if ( !filesystem->IsFileWritable( scriptname ) )
+ {
+ mxMessageBox( NULL, va( "Aborting shutdown, %s, not writable!!", scriptname ), g_appTitle, MX_MB_OK );
+ return false;
+ }
+ }
+ else if ( retval == 1 )
+ {
+ // Don't save
+ save = false;
+ }
+ }
+
+ if ( filesystem->IsFileWritable( scriptname ) )
+ {
+ int retval = mxMessageBox( NULL, va( "Save changes to out '%s'?", scriptname ), g_appTitle, MX_MB_YESNOCANCEL );
+ // Cancel
+ if ( retval == 2 )
+ return false;
+
+ if ( retval == 0 )
+ {
+ if ( !filesystem->IsFileWritable( scriptname ) )
+ {
+ mxMessageBox( NULL, va( "Aborting shutdown, %s, not writable!!", scriptname ), g_appTitle, MX_MB_OK );
+ return false;
+ }
+ }
+ else if ( retval == 1 )
+ {
+ // Skip changes!!!
+ save = false;
+ }
+ }
+ }
+
+ // Try and save it
+ if ( !save )
+ continue;
+
+ g_pSoundEmitterSystem->SaveChangesToSoundScript( i );
+ }
+
+ return CloseWorkspace();
+}
+
+void CWorkspaceManager::OnDelete()
+{
+ SaveRecentFilesMenuToDisk();
+}
+
+void CWorkspaceManager::CreateFileMenu( mxMenu *m )
+{
+ m->add ("&New Workspace", IDC_WSM_FILE_WS_NEW );
+ m->addSeparator();
+ m->add ("Open &Workspace...", IDC_WSM_FILE_WS_OPEN );
+ m->add ("Sa&ve Workspace", IDC_WSM_FILE_WS_SAVE );
+ m->add ("Close Wor&kspace", IDC_WSM_FILE_WS_CLOSE );
+ m->addSeparator();
+ m->add ("&Create New Scene...", IDC_WSM_FILE_SCENE_NEW );
+ m->addSeparator();
+
+ m->add( "V&SS Properties...", IDC_WSM_FILE_WS_VSSPROPERTIES );
+ m->addSeparator();
+
+ m->add( "Refresh\tF5", IDC_WSM_FILE_WS_REFRESH );
+
+ m->addSeparator();
+
+ m_pRecentFileMenu = new mxMenu ();
+ m->addMenu ("Recent Files", m_pRecentFileMenu);
+
+ m->addSeparator();
+ m->add ("E&xit", IDC_WSM_FILE_EXIT );
+}
+
+void CWorkspaceManager::UpdateMenus()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+
+ bool hasworkspace = ws != NULL ? true : false;
+ //bool workspacedirty = ws && ws->IsDirty() ? true : false;
+ bool hasproject = item && item->GetProject() ? true : false;
+
+ m_pMenuBar->setEnabled( IDC_WSM_FILE_WS_SAVE, true );
+ m_pMenuBar->setEnabled( IDC_WSM_FILE_WS_CLOSE, hasworkspace );
+
+
+ if ( hasproject )
+ {
+ m_pMenuBar->modify( IDC_WSM_FILE_SCENE_NEW, IDC_WSM_FILE_SCENE_NEW, va( "&Create Scene in '%s'", item->GetProject()->GetName() ) );
+ }
+ else
+ {
+ m_pMenuBar->modify( IDC_WSM_FILE_SCENE_NEW, IDC_WSM_FILE_SCENE_NEW, "&Create New Scene..." );
+ }
+ m_pMenuBar->setEnabled( IDC_WSM_FILE_SCENE_NEW, hasproject );
+
+}
+
+void CWorkspaceManager::CreateProjectMenu( mxMenu *m )
+{
+ m->add ("Create New Project...", IDC_WSM_PROJECT_PRJ_NEW );
+ m->addSeparator();
+ m->add ("Insert Project...", IDC_WSM_PROJECT_PRJ_INSERT );
+ m->add ("Remove Project...", IDC_WSM_PROJECT_PRJ_REMOVE );
+ m->addSeparator();
+ m->add ("Properties...", IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS );
+}
+
+CWorkspaceBrowser *CWorkspaceManager::GetBrowser()
+{
+ return m_pBrowser;
+}
+
+CSoundBrowser *CWorkspaceManager::GetSoundBrowser()
+{
+ return m_pSoundBrowser;
+}
+
+CWaveBrowser *CWorkspaceManager::GetWaveBrowser()
+{
+ return m_pWaveBrowser;
+}
+
+int CWorkspaceManager::GetMaxRecentFiles() const
+{
+ return IDC_WSM_FILE_RECENT_WORKSPACE_END - IDC_WSM_FILE_RECENT_WORKSPACE_START;
+}
+
+#define MAX_FPS 250.0f
+#define MIN_TIMESTEP ( 1.0f / MAX_FPS )
+
+double realtime = 0.0f;
+
+void CWorkspaceManager::Think( float dt )
+{
+ sound->Update( dt );
+ int c = fileloader->ProcessCompleted();
+ if ( c > 0 )
+ {
+ RefreshBrowsers();
+ Con_Printf( "Thread loaded %i sounds\n", c );
+ }
+}
+
+void CWorkspaceManager::Frame( void )
+{
+ static bool recursion_guard = false;
+
+ static double prev = 0.0;
+ double curr = (double) mx::getTickCount () / 1000.0;
+ double dt = ( curr - prev );
+
+ if ( recursion_guard )
+ return;
+
+ recursion_guard = true;
+
+ // clamp to MAX_FPS
+ if ( dt >= 0.0 && dt < MIN_TIMESTEP )
+ {
+ Sleep( max( 0, (int)( ( MIN_TIMESTEP - dt ) * 1000.0f ) ) );
+
+ recursion_guard = false;
+ return;
+ }
+
+ if ( prev != 0.0 )
+ {
+ dt = min( 0.1, dt );
+
+ Think( dt );
+
+ realtime += dt;
+ }
+
+ prev = curr;
+
+ recursion_guard = false;
+}
+
+int CWorkspaceManager::handleEvent( mxEvent *event )
+{
+ int iret = 0;
+ switch ( event->event )
+ {
+ default:
+ break;
+ case mxEvent::Activate:
+ {
+ if (event->action)
+ {
+ mx::setIdleWindow( this );
+ // Force reload of localization data
+ OnChangeLanguage( GetLanguageId(), true );
+ }
+ else
+ {
+ mx::setIdleWindow( 0 );
+ }
+ iret = 1;
+ }
+ break;
+ case mxEvent::Idle:
+ {
+ iret = 1;
+ Frame();
+ }
+ break;
+ case mxEvent::KeyUp:
+ {
+ if ( event->key == VK_F5 )
+ {
+ RefreshBrowsers();
+ }
+ }
+ break;
+ case mxEvent::Action:
+ {
+ iret = 1;
+ switch ( event->action )
+ {
+ default:
+ {
+ if ( event->action >= IDC_WSM_FILE_RECENT_WORKSPACE_START &&
+ event->action < IDC_WSM_FILE_RECENT_WORKSPACE_END )
+ {
+ OnRecentWorkspace( event->action - IDC_WSM_FILE_RECENT_WORKSPACE_START );
+ }
+ else if ( event->action >= IDC_WSM_OPTIONS_LANGUAGESTART &&
+ event->action < IDC_WSM_OPTIONS_LANGUAGEEND )
+ {
+ OnChangeLanguage( event->action - IDC_WSM_OPTIONS_LANGUAGESTART );
+ }
+ else
+ {
+ iret = 0;
+ }
+ }
+ break;
+ case IDC_WSM_FILE_EXIT:
+ {
+ mx::quit();
+ }
+ break;
+ case IDC_WSM_FILE_WS_REFRESH:
+ {
+ RefreshBrowsers();
+ }
+ break;
+ case IDC_WSM_FILE_WS_NEW:
+ {
+ OnNewWorkspace();
+ }
+ break;
+ case IDC_WSM_FILE_WS_OPEN:
+ {
+ OnOpenWorkspace();
+ }
+ break;
+ case IDC_WSM_FILE_WS_CLOSE:
+ {
+ OnCloseWorkspace();
+ }
+ break;
+ case IDC_WSM_FILE_WS_SAVE:
+ {
+ OnSaveWorkspace();
+ }
+ break;
+ case IDC_WSM_FILE_WS_VSSPROPERTIES:
+ {
+ OnChangeVSSProperites();
+ }
+ break;
+ case IDC_WSM_FILE_WS_CHECKOUT:
+ {
+ OnCheckoutWorkspace();
+ }
+ break;
+ case IDC_WSM_FILE_WS_CHECKIN:
+ {
+ OnCheckinWorkspace();
+ }
+ break;
+ case IDC_WSM_PROJECT_PRJ_NEW:
+ {
+ OnNewProject();
+ }
+ break;
+ case IDC_WSM_PROJECT_PRJ_INSERT:
+ {
+ OnInsertProject();
+ }
+ break;
+ case IDC_WSM_PROJECT_PRJ_REMOVE:
+ {
+ OnRemoveProject();
+ }
+ break;
+ case IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS:
+ {
+ OnModifyProjectComments();
+ }
+ break;
+ case IDC_WSM_PROJECT_SCENE_NEW:
+ {
+ OnNewScene();
+ }
+ break;
+ case IDC_WSM_SOUNDENTRY_PLAY:
+ {
+ OnSoundPlay();
+ }
+ break;
+ case IDC_WSM_SOUNDENTRY_TOGGLEVOICEDUCK:
+ {
+ OnSoundToggleVoiceDuck();
+ }
+ break;
+ case IDC_WSM_SOUNDENTRY_EDITTEXT:
+ {
+ OnSoundEditText();
+ }
+ break;
+ case IDC_WSM_SOUNDENTRY_PROPERTIES:
+ {
+ OnSoundProperties();
+ }
+ break;
+ case IDC_WSM_SCENE_VCD_ADD:
+ {
+ OnSceneAddVCD();
+ }
+ break;
+ case IDC_WSM_SCENE_VCD_REMOVE:
+ {
+ OnSceneRemoveVCD();
+ }
+ break;
+ case IDC_WSM_SCENE_EDIT_COMMENTS:
+ {
+ OnModifySceneComments();
+ }
+ break;
+ case IDC_WSM_VCD_EDIT_COMMENTS:
+ {
+ OnModifyVCDComments();
+ }
+ break;
+ case IDC_WSM_SCENE_REMOVE:
+ {
+ OnRemoveScene();
+ }
+ break;
+ case IDC_WSM_SOUNDENTRY_SHOWINBROWSERS:
+ {
+ OnSoundShowInBrowsers();
+ }
+ break;
+ case IDC_WSM_SELECTION_CHECKOUT:
+ {
+ OnCheckout();
+ }
+ break;
+ case IDC_WSM_SELECTION_CHECKIN:
+ {
+ OnCheckin();
+ }
+ break;
+ case IDC_WSM_SELECTION_MOVEUP:
+ {
+ OnMoveUp();
+ }
+ break;
+ case IDC_WSM_SELECTION_MOVEDOWN:
+ {
+ OnMoveDown();
+ }
+ break;
+ case IDC_WSM_WAVEFILE_PROPERTIES:
+ {
+ OnWaveProperties();
+ }
+ break;
+ }
+ }
+ break;
+ case mxEvent::Size:
+ {
+ iret = 1;
+ PerformLayout( false );
+ }
+ break;
+ }
+
+ return iret;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::PerformLayout( bool movebrowsers )
+{
+ int width = w2();
+ int height = h2();
+
+ int statush = 100;
+ m_pWorkArea->setBounds( 0, 0, width, height - statush );
+ if ( movebrowsers )
+ {
+ GetBrowser()->setBounds( 0, 0, m_pWorkArea->w2(), m_pWorkArea->h2() / 3 );
+ if ( GetSoundBrowser() )
+ {
+ GetSoundBrowser()->setBounds( 0, m_pWorkArea->h2() / 3, m_pWorkArea->w2(), m_pWorkArea->h2() / 3 );
+ }
+ if ( GetWaveBrowser() )
+ {
+ GetWaveBrowser()->setBounds( 0, 2 * m_pWorkArea->h2() / 3, m_pWorkArea->w2(), m_pWorkArea->h2() / 3 );
+ }
+ }
+
+ g_pStatusWindow->setBounds( 0, height - statush, width, statush );
+
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Output : Returns true on success, false on failure.
+//-----------------------------------------------------------------------------
+bool CWorkspaceManager::CloseWorkspace()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ return true;
+
+ if ( !ws->CanClose() )
+ return false;
+
+ delete ws;
+
+ SetWorkspace( NULL );
+
+ return true;
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnUpdateTitle( void )
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+
+ char szTitle[ 256 ];
+ if ( ws )
+ {
+ char const *fmt = g_appTitleFmt;
+ if ( ws->IsDirty() )
+ {
+ fmt = g_appTitleFmtModified;
+ }
+ Q_snprintf( szTitle, sizeof( szTitle ), fmt, ws->GetName(), CSentence::NameForLanguage( m_nLanguageId ) );
+ }
+ else
+ {
+ Q_snprintf( szTitle, sizeof( szTitle ), g_appTitle );
+ }
+
+ setLabel( szTitle );
+
+ UpdateMenus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : *ws -
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::SetWorkspace( CWorkspace *ws )
+{
+ GetBrowser()->SetWorkspace( ws );
+
+ OnUpdateTitle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnNewWorkspace()
+{
+ // Show file io
+ const char *fullpath = mxGetSaveFileName(
+ 0,
+ ".",
+ "*.vsw" );
+
+ if ( !fullpath || !fullpath[ 0 ] )
+ return;
+
+ // Strip game directory and slash
+ char workspace_name[ 512 ];
+ filesystem->FullPathToRelativePath( fullpath, workspace_name, sizeof( workspace_name ) );
+
+ Q_StripExtension( workspace_name, workspace_name, sizeof( workspace_name ) );
+ Q_DefaultExtension( workspace_name, ".vsw", sizeof( workspace_name ) );
+
+ if ( filesystem->FileExists( workspace_name ) )
+ {
+ Con_Printf( "%s exists already!\n", workspace_name );
+ Assert( 0 );
+ return;
+ }
+
+ LoadWorkspace( workspace_name );
+}
+
+void CWorkspaceManager::AddFileToRecentWorkspaceList( char const *filename )
+{
+ int i;
+ int c = m_RecentFiles.Count();
+
+ for ( i = 0; i < c; i++ )
+ {
+ if (!Q_stricmp( m_RecentFiles[i].filename, filename ))
+ break;
+ }
+
+ // swap existing recent file
+ if ( i < c )
+ {
+ RecentFile rf = m_RecentFiles[0];
+ m_RecentFiles[ 0 ] = m_RecentFiles[ i ];
+ m_RecentFiles[ i ] = rf;
+ }
+ // insert recent file
+ else
+ {
+ RecentFile rf;
+ Q_strcpy( rf.filename, filename );
+
+ m_RecentFiles.AddToHead( rf );
+ }
+
+ while( m_RecentFiles.Count() > GetMaxRecentFiles() )
+ {
+ m_RecentFiles.Remove( m_RecentFiles.Count() - 1 );
+ }
+
+ UpdateRecentFilesMenu();
+}
+
+void CWorkspaceManager::LoadRecentFilesMenuFromDisk()
+{
+ KeyValues *kv = new KeyValues( "recentfiles" );
+ if ( kv->LoadFromFile( filesystem, RECENT_FILES_FILE ) )
+ {
+ for ( KeyValues *sub = kv->GetFirstSubKey(); sub; sub = sub->GetNextKey() )
+ {
+ RecentFile rf;
+ Q_strncpy( rf.filename, sub->GetString(), sizeof( rf ) );
+ m_RecentFiles.AddToTail( rf );
+ }
+ }
+ kv->deleteThis();
+
+ UpdateRecentFilesMenu();
+}
+
+void CWorkspaceManager::AutoLoad( char const *workspace )
+{
+ if ( workspace )
+ {
+ LoadWorkspace( workspace );
+ }
+ else
+ {
+ if ( m_RecentFiles.Count() > 0 )
+ {
+ LoadWorkspace( m_RecentFiles[ 0 ].filename );
+ }
+ }
+}
+
+void CWorkspaceManager::SaveRecentFilesMenuToDisk()
+{
+ int i;
+ int c = m_RecentFiles.Count();
+
+ CUtlBuffer buf( 0, 0, CUtlBuffer::TEXT_BUFFER );
+
+ buf.Printf( "recentfiles\n{\n" );
+
+ for ( i = 0; i < c; i++ )
+ {
+ buf.Printf( "\t\"%i\"\t\"%s\"\n", i + 1, m_RecentFiles[ i ].filename );
+ }
+
+ buf.Printf( "}\n" );
+
+ char const *recentfiles = RECENT_FILES_FILE;
+
+ // Write it out baby
+ FileHandle_t fh = filesystem->Open( recentfiles, "wt" );
+ if (fh)
+ {
+ filesystem->Write( buf.Base(), buf.TellPut(), fh );
+ filesystem->Close(fh);
+ }
+ else
+ {
+ Con_Printf( "CWorkspace::SaveRecentFilesMenuToDisk: Unable to write file %s!!!\n", recentfiles );
+ }
+}
+
+void CWorkspaceManager::UpdateRecentFilesMenu()
+{
+ int c = m_RecentFiles.Count();
+
+ while ( c > m_nRecentMenuItems )
+ {
+ m_pRecentFileMenu->add( "(empty)", IDC_WSM_FILE_RECENT_WORKSPACE_START + m_nRecentMenuItems++ );
+ }
+
+ for (int i = 0; i < c; i++)
+ {
+ m_pMenuBar->modify (IDC_WSM_FILE_RECENT_WORKSPACE_START + i, IDC_WSM_FILE_RECENT_WORKSPACE_START + i, m_RecentFiles[i].filename );
+ }
+}
+
+void CWorkspaceManager::LoadWorkspace( char const *filename )
+{
+ if ( !CloseWorkspace() )
+ return;
+
+ Con_Printf( "Loading workspace %s\n", filename );
+
+ CWorkspace *wks = new CWorkspace( filename );
+ SetWorkspace( wks );
+
+ AddFileToRecentWorkspaceList( filename );
+
+ OnUpdateTitle();
+
+ UpdateMenus();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnOpenWorkspace()
+{
+ // Show file io
+ const char *fullpath = mxGetOpenFileName(
+ 0,
+ ".",
+ "*.vsw" );
+
+ if ( !fullpath || !fullpath[ 0 ] )
+ return;
+
+ // Strip game directory and slash
+ char workspace_name[ 512 ];
+ filesystem->FullPathToRelativePath( fullpath, workspace_name, sizeof( workspace_name ) );
+
+ LoadWorkspace( workspace_name );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnCloseWorkspace()
+{
+ if ( !CloseWorkspace() )
+ return;
+
+ Con_Printf( "Closed workspace\n" );
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnSaveWorkspace()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( ws )
+ {
+ ws->SaveChanges();
+
+ OnUpdateTitle();
+ }
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnNewProject()
+{
+ Con_Printf( "OnNewProject()\n" );
+
+ // Show file io
+ const char *fullpath = mxGetSaveFileName(
+ 0,
+ ".",
+ "*.vsp" );
+
+ if ( !fullpath || !fullpath[ 0 ] )
+ return;
+
+ // Strip game directory and slash
+ char project_name[ 512 ];
+ filesystem->FullPathToRelativePath( fullpath, project_name, sizeof( project_name ) );
+
+ Q_StripExtension( project_name, project_name, sizeof( project_name ) );
+ Q_DefaultExtension( project_name, ".vsp", sizeof( project_name ) );
+
+ if ( filesystem->FileExists( project_name ) )
+ {
+ Con_Printf( "%s exists already!\n", project_name );
+ Assert( 0 );
+ return;
+ }
+
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ {
+ // Create one on the fly
+ char workspace_name[ 512 ];
+ Q_StripExtension( project_name, workspace_name, sizeof( workspace_name ) );
+ Q_DefaultExtension( workspace_name, ".vsw", sizeof( workspace_name ) );
+
+ if ( !filesystem->FileExists( workspace_name ) )
+ {
+ int retval = mxMessageBox( NULL, va( "Automatically create workspace %s?", workspace_name ), g_appTitle, MX_MB_YESNOCANCEL );
+ if ( retval != 0 )
+ {
+ Con_Printf( "Canceling project creation\n" );
+ return;
+ }
+ }
+ else
+ {
+ Con_Printf( "Found workspace '%s', automatically loading...\n", workspace_name );
+ }
+
+ LoadWorkspace( workspace_name );
+
+ ws = GetBrowser()->GetWorkspace();
+ }
+
+ if ( ws && ws->FindProjectFile( project_name ) )
+ {
+ Con_Printf( "Project %s already exists in workspace\n", project_name );
+ return;
+ }
+
+ // Create a new project and add it into current workspace
+ CProject *proj = new CProject( ws, project_name );
+ Assert( proj );
+ Assert( ws );
+
+ if ( ws )
+ {
+ GetBrowser()->AddProject( proj );
+ }
+
+ OnUpdateTitle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnInsertProject()
+{
+ Con_Printf( "OnInsertProject()\n" );
+
+ // Show file io
+ const char *fullpath = mxGetOpenFileName(
+ 0,
+ ".",
+ "*.vsp" );
+
+ if ( !fullpath || !fullpath[ 0 ] )
+ return;
+
+ // Strip game directory and slash
+ char project_name[ 512 ];
+ filesystem->FullPathToRelativePath( fullpath, project_name, sizeof( project_name ) );
+
+ Q_StripExtension( project_name, project_name, sizeof( project_name ) );
+ Q_DefaultExtension( project_name, ".vsp", sizeof( project_name ) );
+
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ {
+ // Create one on the fly
+ char workspace_name[ 512 ];
+ Q_StripExtension( project_name, workspace_name, sizeof( workspace_name ) );
+ Q_DefaultExtension( workspace_name, ".vsw", sizeof( workspace_name ) );
+
+ if ( !filesystem->FileExists( workspace_name ) )
+ {
+ int retval = mxMessageBox( NULL, va( "Automatically create workspace %s?", workspace_name ), g_appTitle, MX_MB_YESNOCANCEL );
+ if ( retval != 0 )
+ {
+ Con_Printf( "Canceling project creation\n" );
+ return;
+ }
+ }
+ else
+ {
+ Con_Printf( "Found workspace '%s', automatically loading...\n", workspace_name );
+ }
+
+ LoadWorkspace( workspace_name );
+
+ ws = GetBrowser()->GetWorkspace();
+ }
+
+ if ( ws && ws->FindProjectFile( project_name ) )
+ {
+ Con_Printf( "Project %s already exists in workspace\n", project_name );
+ return;
+ }
+
+ // Create a new project and add it into current workspace
+ CProject *proj = new CProject( ws, project_name );
+ Assert( proj );
+ Assert( ws );
+
+ if ( ws )
+ {
+ GetBrowser()->AddProject( proj );
+ }
+
+ OnUpdateTitle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnRemoveProject()
+{
+ Con_Printf( "OnRemoveProject()\n" );
+
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CProject *project = item->GetProject();
+ if ( !project )
+ {
+ Con_Printf( "Can't remove project, item is not a project\n" );
+ return;
+ }
+
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ {
+ Con_Printf( "Can't remove project '%s', no current workspace?!\n",
+ project->GetName() );
+ return;
+ }
+
+ ws->RemoveProject( project );
+ Con_Printf( "Removed project '%s'\n", project->GetName() );
+ delete project;
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnRemoveScene()
+{
+ Con_Printf( "OnRemoveScene()\n" );
+
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CScene *scene = item->GetScene();
+ if ( !scene )
+ {
+ Con_Printf( "Can't remove scene, item is not a scene\n" );
+ return;
+ }
+
+ CProject *project = scene->GetOwnerProject();
+ if ( !project )
+ {
+ Con_Printf( "Can't remove scene '%s', no current owner project?!\n",
+ scene->GetName() );
+ return;
+ }
+
+ project->RemoveScene( scene );
+ Con_Printf( "Removed scene '%s'\n", scene->GetName() );
+ delete scene;
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnNewScene()
+{
+ Con_Printf( "OnNewScene()\n" );
+
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CProject *project = item->GetProject();
+ if ( !project )
+ {
+ Con_Printf( "Can't add new scene, selected item is not a project\n" );
+ return;
+ }
+
+ CInputParams params;
+ memset( &params, 0, sizeof( params ) );
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Create scene in '%s'", project->GetName() );
+ Q_strcpy( params.m_szPrompt, "Scene Name:" );
+ Q_strcpy( params.m_szInputText, "" );
+
+ if ( !InputProperties( &params ) )
+ return;
+
+ if ( !params.m_szInputText[ 0 ] )
+ {
+ Con_Printf( "You must name the scene!\n" );
+ return;
+ }
+
+ CScene *scene = new CScene( project, params.m_szInputText );
+ Assert( scene );
+
+ project->AddScene( scene );
+
+ Con_Printf( "Added scene '%s' to project '%s'\n", scene->GetName(),
+ project->GetName() );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnModifyProjectComments()
+{
+ Con_Printf( "OnModifyProjectComments()\n" );
+
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CProject *project = item->GetProject();
+ if ( !project )
+ {
+ Con_Printf( "Can't modify comments, item is not a project\n" );
+ return;
+ }
+
+ CInputParams params;
+ memset( &params, 0, sizeof( params ) );
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Edit comments for '%s'", project->GetName() );
+ Q_strcpy( params.m_szPrompt, "Comments:" );
+ Q_strncpy( params.m_szInputText, project->GetComments(), sizeof( params.m_szInputText ) );
+
+ if ( !InputProperties( &params ) )
+ return;
+
+ if ( !Q_strcmp( params.m_szInputText, project->GetComments() ) )
+ return;
+
+ project->SetComments( params.m_szInputText );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+// Input : index -
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnRecentWorkspace( int index )
+{
+ if ( index < 0 || index >= m_RecentFiles.Count() )
+ return;
+
+ LoadWorkspace( m_RecentFiles[ index ].filename );
+}
+
+int CWorkspaceManager::GetLanguageId() const
+{
+ return m_nLanguageId;
+}
+
+void CWorkspaceManager::OnChangeLanguage( int lang_index, bool force /* = false */ )
+{
+ bool changed = m_nLanguageId != lang_index;
+ m_nLanguageId = lang_index;
+
+ if ( changed || force )
+ {
+ // Update the menu
+ for ( int i = 0; i < CC_NUM_LANGUAGES; i++ )
+ {
+ int id = IDC_WSM_OPTIONS_LANGUAGESTART + i;
+ m_pMenuCloseCaptionLanguages->setChecked( id, i == m_nLanguageId );
+ }
+
+ bool filechanged = false;
+
+ char const *suffix = CSentence::NameForLanguage( lang_index );
+ if ( Q_stricmp( suffix, "unknown_language" ) )
+ {
+ char fn[ MAX_PATH ];
+ Q_snprintf( fn, sizeof( fn ), "resource/closecaption_%s.txt", suffix );
+
+ long filetimestamp = filesystem->GetFileTime( fn );
+
+
+ if ( filesystem->FileExists( fn ) )
+ {
+ if ( m_lEnglishCaptionsFileChangeTime != filetimestamp )
+ {
+ filechanged = true;
+ m_lEnglishCaptionsFileChangeTime = filetimestamp;
+ //Con_Printf( "Reloading close caption data from '%s'\n", fn );
+ g_pVGuiLocalize->RemoveAll();
+ g_pVGuiLocalize->AddFile( fn );
+ }
+ }
+ else
+ {
+ Con_Printf( "CWorkspaceManager::OnChangeLanguage Warning, can't find localization file %s\n", fn );
+ }
+ }
+
+ if ( !force || filechanged )
+ {
+ // Update all text for items.
+ RefreshBrowsers();
+
+ OnUpdateTitle();
+ }
+ }
+}
+
+void CWorkspaceManager::OnDoubleClicked( ITreeItem *item )
+{
+ CSoundEntry *s = item->GetSoundEntry();
+ if ( s )
+ {
+ s->Play();
+ return;
+ }
+}
+
+void CWorkspaceManager::OnSoundPlay()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( item->GetSoundEntry() )
+ {
+ item->GetSoundEntry()->Play();
+ }
+ else if ( item->GetWaveFile() )
+ {
+ item->GetWaveFile()->Play();
+ }
+}
+
+void CWorkspaceManager::OnSoundToggleVoiceDuck()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( item->GetWaveFile() )
+ {
+ item->GetWaveFile()->ToggleVoiceDucking();
+ }
+}
+
+void CWorkspaceManager::OnSoundEditText()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CWaveFile *s = item->GetWaveFile();
+ if ( !s )
+ return;
+
+ CInputParams params;
+ memset( &params, 0, sizeof( params ) );
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Edit text of '%s'", s->GetName() );
+ Q_strcpy( params.m_szPrompt, "Sentence text:" );
+ V_strcpy_safe( params.m_szInputText, s->GetSentenceText() );
+
+ if ( !InputProperties( &params ) )
+ return;
+
+ if ( !Q_stricmp( params.m_szInputText, s->GetSentenceText() ) )
+ {
+ return;
+ }
+
+ s->SetSentenceText( params.m_szInputText );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+// Scene entries
+void CWorkspaceManager::OnSceneAddVCD()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CScene *scene = item->GetScene();
+ if ( !scene )
+ return;
+
+ // Show file io
+ const char *fullpath = mxGetOpenFileName(
+ 0,
+ ".",
+ "*.vcd" );
+
+ if ( !fullpath || !fullpath[ 0 ] )
+ return;
+
+ // Strip game directory and slash
+ char vcd_name[ 512 ];
+ filesystem->FullPathToRelativePath( fullpath, vcd_name, sizeof( vcd_name ) );
+
+ Q_StripExtension( vcd_name, vcd_name, sizeof( vcd_name ) );
+ Q_DefaultExtension( vcd_name, ".vcd", sizeof( vcd_name ) );
+
+ if ( scene->FindVCD( vcd_name ) )
+ {
+ Con_Printf( "File '%s' is already in scene '%s'\n", vcd_name, scene->GetName() );
+ return;
+ }
+
+ CVCDFile *vcd = new CVCDFile( scene, vcd_name );
+
+ scene->AddVCD( vcd );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnModifySceneComments()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CScene *scene = item->GetScene();
+ if ( !scene )
+ return;
+
+ CInputParams params;
+ memset( &params, 0, sizeof( params ) );
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Edit comments for '%s'", scene->GetName() );
+ Q_strcpy( params.m_szPrompt, "Comments:" );
+ Q_strncpy( params.m_szInputText, scene->GetComments(), sizeof( params.m_szInputText ) );
+
+ if ( !InputProperties( &params ) )
+ return;
+
+ if ( !Q_strcmp( params.m_szInputText, scene->GetComments() ) )
+ return;
+
+ scene->SetComments( params.m_szInputText );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnModifyVCDComments()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CVCDFile *file = item->GetVCDFile();
+ if ( !file )
+ return;
+
+ CInputParams params;
+ memset( &params, 0, sizeof( params ) );
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Edit comments for '%s'", file->GetName() );
+ Q_strcpy( params.m_szPrompt, "Comments:" );
+ Q_strncpy( params.m_szInputText, file->GetComments(), sizeof( params.m_szInputText ) );
+
+ if ( !InputProperties( &params ) )
+ return;
+
+ if ( !Q_strcmp( params.m_szInputText, file->GetComments() ) )
+ return;
+
+ file->SetComments( params.m_szInputText );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnSceneRemoveVCD()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CVCDFile *file = item->GetVCDFile();
+ if ( !file )
+ return;
+
+ CScene *scene = file->GetOwnerScene();
+ if ( !scene )
+ return;
+
+ scene->RemoveVCD( file );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::ShowContextMenu( int x, int y, ITreeItem *p )
+{
+ CWorkspace *w = p->GetWorkspace();
+ if ( w )
+ {
+ ShowContextMenu_Workspace( x, y, w );
+ return;
+ }
+
+ CProject *proj = p->GetProject();
+ if ( proj )
+ {
+ ShowContextMenu_Project( x, y, proj );
+ return;
+ }
+
+ CScene *scene = p->GetScene();
+ if ( scene )
+ {
+ ShowContextMenu_Scene( x, y, scene );
+ return;
+ }
+
+ CVCDFile *vcd = p->GetVCDFile();
+ if ( vcd )
+ {
+ ShowContextMenu_VCD( x, y, vcd );
+ return;
+ }
+
+ CSoundEntry *sound = p->GetSoundEntry();
+ if ( sound )
+ {
+ ShowContextMenu_SoundEntry( x, y, sound );
+ return;
+ }
+
+ CWaveFile *wave = p->GetWaveFile();
+ if ( wave )
+ {
+ ShowContextMenu_WaveFile( x, y, wave );
+ return;
+ }
+
+ Con_Printf( "unknown tree item type\n" );
+ Assert( 0 );
+}
+
+void CWorkspaceManager::ShowContextMenu_Workspace( int x, int y, CWorkspace *ws )
+{
+ if ( !ws )
+ return;
+
+ // New project and insert project
+ mxPopupMenu *pop = new mxPopupMenu();
+
+ pop->add ("Create New Project...", IDC_WSM_PROJECT_PRJ_NEW );
+ pop->add ("Insert Project...", IDC_WSM_PROJECT_PRJ_INSERT );
+ pop->addSeparator();
+ pop->add( "VSS Properties...", IDC_WSM_FILE_WS_VSSPROPERTIES );
+
+ if ( !filesystem->IsFileWritable( ws->GetFileName() ) )
+ {
+ pop->add( va( "Checkout '%s'", ws->GetName() ), IDC_WSM_SELECTION_CHECKOUT );
+ }
+ else
+ {
+ pop->add( va( "Checkin '%s'", ws->GetName() ), IDC_WSM_SELECTION_CHECKIN );
+ }
+
+ pop->popup( this, x, y );
+}
+
+void CWorkspaceManager::ShowContextMenu_Project( int x, int y, CProject *project )
+{
+ // New scene, edit comments
+ mxPopupMenu *pop = new mxPopupMenu();
+
+ pop->add ("Create New Scene...", IDC_WSM_PROJECT_SCENE_NEW );
+ pop->addSeparator();
+ pop->add ("Remove Project...", IDC_WSM_PROJECT_PRJ_REMOVE );
+ pop->addSeparator();
+ pop->add( "Edit comments...", IDC_WSM_PROJECT_PRJ_MODIFYCOMMENTS );
+ if ( !project->IsFirstChild() || !project->IsLastChild() )
+ {
+ pop->addSeparator();
+ if( !project->IsFirstChild() )
+ {
+ pop->add( va( "Move '%s' Up", project->GetName() ), IDC_WSM_SELECTION_MOVEUP );
+ }
+ if( !project->IsLastChild() )
+ {
+ pop->add( va( "Move '%s' Down", project->GetName() ), IDC_WSM_SELECTION_MOVEDOWN );
+ }
+ }
+ pop->addSeparator();
+
+ if ( !filesystem->IsFileWritable( project->GetFileName() ) )
+ {
+ pop->add( va( "Checkout '%s'", project->GetName() ), IDC_WSM_SELECTION_CHECKOUT );
+ }
+ else
+ {
+ pop->add( va( "Checkin '%s'", project->GetName() ), IDC_WSM_SELECTION_CHECKIN );
+ }
+
+ pop->popup( this, x, y );
+}
+
+void CWorkspaceManager::ShowContextMenu_Scene( int x, int y, CScene *scene )
+{
+ // New scene, edit comments
+ mxPopupMenu *pop = new mxPopupMenu();
+
+ pop->add( va( "Add VCD to '%s'...", scene->GetName() ), IDC_WSM_SCENE_VCD_ADD );
+ pop->addSeparator();
+ pop->add ("Remove Scene", IDC_WSM_SCENE_REMOVE );
+ pop->addSeparator();
+ pop->add( va( "Edit comments..." ), IDC_WSM_SCENE_EDIT_COMMENTS );
+ if ( !scene->IsFirstChild() || !scene->IsLastChild() )
+ {
+ pop->addSeparator();
+ if( !scene->IsFirstChild() )
+ {
+ pop->add( va( "Move '%s' Up", scene->GetName() ), IDC_WSM_SELECTION_MOVEUP );
+ }
+ if( !scene->IsLastChild() )
+ {
+ pop->add( va( "Move '%s' Down", scene->GetName() ), IDC_WSM_SELECTION_MOVEDOWN );
+ }
+ }
+
+ pop->popup( this, x, y );
+}
+
+void CWorkspaceManager::ShowContextMenu_VCD( int x, int y, CVCDFile *vcd )
+{
+ // New scene, edit comments
+ mxPopupMenu *pop = new mxPopupMenu();
+
+ pop->add( va( "Remove VCD" ), IDC_WSM_SCENE_VCD_REMOVE );
+ pop->addSeparator();
+ pop->add( va( "Edit comments..." ), IDC_WSM_VCD_EDIT_COMMENTS );
+ if ( !vcd->IsFirstChild() || !vcd->IsLastChild() )
+ {
+ pop->addSeparator();
+ if( !vcd->IsFirstChild() )
+ {
+ pop->add( va( "Move '%s' Up", vcd->GetName() ), IDC_WSM_SELECTION_MOVEUP );
+ }
+ if( !vcd->IsLastChild() )
+ {
+ pop->add( va( "Move '%s' Down", vcd->GetName() ), IDC_WSM_SELECTION_MOVEDOWN );
+ }
+ }
+ pop->addSeparator();
+ if ( !filesystem->IsFileWritable( vcd->GetName() ) )
+ {
+ pop->add( va( "Checkout '%s'", vcd->GetName() ), IDC_WSM_SELECTION_CHECKOUT );
+ }
+ else
+ {
+ pop->add( va( "Checkin '%s'", vcd->GetName() ), IDC_WSM_SELECTION_CHECKIN );
+ }
+
+ pop->popup( this, x, y );
+}
+
+void CWorkspaceManager::ShowContextMenu_SoundEntry( int x, int y, CSoundEntry *entry )
+{
+ // New scene, edit comments
+ mxPopupMenu *pop = new mxPopupMenu();
+
+ pop->add ("&Play", IDC_WSM_SOUNDENTRY_PLAY );
+ // pop->add( "&Jump To", IDC_WSM_SOUNDENTRY_SHOWINBROWSERS );
+ pop->addSeparator();
+
+ pop->add( "Properties...", IDC_WSM_SOUNDENTRY_PROPERTIES );
+
+ pop->popup( this, x, y );
+}
+
+void CWorkspaceManager::ShowContextMenu_WaveFile( int x, int y, CWaveFile *entry )
+{
+ // New scene, edit comments
+ mxPopupMenu *pop = new mxPopupMenu();
+
+ pop->add ("&Play", IDC_WSM_SOUNDENTRY_PLAY );
+ // pop->add( "&Jump To", IDC_WSM_SOUNDENTRY_SHOWINBROWSERS );
+
+ if ( entry->GetVoiceDuck() )
+ {
+ pop->add ("Disable &voice duck", IDC_WSM_SOUNDENTRY_TOGGLEVOICEDUCK );
+ }
+ else
+ {
+ pop->add ("Enable &voice duck", IDC_WSM_SOUNDENTRY_TOGGLEVOICEDUCK );
+ }
+ pop->add( "&Edit sentence text...", IDC_WSM_SOUNDENTRY_EDITTEXT );
+ pop->addSeparator();
+ if ( !filesystem->IsFileWritable( entry->GetFileName() ) )
+ {
+ pop->add( va( "Checkout '%s'", entry->GetName() ), IDC_WSM_SELECTION_CHECKOUT );
+ }
+ else
+ {
+ pop->add( va( "Checkin '%s'", entry->GetName() ), IDC_WSM_SELECTION_CHECKIN );
+ }
+ pop->addSeparator();
+ pop->add( "Properties...", IDC_WSM_WAVEFILE_PROPERTIES );
+
+ pop->popup( this, x, y );
+}
+
+
+void CWorkspaceManager::OnChangeVSSProperites()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ {
+ return;
+ }
+
+ CVSSParams params;
+ memset( &params, 0, sizeof( params ) );
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "VSS Properites" );
+ V_strcpy_safe( params.m_szUserName, ws->GetVSSUserName() );
+ V_strcpy_safe( params.m_szProject, ws->GetVSSProject() );
+
+ if ( !VSSProperties( &params ) )
+ return;
+
+ if ( !params.m_szUserName[ 0 ] )
+ {
+ Con_Printf( "You must enter a user name\n" );
+ return;
+ }
+
+ if ( !params.m_szProject[ 0 ] )
+ {
+ Con_Printf( "You must enter a project name\n" );
+ return;
+ }
+
+ ws->SetVSSUserName( params.m_szUserName );
+ ws->SetVSSProject( params.m_szProject );
+
+ ws->SetDirty( true );
+
+ Con_Printf( "VSS user = '%s', project = '%s'\n",
+ ws->GetVSSUserName(), ws->GetVSSProject() );
+}
+
+void CWorkspaceManager::OnCheckoutWorkspace()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ {
+ return;
+ }
+
+ ws->Checkout();
+}
+
+void CWorkspaceManager::OnCheckinWorkspace()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( !ws )
+ {
+ return;
+ }
+
+ ws->Checkin();
+}
+
+
+#define CX_ICON 16
+#define CY_ICON 16
+
+HIMAGELIST CWorkspaceManager::CreateImageList()
+{
+ HIMAGELIST list;
+
+ list = ImageList_Create( CX_ICON, CY_ICON,
+ FALSE, NUM_IMAGES, 0 );
+
+ // Load the icon resources, and add the icons to the image list.
+ HICON hicon;
+ int slot;
+#if defined( DBGFLAG_ASSERT )
+ int c = 0;
+#endif
+
+ hicon = LoadIcon( GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WORKSPACE));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon( GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WORKSPACE_CHECKEDOUT));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_PROJECT));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_PROJECT_CHECKEDOUT));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SCENE));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+// hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SCENE_CHECKEDOUT));
+// slot = ImageList_AddIcon(list, hicon);
+// Assert( slot == c++ );
+// DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_VCD));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_VCD_CHECKEDOUT ));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WAV));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_WAV_CHECKEDOUT));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SPEAK));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ hicon = LoadIcon(GetModuleHandle( 0 ), MAKEINTRESOURCE(IDI_SPEAK_CHECKEDOUT));
+ slot = ImageList_AddIcon(list, hicon);
+ Assert( slot == c++ );
+ DeleteObject( hicon );
+
+ return list;
+}
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::RefreshBrowsers()
+{
+ if ( GetBrowser() )
+ {
+ GetBrowser()->PopulateTree();
+ }
+
+ if ( GetSoundBrowser() )
+ {
+ GetSoundBrowser()->RepopulateTree();
+ }
+
+ if ( GetWaveBrowser() )
+ {
+ GetWaveBrowser()->RepopulateTree();
+ }
+}
+
+void CWorkspaceManager::OnSoundShowInBrowsers()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CSoundEntry *se = item->GetSoundEntry();
+ if ( se )
+ {
+ GetSoundBrowser()->JumpToItem( se );
+ return;
+ }
+
+ CWaveFile *wave = item->GetWaveFile();
+ if ( wave )
+ {
+ GetWaveBrowser()->JumpToItem( wave );
+ if ( wave->GetOwnerSoundEntry() )
+ {
+ GetSoundBrowser()->JumpToItem( wave->GetOwnerSoundEntry() );
+ }
+ }
+}
+
+void CWorkspaceManager::OnCheckout()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ item->Checkout();
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnCheckin()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ item->Checkin();
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+}
+
+void CWorkspaceManager::OnMoveUp()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ ITreeItem *parent = item->GetParentItem();
+ if ( !parent )
+ return;
+
+ parent->MoveChildUp( item );
+
+ parent->SetDirty( true );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+
+ GetBrowser()->JumpTo( item );
+}
+
+void CWorkspaceManager::OnMoveDown()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ ITreeItem *parent = item->GetParentItem();
+ if ( !parent )
+ return;
+
+ parent->MoveChildDown( item );
+
+ parent->SetDirty( true );
+
+ GetBrowser()->PopulateTree();
+
+ OnUpdateTitle();
+
+ GetBrowser()->JumpTo( item );
+}
+
+void CWorkspaceManager::SetWorkspaceDirty()
+{
+ CWorkspace *ws = GetBrowser()->GetWorkspace();
+ if ( ws )
+ {
+ ws->SetDirty( true );
+ }
+ OnUpdateTitle();
+}
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnSoundProperties()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CSoundEntry *entry = item->GetSoundEntry();
+ if ( !entry )
+ return;
+
+ CSoundParams params;
+ memset( &params, 0, sizeof( params ) );
+
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Sound Properties" );
+
+ params.items.AddToTail( entry );
+
+ SoundProperties( &params );
+}
+
+
+
+//-----------------------------------------------------------------------------
+// Purpose:
+//-----------------------------------------------------------------------------
+void CWorkspaceManager::OnWaveProperties()
+{
+ ITreeItem *item = GetBrowser()->GetSelectedItem();
+ if ( !item )
+ return;
+
+ CWaveFile *wave = item->GetWaveFile();
+ if ( !wave )
+ return;
+
+ CWaveParams params;
+ memset( &params, 0, sizeof( params ) );
+
+ Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Wave Properties" );
+
+ params.items.AddToTail( wave );
+
+ WaveProperties( &params );
+}