23 Commits
0.8 ... 0.10

Author SHA1 Message Date
Ben
37258e563a Added Divination Cards to base types 2015-07-26 17:12:51 +01:00
Ben
71e1f2bf78 Revert "Removed Stackable Currency from ItemClasses"
This reverts commit f3ed386845.
2015-07-26 17:03:12 +01:00
Ben
b2b412a73c Revert "Removed Thrusting One Hand Swords from Base Types"
This reverts commit e80295cb69.
2015-07-26 17:03:06 +01:00
Ben
ae948c83a5 Updated version number to 0.10 2015-07-26 17:02:54 +01:00
Ben
3727166a44 Added drag and drop to open script/theme functionality 2015-07-26 11:48:54 +01:00
Ben
32b0a0199f Implemented async saving and loading 2015-07-25 19:02:42 +01:00
Ben
e54730d693 Added Tooltips for keyboard shortcuts and added Ctrl+N shortcut 2015-07-25 15:46:38 +01:00
Ben
d11eefaeab Fixed crash when pasting blocks with block groups assigned 2015-07-24 18:41:13 +01:00
Ben
da5b2c73a0 Moved clipboard operations to ClipboardService 2015-07-24 16:52:31 +01:00
Ben
2ff1373c6b Merge branch 'master' of https://github.com/ben-wallis/Filtration.git 2015-07-24 14:47:52 +01:00
Ben
1882687601 Fixed BlockGroupBrowser indeterminate checkbox state bug 2015-07-24 14:47:47 +01:00
Ben Wallis
3ba25b8f07 Updated release to 0.9 2015-07-15 19:55:52 +01:00
Ben
e80295cb69 Removed Thrusting One Hand Swords from Base Types 2015-07-15 19:48:51 +01:00
Ben
f3ed386845 Removed Stackable Currency from ItemClasses 2015-07-15 19:48:33 +01:00
Ben
89e0c717e8 Bumped version to 0.9 2015-07-15 19:45:49 +01:00
Ben
8924637b98 Added hint text when no audio visual block items are added. 2015-07-15 19:41:31 +01:00
Ben
b0b912c676 Added save check on close 2015-07-15 19:36:42 +01:00
Ben
92ebc51e7b Switched file save encoding to UTF-8 2015-07-15 19:17:19 +01:00
Ben
95e7581a5b Fixed Delete Theme Component button being enabled for non-master themes 2015-07-15 19:12:19 +01:00
Ben
9cb854b584 Fixed Usages: 0 being visible when editing a non-master theme 2015-07-15 19:10:51 +01:00
Ben
61c2902f0c Merge branch 'master' of https://github.com/ben-wallis/Filtration.git 2015-07-15 19:02:34 +01:00
Ben
dc157713f3 Fixed Issue #8 - Crash when Filtration cannot perform the update check on startup 2015-07-15 19:02:29 +01:00
Ben Wallis
16fe837544 updated to 0.8 2015-07-13 15:17:53 +01:00
33 changed files with 541 additions and 205 deletions

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Text;
namespace Filtration.Common.Services namespace Filtration.Common.Services
{ {
@@ -20,7 +21,7 @@ namespace Filtration.Common.Services
public void WriteFileFromString(string filePath, string inputString) public void WriteFileFromString(string filePath, string inputString)
{ {
File.WriteAllText(filePath, inputString); File.WriteAllText(filePath, inputString, Encoding.UTF8);
} }
public bool DirectoryExists(string directoryPath) public bool DirectoryExists(string directoryPath)

View File

@@ -1,9 +1,11 @@
namespace Filtration.Interface using System.Threading.Tasks;
namespace Filtration.Interface
{ {
public interface IDocument public interface IDocument
{ {
bool IsScript { get; } bool IsScript { get; }
bool IsTheme { get; } bool IsTheme { get; }
void Close(); Task Close();
} }
} }

View File

@@ -1,9 +1,11 @@
namespace Filtration.Interface using System.Threading.Tasks;
namespace Filtration.Interface
{ {
public interface IEditableDocument : IDocument public interface IEditableDocument : IDocument
{ {
bool IsDirty { get; } bool IsDirty { get; }
void Save(); Task SaveAsync();
void SaveAs(); Task SaveAsAsync();
} }
} }

View File

@@ -18,7 +18,7 @@ namespace Filtration.Tests.Repositories
var mockPersistenceService = new Mock<IItemFilterPersistenceService>(); var mockPersistenceService = new Mock<IItemFilterPersistenceService>();
mockPersistenceService.Setup(p => p.LoadItemFilterScript(testInputPath)).Verifiable(); mockPersistenceService.Setup(p => p.LoadItemFilterScriptAsync(testInputPath)).Verifiable();
var mockItemFilterScriptViewModel = new Mock<IItemFilterScriptViewModel>(); var mockItemFilterScriptViewModel = new Mock<IItemFilterScriptViewModel>();
@@ -28,7 +28,7 @@ namespace Filtration.Tests.Repositories
var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object); var repository = new ItemFilterScriptRepository(mockPersistenceService.Object, mockItemFilterScriptViewModelFactory.Object);
// Act // Act
var result = repository.LoadScriptFromFile(testInputPath); var result = repository.LoadScriptFromFileAsync(testInputPath);
// Assert // Assert
mockPersistenceService.Verify(); mockPersistenceService.Verify();
@@ -42,7 +42,7 @@ namespace Filtration.Tests.Repositories
var testInputPath = "C:\\TestPath.filter"; var testInputPath = "C:\\TestPath.filter";
var mockPersistenceService = new Mock<IItemFilterPersistenceService>(); var mockPersistenceService = new Mock<IItemFilterPersistenceService>();
mockPersistenceService.Setup(p => p.LoadItemFilterScript(testInputPath)).Throws<IOException>(); mockPersistenceService.Setup(p => p.LoadItemFilterScriptAsync(testInputPath)).Throws<IOException>();
var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>(); var mockItemFilterScriptViewModelFactory = new Mock<IItemFilterScriptViewModelFactory>();
@@ -51,7 +51,7 @@ namespace Filtration.Tests.Repositories
// Act // Act
// Assert // Assert
Assert.Throws<IOException>(() => repository.LoadScriptFromFile(testInputPath)); Assert.Throws<IOException>(() => repository.LoadScriptFromFileAsync(testInputPath));
} }
[Test] [Test]

View File

@@ -28,7 +28,7 @@ namespace Filtration.Tests.Services
var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object); var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object);
// Act // Act
var script = service.LoadItemFilterScript(TestInputPath); var script = service.LoadItemFilterScriptAsync(TestInputPath);
// Assert // Assert
mockFileSystemService.Verify(); mockFileSystemService.Verify();
@@ -53,7 +53,7 @@ namespace Filtration.Tests.Services
var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object); var service = new ItemFilterPersistenceService(mockFileSystemService.Object, mockItemFilterScriptTranslator.Object);
// Act // Act
service.SaveItemFilterScript(testScript); service.SaveItemFilterScriptAsync(testScript);
// Assert // Assert
mockFileSystemService.Verify(); mockFileSystemService.Verify();

View File

@@ -1,6 +1,7 @@
using System.Collections.ObjectModel; using System.Collections.ObjectModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using AutoMapper; using AutoMapper;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.ObjectModel.ThemeEditor; using Filtration.ObjectModel.ThemeEditor;
@@ -13,9 +14,9 @@ namespace Filtration.ThemeEditor.Providers
{ {
IThemeEditorViewModel NewThemeForScript(ItemFilterScript script); IThemeEditorViewModel NewThemeForScript(ItemFilterScript script);
IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script); IThemeEditorViewModel MasterThemeForScript(ItemFilterScript script);
IThemeEditorViewModel LoadThemeFromFile(string filePath); Task<IThemeEditorViewModel> LoadThemeFromFile(string filePath);
Theme LoadThemeModelFromFile(string filePath); Task<Theme> LoadThemeModelFromFile(string filePath);
void SaveTheme(IThemeEditorViewModel themeEditorViewModel, string filePath); Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath);
} }
internal class ThemeProvider : IThemeProvider internal class ThemeProvider : IThemeProvider
@@ -54,23 +55,26 @@ namespace Filtration.ThemeEditor.Providers
return themeViewModel; return themeViewModel;
} }
public IThemeEditorViewModel LoadThemeFromFile(string filePath) public async Task<IThemeEditorViewModel> LoadThemeFromFile(string filePath)
{ {
var model = _themePersistenceService.LoadTheme(filePath); var model = await _themePersistenceService.LoadThemeAsync(filePath);
var viewModel = Mapper.Map<IThemeEditorViewModel>(model); var viewModel = Mapper.Map<IThemeEditorViewModel>(model);
viewModel.FilePath = filePath; viewModel.FilePath = filePath;
return viewModel; return viewModel;
} }
public Theme LoadThemeModelFromFile(string filePath) public async Task<Theme> LoadThemeModelFromFile(string filePath)
{ {
return _themePersistenceService.LoadTheme(filePath); return await _themePersistenceService.LoadThemeAsync(filePath);
} }
public void SaveTheme(IThemeEditorViewModel themeEditorViewModel, string filePath) public async Task SaveThemeAsync(IThemeEditorViewModel themeEditorViewModel, string filePath)
{ {
var theme = Mapper.Map<Theme>(themeEditorViewModel); await Task.Run(() =>
_themePersistenceService.SaveTheme(theme, filePath); {
var theme = Mapper.Map<Theme>(themeEditorViewModel);
_themePersistenceService.SaveThemeAsync(theme, filePath);
});
} }
} }
} }

View File

@@ -1,4 +1,5 @@
using System.IO; using System.IO;
using System.Threading.Tasks;
using System.Xml.Serialization; using System.Xml.Serialization;
using Filtration.ObjectModel.ThemeEditor; using Filtration.ObjectModel.ThemeEditor;
@@ -6,35 +7,42 @@ namespace Filtration.ThemeEditor.Services
{ {
internal interface IThemePersistenceService internal interface IThemePersistenceService
{ {
Theme LoadTheme(string filePath); Task<Theme> LoadThemeAsync(string filePath);
void SaveTheme(Theme theme, string filePath); Task SaveThemeAsync(Theme theme, string filePath);
} }
internal class ThemePersistenceService : IThemePersistenceService internal class ThemePersistenceService : IThemePersistenceService
{ {
public Theme LoadTheme(string filePath) public async Task<Theme> LoadThemeAsync(string filePath)
{ {
var xmlSerializer = new XmlSerializer(typeof(Theme)); Theme loadedTheme = null;
Theme loadedTheme; await Task.Run(() =>
using (Stream reader = new FileStream(filePath, FileMode.Open))
{ {
loadedTheme = (Theme)xmlSerializer.Deserialize(reader); var xmlSerializer = new XmlSerializer(typeof (Theme));
}
using (Stream reader = new FileStream(filePath, FileMode.Open))
{
loadedTheme = (Theme) xmlSerializer.Deserialize(reader);
}
loadedTheme.FilePath = filePath;
});
loadedTheme.FilePath = filePath;
return loadedTheme; return loadedTheme;
} }
public void SaveTheme(Theme theme, string filePath) public async Task SaveThemeAsync(Theme theme, string filePath)
{ {
var xmlSerializer = new XmlSerializer(typeof(Theme)); await Task.Run(() =>
using (Stream writer = new FileStream(filePath, FileMode.Create))
{ {
xmlSerializer.Serialize(writer, theme); var xmlSerializer = new XmlSerializer(typeof (Theme));
}
using (Stream writer = new FileStream(filePath, FileMode.Create))
{
xmlSerializer.Serialize(writer, theme);
}
});
} }
} }
} }

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Media; using System.Windows.Media;
@@ -55,7 +56,7 @@ namespace Filtration.ThemeEditor.ViewModels
AddThemeComponentCommand = new RelayCommand<ThemeComponentType>(OnAddThemeComponentCommand, t => IsMasterTheme); AddThemeComponentCommand = new RelayCommand<ThemeComponentType>(OnAddThemeComponentCommand, t => IsMasterTheme);
DeleteThemeComponentCommand = new RelayCommand<ThemeComponent>(OnDeleteThemeComponentCommand, DeleteThemeComponentCommand = new RelayCommand<ThemeComponent>(OnDeleteThemeComponentCommand,
t => IsMasterTheme && SelectedThemeComponent != null); t => IsMasterTheme && SelectedThemeComponent != null);
CloseCommand = new RelayCommand(OnCloseCommand); CloseCommand = new RelayCommand(async () => await OnCloseCommand());
var icon = new BitmapImage(); var icon = new BitmapImage();
icon.BeginInit(); icon.BeginInit();
@@ -123,19 +124,19 @@ namespace Filtration.ThemeEditor.ViewModels
} }
} }
public void Save() public async Task SaveAsync()
{ {
if (IsMasterTheme) return; if (IsMasterTheme) return;
if (_filenameIsFake) if (_filenameIsFake)
{ {
SaveAs(); await SaveAsAsync();
return; return;
} }
try try
{ {
_themeProvider.SaveTheme(this, FilePath); await _themeProvider.SaveThemeAsync(this, FilePath);
//RemoveDirtyFlag(); //RemoveDirtyFlag();
} }
catch (Exception e) catch (Exception e)
@@ -149,7 +150,7 @@ namespace Filtration.ThemeEditor.ViewModels
} }
} }
public void SaveAs() public async Task SaveAsAsync()
{ {
if (IsMasterTheme) return; if (IsMasterTheme) return;
@@ -167,7 +168,7 @@ namespace Filtration.ThemeEditor.ViewModels
try try
{ {
FilePath = saveDialog.FileName; FilePath = saveDialog.FileName;
_themeProvider.SaveTheme(this, FilePath); await _themeProvider.SaveThemeAsync(this, FilePath);
_filenameIsFake = false; _filenameIsFake = false;
Title = Filename; Title = Filename;
//RemoveDirtyFlag(); //RemoveDirtyFlag();
@@ -185,14 +186,16 @@ namespace Filtration.ThemeEditor.ViewModels
} }
} }
public void OnCloseCommand() public async Task OnCloseCommand()
{ {
Close(); await Close();
} }
public void Close() #pragma warning disable 1998
public async Task Close()
#pragma warning restore 1998
{ {
Messenger.Default.Send(new ThemeClosedMessage { ClosedViewModel = this }); Messenger.Default.Send(new ThemeClosedMessage {ClosedViewModel = this});
} }
private void OnAddThemeComponentCommand(ThemeComponentType themeComponentType) private void OnAddThemeComponentCommand(ThemeComponentType themeComponentType)

View File

@@ -21,30 +21,29 @@
</Grid.RowDefinitions> </Grid.RowDefinitions>
<Grid.Resources> <Grid.Resources>
<DataTemplate x:Key="EditableComponentNameTemplate"> <DataTemplate x:Key="EditableComponentNameTemplate">
<TextBox Text="{Binding ComponentName}" /> <StackPanel>
<TextBlock Text="{Binding UsageCount, StringFormat='Usages: {0}'}"
FontSize="10"
HorizontalAlignment="Right"
Visibility="{Binding Path=DataContext.EditEnabled, RelativeSource={RelativeSource AncestorType={x:Type views:ThemeEditorView}}, Converter={StaticResource BooleanVisibilityConverter}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding UsageCount}" Value="0">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
<Setter Property="Foreground" Value="SteelBlue" />
</Style>
</TextBlock.Style>
</TextBlock>
<TextBox Text="{Binding ComponentName}" />
</StackPanel>
</DataTemplate> </DataTemplate>
<DataTemplate x:Key="ViewOnlyComponentNameTemplate"> <DataTemplate x:Key="ViewOnlyComponentNameTemplate">
<TextBlock Text="{Binding ComponentName}" ToolTip="{Binding ComponentName}" /> <TextBlock Text="{Binding ComponentName}" ToolTip="{Binding ComponentName}" />
</DataTemplate> </DataTemplate>
</Grid.Resources> </Grid.Resources>
<DockPanel LastChildFill="True">
<TextBlock DockPanel.Dock="Left"
Text="{Binding UsageCount, StringFormat='Usages: {0}'}"
FontSize="10"
HorizontalAlignment="Right"
Visibility="{Binding Path=DataContext.EditEnabled, RelativeSource={RelativeSource AncestorType={x:Type views:ThemeEditorView}}, Converter={StaticResource BooleanVisibilityConverter}}">
<TextBlock.Style>
<Style TargetType="TextBlock">
<Style.Triggers>
<DataTrigger Binding="{Binding UsageCount}" Value="0">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
</Style.Triggers>
<Setter Property="Foreground" Value="SteelBlue" />
</Style>
</TextBlock.Style>
</TextBlock>
</DockPanel>
<ContentControl Grid.Row="1" Content="{Binding}"> <ContentControl Grid.Row="1" Content="{Binding}">
<ContentControl.Style> <ContentControl.Style>
<Style TargetType="ContentControl"> <Style TargetType="ContentControl">
@@ -59,7 +58,6 @@
</Style> </Style>
</ContentControl.Style> </ContentControl.Style>
</ContentControl> </ContentControl>
<xctk:ColorPicker Grid.Row="2" SelectedColor="{Binding Color}" /> <xctk:ColorPicker Grid.Row="2" SelectedColor="{Binding Color}" />
</Grid> </Grid>
</UserControl> </UserControl>

View File

@@ -94,6 +94,10 @@
<Reference Include="WindowsBase" /> <Reference Include="WindowsBase" />
<Reference Include="PresentationCore" /> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" /> <Reference Include="PresentationFramework" />
<Reference Include="WpfAnimatedGif, Version=1.4.13.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\WpfAnimatedGif.1.4.13\lib\net\WpfAnimatedGif.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="WPFToolkit, Version=3.5.40128.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL"> <Reference Include="WPFToolkit, Version=3.5.40128.1, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion> <SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\WPFToolkit.3.5.50211.1\lib\WPFToolkit.dll</HintPath> <HintPath>..\packages\WPFToolkit.3.5.50211.1\lib\WPFToolkit.dll</HintPath>
@@ -145,6 +149,7 @@
<Compile Include="Models\UpdateData.cs" /> <Compile Include="Models\UpdateData.cs" />
<Compile Include="Properties\Annotations.cs" /> <Compile Include="Properties\Annotations.cs" />
<Compile Include="Repositories\ItemFilterScriptRepository.cs" /> <Compile Include="Repositories\ItemFilterScriptRepository.cs" />
<Compile Include="Services\ClipboardService.cs" />
<Compile Include="Services\HTTPService.cs" /> <Compile Include="Services\HTTPService.cs" />
<Compile Include="Services\ItemFilterPersistenceService.cs" /> <Compile Include="Services\ItemFilterPersistenceService.cs" />
<Compile Include="Services\StaticDataService.cs" /> <Compile Include="Services\StaticDataService.cs" />
@@ -243,7 +248,6 @@
<Compile Include="Views\UpdateAvailableView.xaml.cs"> <Compile Include="Views\UpdateAvailableView.xaml.cs">
<DependentUpon>UpdateAvailableView.xaml</DependentUpon> <DependentUpon>UpdateAvailableView.xaml</DependentUpon>
</Compile> </Compile>
<Compile Include="WindsorInstallers\ModelsInstaller.cs" />
<Compile Include="WindsorInstallers\RepositoriesInstaller.cs" /> <Compile Include="WindsorInstallers\RepositoriesInstaller.cs" />
<Compile Include="WindsorInstallers\ServicesInstaller.cs" /> <Compile Include="WindsorInstallers\ServicesInstaller.cs" />
<Compile Include="WindsorInstallers\TranslatorsInstaller.cs" /> <Compile Include="WindsorInstallers\TranslatorsInstaller.cs" />
@@ -365,6 +369,7 @@
<DependentUpon>Settings.settings</DependentUpon> <DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput> <DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile> </Compile>
<Resource Include="Resources\loading_spinner.gif" />
<EmbeddedResource Include="Properties\Resources.resx"> <EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator> <Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput> <LastGenOutput>Resources.Designer.cs</LastGenOutput>

View File

@@ -7,7 +7,7 @@ using System.Windows;
// set of attributes. Change these attribute values to modify the information // set of attributes. Change these attribute values to modify the information
// associated with an assembly. // associated with an assembly.
[assembly: AssemblyTitle("Filtration")] [assembly: AssemblyTitle("Filtration")]
[assembly: AssemblyDescription("An item filter script manager for Path of Exile")] [assembly: AssemblyDescription("An item filter script editor for Path of Exile")]
[assembly: AssemblyConfiguration("")] [assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("XVar Industries Inc.")] [assembly: AssemblyCompany("XVar Industries Inc.")]
[assembly: AssemblyProduct("Filtration")] [assembly: AssemblyProduct("Filtration")]
@@ -50,7 +50,7 @@ using System.Windows;
// You can specify all the values or you can default the Build and Revision Numbers // You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below: // by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")] // [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("0.8.*")] [assembly: AssemblyVersion("0.10.*")]
[assembly: InternalsVisibleTo("Filtration.Tests")] [assembly: InternalsVisibleTo("Filtration.Tests")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")]

View File

@@ -1,4 +1,5 @@
using Filtration.ObjectModel; using System.Threading.Tasks;
using Filtration.ObjectModel;
using Filtration.Services; using Filtration.Services;
using Filtration.ViewModels; using Filtration.ViewModels;
@@ -6,7 +7,7 @@ namespace Filtration.Repositories
{ {
internal interface IItemFilterScriptRepository internal interface IItemFilterScriptRepository
{ {
IItemFilterScriptViewModel LoadScriptFromFile(string path); Task<IItemFilterScriptViewModel> LoadScriptFromFileAsync(string path);
IItemFilterScriptViewModel NewScript(); IItemFilterScriptViewModel NewScript();
string GetItemFilterScriptDirectory(); string GetItemFilterScriptDirectory();
void SetItemFilterScriptDirectory(string path); void SetItemFilterScriptDirectory(string path);
@@ -24,9 +25,9 @@ namespace Filtration.Repositories
_itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory; _itemFilterScriptViewModelFactory = itemFilterScriptViewModelFactory;
} }
public IItemFilterScriptViewModel LoadScriptFromFile(string path) public async Task<IItemFilterScriptViewModel> LoadScriptFromFileAsync(string path)
{ {
var loadedScript = _itemFilterPersistenceService.LoadItemFilterScript(path); var loadedScript = await _itemFilterPersistenceService.LoadItemFilterScriptAsync(path);
var newViewModel = _itemFilterScriptViewModelFactory.Create(); var newViewModel = _itemFilterScriptViewModelFactory.Create();
newViewModel.Initialise(loadedScript, false); newViewModel.Initialise(loadedScript, false);

View File

@@ -1069,31 +1069,54 @@ Sage Wand
Serpent Wand Serpent Wand
Spiraled Wand Spiraled Wand
Tornado Wand Tornado Wand
Emperor's Luck Abandoned Wealth
The Avenger The Avenger
The Brittle Emperor
Hope
The Battle Born The Battle Born
Birth of the Three
The Brittle Emperor
The Carrion Crow The Carrion Crow
The Cataclysm The Cataclysm
The Celestial Justicar
The Chains that Bind
Chaotic Disposition
Coveted Possession
The Dark Mage The Dark Mage
The Doctor
The Drunken Aristocrat The Drunken Aristocrat
Emperor's Luck
The Explorer
The Feast
The Fiend
The Gambler
The Gemcutter
Gemcutter's Promise
The Gladiator The Gladiator
The Hermit
The Hoarder The Hoarder
Hope
The Hunger The Hunger
Humility
The Incantation
The Inventor
Jack in the Box
The King's Heart
Lantador's Lost Love
The Lover
Lucky Connections
The Metalsmith's Gift The Metalsmith's Gift
The Pact
The Poet The Poet
The Queen
Rain of Chaos
The Road to Power The Road to Power
The Scarred Meadow
The Scholar The Scholar
The Summoner The Summoner
Vinia's Token
Three Faces in the Dark
The Hermit
Lantador's Lost Love
Birth of the Three
The Lover
Chaotic Disposition
Eternal Sword
The Sun The Sun
The Gemcutter Three Faces in the Dark
Time-Lost Relic
The Union
Vinia's Token
The Warden The Warden
The Watcher
The Wind

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB

View File

@@ -0,0 +1,43 @@
using System;
using System.Threading;
using System.Windows;
using NLog;
namespace Filtration.Services
{
internal interface IClipboardService
{
void SetClipboardText(string inputText);
string GetClipboardText();
}
internal class ClipboardService : IClipboardService
{
private static readonly Logger _logger = LogManager.GetCurrentClassLogger();
public void SetClipboardText(string inputText)
{
for (var i = 0; i < 10; i++)
{
try
{
Clipboard.SetText(inputText);
return;
}
catch (Exception e)
{
_logger.Error(e);
}
Thread.Sleep(10);
}
throw new Exception("Failed to copy to clipboard");
}
public string GetClipboardText()
{
return Clipboard.GetText();
}
}
}

View File

@@ -1,4 +1,5 @@
using System.IO; using System.IO;
using System.Threading.Tasks;
using Filtration.Common.Services; using Filtration.Common.Services;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.Properties; using Filtration.Properties;
@@ -10,8 +11,8 @@ namespace Filtration.Services
{ {
void SetItemFilterScriptDirectory(string path); void SetItemFilterScriptDirectory(string path);
string ItemFilterScriptDirectory { get; } string ItemFilterScriptDirectory { get; }
ItemFilterScript LoadItemFilterScript(string filePath); Task<ItemFilterScript> LoadItemFilterScriptAsync(string filePath);
void SaveItemFilterScript(ItemFilterScript script); Task SaveItemFilterScriptAsync(ItemFilterScript script);
string DefaultPathOfExileDirectory(); string DefaultPathOfExileDirectory();
} }
@@ -58,20 +59,30 @@ namespace Filtration.Services
Settings.Default.DefaultFilterDirectory = path; Settings.Default.DefaultFilterDirectory = path;
} }
public ItemFilterScript LoadItemFilterScript(string filePath) public async Task<ItemFilterScript> LoadItemFilterScriptAsync(string filePath)
{ {
var script = ItemFilterScript loadedScript = null;
_itemFilterScriptTranslator.TranslateStringToItemFilterScript( await Task.Run(() =>
{
loadedScript = _itemFilterScriptTranslator.TranslateStringToItemFilterScript(
_fileSystemService.ReadFileAsString(filePath)); _fileSystemService.ReadFileAsString(filePath));
});
script.FilePath = filePath; if (loadedScript != null)
return script; {
loadedScript.FilePath = filePath;
}
return loadedScript;
} }
public void SaveItemFilterScript(ItemFilterScript script) public async Task SaveItemFilterScriptAsync(ItemFilterScript script)
{ {
_fileSystemService.WriteFileFromString(script.FilePath, await Task.Run(() =>
_itemFilterScriptTranslator.TranslateItemFilterScriptToString(script)); {
_fileSystemService.WriteFileFromString(script.FilePath,
_itemFilterScriptTranslator.TranslateItemFilterScriptToString(script));
});
} }
} }
} }

View File

@@ -7,7 +7,7 @@ namespace Filtration.Services
{ {
internal interface IUpdateCheckService internal interface IUpdateCheckService
{ {
Task<UpdateData> GetUpdateData(); Task<UpdateData> GetUpdateDataAsync();
} }
internal class UpdateCheckService : IUpdateCheckService internal class UpdateCheckService : IUpdateCheckService
@@ -20,7 +20,7 @@ namespace Filtration.Services
_httpService = httpService; _httpService = httpService;
} }
public async Task<UpdateData> GetUpdateData() public async Task<UpdateData> GetUpdateDataAsync()
{ {
var updateXml = await _httpService.GetContentAsync(UpdateDataUrl); var updateXml = await _httpService.GetContentAsync(UpdateDataUrl);
return (DeserializeUpdateData(updateXml)); return (DeserializeUpdateData(updateXml));

View File

@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Text.RegularExpressions; using System.Text.RegularExpressions;
using System.Windows.Documents;
using Castle.Core.Internal; using Castle.Core.Internal;
using Filtration.ObjectModel; using Filtration.ObjectModel;
using Filtration.Properties; using Filtration.Properties;

View File

@@ -17,7 +17,8 @@ namespace Filtration.Utilities
if (viewModel.ChildGroups.All(g => g.IsChecked == true)) if (viewModel.ChildGroups.All(g => g.IsChecked == true))
{ {
viewModel.IsChecked = true; viewModel.IsChecked = true;
} else if (viewModel.ChildGroups.Any(g => g.IsChecked == true)) }
else if (viewModel.ChildGroups.Any(g => g.IsChecked == true || g.IsChecked == null))
{ {
viewModel.IsChecked = null; viewModel.IsChecked = null;
} }

View File

@@ -39,9 +39,9 @@ namespace Filtration.ViewModels
private readonly ReadOnlyObservableCollection<IDocument> _readOnlyOpenDocuments; private readonly ReadOnlyObservableCollection<IDocument> _readOnlyOpenDocuments;
public AvalonDockWorkspaceViewModel(ISectionBrowserViewModel sectionBrowserViewModel, public AvalonDockWorkspaceViewModel(ISectionBrowserViewModel sectionBrowserViewModel,
IBlockGroupBrowserViewModel blockGroupBrowserViewModel, IBlockGroupBrowserViewModel blockGroupBrowserViewModel,
IStartPageViewModel startPageViewModel, IStartPageViewModel startPageViewModel,
IBlockOutputPreviewViewModel blockOutputPreviewViewModel) IBlockOutputPreviewViewModel blockOutputPreviewViewModel)
{ {
_sectionBrowserViewModel = sectionBrowserViewModel; _sectionBrowserViewModel = sectionBrowserViewModel;
_blockGroupBrowserViewModel = blockGroupBrowserViewModel; _blockGroupBrowserViewModel = blockGroupBrowserViewModel;
@@ -123,7 +123,6 @@ namespace Filtration.ViewModels
private List<IToolViewModel> _tools; private List<IToolViewModel> _tools;
public IEnumerable<IToolViewModel> Tools public IEnumerable<IToolViewModel> Tools
{ {
get get

View File

@@ -317,6 +317,12 @@ namespace Filtration.ViewModels
get { return Block.HasBlockItemOfType<SoundBlockItem>(); } get { return Block.HasBlockItemOfType<SoundBlockItem>(); }
} }
public bool HasAudioVisualBlockItems
{
get { return AudioVisualBlockItems.Any(); }
}
private void OnSwitchBlockItemsViewCommand() private void OnSwitchBlockItemsViewCommand()
{ {
AudioVisualBlockItemsGridVisible = !AudioVisualBlockItemsGridVisible; AudioVisualBlockItemsGridVisible = !AudioVisualBlockItemsGridVisible;
@@ -459,6 +465,7 @@ namespace Filtration.ViewModels
RaisePropertyChanged("RegularBlockItems"); RaisePropertyChanged("RegularBlockItems");
RaisePropertyChanged("SummaryBlockItems"); RaisePropertyChanged("SummaryBlockItems");
RaisePropertyChanged("AudioVisualBlockItems"); RaisePropertyChanged("AudioVisualBlockItems");
RaisePropertyChanged("HasAudioVisualBlockItems");
} }
} }
} }

View File

@@ -4,11 +4,11 @@ using System.Collections.ObjectModel;
using System.ComponentModel; using System.ComponentModel;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Data; using System.Windows.Data;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Castle.Core.Internal;
using Filtration.Common.Services; using Filtration.Common.Services;
using Filtration.Common.ViewModels; using Filtration.Common.ViewModels;
using Filtration.Interface; using Filtration.Interface;
@@ -19,7 +19,6 @@ using Filtration.Translators;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging; using GalaSoft.MvvmLight.Messaging;
using NLog; using NLog;
using Clipboard = System.Windows.Clipboard;
namespace Filtration.ViewModels namespace Filtration.ViewModels
{ {
@@ -76,6 +75,8 @@ namespace Filtration.ViewModels
private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel; private readonly IAvalonDockWorkspaceViewModel _avalonDockWorkspaceViewModel;
private readonly IItemFilterPersistenceService _persistenceService; private readonly IItemFilterPersistenceService _persistenceService;
private readonly IMessageBoxService _messageBoxService; private readonly IMessageBoxService _messageBoxService;
private readonly IClipboardService _clipboardService;
private readonly IBlockGroupHierarchyBuilder _blockGroupHierarchyBuilder;
private bool _isDirty; private bool _isDirty;
private IItemFilterBlockViewModel _selectedBlockViewModel; private IItemFilterBlockViewModel _selectedBlockViewModel;
@@ -88,7 +89,9 @@ namespace Filtration.ViewModels
IItemFilterBlockTranslator blockTranslator, IItemFilterBlockTranslator blockTranslator,
IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel, IAvalonDockWorkspaceViewModel avalonDockWorkspaceViewModel,
IItemFilterPersistenceService persistenceService, IItemFilterPersistenceService persistenceService,
IMessageBoxService messageBoxService) IMessageBoxService messageBoxService,
IClipboardService clipboardService,
IBlockGroupHierarchyBuilder blockGroupHierarchyBuilder)
{ {
_itemFilterBlockViewModelFactory = itemFilterBlockViewModelFactory; _itemFilterBlockViewModelFactory = itemFilterBlockViewModelFactory;
_blockTranslator = blockTranslator; _blockTranslator = blockTranslator;
@@ -96,11 +99,13 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged; _avalonDockWorkspaceViewModel.ActiveDocumentChanged += OnActiveDocumentChanged;
_persistenceService = persistenceService; _persistenceService = persistenceService;
_messageBoxService = messageBoxService; _messageBoxService = messageBoxService;
_clipboardService = clipboardService;
_blockGroupHierarchyBuilder = blockGroupHierarchyBuilder;
_itemFilterBlockViewModels = new ObservableCollection<IItemFilterBlockViewModel>(); _itemFilterBlockViewModels = new ObservableCollection<IItemFilterBlockViewModel>();
ToggleShowAdvancedCommand = new RelayCommand<bool>(OnToggleShowAdvancedCommand); ToggleShowAdvancedCommand = new RelayCommand<bool>(OnToggleShowAdvancedCommand);
ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null); ClearFilterCommand = new RelayCommand(OnClearFilterCommand, () => BlockFilterPredicate != null);
CloseCommand = new RelayCommand(OnCloseCommand); CloseCommand = new RelayCommand(async () => await OnCloseCommand());
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null); DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => SelectedBlockViewModel != null);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null); MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => SelectedBlockViewModel != null);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null); MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => SelectedBlockViewModel != null);
@@ -347,20 +352,21 @@ namespace Filtration.ViewModels
ContentId = "ScriptContentId"; ContentId = "ScriptContentId";
} }
public void Save() public async Task SaveAsync()
{ {
if (!ValidateScript()) return; if (!ValidateScript()) return;
if (!CheckForUnusedThemeComponents()) return; if (!CheckForUnusedThemeComponents()) return;
if (_filenameIsFake) if (_filenameIsFake)
{ {
SaveAs(); await SaveAsAsync();
return; return;
} }
Messenger.Default.Send(new NotificationMessage("ShowLoadingBanner"));
try try
{ {
_persistenceService.SaveItemFilterScript(Script); await _persistenceService.SaveItemFilterScriptAsync(Script);
RemoveDirtyFlag(); RemoveDirtyFlag();
} }
catch (Exception e) catch (Exception e)
@@ -373,9 +379,15 @@ namespace Filtration.ViewModels
_messageBoxService.Show("Save Error", "Error saving filter file - " + e.Message, MessageBoxButton.OK, _messageBoxService.Show("Save Error", "Error saving filter file - " + e.Message, MessageBoxButton.OK,
MessageBoxImage.Error); MessageBoxImage.Error);
} }
finally
{
Messenger.Default.Send(new NotificationMessage("HideLoadingBanner"));
}
return;
} }
public void SaveAs() public async Task SaveAsAsync()
{ {
if (!ValidateScript()) return; if (!ValidateScript()) return;
if (!CheckForUnusedThemeComponents()) return; if (!CheckForUnusedThemeComponents()) return;
@@ -391,11 +403,13 @@ namespace Filtration.ViewModels
if (result != DialogResult.OK) return; if (result != DialogResult.OK) return;
Messenger.Default.Send(new NotificationMessage("ShowLoadingBanner"));
var previousFilePath = Script.FilePath; var previousFilePath = Script.FilePath;
try try
{ {
Script.FilePath = saveDialog.FileName; Script.FilePath = saveDialog.FileName;
_persistenceService.SaveItemFilterScript(Script); await _persistenceService.SaveItemFilterScriptAsync(Script);
_filenameIsFake = false; _filenameIsFake = false;
Title = Filename; Title = Filename;
RemoveDirtyFlag(); RemoveDirtyFlag();
@@ -411,6 +425,10 @@ namespace Filtration.ViewModels
MessageBoxImage.Error); MessageBoxImage.Error);
Script.FilePath = previousFilePath; Script.FilePath = previousFilePath;
} }
finally
{
Messenger.Default.Send(new NotificationMessage("HideLoadingBanner"));
}
} }
private bool CheckForUnusedThemeComponents() private bool CheckForUnusedThemeComponents()
@@ -476,12 +494,12 @@ namespace Filtration.ViewModels
return false; return false;
} }
private void OnCloseCommand() private async Task OnCloseCommand()
{ {
Close(); await Close();
} }
public void Close() public async Task Close()
{ {
if (!IsDirty) if (!IsDirty)
{ {
@@ -490,25 +508,25 @@ namespace Filtration.ViewModels
else else
{ {
var result = _messageBoxService.Show("Filtration", var result = _messageBoxService.Show("Filtration",
"Want to save your changes to this script?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question); "Save script \"" + Filename + "\"?", MessageBoxButton.YesNoCancel, MessageBoxImage.Question);
switch (result) switch (result)
{ {
case MessageBoxResult.Yes: case MessageBoxResult.Yes:
{ {
Save(); await SaveAsync();
CloseScript(); CloseScript();
break; break;
} }
case MessageBoxResult.No: case MessageBoxResult.No:
{ {
CloseScript(); CloseScript();
break; break;
} }
case MessageBoxResult.Cancel: case MessageBoxResult.Cancel:
{ {
return; return;
} }
} }
} }
} }
@@ -544,7 +562,16 @@ namespace Filtration.ViewModels
public void CopyBlock(IItemFilterBlockViewModel targetBlockViewModel) public void CopyBlock(IItemFilterBlockViewModel targetBlockViewModel)
{ {
Clipboard.SetText(_blockTranslator.TranslateItemFilterBlockToString(SelectedBlockViewModel.Block)); try
{
_clipboardService.SetClipboardText(
_blockTranslator.TranslateItemFilterBlockToString(SelectedBlockViewModel.Block));
}
catch
{
_messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.",
MessageBoxButton.OK, MessageBoxImage.Error);
}
} }
private void OnCopyBlockStyleCommand() private void OnCopyBlockStyleCommand()
@@ -564,8 +591,15 @@ namespace Filtration.ViewModels
} }
outputText += blockItem.OutputText; outputText += blockItem.OutputText;
} }
try
Clipboard.SetText(outputText); {
_clipboardService.SetClipboardText(outputText);
}
catch
{
_messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.",
MessageBoxButton.OK, MessageBoxImage.Error);
}
} }
private void OnPasteBlockStyleCommand() private void OnPasteBlockStyleCommand()
@@ -575,7 +609,7 @@ namespace Filtration.ViewModels
public void PasteBlockStyle(IItemFilterBlockViewModel targetBlockViewModel) public void PasteBlockStyle(IItemFilterBlockViewModel targetBlockViewModel)
{ {
var clipboardText = Clipboard.GetText(); var clipboardText = _clipboardService.GetClipboardText();
if (string.IsNullOrEmpty(clipboardText)) if (string.IsNullOrEmpty(clipboardText))
{ {
return; return;
@@ -594,8 +628,9 @@ namespace Filtration.ViewModels
{ {
try try
{ {
var clipboardText = Clipboard.GetText(); var clipboardText = _clipboardService.GetClipboardText();
if (clipboardText.IsNullOrEmpty()) return; if (string.IsNullOrEmpty(clipboardText)) return;
_blockGroupHierarchyBuilder.Initialise(Script.ItemFilterBlockGroups.First());
var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script.ThemeComponents); var translatedBlock = _blockTranslator.TranslateStringToItemFilterBlock(clipboardText, Script.ThemeComponents);
if (translatedBlock == null) return; if (translatedBlock == null) return;
@@ -621,9 +656,12 @@ namespace Filtration.ViewModels
catch (Exception e) catch (Exception e)
{ {
_logger.Error(e); _logger.Error(e);
var innerException = e.InnerException != null
? e.InnerException.Message
: string.Empty;
_messageBoxService.Show("Paste Error", _messageBoxService.Show("Paste Error",
e.Message + Environment.NewLine + e.StackTrace + Environment.NewLine + e.Message + Environment.NewLine + innerException, MessageBoxButton.OK,
e.InnerException.Message + Environment.NewLine + e.InnerException.StackTrace, MessageBoxButton.OK,
MessageBoxImage.Error); MessageBoxImage.Error);
} }
} }
@@ -753,6 +791,7 @@ namespace Filtration.ViewModels
IsDirty = true; IsDirty = true;
SelectedBlockViewModel = vm; SelectedBlockViewModel = vm;
RaisePropertyChanged("ItemFilterSectionViewModels"); RaisePropertyChanged("ItemFilterSectionViewModels");
Messenger.Default.Send(new NotificationMessage("SectionsChanged"));
} }
private void OnExpandAllBlocksCommand() private void OnExpandAllBlocksCommand()
@@ -784,9 +823,17 @@ namespace Filtration.ViewModels
if (result == MessageBoxResult.Yes) if (result == MessageBoxResult.Yes)
{ {
var isSection = targetBlockViewModel.Block is ItemFilterSection;
Script.ItemFilterBlocks.Remove(targetBlockViewModel.Block); Script.ItemFilterBlocks.Remove(targetBlockViewModel.Block);
ItemFilterBlockViewModels.Remove(targetBlockViewModel); ItemFilterBlockViewModels.Remove(targetBlockViewModel);
IsDirty = true; IsDirty = true;
if (isSection)
{
Messenger.Default.Send(new NotificationMessage("SectionsChanged"));
}
} }
SelectedBlockViewModel = null; SelectedBlockViewModel = null;
} }

View File

@@ -1,9 +1,13 @@
using System; using System;
using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.IO; using System.IO;
using System.Linq;
using System.Reflection; using System.Reflection;
using System.Threading.Tasks;
using System.Windows; using System.Windows;
using System.Windows.Forms; using System.Windows.Forms;
using System.Windows.Forms.VisualStyles;
using System.Windows.Media; using System.Windows.Media;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using Filtration.Common.Services; using Filtration.Common.Services;
@@ -24,7 +28,6 @@ using Filtration.Views;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging; using GalaSoft.MvvmLight.Messaging;
using NLog; using NLog;
using Clipboard = System.Windows.Clipboard;
using OpenFileDialog = Microsoft.Win32.OpenFileDialog; using OpenFileDialog = Microsoft.Win32.OpenFileDialog;
namespace Filtration.ViewModels namespace Filtration.ViewModels
@@ -33,6 +36,8 @@ namespace Filtration.ViewModels
{ {
RelayCommand OpenScriptCommand { get; } RelayCommand OpenScriptCommand { get; }
RelayCommand NewScriptCommand { get; } RelayCommand NewScriptCommand { get; }
Task<bool> CloseAllDocumentsAsync();
Task OpenDroppedFilesAsync(List<string> filenames);
} }
internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel internal class MainWindowViewModel : FiltrationViewModelBase, IMainWindowViewModel
@@ -49,6 +54,8 @@ namespace Filtration.ViewModels
private readonly IUpdateCheckService _updateCheckService; private readonly IUpdateCheckService _updateCheckService;
private readonly IUpdateAvailableViewModel _updateAvailableViewModel; private readonly IUpdateAvailableViewModel _updateAvailableViewModel;
private readonly IMessageBoxService _messageBoxService; private readonly IMessageBoxService _messageBoxService;
private readonly IClipboardService _clipboardService;
private bool _showLoadingBanner;
public MainWindowViewModel(IItemFilterScriptRepository itemFilterScriptRepository, public MainWindowViewModel(IItemFilterScriptRepository itemFilterScriptRepository,
IItemFilterScriptTranslator itemFilterScriptTranslator, IItemFilterScriptTranslator itemFilterScriptTranslator,
@@ -59,7 +66,8 @@ namespace Filtration.ViewModels
IThemeService themeService, IThemeService themeService,
IUpdateCheckService updateCheckService, IUpdateCheckService updateCheckService,
IUpdateAvailableViewModel updateAvailableViewModel, IUpdateAvailableViewModel updateAvailableViewModel,
IMessageBoxService messageBoxService) IMessageBoxService messageBoxService,
IClipboardService clipboardService)
{ {
_itemFilterScriptRepository = itemFilterScriptRepository; _itemFilterScriptRepository = itemFilterScriptRepository;
_itemFilterScriptTranslator = itemFilterScriptTranslator; _itemFilterScriptTranslator = itemFilterScriptTranslator;
@@ -71,14 +79,15 @@ namespace Filtration.ViewModels
_updateCheckService = updateCheckService; _updateCheckService = updateCheckService;
_updateAvailableViewModel = updateAvailableViewModel; _updateAvailableViewModel = updateAvailableViewModel;
_messageBoxService = messageBoxService; _messageBoxService = messageBoxService;
_clipboardService = clipboardService;
NewScriptCommand = new RelayCommand(OnNewScriptCommand); NewScriptCommand = new RelayCommand(OnNewScriptCommand);
CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, () => ActiveDocumentIsScript); CopyScriptCommand = new RelayCommand(OnCopyScriptCommand, () => ActiveDocumentIsScript);
OpenScriptCommand = new RelayCommand(OnOpenScriptCommand); OpenScriptCommand = new RelayCommand(async () => await OnOpenScriptCommand());
OpenThemeCommand = new RelayCommand(OnOpenThemeCommand); OpenThemeCommand = new RelayCommand(async () => await OnOpenThemeCommandAsync());
SaveCommand = new RelayCommand(OnSaveDocumentCommand, ActiveDocumentIsEditable); SaveCommand = new RelayCommand(async () => await OnSaveDocumentCommandAsync(), ActiveDocumentIsEditable);
SaveAsCommand = new RelayCommand(OnSaveAsCommand, ActiveDocumentIsEditable); SaveAsCommand = new RelayCommand(async () => await OnSaveAsCommandAsync(), ActiveDocumentIsEditable);
CloseCommand = new RelayCommand(OnCloseDocumentCommand, ActiveDocumentIsEditable); CloseCommand = new RelayCommand(OnCloseDocumentCommand, ActiveDocumentIsEditable);
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock); CopyBlockCommand = new RelayCommand(OnCopyBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
@@ -102,7 +111,7 @@ namespace Filtration.ViewModels
ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => ActiveDocumentIsScript); ReplaceColorsCommand = new RelayCommand(OnReplaceColorsCommand, () => ActiveDocumentIsScript);
CreateThemeCommand = new RelayCommand(OnCreateThemeCommand, () => ActiveDocumentIsScript); CreateThemeCommand = new RelayCommand(OnCreateThemeCommand, () => ActiveDocumentIsScript);
ApplyThemeToScriptCommand = new RelayCommand(OnApplyThemeToScriptCommand, () => ActiveDocumentIsScript); ApplyThemeToScriptCommand = new RelayCommand(async () => await OnApplyThemeToScriptCommandAsync(), () => ActiveDocumentIsScript);
EditMasterThemeCommand = new RelayCommand(OnEditMasterThemeCommand, () => ActiveDocumentIsScript); EditMasterThemeCommand = new RelayCommand(OnEditMasterThemeCommand, () => ActiveDocumentIsScript);
AddTextColorThemeComponentCommand = new RelayCommand(OnAddTextColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); AddTextColorThemeComponentCommand = new RelayCommand(OnAddTextColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
@@ -110,7 +119,7 @@ namespace Filtration.ViewModels
AddBorderColorThemeComponentCommand = new RelayCommand(OnAddBorderColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable); AddBorderColorThemeComponentCommand = new RelayCommand(OnAddBorderColorThemeComponentCommand, () => ActiveDocumentIsTheme && ActiveThemeIsEditable);
DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand, DeleteThemeComponentCommand = new RelayCommand(OnDeleteThemeComponentCommand,
() => () =>
ActiveDocumentIsTheme && ActiveDocumentIsTheme && ActiveDocumentIsTheme && ActiveThemeIsEditable &&
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent != null); _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent != null);
ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand, () => ActiveDocumentIsScript); ExpandAllBlocksCommand = new RelayCommand(OnExpandAllBlocksCommand, () => ActiveDocumentIsScript);
@@ -164,12 +173,28 @@ namespace Filtration.ViewModels
} }
case "OpenScript": case "OpenScript":
{ {
#pragma warning disable 4014
OnOpenScriptCommand(); OnOpenScriptCommand();
#pragma warning restore 4014
break;
}
case "ShowLoadingBanner":
{
ShowLoadingBanner = true;
break;
}
case "HideLoadingBanner":
{
ShowLoadingBanner = false;
break; break;
} }
} }
}); });
CheckForUpdates();
Task.Run(async () =>
{
await CheckForUpdatesAsync();
}).Wait();
} }
public RelayCommand OpenScriptCommand { get; private set; } public RelayCommand OpenScriptCommand { get; private set; }
@@ -213,14 +238,14 @@ namespace Filtration.ViewModels
public RelayCommand ClearFiltersCommand { get; private set; } public RelayCommand ClearFiltersCommand { get; private set; }
public async void CheckForUpdates() public async Task CheckForUpdatesAsync()
{ {
var assemblyVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location); var assemblyVersion = FileVersionInfo.GetVersionInfo(Assembly.GetExecutingAssembly().Location);
var result = await _updateCheckService.GetUpdateData();
try try
{ {
var result = await _updateCheckService.GetUpdateDataAsync();
if (result.LatestVersionMajorPart >= assemblyVersion.FileMajorPart && if (result.LatestVersionMajorPart >= assemblyVersion.FileMajorPart &&
result.LatestVersionMinorPart > assemblyVersion.FileMinorPart) result.LatestVersionMinorPart > assemblyVersion.FileMinorPart)
{ {
@@ -277,6 +302,16 @@ namespace Filtration.ViewModels
} }
} }
public bool ShowLoadingBanner
{
get { return _showLoadingBanner; }
private set
{
_showLoadingBanner = value;
RaisePropertyChanged();
}
}
public bool ActiveDocumentIsScript public bool ActiveDocumentIsScript
{ {
get { return _avalonDockWorkspaceViewModel.ActiveDocument != null && _avalonDockWorkspaceViewModel.ActiveDocument.IsScript; } get { return _avalonDockWorkspaceViewModel.ActiveDocument != null && _avalonDockWorkspaceViewModel.ActiveDocument.IsScript; }
@@ -320,6 +355,29 @@ namespace Filtration.ViewModels
} }
} }
public async Task OpenDroppedFilesAsync(List<string> filenames)
{
foreach (var filename in filenames)
{
var extension = Path.GetExtension(filename);
if (extension == null) continue;
switch (extension.ToUpperInvariant())
{
case ".FILTER":
{
await LoadScriptAsync(filename);
break;
}
case ".FILTERTHEME":
{
await LoadThemeAsync(filename);
break;
}
}
}
}
private void OnCreateThemeCommand() private void OnCreateThemeCommand()
{ {
var themeViewModel = _themeProvider.NewThemeForScript(AvalonDockWorkspaceViewModel.ActiveScriptViewModel.Script); var themeViewModel = _themeProvider.NewThemeForScript(AvalonDockWorkspaceViewModel.ActiveScriptViewModel.Script);
@@ -360,24 +418,31 @@ namespace Filtration.ViewModels
var aboutWindow = new AboutWindow(); var aboutWindow = new AboutWindow();
aboutWindow.ShowDialog(); aboutWindow.ShowDialog();
} }
private void OnOpenScriptCommand()
private async Task OnOpenScriptCommand()
{ {
var openFileDialog = new OpenFileDialog var filePath = ShowOpenScriptDialog();
if (string.IsNullOrEmpty(filePath))
{ {
Filter = "Filter Files (*.filter)|*.filter|All Files (*.*)|*.*", return;
InitialDirectory = _itemFilterScriptRepository.GetItemFilterScriptDirectory() }
};
if (openFileDialog.ShowDialog() != true) return; await LoadScriptAsync(filePath);
}
private async Task LoadScriptAsync(string scriptFilename)
{
IItemFilterScriptViewModel loadedViewModel; IItemFilterScriptViewModel loadedViewModel;
Messenger.Default.Send(new NotificationMessage("ShowLoadingBanner"));
try try
{ {
loadedViewModel = _itemFilterScriptRepository.LoadScriptFromFile(openFileDialog.FileName); loadedViewModel = await _itemFilterScriptRepository.LoadScriptFromFileAsync(scriptFilename);
} }
catch(IOException e) catch (IOException e)
{ {
Messenger.Default.Send(new NotificationMessage("HideLoadingBanner"));
if (_logger.IsErrorEnabled) if (_logger.IsErrorEnabled)
{ {
_logger.Error(e); _logger.Error(e);
@@ -388,23 +453,28 @@ namespace Filtration.ViewModels
return; return;
} }
Messenger.Default.Send(new NotificationMessage("HideLoadingBanner"));
_avalonDockWorkspaceViewModel.AddDocument(loadedViewModel); _avalonDockWorkspaceViewModel.AddDocument(loadedViewModel);
} }
private void OnOpenThemeCommand() private async Task OnOpenThemeCommandAsync()
{ {
var filePath = ShowOpenThemeDialog(); var filePath = ShowOpenThemeDialog();
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath))
{ {
return; return;
} }
await LoadThemeAsync(filePath);
}
private async Task LoadThemeAsync(string themeFilename)
{
IThemeEditorViewModel loadedViewModel; IThemeEditorViewModel loadedViewModel;
try try
{ {
loadedViewModel = _themeProvider.LoadThemeFromFile(filePath); loadedViewModel = await _themeProvider.LoadThemeFromFile(themeFilename);
} }
catch (IOException e) catch (IOException e)
{ {
@@ -421,7 +491,7 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.AddDocument(loadedViewModel); _avalonDockWorkspaceViewModel.AddDocument(loadedViewModel);
} }
private void OnApplyThemeToScriptCommand() private async Task OnApplyThemeToScriptCommandAsync()
{ {
var filePath = ShowOpenThemeDialog(); var filePath = ShowOpenThemeDialog();
if (string.IsNullOrEmpty(filePath)) if (string.IsNullOrEmpty(filePath))
@@ -433,7 +503,7 @@ namespace Filtration.ViewModels
try try
{ {
loadedTheme = _themeProvider.LoadThemeModelFromFile(filePath); loadedTheme = await _themeProvider.LoadThemeModelFromFile(filePath);
} }
catch (IOException e) catch (IOException e)
{ {
@@ -459,6 +529,16 @@ namespace Filtration.ViewModels
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SetDirtyFlag(); AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SetDirtyFlag();
} }
private string ShowOpenScriptDialog()
{
var openFileDialog = new OpenFileDialog
{
Filter = "Filter Files (*.filter)|*.filter|All Files (*.*)|*.*",
InitialDirectory = _itemFilterScriptRepository.GetItemFilterScriptDirectory()
};
return openFileDialog.ShowDialog() != true ? string.Empty : openFileDialog.FileName;
}
private string ShowOpenThemeDialog() private string ShowOpenThemeDialog()
{ {
@@ -471,8 +551,6 @@ namespace Filtration.ViewModels
return openFileDialog.ShowDialog() != true ? string.Empty : openFileDialog.FileName; return openFileDialog.ShowDialog() != true ? string.Empty : openFileDialog.FileName;
} }
private void SetItemFilterScriptDirectory() private void SetItemFilterScriptDirectory()
{ {
var dlg = new FolderBrowserDialog var dlg = new FolderBrowserDialog
@@ -488,14 +566,14 @@ namespace Filtration.ViewModels
} }
} }
private void OnSaveDocumentCommand() private async Task OnSaveDocumentCommandAsync()
{ {
((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).Save(); await ((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).SaveAsync();
} }
private void OnSaveAsCommand() private async Task OnSaveAsCommandAsync()
{ {
((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).SaveAs(); await ((IEditableDocument)_avalonDockWorkspaceViewModel.ActiveDocument).SaveAsAsync();
} }
private void OnReplaceColorsCommand() private void OnReplaceColorsCommand()
@@ -507,7 +585,18 @@ namespace Filtration.ViewModels
private void OnCopyScriptCommand() private void OnCopyScriptCommand()
{ {
Clipboard.SetText(_itemFilterScriptTranslator.TranslateItemFilterScriptToString(_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script)); try
{
_clipboardService.SetClipboardText(
_itemFilterScriptTranslator.TranslateItemFilterScriptToString(
_avalonDockWorkspaceViewModel.ActiveScriptViewModel.Script));
}
catch
{
_messageBoxService.Show("Clipboard Error", "Failed to access the clipboard, copy command not completed.",
MessageBoxButton.OK, MessageBoxImage.Error);
}
} }
private void OnCopyBlockCommand() private void OnCopyBlockCommand()
@@ -626,5 +715,22 @@ namespace Filtration.ViewModels
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.DeleteThemeComponentCommand.Execute( _avalonDockWorkspaceViewModel.ActiveThemeViewModel.DeleteThemeComponentCommand.Execute(
_avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent); _avalonDockWorkspaceViewModel.ActiveThemeViewModel.SelectedThemeComponent);
} }
public async Task<bool> CloseAllDocumentsAsync()
{
var openDocuments = _avalonDockWorkspaceViewModel.OpenDocuments.OfType<IEditableDocument>().ToList();
foreach (var document in openDocuments)
{
var docCount = _avalonDockWorkspaceViewModel.OpenDocuments.OfType<IEditableDocument>().Count();
await document.Close();
if (_avalonDockWorkspaceViewModel.OpenDocuments.OfType<IEditableDocument>().Count() == docCount)
{
return false;
}
}
return true;
}
} }
} }

View File

@@ -1,4 +1,5 @@
using Filtration.Common.ViewModels; using System.Threading.Tasks;
using Filtration.Common.ViewModels;
using Filtration.Interface; using Filtration.Interface;
using GalaSoft.MvvmLight.CommandWpf; using GalaSoft.MvvmLight.CommandWpf;
using GalaSoft.MvvmLight.Messaging; using GalaSoft.MvvmLight.Messaging;
@@ -25,7 +26,7 @@ namespace Filtration.ViewModels
public bool IsScript { get { return false; } } public bool IsScript { get { return false; } }
public bool IsTheme { get { return false; } } public bool IsTheme { get { return false; } }
public void Close() public Task Close()
{ {
throw new System.NotImplementedException(); throw new System.NotImplementedException();
} }

View File

@@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Windows.Media.Imaging; using System.Windows.Media.Imaging;
using GalaSoft.MvvmLight.Messaging;
namespace Filtration.ViewModels.ToolPanes namespace Filtration.ViewModels.ToolPanes
{ {
@@ -23,6 +24,18 @@ namespace Filtration.ViewModels.ToolPanes
icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/add_section_icon.png"); icon.UriSource = new Uri("pack://application:,,,/Filtration;component/Resources/Icons/add_section_icon.png");
icon.EndInit(); icon.EndInit();
IconSource = icon; IconSource = icon;
Messenger.Default.Register<NotificationMessage>(this, message =>
{
switch (message.Notification)
{
case "SectionsChanged":
{
OnActiveDocumentChanged(this, EventArgs.Empty);
break;
}
}
});
} }
public const string ToolContentId = "SectionBrowserTool"; public const string ToolContentId = "SectionBrowserTool";

View File

@@ -10,9 +10,10 @@
xmlns:converters="clr-namespace:Filtration.Converters" xmlns:converters="clr-namespace:Filtration.Converters"
xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock" xmlns:xcad="http://schemas.xceed.com/wpf/xaml/avalondock"
xmlns:themeEditorViews="clr-namespace:Filtration.ThemeEditor.Views;assembly=Filtration.ThemeEditor" xmlns:themeEditorViews="clr-namespace:Filtration.ThemeEditor.Views;assembly=Filtration.ThemeEditor"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance d:Type=viewModels:AvalonDockWorkspaceViewModel}" d:DataContext="{d:DesignInstance d:Type=viewModels:AvalonDockWorkspaceViewModel}"
d:DesignHeight="300" d:DesignWidth="300"> d:DesignHeight="300" d:DesignWidth="700">
<UserControl.Resources> <UserControl.Resources>
<xcad:BoolToVisibilityConverter x:Key="AvalonBoolToVisibilityConverter" /> <xcad:BoolToVisibilityConverter x:Key="AvalonBoolToVisibilityConverter" />
<converters:ActiveDocumentConverter x:Key="ActiveDocumentConverter" /> <converters:ActiveDocumentConverter x:Key="ActiveDocumentConverter" />

View File

@@ -272,6 +272,8 @@
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
<TextBlock Grid.Row="1" FontStyle="Italic" Visibility="{Binding HasAudioVisualBlockItems, Converter={StaticResource InverseBooleanVisibilityConverter}}">To change the appearance of this block, add a Text, Background or Border Block Item above.</TextBlock>
<!-- Block Items --> <!-- Block Items -->
<WrapPanel Grid.Row="1" MaxHeight="200"> <WrapPanel Grid.Row="1" MaxHeight="200">
<WrapPanel.Resources> <WrapPanel.Resources>

View File

@@ -8,15 +8,18 @@
xmlns:viewModels="clr-namespace:Filtration.ViewModels" xmlns:viewModels="clr-namespace:Filtration.ViewModels"
xmlns:viewsAvalonDock="clr-namespace:Filtration.Views.AvalonDock" xmlns:viewsAvalonDock="clr-namespace:Filtration.Views.AvalonDock"
xmlns:views="clr-namespace:Filtration.Views" xmlns:views="clr-namespace:Filtration.Views"
xmlns:gif="http://wpfanimatedgif.codeplex.com"
mc:Ignorable="d" mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}" d:DataContext="{d:DesignInstance Type=viewModels:MainWindowViewModel}"
Title="{Binding WindowTitle}" Height="762" Width="1126" IsIconVisible="True" > Title="{Binding WindowTitle}" Height="762" Width="1126" IsIconVisible="True"
Closing="MainWindow_OnClosing" Drop="MainWindow_OnDrop" AllowDrop="True">
<fluent:RibbonWindow.InputBindings> <fluent:RibbonWindow.InputBindings>
<KeyBinding Command="{Binding SaveCommand}" Modifiers="Control" Key="S" /> <KeyBinding Command="{Binding SaveCommand}" Modifiers="Control" Key="S" />
<KeyBinding Command="{Binding OpenScriptCommand}" Modifiers="Control" Key="O" /> <KeyBinding Command="{Binding OpenScriptCommand}" Modifiers="Control" Key="O" />
<KeyBinding Command="{Binding NewScriptCommand}" Modifiers="Control" Key="N" />
</fluent:RibbonWindow.InputBindings> </fluent:RibbonWindow.InputBindings>
<DockPanel x:Name="RootDockPanel"> <DockPanel x:Name="RootDockPanel">
<fluent:Ribbon DockPanel.Dock="Top" x:Name="RibbonRoot"> <fluent:Ribbon DockPanel.Dock="Top" x:Name="RibbonRoot" IsEnabled="{Binding ShowLoadingBanner, Converter={StaticResource BoolInverterConverter}}">
<fluent:Ribbon.Menu> <fluent:Ribbon.Menu>
<fluent:Backstage> <fluent:Backstage>
<fluent:BackstageTabControl> <fluent:BackstageTabControl>
@@ -29,10 +32,10 @@
</DataTemplate> </DataTemplate>
</fluent:BackstageTabItem.ContentTemplate> </fluent:BackstageTabItem.ContentTemplate>
</fluent:BackstageTabItem> </fluent:BackstageTabItem>
<fluent:Button Header="New Script" Command="{Binding NewScriptCommand}" Icon="{StaticResource NewIcon}" /> <fluent:Button Header="New Script" Command="{Binding NewScriptCommand}" Icon="{StaticResource NewIcon}" ToolTip="New Script (Ctrl+N)" />
<fluent:Button Header="Open Script" Command="{Binding OpenScriptCommand}" Icon="{StaticResource OpenIcon}" /> <fluent:Button Header="Open Script" Command="{Binding OpenScriptCommand}" Icon="{StaticResource OpenIcon}" ToolTip="Open Script (Ctrl+O)" />
<fluent:Button Header="Open Theme" Command="{Binding OpenThemeCommand}" Icon="{StaticResource OpenIcon}" /> <fluent:Button Header="Open Theme" Command="{Binding OpenThemeCommand}" Icon="{StaticResource OpenIcon}" />
<fluent:Button Header="Save" Command="{Binding SaveCommand}" Icon="{StaticResource SaveIcon}" /> <fluent:Button Header="Save" Command="{Binding SaveCommand}" Icon="{StaticResource SaveIcon}" ToolTip="Save (Ctrl+S)" />
<fluent:Button Header="Save As" Command="{Binding SaveAsCommand}" Icon="{StaticResource SaveIcon}" /> <fluent:Button Header="Save As" Command="{Binding SaveAsCommand}" Icon="{StaticResource SaveIcon}" />
<fluent:Button Header="Close" Command="{Binding CloseCommand}" /> <fluent:Button Header="Close" Command="{Binding CloseCommand}" />
<fluent:SeparatorTabItem /> <fluent:SeparatorTabItem />
@@ -71,10 +74,10 @@
</fluent:RibbonTabItem> </fluent:RibbonTabItem>
<fluent:RibbonTabItem x:Name="ScriptToolsTabItem" Header="Script Tools" Group="{Binding ElementName=ScriptToolsGroup}" Visibility="{Binding ActiveDocumentIsScript, Converter={StaticResource BooleanVisibilityConverter}, Mode=OneWay}" > <fluent:RibbonTabItem x:Name="ScriptToolsTabItem" Header="Script Tools" Group="{Binding ElementName=ScriptToolsGroup}" Visibility="{Binding ActiveDocumentIsScript, Converter={StaticResource BooleanVisibilityConverter}, Mode=OneWay}" >
<fluent:RibbonGroupBox Header="Clipboard"> <fluent:RibbonGroupBox Header="Clipboard">
<fluent:Button Header="Copy Block" Command="{Binding CopyBlockCommand}" Icon="{StaticResource CopyIcon}" LargeIcon="{StaticResource CopyIcon}"/> <fluent:Button Header="Copy Block" Command="{Binding CopyBlockCommand}" Icon="{StaticResource CopyIcon}" LargeIcon="{StaticResource CopyIcon}" ToolTip="Copy Block (Ctrl+C)"/>
<fluent:Button Header="Paste Block" Command="{Binding PasteCommand}" Icon="{StaticResource PasteIcon}" LargeIcon="{StaticResource PasteIcon}" /> <fluent:Button Header="Paste Block" Command="{Binding PasteCommand}" Icon="{StaticResource PasteIcon}" LargeIcon="{StaticResource PasteIcon}" ToolTip="Paste Block (Ctrl+V)"/>
<fluent:Button Header="Copy Style" Command="{Binding CopyBlockStyleCommand}" Icon="{StaticResource CopyIcon}" LargeIcon="{StaticResource CopyIcon}" SizeDefinition="Middle" /> <fluent:Button Header="Copy Style" Command="{Binding CopyBlockStyleCommand}" Icon="{StaticResource CopyIcon}" LargeIcon="{StaticResource CopyIcon}" SizeDefinition="Middle" ToolTip="Copy Style (Ctrl+Shift+C)" />
<fluent:Button Header="Paste Style" Command="{Binding PasteBlockStyleCommand}" Icon="{StaticResource PasteStyleIcon}" LargeIcon="{StaticResource PasteIcon}" SizeDefinition="Middle" /> <fluent:Button Header="Paste Style" Command="{Binding PasteBlockStyleCommand}" Icon="{StaticResource PasteStyleIcon}" LargeIcon="{StaticResource PasteIcon}" SizeDefinition="Middle" ToolTip="Paste Style (Ctrl+Shift+V)" />
<fluent:Button Header="Copy Script" Command="{Binding CopyScriptCommand}" Icon="{StaticResource CopyIcon}" LargeIcon="{StaticResource PasteIcon}" SizeDefinition="Middle" /> <fluent:Button Header="Copy Script" Command="{Binding CopyScriptCommand}" Icon="{StaticResource CopyIcon}" LargeIcon="{StaticResource PasteIcon}" SizeDefinition="Middle" />
</fluent:RibbonGroupBox> </fluent:RibbonGroupBox>
<fluent:RibbonGroupBox Header="Blocks"> <fluent:RibbonGroupBox Header="Blocks">
@@ -116,6 +119,30 @@
</fluent:Ribbon> </fluent:Ribbon>
<Grid> <Grid>
<viewsAvalonDock:AvalonDockWorkspaceView DataContext="{Binding AvalonDockWorkspaceViewModel}" /> <viewsAvalonDock:AvalonDockWorkspaceView DataContext="{Binding AvalonDockWorkspaceViewModel}" />
<Grid ZIndex="9999" Visibility="{Binding ShowLoadingBanner, Converter={StaticResource BooleanToVisibilityConverter}, ConverterParameter={x:Static Visibility.Hidden}}">
<Grid.Background>
<SolidColorBrush Color="Black" Opacity="0.5" />
</Grid.Background>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border Grid.Row="1" Grid.Column="1" BorderBrush="Black" BorderThickness="1" Background="White" Padding="20">
<StackPanel Orientation="Horizontal">
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="20" FontWeight="DemiBold">Working...</TextBlock>
<Image gif:ImageBehavior.AnimatedSource="/Filtration;component/Resources/loading_spinner.gif" Height="32" Margin="10,0,0,0"/>
</StackPanel>
</Border>
</Grid>
</Grid>
</Grid> </Grid>
</DockPanel> </DockPanel>
</fluent:RibbonWindow> </fluent:RibbonWindow>

View File

@@ -1,4 +1,8 @@
using System.Windows; using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Threading.Tasks;
using System.Windows;
using Filtration.ViewModels; using Filtration.ViewModels;
namespace Filtration.Views namespace Filtration.Views
@@ -10,8 +14,11 @@ namespace Filtration.Views
internal partial class MainWindow : IMainWindow internal partial class MainWindow : IMainWindow
{ {
private readonly IMainWindowViewModel _mainWindowViewModel;
public MainWindow(IMainWindowViewModel mainWindowViewModel) public MainWindow(IMainWindowViewModel mainWindowViewModel)
{ {
_mainWindowViewModel = mainWindowViewModel;
InitializeComponent(); InitializeComponent();
DataContext = mainWindowViewModel; DataContext = mainWindowViewModel;
} }
@@ -31,5 +38,38 @@ namespace Filtration.Views
RibbonRoot.SelectedTabItem = ThemeToolsTabItem; RibbonRoot.SelectedTabItem = ThemeToolsTabItem;
} }
} }
private void MainWindow_OnClosing(object sender, CancelEventArgs e)
{
var allDocumentsClosed = _mainWindowViewModel.CloseAllDocumentsAsync().Result;
if (!allDocumentsClosed)
{
e.Cancel = true;
}
}
private async void MainWindow_OnDrop(object sender, DragEventArgs e)
{
if (!e.Data.GetDataPresent(DataFormats.FileDrop)) return;
var filenames = (string[])e.Data.GetData(DataFormats.FileDrop);
var droppedFilterFiles = new List<string>();
foreach (var filename in filenames)
{
var extension = Path.GetExtension(filename);
if (extension != null &&
(extension.ToUpperInvariant() == ".FILTER" || extension.ToUpperInvariant() == ".FILTERTHEME"))
{
droppedFilterFiles.Add(filename);
}
}
if (droppedFilterFiles.Count > 0)
{
await _mainWindowViewModel.OpenDroppedFilesAsync(droppedFilterFiles);
}
}
} }
} }

View File

@@ -1,14 +0,0 @@
using Castle.MicroKernel.Registration;
using Castle.MicroKernel.SubSystems.Configuration;
using Castle.Windsor;
namespace Filtration.WindsorInstallers
{
public class ModelsInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
}
}
}

View File

@@ -34,6 +34,11 @@ namespace Filtration.WindsorInstallers
Component.For<IUpdateCheckService>() Component.For<IUpdateCheckService>()
.ImplementedBy<UpdateCheckService>() .ImplementedBy<UpdateCheckService>()
.LifeStyle.Singleton); .LifeStyle.Singleton);
container.Register(
Component.For<IClipboardService>()
.ImplementedBy<ClipboardService>()
.LifeStyle.Singleton);
} }
} }
} }

View File

@@ -11,5 +11,6 @@
<package id="NLog" version="4.0.1" targetFramework="net451" /> <package id="NLog" version="4.0.1" targetFramework="net451" />
<package id="NLog.Config" version="4.0.1" targetFramework="net451" /> <package id="NLog.Config" version="4.0.1" targetFramework="net451" />
<package id="NLog.Schema" version="4.0.1" targetFramework="net451" /> <package id="NLog.Schema" version="4.0.1" targetFramework="net451" />
<package id="WpfAnimatedGif" version="1.4.13" targetFramework="net451" />
<package id="WPFToolkit" version="3.5.50211.1" targetFramework="net451" /> <package id="WPFToolkit" version="3.5.50211.1" targetFramework="net451" />
</packages> </packages>

View File

@@ -2,10 +2,10 @@
Filtration is an editor for Path of Exile item filter scripts. Filtration is an editor for Path of Exile item filter scripts.
## Current Release (Released 2015-07-06) ## Current Release (Released 2015-07-15)
<b>Installer (6.31mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.7/filtration_0.7_setup.exe">filtration_0.7_setup.exe</a> <b>Installer (6.3mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.9/filtration_0.9_setup.exe">filtration_0.9_setup.exe</a>
<b>Zip File (7.91mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.7/filtration_0.7.zip">filtration_0.7.zip</a> <b>Zip File (7.89mb)</b> <a href="https://github.com/ben-wallis/Filtration/releases/download/0.9/filtration_0.9.zip">filtration_0.9.zip</a>
## System Requirements ## System Requirements
Filtration requires .NET Framework 4.5.1 installed. Filtration requires .NET Framework 4.5.1 installed.