Merge ImageResizer into master (#1469)

* Import Image Resizer for Windows

* getting code analysis and stylecop hooked in

* upgrading to 4.7.2

* adding copyright

* getting stuff to work

headers and trailing commas

adding braces

updated encoder

* Revert "getting stuff to work"

This reverts commit 5310866120.

* update to .net 4.7.2

* access modifier

* zero errors

* Fixed unit tests not running issue

* Fixed ImageResizer.Test stylecop warning

* Formatted ShellExtensions project with clang-format

* Fixed annotation warnings

* Suppressed 6031 and 26812 warnings for specific lines

* Shifting ImageResizer projects to PowerToys solution (#1054)

* Shifted ImageResizer projects to PowerToys solution: Builds, all tests pass, ImageResizer C# project works independently

* Deleted extra files

* Deleted nuget config file and fixed code analysis paths

* Convert ImageResizer to a PowerToy (#1073)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed missing braces

* Fixed call_custom_action

* Add ImageResizer to msi installer (dev/imageResizer) (#1094)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed solution file configurations

* Removed Any CPU from ImageResizer csprojs

* Renamed registry writing and removed build time registry addition

* Added ImageResizer installation details to msi

* Fixed comment on conditions to close explorer.exe

* Sync dev/imageResizer with master (#1105)

* tweaking language

* adjusting elevated permission verbiage to match Windows

* npm audit fix to update stuff

* slight bump for fabric ui

* Remove unwanted files (#1037)

Add temp build files to gitignore

* Ensure previous search and replace texts are evaluated and updated in the UI at startup (#1043)

Ensure stored settings get evaluated after initial enumeration

There was a bug where the list view was not getting updated with the results of the search and replace on launch when we are using a stored search or replace text from a previous session.

* adding fancy zone opacity setting, enhancement #631 (#1008)

* adding fancy zone opacity setting, enhancement #631

* applying zone opacity setting to all zones during zone selection

* changing opacity setting to percentage

* runner: show message box when restarting with different elevation fails (#1061)

Also make the message box appear on top of the settings window.

* Fix misaligned display of zones in layout priview and grid editor (#1010)

Fix misaligned display of zones in layout preview and grid editor

* MSIX: Extract MSIX building functionality from msix_reinstall.ps1 to a separate script (#1068)

* MSIX: label PowerToys as Preview (#1090)

* MSIX: Code sign msixbundle (#1093)

* Update to MSIX README.md (#1095)

* Update README.md

few adjustments

* Update README.md

* Update README.md

* adding in privacy statement, removing About in dialog (#1087)

* adding in privacy statement, removing About in dialog

* added Preview

* Revert "Fix misaligned display of zones in layout priview and grid editor (#1010)" (#1097)

This reverts commit d03690cffd.

* Fix reversed order of zones in layout (#1071)

* Shifted three functions to common (#1101)

Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
Co-authored-by: Chris Davis <chrisdavis@outlook.com>
Co-authored-by: Yosef Durr <yodurr@microsoft.com>
Co-authored-by: Bartosz Sosnowski <bzoz@users.noreply.github.com>
Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com>
Co-authored-by: yuyoyuppe <yuyoyuppe@users.noreply.github.com>

* Revert "Sync dev/imageResizer with master (#1105)"

This reverts commit db7f15541f.

* Added icon to Resize pictures context menu entry (dev/imageResizer) (#1113)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed solution file configurations

* Removed Any CPU from ImageResizer csprojs

* Renamed registry writing and removed build time registry addition

* Added ImageResizer installation details to msi

* Shifted to MII, TODO: Fix position

* Incorporated ImageResizer Icon in context menu entry

* Fixed typo

* Merged with dev/imageResizer

* Renamed Advanced Options to Settings and removed About tab (dev/imageResizer) (#1123)

* Removed about tab, renamed advanced opt to settings, changed assembly info

* Restored Resource designer file

* Reverted changes on AssemblyInfo

* MSI: Fix ImageResizer menu item position (dev/imageResizer) (#1114)

* Updated vcxproj file with common project references and cpp version flags

* Added module template code to dllmain and updated headers for successful build

* Removed unnecessary include

* Added dll to runner and add fixes to show up in PT Settings

* Added settings file

* Added support for enabling/disabling based on PowerRename codebase

* Fixed solution file configurations

* Removed Any CPU from ImageResizer csprojs

* Renamed registry writing and removed build time registry addition

* Added ImageResizer installation details to msi

* Shifted to MII, TODO: Fix position

* Incorporated ImageResizer Icon in context menu entry

* Changed registry entries to SystemFileAssociations and added index changes in InsertMenuItem

* Fixed extra newline

* Fixed merge conflict

* Refactor ImageResizer code base naming to match PowerRename (#1121)

* Created empty README file

* Renamed dll project

* Removed ShellExtensions references in src

* Fixed ImageResizerUI assembly name and added changes to MSI

* added the helper functions

* localized dllmain powerrename

* localized powerRenameExt

* localized the settings file

* built the proj

* Modified resourceIDs for strings in the table

* added common as a reference project

* Removed get_res_string_wchar and used the get_resource_string() function instead which returns a wstring typecast into wchar*

* Added new lines to the end of the file

* Removed string resources from the settings.cpp file

* rebuilt project PowerRename

* moved app name to constructor to init only once

* updated formatting of common.cpp

* reverting formatting of files

* Removed some IDs from resource file. Changed SHIFT to Shift

* Localizing C# Project of FancyZones (FancyZonesEditor) (#199) (#1122)

* removed hardcoded strings from CanvasEditorWindow.xaml

* removed hardcoded strings from GridEditorWindow.xaml

* loc

* Localized MainWindow

* reverting MainWindow.xaml as it is not rendering the window as expected

* Changed the resource settings from internal to public

* the culture is set based on the culture of the system UI set in the system settings

* Removed the french resource files used for testing

* Localized canvasWindow and mainwindow

* Removed setting the UI culture explicitly as it would be implicitly set to the culture of system UI

* Removed redundant header file

* Localize the Shortcut guide PowerToy (#199) (#1126)

* Localized shortcut_guide.cpp

* localized overlay_window.cpp

* formatting changes

* Localize overlay window

* removed the README link from the set of localized resources

* Typo: changed upper to lower

* Localize C++ Projects of FancyZones (#1130)

* localized dllmain.cpp  of fancyzones project

* localized FancyZones.cpp

* format fancyzones.rc file

* Moved SuperFancyZones back to being a string instead of having it in the resource file as it is the window class name

* reverted changes for window name

* Formatted fancyzones rc file

* Align zone dimensions from layout preview with those from grid editor (#1115)

* MSIX: add a dedicated .rc for UWPUI which joins both UI and DLL .rc's (#1139)

* Runner: fix restarting with same elevation (#1133)

* MSIX: reinstall script uses bundle instead of .msi to be able to reinstall in all cases

* Telemetry: add WebView init failure errors

* Settings: initialize COM security to allow communication between elevated Settings and WebView

* Common: implement on_scope_exit helper and typed_storage

* Changes for #1140 and #569 (#1152)

* MSIX build instructions adjustmnet (#1170)

* MSIX: hide the "Run at Startup" option if running as packaged

* MSIX: update identity name and publisher (#1176)

* Runner: fix startup task state setting for MSIX (#1181)

* Add ImageResizer to MSIX installer and make the code MSIX-compatible (#1219)

* Removed ImageResizer.exe location registry key

* Added working resize pictures to MSIX context menu without icon

* Fixed missing icon on MSIX build

* Added comments

* Changed to single context handler entry

* Made changes as per PR comments

* Localize ImageResizer (#1261)

* Removed hardcoded strings

* Added resource dlls to MSIX installer

* Save ImageResizer settings in JSON format (#1258)

* Combined settings files

* Added JSON settings functionality in PowerToys format with thread safety

* Reverting changes to csproj file

* Removed settings.settings and designer file and added target sdk tools to fix warning

* Added NewtonSoft Json package

* Added 3 tests

* Added propertychanged test

* Removed unused libraries

* Removed additional allocation statements in test

* Added comments on test

* Added one-time setup code

* Added Newtonsoft.Json.dll to MSI and MSIX installer

* Fixed copyright header

* Fixed folder location in MSIX

* Renamed jsonMutex to _jsonMutex

* Fixed line endings

* Created private setup functions and added Arrange, Act, Assert comments

* Created private setup functions and added Arrange, Act, Assert comments

* Suppressed copyright warning on AppFixture and enabled treat warnings as errors

* Added comments on Reload/AppFixture and added constructor andispose

* Added telemetry to ImageResizer Shell Extension code (dev/imageResizer) (#1272)

* Added telemetry to C++ ImageResizerExt

* Added Register and unregister calls

* Changed default enable setting

* Set startup location to center of the screen (ImageResizer) (#1452)

* Added ImageResizer resources.dlls to the MSI installer (#1448)

* Implemented fix for foreground issue for ImageResizer (#1434)

* Fixed conflict in installer README.md file

* Fixed conflict in bundle.js

* Auto-generate AssemblyInfo in ImageResizer (#1467)

* Updated assembly info

* Added auto-generation of AssemblyInfo.cs

* Fixed minor issues

* Remove the  License file since Notice.md have been added

* Fix errors due to resolving merge conflicts

Co-authored-by: Brice Lambson <brice@bricelam.net>
Co-authored-by: Clint Rutkas <clint@rutkas.com>
Co-authored-by: Arjun Balgovind <arbalgov@microsoft.com>
Co-authored-by: Enrico Giordani <enricogior@users.noreply.github.com>
Co-authored-by: Chris Davis <chrisdavis@outlook.com>
Co-authored-by: Yosef Durr <yodurr@microsoft.com>
Co-authored-by: Bartosz Sosnowski <bzoz@users.noreply.github.com>
Co-authored-by: vldmr11080 <57061786+vldmr11080@users.noreply.github.com>
Co-authored-by: yuyoyuppe <yuyoyuppe@users.noreply.github.com>
Co-authored-by: Alekhya Kommuru <alkommur@microsoft.com>
Co-authored-by: Alekhya <reddykalekhya@gmail.com>
Co-authored-by: yuyoyuppe <a.yuyoyuppe@gmail.com>
Co-authored-by: Udit Singh <udsing@microsoft.com>
This commit is contained in:
Arjun Balgovind
2020-03-12 12:02:34 -04:00
committed by GitHub
parent 7f12288b2c
commit d84cc370c9
114 changed files with 13436 additions and 10 deletions

View File

@@ -0,0 +1,272 @@
<Window x:Class="ImageResizer.Views.AdvancedWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageResizer.Views"
xmlns:m="clr-namespace:ImageResizer.Models"
xmlns:p="clr-namespace:ImageResizer.Properties"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
MinWidth="390"
MinHeight="340"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
Name="_this"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Title="{x:Static p:Resources.Advanced_Title}"
WindowStyle="ToolWindow"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<ObjectDataProvider x:Key="PngInterlaceOptionValues"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="PngInterlaceOption"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<ObjectDataProvider x:Key="TiffCompressOptionValues"
MethodName="GetValues"
ObjectType="{x:Type sys:Enum}">
<ObjectDataProvider.MethodParameters>
<x:Type TypeName="TiffCompressOption"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<local:ContainerFormatConverter x:Key="ContainerFormatConverter"/>
</Window.Resources>
<Grid Margin="11">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TabControl>
<TabItem Header="{x:Static p:Resources.Advanced_Sizes}">
<StackPanel Margin="11">
<!-- TODO: Allow these to be drag-and-drop reordered (issue #15) -->
<ItemsControl Grid.IsSharedSizeScope="True" ItemsSource="{Binding Settings.Sizes}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="m:ResizeSize">
<Grid Margin="0,0,0,7">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="0"/>
<ColumnDefinition SharedSizeGroup="1"/>
<ColumnDefinition SharedSizeGroup="2"/>
<ColumnDefinition SharedSizeGroup="3"/>
<ColumnDefinition SharedSizeGroup="4"/>
<ColumnDefinition SharedSizeGroup="5"/>
<ColumnDefinition SharedSizeGroup="6"/>
</Grid.ColumnDefinitions>
<TextBox Width="66" Text="{Binding Name}"/>
<ComboBox Grid.Column="1"
Height="23"
Margin="5,0,0,0"
ItemsSource="{Binding Source={StaticResource ResizeFitValues}}"
SelectedItem="{Binding Fit}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type m:ResizeFit}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Grid.Column="2"
Width="43"
Height="23"
Margin="7,0,0,0">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Width"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock Grid.Column="3"
Margin="5,0,0,0"
VerticalAlignment="Center"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
×
</TextBlock>
<TextBox Grid.Column="4"
Width="43"
Height="23"
Margin="5,0,0,0"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Height"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ComboBox Grid.Column="5"
Height="23"
Margin="7,0,0,0"
ItemsSource="{Binding Source={StaticResource ResizeUnitValues}}"
SelectedItem="{Binding Unit}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type m:ResizeUnit}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBlock Grid.Column="6" Margin="5,0,0,0">
<Hyperlink Command="{Binding DataContext.RemoveSizeCommand,ElementName=_this}" CommandParameter="{Binding}">
<Run Text="{x:Static p:Resources.Advanced_DeleteSize}"/>
</Hyperlink>
</TextBlock>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<TextBlock>
<Hyperlink Command="{Binding AddSizeCommand}">
<Run Text="{x:Static p:Resources.Advanced_CreateSize}"/>
</Hyperlink>
</TextBlock>
</StackPanel>
</TabItem>
<TabItem Header="{x:Static p:Resources.Advanced_Encoding}">
<Grid Margin="11" VerticalAlignment="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Label Content="{x:Static p:Resources.Advanced_FallbackEncoder}"
Padding="0,5,5,0"
Target="{Binding ElementName=_fallbackEncoderComboBox}"/>
<ComboBox Grid.Column="1"
Height="23"
HorizontalAlignment="Left"
ItemsSource="{Binding Encoders}"
Name="_fallbackEncoderComboBox"
SelectedItem="{Binding Settings.FallbackEncoder}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type sys:Guid}">
<ContentPresenter Content="{Binding Converter={StaticResource ContainerFormatConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="1"
Margin="0,7,0,0"
Content="{x:Static p:Resources.Advanced_JpegQualityLevel}"
Padding="0,5,5,0"
Target="{Binding ElementName=_jpegQualityLevelTextBox}"/>
<TextBox Grid.Row="1"
Grid.Column="1"
Width="34"
Height="23"
Margin="0,7,0,0"
HorizontalAlignment="Left"
Name="_jpegQualityLevelTextBox"
Text="{Binding Settings.JpegQualityLevel,ValidatesOnExceptions=True,ValidatesOnDataErrors=True}"/>
<Label Grid.Row="2"
Margin="0,7,0,0"
Content="{x:Static p:Resources.Advanced_PngInterlaceOption}"
Padding="0,5,5,0"
Target="{Binding ElementName=_pngInterlaceComboBox}"/>
<ComboBox Grid.Row="2"
Grid.Column="1"
Height="23"
Margin="0,7,0,0"
HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource PngInterlaceOptionValues}}"
Name="_pngInterlaceComboBox"
SelectedItem="{Binding Settings.PngInterlaceOption}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type PngInterlaceOption}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<Label Grid.Row="3"
Margin="0,7,0,0"
Content="{x:Static p:Resources.Advanced_TiffCompressOption}"
Padding="0,5,5,0"
Target="{Binding ElementName=_tiffCompressComboBox}"/>
<ComboBox Grid.Row="3"
Grid.Column="1"
Height="23"
Margin="0,7,0,0"
HorizontalAlignment="Left"
ItemsSource="{Binding Source={StaticResource TiffCompressOptionValues}}"
Name="_tiffCompressComboBox"
SelectedItem="{Binding Settings.TiffCompressOption}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type TiffCompressOption}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</Grid>
</TabItem>
<TabItem Header="{x:Static p:Resources.Advanced_File}">
<StackPanel Margin="11,9">
<TextBlock Text="{x:Static p:Resources.Advanced_FileNameTokens}"/>
<TextBlock Margin="9,5,0,0">
<Run Text="%1 -"/>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken1}"/>
<LineBreak/>
<Run>%2 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken2}"/>
<LineBreak/>
<Run>%3 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken3}"/>
<LineBreak/>
<Run>%4 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken4}"/>
<LineBreak/>
<Run>%5 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken5}"/>
<LineBreak/>
<Run>%6 -</Run>
<Run Text="{x:Static p:Resources.Advanced_FileNameToken6}"/>
</TextBlock>
<Grid Margin="0,7,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Label HorizontalAlignment="Left"
Content="{x:Static p:Resources.Advanced_FileName}"
Padding="0,5,5,0"
Target="{Binding ElementName=_fileNameTextBox}"/>
<TextBox Grid.Column="1"
Height="23"
Name="_fileNameTextBox"
Text="{Binding Settings.FileName}"/>
</Grid>
<Separator Margin="0,11,0,0"/>
<CheckBox Margin="0,11,0,0"
Content="{x:Static p:Resources.Advanced_KeepDateModified}"
IsChecked="{Binding Settings.KeepDateModified}"/>
</StackPanel>
</TabItem>
</TabControl>
<StackPanel Grid.Row="1"
Margin="0,11,0,0"
HorizontalAlignment="Right"
Orientation="Horizontal">
<Button Height="23"
MinWidth="75"
Click="HandleAcceptClick"
Content="{x:Static p:Resources.OK}"
IsDefault="True"/>
<Button Height="23"
MinWidth="75"
Margin="7,0,0,0"
Content="{x:Static p:Resources.Cancel}"
IsCancel="True"/>
</StackPanel>
</Grid>
</Window>

View File

@@ -0,0 +1,29 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Diagnostics;
using System.Windows;
using System.Windows.Navigation;
using ImageResizer.ViewModels;
namespace ImageResizer.Views
{
public partial class AdvancedWindow : Window
{
public AdvancedWindow(AdvancedViewModel viewModel)
{
DataContext = viewModel;
InitializeComponent();
}
private void HandleAcceptClick(object sender, RoutedEventArgs e)
=> DialogResult = true;
private void HandleRequestNavigate(object sender, RequestNavigateEventArgs e)
{
Process.Start(e.Uri.ToString());
e.Handled = true;
}
}
}

View File

@@ -0,0 +1,35 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Windows.Data;
using ImageResizer.Properties;
namespace ImageResizer.Views
{
[ValueConversion(typeof(double), typeof(string))]
internal class AutoDoubleConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var d = (double)value;
return d != 0
? d.ToString(culture)
: (string)parameter == "Auto"
? Resources.Input_Auto
: string.Empty;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
var text = (string)value;
return !string.IsNullOrEmpty(text)
? double.Parse(text, culture)
: 0;
}
}
}

View File

@@ -0,0 +1,22 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Globalization;
using System.Windows.Controls;
namespace ImageResizer.Views
{
internal class AutoDoubleValidationRule : ValidationRule
{
public override ValidationResult Validate(object value, CultureInfo cultureInfo)
{
var text = (string)value;
return new ValidationResult(
string.IsNullOrEmpty(text)
|| double.TryParse(text, NumberStyles.AllowThousands | NumberStyles.Float, cultureInfo, out var _),
null);
}
}
}

View File

@@ -0,0 +1,21 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Windows;
using System.Windows.Data;
namespace ImageResizer.Views
{
[ValueConversion(typeof(Enum), typeof(string))]
internal class BoolValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> (bool)value ? Visibility.Visible : Visibility.Collapsed;
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,23 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Windows.Data;
using ImageResizer.ViewModels;
namespace ImageResizer.Views
{
[ValueConversion(typeof(Guid), typeof(string))]
public class ContainerFormatConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> AdvancedViewModel.EncoderMap.TryGetValue((Guid)value, out var result)
? result
: value.ToString();
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,51 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Text;
using System.Windows.Data;
using ImageResizer.Properties;
namespace ImageResizer.Views
{
[ValueConversion(typeof(Enum), typeof(string))]
public class EnumValueConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var type = value.GetType();
var builder = new StringBuilder();
builder
.Append(type.Name)
.Append("_")
.Append(Enum.GetName(type, value));
var toLower = false;
if ((string)parameter == "ToLower")
{
toLower = true;
}
else if (parameter != null)
{
builder
.Append("_")
.Append(parameter);
}
var targetValue = Resources.ResourceManager.GetString(builder.ToString());
if (toLower)
{
targetValue = targetValue.ToLower();
}
return targetValue;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> value;
}
}

View File

@@ -0,0 +1,18 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Collections.Generic;
using ImageResizer.ViewModels;
namespace ImageResizer.Views
{
public interface IMainView
{
void Close();
void ShowAdvanced(AdvancedViewModel viewModel);
IEnumerable<string> OpenPictureFiles();
}
}

View File

@@ -0,0 +1,154 @@
<UserControl x:Class="ImageResizer.Views.InputPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ImageResizer.Views"
xmlns:m="clr-namespace:ImageResizer.Models"
xmlns:p="clr-namespace:ImageResizer.Properties"
MinWidth="350">
<StackPanel>
<TextBlock Margin="11,11,11,0"
Style="{StaticResource MainInstructionTextBlockStyle}"
Text="{x:Static p:Resources.Input_MainInstruction}"/>
<Label Margin="11,11,11,0"
Content="{x:Static p:Resources.Input_Content}"
Target="{Binding ElementName=_selectedSizeListBox}"/>
<ListBox Margin="20,0,11,0"
BorderThickness="0"
ItemsSource="{Binding Settings.AllSizes}"
Name="_selectedSizeListBox"
SelectedIndex="{Binding Settings.SelectedSizeIndex}">
<ListBox.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<RadioButton Margin="0,7,0,0"
Focusable="False"
IsChecked="{Binding IsSelected,RelativeSource={RelativeSource TemplatedParent}}">
<ContentPresenter/>
</RadioButton>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.ItemContainerStyle>
<ListBox.Resources>
<DataTemplate DataType="{x:Type m:ResizeSize}">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Name}"/>
<TextBlock Text=" ("/>
<TextBlock Text="{Binding Fit,Converter={StaticResource EnumValueConverter},ConverterParameter=ThirdPersonSingular}"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding Width,Converter={StaticResource AutoDoubleConverter},ConverterParameter=Auto}"/>
<TextBlock Text=" × " Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}"/>
<TextBlock Text="{Binding Height,Converter={StaticResource AutoDoubleConverter},ConverterParameter=Auto}" Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}"/>
<TextBlock Text=" "/>
<TextBlock Text="{Binding Unit,Converter={StaticResource EnumValueConverter},ConverterParameter=ToLower}"/>
<TextBlock Text=")"/>
</StackPanel>
</DataTemplate>
<DataTemplate DataType="{x:Type m:CustomSize}">
<StackPanel Orientation="Horizontal">
<TextBlock VerticalAlignment="Center" Text="{Binding Name}"/>
<ComboBox Height="23"
Margin="5,0,0,0"
ItemsSource="{Binding Source={StaticResource ResizeFitValues}}"
SelectedItem="{Binding Fit}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type m:ResizeFit}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<TextBox Width="43"
Height="23"
Margin="7,0,0,0">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Width"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<TextBlock Margin="5,0,0,0"
VerticalAlignment="Center"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
×
</TextBlock>
<TextBox Width="43"
Height="23"
Margin="5,0,0,0"
Visibility="{Binding ShowHeight,Converter={StaticResource BoolValueConverter}}">
<TextBox.Text>
<Binding Converter="{StaticResource AutoDoubleConverter}"
Path="Height"
UpdateSourceTrigger="PropertyChanged">
<Binding.ValidationRules>
<local:AutoDoubleValidationRule/>
</Binding.ValidationRules>
</Binding>
</TextBox.Text>
</TextBox>
<ComboBox Height="23"
Margin="7,0,0,0"
ItemsSource="{Binding Source={StaticResource ResizeUnitValues}}"
SelectedItem="{Binding Unit}">
<ComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type m:ResizeUnit}">
<ContentPresenter Content="{Binding Converter={StaticResource EnumValueConverter}}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</StackPanel>
</DataTemplate>
</ListBox.Resources>
</ListBox>
<CheckBox Margin="11,11,11,0"
Content="{x:Static p:Resources.Input_ShrinkOnly}"
IsChecked="{Binding Settings.ShrinkOnly}"/>
<!-- TODO: This option doesn't make much sense when resizing into a directory. We should swap it for an option
to overwrite any files in the directory instead (issue #88) -->
<CheckBox Margin="11,7,11,0"
Content="{x:Static p:Resources.Input_Replace}"
IsChecked="{Binding Settings.Replace}"/>
<CheckBox Margin="11,7,11,0"
Content="{x:Static p:Resources.Input_IgnoreOrientation}"
IsChecked="{Binding Settings.IgnoreOrientation}"/>
<Border Margin="0,11,0,0"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
BorderThickness="0,1,0,0"
Padding="11,11">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBlock VerticalAlignment="Center">
<Hyperlink Command="{Binding ShowAdvancedCommand}">
<Run Text="{x:Static p:Resources.Input_ShowAdvanced}"/>
</Hyperlink>
</TextBlock>
<Button Grid.Column="1"
Height="23"
MinWidth="75"
Command="{Binding ResizeCommand}"
Content="{x:Static p:Resources.Input_Resize}"
IsDefault="True"/>
<Button Grid.Column="2"
Height="23"
MinWidth="75"
Margin="7,0,0,0"
Command="{Binding CancelCommand}"
Content="{x:Static p:Resources.Cancel}"
IsCancel="True"/>
</Grid>
</Border>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,14 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Windows.Controls;
namespace ImageResizer.Views
{
public partial class InputPage : UserControl
{
public InputPage()
=> InitializeComponent();
}
}

View File

@@ -0,0 +1,38 @@
<Window x:Class="ImageResizer.Views.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:ImageResizer.Views"
xmlns:p="clr-namespace:ImageResizer.Properties"
xmlns:vm="clr-namespace:ImageResizer.ViewModels"
Content="{Binding CurrentPage}"
Icon="/ImageResizer;component/Resources/ImageResizer.ico"
Name="_this"
ResizeMode="NoResize"
SizeToContent="WidthAndHeight"
Title="{x:Static p:Resources.ImageResizer}"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<DataTemplate DataType="{x:Type vm:InputViewModel}">
<local:InputPage/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ProgressViewModel}">
<local:ProgressPage/>
</DataTemplate>
<DataTemplate DataType="{x:Type vm:ResultsViewModel}">
<local:ResultsPage/>
</DataTemplate>
</Window.Resources>
<Window.TaskbarItemInfo>
<TaskbarItemInfo ProgressState="Normal" ProgressValue="{Binding Progress}"/>
</Window.TaskbarItemInfo>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding LoadCommand}" CommandParameter="{Binding ElementName=_this}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</Window>

View File

@@ -0,0 +1,48 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using ImageResizer.ViewModels;
using Microsoft.Win32;
using AppResources = ImageResizer.Properties.Resources;
namespace ImageResizer.Views
{
public partial class MainWindow : Window, IMainView
{
public MainWindow(MainViewModel viewModel)
{
DataContext = viewModel;
InitializeComponent();
}
public IEnumerable<string> OpenPictureFiles()
{
var openFileDialog = new OpenFileDialog
{
Filter = AppResources.PictureFilter +
"|*.bmp;*.dib;*.exif;*.gif;*.jfif;*.jpe;*.jpeg;*.jpg;*.jxr;*.png;*.rle;*.tif;*.tiff;*.wdp|" +
AppResources.AllFilesFilter + "|*.*",
InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyPictures),
Multiselect = true,
};
if (openFileDialog.ShowDialog() != true)
{
return Enumerable.Empty<string>();
}
return openFileDialog.FileNames;
}
public void ShowAdvanced(AdvancedViewModel viewModel)
=> viewModel.Close(new AdvancedWindow(viewModel).ShowDialog() == true);
void IMainView.Close()
=> Dispatcher.Invoke((Action)Close);
}
}

View File

@@ -0,0 +1,43 @@
<UserControl x:Class="ImageResizer.Views.ProgressPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:local="clr-namespace:ImageResizer.Views"
xmlns:p="clr-namespace:ImageResizer.Properties"
MinWidth="350">
<UserControl.Resources>
<local:TimeRemainingConverter x:Key="TimeRemainingConverter"/>
</UserControl.Resources>
<i:Interaction.Triggers>
<i:EventTrigger EventName="Loaded">
<i:InvokeCommandAction Command="{Binding StartCommand}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
<StackPanel>
<TextBlock Margin="11,11,11,0"
Style="{StaticResource MainInstructionTextBlockStyle}"
Text="{x:Static p:Resources.Progress_MainInstruction}"/>
<TextBlock Margin="11,11,11,0" Text="{Binding TimeRemaining,Converter={StaticResource TimeRemainingConverter}}"/>
<ProgressBar Height="15"
Margin="11,11,11,0"
Value="{Binding Progress}"
Maximum="1"/>
<Border Margin="0,11,0,0"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
BorderThickness="0,1,0,0"
Padding="11,11">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Height="23"
MinWidth="75"
Command="{Binding StopCommand}"
Content="{x:Static p:Resources.Progress_Stop}"
IsCancel="True"/>
</StackPanel>
</Border>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,14 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Windows.Controls;
namespace ImageResizer.Views
{
public partial class ProgressPage : UserControl
{
public ProgressPage()
=> InitializeComponent();
}
}

View File

@@ -0,0 +1,31 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Windows.Data;
using ImageResizer.Models;
using ImageResizer.Properties;
namespace ImageResizer.Views
{
[ValueConversion(typeof(ResizeUnit), typeof(string))]
internal class ResizeUnitConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var output = Resources.ResourceManager.GetString(Enum.GetName(typeof(ResizeUnit), value));
if ((string)parameter == "ToLower")
{
output = output.ToLower(culture);
}
return output;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,44 @@
<UserControl x:Class="ImageResizer.Views.ResultsPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:p="clr-namespace:ImageResizer.Properties"
MinWidth="350">
<StackPanel>
<TextBlock Margin="11,11,11,0"
Style="{StaticResource MainInstructionTextBlockStyle}"
Text="{x:Static p:Resources.Results_MainInstruction}"/>
<ScrollViewer MaxWidth="363"
MaxHeight="350"
HorizontalAlignment="Stretch"
VerticalScrollBarVisibility="Auto">
<ItemsControl Margin="11,4,11,0" ItemsSource="{Binding Errors}">
<ItemsControl.ItemTemplate>
<DataTemplate DataType="ResizeError">
<StackPanel>
<TextBlock Margin="0,7,0,0"
FontWeight="Bold"
Text="{Binding File}"/>
<TextBlock Text="{Binding Error}" TextWrapping="Wrap"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
<Border Margin="0,11,0,0"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}"
BorderBrush="{DynamicResource {x:Static SystemColors.ControlLightBrushKey}}"
BorderThickness="0,1,0,0"
Padding="11,11">
<StackPanel HorizontalAlignment="Right" Orientation="Horizontal">
<Button Height="23"
MinWidth="75"
Command="{Binding CloseCommand}"
Content="{x:Static p:Resources.Results_Close}"
IsCancel="True"
IsDefault="True"/>
</StackPanel>
</Border>
</StackPanel>
</UserControl>

View File

@@ -0,0 +1,14 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System.Windows.Controls;
namespace ImageResizer.Views
{
public partial class ResultsPage : UserControl
{
public ResultsPage()
=> InitializeComponent();
}
}

View File

@@ -0,0 +1,23 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media.Imaging;
using ImageResizer.Properties;
namespace ImageResizer.Views
{
[ValueConversion(typeof(TiffCompressOption), typeof(string))]
internal class TiffCompressOptionConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
=> Resources.ResourceManager.GetString(
"TiffCompressOption_" + Enum.GetName(typeof(TiffCompressOption), value));
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}

View File

@@ -0,0 +1,48 @@
// Copyright (c) Brice Lambson
// The Brice Lambson licenses this file to you under the MIT license.
// See the LICENSE file in the project root for more information. Code forked from Brice Lambson's https://github.com/bricelam/ImageResizer/
using System;
using System.Globalization;
using System.Text;
using System.Windows.Data;
using ImageResizer.Properties;
namespace ImageResizer.Views
{
[ValueConversion(typeof(TimeSpan), typeof(string))]
internal class TimeRemainingConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
var timeRemaining = (TimeSpan)value;
var builder = new StringBuilder("Progress_TimeRemaining_");
if (timeRemaining.Hours != 0)
{
builder.Append(timeRemaining.Hours == 1 ? "Hour" : "Hours");
}
if (timeRemaining.Hours != 0 || timeRemaining.Minutes > 0)
{
builder.Append(timeRemaining.Minutes == 1 ? "Minute" : "Minutes");
}
if (timeRemaining.Hours == 0)
{
builder.Append(timeRemaining.Seconds == 1 ? "Second" : "Seconds");
}
return string.Format(
culture,
Resources.ResourceManager.GetString(builder.ToString()),
timeRemaining.Hours,
timeRemaining.Minutes,
timeRemaining.Seconds);
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
=> throw new NotImplementedException();
}
}