@ -15,9 +15,18 @@ using ICSharpCode.SharpDevelop.Widgets.MyersDiff;
@@ -15,9 +15,18 @@ using ICSharpCode.SharpDevelop.Widgets.MyersDiff;
namespace ICSharpCode.SharpDevelop.Workbench
{
sealed class TextDocumentFileModelProvider : IFileModelProvider < TextDocument >
public sealed class TextDocumentFileModelProvider : IFileModelProvider < TextDocument >
{
public TextDocument Load ( OpenedFile file )
/// <summary>
/// Internal ctor: FileModels.TextDocument should be the only instance.
/// </summary>
internal TextDocumentFileModelProvider ( )
{
}
// use explicit interface implementations because these methods are supposed to only
// be called from the OpenedFile infrastructure
TextDocument IFileModelProvider < TextDocument > . Load ( OpenedFile file )
{
TextDocument document = file . GetModel ( this , GetModelOptions . AllowStale | GetModelOptions . DoNotLoad ) ;
var info = document ! = null ? document . GetFileModelInfo ( ) : new DocumentFileModelInfo ( ) ;
@ -30,44 +39,28 @@ namespace ICSharpCode.SharpDevelop.Workbench
@@ -30,44 +39,28 @@ namespace ICSharpCode.SharpDevelop.Workbench
}
if ( document ! = null ) {
// Reload document
var diff = new MyersDiffAlgorithm ( new StringSequence ( document . Text ) , new StringSequence ( textContent ) ) ;
info . isLoading = true ;
try {
document . Replace ( 0 , document . TextLength , textContent , ToOffsetChangeMap ( diff . GetEdits ( ) ) ) ;
document . UndoStack . ClearAll ( ) ;
info . IsStale = false ;
} finally {
info . isLoading = false ;
}
ReloadDocument ( document , new StringTextSource ( textContent ) ) ;
info . IsStale = false ;
} else {
document = new TextDocument ( textContent ) ;
document . TextChanged + = delegate { UpdateFileIsDirty ( document , file , info ) ; } ;
// Store info for the new document (necessary so that we don't forget the encoding we just used)
document . GetRequiredService < IServiceContainer > ( ) . AddService ( typeof ( DocumentFileModelInfo ) , info ) ;
}
file . IsDirtyChanged + = delegate { UpdateUndoStackIsOriginalFile ( file , document ) ; } ;
UpdateUndoStackIsOriginalFile ( file , document ) ;
return document ;
}
static void UpdateUndoStackIsOriginalFile ( ICanBeDirty file , TextDocument document )
{
if ( file . IsDirty ) {
document . UndoStack . DiscardOriginalFileMarker ( ) ;
} else {
document . UndoStack . MarkAsOriginalFile ( ) ;
}
}
void UpdateFileIsDirty ( TextDocument document , OpenedFile file , DocumentFileModelInfo info )
public void ReloadDocument ( TextDocument document , ITextSource newContent )
{
if ( ! info . isLoading ) {
// Set dirty flag on OpenedFile according to UndoStack.IsOriginalFile
if ( document . UndoStack . IsOriginalFile & & file . IsDirty ) {
// reset dirty marker
file . ReplaceModel ( this , document , ReplaceModelMode . SetAsValid ) ;
} else if ( ! document . UndoStack . IsOriginalFile ) {
file . MakeDirty ( this ) ;
}
var info = document . GetFileModelInfo ( ) ;
var diff = new MyersDiffAlgorithm ( new StringSequence ( document . Text ) , new StringSequence ( newContent . Text ) ) ;
if ( info ! = null )
info . isLoading = true ;
try {
document . Replace ( 0 , document . TextLength , newContent , ToOffsetChangeMap ( diff . GetEdits ( ) ) ) ;
document . UndoStack . ClearAll ( ) ;
} finally {
if ( info ! = null )
info . isLoading = false ;
}
}
@ -87,14 +80,14 @@ namespace ICSharpCode.SharpDevelop.Workbench
@@ -87,14 +80,14 @@ namespace ICSharpCode.SharpDevelop.Workbench
return map ;
}
public void Save ( OpenedFile file , TextDocument model , FileSaveOptions options )
void IFileModelProvider < TextDocument > . Save ( OpenedFile file , TextDocument model , FileSaveOptions options )
{
MemoryStream ms = new MemoryStream ( ) ;
SaveTo ( ms , model , options ) ;
file . ReplaceModel ( FileModels . Binary , new BinaryFileModel ( ms . ToArray ( ) ) , ReplaceModelMode . TransferDirty ) ;
}
public void SaveCopyAs ( OpenedFile file , TextDocument model , FileName outputFileName , FileSaveOptions options )
void IFileModelProvider < TextDocument > . SaveCopyAs ( OpenedFile file , TextDocument model , FileName outputFileName , FileSaveOptions options )
{
using ( Stream s = SD . FileSystem . OpenWrite ( outputFileName ) ) {
SaveTo ( s , model , options ) ;
@ -147,7 +140,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
@@ -147,7 +140,7 @@ namespace ICSharpCode.SharpDevelop.Workbench
int r = MessageService . ShowCustomDialog (
"${res:Dialog.Options.IDEOptions.TextEditor.General.FontGroupBox.FileEncodingGroupBox}" ,
StringParser . Parse ( "${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss}" ,
new StringTagPair ( "encoding" , encoding . EncodingName ) ) ,
new StringTagPair ( "encoding" , encoding . EncodingName ) ) ,
0 , - 1 ,
"${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss.UseUTF8}" ,
"${res:AvalonEdit.FileEncoding.EncodingCausesDataLoss.Continue}" ) ;
@ -159,19 +152,24 @@ namespace ICSharpCode.SharpDevelop.Workbench
@@ -159,19 +152,24 @@ namespace ICSharpCode.SharpDevelop.Workbench
return otherProvider = = FileModels . Binary | | FileModels . Binary . CanLoadFrom ( otherProvider ) ;
}
public void NotifyRename ( OpenedFile file , TextDocument model , FileName oldName , FileName newName )
void IFileModelProvider < TextDocument > . NotifyRename ( OpenedFile file , TextDocument model , FileName oldName , FileName newName )
{
model . FileName = newName ;
}
public void NotifyStale ( OpenedFile file , TextDocument model )
void IFileModelProvider < TextDocument > . NotifyStale ( OpenedFile file , TextDocument model )
{
model . GetFileModelInfo ( ) . IsStale = true ;
}
public void NotifyUnl oaded( OpenedFile file , TextDocument model )
void IFileModelProvider < TextDocument > . NotifyL oaded( OpenedFile file , TextDocument model )
{
model . GetFileModelInfo ( ) . IsStale = true ;
model . GetFileModelInfo ( ) . NotifyLoaded ( file , model ) ;
}
void IFileModelProvider < TextDocument > . NotifyUnloaded ( OpenedFile file , TextDocument model )
{
model . GetFileModelInfo ( ) . NotifyUnloaded ( ) ;
}
}
}