//========= 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 #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 #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( ¶ms, 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( ¶ms ) ) 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( ¶ms, 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( ¶ms ) ) 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( ¶ms, 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( ¶ms ) ) 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( ¶ms, 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( ¶ms ) ) 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( ¶ms, 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( ¶ms ) ) 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( ¶ms, 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( ¶ms ) ) 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( ¶ms, 0, sizeof( params ) ); Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Sound Properties" ); params.items.AddToTail( entry ); SoundProperties( ¶ms ); } //----------------------------------------------------------------------------- // Purpose: //----------------------------------------------------------------------------- void CWorkspaceManager::OnWaveProperties() { ITreeItem *item = GetBrowser()->GetSelectedItem(); if ( !item ) return; CWaveFile *wave = item->GetWaveFile(); if ( !wave ) return; CWaveParams params; memset( ¶ms, 0, sizeof( params ) ); Q_snprintf( params.m_szDialogTitle, sizeof( params.m_szDialogTitle ), "Wave Properties" ); params.items.AddToTail( wave ); WaveProperties( ¶ms ); }