aboutsummaryrefslogtreecommitdiff
path: root/sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp
diff options
context:
space:
mode:
authorJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
committerJoe Ludwig <[email protected]>2013-06-26 15:22:04 -0700
commit39ed87570bdb2f86969d4be821c94b722dc71179 (patch)
treeabc53757f75f40c80278e87650ea92808274aa59 /sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp
downloadsource-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.tar.xz
source-sdk-2013-39ed87570bdb2f86969d4be821c94b722dc71179.zip
First version of the SOurce SDK 2013
Diffstat (limited to 'sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp')
-rw-r--r--sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp497
1 files changed, 497 insertions, 0 deletions
diff --git a/sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp b/sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp
new file mode 100644
index 00000000..5572c753
--- /dev/null
+++ b/sp/src/vgui2/vgui_controls/FileOpenStateMachine.cpp
@@ -0,0 +1,497 @@
+//========= Copyright Valve Corporation, All rights reserved. ============//
+//
+// This is a helper class designed to help with the chains of modal dialogs
+// encountered when trying to open or save a particular file
+//
+//=============================================================================
+
+#include "vgui_controls/FileOpenStateMachine.h"
+#include "tier1/KeyValues.h"
+#include "vgui_controls/FileOpenDialog.h"
+#include "vgui_controls/MessageBox.h"
+#include "vgui_controls/perforcefilelistframe.h"
+#include "vgui_controls/savedocumentquery.h"
+#include "filesystem.h"
+#include "p4lib/ip4.h"
+#include "tier2/tier2.h"
+#include "tier0/icommandline.h"
+
+// memdbgon must be the last include file in a .cpp file!!!
+#include "tier0/memdbgon.h"
+
+
+using namespace vgui;
+
+
+//-----------------------------------------------------------------------------
+// Constructor
+//-----------------------------------------------------------------------------
+FileOpenStateMachine::FileOpenStateMachine( vgui::Panel *pParent, IFileOpenStateMachineClient *pClient ) : BaseClass( pParent, "FileOpenStateMachine" )
+{
+ m_pClient = pClient;
+ m_CompletionState = SUCCESSFUL;
+ m_CurrentState = STATE_NONE;
+ m_pContextKeyValues = NULL;
+ SetVisible( false );
+}
+
+FileOpenStateMachine::~FileOpenStateMachine()
+{
+ CleanUpContextKeyValues();
+}
+
+
+//-----------------------------------------------------------------------------
+// Cleans up keyvalues
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::CleanUpContextKeyValues()
+{
+ if ( m_pContextKeyValues )
+ {
+ m_pContextKeyValues->deleteThis();
+ m_pContextKeyValues = NULL;
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Returns the state machine completion state
+//-----------------------------------------------------------------------------
+FileOpenStateMachine::CompletionState_t FileOpenStateMachine::GetCompletionState()
+{
+ return m_CompletionState;
+}
+
+
+//-----------------------------------------------------------------------------
+// Utility to set the completion state
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::SetCompletionState( FileOpenStateMachine::CompletionState_t state )
+{
+ m_CompletionState = state;
+ if ( m_CompletionState == IN_PROGRESS )
+ return;
+
+ m_CurrentState = STATE_NONE;
+
+ KeyValues *kv = new KeyValues( "FileStateMachineFinished" );
+ kv->SetInt( "completionState", m_CompletionState );
+ kv->SetInt( "wroteFile", m_bWroteFile );
+ kv->SetString( "fullPath", m_FileName.Get() );
+ kv->SetString( "fileType", m_bIsOpeningFile ? m_OpenFileType.Get() : m_SaveFileType.Get() );
+ if ( m_pContextKeyValues )
+ {
+ kv->AddSubKey( m_pContextKeyValues );
+ m_pContextKeyValues = NULL;
+ }
+ PostActionSignal( kv );
+}
+
+
+//-----------------------------------------------------------------------------
+// Called by the message box in OverwriteFileDialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OnOverwriteFile( )
+{
+ CheckOutDialog( );
+}
+
+void FileOpenStateMachine::OnCancelOverwriteFile( )
+{
+ SetCompletionState( FILE_NOT_OVERWRITTEN );
+}
+
+
+//-----------------------------------------------------------------------------
+// Shows the overwrite existing file dialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OverwriteFileDialog( )
+{
+ if ( !g_pFullFileSystem->FileExists( m_FileName ) )
+ {
+ CheckOutDialog( );
+ return;
+ }
+
+ m_CurrentState = STATE_SHOWING_OVERWRITE_DIALOG;
+
+ char pBuf[1024];
+ Q_snprintf( pBuf, sizeof(pBuf), "File already exists. Overwrite it?\n\n\"%s\"\n", m_FileName.Get() );
+ vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Overwrite Existing File?", pBuf, GetParent() );
+ pMessageBox->AddActionSignalTarget( this );
+ pMessageBox->SetOKButtonVisible( true );
+ pMessageBox->SetOKButtonText( "Yes" );
+ pMessageBox->SetCancelButtonVisible( true );
+ pMessageBox->SetCancelButtonText( "No" );
+ pMessageBox->SetCloseButtonVisible( false );
+ pMessageBox->SetCommand( new KeyValues( "OverwriteFile" ) );
+ pMessageBox->SetCancelCommand( new KeyValues( "CancelOverwriteFile" ) );
+ pMessageBox->DoModal();
+}
+
+
+//-----------------------------------------------------------------------------
+// Used to open a particular file in perforce, and deal with all the lovely dialogs
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OnFileSelectionCancelled()
+{
+ if ( m_CurrentState == STATE_SHOWING_SAVE_DIALOG )
+ {
+ SetCompletionState( FILE_SAVE_NAME_NOT_SPECIFIED );
+ return;
+ }
+
+ if ( m_CurrentState == STATE_SHOWING_OPEN_DIALOG )
+ {
+ SetCompletionState( FILE_OPEN_NAME_NOT_SPECIFIED );
+ return;
+ }
+
+ Assert(0);
+}
+
+
+//-----------------------------------------------------------------------------
+// Used to open a particular file in perforce, and deal with all the lovely dialogs
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OnFileSelected( KeyValues *pKeyValues )
+{
+ if ( m_CurrentState == STATE_SHOWING_SAVE_DIALOG )
+ {
+ m_FileName = pKeyValues->GetString( "fullpath" );
+ const char *pFilterInfo = pKeyValues->GetString( "filterinfo" );
+ if ( pFilterInfo )
+ {
+ m_SaveFileType = pFilterInfo;
+ }
+ OverwriteFileDialog();
+ return;
+ }
+
+ if ( m_CurrentState == STATE_SHOWING_OPEN_DIALOG )
+ {
+ m_FileName = pKeyValues->GetString( "fullpath" );
+ const char *pFilterInfo = pKeyValues->GetString( "filterinfo" );
+ if ( pFilterInfo )
+ {
+ m_OpenFileType = pFilterInfo;
+ }
+ ReadFile( );
+ return;
+ }
+
+ Assert(0);
+}
+
+
+//-----------------------------------------------------------------------------
+// Writes the file out
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::WriteFile()
+{
+ m_CurrentState = STATE_WRITING_FILE;
+ if ( !m_pClient->OnWriteFileToDisk( m_FileName, m_SaveFileType, m_pContextKeyValues ) )
+ {
+ SetCompletionState( ERROR_WRITING_FILE );
+ return;
+ }
+
+ m_bWroteFile = true;
+ if ( m_bShowPerforceDialogs )
+ {
+ m_CurrentState = STATE_SHOWING_PERFORCE_ADD_DIALOG;
+ ShowPerforceQuery( GetParent(), m_FileName, this, NULL, PERFORCE_ACTION_FILE_ADD );
+ return;
+ }
+
+ if ( !m_bIsOpeningFile )
+ {
+ SetCompletionState( SUCCESSFUL );
+ return;
+ }
+
+ OpenFileDialog();
+}
+
+
+//-----------------------------------------------------------------------------
+// Called by the message box in MakeFileWriteableDialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OnMakeFileWriteable( )
+{
+ if ( !g_pFullFileSystem->SetFileWritable( m_FileName, true ) )
+ {
+ SetCompletionState( ERROR_MAKING_FILE_WRITEABLE );
+ return;
+ }
+
+ WriteFile();
+}
+
+void FileOpenStateMachine::OnCancelMakeFileWriteable( )
+{
+ SetCompletionState( FILE_NOT_MADE_WRITEABLE );
+}
+
+
+//-----------------------------------------------------------------------------
+// Shows the make file writeable dialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::MakeFileWriteableDialog( )
+{
+ // If the file is writeable, write it!
+ if ( !g_pFullFileSystem->FileExists( m_FileName ) || g_pFullFileSystem->IsFileWritable( m_FileName ) )
+ {
+ WriteFile();
+ return;
+ }
+
+ // If it's in perforce, and not checked out, then we must abort.
+ bool bIsInPerforce = p4->IsFileInPerforce( m_FileName );
+ bool bIsOpened = ( p4->GetFileState( m_FileName ) != P4FILE_UNOPENED );
+ if ( bIsInPerforce && !bIsOpened )
+ {
+ SetCompletionState( FILE_NOT_CHECKED_OUT );
+ return;
+ }
+
+ m_CurrentState = STATE_SHOWING_MAKE_FILE_WRITEABLE_DIALOG;
+
+ char pBuf[1024];
+ Q_snprintf( pBuf, sizeof(pBuf), "Encountered read-only file. Should it be made writeable?\n\n\"%s\"\n", m_FileName.Get() );
+ vgui::MessageBox *pMessageBox = new vgui::MessageBox( "Make File Writeable?", pBuf, GetParent() );
+ pMessageBox->AddActionSignalTarget( this );
+ pMessageBox->SetOKButtonVisible( true );
+ pMessageBox->SetOKButtonText( "Yes" );
+ pMessageBox->SetCancelButtonVisible( true );
+ pMessageBox->SetCancelButtonText( "No" );
+ pMessageBox->SetCloseButtonVisible( false );
+ pMessageBox->SetCommand( new KeyValues( "MakeFileWriteable" ) );
+ pMessageBox->SetCancelCommand( new KeyValues( "CancelMakeFileWriteable" ) );
+ pMessageBox->DoModal();
+}
+
+
+//-----------------------------------------------------------------------------
+// Called when ShowPerforceQuery completes
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OnPerforceQueryCompleted( KeyValues *pKeyValues )
+{
+ if ( m_CurrentState == STATE_SHOWING_CHECK_OUT_DIALOG )
+ {
+ if ( pKeyValues->GetInt( "operationPerformed" ) == 0 )
+ {
+ SetCompletionState( FILE_NOT_CHECKED_OUT );
+ return;
+ }
+
+ MakeFileWriteableDialog();
+ return;
+ }
+
+ if ( m_CurrentState == STATE_SHOWING_PERFORCE_ADD_DIALOG )
+ {
+ if ( !m_bIsOpeningFile )
+ {
+ SetCompletionState( SUCCESSFUL );
+ return;
+ }
+
+ OpenFileDialog();
+ return;
+ }
+
+ Assert(0);
+}
+
+
+//-----------------------------------------------------------------------------
+// Used to open a particular file in perforce, and deal with all the lovely dialogs
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::CheckOutDialog( )
+{
+ if ( m_bShowPerforceDialogs )
+ {
+ m_CurrentState = STATE_SHOWING_CHECK_OUT_DIALOG;
+ ShowPerforceQuery( GetParent(), m_FileName, this, NULL, PERFORCE_ACTION_FILE_EDIT );
+ return;
+ }
+
+ WriteFile();
+}
+
+
+//-----------------------------------------------------------------------------
+// These 3 messages come from the savedocumentquery dialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OnSaveFile()
+{
+ if ( !m_FileName[0] || !Q_IsAbsolutePath( m_FileName ) )
+ {
+ m_CurrentState = STATE_SHOWING_SAVE_DIALOG;
+
+ FileOpenDialog *pDialog = new FileOpenDialog( GetParent(), "Save As", false );
+ m_pClient->SetupFileOpenDialog( pDialog, false, m_SaveFileType, m_pContextKeyValues );
+ pDialog->SetDeleteSelfOnClose( true );
+ pDialog->AddActionSignalTarget( this );
+ pDialog->DoModal( );
+ return;
+ }
+
+ CheckOutDialog( );
+}
+
+void FileOpenStateMachine::OnMarkNotDirty()
+{
+ if ( !m_bIsOpeningFile )
+ {
+ SetCompletionState( SUCCESSFUL );
+ return;
+ }
+
+ // Jump right to opening the file
+ OpenFileDialog( );
+}
+
+void FileOpenStateMachine::OnCancelSaveDocument()
+{
+ SetCompletionState( FILE_SAVE_CANCELLED );
+}
+
+
+//-----------------------------------------------------------------------------
+// Show the save document query dialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::ShowSaveQuery( )
+{
+ m_CurrentState = STATE_SHOWING_SAVE_DIRTY_FILE_DIALOG;
+ ShowSaveDocumentQuery( GetParent(), m_FileName, m_SaveFileType, 0, this, NULL );
+}
+
+
+//-----------------------------------------------------------------------------
+// Used to save a specified file, and deal with all the lovely dialogs
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::SaveFile( KeyValues *pContextKeyValues, const char *pFileName, const char *pFileType, int nFlags )
+{
+ CleanUpContextKeyValues();
+ SetCompletionState( IN_PROGRESS );
+ m_pContextKeyValues = pContextKeyValues;
+ m_FileName = pFileName;
+ m_SaveFileType = pFileType;
+ m_OpenFileType = NULL;
+ m_OpenFileName = NULL;
+
+ // Clear the P4 dialog flag for SDK users and licensees without Perforce
+ if ( g_pFullFileSystem->IsSteam() || CommandLine()->FindParm( "-nop4" ) )
+ {
+ nFlags &= ~FOSM_SHOW_PERFORCE_DIALOGS;
+ }
+
+ m_bShowPerforceDialogs = ( nFlags & FOSM_SHOW_PERFORCE_DIALOGS ) != 0;
+ m_bShowSaveQuery = ( nFlags & FOSM_SHOW_SAVE_QUERY ) != 0;
+ m_bIsOpeningFile = false;
+ m_bWroteFile = false;
+
+ if ( m_bShowSaveQuery )
+ {
+ ShowSaveQuery();
+ return;
+ }
+
+ OnSaveFile();
+}
+
+
+//-----------------------------------------------------------------------------
+// Reads the file in
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::ReadFile()
+{
+ m_CurrentState = STATE_READING_FILE;
+ if ( !m_pClient->OnReadFileFromDisk( m_FileName, m_OpenFileType, m_pContextKeyValues ) )
+ {
+ SetCompletionState( ERROR_READING_FILE );
+ return;
+ }
+
+ SetCompletionState( SUCCESSFUL );
+}
+
+
+//-----------------------------------------------------------------------------
+// Shows the open file dialog
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OpenFileDialog( )
+{
+ m_CurrentState = STATE_SHOWING_OPEN_DIALOG;
+
+ if ( m_OpenFileName.IsEmpty() )
+ {
+ FileOpenDialog *pDialog = new FileOpenDialog( GetParent(), "Open", true );
+ m_pClient->SetupFileOpenDialog( pDialog, true, m_OpenFileType, m_pContextKeyValues );
+ pDialog->SetDeleteSelfOnClose( true );
+ pDialog->AddActionSignalTarget( this );
+ pDialog->DoModal( );
+ }
+ else
+ {
+ m_FileName = m_OpenFileName;
+ ReadFile();
+ }
+}
+
+
+//-----------------------------------------------------------------------------
+// Opens a file, saves an existing one if necessary
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OpenFile( const char *pOpenFileType, KeyValues *pContextKeyValues, const char *pSaveFileName, const char *pSaveFileType, int nFlags )
+{
+ CleanUpContextKeyValues();
+ SetCompletionState( IN_PROGRESS );
+ m_pContextKeyValues = pContextKeyValues;
+ m_FileName = pSaveFileName;
+ m_SaveFileType = pSaveFileType;
+ m_OpenFileType = pOpenFileType;
+ m_OpenFileName = NULL;
+ m_bShowPerforceDialogs = ( nFlags & FOSM_SHOW_PERFORCE_DIALOGS ) != 0;
+ m_bShowSaveQuery = ( nFlags & FOSM_SHOW_SAVE_QUERY ) != 0;
+ m_bIsOpeningFile = true;
+ m_bWroteFile = false;
+
+ if ( m_bShowSaveQuery )
+ {
+ ShowSaveQuery();
+ return;
+ }
+
+ OpenFileDialog();
+}
+
+
+//-----------------------------------------------------------------------------
+// Version of OpenFile that skips browsing for a particular file to open
+//-----------------------------------------------------------------------------
+void FileOpenStateMachine::OpenFile( const char *pOpenFileName, const char *pOpenFileType, KeyValues *pContextKeyValues, const char *pSaveFileName, const char *pSaveFileType, int nFlags )
+{
+ CleanUpContextKeyValues();
+ SetCompletionState( IN_PROGRESS );
+ m_pContextKeyValues = pContextKeyValues;
+ m_FileName = pSaveFileName;
+ m_SaveFileType = pSaveFileType;
+ m_OpenFileType = pOpenFileType;
+ m_bShowPerforceDialogs = ( nFlags & FOSM_SHOW_PERFORCE_DIALOGS ) != 0;
+ m_bShowSaveQuery = ( nFlags & FOSM_SHOW_SAVE_QUERY ) != 0;
+ m_bIsOpeningFile = true;
+ m_bWroteFile = false;
+ m_OpenFileName = pOpenFileName;
+ if ( m_bShowSaveQuery )
+ {
+ ShowSaveQuery();
+ return;
+ }
+
+ OpenFileDialog();
+}
+
+