Working on the external command destination, fixed some csproj files.

This commit is contained in:
Robin 2018-06-03 00:29:03 +02:00
commit fe4859817a
23 changed files with 446 additions and 1009 deletions

View file

@ -29,6 +29,9 @@ using Greenshot.Addons.ViewModels;
namespace Greenshot.Addon.Dropbox.ViewModels
{
/// <summary>
/// This defines the view model for the dropbox configuration
/// </summary>
public sealed class DropboxConfigViewModel : SimpleConfigScreen
{
/// <summary>

View file

@ -0,0 +1,80 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System;
namespace Greenshot.Addon.ExternalCommand.Entities
{
/// <summary>
/// This enum specifies behavior of how the external command is called
/// </summary>
[Flags]
public enum CommandBehaviors
{
/// <summary>
/// Just export and call the command, ignore everything else
/// </summary>
None,
/// <summary>
/// Remove the export if the command finishes, this implicitly means the command is awaited
/// </summary>
DeleteOnExit,
/// <summary>
/// Look at the return code, if this is an error the export fails and might be offered again (destination picker)
/// </summary>
ProcessReturncode,
/// <summary>
/// Scan the output for Uris
/// These are than available in the export information
/// </summary>
ParseOutputForUris,
/// <summary>
/// Show the standard error output in the greenshot log as warnings
/// </summary>
ShowErrorOutputInLog,
/// <summary>
/// Show the standard output in the greenshot log
/// </summary>
ShowStandardOutputInLog,
/// <summary>
/// Copy the output to the clipboard
/// </summary>
OutputToClipboard,
/// <summary>
/// Copy any uris to the clipboard
/// </summary>
UriToClipboard,
/// <summary>
/// This is the default
/// </summary>
Default = DeleteOnExit | ParseOutputForUris | ProcessReturncode | ShowErrorOutputInLog |ShowStandardOutputInLog | UriToClipboard
}
}

View file

@ -0,0 +1,48 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
namespace Greenshot.Addon.ExternalCommand.Entities
{
public class ExternalCommandDefinition
{
/// <summary>
/// Name of the command
/// </summary>
public string Name { get; set; }
/// <summary>
/// The command itself
/// </summary>
public string Command { get; set; }
/// <summary>
/// The arguments for the command
/// </summary>
public string Arguments { get; set; }
/// <summary>
/// The behavior or mode of the command
/// </summary>
public CommandBehaviors CommandBehavior { get; set; } = CommandBehaviors.Default;
}
}

View file

@ -43,7 +43,10 @@ namespace Greenshot.Addon.ExternalCommand
.RegisterType<ExternalCommandConfigViewModel>()
.As<IConfigScreen>()
.SingleInstance();
builder
.RegisterType<ExternalCommandMasterViewModel>()
.AsSelf()
.SingleInstance();
base.Load(builder);
}

View file

@ -23,10 +23,14 @@
using System;
using System.IO;
using Greenshot.Addon.ExternalCommand.Entities;
using Greenshot.Addons.Core;
namespace Greenshot.Addon.ExternalCommand
{
/// <summary>
/// Helper extensions for the external command configuration
/// </summary>
public static class ExternalCommandConfigurationExtensions
{
private const string MsPaint = "MS Paint";
@ -59,6 +63,57 @@ namespace Greenshot.Addon.ExternalCommand
}
}
/// <summary>
/// Read a definition
/// </summary>
/// <param name="externalCommandConfiguration">IExternalCommandConfiguration</param>
/// <param name="command">string</param>
/// <returns>ExternalCommandDefinition</returns>
public static ExternalCommandDefinition Read(this IExternalCommandConfiguration externalCommandConfiguration,
string command)
{
var definition = new ExternalCommandDefinition
{
Name = command,
Command = externalCommandConfiguration.Commandline[command]
};
if (externalCommandConfiguration.Argument.ContainsKey(command))
{
definition.Arguments = externalCommandConfiguration.Argument[command];
}
if (externalCommandConfiguration.Behaviors.ContainsKey(command))
{
definition.CommandBehavior = externalCommandConfiguration.Behaviors[command];
}
// Convert old values
if (externalCommandConfiguration.RunInbackground.ContainsKey(command))
{
var runInBackground = externalCommandConfiguration.RunInbackground[command];
if (runInBackground)
{
definition.CommandBehavior |= CommandBehaviors.DeleteOnExit | CommandBehaviors.ProcessReturncode;
}
}
return definition;
}
/// <summary>
/// Read a definition
/// </summary>
/// <param name="externalCommandConfiguration">IExternalCommandConfiguration</param>
/// <param name="definition">ExternalCommandDefinition</param>
public static void Write(this IExternalCommandConfiguration externalCommandConfiguration, ExternalCommandDefinition definition)
{
externalCommandConfiguration.Delete(definition.Name);
externalCommandConfiguration.Commands.Add(definition.Name);
externalCommandConfiguration.Commandline[definition.Name] = definition.Command;
externalCommandConfiguration.Argument[definition.Name] = definition.Arguments;
externalCommandConfiguration.Behaviors[definition.Name] = definition.CommandBehavior;
}
/// <summary>
/// Delete the configuration for the specified command
/// </summary>
@ -73,6 +128,7 @@ namespace Greenshot.Addon.ExternalCommand
configuration.Commands.Remove(command);
configuration.Commandline.Remove(command);
configuration.Argument.Remove(command);
configuration.Behaviors.Remove(command);
configuration.RunInbackground.Remove(command);
if (!MsPaint.Equals(command) && !PaintDotNet.Equals(command))
{
@ -95,9 +151,9 @@ namespace Greenshot.Addon.ExternalCommand
if (HasPaint && !configuration.Commands.Contains(MsPaint) && !configuration.DeletedBuildInCommands.Contains(MsPaint))
{
configuration.Commands.Add(MsPaint);
configuration.Commandline.Add(MsPaint, PaintPath);
configuration.Argument.Add(MsPaint, "\"{0}\"");
configuration.RunInbackground.Add(MsPaint, true);
configuration.Commandline[MsPaint] = PaintPath;
configuration.Argument[MsPaint] = "\"{0}\"";
configuration.Behaviors[MsPaint] = CommandBehaviors.Default;
}
// Check if we need to add Paint.NET
@ -108,9 +164,9 @@ namespace Greenshot.Addon.ExternalCommand
}
configuration.Commands.Add(PaintDotNet);
configuration.Commandline.Add(PaintDotNet, PaintDotNetPath);
configuration.Argument.Add(PaintDotNet, "\"{0}\"");
configuration.RunInbackground.Add(PaintDotNet, true);
configuration.Commandline[PaintDotNet] = PaintDotNetPath;
configuration.Argument[PaintDotNet] = "\"{0}\"";
configuration.Behaviors[PaintDotNet] = CommandBehaviors.Default;
}
}
}

View file

@ -28,13 +28,19 @@ using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using CliWrap;
using CliWrap.Models;
using Dapplo.Ini;
using Dapplo.Log;
using Greenshot.Addon.ExternalCommand.Entities;
using Greenshot.Addons;
using Greenshot.Addons.Components;
using Greenshot.Addons.Core;
using Greenshot.Addons.Extensions;
using Greenshot.Addons.Interfaces;
using Greenshot.Addons.Interfaces.Plugin;
@ -54,13 +60,16 @@ namespace Greenshot.Addon.ExternalCommand
private static readonly IExternalCommandConfiguration Config = IniConfig.Current.Get<IExternalCommandConfiguration>();
private readonly string _presetCommand;
private readonly IExternalCommandConfiguration _externalCommandConfiguration;
public ExternalCommandDestination(string commando,
IExternalCommandConfiguration externalCommandConfiguration,
ICoreConfiguration coreConfiguration,
IGreenshotLanguage greenshotLanguage
) : base(coreConfiguration, greenshotLanguage)
{
_presetCommand = commando;
_externalCommandConfiguration = externalCommandConfiguration;
}
public override string Designation => "External " + _presetCommand.Replace(',', '_');
@ -72,218 +81,43 @@ namespace Greenshot.Addon.ExternalCommand
return IconCache.IconForCommand(_presetCommand, dpi > 100);
}
public override IEnumerable<IDestination> DynamicDestinations()
{
yield break;
}
protected override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
public override async Task<ExportInformation> ExportCaptureAsync(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails)
{
var exportInformation = new ExportInformation(Designation, Description);
var outputSettings = new SurfaceOutputSettings();
outputSettings.PreventGreenshotFormat();
if (_presetCommand == null)
{
return exportInformation;
}
if (!Config.RunInbackground.ContainsKey(_presetCommand))
{
Config.RunInbackground.Add(_presetCommand, true);
}
var runInBackground = Config.RunInbackground[_presetCommand];
var definition = _externalCommandConfiguration.Read(_presetCommand);
var fullPath = captureDetails.Filename;
if (fullPath == null)
{
fullPath = ImageOutput.SaveNamedTmpFile(surface, captureDetails, outputSettings);
fullPath = surface.SaveNamedTmpFile(CoreConfiguration, _externalCommandConfiguration);
}
if (runInBackground)
using (var cli = new Cli(definition.Command))
{
var commandThread = new Thread(() =>
var arguments = string.Format(definition.Arguments, fullPath);
// Execute
var output = await cli.ExecuteAsync(arguments);
if (definition.CommandBehavior.HasFlag(CommandBehaviors.ParseOutputForUris))
{
CallExternalCommand(exportInformation, fullPath, out _, out _);
ProcessExport(exportInformation, surface);
})
var uriMatches = UriRegexp.Matches(output.StandardOutput);
if (uriMatches.Count > 0)
{
Name = "Running " + _presetCommand,
IsBackground = true
};
commandThread.SetApartmentState(ApartmentState.STA);
commandThread.Start();
exportInformation.ExportMade = true;
exportInformation.Uri = uriMatches[0].Groups[1].Value;
ClipboardHelper.SetClipboardData(output.StandardOutput);
}
else
{
CallExternalCommand(exportInformation, fullPath, out _, out _);
ProcessExport(exportInformation, surface);
}
if (definition.CommandBehavior.HasFlag(CommandBehaviors.DeleteOnExit))
{
File.Delete(fullPath);
}
}
ProcessExport(exportInformation, surface);
return exportInformation;
}
/// <summary>
/// Wrapper method for the background and normal call, this does all the logic:
/// Call the external command, parse for URI, place to clipboard and set the export information
/// </summary>
/// <param name="exportInformation"></param>
/// <param name="fullPath"></param>
/// <param name="output"></param>
/// <param name="error"></param>
private void CallExternalCommand(ExportInformation exportInformation, string fullPath, out string output, out string error)
{
output = null;
error = null;
try
{
if (CallExternalCommand(_presetCommand, fullPath, out output, out error) == 0)
{
exportInformation.ExportMade = true;
if (string.IsNullOrEmpty(output))
{
return;
}
var uriMatches = UriRegexp.Matches(output);
// Place output on the clipboard before the URI, so if one is found this overwrites
if (Config.OutputToClipboard)
{
ClipboardHelper.SetClipboardData(output);
}
if (uriMatches.Count <= 0)
{
return;
}
exportInformation.Uri = uriMatches[0].Groups[1].Value;
Log.Info().WriteLine("Got URI : {0} ", exportInformation.Uri);
if (Config.UriToClipboard)
{
ClipboardHelper.SetClipboardData(exportInformation.Uri);
}
}
else
{
Log.Warn().WriteLine("Error calling external command: {0} ", output);
exportInformation.ExportMade = false;
exportInformation.ErrorMessage = error;
}
}
catch (Exception ex)
{
exportInformation.ExportMade = false;
exportInformation.ErrorMessage = ex.Message;
Log.Warn().WriteLine("Error calling external command: {0} ", exportInformation.ErrorMessage);
}
}
/// <summary>
/// Wrapper to retry with a runas
/// </summary>
/// <param name="commando"></param>
/// <param name="fullPath"></param>
/// <param name="output"></param>
/// <param name="error"></param>
/// <returns></returns>
private int CallExternalCommand(string commando, string fullPath, out string output, out string error)
{
try
{
return CallExternalCommand(commando, fullPath, null, out output, out error);
}
catch (Win32Exception w32Ex)
{
try
{
return CallExternalCommand(commando, fullPath, "runas", out output, out error);
}
catch
{
w32Ex.Data.Add("commandline", Config.Commandline[_presetCommand]);
w32Ex.Data.Add("arguments", Config.Argument[_presetCommand]);
throw;
}
}
catch (Exception ex)
{
ex.Data.Add("commandline", Config.Commandline[_presetCommand]);
ex.Data.Add("arguments", Config.Argument[_presetCommand]);
throw;
}
}
/// <summary>
/// The actual executing code for the external command
/// </summary>
/// <param name="commando"></param>
/// <param name="fullPath"></param>
/// <param name="verb"></param>
/// <param name="output"></param>
/// <param name="error"></param>
/// <returns></returns>
private static int CallExternalCommand(string commando, string fullPath, string verb, out string output, out string error)
{
var commandline = Config.Commandline[commando];
var arguments = Config.Argument[commando];
output = null;
error = null;
if (string.IsNullOrEmpty(commandline))
{
return -1;
}
using (var process = new Process())
{
// Fix variables
commandline = FilenameHelper.FillVariables(commandline, true);
commandline = FilenameHelper.FillCmdVariables(commandline);
arguments = FilenameHelper.FillVariables(arguments, false);
arguments = FilenameHelper.FillCmdVariables(arguments, false);
process.StartInfo.FileName = FilenameHelper.FillCmdVariables(commandline);
process.StartInfo.Arguments = FormatArguments(arguments, fullPath);
process.StartInfo.UseShellExecute = false;
if (Config.RedirectStandardOutput)
{
process.StartInfo.RedirectStandardOutput = true;
}
if (Config.RedirectStandardError)
{
process.StartInfo.RedirectStandardError = true;
}
if (verb != null)
{
process.StartInfo.Verb = verb;
}
Log.Info().WriteLine("Starting : {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
process.Start();
process.WaitForExit();
if (Config.RedirectStandardOutput)
{
output = process.StandardOutput.ReadToEnd();
if (Config.ShowStandardOutputInLog && output.Trim().Length > 0)
{
Log.Info().WriteLine("Output:\n{0}", output);
}
}
if (Config.RedirectStandardError)
{
error = process.StandardError.ReadToEnd();
if (error.Trim().Length > 0)
{
Log.Warn().WriteLine("Error:\n{0}", error);
}
}
Log.Info().WriteLine("Finished : {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
return process.ExitCode;
}
}
public static string FormatArguments(string arguments, string fullpath)
{
return string.Format(arguments, fullpath);
}
}
}

View file

@ -62,7 +62,7 @@ namespace Greenshot.Addon.ExternalCommand
public IEnumerable<Lazy<IDestination, DestinationAttribute>> Provide()
{
return _externalCommandConfig.Commands
.Select(command => new Lazy<IDestination, DestinationAttribute>(() => new ExternalCommandDestination(command, _coreConfiguration, _greenshotLanguage), new DestinationAttribute(command)));
.Select(command => new Lazy<IDestination, DestinationAttribute>(() => new ExternalCommandDestination(command, _externalCommandConfig, _coreConfiguration, _greenshotLanguage), new DestinationAttribute(command)));
}
@ -108,6 +108,8 @@ namespace Greenshot.Addon.ExternalCommand
{
_externalCommandConfig.Delete(command);
}
_externalCommandConfig.AfterLoad();
}
}
}

View file

@ -55,6 +55,9 @@
<Reference Include="Caliburn.Micro.Platform.Core, Version=3.2.0.0, Culture=neutral, PublicKeyToken=8e5891231f2ed21f, processorArchitecture=MSIL">
<HintPath>..\packages\Caliburn.Micro.3.2.0\lib\net45\Caliburn.Micro.Platform.Core.dll</HintPath>
</Reference>
<Reference Include="CliWrap, Version=1.8.4.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\CliWrap.1.8.4\lib\net45\CliWrap.dll</HintPath>
</Reference>
<Reference Include="CommonServiceLocator, Version=2.0.3.0, Culture=neutral, PublicKeyToken=489b6accfaf20ef0, processorArchitecture=MSIL">
<HintPath>..\packages\CommonServiceLocator.2.0.3\lib\net45\CommonServiceLocator.dll</HintPath>
</Reference>
@ -147,6 +150,8 @@
<Reference Include="WindowsBase" />
</ItemGroup>
<ItemGroup>
<Compile Include="Entities\CommandBehaviors.cs" />
<Compile Include="Entities\ExternalCommandDefinition.cs" />
<Compile Include="ExternalCommandConfigurationExtensions.cs" />
<Compile Include="ExternalCommandDestination.cs" />
<Compile Include="ExternalCommandDestinationProvider.cs" />
@ -156,19 +161,9 @@
<Compile Include="ListviewComparer.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="IExternalCommandConfiguration.cs" />
<Compile Include="SettingsForm.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
<Compile Include="SettingsFormDetail.cs">
<SubType>Form</SubType>
</Compile>
<Compile Include="SettingsFormDetail.Designer.cs">
<DependentUpon>SettingsFormDetail.cs</DependentUpon>
</Compile>
<Compile Include="ViewModels\ExternalCommandConfigViewModel.cs" />
<Compile Include="ViewModels\ExternalCommandDetailsViewModel.cs" />
<Compile Include="ViewModels\ExternalCommandMasterViewModel.cs" />
<None Include="app.config" />
<None Include="Languages\language_externalcommandplugin-en-US.xml" />
<None Include="packages.config" />
@ -207,10 +202,19 @@
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="Views\ExternalCommandDetailsView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Views\ExternalCommandMasterView.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>mkdir "$(SolutionDir)Greenshot\bin\$(Configuration)\Addons"
copy "$(ProjectDir)bin\$(Configuration)\$(ProjectName).dll" "$(SolutionDir)Greenshot\bin\$(Configuration)\Addons\"
copy "$(ProjectDir)bin\$(Configuration)\CliWrap.dll" "$(SolutionDir)Greenshot\bin\$(Configuration)\Addons\"
copy "$(ProjectDir)bin\$(Configuration)\$(ProjectName).pdb" "$(SolutionDir)Greenshot\bin\$(Configuration)\Addons\"
mkdir "$(SolutionDir)Greenshot\bin\$(Configuration)\Languages\$(ProjectName)"
copy "$(ProjectDir)\Languages\*.xml" "$(SolutionDir)Greenshot\bin\$(Configuration)\Languages\$(ProjectName)"</PostBuildEvent>

View file

@ -27,6 +27,8 @@ using System.Collections.Generic;
using System.ComponentModel;
using Dapplo.Ini;
using Dapplo.InterfaceImpl.Extensions;
using Greenshot.Addon.ExternalCommand.Entities;
using Greenshot.Addons.Core;
#endregion
@ -37,44 +39,23 @@ namespace Greenshot.Addon.ExternalCommand
/// </summary>
[IniSection("ExternalCommand")]
[Description("Greenshot ExternalCommand Plugin configuration")]
public interface IExternalCommandConfiguration : IIniSection, ITransactionalProperties, INotifyPropertyChanged
public interface IExternalCommandConfiguration : IIniSection, IDestinationFileConfiguration, ITransactionalProperties, INotifyPropertyChanged
{
[Description("The commands that are available.")]
IList<string> Commands { get; set; }
[Description("Redirect the standard error of all external commands, used to output as warning to the greenshot.log.")]
[DefaultValue(true)]
bool RedirectStandardError { get; set; }
[Description("Redirect the standard output of all external commands, used for different other functions (more below).")]
[DefaultValue(true)]
bool RedirectStandardOutput { get; set; }
[Description("Depends on 'RedirectStandardOutput': Show standard output of all external commands to the Greenshot log, this can be usefull for debugging.")]
[DefaultValue(false)]
bool ShowStandardOutputInLog { get; set; }
[Description("Depends on 'RedirectStandardOutput': Parse the output and take the first found URI, if a URI is found than clicking on the notify bubble goes there.")]
[DefaultValue(true)]
bool ParseOutputForUri { get; set; }
[Description("Depends on 'RedirectStandardOutput': Place the standard output on the clipboard.")]
[DefaultValue(false)]
bool OutputToClipboard { get; set; }
[Description("Depends on 'RedirectStandardOutput' & 'ParseForUri': If an URI is found in the standard input, place it on the clipboard. (This overwrites the output from OutputToClipboard setting.)")]
[DefaultValue(true)]
bool UriToClipboard { get; set; }
[Description("The commandline for the output command.")]
IDictionary<string, string> Commandline { get; set; }
[Description("The arguments for the output command.")]
IDictionary<string, string> Argument { get; set; }
[Description("Should the command be started in the background.")]
[Description("Should the command be started in the background. (obsolete)")]
IDictionary<string, bool> RunInbackground { get; set; }
[Description("Command behaviors.")]
IDictionary<string, CommandBehaviors> Behaviors { get; set; }
[Description("If a build in command was deleted manually, it should not be recreated.")]
IList<string> DeletedBuildInCommands { get; set; }
}

View file

@ -1,161 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Greenshot.Addons.Controls;
namespace Greenshot.Addon.ExternalCommand {
partial class SettingsForm {
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
DisposeImages();
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent() {
this.buttonCancel = new GreenshotButton();
this.buttonOk = new GreenshotButton();
this.listView = new System.Windows.Forms.ListView();
this.columnHeader1 = ((System.Windows.Forms.ColumnHeader)(new System.Windows.Forms.ColumnHeader()));
this.button_new = new GreenshotButton();
this.button_delete = new GreenshotButton();
this.button_edit = new GreenshotButton();
this.SuspendLayout();
//
// buttonCancel
//
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.LanguageKey = "CANCEL";
this.buttonCancel.Location = new System.Drawing.Point(275, 144);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 11;
this.buttonCancel.UseVisualStyleBackColor = true;
//
// buttonOk
//
this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
this.buttonOk.LanguageKey = "OK";
this.buttonOk.Location = new System.Drawing.Point(275, 173);
this.buttonOk.Name = "buttonOk";
this.buttonOk.Size = new System.Drawing.Size(75, 23);
this.buttonOk.TabIndex = 10;
this.buttonOk.UseVisualStyleBackColor = true;
this.buttonOk.Click += new System.EventHandler(this.ButtonOkClick);
//
// listView1
//
this.listView.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] { this.columnHeader1});
this.listView.FullRowSelect = true;
this.listView.Location = new System.Drawing.Point(13, 13);
this.listView.MultiSelect = false;
this.listView.Name = "listView";
this.listView.Size = new System.Drawing.Size(255, 183);
this.listView.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.listView.TabIndex = 5;
this.listView.UseCompatibleStateImageBehavior = false;
this.listView.View = System.Windows.Forms.View.Details;
this.listView.SelectedIndexChanged += new System.EventHandler(this.ListView1ItemSelectionChanged);
this.listView.DoubleClick += new System.EventHandler(this.ListView1DoubleClick);
//
// columnHeader1
//
this.columnHeader1.Text = "Name";
this.columnHeader1.Width = 226;
//
// button_new
//
this.button_new.LanguageKey = "externalcommand.settings_new";
this.button_new.Location = new System.Drawing.Point(275, 13);
this.button_new.Name = "button_new";
this.button_new.Size = new System.Drawing.Size(75, 23);
this.button_new.TabIndex = 1;
this.button_new.UseVisualStyleBackColor = true;
this.button_new.Click += new System.EventHandler(this.ButtonAddClick);
//
// button_delete
//
this.button_delete.LanguageKey = "externalcommand.settings_delete";
this.button_delete.Location = new System.Drawing.Point(274, 71);
this.button_delete.Name = "button_delete";
this.button_delete.Size = new System.Drawing.Size(75, 23);
this.button_delete.TabIndex = 3;
this.button_delete.UseVisualStyleBackColor = true;
this.button_delete.Click += new System.EventHandler(this.ButtonDeleteClick);
//
// button_edit
//
this.button_edit.Enabled = false;
this.button_edit.LanguageKey = "externalcommand.settings_edit";
this.button_edit.Location = new System.Drawing.Point(275, 42);
this.button_edit.Name = "button_edit";
this.button_edit.Size = new System.Drawing.Size(75, 23);
this.button_edit.TabIndex = 2;
this.button_edit.UseVisualStyleBackColor = true;
this.button_edit.Click += new System.EventHandler(this.ButtonEditClick);
//
// SettingsForm
//
this.AcceptButton = this.buttonOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.buttonCancel;
this.ClientSize = new System.Drawing.Size(365, 208);
this.Controls.Add(this.button_edit);
this.Controls.Add(this.button_delete);
this.Controls.Add(this.button_new);
this.Controls.Add(this.listView);
this.Controls.Add(this.buttonOk);
this.Controls.Add(this.buttonCancel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.LanguageKey = "externalcommand.settings_title";
this.Name = "SettingsForm";
this.ResumeLayout(false);
}
private GreenshotButton button_edit;
private GreenshotButton button_delete;
private GreenshotButton button_new;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ListView listView;
private GreenshotButton buttonOk;
private GreenshotButton buttonCancel;
}
}

View file

@ -1,155 +0,0 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Addons.Controls;
using Greenshot.Gfx;
#endregion
namespace Greenshot.Addon.ExternalCommand
{
/// <summary>
/// External Command settings form
/// </summary>
public partial class SettingsForm : GreenshotForm
{
private readonly IExternalCommandLanguage _externalCommandLanguage;
private readonly IExternalCommandConfiguration _externalCommandConfiguration;
private readonly IList<Image> _images = new List<Image>();
public SettingsForm(IExternalCommandConfiguration externalCommandConfiguration, IExternalCommandLanguage externalCommandLanguage) : base(externalCommandLanguage)
{
_externalCommandConfiguration = externalCommandConfiguration;
_externalCommandLanguage = externalCommandLanguage;
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
AcceptButton = buttonOk;
CancelButton = buttonCancel;
UpdateView();
}
private void ButtonOkClick(object sender, EventArgs e)
{
//IniConfig.Save();
}
private void ButtonAddClick(object sender, EventArgs e)
{
var form = new SettingsFormDetail(null, _externalCommandLanguage);
form.ShowDialog();
UpdateView();
}
private void ButtonDeleteClick(object sender, EventArgs e)
{
foreach (ListViewItem item in listView.SelectedItems)
{
var commando = item.Tag as string;
_externalCommandConfiguration.Delete(commando);
}
UpdateView();
}
private void DisposeImages()
{
// Dispose all images
foreach (var image in _images)
{
image.Dispose();
}
_images.Clear();
}
private void UpdateView()
{
listView.Items.Clear();
DisposeImages();
if (_externalCommandConfiguration.Commands != null)
{
listView.ListViewItemSorter = new ListviewComparer();
var imageList = new ImageList();
listView.SmallImageList = imageList;
var imageNr = 0;
foreach (var commando in _externalCommandConfiguration.Commands)
{
ListViewItem item;
var iconForExe = IconCache.IconForCommand(commando, FormDpiHandler.Dpi > 100);
if (iconForExe != null)
{
var image = iconForExe.ScaleIconForDisplaying(FormDpiHandler.Dpi);
if (!Equals(image, iconForExe))
{
_images.Add(image);
}
imageList.Images.Add(image);
item = new ListViewItem(commando, imageNr++);
}
else
{
item = new ListViewItem(commando);
}
item.Tag = commando;
listView.Items.Add(item);
}
}
// Fix for bug #1484, getting an ArgumentOutOfRangeException as there is nothing selected but the edit button was still active.
button_edit.Enabled = listView.SelectedItems.Count > 0;
}
private void ListView1ItemSelectionChanged(object sender, EventArgs e)
{
button_edit.Enabled = listView.SelectedItems.Count > 0;
}
private void ButtonEditClick(object sender, EventArgs e)
{
ListView1DoubleClick(sender, e);
}
private void ListView1DoubleClick(object sender, EventArgs e)
{
// Safety check for bug #1484
var selectionActive = listView.SelectedItems.Count > 0;
if (!selectionActive)
{
button_edit.Enabled = false;
return;
}
var commando = listView.SelectedItems[0].Tag as string;
var form = new SettingsFormDetail(commando, _externalCommandLanguage);
form.ShowDialog();
UpdateView();
}
}
}

View file

@ -1,202 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using Greenshot.Addons.Controls;
namespace Greenshot.Addon.ExternalCommand {
partial class SettingsFormDetail {
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
base.Dispose(disposing);
}
/// <summary>
/// This method is required for Windows Forms designer support.
/// Do not change the method contents inside the source code editor. The Forms designer might
/// not be able to load this method if it was changed manually.
/// </summary>
private void InitializeComponent()
{
this.buttonOk = new GreenshotButton();
this.buttonCancel = new GreenshotButton();
this.groupBox1 = new GreenshotGroupBox();
this.label4 = new GreenshotLabel();
this.buttonPathSelect = new System.Windows.Forms.Button();
this.label3 = new GreenshotLabel();
this.textBox_name = new System.Windows.Forms.TextBox();
this.label2 = new GreenshotLabel();
this.textBox_arguments = new System.Windows.Forms.TextBox();
this.label1 = new GreenshotLabel();
this.textBox_commandline = new System.Windows.Forms.TextBox();
this.groupBox1.SuspendLayout();
this.SuspendLayout();
//
// buttonOk
//
this.buttonOk.DialogResult = System.Windows.Forms.DialogResult.OK;
this.buttonOk.Enabled = false;
this.buttonOk.LanguageKey = "OK";
this.buttonOk.Location = new System.Drawing.Point(273, 140);
this.buttonOk.Name = "buttonOk";
this.buttonOk.Size = new System.Drawing.Size(75, 23);
this.buttonOk.TabIndex = 10;
this.buttonOk.UseVisualStyleBackColor = true;
this.buttonOk.Click += new System.EventHandler(this.ButtonOkClick);
//
// buttonCancel
//
this.buttonCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.buttonCancel.LanguageKey = "CANCEL";
this.buttonCancel.Location = new System.Drawing.Point(9, 140);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 11;
this.buttonCancel.UseVisualStyleBackColor = true;
//
// groupBox1
//
this.groupBox1.Controls.Add(this.label4);
this.groupBox1.Controls.Add(this.buttonPathSelect);
this.groupBox1.Controls.Add(this.label3);
this.groupBox1.Controls.Add(this.textBox_name);
this.groupBox1.Controls.Add(this.label2);
this.groupBox1.Controls.Add(this.textBox_arguments);
this.groupBox1.Controls.Add(this.label1);
this.groupBox1.Controls.Add(this.textBox_commandline);
this.groupBox1.LanguageKey = "settings_title";
this.groupBox1.Location = new System.Drawing.Point(10, 12);
this.groupBox1.Name = "groupBox1";
this.groupBox1.Size = new System.Drawing.Size(339, 122);
this.groupBox1.TabIndex = 28;
this.groupBox1.TabStop = false;
//
// label4
//
this.label4.LanguageKey = "externalcommand.label_information";
this.label4.Location = new System.Drawing.Point(68, 98);
this.label4.Name = "label4";
this.label4.Size = new System.Drawing.Size(225, 21);
this.label4.TabIndex = 19;
//
// buttonPathSelect
//
this.buttonPathSelect.Location = new System.Drawing.Point(298, 47);
this.buttonPathSelect.Name = "buttonPathSelect";
this.buttonPathSelect.Size = new System.Drawing.Size(33, 23);
this.buttonPathSelect.TabIndex = 3;
this.buttonPathSelect.Text = "...";
this.buttonPathSelect.UseVisualStyleBackColor = true;
this.buttonPathSelect.Click += new System.EventHandler(this.Button3Click);
//
// label3
//
this.label3.LanguageKey = "externalcommand.label_name";
this.label3.Location = new System.Drawing.Point(6, 26);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(56, 17);
this.label3.TabIndex = 17;
//
// textBox_name
//
this.textBox_name.Location = new System.Drawing.Point(68, 23);
this.textBox_name.Name = "textBox_name";
this.textBox_name.Size = new System.Drawing.Size(225, 20);
this.textBox_name.TabIndex = 1;
this.textBox_name.TextChanged += new System.EventHandler(this.textBox_name_TextChanged);
//
// label2
//
this.label2.LanguageKey = "externalcommand.label_argument";
this.label2.Location = new System.Drawing.Point(6, 78);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(56, 17);
this.label2.TabIndex = 16;
//
// textBox_arguments
//
this.textBox_arguments.Location = new System.Drawing.Point(68, 75);
this.textBox_arguments.Name = "textBox_arguments";
this.textBox_arguments.Size = new System.Drawing.Size(225, 20);
this.textBox_arguments.TabIndex = 4;
this.textBox_arguments.TextChanged += new System.EventHandler(this.textBox_arguments_TextChanged);
//
// label1
//
this.label1.LanguageKey = "externalcommand.label_command";
this.label1.Location = new System.Drawing.Point(6, 52);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 17);
this.label1.TabIndex = 15;
//
// textBox_commandline
//
this.textBox_commandline.Location = new System.Drawing.Point(68, 49);
this.textBox_commandline.Name = "textBox_commandline";
this.textBox_commandline.Size = new System.Drawing.Size(225, 20);
this.textBox_commandline.TabIndex = 2;
this.textBox_commandline.TextChanged += new System.EventHandler(this.textBox_commandline_TextChanged);
//
// SettingsFormDetail
//
this.AcceptButton = this.buttonOk;
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackgroundImageLayout = System.Windows.Forms.ImageLayout.None;
this.CancelButton = this.buttonCancel;
this.ClientSize = new System.Drawing.Size(360, 172);
this.Controls.Add(this.groupBox1);
this.Controls.Add(this.buttonOk);
this.Controls.Add(this.buttonCancel);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.LanguageKey = "externalcommand.settings_detail_title";
this.Name = "SettingsFormDetail";
this.groupBox1.ResumeLayout(false);
this.groupBox1.PerformLayout();
this.ResumeLayout(false);
}
private GreenshotLabel label1;
private GreenshotLabel label2;
private GreenshotLabel label3;
private GreenshotLabel label4;
private GreenshotGroupBox groupBox1;
private GreenshotButton buttonCancel;
private GreenshotButton buttonOk;
private System.Windows.Forms.TextBox textBox_commandline;
private System.Windows.Forms.TextBox textBox_arguments;
private System.Windows.Forms.TextBox textBox_name;
private System.Windows.Forms.Button buttonPathSelect;
}
}

View file

@ -1,195 +0,0 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
#region Usings
using System;
using System.Drawing;
using System.IO;
using System.Linq;
using System.Windows.Forms;
using Dapplo.Ini;
using Dapplo.Log;
using Greenshot.Addons.Controls;
using Greenshot.Addons.Core;
#endregion
namespace Greenshot.Addon.ExternalCommand
{
/// <summary>
/// Description of SettingsFormDetail.
/// </summary>
public partial class SettingsFormDetail : GreenshotForm
{
private static readonly LogSource Log = new LogSource();
private static readonly IExternalCommandConfiguration ExternalCommandConfig = IniConfig.Current.Get<IExternalCommandConfiguration>();
private readonly int _commandIndex;
private readonly string _commando;
public SettingsFormDetail(string commando, IExternalCommandLanguage externalCommandLanguage): base(externalCommandLanguage)
{
InitializeComponent();
AcceptButton = buttonOk;
CancelButton = buttonCancel;
_commando = commando;
if (commando != null)
{
textBox_name.Text = commando;
textBox_commandline.Text = ExternalCommandConfig.Commandline[commando];
textBox_arguments.Text = ExternalCommandConfig.Argument[commando];
_commandIndex = ExternalCommandConfig.Commands.ToList().FindIndex(s => s == commando);
}
else
{
textBox_arguments.Text = @"""{0}""";
}
OkButtonState();
}
private void ButtonOkClick(object sender, EventArgs e)
{
var commandName = textBox_name.Text;
var commandLine = textBox_commandline.Text;
var arguments = textBox_arguments.Text;
if (_commando != null)
{
ExternalCommandConfig.Commands[_commandIndex] = commandName;
ExternalCommandConfig.Commandline.Remove(_commando);
ExternalCommandConfig.Commandline.Add(commandName, commandLine);
ExternalCommandConfig.Argument.Remove(_commando);
ExternalCommandConfig.Argument.Add(commandName, arguments);
}
else
{
ExternalCommandConfig.Commands.Add(commandName);
ExternalCommandConfig.Commandline.Add(commandName, commandLine);
ExternalCommandConfig.Argument.Add(commandName, arguments);
}
}
private void Button3Click(object sender, EventArgs e)
{
var openFileDialog = new OpenFileDialog
{
Filter = "Executables (*.exe, *.bat, *.com)|*.exe; *.bat; *.com|All files (*)|*",
FilterIndex = 1,
CheckFileExists = true,
Multiselect = false
};
string initialPath = null;
try
{
initialPath = Path.GetDirectoryName(textBox_commandline.Text);
}
catch (Exception ex)
{
Log.Warn().WriteLine("Can't get the initial path via {0}", textBox_commandline.Text);
Log.Warn().WriteLine(ex, "Exception: ");
}
if (initialPath != null && Directory.Exists(initialPath))
{
openFileDialog.InitialDirectory = initialPath;
}
else
{
initialPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
openFileDialog.InitialDirectory = initialPath;
}
Log.Debug().WriteLine("Starting OpenFileDialog at {0}", initialPath);
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
textBox_commandline.Text = openFileDialog.FileName;
}
}
private void OkButtonState()
{
// Assume OK
buttonOk.Enabled = true;
textBox_name.BackColor = Color.White;
textBox_commandline.BackColor = Color.White;
textBox_arguments.BackColor = Color.White;
// Is there a text in the name field
if (string.IsNullOrEmpty(textBox_name.Text))
{
buttonOk.Enabled = false;
}
// Check if commandname is unique
if (_commando == null && !string.IsNullOrEmpty(textBox_name.Text) && ExternalCommandConfig.Commands.Contains(textBox_name.Text))
{
buttonOk.Enabled = false;
textBox_name.BackColor = Color.Red;
}
// Is there a text in the commandline field
if (string.IsNullOrEmpty(textBox_commandline.Text))
{
buttonOk.Enabled = false;
}
if (!string.IsNullOrEmpty(textBox_commandline.Text))
{
// Added this to be more flexible, using the Greenshot var format
var cmdPath = FilenameHelper.FillVariables(textBox_commandline.Text, true);
// And also replace the "DOS" Variables
cmdPath = FilenameHelper.FillCmdVariables(cmdPath, true);
// Is the command available?
if (!File.Exists(cmdPath))
{
buttonOk.Enabled = false;
textBox_commandline.BackColor = Color.Red;
}
}
// Are the arguments in a valid format?
try
{
var arguments = FilenameHelper.FillVariables(textBox_arguments.Text, false);
arguments = FilenameHelper.FillCmdVariables(arguments, false);
ExternalCommandDestination.FormatArguments(arguments, string.Empty);
}
catch
{
buttonOk.Enabled = false;
textBox_arguments.BackColor = Color.Red;
}
}
private void textBox_name_TextChanged(object sender, EventArgs e)
{
OkButtonState();
}
private void textBox_commandline_TextChanged(object sender, EventArgs e)
{
OkButtonState();
}
private void textBox_arguments_TextChanged(object sender, EventArgs e)
{
OkButtonState();
}
}
}

View file

@ -26,6 +26,7 @@ using Dapplo.CaliburnMicro.Configuration;
using Dapplo.CaliburnMicro.Extensions;
using Greenshot.Addons;
using Greenshot.Addons.Core;
using Greenshot.Addons.ViewModels;
namespace Greenshot.Addon.ExternalCommand.ViewModels
{
@ -42,18 +43,26 @@ namespace Greenshot.Addon.ExternalCommand.ViewModels
public IGreenshotLanguage GreenshotLanguage { get; }
public FileConfigPartViewModel FileConfigPartViewModel { get; private set; }
public ExternalCommandMasterViewModel ExternalCommandMasterViewModel { get; }
public ExternalCommandConfigViewModel(
IExternalCommandConfiguration externalCommandConfiguration,
IExternalCommandLanguage externalCommandLanguage,
IGreenshotLanguage greenshotLanguage)
IGreenshotLanguage greenshotLanguage,
FileConfigPartViewModel fileConfigPartViewModel,
ExternalCommandMasterViewModel externalCommandMasterViewModel)
{
ExternalCommandConfiguration = externalCommandConfiguration;
ExternalCommandLanguage = externalCommandLanguage;
GreenshotLanguage = greenshotLanguage;
FileConfigPartViewModel = fileConfigPartViewModel;
ExternalCommandMasterViewModel = externalCommandMasterViewModel;
}
public override void Initialize(IConfig config)
{
FileConfigPartViewModel.DestinationFileConfiguration = ExternalCommandConfiguration;
// Prepare disposables
_disposables?.Dispose();
_disposables = new CompositeDisposable();

View file

@ -0,0 +1,44 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using Caliburn.Micro;
using Greenshot.Addon.ExternalCommand.Entities;
namespace Greenshot.Addon.ExternalCommand.ViewModels
{
/// <summary>
/// This is used to display the external command settings
/// </summary>
public class ExternalCommandDetailsViewModel : Screen
{
/// <summary>
/// The definition to show the details of or edit
/// </summary>
public ExternalCommandDefinition Definition { get; }
public ExternalCommandDetailsViewModel(ExternalCommandDefinition definition)
{
Definition = definition;
}
}
}

View file

@ -0,0 +1,43 @@
#region Greenshot GNU General Public License
// Greenshot - a free and open source screenshot tool
// Copyright (C) 2007-2018 Thomas Braun, Jens Klingen, Robin Krom
//
// For more information see: http://getgreenshot.org/
// The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 1 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <http://www.gnu.org/licenses/>.
#endregion
using System.Linq;
using Caliburn.Micro;
namespace Greenshot.Addon.ExternalCommand.ViewModels
{
/// <summary>
/// This is the master view of the external command config editor
/// </summary>
public class ExternalCommandMasterViewModel : Conductor<IScreen>.Collection.OneActive
{
public ExternalCommandMasterViewModel(IExternalCommandConfiguration externalCommandConfiguration)
{
var items = externalCommandConfiguration.Commands
.Select(externalCommandConfiguration.Read)
.Select(definition => new ExternalCommandDetailsViewModel(definition));
Items.AddRange(items);
}
}
}

View file

@ -7,10 +7,12 @@
mc:Ignorable="d"
d:DataContext="{d:DesignInstance viewModels:ExternalCommandConfigViewModel,IsDesignTimeCreatable=False}"
>
<StackPanel>
<GroupBox Header="{Binding ExternalCommandLanguage.SettingsTitle}">
<StackPanel>
<ContentControl x:Name="FileConfigPartViewModel"/>
<ContentControl x:Name="ExternalCommandMasterViewModel"/>
</StackPanel>
</GroupBox>
</StackPanel>
</UserControl>

View file

@ -0,0 +1,14 @@
<UserControl x:Class="Greenshot.Addon.ExternalCommand.Views.ExternalCommandDetailsView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:Greenshot.Addon.ExternalCommand.Views"
xmlns:cal="http://www.caliburnproject.org"
xmlns:viewModels="clr-namespace:Greenshot.Addon.ExternalCommand.ViewModels"
d:DataContext="{d:DesignInstance viewModels:ExternalCommandDetailsViewModel,IsDesignTimeCreatable=False}"
mc:Ignorable="d">
<StackPanel>
<Label></Label>
</StackPanel>
</UserControl>

View file

@ -0,0 +1,14 @@
<UserControl x:Class="Greenshot.Addon.ExternalCommand.Views.ExternalCommandMasterView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:Greenshot.Addon.ExternalCommand.Views"
xmlns:cal="http://www.caliburnproject.org"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800">
<StackPanel>
<ListBox x:Name="Items" cal:Message.Attach="[Event SelectionChanged]=[Action ActivateChildView($this.SelectedItem)]"/>
<ContentControl Name="ActiveItem"/>
</StackPanel>
</UserControl>

View file

@ -5,6 +5,7 @@
<package id="Autofac.Mef" version="4.0.0" targetFramework="net46" />
<package id="Caliburn.Micro" version="3.2.0" targetFramework="net46" />
<package id="Caliburn.Micro.Core" version="3.2.0" targetFramework="net46" />
<package id="CliWrap" version="1.8.4" targetFramework="net46" />
<package id="CommonServiceLocator" version="2.0.3" targetFramework="net46" />
<package id="Dapplo.Addons" version="1.0.47" targetFramework="net46" />
<package id="Dapplo.Addons.Bootstrapper" version="1.0.47" targetFramework="net46" />

View file

@ -105,32 +105,32 @@
<Reference Include="Dapplo.Utils, Version=1.0.158.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Utils.1.0.158\lib\net45\Dapplo.Utils.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.0.5.58\lib\net46\Dapplo.Windows.dll</HintPath>
<Reference Include="Dapplo.Windows, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.0.5.60\lib\net46\Dapplo.Windows.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Common, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Common.0.5.58\lib\net46\Dapplo.Windows.Common.dll</HintPath>
<Reference Include="Dapplo.Windows.Common, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Common.0.5.60\lib\net46\Dapplo.Windows.Common.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.DesktopWindowsManager, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.DesktopWindowsManager.0.5.58\lib\net46\Dapplo.Windows.DesktopWindowsManager.dll</HintPath>
<Reference Include="Dapplo.Windows.DesktopWindowsManager, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.DesktopWindowsManager.0.5.60\lib\net46\Dapplo.Windows.DesktopWindowsManager.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Dpi, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Dpi.0.5.58\lib\net46\Dapplo.Windows.Dpi.dll</HintPath>
<Reference Include="Dapplo.Windows.Dpi, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Dpi.0.5.60\lib\net46\Dapplo.Windows.Dpi.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Gdi32, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Gdi32.0.5.58\lib\net46\Dapplo.Windows.Gdi32.dll</HintPath>
<Reference Include="Dapplo.Windows.Gdi32, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Gdi32.0.5.60\lib\net46\Dapplo.Windows.Gdi32.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Input, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Input.0.5.58\lib\net46\Dapplo.Windows.Input.dll</HintPath>
<Reference Include="Dapplo.Windows.Input, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Input.0.5.60\lib\net46\Dapplo.Windows.Input.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Kernel32, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Kernel32.0.5.58\lib\net46\Dapplo.Windows.Kernel32.dll</HintPath>
<Reference Include="Dapplo.Windows.Kernel32, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Kernel32.0.5.60\lib\net46\Dapplo.Windows.Kernel32.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Messages, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Messages.0.5.58\lib\net46\Dapplo.Windows.Messages.dll</HintPath>
<Reference Include="Dapplo.Windows.Messages, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Messages.0.5.60\lib\net46\Dapplo.Windows.Messages.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.User32, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.User32.0.5.58\lib\net46\Dapplo.Windows.User32.dll</HintPath>
<Reference Include="Dapplo.Windows.User32, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.User32.0.5.60\lib\net46\Dapplo.Windows.User32.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.1.6.4\lib\net46\MahApps.Metro.dll</HintPath>

View file

@ -102,32 +102,32 @@
<Reference Include="Dapplo.Utils, Version=1.0.158.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Utils.1.0.158\lib\net45\Dapplo.Utils.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.0.5.58\lib\net46\Dapplo.Windows.dll</HintPath>
<Reference Include="Dapplo.Windows, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.0.5.60\lib\net46\Dapplo.Windows.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Common, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Common.0.5.58\lib\net46\Dapplo.Windows.Common.dll</HintPath>
<Reference Include="Dapplo.Windows.Common, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Common.0.5.60\lib\net46\Dapplo.Windows.Common.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.DesktopWindowsManager, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.DesktopWindowsManager.0.5.58\lib\net46\Dapplo.Windows.DesktopWindowsManager.dll</HintPath>
<Reference Include="Dapplo.Windows.DesktopWindowsManager, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.DesktopWindowsManager.0.5.60\lib\net46\Dapplo.Windows.DesktopWindowsManager.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Dpi, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Dpi.0.5.58\lib\net46\Dapplo.Windows.Dpi.dll</HintPath>
<Reference Include="Dapplo.Windows.Dpi, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Dpi.0.5.60\lib\net46\Dapplo.Windows.Dpi.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Gdi32, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Gdi32.0.5.58\lib\net46\Dapplo.Windows.Gdi32.dll</HintPath>
<Reference Include="Dapplo.Windows.Gdi32, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Gdi32.0.5.60\lib\net46\Dapplo.Windows.Gdi32.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Input, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Input.0.5.58\lib\net46\Dapplo.Windows.Input.dll</HintPath>
<Reference Include="Dapplo.Windows.Input, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Input.0.5.60\lib\net46\Dapplo.Windows.Input.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Kernel32, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Kernel32.0.5.58\lib\net46\Dapplo.Windows.Kernel32.dll</HintPath>
<Reference Include="Dapplo.Windows.Kernel32, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Kernel32.0.5.60\lib\net46\Dapplo.Windows.Kernel32.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.Messages, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Messages.0.5.58\lib\net46\Dapplo.Windows.Messages.dll</HintPath>
<Reference Include="Dapplo.Windows.Messages, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.Messages.0.5.60\lib\net46\Dapplo.Windows.Messages.dll</HintPath>
</Reference>
<Reference Include="Dapplo.Windows.User32, Version=0.5.58.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.User32.0.5.58\lib\net46\Dapplo.Windows.User32.dll</HintPath>
<Reference Include="Dapplo.Windows.User32, Version=0.5.60.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Windows.User32.0.5.60\lib\net46\Dapplo.Windows.User32.dll</HintPath>
</Reference>
<Reference Include="MahApps.Metro, Version=1.6.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\MahApps.Metro.1.6.4\lib\net46\MahApps.Metro.dll</HintPath>

View file

@ -73,5 +73,17 @@ namespace Greenshot.Addons.Extensions
{
ImageOutput.SaveToStream(surface, stream, surface.GenerateOutputSettings(fileConfiguration.Choose(destinationFileConfiguration)));
}
/// <summary>
/// Write the ISurface to the specified stream by using the supplied IFileConfiguration
/// </summary>
/// <param name="surface">ISurface</param>
/// <param name="fileConfiguration">IFileConfiguration</param>
/// <param name="destinationFileConfiguration">IDestinationFileConfiguration</param>
public static string SaveNamedTmpFile(this ISurface surface, IFileConfiguration fileConfiguration, IDestinationFileConfiguration destinationFileConfiguration = null)
{
var outputSettings = surface.GenerateOutputSettings(fileConfiguration.Choose(destinationFileConfiguration));
return ImageOutput.SaveNamedTmpFile(surface, surface.CaptureDetails, outputSettings);
}
}
}