Moving back to trunk!

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@1602 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
RKrom 2012-01-24 19:24:36 +00:00
parent ad265b2c54
commit 8d458998a1
332 changed files with 17647 additions and 9466 deletions

View file

@ -1,4 +1,5 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{C6988EE8-2FEE-4349-9F09-F9628A0D8965}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -15,13 +16,6 @@
<TreatWarningsAsErrors>false</TreatWarningsAsErrors>
<RunPostBuildEvent>OnBuildSuccess</RunPostBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'x86' ">
<PlatformTarget>x86</PlatformTarget>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<OutputPath>bin\Debug\</OutputPath>
<DebugSymbols>true</DebugSymbols>
@ -29,6 +23,11 @@
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>x86</PlatformTarget>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
@ -36,6 +35,11 @@
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
@ -51,6 +55,7 @@
<Compile Include="LanguageKeys.cs" />
<Compile Include="ModiInterop.cs" />
<Compile Include="OCRConfiguration.cs" />
<Compile Include="OCRDestination.cs" />
<Compile Include="OCRPlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsForm.cs" />
@ -63,9 +68,13 @@
<None Include="Languages\language_ocrplugin-en-US.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language_ocrplugin-fr-FR.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language_ocrplugin-nl-NL.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language_ocrplugin-zh-CN.xml" />
<None Include="Properties\AssemblyInfo.cs.template" />
</ItemGroup>
<ItemGroup>

View file

@ -19,11 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Diagnostics;
using System.Globalization;
using System.Resources;
using System.Threading;
using GreenshotPlugin.Core;
namespace GreenshotOCR {

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Français" ietf="fr-FR" version="0.8.0">
<resources>
<resource name="language">
Langage pour l'OCR
</resource>
<resource name="orient_image">
Orienter l'image
</resource>
<resource name="straighten_image">
Redresser l'image
</resource>
</resources>
</language>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="简体中文" ietf="zh-CN" version="0.8.1">
<resources>
<resource name="language">
OCR语言
</resource>
<resource name="orient_image">
图像定位
</resource>
<resource name="straighten_image">
图像矫正
</resource>
</resources>
</language>

View file

@ -19,8 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Collections;
using Greenshot.Interop;
@ -33,6 +31,7 @@ namespace GreenshotOCR {
}
void Create(string file);
void OCR(ModiLanguage language, bool Orientimage, bool StraightenImage);
void SaveAs(string filename, FileFormat fileFormat, CompressionLevel compressionLevel);
}
public interface Common : IDisposable {
@ -84,4 +83,16 @@ namespace GreenshotOCR {
TURKISH = 31,
SYSDEFAULT = 2048
}
public enum CompressionLevel {
miCOMP_LEVEL_LOW = 0,
miCOMP_LEVEL_MEDIUM = 1,
miCOMP_LEVEL_HIGH = 2
}
public enum FileFormat {
miFILE_FORMAT_DEFAULTVALUE = -1,
miFILE_FORMAT_TIFF = 1,
miFILE_FORMAT_TIFF_LOSSLESS = 2,
miFILE_FORMAT_MDI = 4
}
}

View file

@ -19,8 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using GreenshotPlugin.Core;
using IniFile;
namespace GreenshotOCR {
/// <summary>

View file

@ -20,35 +20,47 @@
*/
using System;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
namespace Greenshot.Helpers {
using Greenshot.Interop;
using Greenshot.Plugin;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using IniFile;
namespace GreenshotOCR {
/// <summary>
/// Description of ImageHelper.
/// Description of OCRDestination.
/// </summary>
public class ImageHelper {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageHelper));
public class OCRDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OCRDestination));
private static OCRConfiguration config = IniConfig.GetIniSection<OCRConfiguration>();
private const int MIN_WIDTH = 130;
private const int MIN_HEIGHT = 130;
private ILanguage lang = Language.GetInstance();
private ImageHelper() {
public override string Designation {
get {
return "OCR";
}
}
/// <summary>
/// Crops the image to the specified rectangle
/// </summary>
/// <param name="image">Image to crop</param>
/// <param name="cropRectangle">Rectangle with bitmap coordinates, will be "intersected" to the bitmap</param>
public static bool Crop(ref Image image, ref Rectangle cropRectangle) {
Image returnImage = null;
if (image != null && image is Bitmap && ((image.Width * image.Height) > 0)) {
cropRectangle.Intersect(new Rectangle(0,0, image.Width, image.Height));
if (cropRectangle.Width != 0 || cropRectangle.Height != 0) {
returnImage = (image as Bitmap).Clone(cropRectangle, image.PixelFormat);
image.Dispose();
image = returnImage;
public override string Description {
get {
return "OCR";
}
}
public override bool isActive {
get {
return true;
}
}
LOG.Warn("Can't crop a null/zero size image!");
return false;
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
OcrPlugin.DoOCR(surface);
return true;
}
}
}

View file

@ -21,17 +21,15 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Windows.Forms;
using Greenshot.Interop;
using Greenshot.Plugin;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using IniFile;
//using Microsoft.Win32;
namespace GreenshotOCR {
@ -42,30 +40,36 @@ namespace GreenshotOCR {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OcrPlugin));
private const string CONFIG_FILENAME = "ocr-config.properties";
private IGreenshotPluginHost host;
private ICaptureHost captureHost = null;
private static IGreenshotHost host;
private static OCRConfiguration config;
private PluginAttribute myAttributes;
private OCRConfiguration config;
private ToolStripMenuItem ocrMenuItem = new ToolStripMenuItem();
private int hotkeyIdentifier = 0;
public OcrPlugin() { }
public IEnumerable<IDestination> Destinations() {
yield break;
}
public IEnumerable<IProcessor> Processors() {
yield break;
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="host">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="captureHost">Use the ICaptureHost interface to register in the MainContextMenu</param>
/// <param name="pluginAttribute">My own attributes</param>
public void Initialize(IGreenshotPluginHost host, ICaptureHost captureHost, PluginAttribute myAttributes) {
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
public virtual bool Initialize(IGreenshotHost greenshotHost, PluginAttribute myAttributes) {
LOG.Debug("Initialize called of " + myAttributes.Name);
this.host = (IGreenshotPluginHost)host;
this.captureHost = captureHost;
host = greenshotHost;
this.myAttributes = myAttributes;
if (!HasMODI()) {
LOG.Warn("No MODI found!");
return;
return false;
}
// Load configuration
config = IniConfig.GetIniSection<OCRConfiguration>();
@ -79,22 +83,8 @@ namespace GreenshotOCR {
// Here we can hang ourselves to the main context menu!
ocrMenuItem.Text = "Region OCR";
ocrMenuItem.Click += new System.EventHandler(MainMenuClick);
ContextMenuStrip contextMenu = host.MainMenu;
bool addedItem = false;
// Try to find a separator, so we insert ourselves before
for(int i=0; i < contextMenu.Items.Count; i++) {
if (contextMenu.Items[i].GetType() == typeof(ToolStripSeparator)) {
contextMenu.Items.Insert(i, ocrMenuItem);
addedItem = true;
break;
}
}
// If we didn't insert the item, we just add it...
if (!addedItem) {
contextMenu.Items.Add(ocrMenuItem);
}
PluginUtils.AddToContextMenu(host, ocrMenuItem);
return true;
}
/// <summary>
@ -138,7 +128,7 @@ namespace GreenshotOCR {
private void StartOCRRegion() {
LOG.Debug("Starting OCR!");
captureHost.MakeCapture(CaptureMode.Region, false, new CaptureHandler(DoOCR));
host.CaptureRegion(false, new OCRDestination());
}
private void MyHotkeyHandler() {
@ -160,15 +150,10 @@ namespace GreenshotOCR {
/// <param name="ImageOutputEventArgs">Has the Image and the capture details</param>
private const int MIN_WIDTH = 130;
private const int MIN_HEIGHT = 130;
private void DoOCR(object sender, CaptureTakenEventArgs eventArgs) {
if (eventArgs.Capture.Image == null) {
return;
}
string file = host.GetFilename(OutputFormat.bmp, eventArgs.Capture.CaptureDetails);
string filePath = Path.Combine(Path.GetTempPath(),file);
public static void DoOCR(ISurface surface) {
string filePath = null;
using (FileStream stream = File.Create(filePath)) {
Image capturedImage = eventArgs.Capture.Image;
using (Image capturedImage = surface.GetImageForExport()) {
if (capturedImage.Width < MIN_WIDTH || capturedImage.Height < MIN_HEIGHT) {
LOG.Debug("Captured image is not big enough for OCR, growing image...");
int newWidth = Math.Max(capturedImage.Width, MIN_WIDTH);
@ -178,10 +163,10 @@ namespace GreenshotOCR {
graphics.Clear(Color.White);
graphics.DrawImage(capturedImage, Point.Empty);
}
host.SaveToStream(tmpImage, stream, OutputFormat.bmp, 100);
filePath = host.SaveToTmpFile(tmpImage, OutputFormat.bmp, 100);
}
} else {
host.SaveToStream(capturedImage, stream, OutputFormat.bmp, 100);
filePath = host.SaveToTmpFile(capturedImage, OutputFormat.bmp, 100);
}
}
@ -227,7 +212,7 @@ namespace GreenshotOCR {
}
return true;
} catch(Exception e) {
LOG.Debug("Error trying to initiate MODI:", e);
LOG.DebugFormat("Error trying to initiate MODI: {0}", e.Message);
}
LOG.InfoFormat("No Microsoft Office Document Imaging (MODI) found, disabling OCR");
return false;

View file

@ -19,11 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
namespace GreenshotOCR {

View file

@ -1,104 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Text;
using System.Windows.Forms;
using System.Xml.Serialization;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
namespace RunAtOutput {
/// <summary>
/// An Plugin to run commands after an image was written
/// </summary>
public class RunAtOutputPlugin : IGreenshotPlugin {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(RunAtOutputPlugin));
private IGreenshotPluginHost host;
private ICaptureHost captureHost = null;
private PluginAttribute myAttributes;
private RunAtOutputConfiguration config;
public RunAtOutputPlugin() {
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="host">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="captureHost">Use the ICaptureHost interface to register in the MainContextMenu</param>
/// <param name="pluginAttribute">My own attributes</param>
public virtual void Initialize(IGreenshotPluginHost pluginHost, ICaptureHost captureHost, PluginAttribute myAttributes) {
LOG.Debug("Initialize called of " + myAttributes.Name);
this.host = (IGreenshotPluginHost)pluginHost;
this.captureHost = captureHost;
this.myAttributes = myAttributes;
this.host.OnImageOutput += new OnImageOutputHandler(ImageOutput);
this.config = IniConfig.GetIniSection<RunAtOutputConfiguration>();
}
public virtual void Shutdown() {
LOG.Debug("Shutdown of " + myAttributes.Name);
this.host.OnImageOutput -= new OnImageOutputHandler(ImageOutput);
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
LOG.Debug("Configure called");
new SettingsForm().ShowDialog();
}
/// <summary>
/// Handling of the OnImageOutputHandler event from the IGreenshotPlugin
/// </summary>
/// <param name="ImageOutputEventArgs">Has the FullPath to the image</param>
private void ImageOutput(object sender, ImageOutputEventArgs eventArgs) {
LOG.Debug("ImageOutput called with full path: " + eventArgs.FullPath);
foreach(string commando in config.active) {
string commandline = config.commandlines[commando];
string arguments = config.arguments[commando];
if (commandline != null && commandline.Length > 0) {
Process p = new Process();
p.StartInfo.FileName = commandline;
p.StartInfo.Arguments = String.Format(arguments, eventArgs.FullPath);
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = true;
LOG.Info("Starting : " + p.StartInfo.FileName + " " + p.StartInfo.Arguments);
p.Start();
string output = p.StandardOutput.ReadToEnd();
if (output != null && output.Trim().Length > 0) {
LOG.Info("Output:\n" + output);
}
LOG.Info("Finished : " + p.StartInfo.FileName + " " + p.StartInfo.Arguments);
}
}
}
}
}

View file

@ -1,120 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
namespace TitleFix {
/// <summary>
/// An example Plugin so developers can see how they can develop their own plugin
/// </summary>
public class TitleFix : IGreenshotPlugin {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(TitleFix));
private IGreenshotPluginHost host;
private ICaptureHost captureHost = null;
private PluginAttribute myAttributes;
private TitleFixConfiguration config = null;
public TitleFix() {
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Initialize
/// </summary>
/// <param name="host">Use the IGreenshotPluginHost interface to register events</param>
/// <param name="captureHost">Use the ICaptureHost interface to register in the MainContextMenu</param>
/// <param name="pluginAttribute">My own attributes</param>
public virtual void Initialize(IGreenshotPluginHost pluginHost, ICaptureHost captureHost, PluginAttribute myAttributes) {
LOG.Debug("Initialize called of " + myAttributes.Name);
this.host = (IGreenshotPluginHost)pluginHost;
this.captureHost = captureHost;
this.myAttributes = myAttributes;
this.config = IniConfig.GetIniSection<TitleFixConfiguration>();
// check configuration
List<string> corruptKeys = new List<string>();
foreach(string key in config.active) {
if (!config.matchers.ContainsKey(key) || !config.matchers.ContainsKey(key)) {
LOG.Warn("Key " + key + " not found, configuration is broken! Disabling this key!");
corruptKeys.Add(key);
}
}
// Fix configuration if needed
if(corruptKeys.Count > 0) {
foreach(string corruptKey in corruptKeys) {
// Removing any reference to the key
config.active.Remove(corruptKey);
config.matchers.Remove(corruptKey);
config.replacers.Remove(corruptKey);
}
config.IsDirty = true;
}
if(config.IsDirty) {
IniConfig.Save();
}
this.host.OnCaptureTaken += new OnCaptureTakenHandler(CaptureTaken);
}
public virtual void Shutdown() {
LOG.Debug("Shutdown of " + myAttributes.Name);
this.host.OnCaptureTaken -= new OnCaptureTakenHandler(CaptureTaken);
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
LOG.Debug("Configure called");
}
/// <summary>
/// Implementation of the OnCaptureTaken event
/// </summary>
private void CaptureTaken(object sender, CaptureTakenEventArgs eventArgs) {
string title = eventArgs.Capture.CaptureDetails.Title;
LOG.Debug("Title before: " + title);
if (title != null && title.Length > 0) {
title = title.Trim();
foreach(string titleIdentifier in config.active) {
string regexpString = config.matchers[titleIdentifier];
string replaceString = config.replacers[titleIdentifier];
if (regexpString != null && regexpString.Length > 0) {
Regex regex = new Regex(regexpString);
title = regex.Replace(title, replaceString);
}
}
}
LOG.Debug("Title after: " + title);
eventArgs.Capture.CaptureDetails.Title = title;
}
}
}

View file

@ -1,69 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using GreenshotPlugin.Core;
namespace TitleFix {
/// <summary>
/// Description of FlickrConfiguration.
/// </summary>
[IniSection("TitleFix", Description="Greenshot TitleFix Plugin configuration")]
public class TitleFixConfiguration : IniSection {
[IniProperty("ActiveFixes", Description="The fixes that are active.")]
public List<string> active;
[IniProperty("Matcher", Description="The regular expressions to match the title with.")]
public Dictionary<string, string> matchers;
[IniProperty("Replacer", Description="The replacements for the matchers.")]
public Dictionary<string, string> replacers;
/// <summary>
/// Supply values we can't put as defaults
/// </summary>
/// <param name="property">The property to return a default for</param>
/// <returns>object with the default value for the supplied property</returns>
public override object GetDefault(string property) {
switch(property) {
case "ActiveFixes":
List<string> activeDefaults = new List<string>();
activeDefaults.Add("Firefox");
activeDefaults.Add("IE");
activeDefaults.Add("Chrome");
return activeDefaults;
case "Matcher":
Dictionary<string, string> matcherDefaults = new Dictionary<string, string>();
matcherDefaults.Add("Firefox", " - Mozilla Firefox.*");
matcherDefaults.Add("IE", " - Microsoft Internet Explorer.*");
matcherDefaults.Add("Chrome", " - Google Chrome.*");
return matcherDefaults;
case "Replacer":
Dictionary<string, string> replacerDefaults = new Dictionary<string, string>();
replacerDefaults.Add("Firefox", "");
replacerDefaults.Add("IE", "");
replacerDefaults.Add("Chrome", "");
return replacerDefaults;
}
return null;
}
}
}

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
@ -48,4 +47,4 @@ using System.Runtime.InteropServices;
// You can specify all values by your own or you can build default build and revision
// numbers with the '*' character (the default):
[assembly: AssemblyVersion("0.8.1.$WCREV$")]
[assembly: AssemblyVersion("0.9.0.$WCREV$")]

View file

@ -19,25 +19,17 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Reflection;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.Controls;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using IniFile;
namespace Greenshot.Configuration {
public enum ScreenshotDestinations {Editor=1, FileDefault=2, FileWithDialog=4, Clipboard=8, Printer=16, EMail=32}
@ -183,22 +175,22 @@ namespace Greenshot.Configuration {
}
coreConfiguration.CaptureDelay = delay;
if ((appConfig.Output_Destinations & ScreenshotDestinations.Clipboard) == ScreenshotDestinations.Clipboard) {
coreConfiguration.OutputDestinations.Add(Destination.Clipboard);
coreConfiguration.OutputDestinations.Add("Clipboard");
}
if ((appConfig.Output_Destinations & ScreenshotDestinations.Editor) == ScreenshotDestinations.Editor) {
coreConfiguration.OutputDestinations.Add(Destination.Editor);
coreConfiguration.OutputDestinations.Add("Editor");
}
if ((appConfig.Output_Destinations & ScreenshotDestinations.EMail) == ScreenshotDestinations.EMail) {
coreConfiguration.OutputDestinations.Add(Destination.EMail);
coreConfiguration.OutputDestinations.Add("EMail");
}
if ((appConfig.Output_Destinations & ScreenshotDestinations.Printer) == ScreenshotDestinations.Printer) {
coreConfiguration.OutputDestinations.Add(Destination.Printer);
coreConfiguration.OutputDestinations.Add("Printer");
}
if ((appConfig.Output_Destinations & ScreenshotDestinations.FileDefault) == ScreenshotDestinations.FileDefault) {
coreConfiguration.OutputDestinations.Add(Destination.FileDefault);
coreConfiguration.OutputDestinations.Add("File");
}
if ((appConfig.Output_Destinations & ScreenshotDestinations.FileWithDialog) == ScreenshotDestinations.FileWithDialog) {
coreConfiguration.OutputDestinations.Add(Destination.FileWithDialog);
coreConfiguration.OutputDestinations.Add("FileWithDialog");
}
IniConfig.Save();
} catch (Exception e) {

View file

@ -21,15 +21,10 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.Core;
using GreenshotPlugin.UnmanagedHelpers;
using IniFile;
namespace Greenshot.Configuration {
/// <summary>
@ -56,19 +51,8 @@ namespace Greenshot.Configuration {
[IniProperty("WindowNormalPosition", Description="Position of normal window", DefaultValue="100,100,400,400")]
public Rectangle WindowNormalPosition;
/// <summary>
/// Supply values we can't put as defaults
/// </summary>
/// <param name="property">The property to return a default for</param>
/// <returns>object with the default value for the supplied property</returns>
public override object GetDefault(string property) {
switch(property) {
case "RecentColors":
return new List<Color>();
}
return null;
}
[IniProperty("SuppressSaveDialogAtClose", Description="Suppressed the 'do you want to save' dialog when closing the editor.", DefaultValue="False")]
public bool SuppressSaveDialogAtClose;
/// <param name="requestingType">Type of the class for which to create the field</param>
/// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="scope">FieldType of the field to construct</param>

View file

@ -19,15 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Configuration {
/// <summary>
@ -36,18 +29,25 @@ namespace Greenshot.Configuration {
public class Language : LanguageContainer, ILanguage {
private static ILanguage uniqueInstance;
private const string LANGUAGE_FILENAME_PATTERN = @"language-*.xml";
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public static ILanguage GetInstance() {
return GetInstance(true);
}
public static ILanguage GetInstance(bool freeResources) {
if(uniqueInstance == null) {
uniqueInstance = new LanguageContainer();
uniqueInstance.LanguageFilePattern = LANGUAGE_FILENAME_PATTERN;
uniqueInstance.Load();
CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
if (string.IsNullOrEmpty(conf.Language)) {
uniqueInstance.SynchronizeLanguageToCulture();
} else {
uniqueInstance.SetLanguage(conf.Language);
}
if (freeResources) {
uniqueInstance.FreeResources();
}
}
return uniqueInstance;
}

View file

@ -22,6 +22,7 @@ using System;
namespace Greenshot.Configuration {
public enum LangKey {
none,
about_bugs,
about_donations,
about_host,
@ -88,6 +89,7 @@ namespace Greenshot.Configuration {
editor_drawellipse,
editor_drawhighlighter,
editor_drawline,
editor_drawfreehand,
editor_drawrectangle,
editor_drawtextbox,
editor_duplicate,
@ -127,6 +129,9 @@ namespace Greenshot.Configuration {
editor_title,
editor_uponelevel,
editor_uptotop,
editor_autocrop,
editor_undo,
editor_redo,
error,
error_multipleinstances,
error_nowriteaccess,
@ -162,6 +167,7 @@ namespace Greenshot.Configuration {
settings_destination_file,
settings_destination_fileas,
settings_destination_printer,
settings_destination_picker,
settings_editor,
settings_filenamepattern,
settings_general,
@ -187,6 +193,7 @@ namespace Greenshot.Configuration {
settings_tooltip_registerhotkeys,
settings_tooltip_storagelocation,
settings_visualization,
settings_shownotify,
settings_waittime,
settings_windowscapture,
settings_window_capture_mode,
@ -198,6 +205,7 @@ namespace Greenshot.Configuration {
warning_hotkeys,
hotkeys,
wait_ie_capture,
update_found
update_found,
exported_to
}
}

View file

@ -18,10 +18,11 @@
* 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 System.Drawing.Imaging;
using System.Drawing;
using System.Windows.Forms;
using System;
using System.Collections.Generic;
using System.Drawing;
using Greenshot.Plugin;
namespace Greenshot.Configuration {
/// <summary>

View file

@ -21,7 +21,6 @@
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
/// <summary>

View file

@ -21,7 +21,6 @@
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
/// <summary>

View file

@ -21,7 +21,6 @@
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
/// <summary>

View file

@ -24,8 +24,6 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using GreenshotPlugin.Core;
namespace Greenshot.Controls {
/// <summary>
/// Description of ColorButton.

View file

@ -20,9 +20,8 @@
*/
using System;
using System.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing;
using System.Windows.Forms;
namespace Greenshot.Controls {
/// <summary>

View file

@ -24,9 +24,6 @@ using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
namespace Greenshot.Controls {
public class ToolStripColorButton : ToolStripButton, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;

View file

@ -0,0 +1,89 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of ClipboardDestination.
/// </summary>
public class ClipboardDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ClipboardDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "Clipboard";
private ILanguage lang = Language.GetInstance();
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
return lang.GetString(LangKey.settings_destination_clipboard);
}
}
public override int Priority {
get {
return 2;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.Shift | Keys.C;
}
}
public override Image DisplayIcon {
get {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
return ((System.Drawing.Image)(resources.GetObject("copyToolStripMenuItem.Image")));
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
try {
using (Image image = surface.GetImageForExport()) {
ClipboardHelper.SetClipboardData(image);
surface.Modified = false;
}
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetString(LangKey.editor_storedtoclipboard));
return true;
} catch (Exception) {
surface.SendMessageEvent(this, SurfaceMessageTyp.Error, lang.GetString(LangKey.editor_clipboardfailed));
}
return false;
}
}
}

View file

@ -0,0 +1,122 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of EditorDestination.
/// </summary>
public class EditorDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(EditorDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "Editor";
private ILanguage lang = Language.GetInstance();
private IImageEditor editor = null;
private static Image greenshotIcon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon().ToBitmap();
public EditorDestination() {
}
public EditorDestination(IImageEditor editor) {
this.editor = editor;
}
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
if (editor == null) {
return lang.GetString(LangKey.settings_destination_editor);
} else {
return lang.GetString(LangKey.settings_destination_editor) + " - " + editor.CaptureDetails.Title;
}
}
}
public override int Priority {
get {
return 1;
}
}
public override bool isDynamic {
get {
return true;
}
}
public override Image DisplayIcon {
get {
return greenshotIcon;
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
foreach (IImageEditor editor in ImageEditorForm.Editors) {
yield return new EditorDestination(editor);
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
if (editor == null) {
// Make sure we collect the garbage before opening the screenshot
GC.Collect();
GC.WaitForPendingFinalizers();
try {
ImageEditorForm editorForm = new ImageEditorForm(surface, false); // Output made??
if (!string.IsNullOrEmpty(captureDetails.Filename)) {
editorForm.SetImagePath(captureDetails.Filename);
}
editorForm.Show();
editorForm.Activate();
LOG.Debug("Finished opening Editor");
return true;
} catch (Exception e) {
LOG.Error(e);
}
} else {
using (Bitmap image = (Bitmap)surface.GetImageForExport()) {
editor.Surface.AddBitmapContainer(image, 10, 10);
}
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description));
}
return false;
}
}
}

View file

@ -0,0 +1,200 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Helpers;
using Greenshot.Helpers.OfficeInterop;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of EmailDestination.
/// </summary>
public class EmailDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(EmailDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image icon = null;
private static bool isActiveFlag = false;
private static bool isOutlookUsed = false;
private static string mapiClient = null;
public const string DESIGNATION = "EMail";
private string outlookInspectorCaption = null;
private ILanguage lang = Language.GetInstance();
static EmailDestination() {
// Logic to decide what email implementation we use
if (EmailConfigHelper.HasMAPI()) {
isActiveFlag = true;
mapiClient = EmailConfigHelper.GetMapiClient();
if (!string.IsNullOrEmpty(mapiClient)) {
if (mapiClient.ToLower().Contains("microsoft outlook")) {
isOutlookUsed = true;
}
}
} else if (EmailConfigHelper.HasOutlook()) {
mapiClient = "Microsoft Outlook";
isActiveFlag = true;
isOutlookUsed = true;
}
if (isOutlookUsed) {
exePath = GetExePath("OUTLOOK.EXE");
if (exePath != null && File.Exists(exePath)) {
icon = GetExeIcon(exePath);
} else {
exePath = null;
}
if (exePath == null) {
isOutlookUsed = false;
if (!EmailConfigHelper.HasMAPI()) {
isActiveFlag = false;
}
}
}
if (isActiveFlag && !isOutlookUsed) {
// Use default email icon
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
icon = ((System.Drawing.Image)(resources.GetObject("btnEmail.Image")));
}
}
public EmailDestination() {
}
public EmailDestination(string outlookInspectorCaption) {
this.outlookInspectorCaption = outlookInspectorCaption;
}
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
// Make sure there is some kind of "mail" name
if (mapiClient == null) {
mapiClient = lang.GetString(LangKey.editor_email);
}
if (outlookInspectorCaption == null) {
return mapiClient;
} else {
return mapiClient + " - " + outlookInspectorCaption;
}
}
}
public override int Priority {
get {
return 3;
}
}
public override bool isActive {
get {
return isActiveFlag;
}
}
public override bool isDynamic {
get {
return isOutlookUsed;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.E;
}
}
public override Image DisplayIcon {
get {
return icon;
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
if (!isOutlookUsed) {
yield break;
}
List<string> inspectorCaptions = OutlookExporter.RetrievePossibleTargets();
if (inspectorCaptions != null) {
foreach (string inspectorCaption in inspectorCaptions) {
yield return new EmailDestination(inspectorCaption);
}
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
if (!isOutlookUsed) {
using (Image image = surface.GetImageForExport()) {
MapiMailMessage.SendImage(image, captureDetails);
surface.Modified = false;
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, "Exported to " + mapiClient);
}
return true;
}
// Outlook logic
string tmpFile = captureDetails.Filename;
if (tmpFile == null) {
using (Image image = surface.GetImageForExport()) {
tmpFile = ImageOutput.SaveNamedTmpFile(image, captureDetails, conf.OutputFileFormat, conf.OutputFileJpegQuality);
}
}
// Create a attachment name for the image
string attachmentName = captureDetails.Title;
if (!string.IsNullOrEmpty(attachmentName)) {
attachmentName = attachmentName.Trim();
}
// Set default if non is set
if (string.IsNullOrEmpty(attachmentName)) {
attachmentName = "Greenshot Capture";
}
// Make sure it's "clean" so it doesn't corrupt the header
attachmentName = Regex.Replace(attachmentName, @"[^\x20\d\w]", "");
if (outlookInspectorCaption != null) {
OutlookExporter.ExportToInspector(outlookInspectorCaption, tmpFile, attachmentName);
} else {
OutlookExporter.ExportToOutlook(tmpFile, captureDetails.Title, attachmentName);
}
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description));
surface.Modified = false;
// Don't know how to handle a cancel in the email
return true;
}
}
}

View file

@ -0,0 +1,125 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Helpers.OfficeInterop;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of PowerpointDestination.
/// </summary>
public class ExcelDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ExcelDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image icon = null;
private ILanguage lang = Language.GetInstance();
private string workbookName = null;
static ExcelDestination() {
exePath = GetExePath("EXCEL.EXE");
if (exePath != null && File.Exists(exePath)) {
icon = GetExeIcon(exePath);
} else {
exePath = null;
}
}
public ExcelDestination() {
}
public ExcelDestination(string workbookName) {
this.workbookName = workbookName;
}
public override string Designation {
get {
return "Excel";
}
}
public override string Description {
get {
if (workbookName == null) {
return "Microsoft Excel";
} else {
return "Microsoft Excel - " + workbookName;
}
}
}
public override int Priority {
get {
return 5;
}
}
public override bool isDynamic {
get {
return true;
}
}
public override bool isActive {
get {
return exePath != null;
}
}
public override Image DisplayIcon {
get {
return icon;
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
foreach (string workbookName in ExcelExporter.GetWorkbooks()) {
yield return new ExcelDestination(workbookName);
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
string tmpFile = captureDetails.Filename;
if (tmpFile == null) {
using (Image image = surface.GetImageForExport()) {
tmpFile = ImageOutput.SaveNamedTmpFile(image, captureDetails, conf.OutputFileFormat, conf.OutputFileJpegQuality);
}
}
if (workbookName != null) {
ExcelExporter.InsertIntoExistingWorkbook(workbookName, tmpFile);
} else {
ExcelExporter.InsertIntoNewWorkbook(tmpFile);
}
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description));
surface.Modified = false;
return true;
}
}
}

View file

@ -0,0 +1,112 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of FileSaveAsDestination.
/// </summary>
public class FileDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(FileDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "FileNoDialog";
private ILanguage lang = Language.GetInstance();
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
return lang.GetString(LangKey.quicksettings_destination_file);
}
}
public override int Priority {
get {
return 0;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.S;
}
}
public override Image DisplayIcon {
get {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
return ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image")));
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
bool outputMade = false;
string pattern = conf.OutputFileFilenamePattern;
if (string.IsNullOrEmpty(pattern)) {
pattern = "greenshot ${capturetime}";
}
string filename = FilenameHelper.GetFilenameFromPattern(pattern, conf.OutputFileFormat, captureDetails);
string filepath = FilenameHelper.FillVariables(conf.OutputFilePath, false);
string fullPath = Path.Combine(filepath,filename);
// Catching any exception to prevent that the user can't write in the directory.
// This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642
using (Image image = surface.GetImageForExport()) {
try {
// TODO: For now we overwrite, but this should be fixed some time
ImageOutput.Save(image, fullPath, true);
outputMade = true;
} catch (Exception e) {
LOG.Error("Error saving screenshot!", e);
// Show the problem
MessageBox.Show(lang.GetString(LangKey.error_save), lang.GetString(LangKey.error));
// when save failed we present a SaveWithDialog
fullPath = ImageOutput.SaveWithDialog(image, captureDetails);
outputMade = (fullPath != null);
}
}
// Don't overwite filename if no output is made
if (outputMade) {
surface.LastSaveFullPath = fullPath;
surface.Modified = false;
captureDetails.Filename = fullPath;
surface.SendMessageEvent(this, SurfaceMessageTyp.FileSaved, lang.GetFormattedString(LangKey.editor_imagesaved,surface.LastSaveFullPath));
} else {
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, "");
}
return outputMade;
}
}
}

View file

@ -0,0 +1,92 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of FileWithDialog.
/// </summary>
public class FileWithDialogDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(FileWithDialogDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "FileDialog";
private ILanguage lang = Language.GetInstance();
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
return lang.GetString(LangKey.settings_destination_fileas);
}
}
public override int Priority {
get {
return 0;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.Shift | Keys.S;
}
}
public override Image DisplayIcon {
get {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
return ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image")));
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
string savedTo = null;
using (Image image = surface.GetImageForExport()) {
// Bug #2918756 don't overwrite path if SaveWithDialog returns null!
savedTo = ImageOutput.SaveWithDialog(image, captureDetails);
if (savedTo != null) {
surface.Modified = false;
surface.LastSaveFullPath = savedTo;
captureDetails.Filename = savedTo;
surface.SendMessageEvent(this, SurfaceMessageTyp.FileSaved, lang.GetFormattedString(LangKey.editor_imagesaved,surface.LastSaveFullPath));
} else {
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, "");
}
}
return savedTo != null;
}
}
}

View file

@ -0,0 +1,133 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Forms;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of PickerDestination.
/// </summary>
public class PickerDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PickerDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "Picker";
private ILanguage lang = Language.GetInstance();
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
return lang.GetString(LangKey.settings_destination_picker);
}
}
public override int Priority {
get {
return 1;
}
}
public override bool isActive {
get {
return conf.isExperimentalFeatureEnabled("Picker");
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
ContextMenuStrip menu = new ContextMenuStrip();
menu.Closed += delegate(object source, ToolStripDropDownClosedEventArgs eventArgs) {
// Dispose surface when no item was clicked, else the dispose should be made there!
if (eventArgs.CloseReason != ToolStripDropDownCloseReason.ItemClicked) {
LOG.DebugFormat("Disposing as no item was clicked, reason: {0}", eventArgs.CloseReason);
surface.Dispose();
}
};
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
if ("Picker".Equals(destination.Designation)) {
continue;
}
if (!destination.isActive) {
continue;
}
// Fix foreach loop variable for the delegate
ToolStripMenuItem item = destination.GetMenuItem(delegate(object sender, EventArgs e) {
ToolStripMenuItem toolStripMenuItem = sender as ToolStripMenuItem;
if (toolStripMenuItem == null) {
return;
}
IDestination clickedDestination = (IDestination)toolStripMenuItem.Tag;
if (clickedDestination == null) {
return;
}
bool result = clickedDestination.ExportCapture(surface, captureDetails);
// TODO: Find some better way to detect that we exported to the editor
if (!EditorDestination.DESIGNATION.Equals(clickedDestination.Designation) || result == false) {
LOG.DebugFormat("Disposing as Destination was {0} and result {1}", clickedDestination.Description, result);
// Cleanup surface
surface.Dispose();
}
// Make sure the menu is closed
menu.Close();
});
if (item != null) {
menu.Items.Add(item);
}
}
menu.Items.Add(new ToolStripSeparator());
ToolStripMenuItem closeItem = new ToolStripMenuItem(lang.GetString(LangKey.editor_close));
closeItem.Image = ((System.Drawing.Image)(new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm)).GetObject("closeToolStripMenuItem.Image")));
closeItem.Click += delegate {
// This menu entry is the close itself, we can dispose the surface
menu.Close();
surface.Dispose();
};
menu.Items.Add(closeItem);
// find a suitable location
Point location = Cursor.Position;
Rectangle menuRectangle = new Rectangle(location, menu.Size);
menuRectangle.Intersect(WindowCapture.GetScreenBounds());
if (menuRectangle.Height < menu.Height) {
location.Offset(-40, -(menuRectangle.Height - menu.Height));
} else {
location.Offset(-40, -10);
}
menu.Show(location);
menu.Focus();
return true;
}
}
}

View file

@ -0,0 +1,127 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Helpers.OfficeInterop;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of PowerpointDestination.
/// </summary>
public class PowerpointDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PowerpointDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image icon = null;
private ILanguage lang = Language.GetInstance();
private string presentationName = null;
static PowerpointDestination() {
exePath = GetExePath("POWERPNT.EXE");
if (exePath != null && File.Exists(exePath)) {
icon = GetExeIcon(exePath);
} else {
exePath = null;
}
}
public PowerpointDestination() {
}
public PowerpointDestination(string presentationName) {
this.presentationName = presentationName;
}
public override string Designation {
get {
return "Powerpoint";
}
}
public override string Description {
get {
if (presentationName == null) {
return "Microsoft Powerpoint";
} else {
return "Microsoft Powerpoint - " + presentationName;
}
}
}
public override int Priority {
get {
return 4;
}
}
public override bool isDynamic {
get {
return true;
}
}
public override bool isActive {
get {
return exePath != null;
}
}
public override Image DisplayIcon {
get {
return icon;
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
foreach (string presentationName in PowerpointExporter.GetPowerpointPresentations()) {
yield return new PowerpointDestination(presentationName);
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
string tmpFile = captureDetails.Filename;
Size imageSize = Size.Empty;
if (tmpFile == null) {
using (Image image = surface.GetImageForExport()) {
tmpFile = ImageOutput.SaveNamedTmpFile(image, captureDetails, conf.OutputFileFormat, conf.OutputFileJpegQuality);
imageSize = image.Size;
}
}
if (presentationName != null) {
PowerpointExporter.ExportToPresentation(presentationName, tmpFile, imageSize, captureDetails);
} else {
PowerpointExporter.InsertIntoNewPresentation(tmpFile, imageSize, captureDetails);
}
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description));
surface.Modified = false;
return true;
}
}
}

View file

@ -0,0 +1,89 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of PrinterDestination.
/// </summary>
public class PrinterDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(PrinterDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public const string DESIGNATION = "Printer";
private ILanguage lang = Language.GetInstance();
public override string Designation {
get {
return DESIGNATION;
}
}
public override string Description {
get {
return lang.GetString(LangKey.settings_destination_printer);
}
}
public override int Priority {
get {
return 2;
}
}
public override Keys EditorShortcutKeys {
get {
return Keys.Control | Keys.P;
}
}
public override Image DisplayIcon {
get {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
return ((System.Drawing.Image)(resources.GetObject("printToolStripMenuItem.Image")));
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
PrinterSettings printerSettings = null;
using (Image image = surface.GetImageForExport()) {
printerSettings = new PrintHelper(image, captureDetails).PrintWithDialog();
if (printerSettings != null) {
surface.Modified = false;
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.editor_senttoprinter, printerSettings.PrinterName));
}
}
return printerSettings != null;
}
}
}

View file

@ -0,0 +1,128 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using Greenshot.Helpers;
using Greenshot.Helpers.OfficeInterop;
using IniFile;
namespace Greenshot.Destinations {
/// <summary>
/// Description of EmailDestination.
/// </summary>
public class WordDestination : AbstractDestination {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WordDestination));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static string exePath = null;
private static Image icon = null;
private ILanguage lang = Language.GetInstance();
private string wordCaption = null;
static WordDestination() {
exePath = GetExePath("WINWORD.EXE");
if (exePath != null && File.Exists(exePath)) {
icon = GetExeIcon(exePath);
} else {
exePath = null;
}
}
public WordDestination() {
}
public WordDestination(string wordCaption) {
this.wordCaption = wordCaption;
}
public override string Designation {
get {
return "Word";
}
}
public override string Description {
get {
if (wordCaption == null) {
return "Microsoft Word";
} else {
return "Microsoft Word - " + wordCaption;
}
}
}
public override int Priority {
get {
return 4;
}
}
public override bool isDynamic {
get {
return true;
}
}
public override bool isActive {
get {
return exePath != null;
}
}
public override Image DisplayIcon {
get {
return icon;
}
}
public override IEnumerable<IDestination> DynamicDestinations() {
foreach (string wordCaption in WordExporter.GetWordDocuments()) {
yield return new WordDestination(wordCaption);
}
}
public override bool ExportCapture(ISurface surface, ICaptureDetails captureDetails) {
string tmpFile = captureDetails.Filename;
if (tmpFile == null) {
using (Image image = surface.GetImageForExport()) {
tmpFile = ImageOutput.SaveNamedTmpFile(image, captureDetails, conf.OutputFileFormat, conf.OutputFileJpegQuality);
}
}
if (wordCaption != null) {
WordExporter.InsertIntoExistingDocument(wordCaption, tmpFile);
} else {
WordExporter.InsertIntoNewDocument(tmpFile);
}
surface.SendMessageEvent(this, SurfaceMessageTyp.Info, lang.GetFormattedString(LangKey.exported_to, Description));
surface.Modified = false;
return true;
}
}
}

View file

@ -19,13 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
@ -44,19 +40,19 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.ARROWHEADS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
AddField(GetType(), FieldType.SHADOW, false);
AddField(GetType(), FieldType.SHADOW, true);
AddField(GetType(), FieldType.ARROWHEADS, Greenshot.Drawing.ArrowContainer.ArrowHeadCombination.END_POINT);
}
public override void Draw(Graphics g, RenderMode rm) {
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
ArrowHeadCombination heads = (ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS);;
if ( shadow && lineThickness > 0 ) {
if (lineThickness > 0 ) {
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
ArrowHeadCombination heads = (ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS);
if (shadow) {
//draw shadow first
int basealpha = 100;
int alpha = basealpha;
@ -65,9 +61,7 @@ namespace Greenshot.Drawing {
while ( currentStep <= steps ) {
using (Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowCapPen.Width = lineThickness;
if ( heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.START_POINT ) shadowCapPen.CustomStartCap = ARROW_CAP;
if ( heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.END_POINT ) shadowCapPen.CustomEndCap = ARROW_CAP;
SetArrowHeads(heads, shadowCapPen);
g.DrawLine(shadowCapPen,
this.Left + currentStep,
@ -79,109 +73,60 @@ namespace Greenshot.Drawing {
alpha = alpha - (basealpha / steps);
}
}
}
}
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if ( pen.Width > 0 ) {
if ( heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.START_POINT ) pen.CustomStartCap = ARROW_CAP;
if ( heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.END_POINT ) pen.CustomEndCap = ARROW_CAP;
SetArrowHeads(heads, pen);
g.DrawLine(pen, this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
}
}
}
}
private void SetArrowHeads(ArrowHeadCombination heads, Pen pen) {
if ( heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.START_POINT ) {
pen.CustomStartCap = ARROW_CAP;
}
if ( heads == ArrowHeadCombination.BOTH || heads == ArrowHeadCombination.END_POINT ) {
pen.CustomEndCap = ARROW_CAP;
}
}
public override Rectangle DrawingBounds {
get {
int lineThickness = 0;
if (HasField(FieldType.LINE_THICKNESS)) {
lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
if (lineThickness > 0) {
using (Pen pen = new Pen(Color.White)) {
pen.Width = lineThickness;
SetArrowHeads((ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS), pen);
GraphicsPath path = new GraphicsPath();
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
Rectangle drawingBounds = Rectangle.Round(path.GetBounds(new Matrix(), pen));
drawingBounds.Inflate(2,2);
return drawingBounds;
}
int arrowCapWidth = 0;
int arrowCapHeight = 0;
if (HasField(FieldType.ARROWHEADS)) {
ArrowHeadCombination heads = (ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS);
if(heads.Equals(ArrowHeadCombination.START_POINT) || heads.Equals(ArrowHeadCombination.END_POINT) || heads.Equals(ArrowHeadCombination.BOTH)) {
arrowCapWidth = (int)ARROW_CAP.Width * lineThickness;
arrowCapHeight = (int)ARROW_CAP.Height * lineThickness;
} else {
return Rectangle.Empty;
}
}
int offset = Math.Max(lineThickness/2, Math.Max(arrowCapWidth, arrowCapHeight));
return new Rectangle(Bounds.Left-offset, Bounds.Top-offset, Bounds.Width+offset*2, Bounds.Height+offset*2);
}
}
public override bool ClickableAt(int x, int y) {
bool ret = false;
ret = base.ClickableAt(x, y);
if(!ret) {
// line has not been clicked, check arrow heads
ArrowHeadCombination heads = (ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS);
if(!ArrowHeadCombination.NONE.Equals(heads)) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
double arrowCapHalfWidth = ARROW_CAP.Width * lineThickness / 2;
double arrowCapHeight = ARROW_CAP.Height * lineThickness;
// we have to check only if arrow heads are wider than tolerated area of LineContainer
if(arrowCapHalfWidth > MAX_CLICK_DISTANCE_TOLERANCE) {
double mouseToLineDist = DrawingHelper.CalculateLinePointDistance(Left, Top, Left+Width, Top+Height, x, y);
if(mouseToLineDist > -1) { // point next to line at all?
if(heads.Equals(ArrowHeadCombination.END_POINT) || heads.Equals(ArrowHeadCombination.BOTH)) {
// calculate a perpendicular line at arrow tip to hittest arrow head easily
int p1x = Left + Width + Height;
int p1y = Top + Height - Width;
int p2x = Left + Width - Height;
int p2y = Top + Height + Width;
double mouseToPerpDist = DrawingHelper.CalculateLinePointDistance(p1x,p1y,p2x,p2y, x, y);
if(
// point located within rectangular area of width/height of arrowhead?
mouseToLineDist <= arrowCapHalfWidth
&& mouseToPerpDist <= arrowCapHeight
// point located within arrowhead? (nearer to line than to perp * w/h-factor)
&& mouseToLineDist < mouseToPerpDist * arrowCapHalfWidth / arrowCapHeight) {
return true;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10;
if (lineThickness > 0) {
using (Pen pen = new Pen(Color.White)) {
pen.Width = lineThickness;
SetArrowHeads((ArrowHeadCombination)GetFieldValue(FieldType.ARROWHEADS), pen);
GraphicsPath path = new GraphicsPath();
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
return path.IsOutlineVisible(x,y, pen);
}
}
if(heads.Equals(ArrowHeadCombination.START_POINT) || heads.Equals(ArrowHeadCombination.BOTH)) {
// calculate a perpendicular line at arrow tip to hittest arrow head easily
int p1x = Left - Height;
int p1y = Top + Width;
int p2x = Left + Height;
int p2y = Top - Width;
double mouseToPerpDist = DrawingHelper.CalculateLinePointDistance(p1x,p1y,p2x,p2y, x, y);
if(
// point located within rectangular area of width/height of arrowhead?
mouseToLineDist <= arrowCapHalfWidth
&& mouseToPerpDist <= arrowCapHeight
// point located within arrowhead? (nearer to line than to perp * w/h-factor)
&& mouseToLineDist < mouseToPerpDist * arrowCapHalfWidth / arrowCapHeight) {
return true;
}
}
}
}
}
}
return ret;
/*int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
double distance = DrawingHelper.CalculateLinePointDistance(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height, x, y);
if (distance < 0) {
} else {
return false;
}
return distance <= Math.Max(lineThickness / 2, 10);*/
}
}
}
}

View file

@ -20,14 +20,14 @@
*/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
namespace Greenshot.Drawing {
/// <summary>
@ -40,10 +40,12 @@ namespace Greenshot.Drawing {
protected Bitmap bitmap;
public BitmapContainer(Surface parent, string filename) : this(parent) {
AddField(GetType(), FieldType.SHADOW, false);
Load(filename);
}
public BitmapContainer(Surface parent) : base(parent) {
AddField(GetType(), FieldType.SHADOW, false);
}
@ -93,17 +95,38 @@ namespace Greenshot.Drawing {
public void Load(string filename) {
if (File.Exists(filename)) {
using (Bitmap fileBitmap = new Bitmap(filename)) {
Bitmap = fileBitmap;
Bitmap = ImageHelper.LoadBitmap(filename);
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
public override void Draw(Graphics graphics, RenderMode rm) {
if (bitmap != null) {
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
if (shadow) {
ImageAttributes ia = new ImageAttributes();
ColorMatrix cm = new ColorMatrix();
cm.Matrix00 = 0;
cm.Matrix11 = 0;
cm.Matrix22 = 0;
cm.Matrix33 = 0.25f;
ia.SetColorMatrix(cm);
graphics.DrawImage(bitmap, new Rectangle(Bounds.Left+2, Bounds.Top+2, Bounds.Width, Bounds.Height), 0, 0, bitmap.Width, bitmap.Height, GraphicsUnit.Pixel, ia);
}
graphics.DrawImage(bitmap, Bounds);
}
}
public override void Draw(Graphics g, RenderMode rm) {
if (bitmap != null) {
g.DrawImage(bitmap, Bounds);
}
public override void AddContextMenuItems(ContextMenuStrip menu) {
base.AddContextMenuItems(menu);
ToolStripMenuItem resetItem = new ToolStripMenuItem("Reset size");
resetItem.Click += delegate {
this.Invalidate();
Width = Bitmap.Width;
Height = Bitmap.Height;
this.Invalidate();
};
menu.Items.Add(resetItem);
}
}
}

View file

@ -20,7 +20,6 @@
*/
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Drawing.Fields;
@ -57,5 +56,9 @@ namespace Greenshot.Drawing {
g.FillRectangle(cropBrush, new Rectangle(0, r.Top + r.Height, parent.Width, parent.Height - (r.Top + r.Height)));
}
}
public override void ShowContextMenu(MouseEventArgs e) {
// No context menu for the CropContainer
}
}
}

View file

@ -20,14 +20,9 @@
*/
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
@ -106,5 +101,17 @@ namespace Greenshot.Drawing {
cursor.DrawStretched(graphics, Bounds);
}
}
public override void AddContextMenuItems(ContextMenuStrip menu) {
base.AddContextMenuItems(menu);
ToolStripMenuItem resetItem = new ToolStripMenuItem("Reset size");
resetItem.Click += delegate {
this.Invalidate();
Width = cursor.Size.Width;
Height = cursor.Size.Height;
this.Invalidate();
};
menu.Items.Add(resetItem);
}
}
}

View file

@ -22,18 +22,17 @@ using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Controls;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Greenshot.Plugin.Drawing;
using Greenshot.Memento;
using IniFile;
namespace Greenshot.Drawing {
/// <summary>
@ -45,6 +44,10 @@ namespace Greenshot.Drawing {
[Serializable()]
public abstract class DrawableContainer : AbstractFieldHolderWithChildren, INotifyPropertyChanged, IDrawableContainer {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(DrawableContainer));
private static System.ComponentModel.ComponentResourceManager editorFormResources = new System.ComponentModel.ComponentResourceManager(typeof(ImageEditorForm));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private bool isMadeUndoable = false;
[NonSerialized]
private PropertyChangedEventHandler propertyChanged;
@ -53,32 +56,36 @@ namespace Greenshot.Drawing {
remove{ propertyChanged -= value; }
}
// public List<IFilter> filters = new List<IFilter>();
public List<IFilter> Filters {
get {
List<IFilter> ret = new List<IFilter>();
foreach(IFieldHolder c in Children) {
if(c is IFilter) ret.Add(c as IFilter);
if (c is IFilter) {
ret.Add(c as IFilter);
}
}
return ret;
}
}
[NonSerialized]
protected Surface parent;
internal Surface parent;
public ISurface Parent {
get { return parent; }
set { SwitchParent((Surface)value); }
}
[NonSerialized]
protected Label[] grippers;
protected Gripper[] grippers;
private bool layoutSuspended = false;
[NonSerialized]
private bool selected = false;
public bool Selected {
get {return selected;}
set {selected = value; OnPropertyChanged("Selected"); }
set {
selected = value;
OnPropertyChanged("Selected");
}
}
[NonSerialized]
@ -87,29 +94,86 @@ namespace Greenshot.Drawing {
private int left = 0;
public int Left {
get { return left; }
set { left = value; DoLayout();}
set {
if(value != left) {
left = value;
DoLayout();
}
}
}
private int top = 0;
public int Top {
get { return top; }
set { top = value; DoLayout();}
set {
if(value != top) {
top = value;
DoLayout();
}
}
}
private int width = 0;
public int Width {
get { return width; }
set { width = value; DoLayout();}
set {
if(value != width) {
width = value;
DoLayout();
}
}
}
private int height = 0;
public int Height {
get { return height; }
set { height = value; DoLayout();}
set {
if(value != height) {
height = value;
DoLayout();
}
}
}
public Point Location {
get {
return new Point(left, top);
}
}
public Size Size {
get {
return new Size(width, height);
}
}
[NonSerialized]
/// <summary>
/// will store current bounds of this DrawableContainer before starting a resize
/// </summary>
private Rectangle boundsBeforeResize = Rectangle.Empty;
[NonSerialized]
/// <summary>
/// "workbench" rectangle - used for calculatoing bounds during resizing (to be applied to this DrawableContainer afterwards)
/// </summary>
private RectangleF boundsAfterResize = RectangleF.Empty;
public Rectangle Bounds {
get { return GuiRectangle.GetGuiRectangle(left, top, width, height); }
get { return GuiRectangle.GetGuiRectangle(Left, Top, Width, Height); }
set {
Left = round(value.Left);
Top = round(value.Top);
Width = round(value.Width);
Height = round(value.Height);
}
}
public void ApplyBounds(RectangleF newBounds) {
Left = round(newBounds.Left);
Top = round(newBounds.Top);
Width = round(newBounds.Width);
Height = round(newBounds.Height);
}
public DrawableContainer(Surface parent) {
@ -125,6 +189,18 @@ namespace Greenshot.Drawing {
RemoveChild(filter);
}
private int round(float f) {
if(float.IsPositiveInfinity(f) || f>int.MaxValue/2) return int.MaxValue/2;
else if (float.IsNegativeInfinity(f) || f<int.MinValue/2) return int.MinValue/2;
return (int)Math.Round(f);
}
private int round(double d) {
if(Double.IsPositiveInfinity(d) || d>int.MaxValue/2) return int.MaxValue/2;
else if (Double.IsNegativeInfinity(d) || d<int.MinValue/2) return int.MinValue/2;
else return (int)Math.Round(d);
}
private bool accountForShadowChange = false;
public virtual Rectangle DrawingBounds {
get {
@ -187,24 +263,21 @@ namespace Greenshot.Drawing {
DoLayout();
}
void InitGrippers() {
grippers = new Label[8];
protected void InitGrippers() {
grippers = new Gripper[8];
for(int i=0; i<grippers.Length; i++) {
grippers[i] = new Label();
grippers[i].Name = "gripper" + i;
grippers[i].Width = 5;
grippers[i].Height = 5;
grippers[i].BackColor = Color.Black;
grippers[i] = new Gripper();
grippers[i].Position = i;
grippers[i].MouseDown += new MouseEventHandler(gripperMouseDown);
grippers[i].MouseUp += new MouseEventHandler(gripperMouseUp);
grippers[i].MouseMove += new MouseEventHandler(gripperMouseMove);
grippers[i].Visible = false;
grippers[i].Parent = parent;
}
grippers[1].Cursor = Cursors.SizeNS;
grippers[3].Cursor = Cursors.SizeWE;
grippers[5].Cursor = Cursors.SizeNS;
grippers[7].Cursor = Cursors.SizeWE;
grippers[Gripper.POSITION_TOP_CENTER].Cursor = Cursors.SizeNS;
grippers[Gripper.POSITION_MIDDLE_RIGHT].Cursor = Cursors.SizeWE;
grippers[Gripper.POSITION_BOTTOM_CENTER].Cursor = Cursors.SizeNS;
grippers[Gripper.POSITION_MIDDLE_LEFT].Cursor = Cursors.SizeWE;
if (parent != null) {
parent.Controls.AddRange(grippers); // otherwise we'll attach them in switchParent
}
@ -219,38 +292,38 @@ namespace Greenshot.Drawing {
DoLayout();
}
private void DoLayout() {
protected virtual void DoLayout() {
if (!layoutSuspended) {
int[] xChoords = new int[]{this.Left-2,this.Left+this.Width/2-2,this.Left+this.Width-2};
int[] yChoords = new int[]{this.Top-2,this.Top+this.Height/2-2,this.Top+this.Height-2};
grippers[0].Left = xChoords[0]; grippers[0].Top = yChoords[0];
grippers[1].Left = xChoords[1]; grippers[1].Top = yChoords[0];
grippers[2].Left = xChoords[2]; grippers[2].Top = yChoords[0];
grippers[3].Left = xChoords[2]; grippers[3].Top = yChoords[1];
grippers[4].Left = xChoords[2]; grippers[4].Top = yChoords[2];
grippers[5].Left = xChoords[1]; grippers[5].Top = yChoords[2];
grippers[6].Left = xChoords[0]; grippers[6].Top = yChoords[2];
grippers[7].Left = xChoords[0]; grippers[7].Top = yChoords[1];
grippers[Gripper.POSITION_TOP_LEFT].Left = xChoords[0]; grippers[Gripper.POSITION_TOP_LEFT].Top = yChoords[0];
grippers[Gripper.POSITION_TOP_CENTER].Left = xChoords[1]; grippers[Gripper.POSITION_TOP_CENTER].Top = yChoords[0];
grippers[Gripper.POSITION_TOP_RIGHT].Left = xChoords[2]; grippers[Gripper.POSITION_TOP_RIGHT].Top = yChoords[0];
grippers[Gripper.POSITION_MIDDLE_RIGHT].Left = xChoords[2]; grippers[Gripper.POSITION_MIDDLE_RIGHT].Top = yChoords[1];
grippers[Gripper.POSITION_BOTTOM_RIGHT].Left = xChoords[2]; grippers[Gripper.POSITION_BOTTOM_RIGHT].Top = yChoords[2];
grippers[Gripper.POSITION_BOTTOM_CENTER].Left = xChoords[1]; grippers[Gripper.POSITION_BOTTOM_CENTER].Top = yChoords[2];
grippers[Gripper.POSITION_BOTTOM_LEFT].Left = xChoords[0]; grippers[Gripper.POSITION_BOTTOM_LEFT].Top = yChoords[2];
grippers[Gripper.POSITION_MIDDLE_LEFT].Left = xChoords[0]; grippers[Gripper.POSITION_MIDDLE_LEFT].Top = yChoords[1];
if((grippers[0].Left < grippers[4].Left && grippers[0].Top < grippers[4].Top) ||
grippers[0].Left > grippers[4].Left && grippers[0].Top > grippers[4].Top) {
grippers[0].Cursor = Cursors.SizeNWSE;
grippers[2].Cursor = Cursors.SizeNESW;
grippers[4].Cursor = Cursors.SizeNWSE;
grippers[6].Cursor = Cursors.SizeNESW;
} else if((grippers[0].Left > grippers[4].Left && grippers[0].Top < grippers[4].Top) ||
grippers[0].Left < grippers[4].Left && grippers[0].Top > grippers[4].Top) {
grippers[0].Cursor = Cursors.SizeNESW;
grippers[2].Cursor = Cursors.SizeNWSE;
grippers[4].Cursor = Cursors.SizeNESW;
grippers[6].Cursor = Cursors.SizeNWSE;
} else if (grippers[0].Left == grippers[4].Left) {
grippers[0].Cursor = Cursors.SizeNS;
grippers[4].Cursor = Cursors.SizeNS;
} else if (grippers[0].Top == grippers[4].Top) {
grippers[0].Cursor = Cursors.SizeWE;
grippers[4].Cursor = Cursors.SizeWE;
if((grippers[Gripper.POSITION_TOP_LEFT].Left < grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && grippers[Gripper.POSITION_TOP_LEFT].Top < grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) ||
grippers[Gripper.POSITION_TOP_LEFT].Left > grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && grippers[Gripper.POSITION_TOP_LEFT].Top > grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) {
grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeNWSE;
grippers[Gripper.POSITION_TOP_RIGHT].Cursor = Cursors.SizeNESW;
grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeNWSE;
grippers[Gripper.POSITION_BOTTOM_LEFT].Cursor = Cursors.SizeNESW;
} else if((grippers[Gripper.POSITION_TOP_LEFT].Left > grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && grippers[Gripper.POSITION_TOP_LEFT].Top < grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) ||
grippers[Gripper.POSITION_TOP_LEFT].Left < grippers[Gripper.POSITION_BOTTOM_RIGHT].Left && grippers[Gripper.POSITION_TOP_LEFT].Top > grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) {
grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeNESW;
grippers[Gripper.POSITION_TOP_RIGHT].Cursor = Cursors.SizeNWSE;
grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeNESW;
grippers[Gripper.POSITION_BOTTOM_LEFT].Cursor = Cursors.SizeNWSE;
} else if (grippers[Gripper.POSITION_TOP_LEFT].Left == grippers[Gripper.POSITION_BOTTOM_RIGHT].Left) {
grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeNS;
grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeNS;
} else if (grippers[Gripper.POSITION_TOP_LEFT].Top == grippers[Gripper.POSITION_BOTTOM_RIGHT].Top) {
grippers[Gripper.POSITION_TOP_LEFT].Cursor = Cursors.SizeWE;
grippers[Gripper.POSITION_BOTTOM_RIGHT].Cursor = Cursors.SizeWE;
}
}
}
@ -270,31 +343,48 @@ namespace Greenshot.Drawing {
mx = e.X;
my = e.Y;
Status = EditStatus.RESIZING;
boundsBeforeResize = new Rectangle(left, top, width, height);
boundsAfterResize = new RectangleF(boundsBeforeResize.Left, boundsBeforeResize.Top, boundsBeforeResize.Width, boundsBeforeResize.Height);
isMadeUndoable = false;
}
private void gripperMouseUp(object sender, MouseEventArgs e) {
Status = EditStatus.IDLE;
boundsBeforeResize = Rectangle.Empty;
boundsAfterResize = RectangleF.Empty;
isMadeUndoable = false;
Invalidate();
}
private void gripperMouseMove(object sender, MouseEventArgs e) {
if(Status.Equals(EditStatus.RESIZING)) {
// check if we already made this undoable
if (!isMadeUndoable) {
// don't allow another undo until we are finished with this move
isMadeUndoable = true;
// Make undo-able
MakeBoundsChangeUndoable(false);
}
Invalidate();
SuspendLayout();
Label gr = (Label)sender;
int gripperIndex = Int16.Parse(gr.Name.Substring(7));
if(gripperIndex <= 2) { // top row
this.Top += e.Y - my;
this.Height -= e.Y - my;
} else if(gripperIndex >= 4 && gripperIndex <= 6) { // bottom row
this.Height += e.Y - my;
}
if(gripperIndex >=2 && gripperIndex <= 4) { // right row
this.Width += e.X - mx;
} else if(gripperIndex >=6 || gripperIndex == 0) { // left row
this.Left += e.X - mx;
this.Width -= e.X - mx;
}
Gripper gr = (Gripper)sender;
int absX = gr.Left + e.X;
int absY = gr.Top + e.Y;
// reset "workbench" rectangle to current bounds
boundsAfterResize.X = boundsBeforeResize.X;
boundsAfterResize.Y = boundsBeforeResize.Y;
boundsAfterResize.Width = boundsBeforeResize.Width;
boundsAfterResize.Height = boundsBeforeResize.Height;
// calculate scaled rectangle
ScaleHelper.Scale(ref boundsAfterResize, gr.Position, new PointF(absX, absY), ScaleHelper.GetScaleOptions());
// apply scaled bounds to this DrawableContainer
ApplyBounds(boundsAfterResize);
ResumeLayout();
Invalidate();
}
@ -359,7 +449,7 @@ namespace Greenshot.Drawing {
}
}
public void ShowGrippers() {
public virtual void ShowGrippers() {
for (int i=0; i<grippers.Length; i++) {
if(grippers[i].Enabled) grippers[i].Show();
else grippers[i].Hide();
@ -374,6 +464,21 @@ namespace Greenshot.Drawing {
}
}
public void ResizeTo(int width, int height, int anchorPosition) {
this.SuspendLayout();
Width = width;
Height = height;
this.ResumeLayout();
}
/// <summary>
/// Make a following bounds change on this drawablecontainer undoable!
/// </summary>
/// <param name="allowMerge">true means allow the moves to be merged</param>
public void MakeBoundsChangeUndoable(bool allowMerge) {
this.parent.MakeUndoable(new DrawableContainerBoundsChangeMemento(this), allowMerge);
}
public void MoveBy(int dx, int dy) {
this.SuspendLayout();
this.Left += dx;
@ -381,6 +486,52 @@ namespace Greenshot.Drawing {
this.ResumeLayout();
}
/// <summary>
/// A handler for the MouseDown, used if you don't want the surface to handle this for you
/// </summary>
/// <param name="x">current mouse x</param>
/// <param name="y">current mouse y</param>
/// <returns>true if the event is handled, false if the surface needs to handle it</returns>
public virtual bool HandleMouseDown(int x, int y) {
Left = boundsBeforeResize.X = x;
Top = boundsBeforeResize.Y = y;
return true;
}
/// <summary>
/// A handler for the MouseMove, used if you don't want the surface to handle this for you
/// </summary>
/// <param name="x">current mouse x</param>
/// <param name="y">current mouse y</param>
/// <returns>true if the event is handled, false if the surface needs to handle it</returns>
public virtual bool HandleMouseMove(int x, int y) {
Invalidate();
SuspendLayout();
// reset "workrbench" rectangle to current bounds
boundsAfterResize.X = boundsBeforeResize.Left;
boundsAfterResize.Y = boundsBeforeResize.Top;
boundsAfterResize.Width = x - boundsAfterResize.Left;
boundsAfterResize.Height = y - boundsAfterResize.Top;
ScaleHelper.Scale(boundsBeforeResize, x, y, ref boundsAfterResize, GetAngleRoundProcessor());
// apply scaled bounds to this DrawableContainer
ApplyBounds(boundsAfterResize);
ResumeLayout();
Invalidate();
return true;
}
/// <summary>
/// A handler for the MouseUp
/// </summary>
/// <param name="x">current mouse x</param>
/// <param name="y">current mouse y</param>
public virtual void HandleMouseUp(int x, int y) {
}
private void SwitchParent(Surface newParent) {
if (parent != null) {
for (int i=0; i<grippers.Length; i++) {
@ -419,6 +570,17 @@ namespace Greenshot.Drawing {
}
}
/// <summary>
/// This method will be called before a field is changes.
/// Using this makes it possible to invalidate the object as is before changing.
/// </summary>
/// <param name="fieldToBeChanged">The field to be changed</param>
/// <param name="newValue">The new value</param>
public virtual void BeforeFieldChange(Field fieldToBeChanged, object newValue) {
parent.MakeUndoable(new ChangeFieldHolderMemento(this, fieldToBeChanged), true);
Invalidate();
}
/// <summary>
/// Handle the field changed event, this should invalidate the correct bounds (e.g. when shadow comes or goes more pixels!)
/// </summary>
@ -431,5 +593,101 @@ namespace Greenshot.Drawing {
}
Invalidate();
}
protected virtual ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() {
return ScaleHelper.ShapeAngleRoundBehavior.Instance;
}
/// <summary>
/// Add items to a context menu for the selected item
/// </summary>
/// <param name="menu"></param>
public virtual void AddContextMenuItems(ContextMenuStrip menu) {
DrawableContainerList myselfAsList = new DrawableContainerList();
myselfAsList.Add(this);
ILanguage lang = Language.GetInstance();
bool push = parent.Elements.CanPushDown(myselfAsList);
bool pull = parent.Elements.CanPullUp(myselfAsList);
ToolStripMenuItem item;
// Pull "up"
if (pull) {
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_uptotop));
item.Click += delegate {
parent.Elements.PullElementsToTop(myselfAsList);
parent.Elements.Invalidate();
};
menu.Items.Add(item);
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_uponelevel));
item.Click += delegate {
parent.Elements.PullElementsUp(myselfAsList);
parent.Elements.Invalidate();
};
menu.Items.Add(item);
}
// Push "down"
if (push) {
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_downtobottom));
item.Click += delegate {
parent.Elements.PushElementsToBottom(myselfAsList);
parent.Elements.Invalidate();
};
menu.Items.Add(item);
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_downonelevel));
item.Click += delegate {
parent.Elements.PushElementsDown(myselfAsList);
parent.Elements.Invalidate();
};
menu.Items.Add(item);
}
// Duplicate
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_duplicate));
item.Click += delegate {
DrawableContainerList dcs = myselfAsList.Clone();
dcs.Parent = parent;
dcs.MoveBy(10,10);
parent.AddElements(dcs);
parent.DeselectAllElements();
parent.SelectElements(dcs);
};
menu.Items.Add(item);
// Copy
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_copytoclipboard));
item.Image = ((System.Drawing.Image)(editorFormResources.GetObject("copyToolStripMenuItem.Image")));
item.Click += delegate {
ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), myselfAsList);
};
menu.Items.Add(item);
// Cut
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_cuttoclipboard));
item.Image = ((System.Drawing.Image)(editorFormResources.GetObject("editor_cuttoclipboard.Image")));
item.Click += delegate {
ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), myselfAsList);
parent.RemoveElement(this, true);
};
menu.Items.Add(item);
// Delete
item = new ToolStripMenuItem(lang.GetString(LangKey.editor_deleteelement));
item.Image = ((System.Drawing.Image)(editorFormResources.GetObject("removeObjectToolStripMenuItem.Image")));
item.Click += delegate {
parent.RemoveElement(this, true);
};
menu.Items.Add(item);
}
public virtual void ShowContextMenu(MouseEventArgs e) {
if (conf.isExperimentalFeatureEnabled("Contextmenu")) {
ContextMenuStrip menu = new ContextMenuStrip();
AddContextMenuItems(menu);
if (menu.Items.Count > 0) {
menu.Show(parent, e.Location);
}
}
}
}
}

View file

@ -19,12 +19,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Drawing.Fields;
using Greenshot.Memento;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
@ -84,6 +82,22 @@ namespace Greenshot.Drawing {
}
}
/// <summary>
/// Make a following bounds change on this containerlist undoable!
/// </summary>
/// <param name="allowMerge">true means allow the moves to be merged</param>
public void MakeBoundsChangeUndoable(bool allowMerge) {
List<IDrawableContainer> movingList = new List<IDrawableContainer>();
Surface surface = null;
foreach(DrawableContainer dc in this) {
movingList.Add(dc);
surface = dc.parent;
}
if (movingList.Count > 0 && surface != null) {
surface.MakeUndoable(new DrawableContainerBoundsChangeMemento(movingList), allowMerge);
}
}
/// <summary>
/// Moves all elements in the list by the given amount of pixels.
/// </summary>
@ -93,14 +107,13 @@ namespace Greenshot.Drawing {
// Track modifications
bool modified = false;
// Invalidate before moving (otherwise the old locations aren't refreshed
// Invalidate before moving, otherwise the old locations aren't refreshed
this.Invalidate();
foreach(DrawableContainer dc in this) {
dc.Left += dx;
dc.Top += dy;
modified = true;
}
// Invalidate after
this.Invalidate();

View file

@ -20,10 +20,8 @@
*/
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Windows.Forms;
using System.Drawing.Drawing2D;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
@ -38,7 +36,7 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
AddField(GetType(), FieldType.SHADOW, false);
AddField(GetType(), FieldType.SHADOW, true);
}
public override void Draw(Graphics graphics, RenderMode renderMode) {
@ -68,10 +66,11 @@ namespace Greenshot.Drawing {
//draw the original shape
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
if (!Color.Transparent.Equals(fillColor)) {
using (Brush brush = new SolidBrush(fillColor)) {
graphics.FillEllipse(brush, rect);
}
}
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
@ -87,5 +86,30 @@ namespace Greenshot.Drawing {
// ellipse: x^2/a^2 + y^2/b^2 = 1
return Math.Pow(xDistanceFromCenter,2)/Math.Pow(Width/2,2) + Math.Pow(yDistanceFromCenter,2)/Math.Pow(Height/2,2) < 1;
}
public override bool ClickableAt(int x, int y) {
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10;
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
// If we clicked inside the rectangle and it's visible we are clickable at.
if (!Color.Transparent.Equals(fillColor)) {
if (Contains(x,y)) {
return true;
}
}
// check the rest of the lines
if (lineThickness > 0) {
using (Pen pen = new Pen(Color.White)) {
pen.Width = lineThickness;
GraphicsPath path = new GraphicsPath();
path.AddEllipse(rect);
return path.IsOutlineVisible(x, y, pen);
}
} else {
return false;
}
}
}
}

View file

@ -20,14 +20,11 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.Helpers;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Drawing.Fields {
/// <summary>
@ -61,7 +58,11 @@ namespace Greenshot.Drawing.Fields {
fieldsByType = new Dictionary<FieldType, Field>();
// listen to changing properties
foreach(Field field in fields) {
field.PropertyChanged += delegate { if(fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); };
field.PropertyChanged += delegate {
if (fieldChanged != null) {
fieldChanged(this, new FieldChangedEventArgs(field));
}
};
fieldsByType[field.FieldType] = field;
}
}
@ -85,7 +86,11 @@ namespace Greenshot.Drawing.Fields {
public void RemoveField(Field field) {
fields.Remove(field);
fieldsByType.Remove(field.FieldType);
field.PropertyChanged -= delegate { if(fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); };
field.PropertyChanged -= delegate {
if (fieldChanged != null) {
fieldChanged(this, new FieldChangedEventArgs(field));
}
};
}
public List<Field> GetFields() {
@ -152,8 +157,9 @@ namespace Greenshot.Drawing.Fields {
}
protected void OnFieldChanged(object sender, FieldChangedEventArgs e){
if(fieldChanged != null) fieldChanged(sender, e);
}
if (fieldChanged != null) {
fieldChanged(sender, e);
}
}
}
}

View file

@ -20,13 +20,8 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Reflection;
using System.Runtime.Serialization;
using Greenshot.Helpers;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Basic IFieldHolderWithChildren implementation. Similar to IFieldHolder,

View file

@ -33,10 +33,16 @@ namespace Greenshot.Drawing.Fields {
public object myValue;
public object Value {
get { return myValue; }
set { if(!object.Equals(myValue,value)) {
get {
return myValue;
}
set {
if (!object.Equals(myValue,value)) {
myValue = value;
if(PropertyChanged!=null) PropertyChanged(this, new PropertyChangedEventArgs("Value")); }
if (PropertyChanged!=null) {
PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
}
}
public FieldType FieldType;

View file

@ -21,13 +21,9 @@
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Reflection;
using Greenshot.Configuration;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Drawing.Fields {
/// <summary>
@ -69,6 +65,7 @@ namespace Greenshot.Drawing.Fields {
BindElement(dc);
}
}
public void BindElement(DrawableContainer dc) {
if (!boundContainers.Contains(dc)) {
boundContainers.Add(dc);
@ -111,7 +108,6 @@ namespace Greenshot.Drawing.Fields {
/// </summary>
private void ClearFields() {
internalUpdateRunning = true;
//if(LOG.IsDebugEnabled) LOG.Debug("Clearing fields internally");
foreach(Field field in GetFields()) {
field.Value = null;
}
@ -151,19 +147,24 @@ namespace Greenshot.Drawing.Fields {
}
}
}
if(ret == null) ret = new List<Field>();
if (ret == null) {
ret = new List<Field>();
}
return ret;
}
public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea) {
Field field = (Field) sender;
if (!internalUpdateRunning && field.Value != null) {
foreach(DrawableContainer dc in boundContainers) {
if(dc.HasField(field.FieldType)) {
Field dcf = dc.GetField(field.FieldType);
dcf.Value = field.Value;
foreach(DrawableContainer drawableContainer in boundContainers) {
if (drawableContainer.HasField(field.FieldType)) {
Field drawableContainerField = drawableContainer.GetField(field.FieldType);
// Notify before change, so we can e.g. invalidate the area
drawableContainer.BeforeFieldChange(drawableContainerField, field.Value);
drawableContainerField.Value = field.Value;
// update last used from DC field, so that scope is honored
editorConfiguration.UpdateLastFieldValue(dcf);
editorConfiguration.UpdateLastFieldValue(drawableContainerField);
}
}
}

View file

@ -19,7 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
namespace Greenshot.Drawing.Fields {
/// <summary>

View file

@ -19,14 +19,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;

View file

@ -19,14 +19,12 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.Serialization;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
/// <summary>
/// Graphical filter which can be added to DrawableContainer.

View file

@ -16,15 +16,10 @@
/////////////////////////////////////////////////////////////////////////////////
using System;
using System.ComponentModel;
using System.Drawing;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
namespace Greenshot.Drawing.Filters {
[Serializable()]
@ -78,14 +73,13 @@ namespace Greenshot.Drawing.Filters {
int r = blurRadius;
int[] w = CreateGaussianBlurRow(r);
int wlen = w.Length;
long[] waSums = new long[wlen];
long[] wcSums = new long[wlen];
long[] aSums = new long[wlen];
long[] bSums = new long[wlen];
long[] gSums = new long[wlen];
long[] rSums = new long[wlen];
for (int y = 0; y < applyRect.Height; ++y) {
long* waSums = stackalloc long[wlen];
long* wcSums = stackalloc long[wlen];
long* aSums = stackalloc long[wlen];
long* bSums = stackalloc long[wlen];
long* gSums = stackalloc long[wlen];
long* rSums = stackalloc long[wlen];
long waSum = 0;
long wcSum = 0;
long aSum = 0;

View file

@ -20,10 +20,6 @@
*/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;

View file

@ -1,231 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
[Serializable()]
public class FastSmoothFilter : AbstractFilter {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(FastSmoothFilter));
public FastSmoothFilter(DrawableContainer parent) : base(parent) {
AddField(GetType(), FieldType.BLUR_RADIUS, 3);
}
public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle applyRect, RenderMode renderMode) {
Rectangle sourceRect = new Rectangle(applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height);
Rectangle bitmapRect = new Rectangle(0,0, applyBitmap.Width, applyBitmap.Height);
if(sourceRect.Equals(Rectangle.Empty)) {
sourceRect = bitmapRect;
} else {
sourceRect.Intersect(bitmapRect);
}
// Does the rect have any pixels?
if (sourceRect.Height <= 0 || sourceRect.Width <= 0) {
return;
}
int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
// Calculate new sourceRect to include the matrix size if possible
int leftOffset = Math.Min(sourceRect.X, blurRadius);
int rightOffset = Math.Min(applyBitmap.Width - (sourceRect.X + sourceRect.Width), blurRadius);
int topOffset = Math.Min(sourceRect.Y, blurRadius);
int bottomOffset = Math.Min(applyBitmap.Height - (sourceRect.Y + sourceRect.Height), blurRadius);
LOG.Debug(String.Format("Offsets: {0},{1},{2},{3}", leftOffset, rightOffset, topOffset, bottomOffset));
LOG.Debug(String.Format("SourceRect before: {0},{1},{2},{3}", sourceRect.X, sourceRect.Width, sourceRect.Y, sourceRect.Height));
sourceRect.X -= leftOffset;
sourceRect.Width += leftOffset + rightOffset;
sourceRect.Y -= topOffset;
sourceRect.Height += topOffset + bottomOffset;
LOG.Debug(String.Format("SourceRect after: {0},{1},{2},{3}", sourceRect.X, sourceRect.Width, sourceRect.Y, sourceRect.Height));
// Make a copy of the applyBitmap for reading
using (Bitmap sourceBitmap = applyBitmap.Clone(sourceRect, applyBitmap.PixelFormat)) {
ApplySmooth(sourceBitmap, applyBitmap, sourceRect, blurRadius);
}
}
public static bool ApplySmooth(Bitmap sourceBitmap, Bitmap destinationBitmap, Rectangle destRectangle, int blurRadius) {
if (blurRadius < 1) {
return false;
}
BitmapData destbitmapData = destinationBitmap.LockBits(destRectangle, ImageLockMode.WriteOnly, destinationBitmap.PixelFormat);
BitmapData srcBitmapData = sourceBitmap.LockBits(new Rectangle(0, 0, sourceBitmap.Width, sourceBitmap.Height),
ImageLockMode.ReadOnly,
sourceBitmap.PixelFormat);
int destStride = destbitmapData.Stride;
int srcStride = srcBitmapData.Stride;
IntPtr destScan0 = destbitmapData.Scan0;
IntPtr srcScan0 = srcBitmapData.Scan0;
int bIndex;
int gIndex;
int rIndex;
//int aIndex;
int bytesPerPixel;
switch(destinationBitmap.PixelFormat) {
case PixelFormat.Format32bppArgb:
// GDI+ lies to us - the return format is BGR, NOT RGB.
bIndex = 0;
gIndex = 1;
rIndex = 2;
//aIndex = 3;
bytesPerPixel = 4;
break;
case PixelFormat.Format32bppRgb:
// GDI+ lies to us - the return format is BGR, NOT RGB.
bIndex = 0;
gIndex = 1;
rIndex = 2;
bytesPerPixel = 4;
break;
case PixelFormat.Format24bppRgb:
// GDI+ lies to us - the return format is BGR, NOT RGB.
bIndex = 0;
gIndex = 1;
rIndex = 2;
bytesPerPixel = 3;
break;
default:
throw new FormatException("Bitmap.Pixelformat."+destinationBitmap.PixelFormat+" is currently not supported. Supported: Format32bpp(A)Rgb, Format24bppRgb");
}
long ticks = DateTime.Now.Ticks;
unsafe {
int width = destRectangle.Width - (blurRadius*2);
int height = destRectangle.Height - (blurRadius*2);
int diameter = (2 * blurRadius) + 1;
int mid = ((diameter-1)/2) + 1;
int midPixel = mid * bytesPerPixel;
int midLine = (mid - 1) * destStride;
int writeRPixelOffset = midLine + midPixel + rIndex;
int writeGPixelOffset = midLine + midPixel + gIndex;
int writeBPixelOffset = midLine + midPixel + bIndex;
int readRPixelOffset = diameter * bytesPerPixel + rIndex;
int readGPixelOffset = diameter * bytesPerPixel + gIndex;
int readBPixelOffset = diameter * bytesPerPixel + bIndex;
int destOffset = destStride - (width*bytesPerPixel);
int srcOffset = srcStride - (width*bytesPerPixel);
int factor = diameter * diameter;
byte *destBitmapPointer = (byte *)(void *)destScan0;
byte *srcBitmapPointer = (byte *)(void *)srcScan0;
int pixel, lineOffset;
int rTotal, gTotal, bTotal;
int [,]r = new int[diameter,diameter];
int [,]g = new int[diameter,diameter];
int [,]b = new int[diameter,diameter];
for (int y=0; y < height; y++) {
// Reset totals
rTotal = gTotal = bTotal = 0;
// Intial load: Do the complete radius, fill the arrays with their values
lineOffset = 0; // Offset relative to the srcBitmapPointer
// Vertical loop
for (int v = 0; v < diameter; v++) {
// Start at beginning of the current line
int index = lineOffset;
// Horizontal loop
for (int currentRow = 0; currentRow < diameter; currentRow++) {
// Get & add values
rTotal += r[v,currentRow] = srcBitmapPointer[index + rIndex];
gTotal += g[v,currentRow] = srcBitmapPointer[index + gIndex];
bTotal += b[v,currentRow] = srcBitmapPointer[index + bIndex];
// Move 1px to the right
index += bytesPerPixel;
}
// Move to next line
lineOffset += srcStride;
}
// Now loop the complete line from left to right
for (int x=0; x < width; x++ ) {
// Draw Pixel with calculated values
pixel = rTotal / factor;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
destBitmapPointer[writeRPixelOffset]= (byte)pixel;
pixel = gTotal / factor;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
destBitmapPointer[writeGPixelOffset]= (byte)pixel;
pixel = bTotal / factor;
if (pixel < 0) pixel = 0;
if (pixel > 255) pixel = 255;
destBitmapPointer[writeBPixelOffset]= (byte)pixel;
// Update values with next "row"
int oldRow = x % diameter;
srcBitmapPointer += bytesPerPixel;
lineOffset = 0;
// Vertical Loop, subtract the stored value and add the new value
for (int v = 0; v < diameter; v++) {
// Subtrace the first value, so we can add the new later
rTotal -= r[v, oldRow];
gTotal -= g[v, oldRow];
bTotal -= b[v, oldRow];
// Get & add the next values
rTotal += r[v, oldRow] = srcBitmapPointer[readRPixelOffset + lineOffset];
gTotal += g[v, oldRow] = srcBitmapPointer[readGPixelOffset + lineOffset];
bTotal += b[v, oldRow] = srcBitmapPointer[readBPixelOffset + lineOffset];
// Goto next line
lineOffset += srcStride;
}
destBitmapPointer += bytesPerPixel;
}
srcBitmapPointer += srcOffset;
destBitmapPointer += destOffset;
}
}
LOG.Info("Ticks = " + (DateTime.Now.Ticks - ticks));
destinationBitmap.UnlockBits(destbitmapData);
sourceBitmap.UnlockBits(srcBitmapData);
return true;
}
/**
* Checks if the supplied Bitmap has a PixelFormat we support
*/
private bool SupportsPixelFormat(Bitmap bitmap) {
return (bitmap.PixelFormat.Equals(PixelFormat.Format32bppArgb) ||
bitmap.PixelFormat.Equals(PixelFormat.Format32bppRgb) ||
bitmap.PixelFormat.Equals(PixelFormat.Format24bppRgb));
}
}
}

View file

@ -20,10 +20,6 @@
*/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
/// <summary>

View file

@ -20,10 +20,6 @@
*/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;

View file

@ -19,11 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;

View file

@ -20,12 +20,9 @@
*/
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
namespace Greenshot.Drawing.Filters {
[Serializable()]

View file

@ -21,13 +21,11 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
namespace Greenshot.Drawing.Filters {
[Serializable()]

View file

@ -0,0 +1,272 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.ComponentModel;
using System.Collections.Generic;
using System.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Description of PathContainer.
/// </summary>
[Serializable()]
public class FreehandContainer : DrawableContainer {
private static readonly float [] POINT_OFFSET = new float[]{0.5f, 0.25f, 0.75f};
[NonSerialized]
private GraphicsPath freehandPath = new GraphicsPath();
private Rectangle myBounds = Rectangle.Empty;
private Point lastMouse = Point.Empty;
private List<Point> capturePoints = new List<Point>();
private bool isRecalculated = false;
/// <summary>
/// Constructor
/// </summary>
public FreehandContainer(Surface parent) : base(parent) {
Init();
AddField(GetType(), FieldType.LINE_THICKNESS, 3);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
Width = parent.Width;
Height = parent.Height;
Top = 0;
Left = 0;
}
protected void Init() {
for(int i=0; i<grippers.Length; i++) {
grippers[i].Enabled = false;
grippers[i].Visible = false;
}
}
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
InitGrippers();
DoLayout();
Init();
RecalculatePath();
}
/// <summary>
/// Destructor
/// </summary>
~FreehandContainer() {
Dispose(false);
}
/// <summary>
/// The public accessible Dispose
/// Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
/// </summary>
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
/// <summary>
/// This Dispose is called from the Dispose and the Destructor.
/// </summary>
/// <param name="disposing">When disposing==true all non-managed resources should be freed too!</param>
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (freehandPath != null) {
freehandPath.Dispose();
}
}
freehandPath = null;
}
/// <summary>
/// Called from Surface (the parent) when the drawing begins (mouse-down)
/// </summary>
/// <returns>true if the surface doesn't need to handle the event</returns>
public override bool HandleMouseDown(int mouseX, int mouseY) {
lastMouse = new Point(mouseX, mouseY);
capturePoints.Add(lastMouse);
return true;
}
/// <summary>
/// Called from Surface (the parent) if a mouse move is made while drawing
/// </summary>
/// <returns>true if the surface doesn't need to handle the event</returns>
public override bool HandleMouseMove(int mouseX, int mouseY) {
Point previousPoint = capturePoints[capturePoints.Count-1];
if (GeometryHelper.Distance2D(previousPoint.X, previousPoint.Y, mouseX, mouseY ) > 5) {
capturePoints.Add(new Point(mouseX, mouseY));
}
if (GeometryHelper.Distance2D(lastMouse.X, lastMouse.Y, mouseX, mouseY) > 2 ) {
//path.AddCurve(new Point[]{lastMouse, new Point(mouseX, mouseY)});
freehandPath.AddLine(lastMouse, new Point(mouseX, mouseY));
lastMouse = new Point(mouseX, mouseY);
// Only re-calculate the bounds & redraw when we added something to the path
myBounds = Rectangle.Round(freehandPath.GetBounds());
Invalidate();
}
return true;
}
/// <summary>
/// Called when the surface finishes drawing the element
/// </summary>
public override void HandleMouseUp(int mouseX, int mouseY) {
// Make sure we don't loose the ending point
if (GeometryHelper.Distance2D(lastMouse.X, lastMouse.Y, mouseX, mouseY) > 2) {
capturePoints.Add(new Point(mouseX, mouseY));
}
RecalculatePath();
}
/// <summary>
/// Here we recalculate the freehand path by smoothing out the lines with Beziers.
/// </summary>
private void RecalculatePath() {
isRecalculated = true;
// Dispose the previous path, if we have one
if (freehandPath != null) {
freehandPath.Dispose();
}
freehandPath = new GraphicsPath();
// Here we can put some cleanup... like losing all the uninteresting points.
if (capturePoints.Count > 3) {
int index = 0;
while ((capturePoints.Count - 1) % 3 != 0) {
// duplicate points, first at 50% than 25% than 75%
capturePoints.Insert((int)(capturePoints.Count*POINT_OFFSET[index]), capturePoints[(int)(capturePoints.Count*POINT_OFFSET[index++])]);
}
freehandPath.AddBeziers(capturePoints.ToArray());
}
// Recalculate the bounds
myBounds = Rectangle.Round(freehandPath.GetBounds());
}
/// <summary>
/// Do the drawing of the freehand "stroke"
/// </summary>
/// <param name="graphics"></param>
/// <param name="renderMode"></param>
public override void Draw(Graphics graphics, RenderMode renderMode) {
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if (pen.Width > 0) {
// Make sure the lines are nicely rounded
pen.EndCap = LineCap.Round;
pen.StartCap = LineCap.Round;
pen.LineJoin = LineJoin.Round;
// Move to where we need to draw
graphics.TranslateTransform(Left,Top);
if (isRecalculated && Selected && renderMode == RenderMode.EDIT) {
DrawSelectionBorder(graphics, pen);
}
graphics.DrawPath(pen, freehandPath);
// Move back, otherwise everything is shifted
graphics.TranslateTransform(-Left,-Top);
}
}
}
/// <summary>
/// Draw a selectionborder around the freehand path
/// </summary>
/// <param name="graphics"></param>
/// <param name="linePen"></param>
protected void DrawSelectionBorder(Graphics graphics, Pen linePen) {
using (Pen selectionPen = (Pen) linePen.Clone()) {
using (GraphicsPath selectionPath = (GraphicsPath) freehandPath.Clone()) {
selectionPen.Width += 5;
selectionPen.Color = Color.FromArgb(120, Color.LightSeaGreen);
graphics.DrawPath(selectionPen, selectionPath);
selectionPath.Widen(selectionPen);
selectionPen.DashPattern = new float[]{2,2};
selectionPen.Color = Color.LightSeaGreen;
selectionPen.Width = 1;
graphics.DrawPath(selectionPen, selectionPath);
}
}
}
/// <summary>
/// Get the bounds in which we have something drawn, plus safety margin, these are not the normal bounds...
/// </summary>
public override Rectangle DrawingBounds {
get {
if (!myBounds.IsEmpty) {
int lineThickness = Math.Max(10, GetFieldValueAsInt(FieldType.LINE_THICKNESS));
int safetymargin = 10;
return new Rectangle((myBounds.Left + Left) - (safetymargin+lineThickness), (myBounds.Top + Top) - (safetymargin+lineThickness), myBounds.Width + (2*(lineThickness+safetymargin)), myBounds.Height + (2*(lineThickness+safetymargin)));
} else {
return parent.Bounds;
}
}
}
// FreehandContainer are regarded equal if they are of the same type and their paths are equal.
public override bool Equals(object obj) {
bool ret = false;
if(obj != null && GetType().Equals(obj.GetType())) {
FreehandContainer other = obj as FreehandContainer;
if(freehandPath.Equals(other.freehandPath)) {
ret = true;
}
}
return ret;
}
public override int GetHashCode() {
return freehandPath.GetHashCode();
}
protected override void DoLayout() {
}
public override void ShowGrippers() {
this.ResumeLayout();
}
public override bool ClickableAt(int x, int y) {
bool returnValue = base.ClickableAt(x, y);
if (returnValue) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
using (Pen pen = new Pen(Color.White)) {
pen.Width = lineThickness + 10;
returnValue = freehandPath.IsOutlineVisible(x-Left,y-Top, pen);
}
}
return returnValue;
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Drawing;
using System.Windows.Forms;
namespace Greenshot.Drawing
{
/// <summary>
/// Description of Gripper.
/// </summary>
public class Gripper : Label {
/// <summary>
/// Constants for anchor/gripper position:
/// 0 1 2
/// 7 3
/// 6 5 4
/// </summary>
public const int POSITION_TOP_LEFT = 0;
public const int POSITION_TOP_CENTER = 1;
public const int POSITION_TOP_RIGHT = 2;
public const int POSITION_MIDDLE_RIGHT = 3;
public const int POSITION_BOTTOM_RIGHT = 4;
public const int POSITION_BOTTOM_CENTER = 5;
public const int POSITION_BOTTOM_LEFT = 6;
public const int POSITION_MIDDLE_LEFT = 7;
public int Position;
public Gripper() {
Width = 5;
Height = 5;
BackColor = Color.Black;
}
public bool IsTop() {
return Position == 0 || Position == 1 || Position == 2;
}
public bool IsRight() {
return Position == 2 || Position == 3 || Position == 4;
}
public bool IsBottom() {
return Position == 4 || Position == 5 || Position == 6;
}
public bool IsLeft() {
return Position == 6 || Position == 7 || Position == 0;
}
public bool IsCorner() {
return Position == 0 || Position == 2 || Position == 4 || Position == 6;
}
}
}

View file

@ -21,12 +21,8 @@
using System;
using System.Drawing;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
@ -104,5 +100,17 @@ namespace Greenshot.Drawing {
graphics.DrawIcon(icon, Bounds);
}
}
public override void AddContextMenuItems(ContextMenuStrip menu) {
base.AddContextMenuItems(menu);
ToolStripMenuItem resetItem = new ToolStripMenuItem("Reset size");
resetItem.Click += delegate {
this.Invalidate();
Width = icon.Size.Width;
Height = icon.Size.Height;
this.Invalidate();
};
menu.Items.Add(resetItem);
}
}
}

View file

@ -19,13 +19,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
@ -40,22 +37,27 @@ namespace Greenshot.Drawing {
public LineContainer(Surface parent) : base(parent) {
Init();
AddField(GetType(), FieldType.LINE_THICKNESS, 1);
AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.SHADOW, false);
AddField(GetType(), FieldType.SHADOW, true);
}
private void Init() {
grippers[1].Enabled = false;
grippers[2].Enabled = false;
grippers[3].Enabled = false;
grippers[5].Enabled = false;
grippers[6].Enabled = false;
grippers[7].Enabled = false;
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
InitGrippers();
DoLayout();
Init();
}
public override void Draw(Graphics g, RenderMode rm) {
g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
protected void Init() {
foreach(int index in new int[]{1,2,3,5,6,7}) {
grippers[index].Enabled = false;
}
}
public override void Draw(Graphics graphics, RenderMode rm) {
graphics.SmoothingMode = SmoothingMode.AntiAlias;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
@ -71,7 +73,7 @@ namespace Greenshot.Drawing {
using (Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowCapPen.Width = lineThickness;
g.DrawLine(shadowCapPen,
graphics.DrawLine(shadowCapPen,
this.Left + currentStep,
this.Top + currentStep,
this.Left + currentStep + this.Width,
@ -83,24 +85,32 @@ namespace Greenshot.Drawing {
}
}
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if(pen.Width > 0) {
g.DrawLine(pen, this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
graphics.DrawLine(pen, this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
}
}
}
public override bool ClickableAt(int x, int y) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
double distance = DrawingHelper.CalculateLinePointDistance(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height, x, y);
if (distance < 0) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) +5;
if (lineThickness > 0) {
using (Pen pen = new Pen(Color.White)) {
pen.Width = lineThickness;
GraphicsPath path = new GraphicsPath();
path.AddLine(this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
return path.IsOutlineVisible(x,y, pen);
}
} else {
return false;
}
return distance <= Math.Max(lineThickness / 2, MAX_CLICK_DISTANCE_TOLERANCE);
}
protected override ScaleHelper.IDoubleProcessor GetAngleRoundProcessor() {
return ScaleHelper.LineAngleRoundBehavior.Instance;
}
}
}

View file

@ -22,12 +22,7 @@ using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
@ -107,8 +102,8 @@ namespace Greenshot.Drawing {
public void Load(string filename) {
if (File.Exists(filename)) {
using (Metafile fileMetafile = new Metafile(filename)) {
Metafile = fileMetafile;
using (Stream imageFileStream = File.OpenRead(filename)) {
Metafile = (Metafile)Image.FromStream(imageFileStream, true, true);
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}

View file

@ -20,10 +20,7 @@
*/
using System;
using System.Drawing;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using System.Drawing.Drawing2D;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
@ -40,7 +37,7 @@ namespace Greenshot.Drawing {
AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
AddField(GetType(), FieldType.SHADOW, false);
AddField(GetType(), FieldType.SHADOW, true);
}
@ -73,9 +70,11 @@ namespace Greenshot.Drawing {
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
if (!Color.Transparent.Equals(fillColor)) {
using (Brush brush = new SolidBrush(fillColor)) {
g.FillRectangle(brush, rect);
}
}
if (lineThickness > 0) {
using (Pen pen = new Pen(lineColor)) {
@ -85,5 +84,29 @@ namespace Greenshot.Drawing {
}
}
public override bool ClickableAt(int x, int y) {
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS) + 10;
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
// If we clicked inside the rectangle and it's visible we are clickable at.
if (!Color.Transparent.Equals(fillColor)) {
if (rect.Contains(x,y)) {
return true;
}
}
// check the rest of the lines
if (lineThickness > 0) {
using (Pen pen = new Pen(Color.White)) {
pen.Width = lineThickness;
GraphicsPath path = new GraphicsPath();
path.AddRectangle(rect);
return path.IsOutlineVisible(x, y, pen);
}
} else {
return false;
}
}
}
}

View file

@ -24,23 +24,22 @@ using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Core;
using Greenshot.Memento;
using IniFile;
namespace Greenshot.Drawing {
public delegate void SurfaceElementEventHandler(object source, DrawableContainerList element);
public delegate void SurfaceDrawingModeEventHandler(object source, DrawingModes drawingMode);
public enum DrawingModes { None, Rect, Ellipse, Text, Line, Arrow, Crop, Highlight, Obfuscate, Bitmap }
public enum DrawingModes { None, Rect, Ellipse, Text, Line, Arrow, Crop, Highlight, Obfuscate, Bitmap, Path }
/// <summary>
/// Description of Surface.
/// </summary>
@ -49,6 +48,13 @@ namespace Greenshot.Drawing {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
public event SurfaceElementEventHandler MovingElementChanged;
public event SurfaceDrawingModeEventHandler DrawingModeChanged;
public event SurfaceSizeChangeEventHandler SurfaceSizeChanged;
public event SurfaceMessageEventHandler SurfaceMessage;
private bool inUndoRedo = false;
private bool isSurfaceMoveMadeUndoable = false;
private Stack<IMemento> undoStack = new Stack<IMemento>();
private Stack<IMemento> redoStack = new Stack<IMemento>();
private string lastSaveFullPath = null;
public FieldAggregator FieldAggregator = new FieldAggregator();
@ -100,6 +106,15 @@ namespace Greenshot.Drawing {
}
}
public string LastSaveFullPath {
get {
return lastSaveFullPath;
}
set {
lastSaveFullPath = value;
}
}
public ICaptureDetails CaptureDetails {
get {return captureDetails;}
set {captureDetails = value;}
@ -125,22 +140,22 @@ namespace Greenshot.Drawing {
/// <summary>
/// Private method, the current image is disposed the new one will stay.
/// </summary>
/// <param name="image"></param>
private void SetImage(Image image) {
/// <param name="image">The new image</param>
/// <param name="dispose">true if the old image needs to be disposed, when using undo this should not be true!!</param>
private void SetImage(Image image, bool dispose) {
// Dispose
if (Image != null) {
if (Image != null && dispose) {
Image.Dispose();
}
// Set new values
Image = image;
modified = true;
}
public Surface(Image image) : this() {
LOG.Debug("Got image with dimensions " + image.Width + "," + image.Height + " bpp: " + image.PixelFormat);
SetImage(image);
SetImage(image, true);
}
public Surface(ICapture capture) : this(capture.Image) {
@ -153,6 +168,110 @@ namespace Greenshot.Drawing {
captureDetails = capture.CaptureDetails;
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
LOG.Debug("Disposing a surface!");
if (buffer != null) {
buffer.Dispose();
buffer = null;
}
if (transparencyBackgroundBrush != null) {
transparencyBackgroundBrush.Dispose();
transparencyBackgroundBrush = null;
}
// Cleanup undo/redo stacks
while(undoStack != null && undoStack.Count > 0) {
undoStack.Pop().Dispose();
}
while(redoStack != null && redoStack.Count > 0) {
redoStack.Pop().Dispose();
}
base.Dispose();
GC.SuppressFinalize(this);
}
/// <summary>
/// Undo the last action
/// </summary>
public void Undo() {
if (undoStack.Count > 0) {
inUndoRedo = true;
IMemento top = undoStack.Pop();
redoStack.Push(top.Restore());
inUndoRedo = false;
}
}
/// <summary>
/// Undo an undo (=redo)
/// </summary>
public void Redo() {
if (redoStack.Count > 0) {
inUndoRedo = true;
IMemento top = redoStack.Pop();
undoStack.Push(top.Restore());
inUndoRedo = false;
}
}
public bool CanUndo {
get {
return undoStack.Count > 0;
}
}
public bool CanRedo {
get {
return redoStack.Count > 0;
}
}
public LangKey UndoActionKey {
get {
if (CanUndo) {
return undoStack.Peek().ActionKey;
} else {
return LangKey.none;
}
}
}
public LangKey RedoActionKey {
get {
if (CanRedo) {
return redoStack.Peek().ActionKey;
} else {
return LangKey.none;
}
}
}
/// <summary>
/// Make an action undo-able
/// </summary>
/// <param name="memento">The memento implementing the undo</param>
public void MakeUndoable(IMemento memento, bool allowMerge) {
if (inUndoRedo) {
throw new InvalidOperationException("Involking do within an undo/redo action.");
}
if (memento != null) {
bool allowPush = true;
if (undoStack.Count > 0 && allowMerge) {
// Check if merge is possible
allowPush = !undoStack.Peek().Merge(memento);
}
if (allowPush) {
// Clear the redo-stack and dispose
while(redoStack.Count > 0) {
redoStack.Pop().Dispose();
}
undoStack.Push(memento);
}
}
}
public void SaveElementsToStream(Stream streamWrite) {
try {
BinaryFormatter binaryWrite = new BinaryFormatter();
@ -211,6 +330,9 @@ namespace Greenshot.Drawing {
case DrawingModes.Bitmap:
undrawnElement = new BitmapContainer(this);
break;
case DrawingModes.Path:
undrawnElement = new FreehandContainer(this);
break;
case DrawingModes.None:
undrawnElement = null;
break;
@ -317,7 +439,7 @@ namespace Greenshot.Drawing {
foreach(string filename in dropFileNames) {
LOG.Debug("Found filename: " + filename);
string ext=Path.GetExtension(filename).ToLower();
if ((ext==".jpg") || (ext==".gif") || (ext==".png") || (ext==".bmp") || (ext==".wmf")) {
if ((ext==".jpg") || (ext==".jpeg") ||(ext==".tiff") || (ext==".gif") || (ext==".png") || (ext==".bmp") || (ext==".ico") ||(ext==".wmf")) {
filenames.Add(filename);
}
}
@ -379,7 +501,28 @@ namespace Greenshot.Drawing {
// }
#endregion
bool ApplyCrop(Rectangle cropRectangle) {
/// <summary>
/// Auto crop the image
/// </summary>
/// <returns>true if cropped</returns>
public bool AutoCrop() {
Rectangle cropRectangle = ImageHelper.FindAutoCropRectangle(Image);
if (isCropPossible(ref cropRectangle)) {
DrawingMode = DrawingModes.Crop;
cropContainer = new CropContainer(this);
cropContainer.Left = cropRectangle.X;
cropContainer.Top = cropRectangle.Y;
cropContainer.Width = cropRectangle.Width;
cropContainer.Height = cropRectangle.Height;
DeselectAllElements();
AddElement(cropContainer);
SelectElement(cropContainer);
return true;
}
return false;
}
public bool isCropPossible(ref Rectangle cropRectangle) {
cropRectangle = Helpers.GuiRectangle.GetGuiRectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, cropRectangle.Height);
if (cropRectangle.Left < 0) cropRectangle = new Rectangle(0, cropRectangle.Top, cropRectangle.Width + cropRectangle.Left, cropRectangle.Height);
if (cropRectangle.Top < 0) cropRectangle = new Rectangle(cropRectangle.Left, 0, cropRectangle.Width, cropRectangle.Height + cropRectangle.Top);
@ -387,29 +530,73 @@ namespace Greenshot.Drawing {
if (cropRectangle.Top + cropRectangle.Height > Height) cropRectangle = new Rectangle(cropRectangle.Left, cropRectangle.Top, cropRectangle.Width, Height - cropRectangle.Top);
if (cropRectangle.Height > 0 && cropRectangle.Width > 0) {
return true;
}
return false;
}
public void SendMessageEvent(object source, SurfaceMessageTyp messageType, string message) {
if (SurfaceMessage != null) {
SurfaceMessageEventArgs eventArgs = new SurfaceMessageEventArgs();
eventArgs.Message = message;
eventArgs.MessageType = messageType;
eventArgs.Surface = this;
SurfaceMessage(source, eventArgs);
}
}
public bool ApplyCrop(Rectangle cropRectangle) {
if (isCropPossible(ref cropRectangle)) {
// we should not forget to Dispose the images!!
Bitmap tmpImage = ((Bitmap)Image).Clone(cropRectangle, Image.PixelFormat);
tmpImage.SetResolution(Image.HorizontalResolution, Image.VerticalResolution);
SetImage(tmpImage);
// Make undoable
MakeUndoable(new SurfaceCropMemento(this, cropRectangle), false);
SetImage(tmpImage, false);
elements.MoveBy(-cropRectangle.Left, -cropRectangle.Top);
if (SurfaceSizeChanged != null) {
SurfaceSizeChanged(this);
}
Invalidate();
return true;
}
return false;
}
private Point GetMouseCoordinates(MouseEventArgs e) {
//Point mouseLocation = new Point(e.X - AutoScrollPosition.X, e.Y - AutoScrollPosition.Y);
Point mouseLocation = new Point(e.X, e.Y);
return mouseLocation;
public void UndoCrop(Image previous, Rectangle cropRectangle) {
SetImage(previous, false);
elements.MoveBy(cropRectangle.Left, cropRectangle.Top);
if (SurfaceSizeChanged != null) {
SurfaceSizeChanged(this);
}
Invalidate();
}
void SurfaceMouseDown(object sender, MouseEventArgs e) {
mouseStart = GetMouseCoordinates(e);
mouseStart = e.Location;
// check contextmenu
if (e.Button == MouseButtons.Right) {
if (selectedElements != null && selectedElements.Count > 0) {
// ContainerList logik hier
} else {
// Single element
DrawableContainer rightClickedContainer = elements.ClickableElementAt(mouseStart.X, mouseStart.Y);
if (rightClickedContainer != null) {
SelectElement(rightClickedContainer);
rightClickedContainer.ShowContextMenu(e);
}
}
return;
}
mouseDown = true;
isSurfaceMoveMadeUndoable = false;
if (cropContainer != null && ((undrawnElement == null) || (undrawnElement != null && DrawingMode != DrawingModes.Crop))) {
RemoveElement(cropContainer);
RemoveElement(cropContainer, false);
cropContainer = null;
drawingElement = null;
}
@ -427,8 +614,10 @@ namespace Greenshot.Drawing {
// if a new element has been drawn, set location and register it
if (drawingElement != null) {
drawingElement.PropertyChanged += ElementPropertyChanged;
if (!drawingElement.HandleMouseDown(mouseStart.X, mouseStart.Y)) {
drawingElement.Left = mouseStart.X;
drawingElement.Top = mouseStart.Y;
}
AddElement(drawingElement);
drawingElement.Selected = true;
}
@ -437,6 +626,7 @@ namespace Greenshot.Drawing {
// we save mouse down element separately from selectedElements (checked on mouse up),
// since it could be moved around before it is actually selected
mouseDownElement = elements.ClickableElementAt(mouseStart.X, mouseStart.Y);
if (mouseDownElement != null) {
mouseDownElement.Status = EditStatus.MOVING;
}
@ -444,7 +634,7 @@ namespace Greenshot.Drawing {
}
void SurfaceMouseUp(object sender, MouseEventArgs e) {
Point currentMouse = GetMouseCoordinates(e);
Point currentMouse = new Point(e.X, e.Y);
elements.Status = EditStatus.IDLE;
if (mouseDownElement != null) {
@ -482,11 +672,12 @@ namespace Greenshot.Drawing {
}
if (drawingElement != null) {
drawingElement.Invalidate();
if (!drawingElement.InitContent()) {
elements.Remove(drawingElement);
drawingElement.Invalidate();
} else {
drawingElement.HandleMouseUp(currentMouse.X, currentMouse.Y);
drawingElement.Invalidate();
if (Math.Abs(drawingElement.Width) < 5 && Math.Abs(drawingElement.Height) < 5) {
drawingElement.Width = 25;
drawingElement.Height = 25;
@ -499,7 +690,7 @@ namespace Greenshot.Drawing {
}
void SurfaceMouseMove(object sender, MouseEventArgs e) {
Point currentMouse = GetMouseCoordinates(e);
Point currentMouse = e.Location;
if (DrawingMode != DrawingModes.None) {
Cursor = Cursors.Cross;
@ -511,10 +702,21 @@ namespace Greenshot.Drawing {
if(mouseDownElement != null) { // an element is currently dragged
mouseDownElement.Invalidate();
selectedElements.HideGrippers();
// Move the element
if(mouseDownElement.Selected) {
if (!isSurfaceMoveMadeUndoable) {
// Only allow one undoable per mouse-down/move/up "cycle"
isSurfaceMoveMadeUndoable = true;
selectedElements.MakeBoundsChangeUndoable(false);
}
// dragged element has been selected before -> move all
selectedElements.MoveBy(currentMouse.X - mouseStart.X, currentMouse.Y - mouseStart.Y);
} else {
if (!isSurfaceMoveMadeUndoable) {
// Only allow one undoable per mouse-down/move/up "cycle"
isSurfaceMoveMadeUndoable = true;
mouseDownElement.MakeBoundsChangeUndoable(false);
}
// dragged element is not among selected elements -> just move dragged one
mouseDownElement.MoveBy(currentMouse.X - mouseStart.X, currentMouse.Y - mouseStart.Y);
}
@ -522,11 +724,7 @@ namespace Greenshot.Drawing {
mouseDownElement.Invalidate();
modified = true;
} else if(drawingElement != null) {
// an element is currently drawn
drawingElement.Invalidate();
drawingElement.Width = currentMouse.X - drawingElement.Left;
drawingElement.Height = currentMouse.Y - drawingElement.Top;
drawingElement.Invalidate();
drawingElement.HandleMouseMove(currentMouse.X, currentMouse.Y);
modified = true;
}
}
@ -538,11 +736,10 @@ namespace Greenshot.Drawing {
}
private Image GetImage(RenderMode renderMode) {
Image clone = new Bitmap(Image);
// This actually generates a copy of the original image with a dpi equal to the default...
// Generate a copy of the original image with a dpi equal to the default...
Bitmap clone = ImageHelper.CloneImageToBitmap(Image);
// otherwise we would have a problem drawing the image to the surface... :(
using (Graphics graphics = Graphics.FromImage(clone)) {
graphics.DrawImage(Image, Point.Empty);
elements.Draw(graphics, (Bitmap)clone, renderMode, new Rectangle(Point.Empty, clone.Size));
}
return clone;
@ -560,6 +757,10 @@ namespace Greenshot.Drawing {
void SurfacePaint(object sender, PaintEventArgs e) {
Graphics targetGraphics = e.Graphics;
Rectangle clipRectangle = e.ClipRectangle;
if (Rectangle.Empty.Equals(clipRectangle)) {
LOG.Debug("Empty cliprectangle??");
return;
}
if (elements.hasIntersectingFilters(clipRectangle)) {
if (buffer != null) {
@ -569,6 +770,7 @@ namespace Greenshot.Drawing {
}
}
if (buffer == null) {
LOG.DebugFormat("Created buffer with size: {0}x{1}", Image.Width, Image.Height);
buffer = new Bitmap(Image.Width, Image.Height, Image.PixelFormat);
}
// Elements might need the bitmap, so we copy the part we need
@ -599,8 +801,20 @@ namespace Greenshot.Drawing {
}
}
/// <summary>
/// Wrapper for makeUndoable flag which was introduced later, will call AddElement with makeundoable set to true
/// </summary>
/// <param name="element">the new element</param>
public void AddElement(DrawableContainer element) {
AddElement(element, true);
}
/// <summary>
/// Add a new element to the surface
/// </summary>
/// <param name="element">the new element</param>
/// <param name="makeUndoable">true if the adding should be undoable</param>
public void AddElement(DrawableContainer element, bool makeUndoable) {
elements.Add(element);
element.FieldChanged += element_FieldChanged;
element.PropertyChanged += ElementPropertyChanged;
@ -608,30 +822,29 @@ namespace Greenshot.Drawing {
element.Status = EditStatus.IDLE;
}
element.Invalidate();
if (makeUndoable) {
MakeUndoable(new AddElementMemento(this, element), false);
}
modified = true;
}
public void RemoveElement(DrawableContainer element) {
public void RemoveElement(DrawableContainer element, bool makeUndoable) {
DeselectElement(element);
elements.Remove(element);
element.FieldChanged -= element_FieldChanged;
element.PropertyChanged -= ElementPropertyChanged;
element.Dispose();
// Do not dispose, the memento should!! element.Dispose();
element.Invalidate();
if (makeUndoable) {
MakeUndoable(new DeleteElementMemento(this, element), false);
}
modified = true;
}
public void AddElements(DrawableContainerList elementsToAdd) {
elements.AddRange(elementsToAdd);
foreach(DrawableContainer element in elementsToAdd) {
element.FieldChanged += element_FieldChanged;
element.PropertyChanged += ElementPropertyChanged;
if (element.Status == EditStatus.UNDRAWN) {
element.Status = EditStatus.IDLE;
AddElement(element, true);
}
element.Invalidate();
}
modified = true;
}
public bool HasSelectedElements() {
@ -649,7 +862,7 @@ namespace Greenshot.Drawing {
}
// Remove now
foreach(DrawableContainer element in elementsToRemove) {
RemoveElement(element);
RemoveElement(element, true);
}
selectedElements.Clear();
MovingElementChanged(this, selectedElements);
@ -675,7 +888,8 @@ namespace Greenshot.Drawing {
foreach(DrawableContainer dc in selectedDCs){
if(dc.Equals(cropContainer)){
DrawingMode = DrawingModes.None;
RemoveElement(cropContainer);
// No undo memento for the cropcontainer itself, only for the effect
RemoveElement(cropContainer, false);
if(confirm) {
ApplyCrop(cropContainer.Bounds);
}
@ -706,16 +920,16 @@ namespace Greenshot.Drawing {
DeselectAllElements();
SelectElements(dcs);
}
} else if (Clipboard.ContainsImage()) {
using (Image image = Clipboard.GetImage()) {
} else if (ClipboardHelper.ContainsImage()) {
using (Image image = ClipboardHelper.GetImage()) {
if (image != null) {
DeselectAllElements();
IBitmapContainer bitmapContainer = AddBitmapContainer(image as Bitmap, 0, 0);
SelectElement(bitmapContainer);
}
}
} else if (Clipboard.ContainsText()) {
string text = Clipboard.GetText();
} else if (ClipboardHelper.ContainsText()) {
string text = ClipboardHelper.GetText();
if (text != null) {
DeselectAllElements();
ITextContainer textContainer = AddTextContainer(text, HorizontalAlignment.Center, VerticalAlignment.CENTER,
@ -727,7 +941,7 @@ namespace Greenshot.Drawing {
public void DuplicateSelectedElements() {
if(LOG.IsDebugEnabled) LOG.Debug("Duplicating "+selectedElements.Count+" selected elements");
DrawableContainerList dcs = (DrawableContainerList)Objects.DeepClone(selectedElements);
DrawableContainerList dcs = selectedElements.Clone();
dcs.Parent = this;
dcs.MoveBy(10,10);
AddElements(dcs);
@ -789,30 +1003,24 @@ namespace Greenshot.Drawing {
public void ProcessCmdKey(Keys k) {
if (selectedElements.Count > 0) {
int px = (k == Keys.Shift) ? 10 : 1;
Point moveBy = Point.Empty;
switch (k) {
case Keys.Left:
selectedElements.MoveBy(-1,0);
break;
case Keys.Left | Keys.Shift:
selectedElements.MoveBy(-10,0);
moveBy = new Point(-px, 0);
break;
case Keys.Up:
selectedElements.MoveBy(0,-1);
break;
case Keys.Up | Keys.Shift:
selectedElements.MoveBy(0,-10);
moveBy = new Point(0, -px);
break;
case Keys.Right:
selectedElements.MoveBy(1,0);
break;
case Keys.Right | Keys.Shift:
selectedElements.MoveBy(10,0);
moveBy = new Point(px, 0);
break;
case Keys.Down:
selectedElements.MoveBy(0,1);
break;
case Keys.Down | Keys.Shift:
selectedElements.MoveBy(0,10);
moveBy = new Point(0, px);
break;
case Keys.PageUp:
PullElementsUp();
@ -838,6 +1046,16 @@ namespace Greenshot.Drawing {
default:
return;
}
if (!Point.Empty.Equals(moveBy)) {
selectedElements.MakeBoundsChangeUndoable(true);
selectedElements.MoveBy(moveBy.X, moveBy.Y);
}
}
}
public DrawableContainerList Elements {
get {
return elements;
}
}
@ -889,19 +1107,6 @@ namespace Greenshot.Drawing {
return elements.CanPushDown(selectedElements);
}
public new void Dispose() {
LOG.Debug("Disposing a surface!");
if (buffer != null) {
buffer.Dispose();
buffer = null;
}
if (transparencyBackgroundBrush != null) {
transparencyBackgroundBrush.Dispose();
transparencyBackgroundBrush = null;
}
base.Dispose();
}
public void ElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
//Invalidate();
}

View file

@ -19,18 +19,15 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
using Greenshot.Memento;
namespace Greenshot.Drawing {
/// <summary>
@ -39,17 +36,29 @@ namespace Greenshot.Drawing {
[Serializable()]
public class TextContainer : RectangleContainer, ITextContainer {
private bool fontInvalidated = true;
// If makeUndoable is true the next text-change will make the change undoable.
// This is set to true AFTER the first change is made, as there is already a "add element" on the undo stack
private bool makeUndoable = false;
private Font font;
private string text;
// there is a binding on the following property!
public string Text {
get { return text; }
set {
if((text == null && value != null) || !text.Equals(value)) {
text = value;
OnPropertyChanged("Text");
ChangeText(value, true);
}
}
internal void ChangeText(string newText, bool allowUndoable) {
if ((text == null && newText != null) || !text.Equals(newText)) {
if (makeUndoable && allowUndoable) {
makeUndoable = false;
parent.MakeUndoable(new TextChangeMemento(this), false);
}
text = newText;
OnPropertyChanged("Text");
}
}
[NonSerialized]
@ -57,9 +66,9 @@ namespace Greenshot.Drawing {
public TextContainer(Surface parent) : base(parent) {
Init();
AddField(GetType(), FieldType.LINE_THICKNESS, 1);
AddField(GetType(), FieldType.LINE_THICKNESS, 2);
AddField(GetType(), FieldType.LINE_COLOR, Color.Red);
AddField(GetType(), FieldType.SHADOW, false);
AddField(GetType(), FieldType.SHADOW, true);
AddField(GetType(), FieldType.FONT_ITALIC, false);
AddField(GetType(), FieldType.FONT_BOLD, false);
AddField(GetType(), FieldType.FILL_COLOR, Color.Transparent);
@ -96,8 +105,12 @@ namespace Greenshot.Drawing {
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if(textBox != null) textBox.Dispose();
if(font != null) font.Dispose();
if (textBox != null) {
textBox.Dispose();
}
if (font != null) {
font.Dispose();
}
}
textBox = null;
font = null;
@ -119,11 +132,11 @@ namespace Greenshot.Drawing {
void TextContainer_PropertyChanged(object sender, PropertyChangedEventArgs e) {
if (e.PropertyName.Equals("Selected")) {
if(!Selected && textBox.Visible) HideTextBox();
else if(Selected && Status==EditStatus.DRAWING) {
if (!Selected && textBox.Visible) {
HideTextBox();
} else if (Selected && Status==EditStatus.DRAWING) {
ShowTextBox();
}
//else if(!textBox.Visible) ShowTextBox();
}
if (textBox.Visible) {
UpdateTextBoxPosition();
@ -132,8 +145,7 @@ namespace Greenshot.Drawing {
}
}
void TextContainer_FieldChanged(object sender, FieldChangedEventArgs e)
{
void TextContainer_FieldChanged(object sender, FieldChangedEventArgs e) {
if (textBox.Visible) {
UpdateTextBoxFormat();
textBox.Invalidate();
@ -148,6 +160,7 @@ namespace Greenshot.Drawing {
public override void OnDoubleClick() {
ShowTextBox();
textBox.Focus();
}
private void CreateTextBox() {
@ -212,11 +225,9 @@ namespace Greenshot.Drawing {
}
}
}
font = new Font(fam, fontSize, fs, GraphicsUnit.Pixel);
}
fontInvalidated = false;
}
}
@ -243,6 +254,8 @@ namespace Greenshot.Drawing {
}
void textBox_LostFocus(object sender, EventArgs e) {
// next change will be made undoable
makeUndoable = true;
HideTextBox();
}
@ -293,5 +306,11 @@ namespace Greenshot.Drawing {
g.DrawString(text, font, fontBrush, fontRect);
}
}
public override bool ClickableAt(int x, int y) {
Rectangle r = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
r.Inflate(5, 5);
return r.Contains(x, y);
}
}
}

View file

@ -70,7 +70,7 @@ namespace Greenshot {
this.lblTitle.Font = new System.Drawing.Font("Microsoft Sans Serif", 8.25F, System.Drawing.FontStyle.Bold, System.Drawing.GraphicsUnit.Point, ((byte)(0)));
this.lblTitle.Location = new System.Drawing.Point(108, 12);
this.lblTitle.Name = "lblTitle";
this.lblTitle.Size = new System.Drawing.Size(227, 19);
this.lblTitle.Size = new System.Drawing.Size(263, 19);
this.lblTitle.TabIndex = 2;
this.lblTitle.Text = "Greenshot x.x.xxx";
//
@ -166,9 +166,9 @@ namespace Greenshot {
//
// linkLabel1
//
this.linkLabel1.Location = new System.Drawing.Point(304, 8);
this.linkLabel1.Location = new System.Drawing.Point(377, 8);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(203, 23);
this.linkLabel1.Size = new System.Drawing.Size(130, 23);
this.linkLabel1.TabIndex = 13;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "http://getgreenshot.org";
@ -247,7 +247,7 @@ namespace Greenshot {
link.LinkVisited = true;
System.Diagnostics.Process.Start(link.Text);
} catch (Exception) {
MessageBox.Show(lang.GetString(LangKey.error_openlink),lang.GetString(LangKey.error));
MessageBox.Show(lang.GetFormattedString(LangKey.error_openlink, link.Text),lang.GetString(LangKey.error));
}
}
}

View file

@ -19,12 +19,14 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
using System.Reflection;
using System.Windows.Forms;
using System.IO;
using Greenshot.Helpers;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot {
/// <summary>
@ -41,7 +43,7 @@ namespace Greenshot {
Version v = Assembly.GetExecutingAssembly().GetName().Version;
// Format is like this: AssemblyVersion("Major.Minor.Build.Revision")]
lblTitle.Text = "Greenshot " + v.Major + "." + v.Minor + "." + v.Build + " Build " + v.Revision;
lblTitle.Text = "Greenshot " + v.Major + "." + v.Minor + "." + v.Build + " Build " + v.Revision + (IniConfig.IsPortable?" Portable":"") + (" (" + OSInfo.Bits +" bit)");
lang = Language.GetInstance();
updateUI();
}
@ -58,14 +60,37 @@ namespace Greenshot {
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
try {
if (msg.WParam.ToInt32() == (int)Keys.Escape) {
this.Close();
switch (keyData) {
case Keys.Escape:
DialogResult = DialogResult.OK;
break;
case Keys.E:
MessageBox.Show(EnvironmentInfo.EnvironmentToString(true));
break;
case Keys.L:
try {
if (File.Exists( MainForm.LogFileLocation)) {
System.Diagnostics.Process.Start("\"" + MainForm.LogFileLocation + "\"");
} else {
MessageBox.Show("Greenshot can't write to logfile, otherwise it would be here: " + MainForm.LogFileLocation);
}
} catch (Exception) {
MessageBox.Show("Couldn't open the greenshot.log, it's located here: " + MainForm.LogFileLocation, "Error opening greeenshot.log", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
break;
case Keys.I:
try {
System.Diagnostics.Process.Start("\"" + IniFile.IniConfig.ConfigLocation + "\"");
} catch (Exception) {
MessageBox.Show("Couldn't open the greenshot.ini, it's located here: " + IniFile.IniConfig.ConfigLocation, "Error opening greeenshot.ini", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
}
break;
default:
return base.ProcessCmdKey(ref msg, keyData);
}
} catch (Exception) {
}
return base.ProcessCmdKey(ref msg,keyData);
return true;
}
}
}

View file

@ -19,11 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
using System.Net;
using System.Web;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Helpers;
using GreenshotPlugin.Core;
@ -61,7 +57,7 @@ namespace Greenshot.Forms {
link.LinkVisited = true;
System.Diagnostics.Process.Start(link.Text);
} catch (Exception) {
MessageBox.Show(lang.GetString(LangKey.error_openlink),lang.GetString(LangKey.error));
MessageBox.Show(lang.GetFormattedString(LangKey.error_openlink, link.Text),lang.GetString(LangKey.error));
}
}
}

View file

@ -75,8 +75,8 @@ namespace Greenshot.Forms {
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.TopMost = true;
this.VisibleChanged += new System.EventHandler(this.CaptureFormVisibleChanged);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.CaptureFormKeyDown);
this.KeyUp += new System.Windows.Forms.KeyEventHandler(this.CaptureFormKeyUp);
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.Visible = false;
this.ResumeLayout(false);

View file

@ -19,37 +19,38 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Text;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing;
using Greenshot.Helpers;
using Greenshot.Plugin;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Forms {
/// <summary>
/// Description of CaptureForm.
/// </summary>
public partial class CaptureForm : Form, ICaptureHost {
public partial class CaptureForm : Form {
private enum FixMode {None, Initiated, Horizontal, Vertical};
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(CaptureForm));
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private static Brush GreenOverlayBrush = new SolidBrush(Color.FromArgb(50, Color.MediumSeaGreen));
private static Brush RedOverlayBrush = new SolidBrush(Color.FromArgb(50, Color.DarkRed));
private static Pen OverlayPen = new Pen(Color.FromArgb(50, Color.Black));
private int mX;
private int mY;
private Point cursorPos = Point.Empty;
// TODO: dispose Brush & Pen, not very important as we only instanciate this once
private Brush OverlayBrush = new SolidBrush(Color.FromArgb(50, Color.MediumSeaGreen));
private Pen OverlayPen = new Pen(Color.FromArgb(50, Color.Black));
private CaptureMode captureMode = CaptureMode.None;
private List<WindowDetails> windows = new List<WindowDetails>();
private WindowDetails selectedCaptureWindow;
@ -58,480 +59,80 @@ namespace Greenshot.Forms {
private ICapture capture = null;
private ILanguage lang = Language.GetInstance();
public CaptureForm() {
private Point previousMousePos = Point.Empty;
private FixMode fixMode = FixMode.None;
public Rectangle CaptureRectangle {
get {
return captureRect;
}
}
public CaptureMode UsedCaptureMode {
get {
return captureMode;
}
}
public WindowDetails SelectedCaptureWindow {
get {
return selectedCaptureWindow;
}
}
public CaptureForm(ICapture capture, List<WindowDetails> windows) {
this.capture = capture;
this.windows = windows;
captureMode = capture.CaptureDetails.CaptureMode;
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
this.Text = "Greenshot capture form";
// Make sure the form is hidden (might be overdoing it...)
this.Hide();
}
// Make sure we never capture the captureform
WindowDetails.RegisterIgnoreHandle(this.Handle);
// TODO: Need to call unregister at close
void DoCaptureFeedback() {
if(conf.PlayCameraSound) {
SoundHelper.Play();
}
}
// set cursor location
cursorPos = WindowCapture.GetCursorLocation();
// Offset to screen coordinates
cursorPos.Offset(-capture.ScreenBounds.X, -capture.ScreenBounds.Y);
/// <summary>
/// Make Capture with default destinations
/// </summary>
/// <param name="mode">CaptureMode</param>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
public void MakeCapture(CaptureMode mode, bool captureMouseCursor) {
Capture passingCapture = new Capture();
MakeCapture(mode, captureMouseCursor, passingCapture);
}
this.SuspendLayout();
pictureBox.Image = capture.Image;
this.Bounds = capture.ScreenBounds;
this.ResumeLayout();
/// <summary>
/// Make capture of window
/// </summary>
/// <param name="window">WindowDetails of the window to capture</param>
public void MakeCapture(WindowDetails window) {
MakeCapture(window, null);
}
/// <summary>
/// Make capture of window
/// </summary>
/// <param name="window">WindowDetails of the window to capture</param>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
public void MakeCapture(WindowDetails window, CaptureHandler captureHandler) {
Capture passingCapture = new Capture();
passingCapture.CaptureDetails.CaptureHandler = captureHandler;
selectedCaptureWindow = window;
MakeCapture(CaptureMode.ActiveWindow, false, passingCapture);
}
/// <summary>
/// Make Capture with default destinations
/// </summary>
/// <param name="mode">CaptureMode</param>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
public void MakeCapture(CaptureMode mode, bool captureMouseCursor, CaptureHandler captureHandler) {
Capture passingCapture = new Capture();
passingCapture.CaptureDetails.CaptureHandler = captureHandler;
MakeCapture(mode, captureMouseCursor, passingCapture);
}
/// <summary>
/// Make Capture with specified destinations
/// </summary>
/// <param name="mode">CaptureMode</param>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
/// <param name="captureDestinations">List<CaptureDestination> with destinations</param>
public void MakeCapture(CaptureMode mode, bool captureMouseCursor, List<CaptureDestination> captureDestinations) {
Capture passingCapture = new Capture();
passingCapture.CaptureDetails.CaptureDestinations = captureDestinations;
MakeCapture(mode, captureMouseCursor, passingCapture);
}
/// <summary>
/// Make Capture with file name
/// </summary>
/// <param name="filename">List<CaptureDestination> with destinations</param>
public void MakeCapture(string filename) {
Capture passingCapture = new Capture();
passingCapture.CaptureDetails.Filename = filename;
MakeCapture(CaptureMode.File, false, passingCapture);
}
/// <summary>
/// Make Capture with specified destinations
/// </summary>
/// <param name="mode">CaptureMode</param>
/// <param name="captureMouseCursor">bool false if the mouse should not be captured, true if the configuration should be checked</param>
/// <param name="captureDestinations">List<CaptureDestination> with destinations</param>
private void MakeCapture(CaptureMode mode, bool captureMouseCursor, ICapture newCapture) {
if (captureMode != CaptureMode.None) {
LOG.Warn(String.Format("Capture started while capturing, current mode = {0} new capture was {1}.", captureMode, mode));
return;
} else {
LOG.Debug(String.Format("MakeCapture({0}, {1})", mode, captureMouseCursor));
}
captureMode = mode;
// cleanup the previos information if there is still any
if (capture != null) {
LOG.Debug("Capture wasn't disposed yet, this would suggest a leak");
capture.Dispose();
capture = null;
}
// Use the supplied Capture information
capture = newCapture;
capture.CaptureDetails.CaptureMode = mode;
// Workaround for proble with DPI retrieval, the FromHwnd activates the window...
WindowDetails previouslyActiveWindow = WindowDetails.GetActiveWindow();
// Workaround for changed DPI settings in Windows 7
using (Graphics graphics = Graphics.FromHwnd(this.Handle)) {
capture.CaptureDetails.DpiX = graphics.DpiX;
capture.CaptureDetails.DpiY = graphics.DpiY;
}
if (previouslyActiveWindow != null) {
// Set previouslyActiveWindow as foreground window
previouslyActiveWindow.ToForeground();
}
// Delay for the Context menu
if (conf.CaptureDelay > 0) {
System.Threading.Thread.Sleep(conf.CaptureDelay);
} else {
conf.CaptureDelay = 0;
}
// Allways capture Mousecursor, only show when needed
capture = WindowCapture.CaptureCursor(capture);
capture.CursorVisible = false;
// Check if needed
if (captureMouseCursor && mode != CaptureMode.Clipboard && mode != CaptureMode.File) {
capture.CursorVisible = conf.CaptureMousepointer;
}
switch(mode) {
case CaptureMode.Window:
capture = WindowCapture.CaptureScreen(capture);
capture.CaptureDetails.AddMetaData("source", "Screen");
CaptureWithFeedback();
break;
case CaptureMode.ActiveWindow:
if (CaptureActiveWindow()) {
// Capture worked, offset mouse according to screen bounds and capture location
capture.MoveMouseLocation(capture.ScreenBounds.Location.X-capture.Location.X, capture.ScreenBounds.Location.Y-capture.Location.Y);
capture.CaptureDetails.AddMetaData("source", "Window");
} else {
captureMode = CaptureMode.FullScreen;
capture = WindowCapture.CaptureScreen(capture);
capture.CaptureDetails.AddMetaData("source", "Screen");
capture.CaptureDetails.Title = "Screen";
}
// Make sure capturing is stopped at any cost
StopCapturing(false);
HandleCapture();
break;
case CaptureMode.IE:
if (IECaptureHelper.CaptureIE(capture) != null) {
capture.CaptureDetails.AddMetaData("source", "Internet Explorer");
HandleCapture();
} else {
StopCapturing(true);
}
break;
case CaptureMode.FullScreen:
capture = WindowCapture.CaptureScreen(capture);
HandleCapture();
break;
case CaptureMode.Clipboard:
Image clipboardImage = null;
string text = "Clipboard";
if (Clipboard.ContainsImage()) {
clipboardImage = Clipboard.GetImage();
}
if (clipboardImage != null) {
if (capture != null) {
capture.Image = clipboardImage;
} else {
capture = new Capture(clipboardImage);
}
string title = Clipboard.GetText();
if (title == null || title.Trim().Length == 0) {
title = "Clipboard";
}
capture.CaptureDetails.Title = title;
capture.CaptureDetails.AddMetaData("source", "Clipboard");
// Force Editor
capture.CaptureDetails.AddDestination(CaptureDestination.Editor);
HandleCapture();
} else {
MessageBox.Show("Couldn't create bitmap from : " + text);
}
break;
case CaptureMode.File:
Bitmap fileBitmap = null;
try {
fileBitmap = new Bitmap(capture.CaptureDetails.Filename, true);
} catch (Exception e) {
LOG.Error(e.Message, e);
MessageBox.Show(lang.GetFormattedString(LangKey.error_openfile, capture.CaptureDetails.Filename));
}
capture.CaptureDetails.Title = Path.GetFileNameWithoutExtension(capture.CaptureDetails.Filename);
capture.CaptureDetails.AddMetaData("file", capture.CaptureDetails.Filename);
capture.CaptureDetails.AddMetaData("source", "file");
if (fileBitmap != null) {
if (capture != null) {
capture.Image = fileBitmap;
} else {
capture = new Capture(fileBitmap);
}
// Force Editor
capture.CaptureDetails.AddDestination(CaptureDestination.Editor);
HandleCapture();
}
break;
case CaptureMode.LastRegion:
if (!RuntimeConfig.LastCapturedRegion.Equals(Rectangle.Empty)) {
capture = WindowCapture.CaptureRectangle(capture, RuntimeConfig.LastCapturedRegion);
capture.CaptureDetails.AddMetaData("source", "screen");
HandleCapture();
}
break;
case CaptureMode.Region:
capture = WindowCapture.CaptureScreen(capture);
capture.CaptureDetails.AddMetaData("source", "screen");
CaptureWithFeedback();
break;
default:
LOG.Warn("Unknown capture mode: " + mode);
break;
}
}
private ICapture AddConfiguredDestination(ICapture capture) {
if (conf.OutputDestinations.Contains(Destination.FileDefault)) {
capture.CaptureDetails.AddDestination(CaptureDestination.File);
}
if (conf.OutputDestinations.Contains(Destination.FileWithDialog)) {
capture.CaptureDetails.AddDestination(CaptureDestination.FileWithDialog);
}
if (conf.OutputDestinations.Contains(Destination.Clipboard)) {
capture.CaptureDetails.AddDestination(CaptureDestination.Clipboard);
}
if (conf.OutputDestinations.Contains(Destination.Printer)) {
capture.CaptureDetails.AddDestination(CaptureDestination.Printer);
}
if (conf.OutputDestinations.Contains(Destination.Editor)) {
capture.CaptureDetails.AddDestination(CaptureDestination.Editor);
}
if (conf.OutputDestinations.Contains(Destination.EMail)) {
capture.CaptureDetails.AddDestination(CaptureDestination.EMail);
}
return capture;
}
/// <summary>
/// Process a bitmap like it was captured
/// </summary>
/// <param name="bitmap">The bitmap to process</param>
public void HandleCapture(Bitmap bitmap) {
Capture capture = new Capture(bitmap);
HandleCapture(capture);
}
// This is also an ICapture Interface implementation
public void HandleCapture(Capture capture) {
this.capture = capture;
HandleCapture();
}
private void HandleCapture() {
string fullPath = null;
// Flag to see if the image was "exported" so the FileEditor doesn't
// ask to save the file as long as nothing is done.
bool outputMade = false;
// Make sure the user sees that the capture is made
if (capture.CaptureDetails.CaptureMode != CaptureMode.File && capture.CaptureDetails.CaptureMode != CaptureMode.Clipboard) {
DoCaptureFeedback();
} else {
// If File || Clipboard
// Maybe not "made" but the original is still there... somehow
outputMade = true;
}
LOG.Debug("A capture of: " + capture.CaptureDetails.Title);
// Create event OnCaptureTaken for all Plugins
PluginHelper.instance.CreateCaptureTakenEvent(capture);
// check if someone has passed a handler
if (capture.CaptureDetails.CaptureHandler != null) {
CaptureTakenEventArgs eventArgs = new CaptureTakenEventArgs(capture);
capture.CaptureDetails.CaptureHandler(this, eventArgs);
} else if (capture.CaptureDetails.CaptureDestinations == null || capture.CaptureDetails.CaptureDestinations.Count == 0) {
AddConfiguredDestination(capture);
}
// Create Surface with capture, this way elements can be added automatically (like the mouse cursor)
Surface surface = new Surface(capture);
// As the surfaces copies the reference to the image, make sure the image is not being disposed (a trick to save memory)
capture.Image = null;
// Call plugins to do something with the screenshot
PluginHelper.instance.CreateSurfaceFromCaptureEvent(capture, surface);
// Disable capturing
captureMode = CaptureMode.None;
// Retrieve important information from the Capture object
ICaptureDetails captureDetails = capture.CaptureDetails;
List<CaptureDestination> captureDestinations = capture.CaptureDetails.CaptureDestinations;
// Dispose the capture, we don't need it anymore (the surface copied all information and we got the title (if any)).
capture.Dispose();
capture = null;
// Want to add more stuff to the surface?? DO IT HERE!
int destinationsCount = captureDestinations.Count;
if (captureDestinations.Contains(CaptureDestination.Editor)) {
destinationsCount--;
}
if (destinationsCount > 0) {
// Create Image for writing/printing etc and use "using" as all code paths either output the image or copy the image
using (Image image = surface.GetImageForExport()) {
// Flag to detect if we need to create a temp file for the email
// or use the file that was written
bool fileWritten = false;
if (captureDestinations.Contains(CaptureDestination.File)) {
string pattern = conf.OutputFileFilenamePattern;
if (pattern == null || string.IsNullOrEmpty(pattern.Trim())) {
pattern = "greenshot ${capturetime}";
}
string filename = FilenameHelper.GetFilenameFromPattern(pattern, conf.OutputFileFormat, captureDetails);
string filepath = FilenameHelper.FillVariables(conf.OutputFilePath);
fullPath = Path.Combine(filepath,filename);
// Catching any exception to prevent that the user can't write in the directory.
// This is done for e.g. bugs #2974608, #2963943, #2816163, #2795317, #2789218, #3004642
try {
ImageOutput.Save(image, fullPath);
fileWritten = true;
outputMade = true;
} catch (Exception e) {
LOG.Error("Error saving screenshot!", e);
// Show the problem
MessageBox.Show(lang.GetString(LangKey.error_save), lang.GetString(LangKey.error));
// when save failed we present a SaveWithDialog
fullPath = ImageOutput.SaveWithDialog(image, captureDetails);
fileWritten = (fullPath != null);
}
}
if (captureDestinations.Contains(CaptureDestination.FileWithDialog)) {
fullPath = ImageOutput.SaveWithDialog(image, captureDetails);
fileWritten = (fullPath != null);
outputMade = outputMade || fileWritten;
}
if (captureDestinations.Contains(CaptureDestination.Clipboard)) {
ClipboardHelper.SetClipboardData(image);
outputMade = true;
}
if (captureDestinations.Contains(CaptureDestination.Printer)) {
PrinterSettings printerSettings = new PrintHelper(image, captureDetails).PrintWithDialog();
outputMade = outputMade || printerSettings != null;
}
if (captureDestinations.Contains(CaptureDestination.EMail)) {
if (!fileWritten) {
MapiMailMessage.SendImage(image, captureDetails);
} else {
MapiMailMessage.SendImage(fullPath, captureDetails.Title, false);
}
// Don't know how to handle a cancel in the email
outputMade = true;
}
}
}
// Make sure we don't have garbage before opening the screenshot
GC.Collect();
GC.WaitForPendingFinalizers();
// If the editor is opened, let it Dispose the surface!
if (captureDestinations.Contains(CaptureDestination.Editor)) {
try {
ImageEditorForm editor = new ImageEditorForm(surface, outputMade);
if (fullPath != null) {
editor.SetImagePath(fullPath);
}
editor.Show();
editor.Activate();
LOG.Debug("Finished opening Editor");
} catch (Exception e) {
// Dispose the surface when an error is caught
surface.Dispose();
throw e;
}
} else {
// Dispose the surface, we are done with it!
surface.Dispose();
}
// Make CaptureForm invisible
this.Visible = false;
// Hiding makes the editor (if any) get focus
this.Hide();
}
/**
* Finishing the whole Capture with Feedback flow, passing the result on to the HandleCapture
*/
private void finishCaptureWithFeedback() {
// Get title
if (selectedCaptureWindow != null) {
if (capture == null) {
capture = new Capture();
}
capture.CaptureDetails.Title = selectedCaptureWindow.Text;
}
if (captureRect.Height > 0 && captureRect.Width > 0) {
// Take the captureRect, this already is specified as bitmap coordinates
capture.Crop(captureRect);
// save for re-capturing later and show recapture context menu option
RuntimeConfig.LastCapturedRegion = captureRect;
StopCapturing(false);
HandleCapture();
}
}
/**
* Stopping the whole Capture with Feedback flow
*/
private void StopCapturing(bool cleanupCapture) {
mouseDown = false;
// Disable the capture mode
captureMode = CaptureMode.None;
cursorPos.X = 0;
cursorPos.Y = 0;
captureRect = Rectangle.Empty;
if (cleanupCapture && capture != null) {
capture.Dispose();
capture = null;
}
this.Hide();
// Example of how to capture a scrolling window... somewhat...
// if (selectedCaptureWindow.hasVScroll()) {
// using (Image captured = selectedCaptureWindow.PrintWithVScroll()) {
// Quantizer quantizer = new OctreeQuantizer(255,8);
// using (Image imageToSave = quantizer.Quantize(captured)) {
// imageToSave.Save(@"D:\BLA.PNG", ImageFormat.Png);
// }
// }
// }
selectedCaptureWindow = null;
// Fix missing focus
WindowDetails.ToForeground(this.Handle);
}
#region key handling
void CaptureFormKeyUp(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.ShiftKey) {
fixMode = FixMode.None;
}
}
void CaptureFormKeyDown(object sender, KeyEventArgs e) {
// Check fixmode
if (e.KeyCode == Keys.ShiftKey) {
if (fixMode == FixMode.None) {
fixMode = FixMode.Initiated;
return;
}
}
if (e.KeyCode == Keys.Escape) {
StopCapturing(true);
DialogResult = DialogResult.Cancel;
} else if (e.KeyCode == Keys.M) {
// Toggle mouse cursor
capture.CursorVisible = !capture.CursorVisible;
PictureBoxMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
pictureBox.Invalidate();
} else if (e.KeyCode == Keys.V && conf.isExperimentalFeatureEnabled("Video")) {
capture.CaptureDetails.CaptureMode = CaptureMode.Video;
pictureBox.Invalidate();
} else if (e.KeyCode == Keys.Space) {
switch (captureMode) {
case CaptureMode.Region:
@ -545,203 +146,11 @@ namespace Greenshot.Forms {
selectedCaptureWindow = null;
PictureBoxMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
} else if (e.KeyCode == Keys.Return && captureMode == CaptureMode.Window) {
finishCaptureWithFeedback();
DialogResult = DialogResult.OK;
}
}
#endregion
private bool CaptureActiveWindow() {
bool presupplied = false;
LOG.Debug("CaptureActiveWindow");
if (selectedCaptureWindow != null) {
LOG.Debug("Using supplied window");
presupplied = true;
} else {
selectedCaptureWindow = WindowDetails.GetActiveWindow();
if (selectedCaptureWindow != null) {
LOG.DebugFormat("Capturing window: {0} with {1}", selectedCaptureWindow.Text, selectedCaptureWindow.ClientRectangle);
}
}
if (selectedCaptureWindow == null || (!presupplied && selectedCaptureWindow.Iconic)) {
LOG.Warn("No window to capture!");
// Nothing to capture, code up in the stack will capture the full screen
return false;
}
if (selectedCaptureWindow.Iconic) {
// Restore the window making sure it's visible!
// This is done mainly for a screen capture, but some applications like Excel and TOAD have weird behaviour!
selectedCaptureWindow.Restore();
}
selectedCaptureWindow = SelectCaptureWindow(selectedCaptureWindow);
if (selectedCaptureWindow == null) {
LOG.Warn("No window to capture, after SelectCaptureWindow!");
// Nothing to capture, code up in the stack will capture the full screen
return false;
}
return CaptureWindow(selectedCaptureWindow, capture, conf.WindowCaptureMode) != null;
}
/// <summary>
/// Select the window to capture, this has logic which takes care of certain special applications
/// like TOAD or Excel
/// </summary>
/// <param name="windowToCapture">WindowDetails with the target Window</param>
/// <returns>WindowDetails with the target Window OR a replacement</returns>
public static WindowDetails SelectCaptureWindow(WindowDetails windowToCapture) {
Rectangle windowRectangle = windowToCapture.ClientRectangle;
if (windowToCapture.Iconic || windowRectangle.Width == 0 || windowRectangle.Height == 0) {
LOG.WarnFormat("Window {0} has nothing to capture, using workaround to find other window of same process.", windowToCapture.Text);
// Trying workaround, the size 0 arrises with e.g. Toad.exe, has a different Window when minimized
WindowDetails linkedWindow = WindowDetails.GetLinkedWindow(windowToCapture);
if (linkedWindow != null) {
windowRectangle = linkedWindow.ClientRectangle;
windowToCapture = linkedWindow;
} else {
return null;
}
}
return windowToCapture;
}
/// <summary>
/// Capture the supplied Window
/// </summary>
/// <param name="windowToCapture">Window to capture</param>
/// <param name="captureForWindow">The capture to store the details</param>
/// <param name="windowCaptureMode">What WindowCaptureMode to use</param>
/// <returns></returns>
public static ICapture CaptureWindow(WindowDetails windowToCapture, ICapture captureForWindow, WindowCaptureMode windowCaptureMode) {
Rectangle windowRectangle = windowToCapture.ClientRectangle;
if (windowToCapture.Iconic) {
// Restore the window making sure it's visible!
windowToCapture.Restore();
}
// When Vista & DWM (Aero) enabled
bool dwmEnabled = DWM.isDWMEnabled();
// For WindowCaptureMode.Auto we check:
// 1) Is window IE, use IE Capture
// 2) Is Windows >= Vista & DWM enabled: use DWM
// 3) Otherwise use GDI (Screen might be also okay but might lose content)
if (windowCaptureMode == WindowCaptureMode.Auto) {
if (windowToCapture.ClassName == "IEFrame") {
ICapture ieCapture = IECaptureHelper.CaptureIE(captureForWindow);
if (ieCapture != null) {
return ieCapture;
}
}
// Take default GDI
windowCaptureMode = WindowCaptureMode.GDI;
// Take DWM if enabled
if (dwmEnabled) {
windowCaptureMode = WindowCaptureMode.Aero;
}
} else if (windowCaptureMode == WindowCaptureMode.Aero || windowCaptureMode == WindowCaptureMode.AeroTransparent) {
if (!dwmEnabled) {
windowCaptureMode = WindowCaptureMode.GDI;
}
}
LOG.DebugFormat("Capturing window with mode {0}", windowCaptureMode);
switch(windowCaptureMode) {
case WindowCaptureMode.GDI:
// GDI
captureForWindow = windowToCapture.CaptureWindow(captureForWindow);
break;
case WindowCaptureMode.Aero:
case WindowCaptureMode.AeroTransparent:
// DWM
captureForWindow = windowToCapture.CaptureDWMWindow(captureForWindow, windowCaptureMode);
break;
case WindowCaptureMode.Screen:
default:
// Screen capture
windowRectangle.Intersect(captureForWindow.ScreenBounds);
try {
captureForWindow = WindowCapture.CaptureRectangle(captureForWindow, windowRectangle);
} catch (Exception e) {
LOG.Error("Problem capturing", e);
return null;
}
break;
}
captureForWindow.CaptureDetails.Title = windowToCapture.Text;
((Bitmap)captureForWindow.Image).SetResolution(captureForWindow.CaptureDetails.DpiX, captureForWindow.CaptureDetails.DpiY);
return captureForWindow;
}
#region capture with feedback
private void CaptureWithFeedback() {
windows.Clear();
// Start Enumeration of "active" windows
foreach(WindowDetails window in WindowDetails.GetAllWindows()) {
// Window should be visible and not ourselves
if (!window.Visible) {
continue;
}
if (window.Handle.Equals(this.Handle)) {
continue;
}
// Skip empty
Size windowSize = window.ClientRectangle.Size;
if (windowSize.Width == 0 || windowSize.Height == 0) {
continue;
}
windows.Add(window);
}
// Reset "previous" cursor location
cursorPos = WindowCapture.GetCursorLocation();
// Offset to screen coordinates
cursorPos.Offset(-capture.ScreenBounds.X, -capture.ScreenBounds.Y);
this.SuspendLayout();
pictureBox.Image = capture.Image;
this.Bounds = capture.ScreenBounds;
this.ResumeLayout();
this.Visible = true;
// Fix missing focus
WindowDetails.ToForeground(this.Handle);
}
/// <summary>
/// Helper Method for finding the current Window in the available rectangles
/// </summary>
/// <returns>WindowDetails</returns>
private WindowDetails FindCurrentWindow() {
foreach(WindowDetails window in windows) {
Rectangle windowRectangle = window.ClientRectangle;
if (windowRectangle.Contains(Cursor.Position)) {
WindowDetails selectedChild = null;
Rectangle selectedChildRectangle = Rectangle.Empty;
// Check if Children need to be parsed (only if "pgdn" was used)
foreach(WindowDetails childWindow in window.Children) {
windowRectangle = childWindow.ClientRectangle;
if (windowRectangle.Contains(Cursor.Position)) {
if (selectedChild == null) {
selectedChild = childWindow;
selectedChildRectangle = selectedChild.ClientRectangle;
} else {
Rectangle childRectangle = childWindow.ClientRectangle;
int sizeCurrent = childRectangle.Height * childRectangle.Width;
int sizeSelected = selectedChildRectangle.Height * selectedChildRectangle.Width;
if (sizeCurrent < sizeSelected) {
selectedChild = childWindow;
}
}
}
}
if (selectedChild != null) {
return selectedChild;
}
return window;
}
}
return null;
}
#endregion
#region pictureBox events
void PictureBoxMouseDown(object sender, MouseEventArgs e) {
if (e.Button == MouseButtons.Left) {
@ -759,13 +168,12 @@ namespace Greenshot.Forms {
void PictureBoxMouseUp(object sender, MouseEventArgs e) {
if (mouseDown) {
pictureBox.Invalidate();
// If the mouse goes up we set down to false (nice logic!)
mouseDown = false;
// Check if anything is selected
if (captureMode == CaptureMode.Window && selectedCaptureWindow != null) {
// Go and process the capture
finishCaptureWithFeedback();
DialogResult = DialogResult.OK;
} else if (captureRect.Height > 0 && captureRect.Width > 0) {
// correct the GUI width to real width if Region mode
if (captureMode == CaptureMode.Region) {
@ -773,14 +181,34 @@ namespace Greenshot.Forms {
captureRect.Height += 1;
}
// Go and process the capture
finishCaptureWithFeedback();
DialogResult = DialogResult.OK;
} else {
pictureBox.Invalidate();
}
}
}
private Point FixMouseCoordinates(Point currentMouse) {
if (fixMode == FixMode.Initiated) {
if (previousMousePos.X != currentMouse.X) {
fixMode = FixMode.Vertical;
} else if (previousMousePos.Y != currentMouse.Y) {
fixMode = FixMode.Horizontal;
}
} else if (fixMode == FixMode.Vertical) {
currentMouse = new Point(currentMouse.X, previousMousePos.Y);
} else if (fixMode == FixMode.Horizontal) {
currentMouse = new Point(previousMousePos.X, currentMouse.Y);
}
previousMousePos = currentMouse;
return currentMouse;
}
void PictureBoxMouseMove(object sender, MouseEventArgs e) {
Point lastPos = new Point(cursorPos.X, cursorPos.Y);
cursorPos = WindowCapture.GetCursorLocation();
// Make sure the mouse coordinates are fixed, when pressing shift
cursorPos = FixMouseCoordinates(cursorPos);
// As the cursorPos is not in Bitmap coordinates, we need to correct.
cursorPos.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
Rectangle lastCaptureRect = new Rectangle(captureRect.Location, captureRect.Size);
@ -800,21 +228,30 @@ namespace Greenshot.Forms {
}
// Iterate over the found windows and check if the current location is inside a window
selectedCaptureWindow = FindCurrentWindow();
if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow)) {
if (capture == null) {
capture = new Capture();
Point cursorPosition = Cursor.Position;
selectedCaptureWindow = null;
foreach (WindowDetails window in windows) {
if (window.Contains(cursorPosition)) {
// Only go over the children if we are in window mode
if (CaptureMode.Window == captureMode) {
selectedCaptureWindow = window.FindChildUnderPoint(cursorPosition);
} else {
selectedCaptureWindow = window;
}
break;
}
}
if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow)) {
capture.CaptureDetails.Title = selectedCaptureWindow.Text;
capture.CaptureDetails.AddMetaData("windowtitle", selectedCaptureWindow.Text);
if (captureMode == CaptureMode.Window) {
// Here we want to capture the window which is under the mouse
captureRect = selectedCaptureWindow.ClientRectangle;
captureRect = selectedCaptureWindow.WindowRectangle;
// As the ClientRectangle is not in Bitmap coordinates, we need to correct.
captureRect.Offset(-capture.ScreenBounds.Location.X, -capture.ScreenBounds.Location.Y);
}
}
if (mouseDown) {
if (mouseDown && (CaptureMode.Window != captureMode)) {
int x1 = Math.Min(mX, lastPos.X);
int x2 = Math.Max(mX, lastPos.X);
int y1 = Math.Min(mY, lastPos.Y);
@ -845,38 +282,40 @@ namespace Greenshot.Forms {
pictureBox.Invalidate(invalidateRectangle);
} else {
if (captureMode == CaptureMode.Window) {
if (!selectedCaptureWindow.Equals(lastWindow)) {
if (selectedCaptureWindow != null && !selectedCaptureWindow.Equals(lastWindow)) {
// Using a 50 Pixel offset to the left, top, to make sure the text is invalidated too
const int SAFETY_SIZE = 50;
Rectangle invalidateRectangle = new Rectangle(lastCaptureRect.Location, lastCaptureRect.Size);
invalidateRectangle.X -= SAFETY_SIZE;
invalidateRectangle.Y -= SAFETY_SIZE;
invalidateRectangle.X -= SAFETY_SIZE/2;
invalidateRectangle.Y -= SAFETY_SIZE/2;
invalidateRectangle.Width += SAFETY_SIZE;
invalidateRectangle.Height += SAFETY_SIZE;
pictureBox.Invalidate(invalidateRectangle);
invalidateRectangle = new Rectangle(captureRect.Location, captureRect.Size);
invalidateRectangle.X -= SAFETY_SIZE;
invalidateRectangle.Y -= SAFETY_SIZE;
invalidateRectangle.X -= SAFETY_SIZE/2;
invalidateRectangle.Y -= SAFETY_SIZE/2;
invalidateRectangle.Width += SAFETY_SIZE;
invalidateRectangle.Height += SAFETY_SIZE;
pictureBox.Invalidate(invalidateRectangle);
}
} else {
if (!conf.OptimizeForRDP) {
if (verticalMove) {
Rectangle before = GuiRectangle.GetGuiRectangle(0, lastPos.Y - 2, this.Width, 45);
Rectangle after = GuiRectangle.GetGuiRectangle(0, cursorPos.Y - 2, this.Width, 45);
Rectangle before = GuiRectangle.GetGuiRectangle(0, lastPos.Y - 2, this.Width+2, 45);
Rectangle after = GuiRectangle.GetGuiRectangle(0, cursorPos.Y - 2, this.Width+2, 45);
pictureBox.Invalidate(before);
pictureBox.Invalidate(after);
}
if (horizontalMove) {
Rectangle before = GuiRectangle.GetGuiRectangle(lastPos.X - 2, 0, 75, this.Height);
Rectangle after = GuiRectangle.GetGuiRectangle(cursorPos.X -2, 0, 75, this.Height);
Rectangle before = GuiRectangle.GetGuiRectangle(lastPos.X - 2, 0, 75, this.Height+2);
Rectangle after = GuiRectangle.GetGuiRectangle(cursorPos.X -2, 0, 75, this.Height+2);
pictureBox.Invalidate(before);
pictureBox.Invalidate(after);
}
}
}
}
}
void PictureBoxPaint(object sender, PaintEventArgs e) {
Graphics graphics = e.Graphics;
@ -889,7 +328,11 @@ namespace Greenshot.Forms {
if (mouseDown || captureMode == CaptureMode.Window) {
captureRect.Intersect(new Rectangle(Point.Empty, capture.ScreenBounds.Size)); // crop what is outside the screen
Rectangle fixedRect = new Rectangle( captureRect.X, captureRect.Y, captureRect.Width, captureRect.Height );
graphics.FillRectangle( OverlayBrush, fixedRect );
if (capture.CaptureDetails.CaptureMode == CaptureMode.Video) {
graphics.FillRectangle( RedOverlayBrush, fixedRect );
} else {
graphics.FillRectangle( GreenOverlayBrush, fixedRect );
}
graphics.DrawRectangle( OverlayPen, fixedRect );
// rulers
@ -979,6 +422,7 @@ namespace Greenshot.Forms {
}
} else {
if (cursorPos.X >= 0 || cursorPos.Y >= 0) {
if (!conf.OptimizeForRDP) {
using (Pen pen = new Pen(Color.LightSeaGreen)) {
pen.DashStyle = DashStyle.Dot;
Rectangle screenBounds = capture.ScreenBounds;
@ -989,12 +433,7 @@ namespace Greenshot.Forms {
string xy = cursorPos.X + " x " + cursorPos.Y;
using (Font f = new Font(FontFamily.GenericSansSerif, 8)) {
Size xySize = TextRenderer.MeasureText(xy, f);
using (GraphicsPath gp = Drawing.RoundedRectangle.Create2(
cursorPos.X + 5,
cursorPos.Y + 5,
xySize.Width - 3,
xySize.Height,
3)) {
using (GraphicsPath gp = Drawing.RoundedRectangle.Create2(cursorPos.X + 5, cursorPos.Y + 5, xySize.Width - 3, xySize.Height, 3)) {
using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227))) {
graphics.FillPath(bgBrush, gp);
}
@ -1008,15 +447,6 @@ namespace Greenshot.Forms {
}
}
}
#endregion
#region Form Events
private void CaptureFormVisibleChanged( object sender, EventArgs e ) {
if ( !this.Visible && pictureBox.Image != null ) {
Image img = pictureBox.Image;
pictureBox.Image = null;
img.Dispose();
}
}
#endregion
}

View file

@ -20,13 +20,13 @@
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot {
/// <summary>

View file

@ -1,96 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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/>.
*/
namespace Greenshot.Forms
{
partial class DestinationPickerForm
{
/// <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.flowLayoutPanel1 = new System.Windows.Forms.FlowLayoutPanel();
this.buttonGo = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// flowLayoutPanel1
//
this.flowLayoutPanel1.AutoSize = true;
this.flowLayoutPanel1.Dock = System.Windows.Forms.DockStyle.Fill;
this.flowLayoutPanel1.FlowDirection = System.Windows.Forms.FlowDirection.TopDown;
this.flowLayoutPanel1.Location = new System.Drawing.Point(0, 0);
this.flowLayoutPanel1.Name = "flowLayoutPanel1";
this.flowLayoutPanel1.Size = new System.Drawing.Size(292, 273);
this.flowLayoutPanel1.TabIndex = 0;
//
// buttonGo
//
this.buttonGo.AutoSize = true;
this.buttonGo.Dock = System.Windows.Forms.DockStyle.Bottom;
this.buttonGo.Location = new System.Drawing.Point(0, 250);
this.buttonGo.Name = "buttonGo";
this.buttonGo.Size = new System.Drawing.Size(292, 23);
this.buttonGo.TabIndex = 1;
this.buttonGo.Text = "GO";
this.buttonGo.UseVisualStyleBackColor = true;
//
// DestinationPickerForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.AutoSize = true;
this.AutoSizeMode = System.Windows.Forms.AutoSizeMode.GrowAndShrink;
this.ClientSize = new System.Drawing.Size(292, 273);
this.Controls.Add(this.buttonGo);
this.Controls.Add(this.flowLayoutPanel1);
this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon();
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "DestinationPickerForm";
this.Text = "DestinationPickerForm";
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.Button buttonGo;
private System.Windows.Forms.FlowLayoutPanel flowLayoutPanel1;
}
}

View file

@ -1,71 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
namespace Greenshot.Forms
{
/// <summary>
/// Description of DestinationPickerForm.
/// </summary>
public partial class DestinationPickerForm : Form {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(DestinationPickerForm));
private static CoreConfiguration config = IniConfig.GetIniSection<CoreConfiguration>();
private static ILanguage lang = Language.GetInstance();
public DestinationPickerForm() {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
this.Text = lang.GetString(LangKey.settings_destination);
AddCheckBox(flowLayoutPanel1, Destination.Clipboard, lang.GetString(LangKey.settings_destination_clipboard));
AddCheckBox(flowLayoutPanel1, Destination.Editor, lang.GetString(LangKey.settings_destination_editor));
AddCheckBox(flowLayoutPanel1, Destination.EMail, lang.GetString(LangKey.settings_destination_email));
AddCheckBox(flowLayoutPanel1, Destination.FileDefault, lang.GetString(LangKey.settings_destination_file));
AddCheckBox(flowLayoutPanel1, Destination.FileWithDialog, lang.GetString(LangKey.settings_destination_fileas));
AddCheckBox(flowLayoutPanel1, Destination.Printer, lang.GetString(LangKey.settings_destination_printer));
}
public void ShowAtMouse(IWin32Window owner) {
this.Show(owner);
Point target = Cursor.Position;
target.X -= this.Width / 2;
target.Y -= this.Height / 2;
this.Location = target;
}
private void AddCheckBox(Panel panel, Destination destination, string text) {
CheckBox checkbox = new CheckBox();
checkbox.Text = text;
//checkbox.Width = 200;
//checkbox.Height = 20;
checkbox.AutoSize = true;
if (config.OutputDestinations.Contains(destination)) {
checkbox.Checked = true;
}
panel.Controls.Add(checkbox);
}
}
}

View file

@ -0,0 +1,33 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Windows.Forms;
namespace Greenshot.Forms {
/// <summary>
/// FormWithoutActivation is exactly like a normal form, but doesn't activate (steal focus)
/// </summary>
public class FormWithoutActivation : Form {
protected override bool ShowWithoutActivation {
get { return true; }
}
}
}

View file

@ -61,23 +61,23 @@ namespace Greenshot {
this.btnArrow = new System.Windows.Forms.ToolStripButton();
this.btnText = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator14 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripSeparator15 = new System.Windows.Forms.ToolStripSeparator();
this.toolStripSeparator16 = new System.Windows.Forms.ToolStripSeparator();
this.btnHighlight = new System.Windows.Forms.ToolStripButton();
this.btnObfuscate = new System.Windows.Forms.ToolStripButton();
this.btnFreehand = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator13 = new System.Windows.Forms.ToolStripSeparator();
this.btnCrop = new System.Windows.Forms.ToolStripButton();
this.menuStrip1 = new System.Windows.Forms.MenuStrip();
this.fileStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.saveAsToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyImageToClipboardToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.printToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.emailToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator9 = new System.Windows.Forms.ToolStripSeparator();
this.closeToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.editToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.cutToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.copyToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.pasteToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.undoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.redoToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator4 = new System.Windows.Forms.ToolStripSeparator();
this.duplicateToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripSeparator12 = new System.Windows.Forms.ToolStripSeparator();
@ -85,6 +85,7 @@ namespace Greenshot {
this.objectToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addRectangleToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addEllipseToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.drawFreehandToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.drawLineToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.drawArrowToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.addTextBoxToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
@ -113,6 +114,8 @@ namespace Greenshot {
this.btnCut = new System.Windows.Forms.ToolStripButton();
this.btnCopy = new System.Windows.Forms.ToolStripButton();
this.btnPaste = new System.Windows.Forms.ToolStripButton();
this.btnUndo = new System.Windows.Forms.ToolStripButton();
this.btnRedo = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator6 = new System.Windows.Forms.ToolStripSeparator();
this.btnSettings = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator11 = new System.Windows.Forms.ToolStripSeparator();
@ -162,9 +165,10 @@ namespace Greenshot {
this.fileSavedStatusContextMenu = new System.Windows.Forms.ContextMenuStrip(this.components);
this.copyPathMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.openDirectoryMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.btnEmail = new System.Windows.Forms.ToolStripButton();
this.toolStripSeparator5 = new System.Windows.Forms.ToolStripSeparator();
this.insert_window_toolstripmenuitem = new System.Windows.Forms.ToolStripMenuItem();
this.dimensionsLabel = new System.Windows.Forms.ToolStripStatusLabel();
this.autoCropToolStripMenuItem = new System.Windows.Forms.ToolStripMenuItem();
this.toolStripContainer1.BottomToolStripPanel.SuspendLayout();
this.toolStripContainer1.ContentPanel.SuspendLayout();
this.toolStripContainer1.LeftToolStripPanel.SuspendLayout();
@ -211,8 +215,7 @@ namespace Greenshot {
// statusStrip1
//
this.statusStrip1.Dock = System.Windows.Forms.DockStyle.None;
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.statusLabel});
this.statusStrip1.Items.AddRange(new System.Windows.Forms.ToolStripItem[] {this.dimensionsLabel, this.statusLabel});
this.statusStrip1.Location = new System.Drawing.Point(0, 0);
this.statusStrip1.Name = "statusStrip1";
this.statusStrip1.Size = new System.Drawing.Size(785, 22);
@ -221,6 +224,11 @@ namespace Greenshot {
//
// statusLabel
//
this.statusLabel.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Top)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Right)
| System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.statusLabel.BorderStyle = System.Windows.Forms.Border3DStyle.Sunken;
this.statusLabel.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.statusLabel.Name = "statusLabel";
this.statusLabel.Size = new System.Drawing.Size(0, 17);
this.statusLabel.MouseDown += new System.Windows.Forms.MouseEventHandler(this.StatusLabelClicked);
@ -262,6 +270,7 @@ namespace Greenshot {
this.btnEllipse,
this.btnLine,
this.btnArrow,
this.btnFreehand,
this.btnText,
this.toolStripSeparator14,
this.btnHighlight,
@ -300,7 +309,6 @@ namespace Greenshot {
this.btnRect.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnRect.Name = "btnRect";
this.btnRect.Size = new System.Drawing.Size(22, 20);
this.btnRect.Text = "Draw rectangle";
this.btnRect.Click += new System.EventHandler(this.BtnRectClick);
//
// btnEllipse
@ -311,7 +319,6 @@ namespace Greenshot {
this.btnEllipse.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnEllipse.Name = "btnEllipse";
this.btnEllipse.Size = new System.Drawing.Size(22, 20);
this.btnEllipse.Text = "Draw ellipse";
this.btnEllipse.Click += new System.EventHandler(this.BtnEllipseClick);
//
// btnLine
@ -322,7 +329,6 @@ namespace Greenshot {
this.btnLine.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnLine.Name = "btnLine";
this.btnLine.Size = new System.Drawing.Size(22, 20);
this.btnLine.Text = "Draw line";
this.btnLine.Click += new System.EventHandler(this.BtnLineClick);
//
// btnArrow
@ -333,7 +339,6 @@ namespace Greenshot {
this.btnArrow.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnArrow.Name = "btnArrow";
this.btnArrow.Size = new System.Drawing.Size(22, 20);
this.btnArrow.Text = "Draw arrow";
this.btnArrow.Click += new System.EventHandler(this.BtnArrowClick);
//
// btnText
@ -344,7 +349,6 @@ namespace Greenshot {
this.btnText.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnText.Name = "btnText";
this.btnText.Size = new System.Drawing.Size(22, 20);
this.btnText.Text = "Add text";
this.btnText.Click += new System.EventHandler(this.BtnTextClick);
//
// toolStripSeparator14
@ -352,6 +356,16 @@ namespace Greenshot {
this.toolStripSeparator14.Name = "toolStripSeparator14";
this.toolStripSeparator14.Size = new System.Drawing.Size(22, 6);
//
// toolStripSeparator15
//
this.toolStripSeparator15.Name = "toolStripSeparator15";
this.toolStripSeparator15.Size = new System.Drawing.Size(22, 6);
//
// toolStripSeparator16
//
this.toolStripSeparator16.Name = "toolStripSeparator16";
this.toolStripSeparator16.Size = new System.Drawing.Size(22, 6);
//
// btnHighlight
//
this.btnHighlight.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
@ -359,7 +373,6 @@ namespace Greenshot {
this.btnHighlight.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnHighlight.Name = "btnHighlight";
this.btnHighlight.Size = new System.Drawing.Size(22, 20);
this.btnHighlight.Text = "Highlight";
this.btnHighlight.Click += new System.EventHandler(this.BtnHighlightClick);
//
// btnObfuscate
@ -369,13 +382,21 @@ namespace Greenshot {
this.btnObfuscate.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnObfuscate.Name = "btnObfuscate";
this.btnObfuscate.Size = new System.Drawing.Size(22, 20);
this.btnObfuscate.Text = "Obfuscate";
this.btnObfuscate.Click += new System.EventHandler(this.BtnObfuscateClick);
//
// btnFreehand
//
this.btnFreehand.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnFreehand.Image = ((System.Drawing.Image)(resources.GetObject("freehand.Image")));
this.btnFreehand.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnFreehand.Name = "btnFreehand";
this.btnFreehand.Size = new System.Drawing.Size(30, 20);
this.btnFreehand.Click += new System.EventHandler(this.BtnFreehandClick);
//
// toolStripSeparator13
//
this.toolStripSeparator13.Name = "toolStripSeparator13";
this.toolStripSeparator13.Size = new System.Drawing.Size(22, 6);
this.toolStripSeparator13.Size = new System.Drawing.Size(30, 6);
//
// btnCrop
//
@ -384,7 +405,6 @@ namespace Greenshot {
this.btnCrop.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnCrop.Name = "btnCrop";
this.btnCrop.Size = new System.Drawing.Size(22, 20);
this.btnCrop.Text = "Crop";
this.btnCrop.Click += new System.EventHandler(this.BtnCropClick);
//
// menuStrip1
@ -400,69 +420,13 @@ namespace Greenshot {
this.menuStrip1.Name = "menuStrip1";
this.menuStrip1.Size = new System.Drawing.Size(785, 24);
this.menuStrip1.TabIndex = 1;
this.menuStrip1.Text = "menuStrip1";
//
// fileStripMenuItem
//
this.fileStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.saveToolStripMenuItem,
this.saveAsToolStripMenuItem,
this.copyImageToClipboardToolStripMenuItem,
this.printToolStripMenuItem,
this.emailToolStripMenuItem,
this.toolStripSeparator9,
this.closeToolStripMenuItem});
this.fileStripMenuItem.Name = "fileStripMenuItem";
this.fileStripMenuItem.Size = new System.Drawing.Size(35, 20);
this.fileStripMenuItem.Text = "File";
//
// saveToolStripMenuItem
//
this.saveToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image")));
this.saveToolStripMenuItem.Name = "saveToolStripMenuItem";
this.saveToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.S)));
this.saveToolStripMenuItem.Size = new System.Drawing.Size(307, 22);
this.saveToolStripMenuItem.Text = "Save";
this.saveToolStripMenuItem.Click += new System.EventHandler(this.SaveToolStripMenuItemClick);
//
// saveAsToolStripMenuItem
//
this.saveAsToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("saveToolStripMenuItem.Image")));
this.saveAsToolStripMenuItem.Name = "saveAsToolStripMenuItem";
this.saveAsToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.S)));
this.saveAsToolStripMenuItem.Size = new System.Drawing.Size(307, 22);
this.saveAsToolStripMenuItem.Text = "Save as...";
this.saveAsToolStripMenuItem.Click += new System.EventHandler(this.SaveAsToolStripMenuItemClick);
//
// copyImageToClipboardToolStripMenuItem
//
this.copyImageToClipboardToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("copyImageToClipboardToolStripMenuItem.Image")));
this.copyImageToClipboardToolStripMenuItem.Name = "copyImageToClipboardToolStripMenuItem";
this.copyImageToClipboardToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)(((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Shift)
| System.Windows.Forms.Keys.C)));
this.copyImageToClipboardToolStripMenuItem.Size = new System.Drawing.Size(307, 22);
this.copyImageToClipboardToolStripMenuItem.Text = "Copy image to clipboard";
this.copyImageToClipboardToolStripMenuItem.Click += new System.EventHandler(this.CopyImageToClipboardToolStripMenuItemClick);
//
// printToolStripMenuItem
//
this.printToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("printToolStripMenuItem.Image")));
this.printToolStripMenuItem.Name = "printToolStripMenuItem";
this.printToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.P)));
this.printToolStripMenuItem.Size = new System.Drawing.Size(307, 22);
this.printToolStripMenuItem.Text = "Print...";
this.printToolStripMenuItem.Click += new System.EventHandler(this.PrintToolStripMenuItemClick);
//
// emailToolStripMenuItem
//
this.emailToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("emailToolStripMenuItem.Image")));
this.emailToolStripMenuItem.Name = "emailToolStripMenuItem";
this.emailToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.E)));
this.emailToolStripMenuItem.Size = new System.Drawing.Size(307, 22);
this.emailToolStripMenuItem.Text = "EMail";
this.emailToolStripMenuItem.Click += new System.EventHandler(this.EmailToolStripMenuItemClick);
//
this.fileStripMenuItem.DropDownOpening += new System.EventHandler(this.FileMenuDropDownOpening);
// toolStripSeparator9
//
this.toolStripSeparator9.Name = "toolStripSeparator9";
@ -477,9 +441,19 @@ namespace Greenshot {
this.closeToolStripMenuItem.Text = "Close";
this.closeToolStripMenuItem.Click += new System.EventHandler(this.CloseToolStripMenuItemClick);
//
// autoCropToolStripMenuItem
//
this.autoCropToolStripMenuItem.Name = "autoCropToolStripMenuItem";
this.autoCropToolStripMenuItem.Size = new System.Drawing.Size(166, 22);
this.autoCropToolStripMenuItem.Text = "Auto Crop";
this.autoCropToolStripMenuItem.Click += new System.EventHandler(this.AutoCropToolStripMenuItemClick);
//
// editToolStripMenuItem
//
this.editToolStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.undoToolStripMenuItem,
this.redoToolStripMenuItem,
this.toolStripSeparator15,
this.cutToolStripMenuItem,
this.copyToolStripMenuItem,
this.pasteToolStripMenuItem,
@ -488,6 +462,7 @@ namespace Greenshot {
this.toolStripSeparator12,
this.preferencesToolStripMenuItem,
this.toolStripSeparator5,
this.autoCropToolStripMenuItem,
this.insert_window_toolstripmenuitem});
this.editToolStripMenuItem.Name = "editToolStripMenuItem";
this.editToolStripMenuItem.Size = new System.Drawing.Size(37, 20);
@ -524,6 +499,26 @@ namespace Greenshot {
this.pasteToolStripMenuItem.Text = "Paste";
this.pasteToolStripMenuItem.Click += new System.EventHandler(this.PasteToolStripMenuItemClick);
//
// undoToolStripMenuItem
//
this.undoToolStripMenuItem.Enabled = false;
this.undoToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("btnUndo.Image")));
this.undoToolStripMenuItem.Name = "undoToolStripMenuItem";
this.undoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Z)));
this.undoToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.undoToolStripMenuItem.Text = "Undo";
this.undoToolStripMenuItem.Click += new System.EventHandler(this.UndoToolStripMenuItemClick);
//
// redoToolStripMenuItem
//
this.redoToolStripMenuItem.Enabled = false;
this.redoToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("btnRedo.Image")));
this.redoToolStripMenuItem.Name = "redoToolStripMenuItem";
this.redoToolStripMenuItem.ShortcutKeys = ((System.Windows.Forms.Keys)((System.Windows.Forms.Keys.Control | System.Windows.Forms.Keys.Y)));
this.redoToolStripMenuItem.Size = new System.Drawing.Size(160, 22);
this.redoToolStripMenuItem.Text = "Redo";
this.redoToolStripMenuItem.Click += new System.EventHandler(this.RedoToolStripMenuItemClick);
//
// toolStripSeparator4
//
this.toolStripSeparator4.Name = "toolStripSeparator4";
@ -558,6 +553,7 @@ namespace Greenshot {
this.addEllipseToolStripMenuItem,
this.drawLineToolStripMenuItem,
this.drawArrowToolStripMenuItem,
this.drawFreehandToolStripMenuItem,
this.addTextBoxToolStripMenuItem,
this.toolStripSeparator8,
this.selectAllToolStripMenuItem,
@ -586,6 +582,14 @@ namespace Greenshot {
this.addEllipseToolStripMenuItem.Text = "Draw ellipse";
this.addEllipseToolStripMenuItem.Click += new System.EventHandler(this.AddEllipseToolStripMenuItemClick);
//
// drawFreehandToolStripMenuItem
//
this.drawFreehandToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("freehand.Image")));
this.drawFreehandToolStripMenuItem.Name = "drawFreehandToolStripMenuItem";
this.drawFreehandToolStripMenuItem.Size = new System.Drawing.Size(189, 22);
this.drawFreehandToolStripMenuItem.Text = "Draw freehand";
this.drawFreehandToolStripMenuItem.Click += new System.EventHandler(this.DrawFreehandToolStripMenuItemClick);
//
// drawLineToolStripMenuItem
//
this.drawLineToolStripMenuItem.Image = ((System.Drawing.Image)(resources.GetObject("drawLineToolStripMenuItem.Image")));
@ -740,16 +744,18 @@ namespace Greenshot {
this.btnSave,
this.btnClipboard,
this.btnPrint,
this.btnEmail,
this.toolStripSeparator2,
this.btnDelete,
this.toolStripSeparator3,
this.btnCut,
this.btnCopy,
this.btnPaste,
this.btnUndo,
this.btnRedo,
this.toolStripSeparator6,
this.btnSettings,
this.toolStripSeparator11,
this.toolStripSeparator16,
this.btnHelp});
this.toolStrip1.Location = new System.Drawing.Point(0, 24);
this.toolStrip1.Name = "toolStrip1";
@ -840,6 +846,25 @@ namespace Greenshot {
this.btnPaste.Size = new System.Drawing.Size(23, 22);
this.btnPaste.Text = "Paste element from clipboard";
this.btnPaste.Click += new System.EventHandler(this.BtnPasteClick);
// btnUndo
//
this.btnUndo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnUndo.Enabled = false;
this.btnUndo.Image = ((System.Drawing.Image)(resources.GetObject("btnUndo.Image")));
this.btnUndo.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnUndo.Name = "btnUndo";
this.btnUndo.Size = new System.Drawing.Size(23, 22);
this.btnUndo.Click += new System.EventHandler(this.BtnUndoClick);
//
// btnRedo
//
this.btnRedo.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnRedo.Enabled = false;
this.btnRedo.Image = ((System.Drawing.Image)(resources.GetObject("btnRedo.Image")));
this.btnRedo.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnRedo.Name = "btnRedo";
this.btnRedo.Size = new System.Drawing.Size(23, 22);
this.btnRedo.Click += new System.EventHandler(this.BtnRedoClick);
//
// toolStripSeparator6
//
@ -1351,7 +1376,6 @@ namespace Greenshot {
this.shadowButton.ImageTransparentColor = System.Drawing.Color.Magenta;
this.shadowButton.Name = "shadowButton";
this.shadowButton.Size = new System.Drawing.Size(23, 20);
this.shadowButton.Text = "Shadow";
//
// toolStripSeparator
//
@ -1425,16 +1449,6 @@ namespace Greenshot {
this.openDirectoryMenuItem.Text = "Open directory in Windows Explorer";
this.openDirectoryMenuItem.Click += new System.EventHandler(this.OpenDirectoryMenuItemClick);
//
// btnEmail
//
this.btnEmail.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
this.btnEmail.Image = ((System.Drawing.Image)(resources.GetObject("btnEmail.Image")));
this.btnEmail.ImageTransparentColor = System.Drawing.Color.Magenta;
this.btnEmail.Name = "btnEmail";
this.btnEmail.Size = new System.Drawing.Size(23, 22);
this.btnEmail.Text = "Email";
this.btnEmail.Click += new System.EventHandler(this.BtnEmailClick);
//
// toolStripSeparator5
//
this.toolStripSeparator5.Name = "toolStripSeparator5";
@ -1447,6 +1461,15 @@ namespace Greenshot {
this.insert_window_toolstripmenuitem.Text = "Insert window";
this.insert_window_toolstripmenuitem.MouseEnter += new System.EventHandler(this.Insert_window_toolstripmenuitemMouseEnter);
//
// dimensionsLabel
//
this.dimensionsLabel.BorderSides = ((System.Windows.Forms.ToolStripStatusLabelBorderSides)((((System.Windows.Forms.ToolStripStatusLabelBorderSides.Left | System.Windows.Forms.ToolStripStatusLabelBorderSides.Top) | System.Windows.Forms.ToolStripStatusLabelBorderSides.Right) | System.Windows.Forms.ToolStripStatusLabelBorderSides.Bottom)));
this.dimensionsLabel.BorderStyle = System.Windows.Forms.Border3DStyle.Sunken;
this.dimensionsLabel.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Text;
this.dimensionsLabel.Name = "dimensionsLabel";
this.dimensionsLabel.Size = new System.Drawing.Size(48, 17);
this.dimensionsLabel.Text = "123x321";
//
// ImageEditorForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
@ -1482,9 +1505,9 @@ namespace Greenshot {
this.fileSavedStatusContextMenu.ResumeLayout(false);
this.ResumeLayout(false);
}
private System.Windows.Forms.ToolStripStatusLabel dimensionsLabel;
private System.Windows.Forms.ToolStripMenuItem insert_window_toolstripmenuitem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator5;
private System.Windows.Forms.ToolStripButton btnEmail;
private System.Windows.Forms.ToolStripMenuItem grayscaleHighlightMenuItem;
private System.Windows.Forms.ToolStripMenuItem areaHighlightMenuItem;
private System.Windows.Forms.ToolStripMenuItem textHighlightMenuItem;
@ -1501,7 +1524,6 @@ namespace Greenshot {
private System.Windows.Forms.ToolStripMenuItem blurToolStripMenuItem;
private Greenshot.Controls.BindableToolStripDropDownButton obfuscateModeButton;
private System.Windows.Forms.ToolStripButton btnHighlight;
private System.Windows.Forms.ToolStripMenuItem emailToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem loadElementsToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveElementsToolStripMenuItem;
private Greenshot.Controls.FontFamilyComboBox fontFamilyComboBox;
@ -1531,6 +1553,9 @@ namespace Greenshot {
private System.Windows.Forms.ToolStripLabel lineThicknessLabel;
private Greenshot.Controls.ToolStripNumericUpDown lineThicknessUpDown;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator14;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator15;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator16;
private System.Windows.Forms.ToolStripButton btnFreehand;
private System.Windows.Forms.ToolStripButton btnObfuscate;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator13;
private System.Windows.Forms.ToolStripButton btnCrop;
@ -1546,6 +1571,7 @@ namespace Greenshot {
private System.Windows.Forms.ToolStrip toolStrip2;
private System.Windows.Forms.ToolStripButton btnArrow;
private System.Windows.Forms.ToolStripMenuItem drawArrowToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem drawFreehandToolStripMenuItem;
private System.Windows.Forms.ToolStripButton btnText;
private System.Windows.Forms.ToolStripMenuItem drawLineToolStripMenuItem;
private System.Windows.Forms.ToolStripButton btnLine;
@ -1563,29 +1589,29 @@ namespace Greenshot {
private System.Windows.Forms.ToolStripSeparator toolStripSeparator8;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator6;
private System.Windows.Forms.ToolStripButton btnPrint;
private System.Windows.Forms.ToolStripMenuItem printToolStripMenuItem;
private System.Windows.Forms.PrintDialog printDialog1;
private System.Windows.Forms.ToolStripMenuItem duplicateToolStripMenuItem;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator4;
private System.Windows.Forms.ToolStripMenuItem fileStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem removeObjectToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem addTextBoxToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem addEllipseToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem addRectangleToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem objectToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem undoToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem redoToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem pasteToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem cutToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem editToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem copyImageToClipboardToolStripMenuItem;
private System.Windows.Forms.ToolStripMenuItem saveAsToolStripMenuItem;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.ToolStripStatusLabel statusLabel;
private System.Windows.Forms.StatusStrip statusStrip1;
private System.Windows.Forms.ToolStripButton btnCut;
private System.Windows.Forms.ToolStripButton btnPaste;
private System.Windows.Forms.ToolStripButton btnCopy;
private System.Windows.Forms.ToolStripButton btnPaste;
private System.Windows.Forms.ToolStripButton btnUndo;
private System.Windows.Forms.ToolStripButton btnRedo;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator3;
private System.Windows.Forms.ToolStripButton btnClipboard;
private System.Windows.Forms.ToolStripButton btnDelete;
@ -1600,5 +1626,6 @@ namespace Greenshot {
private GreenshotPlugin.Controls.NonJumpingPanel panel1;
private Greenshot.Controls.ToolStripColorButton btnFillColor;
private Greenshot.Controls.ToolStripColorButton btnLineColor;
private System.Windows.Forms.ToolStripMenuItem autoCropToolStripMenuItem;
}
}

View file

@ -19,29 +19,25 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Printing;
using System.IO;
using System.Resources;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Fields.Binding;
using Greenshot.Experimental;
using Greenshot.Forms;
using Greenshot.Help;
using Greenshot.Helpers;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot {
/// <summary>
@ -52,12 +48,12 @@ namespace Greenshot {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageEditorForm));
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
private static CoreConfiguration coreConf = IniConfig.GetIniSection<CoreConfiguration>();
private static List<string> ignoreDestinations = new List<string>() {"Picker", "Editor"};
private static List<IImageEditor> editorList = new List<IImageEditor>();
private ILanguage lang;
private string lastSaveFullPath;
public Surface surface;
private Surface surface;
private System.Windows.Forms.ToolStripButton[] toolbarButtons;
private static string[] SUPPORTED_CLIPBOARD_FORMATS = {typeof(string).FullName, "Text", "DeviceIndependentBitmap", "Bitmap", typeof(DrawableContainerList).FullName};
@ -75,8 +71,22 @@ namespace Greenshot {
get { return this; }
}
public ImageEditorForm(Surface surface, bool outputMade) {
public Surface EditorSurface {
get {
return surface;
}
}
public static List<IImageEditor> Editors {
get {
return editorList;
}
}
public ImageEditorForm(ISurface iSurface, bool outputMade) {
// init surface
this.surface = iSurface as Surface;
editorList.Add(this);
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
@ -95,12 +105,12 @@ namespace Greenshot {
// a smaller size than the initial panel size (as set by the forms designer)
panel1.Height = 10;
// init surface
this.surface = surface;
surface.TabStop = false;
surface.MovingElementChanged += delegate { refreshEditorControls(); };
surface.DrawingModeChanged += new SurfaceDrawingModeEventHandler(surface_DrawingModeChanged);
surface.SurfaceSizeChanged += new SurfaceSizeChangeEventHandler(SurfaceSizeChanged);
surface.SurfaceMessage += new SurfaceMessageEventHandler(SurfaceMessageReceived);
this.fontFamilyComboBox.PropertyChanged += new PropertyChangedEventHandler(FontPropertyChanged);
@ -116,34 +126,151 @@ namespace Greenshot {
WindowDetails thisForm = new WindowDetails(this.Handle);
thisForm.SetWindowPlacement(editorConfiguration.GetEditorPlacement());
if (editorConfiguration.MatchSizeToCapture) {
// Set editor's initial size to the size of the surface plus the size of the chrome
Size imageSize = this.Surface.Image.Size;
Size currentFormSize = this.Size;
Size currentImageClientSize = this.panel1.ClientSize;
int minimumFormWidth = 480;
int minimumFormHeight = 360;
int newWidth = Math.Max(minimumFormWidth, (currentFormSize.Width - currentImageClientSize.Width) + imageSize.Width);
int newHeight = Math.Max(minimumFormHeight, (currentFormSize.Height - currentImageClientSize.Height) + imageSize.Height);
this.Size = new Size(newWidth, newHeight);
}
SurfaceSizeChanged(this.Surface);
updateUI();
IniConfig.IniChanged += new FileSystemEventHandler(ReloadConfiguration);
bindFieldControls();
refreshEditorControls();
// Workaround: As the cursor is (mostly) selected on the surface a funny artifact is visible, this fixes it.
hideToolstripItems();
toolbarButtons = new ToolStripButton[]{btnCursor,btnRect,btnEllipse,btnText,btnLine,btnArrow,btnHighlight, btnObfuscate, btnCrop};
toolbarButtons = new ToolStripButton[]{btnCursor,btnRect,btnEllipse,btnText,btnLine,btnArrow, btnFreehand, btnHighlight, btnObfuscate, btnCrop};
//toolbarDropDownButtons = new ToolStripDropDownButton[]{btnBlur, btnPixeliate, btnTextHighlighter, btnAreaHighlighter, btnMagnifier};
PluginHelper.instance.CreateImageEditorOpenEvent(this);
pluginToolStripMenuItem.Visible = pluginToolStripMenuItem.DropDownItems.Count > 0;
emailToolStripMenuItem.Enabled = MapiMailMessage.HasMAPIorOutlook();
// This is a "work-around" for the MouseWheel event which doesn't get to the panel
// Workaround: for the MouseWheel event which doesn't get to the panel
this.MouseWheel += new MouseEventHandler( PanelMouseWheel);
// Create export buttons
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
if (destination.Priority <= 2) {
continue;
}
if (!destination.isActive) {
continue;
}
if (destination.DisplayIcon == null) {
continue;
}
try {
AddDestinationButton(destination);
} catch (Exception addingException) {
LOG.WarnFormat("Problem adding destination {0}", destination.Designation);
LOG.Warn("Exception: ", addingException);
}
}
}
void AddDestinationButton(IDestination toolstripDestination) {
if (toolstripDestination.isDynamic) {
ToolStripSplitButton destinationButton = new ToolStripSplitButton();
//ToolStripDropDownButton destinationButton = new ToolStripDropDownButton();
destinationButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
destinationButton.Size = new System.Drawing.Size(23, 22);
destinationButton.Text = toolstripDestination.Description;
destinationButton.Image = toolstripDestination.DisplayIcon;
ToolStripMenuItem defaultItem = new ToolStripMenuItem(toolstripDestination.Description);
defaultItem.Tag = toolstripDestination;
defaultItem.Image = toolstripDestination.DisplayIcon;
defaultItem.Click += delegate {
toolstripDestination.ExportCapture(surface, surface.CaptureDetails);
};
// The ButtonClick, this is for the icon, gets the current default item
destinationButton.ButtonClick += delegate(object sender, EventArgs e) {
toolstripDestination.ExportCapture(surface, surface.CaptureDetails);
};
// Generate the entries for the drop down
destinationButton.DropDownOpening += delegate(object sender, EventArgs e) {
destinationButton.DropDownItems.Clear();
destinationButton.DropDownItems.Add(defaultItem);
List<IDestination> subDestinations = new List<IDestination>();
subDestinations.AddRange(toolstripDestination.DynamicDestinations());
if (subDestinations.Count > 0) {
subDestinations.Sort();
foreach(IDestination subDestination in subDestinations) {
ToolStripMenuItem destinationMenuItem = new ToolStripMenuItem(subDestination.Description);
destinationMenuItem.Tag = subDestination;
destinationMenuItem.Image = subDestination.DisplayIcon;
destinationMenuItem.Click += delegate {
subDestination.ExportCapture(surface, surface.CaptureDetails);
};
destinationButton.DropDownItems.Add(destinationMenuItem);
}
}
};
toolStrip1.Items.Insert(toolStrip1.Items.IndexOf(toolStripSeparator16), destinationButton);
} else {
ToolStripButton destinationButton = new ToolStripButton();
toolStrip1.Items.Insert(toolStrip1.Items.IndexOf(toolStripSeparator16), destinationButton);
destinationButton.DisplayStyle = System.Windows.Forms.ToolStripItemDisplayStyle.Image;
destinationButton.Size = new System.Drawing.Size(23, 22);
destinationButton.Text = toolstripDestination.Description;
destinationButton.Image = toolstripDestination.DisplayIcon;
destinationButton.Click += delegate(object sender, EventArgs e) {
toolstripDestination.ExportCapture(surface, surface.CaptureDetails);
};
}
}
void FileMenuDropDownOpening(object sender, EventArgs eventArgs) {
this.fileStripMenuItem.DropDownItems.Clear();
//this.fileStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
// this.saveToolStripMenuItem,
// this.saveAsToolStripMenuItem,
// this.copyImageToClipboardToolStripMenuItem,
// this.printToolStripMenuItem});
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
if (ignoreDestinations.Contains(destination.Designation)) {
continue;
}
if (!destination.isActive) {
continue;
}
ToolStripMenuItem item = destination.GetMenuItem(new EventHandler(DestinationToolStripMenuItemClick));
item.ShortcutKeys = destination.EditorShortcutKeys;
if (item != null) {
fileStripMenuItem.DropDownItems.Add(item);
}
}
// add the elements after the destinations
this.fileStripMenuItem.DropDownItems.AddRange(new System.Windows.Forms.ToolStripItem[] {
this.toolStripSeparator9,
this.closeToolStripMenuItem});
}
private void SurfaceMessageReceived(object sender, SurfaceMessageEventArgs eventArgs) {
string dateTime = DateTime.Now.ToLongTimeString();
if (eventArgs.MessageType == SurfaceMessageTyp.FileSaved) {
updateStatusLabel(dateTime + " - " + eventArgs.Message, fileSavedStatusContextMenu);
} else {
updateStatusLabel(dateTime + " - " + eventArgs.Message);
}
}
private void SurfaceSizeChanged(object source) {
if (editorConfiguration.MatchSizeToCapture) {
// Set editor's initial size to the size of the surface plus the size of the chrome
Size imageSize = this.Surface.Image.Size;
Size currentFormSize = this.Size;
Size currentImageClientSize = this.panel1.ClientSize;
int minimumFormWidth = 480;
int minimumFormHeight = 390;
int newWidth = Math.Max(minimumFormWidth, (currentFormSize.Width - currentImageClientSize.Width) + imageSize.Width);
int newHeight = Math.Max(minimumFormHeight, (currentFormSize.Height - currentImageClientSize.Height) + imageSize.Height);
this.Size = new Size(newWidth, newHeight);
}
dimensionsLabel.Text = this.Surface.Image.Width + "x" + this.Surface.Image.Height;
}
private void ReloadConfiguration(object source, FileSystemEventArgs e) {
@ -156,21 +283,15 @@ namespace Greenshot {
private void updateUI() {
string editorTitle = lang.GetString(LangKey.editor_title);
if (surface != null && surface.CaptureDetails != null && surface.CaptureDetails.Title != null) {
editorTitle = editorTitle + " - " + surface.CaptureDetails.Title;
editorTitle = surface.CaptureDetails.Title + " - " + editorTitle;
}
this.Text = editorTitle;
this.fileStripMenuItem.Text = lang.GetString(LangKey.editor_file);
this.btnSave.Text = lang.GetString(LangKey.editor_save);
this.saveToolStripMenuItem.Text = lang.GetString(LangKey.editor_save);
this.saveAsToolStripMenuItem.Text = lang.GetString(LangKey.editor_saveas);
this.btnClipboard.Text = lang.GetString(LangKey.editor_copyimagetoclipboard);
this.copyImageToClipboardToolStripMenuItem.Text = lang.GetString(LangKey.editor_copyimagetoclipboard);
this.emailToolStripMenuItem.Text = lang.GetString(LangKey.editor_email);
this.btnEmail.Text = lang.GetString(LangKey.editor_email);
this.btnPrint.Text = lang.GetString(LangKey.editor_print);
this.printToolStripMenuItem.Text = lang.GetString(LangKey.editor_print)+"...";
this.closeToolStripMenuItem.Text = lang.GetString(LangKey.editor_close);
this.editToolStripMenuItem.Text = lang.GetString(LangKey.editor_edit);
@ -183,25 +304,28 @@ namespace Greenshot {
this.addTextBoxToolStripMenuItem.Text = lang.GetString(LangKey.editor_drawtextbox);
this.btnLine.Text = lang.GetString(LangKey.editor_drawline);
this.drawLineToolStripMenuItem.Text = lang.GetString(LangKey.editor_drawline);
this.drawFreehandToolStripMenuItem.Text = lang.GetString(LangKey.editor_drawfreehand);
this.btnArrow.Text = lang.GetString(LangKey.editor_drawarrow);
this.drawArrowToolStripMenuItem.Text = lang.GetString(LangKey.editor_drawarrow);
this.btnHighlight.Text = lang.GetString(LangKey.editor_drawhighlighter);
this.selectAllToolStripMenuItem.Text = lang.GetString(LangKey.editor_selectall);
this.btnObfuscate.Text = lang.GetString(LangKey.editor_obfuscate);
this.btnFreehand.Text = lang.GetString(LangKey.editor_drawfreehand);
this.btnCrop.Text = lang.GetString(LangKey.editor_crop);
this.btnDelete.Text = lang.GetString(LangKey.editor_deleteelement);
this.removeObjectToolStripMenuItem.Text = lang.GetString(LangKey.editor_deleteelement);
this.btnSettings.Text = lang.GetString(LangKey.contextmenu_settings);
this.preferencesToolStripMenuItem.Text = lang.GetString(LangKey.contextmenu_settings);
this.objectToolStripMenuItem.Text = lang.GetString(LangKey.editor_object);
this.btnCut.Text = lang.GetString(LangKey.editor_cuttoclipboard);
this.cutToolStripMenuItem.Text = lang.GetString(LangKey.editor_cuttoclipboard);
this.btnCopy.Text = lang.GetString(LangKey.editor_copytoclipboard);
this.copyToolStripMenuItem.Text = lang.GetString(LangKey.editor_copytoclipboard);
this.btnPaste.Text = lang.GetString(LangKey.editor_pastefromclipboard);
this.selectAllToolStripMenuItem.Text = lang.GetString(LangKey.editor_selectall);
this.preferencesToolStripMenuItem.Text = lang.GetString(LangKey.contextmenu_settings);
this.removeObjectToolStripMenuItem.Text = lang.GetString(LangKey.editor_deleteelement);
this.copyToolStripMenuItem.Text = lang.GetString(LangKey.editor_copytoclipboard);
this.pasteToolStripMenuItem.Text = lang.GetString(LangKey.editor_pastefromclipboard);
this.cutToolStripMenuItem.Text = lang.GetString(LangKey.editor_cuttoclipboard);
this.duplicateToolStripMenuItem.Text = lang.GetString(LangKey.editor_duplicate);
this.objectToolStripMenuItem.Text = lang.GetString(LangKey.editor_object);
this.arrangeToolStripMenuItem.Text = lang.GetString(LangKey.editor_arrange);
this.upToTopToolStripMenuItem.Text = lang.GetString(LangKey.editor_uptotop);
@ -253,6 +377,7 @@ namespace Greenshot {
this.saveElementsToolStripMenuItem.Text = lang.GetString(LangKey.editor_save_objects);
this.loadElementsToolStripMenuItem.Text = lang.GetString(LangKey.editor_load_objects);
this.autoCropToolStripMenuItem.Text = lang.GetString(LangKey.editor_autocrop);
}
public ISurface Surface {
@ -260,7 +385,12 @@ namespace Greenshot {
}
public void SetImagePath(string fullpath) {
this.lastSaveFullPath = fullpath;
// Check if the editor supports the format
if (fullpath != null && (fullpath.EndsWith(".ico") || fullpath.EndsWith(".wmf"))) {
fullpath = null;
}
surface.LastSaveFullPath = fullpath;
if (fullpath == null) {
return;
}
@ -297,6 +427,9 @@ namespace Greenshot {
case DrawingModes.Obfuscate:
SetButtonChecked(btnObfuscate);
break;
case DrawingModes.Path:
SetButtonChecked(btnFreehand);
break;
}
}
@ -330,92 +463,20 @@ namespace Greenshot {
#endregion
#region filesystem options
void SaveToolStripMenuItemClick(object sender, System.EventArgs e) {
// Use SaveAs if we didn't save before
if (lastSaveFullPath == null) {
SaveAsToolStripMenuItemClick(sender,e);
return;
}
try {
using (Image img = surface.GetImageForExport()) {
ImageOutput.Save(img, lastSaveFullPath);
surface.Modified = false;
}
updateStatusLabel(lang.GetFormattedString(LangKey.editor_imagesaved,lastSaveFullPath),fileSavedStatusContextMenu);
} catch(Exception) {
MessageBox.Show(lang.GetFormattedString(LangKey.error_nowriteaccess,lastSaveFullPath).Replace(@"\\",@"\"), lang.GetString(LangKey.error));
}
}
void BtnSaveClick(object sender, EventArgs e) {
if (lastSaveFullPath != null) {
SaveToolStripMenuItemClick(sender,e);
} else {
SaveAsToolStripMenuItemClick(sender, e);
}
}
void SaveAsToolStripMenuItemClick(object sender, EventArgs eventArgs) {
try {
using (Image img = surface.GetImageForExport()) {
// Bug #2918756 don't overwrite lastSaveFullPath if SaveWithDialog returns null!
string savedTo = ImageOutput.SaveWithDialog(img, surface.CaptureDetails);
if (savedTo != null) {
surface.Modified = false;
lastSaveFullPath = savedTo;
}
}
if(lastSaveFullPath != null) {
SetImagePath(lastSaveFullPath);
updateStatusLabel(lang.GetFormattedString(LangKey.editor_imagesaved,lastSaveFullPath),fileSavedStatusContextMenu);
} else {
clearStatusLabel();
}
} catch (Exception e) {
LOG.Error(lang.GetString(LangKey.error_save), e);
MessageBox.Show(lang.GetString(LangKey.error_save), lang.GetString(LangKey.error));
}
}
void CopyImageToClipboardToolStripMenuItemClick(object sender, System.EventArgs e) {
try {
using (Image img = surface.GetImageForExport()) {
ClipboardHelper.SetClipboardData(img);
surface.Modified = false;
}
updateStatusLabel(lang.GetString(LangKey.editor_storedtoclipboard));
} catch (Exception) {
updateStatusLabel(lang.GetString(LangKey.editor_clipboardfailed));
string destinationDesignation = Destinations.FileDestination.DESIGNATION;
if (surface.LastSaveFullPath == null) {
destinationDesignation = Destinations.FileWithDialogDestination.DESIGNATION;
}
DestinationHelper.ExportCapture(destinationDesignation, surface, surface.CaptureDetails);
}
void BtnClipboardClick(object sender, EventArgs e) {
this.CopyImageToClipboardToolStripMenuItemClick(sender, e);
}
void PrintToolStripMenuItemClick(object sender, EventArgs e) {
InvokePrint();
DestinationHelper.ExportCapture(Destinations.ClipboardDestination.DESIGNATION, surface, surface.CaptureDetails);
}
void BtnPrintClick(object sender, EventArgs e) {
// commented for now: workaround seems to have issues on Vista :(
//new ShowPrintDialogDelegate(InvokePrint).BeginInvoke(null,null);
InvokePrint();
}
void InvokePrint() {
using(Image img = surface.GetImageForExport()) {
PrintHelper ph = new PrintHelper(img, surface.CaptureDetails);
this.Hide();
this.Show();
PrinterSettings ps = ph.PrintWithDialog();
if(ps != null) {
surface.Modified = false;
updateStatusLabel(lang.GetFormattedString(LangKey.editor_senttoprinter,ps.PrinterName));
}
}
DestinationHelper.ExportCapture(Destinations.PrinterDestination.DESIGNATION, surface, surface.CaptureDetails);
}
void CloseToolStripMenuItemClick(object sender, System.EventArgs e) {
@ -470,6 +531,11 @@ namespace Greenshot {
refreshFieldControls();
}
void BtnFreehandClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Path;
refreshFieldControls();
}
void SetButtonChecked(ToolStripButton btn) {
UncheckAllToolButtons();
btn.Checked = true;
@ -487,6 +553,10 @@ namespace Greenshot {
BtnRectClick(sender, e);
}
void DrawFreehandToolStripMenuItemClick(object sender, System.EventArgs e) {
BtnFreehandClick(sender, e);
}
void AddEllipseToolStripMenuItemClick(object sender, System.EventArgs e) {
BtnEllipseClick(sender, e);
}
@ -548,6 +618,24 @@ namespace Greenshot {
PasteToolStripMenuItemClick(sender, e);
}
void UndoToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.Undo();
updateUndoRedoSurfaceDependencies();
}
void BtnUndoClick(object sender, System.EventArgs e) {
UndoToolStripMenuItemClick(sender, e);
}
void RedoToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.Redo();
updateUndoRedoSurfaceDependencies();
}
void BtnRedoClick(object sender, System.EventArgs e) {
RedoToolStripMenuItemClick(sender, e);
}
void DuplicateToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.DuplicateSelectedElements();
updateClipboardSurfaceDependencies();
@ -584,7 +672,7 @@ namespace Greenshot {
}
void PreferencesToolStripMenuItemClick(object sender, System.EventArgs e) {
new SettingsForm().Show();
MainForm.instance.ShowSetting();
}
void BtnSettingsClick(object sender, System.EventArgs e) {
@ -599,11 +687,12 @@ namespace Greenshot {
#region image editor event handlers
void ImageEditorFormActivated(object sender, EventArgs e) {
updateClipboardSurfaceDependencies();
updateUndoRedoSurfaceDependencies();
}
void ImageEditorFormFormClosing(object sender, FormClosingEventArgs e) {
IniConfig.IniChanged -= new FileSystemEventHandler(ReloadConfiguration);
if (surface.Modified) {
if (surface.Modified && !editorConfiguration.SuppressSaveDialogAtClose) {
// Make sure the editor is visible
WindowDetails.ToForeground(this.Handle);
@ -618,11 +707,7 @@ namespace Greenshot {
return;
}
if (result.Equals(DialogResult.Yes)) {
if (lastSaveFullPath != null) {
SaveToolStripMenuItemClick(sender,e);
} else {
SaveAsToolStripMenuItemClick(sender, e);
}
BtnSaveClick(sender,e);
// Check if the save was made, if not it was cancelled so we cancel the closing
if (surface.Modified) {
e.Cancel = true;
@ -634,6 +719,9 @@ namespace Greenshot {
editorConfiguration.SetEditorPlacement(new WindowDetails(this.Handle).GetWindowPlacement());
IniConfig.Save();
// remove from the editor list
editorList.Remove(this);
surface.Dispose();
System.GC.Collect();
@ -644,24 +732,51 @@ namespace Greenshot {
// avoid conflict with other shortcuts and
// make sure there's no selected element claiming input focus
if(e.Modifiers.Equals(Keys.None) && !surface.KeysLocked) {
if (Keys.Escape.Equals(e.KeyCode)) {
switch(e.KeyCode) {
case Keys.Escape:
BtnCursorClick(sender, e);
} else if (Keys.R.Equals(e.KeyCode)) {
break;
case Keys.R:
BtnRectClick(sender, e);
} else if (Keys.E.Equals(e.KeyCode)) {
break;
case Keys.E:
BtnEllipseClick(sender, e);
} else if (Keys.L.Equals(e.KeyCode)) {
break;
case Keys.L:
BtnLineClick(sender, e);
} else if (Keys.A.Equals(e.KeyCode)) {
break;
case Keys.F:
BtnFreehandClick(sender, e);
break;
case Keys.A:
BtnArrowClick(sender, e);
} else if (Keys.T.Equals(e.KeyCode)) {
break;
case Keys.T:
BtnTextClick(sender, e);
} else if(Keys.H.Equals(e.KeyCode)) {
break;
case Keys.H:
BtnHighlightClick(sender, e);
} else if(Keys.O.Equals(e.KeyCode)) {
break;
case Keys.O:
BtnObfuscateClick(sender, e);
} else if(Keys.C.Equals(e.KeyCode)) {
break;
case Keys.C:
BtnCropClick(sender, e);
break;
case Keys.P:
//surface.PreviewMode = !surface.PreviewMode;
break;
}
} else if (e.Modifiers.Equals(Keys.Control)) {
switch (e.KeyCode) {
case Keys.Z:
surface.Undo();
updateUndoRedoSurfaceDependencies();
break;
case Keys.Y:
surface.Redo();
updateUndoRedoSurfaceDependencies();
break;
}
}
}
@ -676,7 +791,15 @@ namespace Greenshot {
}
#endregion
#region cursor key strokes
#region key handling
protected override bool ProcessKeyPreview(ref Message msg) {
// disable default key handling if surface has requested a lock
if (!surface.KeysLocked) {
return base.ProcessKeyPreview(ref msg);
}
return false;
}
protected override bool ProcessCmdKey(ref Message msg, Keys k) {
// disable default key handling if surface has requested a lock
if (!surface.KeysLocked) {
@ -688,16 +811,46 @@ namespace Greenshot {
#endregion
#region helpers
private void updateUndoRedoSurfaceDependencies() {
bool canUndo = surface.CanUndo;
this.btnUndo.Enabled = canUndo;
this.undoToolStripMenuItem.Enabled = canUndo;
string undoAction = "";
if (canUndo) {
undoAction = lang.GetString(surface.UndoActionKey);
}
string undoText = lang.GetFormattedString(LangKey.editor_undo, undoAction);
this.btnUndo.Text = undoText;
this.undoToolStripMenuItem.Text = undoText;
bool canRedo = surface.CanRedo;
this.btnRedo.Enabled = canRedo;
this.redoToolStripMenuItem.Enabled = canRedo;
string redoAction = "";
if (canRedo) {
redoAction = lang.GetString(surface.RedoActionKey);
}
string redoText = lang.GetFormattedString(LangKey.editor_redo, redoAction);
this.btnRedo.Text = redoText;
this.redoToolStripMenuItem.Text = redoText;
}
private void updateClipboardSurfaceDependencies() {
// check dependencies for the Surface
bool hasItems = surface.HasSelectedElements();
bool actionAllowedForSelection = hasItems && !controlsDisabledDueToConfirmable;
this.cutToolStripMenuItem.Enabled = actionAllowedForSelection;
// buttons
this.btnCut.Enabled = actionAllowedForSelection;
this.btnCopy.Enabled = actionAllowedForSelection;
this.copyToolStripMenuItem.Enabled = actionAllowedForSelection;
this.btnDelete.Enabled = actionAllowedForSelection;
// menus
this.removeObjectToolStripMenuItem.Enabled = actionAllowedForSelection;
this.copyToolStripMenuItem.Enabled = actionAllowedForSelection;
this.cutToolStripMenuItem.Enabled = actionAllowedForSelection;
this.duplicateToolStripMenuItem.Enabled = actionAllowedForSelection;
// check dependencies for the Clipboard
@ -729,12 +882,12 @@ namespace Greenshot {
}
void CopyPathMenuItemClick(object sender, EventArgs e) {
Clipboard.SetText(lastSaveFullPath);
ClipboardHelper.SetClipboardData(surface.LastSaveFullPath);
}
void OpenDirectoryMenuItemClick(object sender, EventArgs e) {
ProcessStartInfo psi = new ProcessStartInfo("explorer");
psi.Arguments = Path.GetDirectoryName(lastSaveFullPath);
psi.Arguments = Path.GetDirectoryName(surface.LastSaveFullPath);
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
@ -787,13 +940,17 @@ namespace Greenshot {
obfuscateModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE);
highlightModeButton.Visible = props.HasFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT);
} else {
foreach(ToolStripItem c in propertiesToolStrip.Items) {
c.Visible = false;
}
hideToolstripItems();
}
propertiesToolStrip.ResumeLayout();
}
private void hideToolstripItems() {
foreach(ToolStripItem toolStripItem in propertiesToolStrip.Items) {
toolStripItem.Visible = false;
}
}
/// <summary>
/// refreshes all editor controls depending on selected elements and their fields
/// </summary>
@ -822,16 +979,11 @@ namespace Greenshot {
}
// en/disable controls depending on whether an element is selected at all
bool actionAllowedForSelection = surface.HasSelectedElements() && !controlsDisabledDueToConfirmable;
this.btnCopy.Enabled = actionAllowedForSelection;
this.btnCut.Enabled = actionAllowedForSelection;
this.btnDelete.Enabled = actionAllowedForSelection;
this.copyToolStripMenuItem.Enabled = actionAllowedForSelection;
this.cutToolStripMenuItem.Enabled = actionAllowedForSelection;
this.duplicateToolStripMenuItem.Enabled = actionAllowedForSelection;
this.removeObjectToolStripMenuItem.Enabled = actionAllowedForSelection;
updateClipboardSurfaceDependencies();
updateUndoRedoSurfaceDependencies();
// en/disablearrage controls depending on hierarchy of selected elements
bool actionAllowedForSelection = surface.HasSelectedElements() && !controlsDisabledDueToConfirmable;
bool push = actionAllowedForSelection && surface.CanPushSelectionDown();
bool pull = actionAllowedForSelection && surface.CanPullSelectionUp();
this.arrangeToolStripMenuItem.Enabled = (push || pull);
@ -853,6 +1005,7 @@ namespace Greenshot {
void EditToolStripMenuItemClick(object sender, EventArgs e) {
updateClipboardSurfaceDependencies();
updateUndoRedoSurfaceDependencies();
}
void FontPropertyChanged(object sender, EventArgs e) {
@ -929,20 +1082,29 @@ namespace Greenshot {
}
}
void EmailToolStripMenuItemClick(object sender, EventArgs e) {
using (Image img = surface.GetImageForExport()) {
MapiMailMessage.SendImage(img, surface.CaptureDetails);
void DestinationToolStripMenuItemClick(object sender, EventArgs e) {
IDestination clickedDestination = null;
if (sender is Control) {
Control clickedControl = sender as Control;
if (clickedControl.ContextMenuStrip != null) {
clickedControl.ContextMenuStrip.Show(Cursor.Position);
return;
}
clickedDestination = (IDestination)clickedControl.Tag;
} else if (sender is ToolStripMenuItem) {
ToolStripMenuItem clickedMenuItem = sender as ToolStripMenuItem;
clickedDestination = (IDestination)clickedMenuItem.Tag;
}
if (clickedDestination != null) {
if (clickedDestination.ExportCapture(surface, surface.CaptureDetails)) {
surface.Modified = false;
}
}
void BtnEmailClick(object sender, EventArgs e) {
EmailToolStripMenuItemClick(sender, e);
}
protected void FilterPresetDropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) {
refreshFieldControls();
this.Invalidate(true);
}
void SelectAllToolStripMenuItemClick(object sender, EventArgs e) {
@ -962,7 +1124,7 @@ namespace Greenshot {
void Insert_window_toolstripmenuitemMouseEnter(object sender, EventArgs e) {
ToolStripMenuItem captureWindowMenuItem = (ToolStripMenuItem)sender;
MainForm.AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click);
MainForm.instance.AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click);
}
void Contextmenu_window_Click(object sender, EventArgs e) {
@ -975,9 +1137,9 @@ namespace Greenshot {
capture.CaptureDetails.DpiY = graphics.DpiY;
}
windowToCapture.Restore();
windowToCapture = CaptureForm.SelectCaptureWindow(windowToCapture);
windowToCapture = CaptureHelper.SelectCaptureWindow(windowToCapture);
if (windowToCapture != null) {
capture = CaptureForm.CaptureWindow(windowToCapture, capture, coreConf.WindowCaptureMode);
capture = CaptureHelper.CaptureWindow(windowToCapture, capture, coreConf.WindowCaptureMode);
this.Activate();
WindowDetails.ToForeground(this.Handle);
if (capture!= null && capture.Image != null) {
@ -992,5 +1154,11 @@ namespace Greenshot {
LOG.Error(exception);
}
}
void AutoCropToolStripMenuItemClick(object sender, EventArgs e) {
if (surface.AutoCrop()) {
refreshFieldControls();
}
}
}
}

View file

@ -834,9 +834,118 @@
</data>
<data name="checkerboard.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAIAAAACUFjqAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAgY0hSTQAAeiYAAICEAAD6AAAAgOgAAHUwAADqYAAAOpgAABdwnLpRPAAAACJJREFUKFNjZEAF
////RxNB4QKlkQG6UupKU9c0TI+S7xMAKX+JeHFERhgAAAAASUVORK5CYII=
iVBORw0KGgoAAAANSUhEUgAAAAoAAAAKCAMAAAC67D+PAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6
JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAADAFBMVEWAgID///8AAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA4OAdWAAAACXBIWXMAAA7CAAAOwgEVKEqAAAAAGXRF
WHRTb2Z0d2FyZQBQYWludC5ORVQgdjMuNS44NzuAXQAAABZJREFUGFdjYAABRhAAs4hlkq4DZDgACywA
M12jTsYAAAAASUVORK5CYII=
</value>
</data>
<data name="freehand.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABGdBTUEAALGOfPtRkwAAACBjSFJNAACH
DwAAjA8AAP1SAACBQAAAfXkAAOmLAAA85QAAGcxzPIV3AAAKOWlDQ1BQaG90b3Nob3AgSUNDIHByb2Zp
bGUAAEjHnZZ3VFTXFofPvXd6oc0wAlKG3rvAANJ7k15FYZgZYCgDDjM0sSGiAhFFRJoiSFDEgNFQJFZE
sRAUVLAHJAgoMRhFVCxvRtaLrqy89/Ly++Osb+2z97n77L3PWhcAkqcvl5cGSwGQyhPwgzyc6RGRUXTs
AIABHmCAKQBMVka6X7B7CBDJy82FniFyAl8EAfB6WLwCcNPQM4BOB/+fpFnpfIHomAARm7M5GSwRF4g4
JUuQLrbPipgalyxmGCVmvihBEcuJOWGRDT77LLKjmNmpPLaIxTmns1PZYu4V8bZMIUfEiK+ICzO5nCwR
3xKxRoowlSviN+LYVA4zAwAUSWwXcFiJIjYRMYkfEuQi4uUA4EgJX3HcVyzgZAvEl3JJS8/hcxMSBXQd
li7d1NqaQffkZKVwBALDACYrmcln013SUtOZvBwAFu/8WTLi2tJFRbY0tba0NDQzMv2qUP91829K3NtF
ehn4uWcQrf+L7a/80hoAYMyJarPziy2uCoDOLQDI3fti0zgAgKSobx3Xv7oPTTwviQJBuo2xcVZWlhGX
wzISF/QP/U+Hv6GvvmckPu6P8tBdOfFMYYqALq4bKy0lTcinZ6QzWRy64Z+H+B8H/nUeBkGceA6fwxNF
hImmjMtLELWbx+YKuGk8Opf3n5r4D8P+pMW5FonS+BFQY4yA1HUqQH7tBygKESDR+8Vd/6NvvvgwIH55
4SqTi3P/7zf9Z8Gl4iWDm/A5ziUohM4S8jMX98TPEqABAUgCKpAHykAd6ABDYAasgC1wBG7AG/iDEBAJ
VgMWSASpgA+yQB7YBApBMdgJ9oBqUAcaQTNoBcdBJzgFzoNL4Bq4AW6D+2AUTIBnYBa8BgsQBGEhMkSB
5CEVSBPSh8wgBmQPuUG+UBAUCcVCCRAPEkJ50GaoGCqDqqF6qBn6HjoJnYeuQIPQXWgMmoZ+h97BCEyC
qbASrAUbwwzYCfaBQ+BVcAK8Bs6FC+AdcCXcAB+FO+Dz8DX4NjwKP4PnEIAQERqiihgiDMQF8UeikHiE
j6xHipAKpAFpRbqRPuQmMorMIG9RGBQFRUcZomxRnqhQFAu1BrUeVYKqRh1GdaB6UTdRY6hZ1Ec0Ga2I
1kfboL3QEegEdBa6EF2BbkK3oy+ib6Mn0K8xGAwNo42xwnhiIjFJmLWYEsw+TBvmHGYQM46Zw2Kx8lh9
rB3WH8vECrCF2CrsUexZ7BB2AvsGR8Sp4Mxw7rgoHA+Xj6vAHcGdwQ3hJnELeCm8Jt4G749n43PwpfhG
fDf+On4Cv0CQJmgT7AghhCTCJkIloZVwkfCA8JJIJKoRrYmBRC5xI7GSeIx4mThGfEuSIemRXEjRJCFp
B+kQ6RzpLuklmUzWIjuSo8gC8g5yM/kC+RH5jQRFwkjCS4ItsUGiRqJDYkjiuSReUlPSSXK1ZK5kheQJ
yeuSM1J4KS0pFymm1HqpGqmTUiNSc9IUaVNpf+lU6RLpI9JXpKdksDJaMm4ybJkCmYMyF2TGKQhFneJC
YVE2UxopFykTVAxVm+pFTaIWU7+jDlBnZWVkl8mGyWbL1sielh2lITQtmhcthVZKO04bpr1borTEaQln
yfYlrUuGlszLLZVzlOPIFcm1yd2WeydPl3eTT5bfJd8p/1ABpaCnEKiQpbBf4aLCzFLqUtulrKVFS48v
vacIK+opBimuVTyo2K84p6Ss5KGUrlSldEFpRpmm7KicpFyufEZ5WoWiYq/CVSlXOavylC5Ld6Kn0Cvp
vfRZVUVVT1Whar3qgOqCmrZaqFq+WpvaQ3WCOkM9Xr1cvUd9VkNFw08jT6NF454mXpOhmai5V7NPc15L
Wytca6tWp9aUtpy2l3audov2Ax2yjoPOGp0GnVu6GF2GbrLuPt0berCehV6iXo3edX1Y31Kfq79Pf9AA
bWBtwDNoMBgxJBk6GWYathiOGdGMfI3yjTqNnhtrGEcZ7zLuM/5oYmGSYtJoct9UxtTbNN+02/R3Mz0z
llmN2S1zsrm7+QbzLvMXy/SXcZbtX3bHgmLhZ7HVosfig6WVJd+y1XLaSsMq1qrWaoRBZQQwShiXrdHW
ztYbrE9Zv7WxtBHYHLf5zdbQNtn2iO3Ucu3lnOWNy8ft1OyYdvV2o/Z0+1j7A/ajDqoOTIcGh8eO6o5s
xybHSSddpySno07PnU2c+c7tzvMuNi7rXM65Iq4erkWuA24ybqFu1W6P3NXcE9xb3Gc9LDzWepzzRHv6
eO7yHPFS8mJ5NXvNelt5r/Pu9SH5BPtU+zz21fPl+3b7wX7efrv9HqzQXMFb0ekP/L38d/s/DNAOWBPw
YyAmMCCwJvBJkGlQXlBfMCU4JvhI8OsQ55DSkPuhOqHC0J4wybDosOaw+XDX8LLw0QjjiHUR1yIVIrmR
XVHYqLCopqi5lW4r96yciLaILoweXqW9KnvVldUKq1NWn46RjGHGnIhFx4bHHol9z/RnNjDn4rziauNm
WS6svaxnbEd2OXuaY8cp40zG28WXxU8l2CXsTphOdEisSJzhunCruS+SPJPqkuaT/ZMPJX9KCU9pS8Wl
xqae5Mnwknm9acpp2WmD6frphemja2zW7Fkzy/fhN2VAGasyugRU0c9Uv1BHuEU4lmmfWZP5Jiss60S2
dDYvuz9HL2d7zmSue+63a1FrWWt78lTzNuWNrXNaV78eWh+3vmeD+oaCDRMbPTYe3kTYlLzpp3yT/LL8
V5vDN3cXKBVsLBjf4rGlpVCikF84stV2a9021DbutoHt5turtn8sYhddLTYprih+X8IqufqN6TeV33za
Eb9joNSydP9OzE7ezuFdDrsOl0mX5ZaN7/bb3VFOLy8qf7UnZs+VimUVdXsJe4V7Ryt9K7uqNKp2Vr2v
Tqy+XeNc01arWLu9dn4fe9/Qfsf9rXVKdcV17w5wD9yp96jvaNBqqDiIOZh58EljWGPft4xvm5sUmoqb
PhziHRo9HHS4t9mqufmI4pHSFrhF2DJ9NProje9cv+tqNWytb6O1FR8Dx4THnn4f+/3wcZ/jPScYJ1p/
0Pyhtp3SXtQBdeR0zHYmdo52RXYNnvQ+2dNt293+o9GPh06pnqo5LXu69AzhTMGZT2dzz86dSz83cz7h
/HhPTM/9CxEXbvUG9g5c9Ll4+ZL7pQt9Tn1nL9tdPnXF5srJq4yrndcsr3X0W/S3/2TxU/uA5UDHdavr
XTesb3QPLh88M+QwdP6m681Lt7xuXbu94vbgcOjwnZHokdE77DtTd1PuvriXeW/h/sYH6AdFD6UeVjxS
fNTws+7PbaOWo6fHXMf6Hwc/vj/OGn/2S8Yv7ycKnpCfVEyqTDZPmU2dmnafvvF05dOJZ+nPFmYKf5X+
tfa5zvMffnP8rX82YnbiBf/Fp99LXsq/PPRq2aueuYC5R69TXy/MF72Rf3P4LeNt37vwd5MLWe+x7ys/
6H7o/ujz8cGn1E+f/gUDmPP8usTo0wAAAAlwSFlzAAALEgAACxIB0t1+/AAAAhFJREFUOE+V009Ik2Ec
B/Dfb0owoUMRkiSeyovUxYoOgQwHIwP37k1XEGiHNAPXi8pqzhU157RYDOqgRtFr5oo1jHTWxZIoOoQo
/qNTkIJpUdaxDuvp+4xe2eu2Q4cPz3hevt/nz/uOhBAkVZ0KbXJqMXJffEqvYkwulyttlVkqnsM4TpTO
SJs/ZEFT9/P94JThHAVHl5lHZ5l7ZYHH4zEXVDdEZEES3FsLFEUpt9ls2h+vV6w4HF9GiexZBQg2wyAU
ZBYY4VQqJRKJxFKc6O1Irh0g+B4q5bkNL0e4auwOJz+8U8VkvPKn1WrtC+AO9DwFn1Cwc2v493qXWHyt
fA1r9GZvWSGpFkvegn4UDOBsO4yVjXCPtm0W8yegBopy7qDWMywv8VowoHwbiu75LsMzk+qvq1pJ6t/x
4hgnYA3qwPwW7nqJdB+V3fNvv7zxsVkkhw7/CGnWRaxYaG+MknSoRpOLlMMT2GX6Dm5dII62clBsTIt2
N+vnFfZ3nWW60oJ3hnDn7Sl6kFwgfWxeljyGClNBuIkjn5diolXlRy1OPnaulqnjNNNUo52GJxbS4YyC
hyg4YCqQXyeCcQQrbqr7aLzOQeLkDRL1faYCBEvgWdYRMLEOYTgoLyiPIsz3QDDrEjFRCpfgBcyBDj44
Aw3QDgm4D7tzFRirWvCwGI5DG/TCdQjAkcydme7A+Hv+7/gXya8DPW6boNQAAAAASUVORK5CYII=
</value>
</data>
<data name="btnRedo.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAACp0lEQVQ4T6WTa0iTcRTG/xTt
g5aG+aENuphoXog0DSoSR5JEMOliJMuUUIp0g9CKYWmpaWuYbVTSKsW8zFsz1EosvKWl2atvTO3mqyVr
zkWFSmvsUqfzH/GC1jc//NhznvOc5/1/GQEAshjcx1s1HNleMkmibptIdOm0SFxmkSE6hPkL1TK6i7oz
RVAnIlp6u7BAElNuZk+0zxnzDQ6rhvsNFKqpt6vM3IkfKUAYyvyCm58ksfdMhusTv6CAdcClIQcoh52g
GnXBZYMTCl874OpbJ+BLGa0J3L98QeS1D6KdJROsZswF2b0/4HTHjG1ftYmLVI8xlEMNU5xqxA5Zz+bw
RS6gmvp8QdiVEVlyk9mo6PgOaS3TNpyZcNWoNKL4PdmsHCY436CeeswJGa1foJC1Ap35gpC8wZrMzq/W
k/rPINaMcqH5Q1IMkKCLr0hwLpOIe/ez8wbm3BS/swP1+IKArOfM2a5vkFT9EajemN1PgnJeksDzfSTw
3Ast9RZCfb5gXWYHk95mgYMV40D1mlNPiUjeSvzOdBE8JP6KHrI2o53gLgIzYsxG47yeLxCmP66Jr5u0
7qmahE15fZww7ZHUN/UB8U6uJ77HmwjV6G0JvdCrwIwsrmo8Hm8C+AIMyCKKBo07aqchts5kw5lZldIo
pQUU1HvRU+6uMWowIw9TDsThLOQLvJPqRD6penZbyyyE3J8BcaPFFpzbw3kdrWWQbtRPxHpLM+7UmJH7
pOhj8EbAF6w4oiOeCZUSrxS9wa/ZBqsbf4J/iw3C2+yUWdRv0HuIO7XXsYZkzArpzbwCj8MVRHCgVCJI
qGQ9c/qNy8stVo9mFyCzqFnP7D6dIKFCgZkNNPvfgmX775KlcVrREsktGaJDGKQbKUIkuFtJM/8ULObv
/AfX+Vsh8ZRqjgAAAABJRU5ErkJggg==
</value>
</data>
<data name="btnUndo.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8
YQUAAAAZdEVYdFNvZnR3YXJlAEFkb2JlIEltYWdlUmVhZHlxyWU8AAACrUlEQVQ4T6WTa0iTYRTHH4r2
QWuG+aENuphoXoi0GWQkjiSJYNLFSJYpoRTphNCKYWmpaUvMNipplWJepmYznJVYeEtLs1ffmK7bXi1Z
UxcVKq3htjqdZ8ik7Jsffu/+53/+5+x9njECAGQxuIbF5RY1khB5e5xElU0KUcsQDcLMQbWM9iJvmUlE
6RjZquJcs64HmswcBTvLJzqOt82Y8vV2q4r7DRSqqRddMcFiTrJgARqM2gxAP6+8dUDhaztc0jugyOAE
xZADLg7aoYC1w7XRXxBz16yPuPFJ8tcbhCuNTNHwLH6bE7KezQDVBxvGOepT9taYuVPtU7bsnh+gMjph
R+koG371g9B9hNDLw0wha4WMli+gNDqA1sj1zYohIip5T8KKDFLqpTZP2uTt3yGpacKEtcy9IDhvgCl5
Nwt5/TMu6HGoF5TLJAReeEUwTELyB6VilYE7of0MmR1frdivdS8IOPtC7Z/1nPkX6gec6yWBOS/Jxuw+
QvuJNR/hTOc3oNq9YG1G2/q0VkvUgcoR8brMdhHWxE/eTQeI7+lOIkxvIWtOPiXYYzADmAWq3QsEaY/9
Y6tH4nZXj8lCzvfIBamPtvikPCA+x5qIV9I9QjV60k15vRxmIK5+zIoz80fAgCBU0R+7vW4yfVetSYW1
YlVy4x46TEEtRY+JqTfbMAOi4gET1vOX6JVYz/NO1kZva55OD74/pRRrLbqg3O4n/CN1XQheZjcnbrTY
sAeYAe8ULYsz8z/jisMa4hlfJeAfbUjy1dmUqxt/PvRrtr0Ja52dRgA1oAfYA36yVo9ZCZ1x3wEtPA5V
Et7+sg28+Eq5Z3avZnmFhfXQOacRQG31zOkz8eKrWMxIaPa/C5btu0OWxqpXLpHclCDFSBfCIBpEhj0h
zSxYsJi/8x/XGVshytjcjQAAAABJRU5ErkJggg==
</value>
</data>
<metadata name="statusStrip1.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">

View file

@ -19,11 +19,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot {
/// <summary>

View file

@ -58,7 +58,7 @@ namespace Greenshot.Forms {
this.comboBoxLanguage.FormattingEnabled = true;
this.comboBoxLanguage.Location = new System.Drawing.Point(13, 15);
this.comboBoxLanguage.Name = "comboBoxLanguage";
this.comboBoxLanguage.Size = new System.Drawing.Size(299, 21);
this.comboBoxLanguage.Size = new System.Drawing.Size(360, 21);
this.comboBoxLanguage.TabIndex = 3;
//
// btnOK
@ -76,17 +76,19 @@ namespace Greenshot.Forms {
this.AcceptButton = this.btnOK;
this.AutoScaleDimensions = new System.Drawing.SizeF(96F, 96F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(327, 77);
this.ControlBox = false;
this.ClientSize = new System.Drawing.Size(390, 77);
this.ControlBox = true;
this.Controls.Add(this.btnOK);
this.Controls.Add(this.comboBoxLanguage);
this.Controls.Add(this.lblSelectLanguage);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon();
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "LanguageDialog";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "Choose language / Sprache wählen / Taal kiezen";
this.Text = "Greenshot: Choose language / Sprache wählen / Taal kiezen";
this.TopMost = true;
this.ResumeLayout(false);
}
private System.Windows.Forms.Label lblSelectLanguage;

View file

@ -19,9 +19,6 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.Threading;
using System.Windows.Forms;
@ -35,14 +32,24 @@ namespace Greenshot.Forms {
public partial class LanguageDialog : Form {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(LanguageDialog));
private static LanguageDialog uniqueInstance;
private ILanguage language = Language.GetInstance();
private ILanguage language = Language.GetInstance(false);
private bool properOkPressed = false;
private LanguageDialog() {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
this.Load += FormLoad;
this.FormClosing += PreventFormClose;
}
private void PreventFormClose(object sender, FormClosingEventArgs e) {
if(!properOkPressed) {
e.Cancel = true;
} else {
language.FreeResources();
}
}
public string SelectedLanguage {
@ -61,10 +68,15 @@ namespace Greenshot.Forms {
if (language.CurrentLanguage != null) {
LOG.DebugFormat("Selecting {0}", language.CurrentLanguage);
this.comboBoxLanguage.SelectedValue = language.CurrentLanguage;
} else {
this.comboBoxLanguage.SelectedValue = Thread.CurrentThread.CurrentUICulture.Name;
}
}
void BtnOKClick(object sender, EventArgs e) {
properOkPressed = true;
// Fix for Bug #3431100
language.SetLanguage(SelectedLanguage);
this.Close();
}

View file

@ -123,7 +123,8 @@ namespace Greenshot {
this.contextmenu_capturewindow.ShortcutKeyDisplayString = "Alt + Print";
this.contextmenu_capturewindow.Size = new System.Drawing.Size(242, 22);
this.contextmenu_capturewindow.Text = "Capture window";
this.contextmenu_capturewindow.MouseEnter += new System.EventHandler(EnterCaptureWindowMenuItem);
this.contextmenu_capturewindow.DropDownOpening += new System.EventHandler(CaptureWindowMenuDropDownOpening);
this.contextmenu_capturewindow.DropDownClosed += new System.EventHandler(CaptureWindowMenuDropDownClosed);
//
// contextmenu_capturefullscreen
//
@ -226,7 +227,7 @@ namespace Greenshot {
this.contextmenu_captureie.Size = new System.Drawing.Size(231, 22);
this.contextmenu_captureie.Text = "Capture IE Tab";
this.contextmenu_captureie.ShortcutKeyDisplayString = "Ctrl + Shift + Print";
this.contextmenu_captureie.MouseEnter += new System.EventHandler(EnterCaptureIEMenuItem);
this.contextmenu_captureie.DropDownOpening += new System.EventHandler(CaptureIEMenuDropDownOpening);
//
// backgroundWorkerTimer
//
@ -277,7 +278,7 @@ namespace Greenshot {
private System.Windows.Forms.ToolStripMenuItem contextmenu_capturefullscreen;
private System.Windows.Forms.ToolStripMenuItem contextmenu_capturelastregion;
private System.Windows.Forms.ToolStripMenuItem contextmenu_capturearea;
private System.Windows.Forms.NotifyIcon notifyIcon;
public System.Windows.Forms.NotifyIcon notifyIcon;
private System.Windows.Forms.ToolStripSeparator toolStripSeparator1;
private System.Windows.Forms.ToolStripMenuItem contextmenu_exit;
private System.Windows.Forms.ContextMenuStrip contextMenu;

View file

@ -19,12 +19,9 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Drawing.Printing;
using System.IO;
using System.Reflection;
using System.Security.AccessControl;
@ -34,41 +31,27 @@ using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing;
using Greenshot.Experimental;
using Greenshot.Forms;
using Greenshot.Help;
using Greenshot.Helpers;
using Greenshot.Plugin;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot {
/// <summary>
/// Description of MainForm.
/// </summary>
public partial class MainForm : Form {
private const string LOG4NET_FILE = "log4net.xml";
private static log4net.ILog LOG = null;
private static Mutex applicationMutex = null;
private static CoreConfiguration conf;
public static string LogFileLocation = null;
private static void InitializeLog4NET() {
// Setup log4j, currently the file is called log4net.xml
string log4netFilename = Path.Combine(Application.StartupPath, LOG4NET_FILE);
if (File.Exists(log4netFilename)) {
log4net.Config.XmlConfigurator.Configure(new FileInfo(log4netFilename));
} else {
MessageBox.Show("Can't find file " + LOG4NET_FILE);
}
// Setup the LOG
LOG = log4net.LogManager.GetLogger(typeof(MainForm));
}
[STAThread]
public static void Main(string[] args) {
public static void Start(string[] args) {
bool isAlreadyRunning = false;
List<string> filesToOpen = new List<string>();
@ -76,7 +59,9 @@ namespace Greenshot {
Thread.CurrentThread.Name = Application.ProductName;
// Init Log4NET
InitializeLog4NET();
LogFileLocation = LogHelper.InitializeLog4NET();
// Get logger
LOG = log4net.LogManager.GetLogger(typeof(MainForm));
Application.ThreadException += new System.Threading.ThreadExceptionEventHandler(Application_ThreadException);
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
@ -84,6 +69,7 @@ namespace Greenshot {
// Log the startup
LOG.Info("Starting: " + EnvironmentInfo.EnvironmentToString(false));
IniConfig.Init();
AppConfig.UpgradeToIni();
// Read configuration
conf = IniConfig.GetIniSection<CoreConfiguration>();
@ -223,8 +209,9 @@ namespace Greenshot {
}
}
ILanguage lang = Language.GetInstance();
if (isAlreadyRunning) {
// We didn't initialize the language yet, do it here just for the message box
ILanguage lang = Language.GetInstance();
if (filesToOpen.Count > 0) {
SendData(transport);
} else {
@ -240,10 +227,10 @@ namespace Greenshot {
Application.SetCompatibleTextRenderingDefault(false);
// if language is not set, show language dialog
if(conf.Language == null || conf.Language.Trim().Length == 0) {
LanguageDialog ld = LanguageDialog.GetInstance();
ld.ShowDialog();
conf.Language = ld.SelectedLanguage;
if(string.IsNullOrEmpty(conf.Language)) {
LanguageDialog languageDialog = LanguageDialog.GetInstance();
languageDialog.ShowDialog();
conf.Language = languageDialog.SelectedLanguage;
IniConfig.Save();
}
@ -253,8 +240,9 @@ namespace Greenshot {
IniConfig.Save();
transport.AddCommand(CommandEnum.FirstLaunch);
}
MainForm mainForm = new MainForm(transport);
Application.Run(mainForm);
Application.Run();
} catch(Exception ex) {
LOG.Error("Exception in startup.", ex);
Application_ThreadException(MainForm.ActiveForm, new ThreadExceptionEventArgs(ex));
@ -288,11 +276,24 @@ namespace Greenshot {
private ILanguage lang;
private ToolTip tooltip;
private CaptureForm captureForm = null;
private CopyData copyData = null;
// Thumbnail preview
private FormWithoutActivation thumbnailForm = null;
private IntPtr thumbnailHandle = IntPtr.Zero;
private Rectangle parentMenuBounds = Rectangle.Empty;
// Make sure we have only one settings form
private SettingsForm settingsForm = null;
// Make sure we have only one about form
private AboutForm aboutForm = null;
// Make sure we have only one help browser
private HelpBrowserForm helpBrowserForm = null;
public MainForm(CopyDataTransport dataTransport) {
instance = this;
// Make sure we never capture the mainform
WindowDetails.RegisterIgnoreHandle(this.Handle);
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
@ -307,14 +308,35 @@ namespace Greenshot {
tooltip = new ToolTip();
UpdateUI();
InitializeQuickSettingsMenu();
captureForm = new CaptureForm();
// Do loading on a different Thread to shorten the startup
Thread pluginInitThread = new Thread (delegate() {
// Load all the plugins
PluginHelper.instance.LoadPlugins(this, captureForm);
PluginHelper.instance.LoadPlugins(this);
// Check destinations, remove all that don't exist
foreach(string destination in conf.OutputDestinations.ToArray()) {
if (DestinationHelper.GetDestination(destination) == null) {
conf.OutputDestinations.Remove(destination);
}
}
// we should have at least one!
if (conf.OutputDestinations.Count == 0) {
conf.OutputDestinations.Add(Destinations.EditorDestination.DESIGNATION);
}
BeginInvoke((MethodInvoker)delegate {
// Do after all plugins & finding the destination, otherwise they are missing!
InitializeQuickSettingsMenu();
});
});
pluginInitThread.Name = "Initialize plug-ins";
pluginInitThread.IsBackground = true;
pluginInitThread.Start();
SoundHelper.Initialize();
// Enable the Greenshot icon to be visible, this prevents Problems with the context menu
notifyIcon.Visible = true;
@ -331,7 +353,6 @@ namespace Greenshot {
if (dataTransport != null) {
HandleDataTransport(dataTransport);
}
ClipboardHelper.RegisterClipboardViewer(this.Handle);
}
/// <summary>
@ -350,19 +371,41 @@ namespace Greenshot {
LOG.Debug("Data received, Command = " + command.Key + ", Data: " + command.Value);
switch(command.Key) {
case CommandEnum.Exit:
exit();
Exit();
break;
case CommandEnum.FirstLaunch:
LOG.Info("FirstLaunch: Created new configuration.");
LOG.Info("FirstLaunch: Created new configuration, showing balloon.");
try {
EventHandler balloonTipClickedHandler = null;
EventHandler balloonTipClosedHandler = null;
balloonTipClosedHandler = delegate(object sender, EventArgs e) {
notifyIcon.BalloonTipClicked -= balloonTipClickedHandler;
notifyIcon.BalloonTipClosed -= balloonTipClosedHandler;
};
balloonTipClickedHandler = delegate(object sender, EventArgs e) {
ShowSetting();
notifyIcon.BalloonTipClicked -= balloonTipClickedHandler;
notifyIcon.BalloonTipClosed -= balloonTipClosedHandler;
};
notifyIcon.BalloonTipClicked += balloonTipClickedHandler;
notifyIcon.BalloonTipClosed += balloonTipClosedHandler;
notifyIcon.ShowBalloonTip(2000, "Greenshot", lang.GetFormattedString(LangKey.tooltip_firststart, HotkeyControl.GetLocalizedHotkeyStringFromString(conf.RegionHotkey)), ToolTipIcon.Info);
} catch {}
break;
case CommandEnum.ReloadConfig:
try {
IniConfig.Reload();
ReloadConfiguration(null, null);
} catch {}
break;
case CommandEnum.OpenFile:
string filename = command.Value;
if (File.Exists(filename)) {
captureForm.MakeCapture(filename);
BeginInvoke((MethodInvoker)delegate {
CaptureHelper.CaptureFile(filename);
});
} else {
LOG.Warn("No such file: " + filename);
}
@ -374,8 +417,15 @@ namespace Greenshot {
}
}
/// <summary>
/// This is called when the ini-file changes
/// </summary>
/// <param name="source"></param>
/// <param name="e"></param>
private void ReloadConfiguration(object source, FileSystemEventArgs e) {
lang.Load();
lang.SetLanguage(conf.Language);
lang.FreeResources();
this.Invoke((MethodInvoker) delegate {
// Even update language when needed
UpdateUI();
@ -392,9 +442,6 @@ namespace Greenshot {
#region hotkeys
protected override void WndProc(ref Message m) {
if (ClipboardHelper.HandleClipboardMessages(ref m)) {
return;
}
if (HotkeyControl.HandleMessages(ref m)) {
return;
}
@ -503,8 +550,9 @@ namespace Greenshot {
#region mainform events
void MainFormFormClosing(object sender, FormClosingEventArgs e) {
LOG.DebugFormat("Mainform closing, reason: {0}", e.CloseReason);
instance = null;
exit();
Exit();
}
void MainFormActivated(object sender, EventArgs e) {
@ -515,66 +563,68 @@ namespace Greenshot {
#region key handlers
void CaptureRegion() {
captureForm.MakeCapture(CaptureMode.Region, true);
CaptureHelper.CaptureRegion(true);
}
void CaptureClipboard() {
captureForm.MakeCapture(CaptureMode.Clipboard, false);
CaptureHelper.CaptureClipboard();
}
void CaptureFile() {
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Image files (*.png, *.jpg, *.gif, *.bmp, *.ico)|*.png; *.jpg; *.jpeg; *.gif; *.bmp; *.ico";
openFileDialog.Filter = "Image files (*.png, *.jpg, *.gif, *.bmp, *.ico, *.tiff, *.wmf)|*.png; *.jpg; *.jpeg; *.gif; *.bmp; *.ico; *.tiff; *.tif; *.wmf";
if (openFileDialog.ShowDialog() == DialogResult.OK) {
if (File.Exists(openFileDialog.FileName)) {
captureForm.MakeCapture(openFileDialog.FileName);
CaptureHelper.CaptureFile(openFileDialog.FileName);
}
}
}
void CaptureFullScreen() {
captureForm.MakeCapture(CaptureMode.FullScreen, true);
CaptureHelper.CaptureFullscreen(true);
}
void CaptureLastRegion() {
captureForm.MakeCapture(CaptureMode.LastRegion, true);
CaptureHelper.CaptureLastRegion(true);
}
void CaptureIE() {
captureForm.MakeCapture(CaptureMode.IE, true);
CaptureHelper.CaptureIE(true);
}
void CaptureWindow() {
CaptureMode captureMode = CaptureMode.None;
if (conf.CaptureWindowsInteractive) {
captureMode = CaptureMode.Window;
CaptureHelper.CaptureWindowInteractive(true);
} else {
captureMode = CaptureMode.ActiveWindow;
CaptureHelper.CaptureWindow(true);
}
captureForm.MakeCapture(captureMode, true);
}
#endregion
#region contextmenu
void ContextMenuOpening(object sender, System.ComponentModel.CancelEventArgs e) {
if (Clipboard.ContainsImage()) {
contextmenu_captureclipboard.Enabled = true;
} else {
contextmenu_captureclipboard.Enabled = false;
}
contextmenu_captureclipboard.Enabled = ClipboardHelper.ContainsImage();
contextmenu_capturelastregion.Enabled = RuntimeConfig.LastCapturedRegion != Rectangle.Empty;
// IE context menu code
try {
if (conf.IECapture && IECaptureHelper.IsIERunning()) {
this.contextmenu_captureie.Enabled = true;
} else {
this.contextmenu_captureie.Enabled = false;
}
} catch (Exception ex) {
LOG.WarnFormat("Problem accessing IE information: {0}", ex.Message);
}
}
void ContextMenuClosing(object sender, EventArgs e) {
this.contextmenu_captureie.DropDownItems.Clear();
this.contextmenu_capturewindow.DropDownItems.Clear();
cleanupThumbnail();
}
/// <summary>
/// Build a selectable list of IE tabs when we enter the menu item
/// </summary>
void EnterCaptureIEMenuItem(object sender, EventArgs e) {
void CaptureIEMenuDropDownOpening(object sender, EventArgs e) {
try {
List<KeyValuePair<WindowDetails, string>> tabs = IECaptureHelper.GetTabList();
this.contextmenu_captureie.DropDownItems.Clear();
if (tabs.Count > 0) {
@ -601,12 +651,15 @@ namespace Greenshot {
} else {
this.contextmenu_captureie.Enabled = false;
}
} catch (Exception ex) {
LOG.WarnFormat("Problem accessing IE information: {0}", ex.Message);
}
}
/// <summary>
/// Build a selectable list of windows when we enter the menu item
/// </summary>
void EnterCaptureWindowMenuItem(object sender, EventArgs e) {
private void CaptureWindowMenuDropDownOpening(object sender, EventArgs e) {
// The Capture window context menu item used to go to the following code:
// captureForm.MakeCapture(CaptureMode.Window, false);
// Now we check which windows are there to capture
@ -614,46 +667,146 @@ namespace Greenshot {
AddCaptureWindowMenuItems(captureWindowMenuItem, Contextmenu_window_Click);
}
public static void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler) {
private void CaptureWindowMenuDropDownClosed(object sender, EventArgs e) {
cleanupThumbnail();
}
private void ShowThumbnailOnEnter(object sender, EventArgs e) {
ToolStripMenuItem captureWindowItem = sender as ToolStripMenuItem;
WindowDetails window = captureWindowItem.Tag as WindowDetails;
parentMenuBounds = captureWindowItem.GetCurrentParent().TopLevelControl.Bounds;
if (thumbnailForm == null) {
thumbnailForm = new FormWithoutActivation();
thumbnailForm.ShowInTaskbar = false;
thumbnailForm.FormBorderStyle = FormBorderStyle.None;
thumbnailForm.TopMost = false;
thumbnailForm.Enabled = false;
if (conf.WindowCaptureMode == WindowCaptureMode.Auto || conf.WindowCaptureMode == WindowCaptureMode.Aero) {
thumbnailForm.BackColor = Color.FromArgb(255, conf.DWMBackgroundColor.R, conf.DWMBackgroundColor.G, conf.DWMBackgroundColor.B);
} else {
thumbnailForm.BackColor = Color.White;
}
}
if (thumbnailHandle != IntPtr.Zero) {
DWM.DwmUnregisterThumbnail(thumbnailHandle);
thumbnailHandle = IntPtr.Zero;
}
DWM.DwmRegisterThumbnail(thumbnailForm.Handle, window.Handle, out thumbnailHandle);
if (thumbnailHandle != IntPtr.Zero) {
Rectangle windowRectangle = window.WindowRectangle;
int thumbnailHeight = 200;
int thumbnailWidth = (int)(thumbnailHeight * ((float)windowRectangle.Width / (float)windowRectangle.Height));
if (thumbnailWidth > parentMenuBounds.Width) {
thumbnailWidth = parentMenuBounds.Width;
thumbnailHeight = (int)(thumbnailWidth * ((float)windowRectangle.Height / (float)windowRectangle.Width));
}
thumbnailForm.Width = thumbnailWidth;
thumbnailForm.Height = thumbnailHeight;
// Prepare the displaying of the Thumbnail
DWM_THUMBNAIL_PROPERTIES props = new DWM_THUMBNAIL_PROPERTIES();
props.Opacity = (byte)255;
props.Visible = true;
props.SourceClientAreaOnly = false;
props.Destination = new RECT(0, 0, thumbnailWidth, thumbnailHeight);
DWM.DwmUpdateThumbnailProperties(thumbnailHandle, ref props);
if (!thumbnailForm.Visible) {
thumbnailForm.Show();
}
// Make sure it's on "top"!
User32.SetWindowPos(thumbnailForm.Handle,captureWindowItem.GetCurrentParent().TopLevelControl.Handle, 0,0,0,0, WindowPos.SWP_NOMOVE | WindowPos.SWP_NOSIZE | WindowPos.SWP_NOACTIVATE);
// Align to menu
Rectangle screenBounds = WindowCapture.GetScreenBounds();
if (screenBounds.Contains(parentMenuBounds.Left, parentMenuBounds.Top - thumbnailHeight)) {
thumbnailForm.Location = new Point(parentMenuBounds.Left + (parentMenuBounds.Width/2) - (thumbnailWidth/2), parentMenuBounds.Top - thumbnailHeight);
} else {
thumbnailForm.Location = new Point(parentMenuBounds.Left + (parentMenuBounds.Width/2) - (thumbnailWidth/2), parentMenuBounds.Bottom);
}
}
}
private void HideThumbnailOnLeave(object sender, EventArgs e) {
hideThumbnail();
}
private void hideThumbnail() {
if (thumbnailHandle != IntPtr.Zero) {
DWM.DwmUnregisterThumbnail(thumbnailHandle);
thumbnailHandle = IntPtr.Zero;
thumbnailForm.Hide();
}
}
private void cleanupThumbnail() {
hideThumbnail();
if (thumbnailForm != null) {
thumbnailForm.Close();
thumbnailForm = null;
}
}
public void AddCaptureWindowMenuItems(ToolStripMenuItem menuItem, EventHandler eventHandler) {
ILanguage lang = Language.GetInstance();
menuItem.DropDownItems.Clear();
// check if thumbnailPreview is enabled and DWM is enabled
bool thumbnailPreview = conf.ThumnailPreview && DWM.isDWMEnabled();
List<WindowDetails> windows = WindowDetails.GetVisibleWindows();
foreach(WindowDetails window in windows) {
ToolStripMenuItem captureWindowItem = new ToolStripMenuItem(window.Text);
captureWindowItem.Tag = window;
captureWindowItem.Image = window.DisplayIcon;
captureWindowItem.Click += new System.EventHandler(eventHandler);
// Only show preview when enabled
if (thumbnailPreview) {
captureWindowItem.MouseEnter += new System.EventHandler(ShowThumbnailOnEnter);
captureWindowItem.MouseLeave += new System.EventHandler(HideThumbnailOnLeave);
}
menuItem.DropDownItems.Add(captureWindowItem);
}
}
void CaptureAreaToolStripMenuItemClick(object sender, EventArgs e) {
captureForm.MakeCapture(CaptureMode.Region, false);
BeginInvoke((MethodInvoker)delegate {
CaptureHelper.CaptureRegion(false);
});
}
void CaptureClipboardToolStripMenuItemClick(object sender, EventArgs e) {
CaptureClipboard();
BeginInvoke((MethodInvoker)delegate {
CaptureHelper.CaptureClipboard();
});
}
void OpenFileToolStripMenuItemClick(object sender, EventArgs e) {
BeginInvoke((MethodInvoker)delegate {
CaptureFile();
});
}
void CaptureFullScreenToolStripMenuItemClick(object sender, EventArgs e) {
captureForm.MakeCapture(CaptureMode.FullScreen, false);
BeginInvoke((MethodInvoker)delegate {
CaptureHelper.CaptureFullscreen(false);
});
}
void Contextmenu_capturelastregionClick(object sender, EventArgs e) {
captureForm.MakeCapture(CaptureMode.LastRegion, false);
BeginInvoke((MethodInvoker)delegate {
CaptureHelper.CaptureLastRegion(false);
});
}
void Contextmenu_window_Click(object sender,EventArgs e) {
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
BeginInvoke((MethodInvoker)delegate {
try {
WindowDetails windowToCapture = (WindowDetails)clickedItem.Tag;
captureForm.MakeCapture(windowToCapture);
CaptureHelper.CaptureWindow(windowToCapture);
} catch (Exception exception) {
LOG.Error(exception);
}
});
}
void Contextmenu_captureIE_Click(object sender, EventArgs e) {
@ -663,109 +816,187 @@ namespace Greenshot {
}
ToolStripMenuItem clickedItem = (ToolStripMenuItem)sender;
KeyValuePair<WindowDetails, int> tabData = (KeyValuePair<WindowDetails, int>)clickedItem.Tag;
BeginInvoke((MethodInvoker)delegate {
try {
IECaptureHelper.ActivateIETab(tabData.Key, tabData.Value);
} catch (Exception exception) {
LOG.Error(exception);
}
try {
captureForm.MakeCapture(CaptureMode.IE, false);
CaptureHelper.CaptureIE(false);
} catch (Exception exception) {
LOG.Error(exception);
}
});
}
void Contextmenu_donateClick(object sender, EventArgs e) {
BeginInvoke((MethodInvoker)delegate {
Process.Start("http://getgreenshot.org/support/");
});
}
void Contextmenu_settingsClick(object sender, EventArgs e) {
SettingsForm settings = new SettingsForm();
settings.ShowDialog();
BeginInvoke((MethodInvoker)delegate {
ShowSetting();
});
}
public void ShowSetting() {
if (settingsForm != null) {
WindowDetails.ToForeground(settingsForm.Handle);
} else {
try {
using (settingsForm = new SettingsForm()) {
if (settingsForm.ShowDialog() == DialogResult.OK) {
InitializeQuickSettingsMenu();
this.Hide();
}
}
} finally {
settingsForm = null;
}
}
}
void Contextmenu_aboutClick(object sender, EventArgs e) {
new AboutForm().Show();
if (aboutForm != null) {
WindowDetails.ToForeground(aboutForm.Handle);
} else {
try {
using (aboutForm = new AboutForm()) {
aboutForm.ShowDialog();
}
} finally {
aboutForm = null;
}
}
}
void Contextmenu_helpClick(object sender, EventArgs e) {
HelpBrowserForm hpf = new HelpBrowserForm(conf.Language);
hpf.Show();
if (helpBrowserForm != null) {
WindowDetails.ToForeground(helpBrowserForm.Handle);
} else {
try {
using (helpBrowserForm = new HelpBrowserForm(conf.Language)) {
helpBrowserForm.ShowDialog();
}
} finally {
helpBrowserForm = null;
}
}
}
void Contextmenu_exitClick(object sender, EventArgs e) {
exit();
Exit();
}
private void InitializeQuickSettingsMenu() {
this.contextmenu_quicksettings.DropDownItems.Clear();
// screenshot destination
ToolStripMenuSelectList selectList = new ToolStripMenuSelectList("destination",true);
ToolStripMenuSelectList selectList = new ToolStripMenuSelectList("destinations",true);
selectList.Text = lang.GetString(LangKey.settings_destination);
selectList.AddItem(lang.GetString(LangKey.settings_destination_editor), Destination.Editor, conf.OutputDestinations.Contains(Destination.Editor));
selectList.AddItem(lang.GetString(LangKey.settings_destination_clipboard), Destination.Clipboard, conf.OutputDestinations.Contains(Destination.Clipboard));
selectList.AddItem(lang.GetString(LangKey.quicksettings_destination_file), Destination.FileDefault, conf.OutputDestinations.Contains(Destination.FileDefault));
selectList.AddItem(lang.GetString(LangKey.settings_destination_fileas), Destination.FileWithDialog, conf.OutputDestinations.Contains(Destination.FileWithDialog));
selectList.AddItem(lang.GetString(LangKey.settings_destination_printer), Destination.Printer, conf.OutputDestinations.Contains(Destination.Printer));
selectList.AddItem(lang.GetString(LangKey.settings_destination_email), Destination.EMail, conf.OutputDestinations.Contains(Destination.EMail));
selectList.CheckedChanged += new EventHandler(this.QuickSettingItemChanged);
// Working with IDestination:
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
selectList.AddItem(destination.Description, destination, conf.OutputDestinations.Contains(destination.Designation));
}
selectList.CheckedChanged += new EventHandler(this.QuickSettingDestinationChanged);
this.contextmenu_quicksettings.DropDownItems.Add(selectList);
// Capture Modes
selectList = new ToolStripMenuSelectList("capturemodes", false);
selectList.Text = lang.GetString(LangKey.settings_window_capture_mode);
string enumTypeName = typeof(WindowCaptureMode).Name;
foreach(WindowCaptureMode captureMode in Enum.GetValues(typeof(WindowCaptureMode))) {
selectList.AddItem(lang.GetString(enumTypeName + "." + captureMode.ToString()), captureMode, conf.WindowCaptureMode == captureMode);
}
selectList.CheckedChanged += new EventHandler(this.QuickSettingCaptureModeChanged);
this.contextmenu_quicksettings.DropDownItems.Add(selectList);
// print options
selectList = new ToolStripMenuSelectList("printoptions",true);
selectList.Text = lang.GetString(LangKey.settings_printoptions);
selectList.AddItem(lang.GetString(LangKey.printoptions_allowshrink), "AllowPrintShrink", conf.OutputPrintAllowShrink);
selectList.AddItem(lang.GetString(LangKey.printoptions_allowenlarge), "AllowPrintEnlarge", conf.OutputPrintAllowEnlarge);
selectList.AddItem(lang.GetString(LangKey.printoptions_allowrotate), "AllowPrintRotate", conf.OutputPrintAllowRotate);
selectList.AddItem(lang.GetString(LangKey.printoptions_allowcenter), "AllowPrintCenter", conf.OutputPrintCenter);
selectList.CheckedChanged += new EventHandler(this.QuickSettingItemChanged);
IniValue iniValue;
foreach(string propertyName in conf.Values.Keys) {
if (propertyName.StartsWith("OutputPrint")) {
iniValue = conf.Values[propertyName];
selectList.AddItem(lang.GetString(iniValue.Attributes.LanguageKey), iniValue, (bool)iniValue.Value);
}
}
selectList.CheckedChanged += new EventHandler(this.QuickSettingBoolItemChanged);
this.contextmenu_quicksettings.DropDownItems.Add(selectList);
// effects
selectList = new ToolStripMenuSelectList("effects",true);
selectList.Text = lang.GetString(LangKey.settings_visualization);
selectList.AddItem(lang.GetString(LangKey.settings_playsound), "PlaySound", conf.PlayCameraSound);
selectList.CheckedChanged += new EventHandler(this.QuickSettingItemChanged);
iniValue = conf.Values["PlayCameraSound"];
selectList.AddItem(lang.GetString(iniValue.Attributes.LanguageKey), iniValue, (bool)iniValue.Value);
iniValue = conf.Values["ShowTrayNotification"];
selectList.AddItem(lang.GetString(iniValue.Attributes.LanguageKey), iniValue, (bool)iniValue.Value);
selectList.CheckedChanged += new EventHandler(this.QuickSettingBoolItemChanged);
this.contextmenu_quicksettings.DropDownItems.Add(selectList);
}
void QuickSettingItemChanged(object sender, EventArgs e) {
ToolStripMenuSelectList selectList = (ToolStripMenuSelectList)sender;
void QuickSettingCaptureModeChanged(object sender, EventArgs e) {
ToolStripMenuSelectListItem item = ((ItemCheckedChangedEventArgs)e).Item;
if(selectList.Identifier.Equals("destination")) {
Destination selectedDestination = (Destination)item.Data;
if (item.Checked && !conf.OutputDestinations.Contains(selectedDestination)) {
conf.OutputDestinations.Add(selectedDestination);
WindowCaptureMode windowsCaptureMode = (WindowCaptureMode)item.Data;
if (item.Checked) {
conf.WindowCaptureMode = windowsCaptureMode;
}
if (!item.Checked && conf.OutputDestinations.Contains(selectedDestination)) {
conf.OutputDestinations.Remove(selectedDestination);
}
void QuickSettingBoolItemChanged(object sender, EventArgs e) {
ToolStripMenuSelectListItem item = ((ItemCheckedChangedEventArgs)e).Item;
IniValue iniValue = item.Data as IniValue;
if (iniValue != null) {
iniValue.Value = item.Checked;
IniConfig.Save();
} else if(selectList.Identifier.Equals("printoptions")) {
if(item.Data.Equals("AllowPrintShrink")) conf.OutputPrintAllowShrink = item.Checked;
else if(item.Data.Equals("AllowPrintEnlarge")) conf.OutputPrintAllowEnlarge = item.Checked;
else if(item.Data.Equals("AllowPrintRotate")) conf.OutputPrintAllowRotate = item.Checked;
else if(item.Data.Equals("AllowPrintCenter")) conf.OutputPrintCenter = item.Checked;
IniConfig.Save();
} else if(selectList.Identifier.Equals("effects")) {
if(item.Data.Equals("PlaySound")) {
conf.PlayCameraSound = item.Checked;
}
IniConfig.Save();
}
void QuickSettingDestinationChanged(object sender, EventArgs e) {
ToolStripMenuSelectListItem item = ((ItemCheckedChangedEventArgs)e).Item;
IDestination selectedDestination = (IDestination)item.Data;
if (item.Checked && selectedDestination.Designation.Equals("Picker")) {
foreach(ToolStripMenuSelectList ddi in contextmenu_quicksettings.DropDownItems) {
if (ddi.Identifier.Equals("destinations")) {
foreach(ToolStripMenuSelectListItem dropDownItem in ddi.DropDownItems) {
IDestination destination = dropDownItem.Data as IDestination;
if (!destination.Designation.Equals("Picker")) {
if (dropDownItem.CheckState == CheckState.Checked) {
dropDownItem.CheckState = CheckState.Unchecked;
}
}
}
}
}
conf.OutputDestinations.Clear();
conf.OutputDestinations.Add(selectedDestination.Designation);
} else {
if (item.Checked && !conf.OutputDestinations.Contains(selectedDestination.Designation)) {
conf.OutputDestinations.Add(selectedDestination.Designation);
}
if (!item.Checked && conf.OutputDestinations.Contains(selectedDestination.Designation)) {
conf.OutputDestinations.Remove(selectedDestination.Designation);
}
}
IniConfig.Save();
}
#endregion
private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e) {
string exceptionText = EnvironmentInfo.BuildReport(e.ExceptionObject as Exception);
LOG.Error(exceptionText);
Exception exceptionToLog = e.ExceptionObject as Exception;
string exceptionText = EnvironmentInfo.BuildReport(exceptionToLog);
LOG.Error(EnvironmentInfo.ExceptionToString(exceptionToLog));
new BugReportForm(exceptionText).ShowDialog();
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
string exceptionText = EnvironmentInfo.BuildReport(e.Exception);
LOG.Error(exceptionText);
Exception exceptionToLog = e.Exception;
string exceptionText = EnvironmentInfo.BuildReport(exceptionToLog);
LOG.Error(EnvironmentInfo.ExceptionToString(exceptionToLog));
new BugReportForm(exceptionText).ShowDialog();
}
@ -779,7 +1010,7 @@ namespace Greenshot {
/// </summary>
private void Contextmenu_OpenRecent(object sender, EventArgs eventArgs) {
string path;
string configPath = FilenameHelper.FillVariables(conf.OutputFilePath);
string configPath = FilenameHelper.FillVariables(conf.OutputFilePath, false);
string lastFilePath = Path.GetDirectoryName(conf.OutputFileAsFullpath);
if (Directory.Exists(lastFilePath)) {
path = lastFilePath;
@ -802,9 +1033,7 @@ namespace Greenshot {
/// <summary>
/// Shutdown / cleanup
/// </summary>
public void exit() {
ClipboardHelper.DeregisterClipboardViewer(this.Handle);
public void Exit() {
LOG.Info("Exit: " + EnvironmentInfo.EnvironmentToString(false));
// Close all open forms (except this), use a separate List to make sure we don't get a "InvalidOperationException: Collection was modified"
@ -852,6 +1081,8 @@ namespace Greenshot {
LOG.Error("Error closing application!", e);
}
ImageOutput.RemoveTmpFiles();
// Store any open configuration changes
try {
IniConfig.Save();
@ -876,9 +1107,8 @@ namespace Greenshot {
/// <param name="sender"></param>
/// <param name="e"></param>
private void BackgroundWorkerTimerTick(object sender, EventArgs e) {
LOG.Debug("BackgroundWorkerTimerTick");
if (UpdateHelper.IsUpdateCheckNeeded()) {
LOG.Debug("BackgroundWorkerTimerTick checking for update");
// Start update check in the background
Thread backgroundTask = new Thread (new ThreadStart(UpdateHelper.CheckAndAskForUpdate));
backgroundTask.IsBackground = true;

View file

@ -19,11 +19,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Forms {
/// <summary>

View file

@ -19,17 +19,13 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Drawing;
using System.IO;
using System.Reflection;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Helpers;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Forms {
/// <summary>
@ -168,7 +164,7 @@ namespace Greenshot.Forms {
private string GetRootDirFromConfig() {
string rootDir = conf.OutputFilePath;
rootDir = FilenameHelper.FillVariables(rootDir);
rootDir = FilenameHelper.FillVariables(rootDir, false);
return rootDir;
}
@ -178,12 +174,16 @@ namespace Greenshot.Forms {
}
private void CleanUp() {
if(eagerlyCreatedDirectory!=null
&& eagerlyCreatedDirectory.GetFiles().Length==0
&& eagerlyCreatedDirectory.GetDirectories().Length==0) {
// fix for bug #3379053
try {
if(eagerlyCreatedDirectory != null && eagerlyCreatedDirectory.GetFiles().Length == 0 && eagerlyCreatedDirectory.GetDirectories().Length == 0) {
eagerlyCreatedDirectory.Delete();
eagerlyCreatedDirectory = null;
}
} catch (Exception e) {
LOG.WarnFormat("Couldn't cleanup directory due to: {0}", e.Message);
eagerlyCreatedDirectory = null;
}
}
private string CreateDirectoryIfNotExists(string fullPath) {

View file

@ -64,19 +64,13 @@ namespace Greenshot {
this.checkbox_copypathtoclipboard = new System.Windows.Forms.CheckBox();
this.groupbox_applicationsettings = new System.Windows.Forms.GroupBox();
this.checkbox_autostartshortcut = new System.Windows.Forms.CheckBox();
this.checkbox_editor = new System.Windows.Forms.CheckBox();
this.groupbox_jpegsettings = new System.Windows.Forms.GroupBox();
this.checkbox_alwaysshowjpegqualitydialog = new System.Windows.Forms.CheckBox();
this.label_jpegquality = new System.Windows.Forms.Label();
this.textBoxJpegQuality = new System.Windows.Forms.TextBox();
this.trackBarJpegQuality = new System.Windows.Forms.TrackBar();
this.checkbox_clipboard = new System.Windows.Forms.CheckBox();
this.checkbox_file = new System.Windows.Forms.CheckBox();
this.checkbox_printer = new System.Windows.Forms.CheckBox();
this.groupbox_destination = new System.Windows.Forms.GroupBox();
this.combobox_emailformat = new System.Windows.Forms.ComboBox();
this.checkbox_email = new System.Windows.Forms.CheckBox();
this.checkbox_fileas = new System.Windows.Forms.CheckBox();
this.checkedDestinationsListBox = new System.Windows.Forms.CheckedListBox();
this.tabcontrol = new System.Windows.Forms.TabControl();
this.tab_general = new System.Windows.Forms.TabPage();
this.groupbox_network = new System.Windows.Forms.GroupBox();
@ -299,17 +293,6 @@ namespace Greenshot {
this.checkbox_autostartshortcut.Text = "Launch Greenshot on startup";
this.checkbox_autostartshortcut.UseVisualStyleBackColor = true;
//
// checkbox_editor
//
this.checkbox_editor.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_editor.Location = new System.Drawing.Point(12, 19);
this.checkbox_editor.Name = "checkbox_editor";
this.checkbox_editor.Size = new System.Drawing.Size(158, 24);
this.checkbox_editor.TabIndex = 14;
this.checkbox_editor.Text = "Open in editor";
this.checkbox_editor.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_editor.UseVisualStyleBackColor = true;
//
// groupbox_jpegsettings
//
this.groupbox_jpegsettings.Controls.Add(this.checkbox_alwaysshowjpegqualitydialog);
@ -360,48 +343,9 @@ namespace Greenshot {
this.trackBarJpegQuality.TickFrequency = 10;
this.trackBarJpegQuality.Scroll += new System.EventHandler(this.TrackBarJpegQualityScroll);
//
// checkbox_clipboard
//
this.checkbox_clipboard.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_clipboard.Location = new System.Drawing.Point(12, 41);
this.checkbox_clipboard.Name = "checkbox_clipboard";
this.checkbox_clipboard.Size = new System.Drawing.Size(158, 24);
this.checkbox_clipboard.TabIndex = 15;
this.checkbox_clipboard.Text = "Copy to clipboard";
this.checkbox_clipboard.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_clipboard.UseVisualStyleBackColor = true;
//
// checkbox_file
//
this.checkbox_file.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_file.Location = new System.Drawing.Point(176, 42);
this.checkbox_file.Name = "checkbox_file";
this.checkbox_file.Size = new System.Drawing.Size(230, 23);
this.checkbox_file.TabIndex = 16;
this.checkbox_file.Text = "Sofort speichern (mit nachstehend angegebenen Einstellungen)";
this.checkbox_file.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_file.UseVisualStyleBackColor = true;
//
// checkbox_printer
//
this.checkbox_printer.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_printer.Location = new System.Drawing.Point(12, 63);
this.checkbox_printer.Name = "checkbox_printer";
this.checkbox_printer.Size = new System.Drawing.Size(158, 24);
this.checkbox_printer.TabIndex = 17;
this.checkbox_printer.Text = "Send to printer";
this.checkbox_printer.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_printer.UseVisualStyleBackColor = true;
//
// groupbox_destination
//
this.groupbox_destination.Controls.Add(this.combobox_emailformat);
this.groupbox_destination.Controls.Add(this.checkbox_email);
this.groupbox_destination.Controls.Add(this.checkbox_fileas);
this.groupbox_destination.Controls.Add(this.checkbox_printer);
this.groupbox_destination.Controls.Add(this.checkbox_editor);
this.groupbox_destination.Controls.Add(this.checkbox_file);
this.groupbox_destination.Controls.Add(this.checkbox_clipboard);
this.groupbox_destination.Controls.Add(this.checkedDestinationsListBox);
this.groupbox_destination.Location = new System.Drawing.Point(2, 6);
this.groupbox_destination.Name = "groupbox_destination";
this.groupbox_destination.Size = new System.Drawing.Size(412, 94);
@ -409,36 +353,15 @@ namespace Greenshot {
this.groupbox_destination.TabStop = false;
this.groupbox_destination.Text = "Screenshot Destination";
//
// combobox_emailformat
// checkedDestinationsListBox
//
this.combobox_emailformat.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
this.combobox_emailformat.FormattingEnabled = true;
this.combobox_emailformat.Location = new System.Drawing.Point(312, 61);
this.combobox_emailformat.Name = "combobox_emailformat";
this.combobox_emailformat.Size = new System.Drawing.Size(94, 21);
this.combobox_emailformat.TabIndex = 20;
//
// checkbox_email
//
this.checkbox_email.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_email.Location = new System.Drawing.Point(176, 63);
this.checkbox_email.Name = "checkbox_email";
this.checkbox_email.Size = new System.Drawing.Size(230, 23);
this.checkbox_email.TabIndex = 19;
this.checkbox_email.Text = "Email";
this.checkbox_email.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_email.UseVisualStyleBackColor = true;
//
// checkbox_fileas
//
this.checkbox_fileas.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_fileas.Location = new System.Drawing.Point(176, 19);
this.checkbox_fileas.Name = "checkbox_fileas";
this.checkbox_fileas.Size = new System.Drawing.Size(230, 24);
this.checkbox_fileas.TabIndex = 18;
this.checkbox_fileas.Text = "Save as (displaying dialog)";
this.checkbox_fileas.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_fileas.UseVisualStyleBackColor = true;
this.checkedDestinationsListBox.FormattingEnabled = true;
this.checkedDestinationsListBox.Location = new System.Drawing.Point(5, 20);
this.checkedDestinationsListBox.Name = "checkedDestinationsListBox";
this.checkedDestinationsListBox.ScrollAlwaysVisible = true;
this.checkedDestinationsListBox.Size = new System.Drawing.Size(401, 64);
this.checkedDestinationsListBox.TabIndex = 0;
this.checkedDestinationsListBox.SelectedValueChanged += new System.EventHandler(this.DestinationsCheckStateChanged);
//
// tabcontrol
//
@ -639,7 +562,7 @@ namespace Greenshot {
//
this.checkbox_editor_match_capture_size.Location = new System.Drawing.Point(6, 19);
this.checkbox_editor_match_capture_size.Name = "checkbox_editor_match_capture_size";
this.checkbox_editor_match_capture_size.Size = new System.Drawing.Size(213, 24);
this.checkbox_editor_match_capture_size.Size = new System.Drawing.Size(397, 24);
this.checkbox_editor_match_capture_size.TabIndex = 26;
this.checkbox_editor_match_capture_size.Text = "Match capture size";
this.checkbox_editor_match_capture_size.UseVisualStyleBackColor = true;
@ -989,13 +912,13 @@ namespace Greenshot {
this.groupbox_plugins.PerformLayout();
this.ResumeLayout(false);
}
private System.Windows.Forms.CheckedListBox checkedDestinationsListBox;
private System.Windows.Forms.GroupBox groupbox_editor;
private System.Windows.Forms.CheckBox checkbox_editor_match_capture_size;
private System.Windows.Forms.NumericUpDown numericUpDown_daysbetweencheck;
private System.Windows.Forms.GroupBox groupbox_network;
private System.Windows.Forms.CheckBox checkbox_usedefaultproxy;
private System.Windows.Forms.Label label_checkperiod;
private System.Windows.Forms.ComboBox combobox_emailformat;
private GreenshotPlugin.Controls.HotkeyControl fullscreen_hotkeyControl;
private GreenshotPlugin.Controls.HotkeyControl window_hotkeyControl;
private GreenshotPlugin.Controls.HotkeyControl region_hotkeyControl;
@ -1018,7 +941,6 @@ namespace Greenshot {
private System.Windows.Forms.ComboBox combobox_window_capture_mode;
private System.Windows.Forms.NumericUpDown numericUpDownWaitTime;
private System.Windows.Forms.Label label_waittime;
private System.Windows.Forms.CheckBox checkbox_email;
private System.Windows.Forms.CheckBox checkbox_capture_windows_interactive;
private System.Windows.Forms.CheckBox checkbox_capture_mousepointer;
private System.Windows.Forms.TabPage tab_printer;
@ -1027,7 +949,6 @@ namespace Greenshot {
private System.Windows.Forms.GroupBox groupbox_plugins;
private System.Windows.Forms.TabPage tab_plugins;
private System.Windows.Forms.CheckBox checkboxTimestamp;
private System.Windows.Forms.CheckBox checkbox_fileas;
private System.Windows.Forms.Button btnPatternHelp;
private System.Windows.Forms.CheckBox checkbox_copypathtoclipboard;
private System.Windows.Forms.CheckBox checkboxAllowShrink;
@ -1041,10 +962,6 @@ namespace Greenshot {
private System.Windows.Forms.TabControl tabcontrol;
private System.Windows.Forms.CheckBox checkbox_autostartshortcut;
private System.Windows.Forms.GroupBox groupbox_destination;
private System.Windows.Forms.CheckBox checkbox_editor;
private System.Windows.Forms.CheckBox checkbox_clipboard;
private System.Windows.Forms.CheckBox checkbox_file;
private System.Windows.Forms.CheckBox checkbox_printer;
private System.Windows.Forms.CheckBox checkbox_alwaysshowjpegqualitydialog;
private System.Windows.Forms.TextBox textBoxJpegQuality;
private System.Windows.Forms.Label label_jpegquality;

View file

@ -21,18 +21,16 @@
using System;
using System.Collections.Generic;
using System.Drawing;
using System.Globalization;
using System.IO;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Helpers;
using Greenshot.Helpers.OfficeInterop;
using Greenshot.Plugin;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using GreenshotPlugin.UnmanagedHelpers;
using Greenshot.Plugin;
using IniFile;
namespace Greenshot {
/// <summary>
@ -42,7 +40,7 @@ namespace Greenshot {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(SettingsForm));
private static CoreConfiguration coreConfiguration = IniConfig.GetIniSection<CoreConfiguration>();
private static EditorConfiguration editorConfiguration = IniConfig.GetIniSection<EditorConfiguration>();
ILanguage lang;
private ILanguage lang;
private ToolTip toolTip;
public SettingsForm() {
@ -60,17 +58,95 @@ namespace Greenshot {
toolTip = new ToolTip();
AddPluginTab();
this.combobox_primaryimageformat.Items.AddRange(new object[]{OutputFormat.bmp, OutputFormat.gif, OutputFormat.jpg, OutputFormat.png, OutputFormat.tiff});
this.combobox_emailformat.Items.AddRange(new object[]{EmailFormat.TXT, EmailFormat.HTML});
this.combobox_window_capture_mode.Items.AddRange(new object[]{WindowCaptureMode.Auto, WindowCaptureMode.Screen, WindowCaptureMode.GDI});
if (DWM.isDWMEnabled()) {
this.combobox_window_capture_mode.Items.Add(WindowCaptureMode.Aero);
this.combobox_window_capture_mode.Items.Add(WindowCaptureMode.AeroTransparent);
}
UpdateUI();
DisplaySettings();
CheckSettings();
}
/// <summary>
/// This is a method to popululate the ComboBox
/// with the items from the enumeration
/// </summary>
/// <param name="comboBox">ComboBox to populate</param>
/// <param name="enumeration">Enum to populate with</param>
private void PopulateComboBox<ET>(ComboBox comboBox) {
ET[] availableValues = (ET[])Enum.GetValues(typeof(ET));
PopulateComboBox<ET>(comboBox, availableValues, availableValues[0]);
}
/// <summary>
/// This is a method to popululate the ComboBox
/// with the items from the enumeration
/// </summary>
/// <param name="comboBox">ComboBox to populate</param>
/// <param name="enumeration">Enum to populate with</param>
private void PopulateComboBox<ET>(ComboBox comboBox, ET[] availableValues, ET selectedValue) {
comboBox.Items.Clear();
string enumTypeName = typeof(ET).Name;
foreach(ET enumValue in availableValues) {
string translation = lang.GetString(enumTypeName + "." + enumValue.ToString());
comboBox.Items.Add(translation);
}
comboBox.SelectedItem = lang.GetString(enumTypeName + "." + selectedValue.ToString());
}
/// <summary>
/// Get the selected enum value from the combobox, uses generics
/// </summary>
/// <param name="comboBox">Combobox to get the value from</param>
/// <returns>The generics value of the combobox</returns>
private ET GetSelected<ET>(ComboBox comboBox) {
string enumTypeName = typeof(ET).Name;
string selectedValue = comboBox.SelectedItem as string;
ET[] availableValues = (ET[])Enum.GetValues(typeof(ET));
ET returnValue = availableValues[0];
foreach(ET enumValue in availableValues) {
string translation = lang.GetString(enumTypeName + "." + enumValue.ToString());
if (translation.Equals(selectedValue)) {
returnValue = enumValue;
break;
}
}
return returnValue;
}
private void SetEmailFormat(EmailFormat selectedEmailFormat) {
// TODO: Fix!!
// Setup the email settings
EmailFormat [] availableValues;
if (EmailConfigHelper.HasMAPI()) {
//checkbox_email.Enabled = true;
//combobox_emailformat.Visible = true;
if (EmailConfigHelper.HasOutlook()) {
availableValues = new EmailFormat[]{EmailFormat.MAPI, EmailFormat.OUTLOOK_TXT, EmailFormat.OUTLOOK_HTML};
} else {
// Force MAPI in configuration if no Outlook
coreConfiguration.OutputEMailFormat = EmailFormat.MAPI;
availableValues = new EmailFormat[]{EmailFormat.MAPI};
}
//PopulateComboBox<EmailFormat>(combobox_emailformat, availableValues, selectedEmailFormat);
} else {
//checkbox_email.Enabled = false;
//checkbox_email.Checked = false;
//combobox_emailformat.Visible = false;
}
}
private void SetWindowCaptureMode(WindowCaptureMode selectedWindowCaptureMode) {
WindowCaptureMode[] availableModes;
if (!DWM.isDWMEnabled()) {
// Remove DWM from configuration, as DWM is disabled!
if (coreConfiguration.WindowCaptureMode == WindowCaptureMode.Aero || coreConfiguration.WindowCaptureMode == WindowCaptureMode.AeroTransparent) {
coreConfiguration.WindowCaptureMode = WindowCaptureMode.GDI;
}
availableModes = new WindowCaptureMode[]{WindowCaptureMode.Auto, WindowCaptureMode.Screen, WindowCaptureMode.GDI};
} else {
availableModes = new WindowCaptureMode[]{WindowCaptureMode.Auto, WindowCaptureMode.Screen, WindowCaptureMode.GDI, WindowCaptureMode.Aero, WindowCaptureMode.AeroTransparent};
}
PopulateComboBox<WindowCaptureMode>(combobox_window_capture_mode, availableModes, selectedWindowCaptureMode);
}
private void AddPluginTab() {
if (PluginHelper.instance.HasPlugins()) {
this.tabcontrol.TabPages.Add(tab_plugins);
@ -133,12 +209,6 @@ namespace Greenshot {
this.checkbox_autostartshortcut.Text = lang.GetString(LangKey.settings_autostartshortcut);
this.groupbox_destination.Text = lang.GetString(LangKey.settings_destination);
this.checkbox_clipboard.Text = lang.GetString(LangKey.settings_destination_clipboard);
this.checkbox_printer.Text = lang.GetString(LangKey.settings_destination_printer);
this.checkbox_file.Text = lang.GetString(LangKey.settings_destination_file);
this.checkbox_fileas.Text = lang.GetString(LangKey.settings_destination_fileas);
this.checkbox_editor.Text = lang.GetString(LangKey.settings_destination_editor);
this.checkbox_email.Text = lang.GetString(LangKey.settings_destination_email);
this.groupbox_preferredfilesettings.Text = lang.GetString(LangKey.settings_preferredfilesettings);
@ -177,7 +247,9 @@ namespace Greenshot {
// Initialize the Language ComboBox
this.combobox_language.DisplayMember = "Description";
this.combobox_language.ValueMember = "Ietf";
if (lang.CurrentLanguage != null) {
this.combobox_language.SelectedValue = lang.CurrentLanguage;
}
// Set datasource last to prevent problems
// See: http://www.codeproject.com/KB/database/scomlistcontrolbinding.aspx?fid=111644
this.combobox_language.DataSource = lang.SupportedLanguages;
@ -189,7 +261,7 @@ namespace Greenshot {
// Check the settings and somehow visibly mark when something is incorrect
private bool CheckSettings() {
bool settingsOk = true;
if(!Directory.Exists(FilenameHelper.FillVariables(textbox_storagelocation.Text))) {
if(!Directory.Exists(FilenameHelper.FillVariables(textbox_storagelocation.Text, false))) {
textbox_storagelocation.BackColor = Color.Red;
settingsOk = false;
} else {
@ -207,18 +279,15 @@ namespace Greenshot {
colorButton_window_background.SelectedColor = coreConfiguration.DWMBackgroundColor;
checkbox_ie_capture.Checked = coreConfiguration.IECapture;
if (lang.CurrentLanguage != null) {
combobox_language.SelectedValue = lang.CurrentLanguage;
textbox_storagelocation.Text = FilenameHelper.FillVariables(coreConfiguration.OutputFilePath);
}
textbox_storagelocation.Text = FilenameHelper.FillVariables(coreConfiguration.OutputFilePath, false);
textbox_screenshotname.Text = coreConfiguration.OutputFileFilenamePattern;
combobox_primaryimageformat.SelectedItem = coreConfiguration.OutputFileFormat;
combobox_emailformat.SelectedItem = coreConfiguration.OutputEMailFormat;
if (!DWM.isDWMEnabled()) {
// Remove DWM from configuration, as DWM is disabled!
if (coreConfiguration.WindowCaptureMode == WindowCaptureMode.Aero || coreConfiguration.WindowCaptureMode == WindowCaptureMode.AeroTransparent) {
coreConfiguration.WindowCaptureMode = WindowCaptureMode.GDI;
}
}
combobox_window_capture_mode.SelectedItem = coreConfiguration.WindowCaptureMode;
SetEmailFormat(coreConfiguration.OutputEMailFormat);
SetWindowCaptureMode(coreConfiguration.WindowCaptureMode);
checkbox_copypathtoclipboard.Checked = coreConfiguration.OutputFileCopyPathToClipboard;
trackBarJpegQuality.Value = coreConfiguration.OutputFileJpegQuality;
@ -226,12 +295,16 @@ namespace Greenshot {
checkbox_alwaysshowjpegqualitydialog.Checked = coreConfiguration.OutputFilePromptJpegQuality;
checkbox_playsound.Checked = coreConfiguration.PlayCameraSound;
checkbox_clipboard.Checked = coreConfiguration.OutputDestinations.Contains(Destination.Clipboard);
checkbox_file.Checked = coreConfiguration.OutputDestinations.Contains(Destination.FileDefault);
checkbox_fileas.Checked = coreConfiguration.OutputDestinations.Contains(Destination.FileWithDialog);
checkbox_printer.Checked = coreConfiguration.OutputDestinations.Contains(Destination.Printer);
checkbox_editor.Checked = coreConfiguration.OutputDestinations.Contains(Destination.Editor);
checkbox_email.Checked = coreConfiguration.OutputDestinations.Contains(Destination.EMail);
checkedDestinationsListBox.Items.Clear();
foreach(IDestination destination in DestinationHelper.GetAllDestinations()) {
checkedDestinationsListBox.Items.Add(destination, coreConfiguration.OutputDestinations.Contains(destination.Designation));
}
// checkbox_clipboard.Checked = coreConfiguration.OutputDestinations.Contains("Clipboard");
// checkbox_file.Checked = coreConfiguration.OutputDestinations.Contains("File");
// checkbox_fileas.Checked = coreConfiguration.OutputDestinations.Contains("FileWithDialog");
// checkbox_printer.Checked = coreConfiguration.OutputDestinations.Contains("Printer");
// checkbox_editor.Checked = coreConfiguration.OutputDestinations.Contains("Editor");
// checkbox_email.Checked = coreConfiguration.OutputDestinations.Contains("EMail");
checkboxPrintInverted.Checked = coreConfiguration.OutputPrintInverted;
checkboxAllowCenter.Checked = coreConfiguration.OutputPrintCenter;
@ -257,46 +330,43 @@ namespace Greenshot {
checkbox_autostartshortcut.Checked = StartupHelper.checkRunUser();
}
if (!MapiMailMessage.HasMAPIorOutlook()) {
// Disable MAPI functionality as it's not available
checkbox_email.Enabled = false;
checkbox_email.Checked = false;
combobox_emailformat.Visible = false;
} else {
// Enable MAPI functionality
checkbox_email.Enabled = true;
if (OutlookExporter.HasOutlook()) {
combobox_emailformat.Visible = true;
}
}
checkbox_usedefaultproxy.Checked = coreConfiguration.UseProxy;
numericUpDown_daysbetweencheck.Value = coreConfiguration.UpdateCheckInterval;
CheckDestinationSettings();
}
private void SaveSettings() {
if (combobox_language.SelectedItem != null) {
coreConfiguration.Language = combobox_language.SelectedValue.ToString();
}
coreConfiguration.WindowCaptureMode = (WindowCaptureMode)combobox_window_capture_mode.SelectedItem;
coreConfiguration.WindowCaptureMode = GetSelected<WindowCaptureMode>(combobox_window_capture_mode);
coreConfiguration.OutputFileFilenamePattern = textbox_screenshotname.Text;
if (!FilenameHelper.FillVariables(coreConfiguration.OutputFilePath).Equals(textbox_storagelocation.Text)) {
if (!FilenameHelper.FillVariables(coreConfiguration.OutputFilePath, false).Equals(textbox_storagelocation.Text)) {
coreConfiguration.OutputFilePath = textbox_storagelocation.Text;
}
if (combobox_primaryimageformat.SelectedItem != null) {
coreConfiguration.OutputFileFormat = (OutputFormat)combobox_primaryimageformat.SelectedItem;
coreConfiguration.OutputEMailFormat = (EmailFormat)combobox_emailformat.SelectedItem;
} else {
coreConfiguration.OutputFileFormat = OutputFormat.png;
}
// TODO: Fix
//coreConfiguration.OutputEMailFormat = GetSelected<EmailFormat>(combobox_emailformat);
coreConfiguration.OutputEMailFormat = EmailFormat.OUTLOOK_HTML;
coreConfiguration.OutputFileCopyPathToClipboard = checkbox_copypathtoclipboard.Checked;
coreConfiguration.OutputFileJpegQuality = trackBarJpegQuality.Value;
coreConfiguration.OutputFilePromptJpegQuality = checkbox_alwaysshowjpegqualitydialog.Checked;
coreConfiguration.PlayCameraSound = checkbox_playsound.Checked;
List<Destination> destinations = new List<Destination>();
if (checkbox_clipboard.Checked) destinations.Add(Destination.Clipboard);
if (checkbox_file.Checked) destinations.Add(Destination.FileDefault);
if (checkbox_fileas.Checked) destinations.Add(Destination.FileWithDialog);
if (checkbox_printer.Checked) destinations.Add(Destination.Printer);
if (checkbox_editor.Checked) destinations.Add(Destination.Editor);
if (checkbox_email.Checked) destinations.Add(Destination.EMail);
List<string> destinations = new List<string>();
foreach(int index in checkedDestinationsListBox.CheckedIndices) {
IDestination destination = (IDestination)checkedDestinationsListBox.Items[index];
if (checkedDestinationsListBox.GetItemCheckState(index) == CheckState.Checked) {
destinations.Add(destination.Designation);
}
}
coreConfiguration.OutputDestinations = destinations;
coreConfiguration.OutputPrintInverted = checkboxPrintInverted.Checked;
@ -348,24 +418,26 @@ namespace Greenshot {
}
void Settings_cancelClick(object sender, System.EventArgs e) {
this.Close();
DialogResult = DialogResult.Cancel;
lang.FreeResources();
}
void Settings_okayClick(object sender, System.EventArgs e) {
if (CheckSettings()) {
SaveSettings();
this.Close();
DialogResult = DialogResult.OK;
} else {
this.tabcontrol.SelectTab(this.tab_output);
}
lang.FreeResources();
}
void BrowseClick(object sender, System.EventArgs e) {
// Get the storage location and replace the environment variables
this.folderBrowserDialog1.SelectedPath = FilenameHelper.FillVariables(this.textbox_storagelocation.Text);
this.folderBrowserDialog1.SelectedPath = FilenameHelper.FillVariables(this.textbox_storagelocation.Text, false);
if (this.folderBrowserDialog1.ShowDialog() == DialogResult.OK) {
// Only change if there is a change, otherwise we might overwrite the environment variables
if (this.folderBrowserDialog1.SelectedPath != null && !this.folderBrowserDialog1.SelectedPath.Equals(FilenameHelper.FillVariables(this.textbox_storagelocation.Text))) {
if (this.folderBrowserDialog1.SelectedPath != null && !this.folderBrowserDialog1.SelectedPath.Equals(FilenameHelper.FillVariables(this.textbox_storagelocation.Text, false))) {
this.textbox_storagelocation.Text = this.folderBrowserDialog1.SelectedPath;
}
}
@ -390,24 +462,34 @@ namespace Greenshot {
}
void Combobox_languageSelectedIndexChanged(object sender, EventArgs e) {
// Get the combobox values BEFORE changing the language
//EmailFormat selectedEmailFormat = GetSelected<EmailFormat>(combobox_emailformat);
WindowCaptureMode selectedWindowCaptureMode = GetSelected<WindowCaptureMode>(combobox_window_capture_mode);
if (combobox_language.SelectedItem != null) {
LOG.Debug("Setting language to: " + (string)combobox_language.SelectedValue);
lang.SetLanguage((string)combobox_language.SelectedValue);
}
// Reflect language changes to the settings form
UpdateUI();
// Update the email & windows capture mode
//SetEmailFormat(selectedEmailFormat);
SetWindowCaptureMode(selectedWindowCaptureMode);
}
void Combobox_window_capture_modeSelectedIndexChanged(object sender, EventArgs e) {
int windowsVersion = Environment.OSVersion.Version.Major;
string modeText = combobox_window_capture_mode.Text;
string dwmMode = WindowCaptureMode.Aero.ToString();
string autoMode = WindowCaptureMode.Auto.ToString();
if (modeText.Equals(dwmMode, StringComparison.CurrentCultureIgnoreCase)
|| (modeText.Equals(autoMode, StringComparison.CurrentCultureIgnoreCase) && windowsVersion >= 6) ) {
WindowCaptureMode mode = GetSelected<WindowCaptureMode>(combobox_window_capture_mode);
if (windowsVersion >= 6) {
switch (mode) {
case WindowCaptureMode.Aero:
case WindowCaptureMode.Auto:
colorButton_window_background.Visible = true;
} else {
colorButton_window_background.Visible = false;
return;
}
}
colorButton_window_background.Visible = false;
}
void SettingsFormFormClosing(object sender, FormClosingEventArgs e) {
MainForm.RegisterHotkeys();
@ -416,5 +498,46 @@ namespace Greenshot {
void SettingsFormShown(object sender, EventArgs e) {
HotkeyControl.UnregisterHotkeys();
}
/// <summary>
/// Check the destination settings
/// </summary>
void CheckDestinationSettings() {
bool clipboardDestinationChecked = false;
bool pickerSelected = false;
foreach(IDestination destination in checkedDestinationsListBox.CheckedItems) {
if (destination.Designation.Equals("Clipboard")) {
clipboardDestinationChecked = true;
}
if (destination.Designation.Equals("Picker")) {
pickerSelected = true;
}
}
if (pickerSelected) {
foreach(int index in checkedDestinationsListBox.CheckedIndices) {
IDestination destination = (IDestination)checkedDestinationsListBox.Items[index];
if (!destination.Designation.Equals("Picker")) {
checkedDestinationsListBox.SetItemCheckState(index, CheckState.Indeterminate);
}
}
} else {
foreach(int index in checkedDestinationsListBox.CheckedIndices) {
if (checkedDestinationsListBox.GetItemCheckState(index) == CheckState.Indeterminate) {
checkedDestinationsListBox.SetItemCheckState(index, CheckState.Checked);
}
}
// Prevent multiple clipboard settings at once, see bug #3435056
if (clipboardDestinationChecked) {
checkbox_copypathtoclipboard.Checked = false;
checkbox_copypathtoclipboard.Enabled = false;
} else {
checkbox_copypathtoclipboard.Enabled = true;
}
}
}
void DestinationsCheckStateChanged(object sender, EventArgs e) {
CheckDestinationSettings();
}
}
}

View file

@ -1,4 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003" ToolsVersion="3.5">
<PropertyGroup>
<ProjectGuid>{CD642BF4-D815-4D67-A0B5-C69F0B8231AF}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -21,8 +22,13 @@
<DebugSymbols>true</DebugSymbols>
<DebugType>Full</DebugType>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<Optimize>False</Optimize>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>x86</PlatformTarget>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
@ -30,23 +36,19 @@
<DebugType>None</DebugType>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<Optimize>True</Optimize>
</PropertyGroup>
<PropertyGroup Condition=" '$(Platform)' == 'AnyCPU' ">
<RegisterForComInterop>False</RegisterForComInterop>
<GenerateSerializationAssemblies>Auto</GenerateSerializationAssemblies>
<BaseAddress>4194304</BaseAddress>
<PlatformTarget>x86</PlatformTarget>
<PlatformTarget>AnyCPU</PlatformTarget>
<FileAlignment>4096</FileAlignment>
</PropertyGroup>
<ItemGroup>
<Reference Include="Accessibility" />
<Reference Include="log4net">
<HintPath>Lib\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="AssemblyInfo.cs" />
@ -63,8 +65,17 @@
<Compile Include="Controls\ToolStripColorButton.cs" />
<Compile Include="Controls\FontFamilyComboBox.cs" />
<Compile Include="Controls\ToolStripNumericUpDown.cs" />
<Compile Include="Destinations\ClipboardDestination.cs" />
<Compile Include="Destinations\EditorDestination.cs" />
<Compile Include="Destinations\EmailDestination.cs" />
<Compile Include="Destinations\ExcelDestination.cs" />
<Compile Include="Destinations\FileDestination.cs" />
<Compile Include="Destinations\FileWithDialogDestination.cs" />
<Compile Include="Destinations\PickerDestination.cs" />
<Compile Include="Destinations\PowerpointDestination.cs" />
<Compile Include="Destinations\PrinterDestination.cs" />
<Compile Include="Destinations\WordDestination.cs" />
<Compile Include="Drawing\ArrowContainer.cs" />
<Compile Include="Drawing\BitmapBuffer.cs" />
<Compile Include="Drawing\BitmapContainer.cs" />
<Compile Include="Drawing\CropContainer.cs" />
<Compile Include="Drawing\CursorContainer.cs" />
@ -83,13 +94,13 @@
<Compile Include="Drawing\FilterContainer.cs" />
<Compile Include="Drawing\Filters\AbstractFilter.cs" />
<Compile Include="Drawing\Filters\BrightnessFilter.cs" />
<Compile Include="Drawing\Filters\FastSmoothFilter.cs" />
<Compile Include="Drawing\Filters\GrayscaleFilter.cs" />
<Compile Include="Drawing\Filters\HighlightFilter.cs" />
<Compile Include="Drawing\Filters\IFilter.cs" />
<Compile Include="Drawing\Filters\MagnifierFilter.cs" />
<Compile Include="Drawing\Filters\PixelizationFilter.cs" />
<Compile Include="Drawing\Filters\BlurFilter.cs" />
<Compile Include="Drawing\Gripper.cs" />
<Compile Include="Drawing\HighlightContainer.cs" />
<Compile Include="Drawing\IconContainer.cs" />
<Compile Include="Drawing\LineContainer.cs" />
@ -100,6 +111,7 @@
<Compile Include="Drawing\Fields\FieldAggregator.cs" />
<Compile Include="Drawing\MetafileContainer.cs" />
<Compile Include="Drawing\ObfuscateContainer.cs" />
<Compile Include="Drawing\FreehandContainer.cs" />
<Compile Include="Drawing\RectangleContainer.cs" />
<Compile Include="Drawing\RoundedRectangle.cs" />
<Compile Include="Drawing\Surface.cs" />
@ -112,10 +124,7 @@
<Compile Include="Forms\CaptureForm.Designer.cs">
<DependentUpon>CaptureForm.cs</DependentUpon>
</Compile>
<None Include="Forms\DestinationPickerForm.cs" />
<None Include="Forms\DestinationPickerForm.Designer.cs">
<DependentUpon>DestinationPickerForm.cs</DependentUpon>
</None>
<Compile Include="Forms\FormWithoutActivation.cs" />
<Compile Include="Forms\ImageEditorForm.cs" />
<Compile Include="Forms\ImageEditorForm.Designer.cs">
<DependentUpon>ImageEditorForm.cs</DependentUpon>
@ -142,14 +151,17 @@
<Compile Include="Forms\BugReportForm.Designer.cs">
<DependentUpon>BugReportForm.cs</DependentUpon>
</Compile>
<Compile Include="Helpers\AviHelper.cs" />
<Compile Include="Helpers\CaptureHelper.cs" />
<Compile Include="Helpers\ClipboardHelper.cs" />
<Compile Include="Helpers\Colors.cs" />
<Compile Include="Helpers\CopyData.cs" />
<Compile Include="Helpers\DrawingHelper.cs" />
<Compile Include="Helpers\GeometryHelper.cs" />
<Compile Include="Helpers\DestinationHelper.cs" />
<Compile Include="Helpers\IECaptureHelper.cs" />
<Compile Include="Helpers\AccessibleHelper.cs" />
<Compile Include="Helpers\IEInterop\IEContainer.cs" />
<Compile Include="Helpers\IEInterop\IHTMLBodyElement.cs" />
<Compile Include="Helpers\IEInterop\IHTMLCurrentStyle.cs" />
<Compile Include="Helpers\IEInterop\IHTMLElement2.cs" />
<Compile Include="Helpers\IEInterop\IHTMLFrameBase.cs" />
<Compile Include="Helpers\IEInterop\IHTMLFramesCollection2.cs" />
@ -160,7 +172,6 @@
<Compile Include="Helpers\IEInterop\IHTMLWindow4.cs" />
<Compile Include="Helpers\IEInterop\IOleWindow.cs" />
<Compile Include="Helpers\IEInterop\IServiceProvider.cs" />
<Compile Include="Helpers\ImageHelper.cs" />
<Compile Include="Helpers\IEInterop\IHTMLDocument.cs" />
<Compile Include="Helpers\IEInterop\IHTMLDocument2.cs" />
<Compile Include="Helpers\IEInterop\IHTMLDocument3.cs" />
@ -173,19 +184,29 @@
<Compile Include="Helpers\IEInterop\IHTMLWindow2.cs" />
<Compile Include="Helpers\IEInterop\IHTMLWindow3.cs" />
<Compile Include="Helpers\IEInterop\IWebBrowser2.cs" />
<None Include="Helpers\OfficeInterop\ExcelWrapper.cs" />
<Compile Include="Helpers\OfficeInterop\ExcelWrapper.cs" />
<Compile Include="Helpers\ProcessorHelper.cs" />
<Compile Include="Processors\TitleFixProcessor.cs" />
<None Include="Helpers\OfficeInterop\OutlookUtils.cs" />
<Compile Include="Helpers\WindowWrapper.cs" />
<Compile Include="Memento\AddElementMemento.cs" />
<Compile Include="Memento\ChangeFieldHolderMemento.cs" />
<Compile Include="Memento\DeleteElementMemento.cs" />
<Compile Include="Memento\TextChangeMemento.cs" />
<Compile Include="Memento\IMemento.cs" />
<Compile Include="Memento\DrawableContainerBoundsChangeMemento.cs" />
<Compile Include="Memento\SurfaceCropMemento.cs" />
<Compile Include="Helpers\OfficeInterop\OfficeWrappers.cs" />
<Compile Include="Helpers\OfficeInterop\OutlookWrapper.cs" />
<None Include="Helpers\OfficeInterop\PowerpointWrapper.cs" />
<Compile Include="Helpers\OfficeInterop\PowerpointWrapper.cs" />
<Compile Include="Helpers\OfficeInterop\WordWrapper.cs" />
<Compile Include="Helpers\QuantizerHelper.cs" />
<Compile Include="Helpers\ScreenCaptureHelper.cs" />
<Compile Include="Helpers\UpdateHelper.cs" />
<Compile Include="Helpers\WindowsHelper.cs" />
<Compile Include="Helpers\EnvironmentInfo.cs" />
<Compile Include="Helpers\GuiRectangle.cs" />
<Compile Include="Helpers\LogHelper.cs" />
<Compile Include="Helpers\MailHelper.cs" />
<Compile Include="Helpers\Objects.cs" />
<Compile Include="Helpers\PluginHelper.cs" />
<Compile Include="Helpers\PrintHelper.cs" />
<Compile Include="Helpers\ImageOutput.cs" />
@ -193,13 +214,7 @@
<Compile Include="Helpers\SoundHelper.cs" />
<Compile Include="Helpers\StartupHelper.cs" />
<Compile Include="Helpers\ToolStripItemEndisabler.cs" />
<Compile Include="Helpers\WindowCapture.cs" />
<Compile Include="UnmanagedHelpers\DWM.cs" />
<Compile Include="UnmanagedHelpers\Enumerations.cs" />
<Compile Include="UnmanagedHelpers\GDI32.cs" />
<Compile Include="UnmanagedHelpers\Kernel32.cs" />
<Compile Include="UnmanagedHelpers\Structs.cs" />
<Compile Include="UnmanagedHelpers\User32.cs" />
<Compile Include="GreenshotMain.cs" />
<EmbeddedResource Include="Forms\ImageEditorForm.resx">
<DependentUpon>ImageEditorForm.cs</DependentUpon>
</EmbeddedResource>
@ -221,6 +236,9 @@
<None Include="Languages\help-es-ES.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\help-fr-FR.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\help-hu-HU.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -230,6 +248,9 @@
<None Include="Languages\help-nl-NL.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\help-pl-PL.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\help-ru-RU.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -242,6 +263,9 @@
<None Include="Languages\help-zh-CN.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-ar-SY.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-cs-CZ.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -287,6 +311,9 @@
<None Include="Languages\language-pt-BR.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-pt-PT.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-ru-RU.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
@ -304,6 +331,9 @@
</None>
<None Include="Lib\log4net.dll" />
<None Include="log4net-debug.xml" />
<None Include="log4net-portable.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="log4net.xml">
<CopyToOutputDirectory>Never</CopyToOutputDirectory>
</None>
@ -320,8 +350,6 @@
<DependentUpon>ColorDialog.cs</DependentUpon>
</Compile>
<Compile Include="Forms\ColorDialog.cs" />
<Compile Include="UnmanagedHelpers\Win32Errors.cs" />
<Compile Include="UnmanagedHelpers\WinMM.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Drawing\Fields\Binding" />
@ -334,11 +362,13 @@
<Folder Include="Drawing" />
<Folder Include="Controls" />
<Folder Include="Helpers\IEInterop" />
<Folder Include="Memento" />
<Folder Include="Helpers\OfficeInterop" />
<Folder Include="Lib" />
<Folder Include="Languages" />
<Folder Include="UnmanagedHelpers" />
<Folder Include="Help" />
<Folder Include="Destinations" />
<Folder Include="Processors" />
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
<Name>GreenshotPlugin</Name>
@ -346,15 +376,22 @@
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<PostBuildEvent>"$(MSBuildProjectDirectory)\tools\TortoiseSVN\SubWCRev.exe" "$(MSBuildProjectDirectory)\." "$(MSBuildProjectDirectory)\releases\innosetup\setup.iss" "$(MSBuildProjectDirectory)\releases\innosetup\setup-SVN.iss"
cd "$(MSBuildProjectDirectory)\bin\Release"
"$(MSBuildProjectDirectory)\tools\FileVerifier++\fvc.exe" -c -a MD5 -r -o "checksum.MD5" *.dll *.exe
"$(MSBuildProjectDirectory)\tools\7zip\7za.exe" a -x!.SVN -r "$(MSBuildProjectDirectory)\releases\Greenshot-NO-INSTALLER.zip" "$(MSBuildProjectDirectory)\bin\Release\*" "$(MSBuildProjectDirectory)\releases\additional_files\*"
cd "$(MSBuildProjectDirectory)\releases\innosetup"
"$(MSBuildProjectDirectory)\tools\innosetup\ISCC.exe" "$(MSBuildProjectDirectory)\releases\innosetup\setup-SVN.iss"
</PostBuildEvent>
<PreBuildEvent>"$(MSBuildProjectDirectory)\tools\TortoiseSVN\SubWCRev.exe" "$(MSBuildProjectDirectory)\." "$(MSBuildProjectDirectory)\AssemblyInfo.cs.template" "$(MSBuildProjectDirectory)\AssemblyInfo.cs"
copy "$(ProjectDir)log4net.xml" "$(SolutionDir)bin\$(Configuration)\log4net.xml"</PreBuildEvent>
<PostBuildEvent>"$(MSBuildProjectDirectory)\tools\TortoiseSVN\SubWCRev.exe" "$(MSBuildProjectDirectory)\." "$(MSBuildProjectDirectory)\releases\innosetup\setup.iss" "$(MSBuildProjectDirectory)\releases\innosetup\setup-SVN.iss"
cd "$(MSBuildProjectDirectory)\bin\Release"
del *.config
del *.log
"$(MSBuildProjectDirectory)\tools\FileVerifier++\fvc.exe" -c -a MD5 -r -o "checksum.MD5" *.dll *.exe
cd "$(MSBuildProjectDirectory)\releases\innosetup"
"$(MSBuildProjectDirectory)\tools\innosetup\ISCC.exe" "$(MSBuildProjectDirectory)\releases\innosetup\setup-SVN.iss"
cd "$(MSBuildProjectDirectory)\bin\Release"
echo dummy config, used to make greenshot store the configuration in this directory &gt; greenshot.ini
move log4net-portable.xml log4net.xml
del installer.txt
del "$(MSBuildProjectDirectory)\releases\Greenshot-NO-INSTALLER.zip"
"$(MSBuildProjectDirectory)\tools\7zip\7za.exe" a -x!.SVN -r "$(MSBuildProjectDirectory)\releases\Greenshot-NO-INSTALLER.zip" "$(MSBuildProjectDirectory)\bin\Release\*" "$(MSBuildProjectDirectory)\releases\additional_files\*"
del greenshot.ini</PostBuildEvent>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
<PreBuildEvent>"$(MSBuildProjectDirectory)\tools\TortoiseSVN\SubWCRev.exe" "$(MSBuildProjectDirectory)\." "$(MSBuildProjectDirectory)\AssemblyInfo.cs.template" "$(MSBuildProjectDirectory)\AssemblyInfo.cs"

View file

@ -1,13 +1,11 @@

Microsoft Visual Studio Solution File, Format Version 10.00
# Visual Studio 2008
# SharpDevelop 3.2.0.5777
# SharpDevelop 4.1.0.8000
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotPlugin", "..\GreenshotPlugin\GreenshotPlugin.csproj", "{5B924697-4DCD-4F98-85F1-105CB84B7341}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greenshot-OCR-Plugin", "..\Greenshot-OCR-Plugin\Greenshot-OCR-Plugin.csproj", "{C6988EE8-2FEE-4349-9F09-F9628A0D8965}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greenshot-TitleFix-Plugin", "..\Greenshot-TitleFix-Plugin\Greenshot-TitleFix-Plugin.csproj", "{0A07500E-7404-48D7-8789-7EB2A23E0DD5}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotJiraPlugin", "..\GreenshotJiraPlugin\GreenshotJiraPlugin.csproj", "{19FEEF09-313F-43C7-819D-F1BCA782B08B}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotImgurPlugin", "..\GreenshotImgurPlugin\GreenshotImgurPlugin.csproj", "{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}"
@ -23,10 +21,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Greenshot", "Greenshot.cspr
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotTest", "..\GreenshotTest\GreenshotTest.csproj", "{EFD01BC7-15E5-48AD-BE68-D7B62FEEED2D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotConfluencePlugin", "..\GreenshotConfluencePlugin\GreenshotConfluencePlugin.csproj", "{C3052651-598A-44E2-AAB3-2E41311D50F9}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "GreenshotExternalCommandPlugin", "..\GreenshotExternalCommandPlugin\GreenshotExternalCommandPlugin.csproj", "{47F23C86-604E-4CC3-8767-B3D4088F30BB}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PluginExample", "..\PluginExample\PluginExample.csproj", "{6BD38118-B27F-43A1-951C-FB6464D39260}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Debug|x86 = Debug|x86
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{CD642BF4-D815-4D67-A0B5-C69F0B8231AF}.Debug|Any CPU.Build.0 = Debug|Any CPU
@ -41,10 +47,6 @@ Global
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|Any CPU.ActiveCfg = Debug|x86
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|Any CPU.Build.0 = Release|x86
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|Any CPU.ActiveCfg = Release|x86
{0A07500E-7404-48D7-8789-7EB2A23E0DD5}.Debug|Any CPU.Build.0 = Debug|x86
{0A07500E-7404-48D7-8789-7EB2A23E0DD5}.Debug|Any CPU.ActiveCfg = Debug|x86
{0A07500E-7404-48D7-8789-7EB2A23E0DD5}.Release|Any CPU.Build.0 = Release|x86
{0A07500E-7404-48D7-8789-7EB2A23E0DD5}.Release|Any CPU.ActiveCfg = Release|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Debug|Any CPU.Build.0 = Debug|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Debug|Any CPU.ActiveCfg = Debug|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|Any CPU.Build.0 = Release|x86
@ -57,5 +59,49 @@ Global
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Debug|Any CPU.ActiveCfg = Debug|x86
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Release|Any CPU.Build.0 = Release|x86
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Release|Any CPU.ActiveCfg = Release|x86
{EFD01BC7-15E5-48AD-BE68-D7B62FEEED2D}.Debug|x86.Build.0 = Debug|x86
{EFD01BC7-15E5-48AD-BE68-D7B62FEEED2D}.Debug|x86.ActiveCfg = Debug|x86
{EFD01BC7-15E5-48AD-BE68-D7B62FEEED2D}.Release|x86.Build.0 = Release|x86
{EFD01BC7-15E5-48AD-BE68-D7B62FEEED2D}.Release|x86.ActiveCfg = Release|x86
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Debug|x86.Build.0 = Debug|x86
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Debug|x86.ActiveCfg = Debug|x86
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Release|x86.Build.0 = Release|x86
{80D8DEB9-94E3-4876-8CCA-2DF1ED5F2C50}.Release|x86.ActiveCfg = Release|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Debug|x86.Build.0 = Debug|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Debug|x86.ActiveCfg = Debug|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|x86.Build.0 = Release|x86
{19FEEF09-313F-43C7-819D-F1BCA782B08B}.Release|x86.ActiveCfg = Release|x86
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|x86.Build.0 = Debug|x86
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Debug|x86.ActiveCfg = Debug|x86
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|x86.Build.0 = Release|x86
{C6988EE8-2FEE-4349-9F09-F9628A0D8965}.Release|x86.ActiveCfg = Release|x86
{5B924697-4DCD-4F98-85F1-105CB84B7341}.Debug|x86.Build.0 = Debug|x86
{5B924697-4DCD-4F98-85F1-105CB84B7341}.Debug|x86.ActiveCfg = Debug|x86
{5B924697-4DCD-4F98-85F1-105CB84B7341}.Release|x86.Build.0 = Release|x86
{5B924697-4DCD-4F98-85F1-105CB84B7341}.Release|x86.ActiveCfg = Release|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Debug|Any CPU.Build.0 = Debug|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Debug|Any CPU.ActiveCfg = Debug|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Debug|x86.Build.0 = Debug|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Debug|x86.ActiveCfg = Debug|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Release|Any CPU.Build.0 = Release|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Release|Any CPU.ActiveCfg = Release|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Release|x86.Build.0 = Release|x86
{C3052651-598A-44E2-AAB3-2E41311D50F9}.Release|x86.ActiveCfg = Release|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Debug|Any CPU.Build.0 = Debug|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Debug|Any CPU.ActiveCfg = Debug|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Debug|x86.Build.0 = Debug|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Debug|x86.ActiveCfg = Debug|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Release|Any CPU.Build.0 = Release|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Release|Any CPU.ActiveCfg = Release|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Release|x86.Build.0 = Release|x86
{47F23C86-604E-4CC3-8767-B3D4088F30BB}.Release|x86.ActiveCfg = Release|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Debug|Any CPU.Build.0 = Debug|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Debug|Any CPU.ActiveCfg = Debug|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Debug|x86.Build.0 = Debug|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Debug|x86.ActiveCfg = Debug|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Release|Any CPU.Build.0 = Release|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Release|Any CPU.ActiveCfg = Release|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Release|x86.Build.0 = Release|x86
{6BD38118-B27F-43A1-951C-FB6464D39260}.Release|x86.ActiveCfg = Release|x86
EndGlobalSection
EndGlobal

View file

@ -0,0 +1,57 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Reflection;
// Remove AppendPrivatePath warning:
#pragma warning disable 0618
namespace Greenshot {
/// <summary>
/// Description of Main.
/// </summary>
public class GreenshotMain {
private const string PAF_PATH = @"App\Greenshot";
static GreenshotMain() {
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(CurrentDomain_AssemblyResolve);
}
static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) {
Assembly ayResult = null;
string sShortAssemblyName = args.Name.Split(',')[0];
Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
foreach (Assembly ayAssembly in ayAssemblies) {
if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) {
ayResult = ayAssembly;
break;
}
}
return ayResult;
}
[STAThread]
public static void Main(string[] args) {
// Needed to make Greenshot portable, the path should be appended before the DLL's are loaded!!
AppDomain.CurrentDomain.AppendPrivatePath(PAF_PATH);
MainForm.Start(args);
}
}
}

View file

@ -67,7 +67,7 @@ namespace Greenshot.Help
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Dpi;
this.ClientSize = new System.Drawing.Size(412, 560);
this.Controls.Add(this.webBrowser1);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Icon = GreenshotPlugin.Core.GreenshotResources.getGreenshotIcon();
this.Name = "HelpBrowserForm";
this.Text = "Greenshot Help";
this.ResumeLayout(false);

View file

@ -1,264 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2011 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on Sourceforge: http://sourceforge.net/projects/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 System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using Accessibility;
using Greenshot.Helpers.IEInterop;
namespace Greenshot.Helpers {
/// <summary>
/// See: http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/03a8c835-e9e4-405b-8345-6c3d36bc8941
/// This should really be cleaned up, there is little OO behind this class!
/// Maybe move the basic Accessible functions to WindowDetails!?
/// </summary>
public class Accessible {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(Accessible));
#region Interop
private static int AccessibleObjectFromWindow(WindowDetails windowDetails, OBJID idObject, ref IAccessible acc) {
Guid guid = new Guid("{618736e0-3c3d-11cf-810c-00aa00389b71}"); // IAccessible
object obj = null;
int num = AccessibleObjectFromWindow(windowDetails.Handle, (uint)idObject, ref guid, ref obj);
acc = (IAccessible)obj;
return num;
}
[DllImport("oleacc.dll")]
public static extern int AccessibleObjectFromWindow(IntPtr hwnd, uint id, ref Guid iid, [In, Out, MarshalAs(UnmanagedType.IUnknown)] ref object ppvObject);
[DllImport("oleacc.dll")]
public static extern int AccessibleChildren(IAccessible paccContainer, int iChildStart, int cChildren, [In, Out, MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 2)] object[] rgvarChildren, out int pcObtained);
[DllImport("oleacc.dll")]
public static extern int ObjectFromLresult(int lResult, ref Guid riid, int wParam, ref IHTMLDocument2 ppvObject);
#endregion
private enum OBJID : uint {
OBJID_WINDOW = 0x00000000,
}
private const int IE_ACTIVE_TAB = 2097154;
private const int CHILDID_SELF = 0;
private IAccessible accessible;
private Accessible[] Children {
get {
int num = 0;
object[] res = GetAccessibleChildren(accessible, out num);
if (res == null) {
return new Accessible[0];
}
List<Accessible> list = new List<Accessible>(res.Length);
foreach (object obj in res) {
IAccessible acc = obj as IAccessible;
if (acc != null) {
list.Add(new Accessible(acc));
}
}
return list.ToArray();
}
}
private string Name {
get {
return accessible.get_accName(CHILDID_SELF);
}
}
private int ChildCount {
get {
return accessible.accChildCount;
}
}
public Accessible(WindowDetails windowDetails) {
AccessibleObjectFromWindow(windowDetails, OBJID.OBJID_WINDOW, ref accessible);
if (accessible == null) {
throw new Exception();
}
}
public void ActivateIETab(string tabCaptionToActivate) {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
if (tab.Name == tabCaptionToActivate) {
tab.Activate();
return;
}
}
}
}
}
public void CloseIETab(string tabCaptionToClose) {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
if (tab.Name == tabCaptionToClose) {
foreach (var CloseTab in tab.Children) {
CloseTab.Activate();
}
return;
}
}
}
}
}
public void ActivateIETab(int tabIndexToActivate) {
var index = 0;
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
if (tabIndexToActivate >= child.ChildCount -1) {
return;
}
if (index == tabIndexToActivate) {
tab.Activate();
return;
}
index++;
}
}
}
}
public string IEActiveTabUrl {
get {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
object tabIndex = tab.accessible.get_accState(CHILDID_SELF);
if ((int)tabIndex == IE_ACTIVE_TAB) {
var description = tab.accessible.get_accDescription(CHILDID_SELF);
if (!string.IsNullOrEmpty(description)) {
if (description.Contains(Environment.NewLine)) {
var url = description.Substring(description.IndexOf(Environment.NewLine)).Trim();
return url;
}
}
}
}
}
}
return String.Empty;
}
}
public int IEActiveTabIndex {
get {
var index = 0;
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
object tabIndex = tab.accessible.get_accState(0);
if ((int)tabIndex == IE_ACTIVE_TAB) {
return index;
}
index++;
}
}
}
return -1;
}
}
public string IEActiveTabCaption {
get {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
object tabIndex = tab.accessible.get_accState(0);
if ((int)tabIndex == IE_ACTIVE_TAB) {
return tab.Name;
}
}
}
}
return String.Empty;
}
}
public List<string> IETabCaptions {
get {
var captionList = new List<string>();
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
captionList.Add(tab.Name);
}
}
}
if (captionList.Count > 0) {
captionList.RemoveAt(captionList.Count - 1);
}
return captionList;
}
}
public int IETabCount {
get {
foreach (Accessible accessor in Children) {
foreach (var child in accessor.Children) {
foreach (var tab in child.Children) {
return child.ChildCount - 1;
}
}
}
return 0;
}
}
private Accessible(IAccessible acc) {
if (acc == null) {
throw new Exception();
}
accessible = acc;
}
private void Activate() {
accessible.accDoDefaultAction(CHILDID_SELF);
}
private static object[] GetAccessibleChildren(IAccessible ao, out int childs) {
childs = 0;
object[] ret = null;
int count = ao.accChildCount;
if (count > 0) {
ret = new object[count];
AccessibleChildren(ao, 0, count, ret, out childs);
}
return ret;
}
}
}

View file

@ -29,18 +29,18 @@ using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Helpers {
/// <summary>
/// Description of ClipboardHelper.
/// </summary>
public class ClipboardHelper {
public static class ClipboardHelper {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ClipboardHelper));
private static readonly Object clipboardLockObject = new Object();
private static string previousTmpFile = null;
private static readonly CoreConfiguration config = IniConfig.GetIniSection<CoreConfiguration>();
private static IntPtr nextClipboardViewer = IntPtr.Zero;
// Template for the HTML Text on the clipboard, see: http://msdn.microsoft.com/en-us/library/ms649015%28v=vs.85%29.aspx
private const string HTML_CLIPBOARD_STRING = @"Version:0.9
@ -62,51 +62,6 @@ EndSelection:<<<<<<<4
</BODY>
</HTML>";
/// <summary>
/// Register the window to monitor the clipboard
/// </summary>
/// <param name="handle">Handle for the window</param>
public static void RegisterClipboardViewer(IntPtr handle) {
LOG.Debug("RegisterClipboardViewer called");
nextClipboardViewer = User32.SetClipboardViewer(handle);
}
/// <summary>
/// Deregister the window to monitor the clipboard
/// </summary>
/// <param name="handle">Handle for the window</param>
public static void DeregisterClipboardViewer(IntPtr handle) {
LOG.Debug("DeregisterClipboardViewer called");
User32.ChangeClipboardChain(handle, nextClipboardViewer);
CleanupTmpFile();
}
/// <summary>
/// Handle WndProc messages for the clipboard
/// </summary>
/// <param name="m">Messag</param>
/// <returns>true if the message is handled</returns>
public static bool HandleClipboardMessages(ref Message m) {
switch (m.Msg) {
case (int)WindowsMessages.WM_DRAWCLIPBOARD:
// Check if there is a format "greenshot" on the clipboard, than don't delete
List<string> currentFormats = GetFormats();
if (currentFormats != null && !currentFormats.Contains("greenshot")) {
CleanupTmpFile();
}
// Make sure the next clipboard viewer gets the message
User32.SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
return true;
case (int)WindowsMessages.WM_CHANGECBCHAIN:
if (m.WParam == nextClipboardViewer) {
nextClipboardViewer = m.LParam;
} else {
User32.SendMessage(nextClipboardViewer, m.Msg, m.WParam, m.LParam);
}
return true;
}
return false;
}
/**
* Get the current "ClipboardOwner" but only if it isn't us!
*/
@ -180,11 +135,142 @@ EndSelection:<<<<<<<4
}
}
/// <summary>
/// Safe wrapper for Clipboard.ContainsText
/// Created for Bug #3432313
/// </summary>
/// <returns>boolean if there is text on the clipboard</returns>
public static bool ContainsText() {
lock (clipboardLockObject) {
int retryCount = 2;
while (retryCount >= 0) {
try {
return Clipboard.ContainsText();
} catch (Exception ee) {
if (retryCount == 0) {
string messageText = null;
string clipboardOwner = GetClipboardOwner();
ILanguage lang = Language.GetInstance();
if (clipboardOwner != null) {
messageText = String.Format(lang.GetString(LangKey.clipboard_inuse), clipboardOwner);
} else {
messageText = lang.GetString(LangKey.clipboard_error);
}
LOG.Error(messageText, ee);
} else {
Thread.Sleep(100);
}
} finally {
--retryCount;
}
}
}
return false;
}
/// <summary>
/// Safe wrapper for Clipboard.ContainsImage
/// Created for Bug #3432313
/// </summary>
/// <returns>boolean if there is an image on the clipboard</returns>
public static bool ContainsImage() {
lock (clipboardLockObject) {
int retryCount = 2;
while (retryCount >= 0) {
try {
return Clipboard.ContainsImage();
} catch (Exception ee) {
if (retryCount == 0) {
string messageText = null;
string clipboardOwner = GetClipboardOwner();
ILanguage lang = Language.GetInstance();
if (clipboardOwner != null) {
messageText = String.Format(lang.GetString(LangKey.clipboard_inuse), clipboardOwner);
} else {
messageText = lang.GetString(LangKey.clipboard_error);
}
LOG.Error(messageText, ee);
} else {
Thread.Sleep(100);
}
} finally {
--retryCount;
}
}
}
return false;
}
/// <summary>
/// Safe wrapper for Clipboard.GetImage
/// Created for Bug #3432313
/// </summary>
/// <returns>Image if there is an image on the clipboard</returns>
public static Image GetImage() {
lock (clipboardLockObject) {
int retryCount = 2;
while (retryCount >= 0) {
try {
return Clipboard.GetImage();
} catch (Exception ee) {
if (retryCount == 0) {
string messageText = null;
string clipboardOwner = GetClipboardOwner();
ILanguage lang = Language.GetInstance();
if (clipboardOwner != null) {
messageText = String.Format(lang.GetString(LangKey.clipboard_inuse), clipboardOwner);
} else {
messageText = lang.GetString(LangKey.clipboard_error);
}
LOG.Error(messageText, ee);
} else {
Thread.Sleep(100);
}
} finally {
--retryCount;
}
}
}
return null;
}
/// <summary>
/// Safe wrapper for Clipboard.GetText
/// Created for Bug #3432313
/// </summary>
/// <returns>string if there is text on the clipboard</returns>
public static string GetText() {
lock (clipboardLockObject) {
int retryCount = 2;
while (retryCount >= 0) {
try {
return Clipboard.GetText();
} catch (Exception ee) {
if (retryCount == 0) {
string messageText = null;
string clipboardOwner = GetClipboardOwner();
ILanguage lang = Language.GetInstance();
if (clipboardOwner != null) {
messageText = String.Format(lang.GetString(LangKey.clipboard_inuse), clipboardOwner);
} else {
messageText = lang.GetString(LangKey.clipboard_error);
}
LOG.Error(messageText, ee);
} else {
Thread.Sleep(100);
}
} finally {
--retryCount;
}
}
}
return null;
}
/**
* Set text to the clipboard
*/
public static void SetClipboardData(string text) {
CleanupTmpFile();
IDataObject ido = new DataObject();
ido.SetData(DataFormats.Text, true, text);
SetDataObject(ido);
@ -204,22 +290,6 @@ EndSelection:<<<<<<<4
return sb.ToString();
}
/// <summary>
/// Cleanup previously created tmp file
/// </summary>
private static void CleanupTmpFile() {
if (previousTmpFile != null) {
try {
LOG.DebugFormat("Deleting previous tmp file: {0}", previousTmpFile);
File.Delete(previousTmpFile);
} catch (Exception e) {
LOG.Warn("Error deleting " + previousTmpFile, e);
} finally {
previousTmpFile = null;
}
}
}
/**
* Set an Image to the clipboard
*
@ -233,35 +303,45 @@ EndSelection:<<<<<<<4
*/
private const int BITMAPFILEHEADER_LENGTH = 14;
public static void SetClipboardData(Image image) {
CleanupTmpFile();
DataObject ido = new DataObject();
// This will work for Office and most other applications
//ido.SetData(DataFormats.Bitmap, true, image);
MemoryStream bmpStream = new MemoryStream();
MemoryStream imageStream = new MemoryStream();
MemoryStream pngStream = new MemoryStream();
MemoryStream bmpStream = null;
MemoryStream imageStream = null;
MemoryStream pngStream = null;
try {
if (config.ClipboardFormats.Contains(ClipboardFormat.PNG)) {
pngStream = new MemoryStream();
// PNG works for Powerpoint
image.Save(pngStream, ImageFormat.Png);
// Set the PNG stream
ido.SetData("PNG", false, pngStream);
}
if (config.ClipboardFormats.Contains(ClipboardFormat.HTML)) {
bmpStream = new MemoryStream();
// Save image as BMP
image.Save(bmpStream, ImageFormat.Bmp);
imageStream = new MemoryStream();
// Copy the source, but skip the "BITMAPFILEHEADER" which has a size of 14
imageStream.Write(bmpStream.GetBuffer(), BITMAPFILEHEADER_LENGTH, (int) bmpStream.Length - BITMAPFILEHEADER_LENGTH);
// Mark the clipboard for us as "do not touch"
ido.SetData("greenshot", false, "was here!");
// Set the PNG stream
ido.SetData("PNG", false, pngStream);
// Set the DIB to the clipboard DataObject
ido.SetData(DataFormats.Dib, true, imageStream);
}
// Set the HTML
previousTmpFile = ImageOutput.SaveToTmpFile(image);
string html = getClipboardString(image, previousTmpFile);
if (config.ClipboardFormats.Contains(ClipboardFormat.HTML)) {
// Mark the clipboard for us as "do not touch"
ido.SetData("greenshot", false, "was here!");
string tmpFile = ImageOutput.SaveToTmpFile(image, OutputFormat.png, config.OutputFileJpegQuality);
string html = getClipboardString(image, tmpFile);
ido.SetText(html, TextDataFormat.Html);
}
} finally {
// we need to use the SetDataOject before the streams are closed otherwise the buffer will be gone!
// Place the DataObject to the clipboard
@ -288,7 +368,6 @@ EndSelection:<<<<<<<4
* Set Object with type Type to the clipboard
*/
public static void SetClipboardData(Type type, Object obj) {
CleanupTmpFile();
DataFormats.Format format = DataFormats.GetFormat(type.FullName);
//now copy to clipboard

View file

@ -22,11 +22,8 @@ using System;
using System.Collections.Generic;
using System.Drawing;
namespace Greenshot.Helpers
{
public class Colors {
private Colors() {}
namespace Greenshot.Helpers {
public static class Colors {
public static bool IsVisible(Color c) {
return c != null && !c.Equals(Color.Empty) && !c.Equals(Color.Transparent) && c.A > 0;
}

View file

@ -24,9 +24,10 @@ using System.Collections.Generic;
using System.IO;
using System.Runtime.InteropServices;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Windows.Forms;
using GreenshotPlugin.Core;
/// <summary>
/// Code from vbAccelerator, location:
/// http://www.vbaccelerator.com/home/NET/Code/Libraries/Windows_Messages/Simple_Interprocess_Communication/WM_COPYDATA_Demo_zip_SimpleInterprocessCommunicationsCS_CopyData_cs.asp

View file

@ -19,25 +19,31 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.IO;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Helpers {
/// <summary>
/// Description of EnvironmentInfo.
/// </summary>
public class EnvironmentInfo {
public static class EnvironmentInfo {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger("Greenshot");
private EnvironmentInfo(){}
public static string EnvironmentToString(bool newline) {
StringBuilder environment = new StringBuilder();
environment.Append("Software version: " + Application.ProductVersion);
if (IniConfig.IsPortable) {
environment.Append(" Portable");
}
environment.Append(" (" + OSInfo.Bits +" bit)");
if (newline) {
environment.AppendLine();
} else {
@ -85,8 +91,11 @@ namespace Greenshot.Helpers {
if (ex.Data != null && ex.Data.Count > 0) {
report.AppendLine();
report.AppendLine("Additional Information:");
foreach(string key in ex.Data.Keys) {
report.AppendLine(key + " = " + ex.Data[key]);
foreach(object key in ex.Data.Keys) {
object data = ex.Data[key];
if (data != null) {
report.AppendLine(key + " = " + data);
}
}
}
if (ex is ExternalException) {
@ -114,6 +123,11 @@ namespace Greenshot.Helpers {
StringBuilder exceptionText = new StringBuilder();
exceptionText.AppendLine(EnvironmentInfo.EnvironmentToString(true));
exceptionText.AppendLine(EnvironmentInfo.ExceptionToString(exception));
exceptionText.AppendLine("Configuration dump:");
using (TextWriter writer = new StringWriter(exceptionText)) {
IniConfig.SaveIniSectionToWriter(writer, IniConfig.GetIniSection<CoreConfiguration>(), true);
}
return exceptionText.ToString();
}
}

View file

@ -24,12 +24,12 @@ using System.IO;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Helpers {
public class FilenameHelper {
public static class FilenameHelper {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(FilenameHelper));
private static readonly Regex VAR_REGEXP = new Regex(@"\${(?<variable>[^:}]+)[:]?(?<parameters>[^}]*)}", RegexOptions.Compiled);
private static readonly Regex SPLIT_REGEXP = new Regex(";(?=(?:[^\"]*\"[^\"]*\")*[^\"]*$)", RegexOptions.Compiled);
@ -37,8 +37,6 @@ namespace Greenshot.Helpers {
private static CoreConfiguration conf = IniConfig.GetIniSection<CoreConfiguration>();
private const string UNSAFE_REPLACEMENT = "_";
private FilenameHelper() {
}
/// <summary>
/// Remove invalid characters from the fully qualified filename
/// </summary>
@ -106,9 +104,9 @@ namespace Greenshot.Helpers {
/// <param name="userVars">Variables from the user</param>
/// <param name="machineVars">Variables from the machine</param>
/// <returns>string with the match replacement</returns>
private static string MatchVarEvaluator(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars) {
private static string MatchVarEvaluator(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars, bool filenameSafeMode) {
try {
return MatchVarEvaluatorInternal(match, captureDetails, processVars, userVars, machineVars);
return MatchVarEvaluatorInternal(match, captureDetails, processVars, userVars, machineVars, filenameSafeMode);
} catch (Exception e) {
LOG.Error("Error in MatchVarEvaluatorInternal", e);
}
@ -121,7 +119,8 @@ namespace Greenshot.Helpers {
/// <param name="match">What are we matching?</param>
/// <param name="captureDetails">The detail, can be null</param>
/// <returns></returns>
private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars) { // some defaults
private static string MatchVarEvaluatorInternal(Match match, ICaptureDetails captureDetails, IDictionary processVars, IDictionary userVars, IDictionary machineVars, bool filenameSafeMode) {
// some defaults
int padWidth = 0;
int startIndex = 0;
int endIndex = 0;
@ -176,11 +175,23 @@ namespace Greenshot.Helpers {
}
}
if (processVars != null && processVars.Contains(variable)) {
if (filenameSafeMode) {
replaceValue = MakePathSafe((string)processVars[variable]);
} else {
replaceValue = (string)processVars[variable];
}
} else if (userVars != null && userVars.Contains(variable)) {
if (filenameSafeMode) {
replaceValue = MakePathSafe((string)userVars[variable]);
} else {
replaceValue = (string)userVars[variable];
}
} else if (machineVars != null && machineVars.Contains(variable)) {
if (filenameSafeMode) {
replaceValue = MakePathSafe((string)machineVars[variable]);
} else {
replaceValue = (string)machineVars[variable];
}
} else if (captureDetails != null && captureDetails.MetaData != null && captureDetails.MetaData.ContainsKey(variable)) {
replaceValue = MakePathSafe(captureDetails.MetaData[variable]);
} else {
@ -273,6 +284,13 @@ namespace Greenshot.Helpers {
break;
}
}
// do padding
if (padWidth >0) {
replaceValue = replaceValue.PadRight(padWidth, padChar);
} else if (padWidth < 0) {
replaceValue = replaceValue.PadLeft(-padWidth, padChar);
}
// do substring
if (startIndex != 0 || endIndex != 0) {
if (startIndex < 0) {
@ -296,12 +314,6 @@ namespace Greenshot.Helpers {
}
}
// do padding
if (padWidth >0) {
replaceValue = replaceValue.PadRight(padWidth, padChar);
} else if (padWidth < 0) {
replaceValue = replaceValue.PadLeft(-padWidth, padChar);
}
return replaceValue;
}
@ -309,8 +321,9 @@ namespace Greenshot.Helpers {
/// "Simply" fill the pattern with environment variables
/// </summary>
/// <param name="pattern">String with pattern ${var}</param>
/// <param name="filenameSafeMode">true to make sure everything is filenamesafe</param>
/// <returns>Filled string</returns>
public static string FillVariables(string pattern) {
public static string FillVariables(string pattern, bool filenameSafeMode) {
IDictionary processVars = null;
IDictionary userVars = null;
IDictionary machineVars = null;
@ -333,7 +346,7 @@ namespace Greenshot.Helpers {
}
return VAR_REGEXP.Replace(pattern,
new MatchEvaluator(delegate(Match m) { return MatchVarEvaluator(m, null, processVars, userVars, machineVars); })
new MatchEvaluator(delegate(Match m) { return MatchVarEvaluator(m, null, processVars, userVars, machineVars, filenameSafeMode); })
);
}
@ -361,7 +374,7 @@ namespace Greenshot.Helpers {
try {
return VAR_REGEXP.Replace(pattern,
new MatchEvaluator(delegate(Match m) { return MatchVarEvaluator(m, captureDetails, processVars, userVars, machineVars); })
new MatchEvaluator(delegate(Match m) { return MatchVarEvaluator(m, captureDetails, processVars, userVars, machineVars, true); })
);
} catch (Exception e) {
// adding additional data for bug tracking

View file

@ -21,29 +21,44 @@
using System;
using System.Drawing;
namespace Greenshot.Helpers
{
namespace Greenshot.Helpers {
/// <summary>
/// Description of GuiRectangle.
/// Helper class for creating rectangles with positive dimensions, regardless of input coordinates
/// </summary>
public class GuiRectangle
{
private GuiRectangle()
{
}
public static class GuiRectangle {
public static Rectangle GetGuiRectangle(int x, int y, int w, int h) {
if (w < 0) {
x = x + w;
w = -w;
}
if (h < 0) {
y = y + h;
h = -h;
}
return new Rectangle(x, y, w, h);
Rectangle rect = new Rectangle(x, y, w, h);
MakeGuiRectangle(ref rect);
return rect;
}
public static void MakeGuiRectangle(ref Rectangle rect) {
if (rect.Width < 0) {
rect.X += rect.Width;
rect.Width = -rect.Width;
}
if (rect.Height < 0) {
rect.Y += rect.Height;
rect.Height = -rect.Height;
}
}
public static RectangleF GetGuiRectangleF(float x, float y, float w, float h) {
RectangleF rect = new RectangleF(x, y, w, h);
MakeGuiRectangleF(ref rect);
return rect;
}
public static void MakeGuiRectangleF(ref RectangleF rect) {
if (rect.Width < 0) {
rect.X += rect.Width;
rect.Width = -rect.Width;
}
if (rect.Height < 0) {
rect.Y += rect.Height;
rect.Height = -rect.Height;
}
}
}
}

View file

@ -19,23 +19,18 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;
using System.Drawing.Imaging;
using System.Globalization;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using Greenshot.Helpers.IEInterop;
using Greenshot.Plugin;
using Greenshot.UnmanagedHelpers;
using GreenshotPlugin.UnmanagedHelpers;
using GreenshotPlugin.Controls;
using GreenshotPlugin.Core;
using IniFile;
namespace Greenshot.Helpers {
/// <summary>
@ -44,45 +39,22 @@ namespace Greenshot.Helpers {
/// On top I modified it to use the already available code in Greenshot.
/// Many thanks to all the people who contributed here!
/// </summary>
public class IECaptureHelper {
public static class IECaptureHelper {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(IECaptureHelper));
private static CoreConfiguration configuration = IniConfig.GetIniSection<CoreConfiguration>();
private static ILanguage language = Language.GetInstance();
// Helper method to activate a certain IE Tab
public static void ActivateIETab(WindowDetails ieWindowDetails, int tabIndex) {
WindowDetails directUIWindowDetails = GetDirectUI(ieWindowDetails);
WindowDetails directUIWindowDetails = IEHelper.GetDirectUI(ieWindowDetails);
// Bring window to the front
ieWindowDetails.Restore();
// Get accessible
Accessible ieAccessible = new Accessible(directUIWindowDetails);
Accessible ieAccessible = new Accessible(directUIWindowDetails.Handle);
// Activate Tab
ieAccessible.ActivateIETab(tabIndex);
}
/// <summary>
/// Find the DirectUI window for MSAA (Accessible)
/// </summary>
/// <param name="browserWindowDetails">The browser WindowDetails</param>
/// <returns>WindowDetails for the DirectUI window</returns>
private static WindowDetails GetDirectUI(WindowDetails browserWindowDetails) {
WindowDetails tmpWD = browserWindowDetails;
// Since IE 9 the TabBandClass is less deep!
if (IEHelper.IEVersion() < 9) {
tmpWD = tmpWD.GetChild("CommandBarClass");
if (tmpWD != null) {
tmpWD = tmpWD.GetChild("ReBarWindow32");
}
}
if (tmpWD != null) {
tmpWD = tmpWD.GetChild("TabBandClass");
}
if (tmpWD != null) {
tmpWD = tmpWD.GetChild("DirectUIHWND");;
}
return tmpWD;
}
/// <summary>
/// Simple check if IE is running
/// </summary>
@ -106,9 +78,9 @@ namespace Greenshot.Helpers {
foreach (WindowDetails ieWindow in WindowDetails.GetAllWindows("IEFrame")) {
try {
if (!ieHandleList.Contains(ieWindow.Handle)) {
WindowDetails directUIWD = GetDirectUI(ieWindow);
WindowDetails directUIWD = IEHelper.GetDirectUI(ieWindow);
if (directUIWD != null) {
Accessible accessible = new Accessible(directUIWD);
Accessible accessible = new Accessible(directUIWD.Handle);
browserWindows.Add(ieWindow, accessible.IETabCaptions);
} else {
List<string> singleWindowText = new List<string>();
@ -138,25 +110,25 @@ namespace Greenshot.Helpers {
/// <param name="browserWindowDetails">The WindowDetails to get the IHTMLDocument2 for</param>
/// <param name="document2">Ref to the IHTMLDocument2 to return</param>
/// <returns>The WindowDetails to which the IHTMLDocument2 belongs</returns>
private static DocumentContainer GetDocument() {
private static DocumentContainer GetDocument(WindowDetails activeWindow) {
DocumentContainer returnDocumentContainer = null;
WindowDetails returnWindow = null;
IHTMLDocument2 returnDocument2 = null;
// alternative if no match
WindowDetails alternativeReturnWindow = null;
IHTMLDocument2 alternativeReturnDocument2 = null;
WindowDetails activeWindow = WindowDetails.GetActiveWindow();
// Find the IE window
foreach (WindowDetails ieWindow in WindowDetails.GetAllWindows("IEFrame")) {
LOG.DebugFormat("Processing {0} - {1}", ieWindow.ClassName, ieWindow.Text);
Accessible ieAccessible = null;
WindowDetails directUIWD = GetDirectUI(ieWindow);
WindowDetails directUIWD = IEHelper.GetDirectUI(ieWindow);
if (directUIWD != null) {
ieAccessible = new Accessible(directUIWD);
ieAccessible = new Accessible(directUIWD.Handle);
}
if (ieAccessible == null) {
LOG.InfoFormat("Active Window is {0}", activeWindow.Text);
if (!ieWindow.Equals(activeWindow)) {
LOG.WarnFormat("No ieAccessible for {0}", ieWindow.Text);
continue;
@ -167,24 +139,22 @@ namespace Greenshot.Helpers {
try {
// Get the Document
IHTMLDocument2 document2 = null;
int windowMessage = User32.RegisterWindowMessage("WM_HTML_GETOBJECT");
uint windowMessage = User32.RegisterWindowMessage("WM_HTML_GETOBJECT");
if (windowMessage == 0) {
LOG.WarnFormat("Couldn't register WM_HTML_GETOBJECT");
continue;
}
WindowDetails ieServer= ieWindow.GetChild("Internet Explorer_Server");
if (ieServer == null) {
LOG.WarnFormat("No Internet Explorer_Server for {0}", ieWindow.Text);
continue;
}
LOG.DebugFormat("Trying WM_HTML_GETOBJECT on {0}", ieServer.ClassName);
int response;
User32.SendMessageTimeout(ieServer.Handle, windowMessage, 0, 0, 0x2, 1000, out response);
if (response != 0) {
Guid IID_IHTMLDocument = new Guid("626FC520-A41E-11CF-A731-00A0C9082637");
int hr = Accessible.ObjectFromLresult(response, ref IID_IHTMLDocument, 0, ref document2);
UIntPtr response;
User32.SendMessageTimeout(ieServer.Handle, windowMessage, IntPtr.Zero, IntPtr.Zero, SendMessageTimeoutFlags.SMTO_NORMAL, 1000, out response);
if (response != UIntPtr.Zero) {
document2 = (IHTMLDocument2)Accessible.ObjectFromLresult(response, typeof(IHTMLDocument).GUID, IntPtr.Zero);
if (document2 == null) {
LOG.Error("No IHTMLDocument2 found");
continue;
@ -263,10 +233,15 @@ namespace Greenshot.Helpers {
/// <param name="capture">ICapture where the capture needs to be stored</param>
/// <returns>ICapture with the content (if any)</returns>
public static ICapture CaptureIE(ICapture capture) {
BackgroundForm backgroundForm = BackgroundForm.ShowAndWait("Greenshot", language.GetString(LangKey.wait_ie_capture));
WindowDetails activeWindow = WindowDetails.GetActiveWindow();
// Show backgroundform after retrieving the active window..
BackgroundForm backgroundForm = new BackgroundForm(language.GetString(LangKey.contextmenu_captureie), language.GetString(LangKey.wait_ie_capture));
backgroundForm.Show();
//BackgroundForm backgroundForm = BackgroundForm.ShowAndWait(language.GetString(LangKey.contextmenu_captureie), language.GetString(LangKey.wait_ie_capture));
try {
//Get IHTMLDocument2 for the current active window
DocumentContainer documentContainer = GetDocument();
DocumentContainer documentContainer = GetDocument(activeWindow);
// Nothing found
if (documentContainer == null) {
@ -276,17 +251,39 @@ namespace Greenshot.Helpers {
LOG.DebugFormat("Window class {0}", documentContainer.ContentWindow.ClassName);
LOG.DebugFormat("Window location {0}", documentContainer.ContentWindow.Location);
// The URL is available unter "document2.url" and can be used to enhance the meta-data etc.
capture.CaptureDetails.AddMetaData("url", documentContainer.Url);
// bitmap to return
Bitmap returnBitmap = null;
Size pageSize = Size.Empty;
try {
returnBitmap = capturePage(documentContainer, capture);
} catch (Exception e) {
LOG.Error("Exception found, ignoring and returning nothing! Error was: ", e);
pageSize = PrepareCapture(documentContainer, capture);
returnBitmap = capturePage(documentContainer, capture, pageSize);
} catch (Exception captureException) {
LOG.Error("Exception found, ignoring and returning nothing! Error was: ", captureException);
}
// Capture the element on the page
try {
if (configuration.IEFieldCapture && capture.CaptureDetails.HasDestination("Editor")) {
// clear the current elements, as they are for the window itself
capture.Elements.Clear();
CaptureElement documentCaptureElement = documentContainer.CreateCaptureElements(pageSize);
foreach(DocumentContainer frameDocument in documentContainer.Frames) {
CaptureElement frameCaptureElement = frameDocument.CreateCaptureElements(Size.Empty);
if (frameCaptureElement != null) {
documentCaptureElement.Children.Add(frameCaptureElement);
}
}
capture.AddElement(documentCaptureElement);
// Offset the elements, as they are "back offseted" later...
Point windowLocation = documentContainer.ContentWindow.WindowRectangle.Location;
capture.MoveElements(-(capture.ScreenBounds.Location.X-windowLocation.X), -(capture.ScreenBounds.Location.Y-windowLocation.Y));
}
} catch (Exception elementsException) {
LOG.Warn("An error occurred while creating the capture elements: ", elementsException);
}
if (returnBitmap == null) {
return null;
@ -297,23 +294,29 @@ namespace Greenshot.Helpers {
// Store the location of the window
capture.Location = documentContainer.ContentWindow.Location;
// Store the title of the Page
if (documentContainer.Name != null) {
capture.CaptureDetails.Title = documentContainer.Name;
} else {
capture.CaptureDetails.Title = activeWindow.Text;
}
// Only move the mouse to correct for the capture offset
capture.MoveMouseLocation(-documentContainer.ViewportRectangle.X, -documentContainer.ViewportRectangle.Y);
// Used to be: capture.MoveMouseLocation(-(capture.Location.X + documentContainer.CaptureOffset.X), -(capture.Location.Y + documentContainer.CaptureOffset.Y));
} finally {
// Always close the background form
backgroundForm.CloseDialog();
}
return capture;
}
/// <summary>
/// Capture the actual page (document)
/// Prepare the calculates for all the frames, move and fit...
/// </summary>
/// <param name="documentContainer">The document wrapped in a container</param>
/// <returns>Bitmap with the page content as an image</returns>
private static Bitmap capturePage(DocumentContainer documentContainer, ICapture capture) {
WindowDetails contentWindowDetails = documentContainer.ContentWindow;
/// <param name="documentContainer"></param>
/// <param name="capture"></param>
/// <returns>Size of the complete page</returns>
private static Size PrepareCapture(DocumentContainer documentContainer, ICapture capture) {
// Calculate the page size
int pageWidth = documentContainer.ScrollWidth;
int pageHeight = documentContainer.ScrollHeight;
@ -390,9 +393,19 @@ namespace Greenshot.Helpers {
LOG.WarnFormat("Capture has a height of {0} which bigger than the maximum supported {1}, cutting height to the maxium", pageHeight, short.MaxValue);
pageHeight = Math.Min(pageHeight, short.MaxValue);
}
return new Size(pageWidth, pageHeight);
}
/// <summary>
/// Capture the actual page (document)
/// </summary>
/// <param name="documentContainer">The document wrapped in a container</param>
/// <returns>Bitmap with the page content as an image</returns>
private static Bitmap capturePage(DocumentContainer documentContainer, ICapture capture, Size pageSize) {
WindowDetails contentWindowDetails = documentContainer.ContentWindow;
//Create a target bitmap to draw into with the calculated page size
Bitmap returnBitmap = new Bitmap(pageWidth, pageHeight, PixelFormat.Format24bppRgb);
Bitmap returnBitmap = new Bitmap(pageSize.Width, pageSize.Height, PixelFormat.Format24bppRgb);
using (Graphics graphicsTarget = Graphics.FromImage(returnBitmap)) {
// Clear the target with the backgroundcolor
Color clearColor = documentContainer.BackgroundColor;
@ -401,7 +414,7 @@ namespace Greenshot.Helpers {
// Get the base document & draw it
drawDocument(documentContainer, contentWindowDetails, graphicsTarget);
//ParseElements(documentContainer, graphicsTarget, returnBitmap);
// Loop over the frames and clear their source area so we don't see any artefacts
foreach(DocumentContainer frameDocument in documentContainer.Frames) {
using(Brush brush = new SolidBrush(clearColor)) {
@ -411,7 +424,6 @@ namespace Greenshot.Helpers {
// Loop over the frames and capture their content
foreach(DocumentContainer frameDocument in documentContainer.Frames) {
drawDocument(frameDocument, contentWindowDetails, graphicsTarget);
//ParseElements(frameDocument, graphicsTarget, returnBitmap);
}
}
return returnBitmap;
@ -450,16 +462,24 @@ namespace Greenshot.Helpers {
//Get Browser Window Width & Height
int pageWidth = documentContainer.ScrollWidth;
int pageHeight = documentContainer.ScrollHeight;
if (pageWidth * pageHeight == 0) {
LOG.WarnFormat("Empty page for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
return;
}
//Get Screen Width & Height (this is better as the WindowDetails.ClientRectangle as the real visible parts are there!
int viewportWidth = documentContainer.ClientWidth;
int viewportHeight = documentContainer.ClientHeight;
if (viewportWidth * viewportHeight == 0) {
LOG.WarnFormat("Empty viewport for DocumentContainer {0}: {1}", documentContainer.Name, documentContainer.Url);
return;
}
// Store the current location so we can set the browser back and use it for the mouse cursor
int startLeft = documentContainer.ScrollLeft;
int startTop = documentContainer.ScrollTop;
LOG.DebugFormat("Capturing {4} with total size {0},{1} displayed in with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name);
LOG.DebugFormat("Capturing {4} with total size {0},{1} displayed with size {2},{3}", pageWidth, pageHeight, viewportWidth, viewportHeight, documentContainer.Name);
// Variable used for looping horizontally
int horizontalPage = 0;
@ -490,7 +510,7 @@ namespace Greenshot.Helpers {
try {
// cut all junk, due to IE "border" we need to remove some parts
Rectangle viewportRect = documentContainer.ViewportRectangle;
if (!Rectangle.Empty.Equals(viewportRect)) {
if (!viewportRect.IsEmpty) {
LOG.DebugFormat("Cropping to viewport: {0}", viewportRect);
ImageHelper.Crop(ref fragment, ref viewportRect);
}

View file

@ -24,8 +24,9 @@ using System.Drawing;
using System.Globalization;
using System.Runtime.InteropServices;
using Greenshot.Helpers.IEInterop;
using GreenshotPlugin.Core;
using Greenshot.Plugin;
using IniFile;
namespace Greenshot.Helpers.IEInterop {
public class ElementContainer {
@ -37,6 +38,7 @@ namespace Greenshot.Helpers.IEInterop {
public class DocumentContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(DocumentContainer));
private static CoreConfiguration configuration = IniConfig.GetIniSection<CoreConfiguration>();
private static readonly List<string> CAPTURE_TAGS = new List<string>();
private const int E_ACCESSDENIED = unchecked((int)0x80070005L);
private static Guid IID_IWebBrowserApp = new Guid("0002DF05-0000-0000-C000-000000000046");
private static Guid IID_IWebBrowser2 = new Guid("D30C1661-CDAF-11D0-8A3E-00C04FC9E26E");
@ -48,7 +50,7 @@ namespace Greenshot.Helpers.IEInterop {
private Point destinationLocation;
private Point startLocation = Point.Empty;
private Rectangle viewportRectangle = Rectangle.Empty;
private string name;
private string name = null;
private string url;
private bool isDTD;
private DocumentContainer parent;
@ -57,12 +59,37 @@ namespace Greenshot.Helpers.IEInterop {
private double zoomLevelY = 1;
private List<DocumentContainer> frames = new List<DocumentContainer>();
static DocumentContainer() {
CAPTURE_TAGS.Add("LABEL");
CAPTURE_TAGS.Add("DIV");
CAPTURE_TAGS.Add("IMG");
CAPTURE_TAGS.Add("INPUT");
CAPTURE_TAGS.Add("BUTTON");
CAPTURE_TAGS.Add("TD");
CAPTURE_TAGS.Add("TR");
CAPTURE_TAGS.Add("TH");
CAPTURE_TAGS.Add("TABLE");
CAPTURE_TAGS.Add("TBODY");
CAPTURE_TAGS.Add("SPAN");
CAPTURE_TAGS.Add("A");
CAPTURE_TAGS.Add("UL");
CAPTURE_TAGS.Add("LI");
CAPTURE_TAGS.Add("H1");
CAPTURE_TAGS.Add("H2");
CAPTURE_TAGS.Add("H3");
CAPTURE_TAGS.Add("H4");
CAPTURE_TAGS.Add("H5");
CAPTURE_TAGS.Add("FORM");
CAPTURE_TAGS.Add("FIELDSET");
}
private DocumentContainer(IHTMLWindow2 frameWindow, WindowDetails contentWindow, DocumentContainer parent) {
//IWebBrowser2 webBrowser2 = frame as IWebBrowser2;
//IHTMLDocument2 document2 = webBrowser2.Document as IHTMLDocument2;
IHTMLDocument2 document2 = GetDocumentFromWindow(frameWindow);
try {
LOG.DebugFormat("frameWindow.name {0}", frameWindow.name);
name = frameWindow.name;
} catch {
}
@ -89,7 +116,7 @@ namespace Greenshot.Helpers.IEInterop {
// element = element.offsetParent;
// } while (element != null);
// startLocation = new Point((int)x, (int)y);
Point contentWindowLocation = contentWindow.ClientRectangle.Location;
Point contentWindowLocation = contentWindow.WindowRectangle.Location;
int x = window3.screenLeft - contentWindowLocation.X;
int y = window3.screenTop - contentWindowLocation.Y;
startLocation = new Point(x, y);
@ -118,7 +145,7 @@ namespace Greenshot.Helpers.IEInterop {
} else {
isDTD = false;
}
Rectangle clientRectangle = contentWindow.ClientRectangle;
Rectangle clientRectangle = contentWindow.WindowRectangle;
try {
IHTMLWindow3 window3 = (IHTMLWindow3)document2.parentWindow;
IHTMLWindow2 window2 = (IHTMLWindow2)document2.parentWindow;
@ -164,8 +191,16 @@ namespace Greenshot.Helpers.IEInterop {
sourceLocation = new Point(ScaleX((int)startLocation.X), ScaleY((int)startLocation.Y));
destinationLocation = new Point(ScaleX((int)startLocation.X), ScaleY((int)startLocation.Y));
try {
if (name == null) {
name = document2.title;
}
} catch {
}
try {
url = document2.url;
} catch {
}
if (parent != null) {
return;
@ -322,6 +357,84 @@ namespace Greenshot.Helpers.IEInterop {
return elements;
}
/// <summary>
/// Create a CaptureElement for every element on the page, which can be used by the editor.
/// </summary>
/// <returns></returns>
public CaptureElement CreateCaptureElements(Size documentSize) {
LOG.DebugFormat("CreateCaptureElements for {0}", Name);
IHTMLElement baseElement = document3.documentElement as IHTMLElement;
IHTMLElement2 baseElement2 = baseElement as IHTMLElement2;
IHTMLRect htmlRect = baseElement2.getBoundingClientRect();
if (Size.Empty.Equals(documentSize)) {
documentSize = new Size(ScrollWidth, ScrollHeight);
}
Rectangle baseElementBounds = new Rectangle(DestinationLocation.X + htmlRect.left, DestinationLocation.Y + htmlRect.top, documentSize.Width, documentSize.Height);
if (baseElementBounds.Width <= 0 || baseElementBounds.Height <= 0) {
// not visisble
return null;
}
CaptureElement captureBaseElement = new CaptureElement(name, baseElementBounds);
foreach(IHTMLElement bodyElement in baseElement.children) {
if ("BODY".Equals(bodyElement.tagName)) {
captureBaseElement.Children.AddRange(RecurseElements(bodyElement));
}
}
return captureBaseElement;
}
/// <summary>
/// Recurse into the document tree
/// </summary>
/// <param name="parentElement">IHTMLElement we want to recurse into</param>
/// <returns>List of ICaptureElements with child elements</returns>
private List<ICaptureElement> RecurseElements(IHTMLElement parentElement) {
List<ICaptureElement> childElements = new List<ICaptureElement>();
foreach(IHTMLElement element in parentElement.children) {
string tagName = element.tagName;
// Skip elements we aren't interested in
if (!CAPTURE_TAGS.Contains(tagName)) {
continue;
}
ICaptureElement captureElement = new CaptureElement(tagName);
captureElement.Children.AddRange(RecurseElements(element));
// Get Bounds
IHTMLElement2 element2 = element as IHTMLElement2;
IHTMLRect htmlRect = element2.getBoundingClientRect();
int left = htmlRect.left;
int top = htmlRect.top;
int right = htmlRect.right;
int bottom = htmlRect.bottom;
// Offset
left += DestinationLocation.X;
top += DestinationLocation.Y;
right += DestinationLocation.X;
bottom += DestinationLocation.Y;
// Fit to floating children
foreach(ICaptureElement childElement in captureElement.Children) {
//left = Math.Min(left, childElement.Bounds.Left);
//top = Math.Min(top, childElement.Bounds.Top);
right = Math.Max(right, childElement.Bounds.Right);
bottom = Math.Max(bottom, childElement.Bounds.Bottom);
}
Rectangle bounds = new Rectangle(left, top, right-left, bottom-top);
if (bounds.Width > 0 && bounds.Height > 0) {
captureElement.Bounds = bounds;
childElements.Add(captureElement);
}
}
return childElements;
}
public Color BackgroundColor {
get {
if (document2.bgColor != null) {
@ -377,6 +490,7 @@ namespace Greenshot.Helpers.IEInterop {
public void setAttribute(string attribute, int value) {
setAttribute(attribute, value.ToString());
}
/// <summary>
/// Set/change an attribute on a document
/// </summary>

View file

@ -19,9 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
namespace Greenshot.Helpers.IEInterop {
[ComImport, Guid("3050F1D8-98B5-11CF-BB82-00AA00BDCE0B"),

View file

@ -20,8 +20,6 @@
*/
using System;
using System.Runtime.InteropServices;
using System.Runtime.InteropServices.ComTypes;
using System.Collections;
namespace Greenshot.Helpers.IEInterop {
/// <summary><para><c>IHTMLDocument</c> interface.</para></summary>

Some files were not shown because too many files have changed in this diff Show more