Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add save prompt and modify CodeEditor and TextEditor #239

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions src/Gemini.Demo/Modules/TextEditor/ViewModels/EditorViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,19 @@
using Gemini.Demo.Modules.TextEditor.Views;
using Gemini.Framework;
using Gemini.Framework.Threading;
using System.ComponentModel.Composition;

namespace Gemini.Demo.Modules.TextEditor.ViewModels
{
[Export(typeof(EditorViewModel))]
[PartCreationPolicy(CreationPolicy.NonShared)]
#pragma warning disable 659
public class EditorViewModel : PersistedDocument
#pragma warning restore 659
{
private EditorView _view;
private string _originalText;
private bool notYetLoaded = false;

protected override Task DoNew()
{
Expand All @@ -38,6 +42,12 @@ protected override Task DoSave(string filePath)

private void ApplyOriginalText()
{
// At StartUp, _view is null, so notYetLoaded flag is added
if (_view == null)
{
notYetLoaded = true;
return;
}
_view.textBox.Text = _originalText;

_view.textBox.TextChanged += delegate
Expand All @@ -49,6 +59,12 @@ private void ApplyOriginalText()
protected override void OnViewLoaded(object view)
{
_view = (EditorView) view;

if (notYetLoaded)
{
ApplyOriginalText();
notYetLoaded = false;
}
}

public override bool Equals(object obj)
Expand Down
1 change: 1 addition & 0 deletions src/Gemini.Demo/Modules/TextEditor/Views/EditorView.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
BorderThickness="0"
FontFamily="Consolas"
FontSize="14"
TextWrapping="Wrap"
ScrollViewer.VerticalScrollBarVisibility="Auto"
ScrollViewer.HorizontalScrollBarVisibility="Auto"/>
</UserControl>
23 changes: 11 additions & 12 deletions src/Gemini/Framework/Document.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,3 @@
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;
using Caliburn.Micro;
using Gemini.Framework.Commands;
using Gemini.Framework.Services;
Expand All @@ -14,10 +10,14 @@
using Gemini.Modules.UndoRedo.Commands;
using Gemini.Modules.UndoRedo.Services;
using Microsoft.Win32;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using System.Windows.Input;

namespace Gemini.Framework
{
public abstract class Document : LayoutItemBase, IDocument,
public abstract class Document : LayoutItemBase, IDocument,
ICommandHandler<UndoCommandDefinition>,
ICommandHandler<RedoCommandDefinition>,
ICommandHandler<SaveFileCommandDefinition>,
Expand Down Expand Up @@ -125,22 +125,21 @@ async Task ICommandHandler<SaveFileAsCommandDefinition>.Run(Command command)
}

private static async Task DoSaveAs(IPersistedDocument persistedDocument)
{
// Show user dialog to choose filename.
var dialog = new SaveFileDialog();
dialog.FileName = persistedDocument.FileName;
{
var filter = string.Empty;

var fileExtension = Path.GetExtension(persistedDocument.FileName);
var fileType = IoC.GetAll<IEditorProvider>()
.SelectMany(x => x.FileTypes)
.SingleOrDefault(x => x.FileExtension == fileExtension);
if (fileType != null)
filter = fileType.Name + "|*" + fileType.FileExtension + "|";

filter += "All Files|*.*";
dialog.Filter = filter;

// Show user dialog to choose filename.
// Note that SaveFileDialog may need Administrator right.
var dialog = new SaveFileDialog();
dialog.FileName = persistedDocument.FileName;
dialog.Filter = filter;
if (dialog.ShowDialog() != true)
return;

Expand Down
84 changes: 81 additions & 3 deletions src/Gemini/Framework/PersistedDocument.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
using Caliburn.Micro;
using Gemini.Framework.Services;
using Gemini.Properties;
using Microsoft.Win32;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Linq;
using System.Threading;

namespace Gemini.Framework
{
Expand All @@ -26,10 +32,82 @@ public bool IsDirty
}
}

// ShouldReopenOnStart, SaveState and LoadState are default methods of PersistedDocument.
public override bool ShouldReopenOnStart
{
get { return (FilePath != null); } // if FilePath is null, SaveState() will generate an NullExceptionError
}

public override void SaveState(BinaryWriter writer)
{
writer.Write(FilePath);
}

public override async void LoadState(BinaryReader reader)
{
await Load(reader.ReadString());
}

public override Task<bool> CanCloseAsync(CancellationToken cancellationToken)
{
// TODO: Show save prompt.
return Task.FromResult(!IsDirty);
if (IsDirty)
{
// Show save prompt.
// Note that CanClose method of Demo ShellViewModel blocks this.
string title = IoC.Get<IMainWindow>().Title;
string fileName = Path.GetFileNameWithoutExtension(FileName);
string fileExtension = Path.GetExtension(FileName);
var fileType = IoC.GetAll<IEditorProvider>()
.SelectMany(x => x.FileTypes)
.SingleOrDefault(x => x.FileExtension == fileExtension);

string message = string.Format(Resources.SaveChangesBeforeClosingMessage, fileType.Name, fileName);
var result = MessageBox.Show(message, title, MessageBoxButton.YesNoCancel, MessageBoxImage.Warning);

if (result == MessageBoxResult.Yes)
{
if (IsNew)
{
// Ask new file path.
var filter = string.Empty;
if (fileType != null)
filter = fileType.Name + "|*" + fileType.FileExtension + "|";
filter += Properties.Resources.AllFiles + "|*.*";

// note that SaveFileDialog may need Administrator right.
var dialog = new SaveFileDialog();
dialog.FileName = this.FileName;
dialog.Filter = filter;
if (dialog.ShowDialog() == true)
{
// Save file.
#pragma warning disable 4014
Save(dialog.FileName);
#pragma warning restore 4014
// Add to recent files. Temporally, commented out.
//IShell _shell = IoC.Get<IShell>();
//_shell.RecentFiles.Update(dialog.FileName);
}
else
{
return Task.FromResult(false);
}
}
else
{
// Save file.
#pragma warning disable 4014
Save(FilePath);
#pragma warning restore 4014
}
}
else if (result == MessageBoxResult.Cancel)
{
return Task.FromResult(false);
}
}

return Task.FromResult(true);
}

private void UpdateDisplayName()
Expand Down