moved all sources to trunk directory

git-svn-id: http://svn.code.sf.net/p/greenshot/code/trunk@693 7dccd23d-a4a3-4e1f-8c07-b4c1b4018ab4
This commit is contained in:
JKlingen 2010-07-25 08:48:59 +00:00
commit a22b7578bd
392 changed files with 61489 additions and 0 deletions

View file

@ -0,0 +1,94 @@
<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>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<RootNamespace>GreenshotOCR</RootNamespace>
<AssemblyName>Greenshot-OCR-Plugin</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SourceAnalysisOverrideSettingsFile>C:\Dokumente und Einstellungen\05018085\Anwendungsdaten\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<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>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
</Reference>
<Reference Include="MODI11">
<HintPath>lib\MODI11.dll</HintPath>
</Reference>
<Reference Include="MODI12">
<HintPath>lib\MODI12.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="Language.cs" />
<Compile Include="LanguageKeys.cs" />
<Compile Include="OCRPlugin.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsForm.cs" />
<Compile Include="SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
<None Include="Languages\language_ocrplugin-de-DE.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language_ocrplugin-en-US.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language_ocrplugin-nl-NL.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="lib\MODI11.dll" />
<None Include="lib\MODI12.dll" />
<None Include="Properties\AssemblyInfo.cs.template" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
<Name>GreenshotPlugin</Name>
</ProjectReference>
<Folder Include="Languages" />
<Folder Include="lib" />
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>"$(SolutionDir)\tools\TortoiseSVN\SubWCRev.exe" "$(ProjectDir)\" "$(ProjectDir)\Properties\AssemblyInfo.cs.template" "$(ProjectDir)\Properties\AssemblyInfo.cs"</PreBuildEvent>
<PostBuildEvent>mkdir "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)"
copy "$(ProjectDir)bin\$(Configuration)\$(TargetFileName)" "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp"
copy "$(ProjectDir)bin\$(Configuration)\MODI*.dll" "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\*"
mkdir "$(SolutionDir)bin\$(Configuration)\Languages\Plugins\$(ProjectName)"
copy "$(ProjectDir)bin\$(Configuration)\Languages\*.xml" "$(SolutionDir)bin\$(Configuration)\Languages\Plugins\$(ProjectName)\"</PostBuildEvent>
</PropertyGroup>
</Project>

View file

@ -0,0 +1,47 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Diagnostics;
using System.Globalization;
using System.Resources;
using System.Threading;
using GreenshotPlugin.Core;
namespace GreenshotOCR {
/// <summary>
/// Wrapper for the language container for the Jira plugin.
/// </summary>
public class Language : LanguageContainer, ILanguage {
private static ILanguage uniqueInstance;
private const string LANGUAGE_FILENAME_PATTERN = @"language_ocrplugin-*.xml";
public static ILanguage GetInstance() {
if(uniqueInstance == null) {
uniqueInstance = new LanguageContainer();
uniqueInstance.LanguageFilePattern = LANGUAGE_FILENAME_PATTERN;
uniqueInstance.Load();
uniqueInstance.SetLanguage(Thread.CurrentThread.CurrentUICulture.Name);
}
return uniqueInstance;
}
}
}

View file

@ -0,0 +1,29 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace GreenshotOCR {
public enum LangKey {
language,
orient_image,
straighten_image
}
}

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Deutsch" ietf="de-DE" version="0.8.0">
<resources>
<resource name="language">
Sprache für OCR
</resource>
<resource name="orient_image">
Bild Orientieren
</resource>
<resource name="straighten_image">
Bild Aufrichten
</resource>
</resources>
</language>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="English" ietf="en-US" version="0.8.0">
<resources>
<resource name="language">
Language for OCR
</resource>
<resource name="orient_image">
Orient image
</resource>
<resource name="straighten_image">
Straighten image
</resource>
</resources>
</language>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Nederlands" ietf="nl-NL" version="0.8.0">
<resources>
<resource name="language">
Taal voor OCR
</resource>
<resource name="orient_image">
Beeld richten
</resource>
<resource name="straighten_image">
Beeld vereffenen
</resource>
</resources>
</language>

View file

@ -0,0 +1,322 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Windows.Forms;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
using Microsoft.Win32;
namespace GreenshotOCR {
/// <summary>
/// OCR Plugin Greenshot
/// </summary>
public class OcrPlugin : IGreenshotPlugin {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OcrPlugin));
private const string CONFIG_FILENAME = "ocr-config.properties";
private const string MODI_OFFICE11 = @"Software\Microsoft\Office\11.0\MODI";
private const string MODI_OFFICE12 = @"Software\Microsoft\Office\12.0\MODI";
private IGreenshotPluginHost host;
private ICaptureHost captureHost = null;
private PluginAttribute myAttributes;
private Properties config = new Properties();
public OcrPlugin() { }
/// <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) {
LOG.Debug("Initialize called of " + myAttributes.Name);
this.host = (IGreenshotPluginHost)host;
this.captureHost = captureHost;
this.myAttributes = myAttributes;
// Make sure the MODI-DLLs are found by adding a resolver
AppDomain.CurrentDomain.AssemblyResolve += new ResolveEventHandler(MyAssemblyResolver);
if (!HasMODI()) {
LOG.Warn("No MODI found!");
return;
}
LoadConfig();
this.host.RegisterHotKey(3, 0x2C, new HotKeyHandler(MyHotkeyHandler));
// Here we can hang ourselves to the main context menu!
ToolStripMenuItem item = new ToolStripMenuItem();
item.Text = "Region OCR";
item.ShortcutKeyDisplayString = "Ctrl + Alt + Print";
item.Click += new System.EventHandler(MainMenuClick);
ContextMenuStrip contextMenu = host.MainMenu;
bool addedItem = false;
for(int i=0; i < contextMenu.Items.Count; i++) {
if (contextMenu.Items[i].GetType() == typeof(ToolStripSeparator)) {
contextMenu.Items.Insert(i, item);
addedItem = true;
break;
}
}
if (!addedItem) {
contextMenu.Items.Add(item);
}
}
/// <summary>
/// Implementation of the IGreenshotPlugin.Shutdown
/// </summary>
public void Shutdown() {
LOG.Debug("Shutdown of " + myAttributes.Name);
}
/// <summary>
/// Implementation of the IPlugin.Configure
/// </summary>
public virtual void Configure() {
if (!HasMODI()) {
MessageBox.Show("Sorry, is seems that Microsoft Office Document Imaging (MODI) is not installed, therefor the OCR Plugin cannot work.");
return;
}
SettingsForm settingsForm = new SettingsForm(GetLanguages(),config);
DialogResult result = settingsForm.ShowDialog();
if (result == DialogResult.OK) {
config.ChangeProperty("language", settingsForm.OCRLanguage);
config.ChangeBoolProperty("orientImage", settingsForm.OrientImage);
config.ChangeBoolProperty("straightenImage", settingsForm.StraightenImage);;
SaveConfig();
}
}
/// <summary>
/// This method helps to resolve the MODI DLL files
/// </summary>
/// <param name="sender">object which is starting the resolve</param>
/// <param name="args">ResolveEventArgs describing the Assembly that needs to be found</param>
/// <returns></returns>
private Assembly MyAssemblyResolver(object sender, ResolveEventArgs args) {
string dllPath = Path.GetDirectoryName(myAttributes.DllFile);
string dllFilename = args.Name.Substring(0, args.Name.IndexOf(",")) + ".dll";
LOG.Debug("Resolving: " + dllFilename);
if (dllFilename.StartsWith("MODI")) {
return Assembly.LoadFile(Path.Combine(dllPath, dllFilename));
}
return null;
}
private void LoadConfig() {
string filename = Path.Combine(host.ConfigurationPath, CONFIG_FILENAME);
if (File.Exists(filename)) {
LOG.Debug("Loading configuration from: " + filename);
config = Properties.read(filename);
}
bool changed = false;
if (config == null) {
config = new Properties();
changed = true;
}
if (!config.ContainsKey("language")) {
config.AddProperty("language", "miLANG_ENGLISH");
changed = true;
}
if (!config.ContainsKey("straightenImage")) {
config.AddBoolProperty("straightenImage", false);
changed = true;
}
if (!config.ContainsKey("orientImage")) {
config.AddBoolProperty("orientImage", false);
changed = true;
}
if (changed) {
SaveConfig();
}
}
private void SaveConfig() {
string filename = Path.Combine(host.ConfigurationPath, CONFIG_FILENAME);
LOG.Debug("Saving configuration to: " + filename);
config.write(filename, "# The configuration file for the Greenshot OCR Plugin");
}
private void StartOCRRegion() {
LOG.Debug("Starting OCR!");
captureHost.MakeCapture(CaptureMode.Region, false, new CaptureHandler(DoOCR));
}
private void MyHotkeyHandler() {
StartOCRRegion();
}
/// <summary>
/// Is called when the OCR menu is selected
/// </summary>
/// <param name="sender">ContextMenu</param>
/// <param name="e">EventArgs from ContextMenu</param>
private void MainMenuClick(object sender, EventArgs e) {
StartOCRRegion();
}
/// <summary>
/// Handling of the CaptureTaken "event" from the ICaptureHost
/// We do the OCR here!
/// </summary>
/// <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("bmp", eventArgs.Capture.CaptureDetails);
string filePath = Path.Combine(Path.GetTempPath(),file);
using (FileStream stream = File.Create(filePath)) {
Image capturedImage = eventArgs.Capture.Image;
if (capturedImage.Width < MIN_WIDTH || capturedImage.Height < MIN_HEIGHT) {
LOG.Debug("Image not big enough, copying to bigger image");
int newWidth = Math.Max(capturedImage.Width, MIN_WIDTH);
int newHeight = Math.Max(capturedImage.Height, MIN_HEIGHT);
using (Image tmpImage = new Bitmap(newWidth, newHeight, capturedImage.PixelFormat)) {
using (Graphics graphics = Graphics.FromImage(tmpImage)) {
graphics.Clear(Color.White);
graphics.DrawImage(capturedImage, Point.Empty);
}
host.SaveToStream(tmpImage, stream, "bmp", 100);
}
} else {
host.SaveToStream(capturedImage, stream, "bmp", 100);
}
}
LOG.Debug("Saved tmp file to: " + filePath);
string text = "";
try {
switch (CheckModiVersion()) {
case ModiVersion.MODI11:
// Instantiate the MODI.Document object
MODI11.Document modi11Document = new MODI11.Document();
// The Create method grabs the picture from disk snd prepares for OCR.
modi11Document.Create(filePath);
// Add progress bar here:
//md.OnOCRProgress += ;
// Do the OCR.
modi11Document.OCR((MODI11.MiLANGUAGES)Enum.Parse(typeof(MODI11.MiLANGUAGES), config.GetProperty("language")), config.GetBoolProperty("orientImage"), config.GetBoolProperty("straightenImage"));
// Get the first (and only image)
MODI11.Image modi11Image = (MODI11.Image)modi11Document.Images[0];
// Get the layout.
MODI11.Layout modi11layout = modi11Image.Layout;
text = modi11layout.Text;
// Close the MODI.Document object.
modi11Document.Close(false);
break;
case ModiVersion.MODI12:
// Instantiate the MODI.Document object
MODI12.Document modi12Document = new MODI12.Document();
// The Create method grabs the picture from disk snd prepares for OCR.
modi12Document.Create(filePath);
// Add progress bar here:
//md.OnOCRProgress += ;
// Do the OCR.
modi12Document.OCR((MODI12.MiLANGUAGES)Enum.Parse(typeof(MODI12.MiLANGUAGES), config.GetProperty("language")), config.GetBoolProperty("orientImage"), config.GetBoolProperty("straightenImage"));
// Get the first (and only image)
MODI12.Image modi12Image = (MODI12.Image)modi12Document.Images[0];
// Get the layout.
MODI12.Layout modi12layout = modi12Image.Layout;
text = modi12layout.Text;
// Close the MODI.Document object.
modi12Document.Close(false);
break;
default:
LOG.Error("Unknown MODI version!");
break;
}
// Paste to Clipboard (the Plugin currently doesn't have access to the ClipboardHelper from Greenshot
IDataObject ido = new DataObject();
ido.SetData(DataFormats.Text, true, text);
Clipboard.SetDataObject(ido, true);
} catch (Exception e) {
string message = "A problem occured while trying to OCR the region, this plugin is still in a experimental stage!!";
LOG.Error(message, e);
MessageBox.Show(message);
} finally {
if (File.Exists(filePath)) {
LOG.Debug("Cleaning up tmp file: " + filePath);
File.Delete(filePath);
}
}
}
private string [] GetLanguages() {
string [] languages = null;
switch (CheckModiVersion()) {
case ModiVersion.MODI11:
languages = Enum.GetNames(typeof(MODI11.MiLANGUAGES));
break;
case ModiVersion.MODI12:
languages =Enum.GetNames(typeof(MODI12.MiLANGUAGES));
break;
}
return languages;
}
private enum ModiVersion { None, MODI11, MODI12 };
private ModiVersion CheckModiVersion() {
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(MODI_OFFICE11, false)) {
if (key != null) {
LOG.Debug("Found Modi V11 in registry: " + key.Name);
return ModiVersion.MODI11;
}
}
using (RegistryKey key = Registry.CurrentUser.OpenSubKey(MODI_OFFICE12, false)) {
if (key != null) {
LOG.Debug("Found Modi V12 in registry: " + key.Name);
return ModiVersion.MODI12;
}
}
return ModiVersion.None;
}
private bool HasMODI() {
return CheckModiVersion() != ModiVersion.None;
}
}
}

View file

@ -0,0 +1,54 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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/>.
*/
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Greenshot.Plugin;
#endregion
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("GreenshotOCR")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("GreenshotOCR")]
[assembly: AssemblyCopyright("Copyright 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: PluginAttribute("GreenshotOCR.OcrPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.$WCREV$")]

View file

@ -0,0 +1,138 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 GreenshotOCR
{
partial class SettingsForm
{
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
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.comboBox_languages = new System.Windows.Forms.ComboBox();
this.checkBox_orientImage = new System.Windows.Forms.CheckBox();
this.checkBox_straightenImage = new System.Windows.Forms.CheckBox();
this.label_language = new System.Windows.Forms.Label();
this.buttonOK = new System.Windows.Forms.Button();
this.buttonCancel = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// comboBox_languages
//
this.comboBox_languages.FormattingEnabled = true;
this.comboBox_languages.Items.AddRange(new object[] {
"English",
"Deutsch"});
this.comboBox_languages.Location = new System.Drawing.Point(74, 12);
this.comboBox_languages.Name = "comboBox_languages";
this.comboBox_languages.Size = new System.Drawing.Size(153, 21);
this.comboBox_languages.TabIndex = 0;
//
// checkBox_orientImage
//
this.checkBox_orientImage.Location = new System.Drawing.Point(13, 41);
this.checkBox_orientImage.Name = "checkBox_orientImage";
this.checkBox_orientImage.Size = new System.Drawing.Size(104, 24);
this.checkBox_orientImage.TabIndex = 1;
this.checkBox_orientImage.Text = "Orient image";
this.checkBox_orientImage.UseVisualStyleBackColor = true;
//
// checkBox_straightenImage
//
this.checkBox_straightenImage.Location = new System.Drawing.Point(123, 41);
this.checkBox_straightenImage.Name = "checkBox_straightenImage";
this.checkBox_straightenImage.Size = new System.Drawing.Size(109, 24);
this.checkBox_straightenImage.TabIndex = 2;
this.checkBox_straightenImage.Text = "Straighten image";
this.checkBox_straightenImage.UseVisualStyleBackColor = true;
//
// label_language
//
this.label_language.Location = new System.Drawing.Point(13, 15);
this.label_language.Name = "label_language";
this.label_language.Size = new System.Drawing.Size(55, 23);
this.label_language.TabIndex = 3;
this.label_language.Text = "Language";
//
// buttonOK
//
this.buttonOK.Location = new System.Drawing.Point(13, 72);
this.buttonOK.Name = "buttonOK";
this.buttonOK.Size = new System.Drawing.Size(104, 23);
this.buttonOK.TabIndex = 4;
this.buttonOK.Text = "OK";
this.buttonOK.UseVisualStyleBackColor = true;
this.buttonOK.Click += new System.EventHandler(this.ButtonOKClick);
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(123, 72);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(104, 23);
this.buttonCancel.TabIndex = 5;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancelClick);
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(244, 111);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.buttonOK);
this.Controls.Add(this.label_language);
this.Controls.Add(this.checkBox_straightenImage);
this.Controls.Add(this.checkBox_orientImage);
this.Controls.Add(this.comboBox_languages);
this.Name = "SettingsForm";
this.Text = "SettingsForm";
this.ResumeLayout(false);
}
private System.Windows.Forms.Label label_language;
private System.Windows.Forms.Button buttonCancel;
private System.Windows.Forms.Button buttonOK;
private System.Windows.Forms.CheckBox checkBox_orientImage;
private System.Windows.Forms.CheckBox checkBox_straightenImage;
private System.Windows.Forms.ComboBox comboBox_languages;
}
}

View file

@ -0,0 +1,99 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Windows.Forms;
using GreenshotPlugin.Core;
namespace GreenshotOCR {
/// <summary>
/// Description of SettingsForm.
/// </summary>
public partial class SettingsForm : Form {
private ILanguage language = Language.GetInstance();
private string selectedLanguage;
private bool orientImage;
private bool straightenImage;
public SettingsForm(string [] languages, Properties config) {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
language.SynchronizeLanguageToCulture();
initializeComponentText();
comboBox_languages.Items.Clear();
int index=0;
foreach(string availableLanguage in languages) {
string displayLanguage = cleanLanguage(availableLanguage);
comboBox_languages.Items.Add(displayLanguage);
if (availableLanguage.Equals(config["language"])) {
comboBox_languages.SelectedIndex = index;
}
index++;
}
checkBox_orientImage.Checked = config.GetBoolProperty("orientImage");
checkBox_straightenImage.Checked = config.GetBoolProperty("straightenImage");
}
private void initializeComponentText() {
this.label_language.Text = language.GetString(LangKey.language);
this.checkBox_orientImage.Text = language.GetString(LangKey.orient_image);
}
private string cleanLanguage(string suppliedLanguage) {
string displayLanguage = "";
if (suppliedLanguage != null) {
displayLanguage = suppliedLanguage.Replace("miLANG_","").Replace("_"," ");
displayLanguage = displayLanguage.Substring(0, 1).ToUpper() + displayLanguage.Substring(1).ToLower();
}
return displayLanguage;
}
public string OCRLanguage {
get {return selectedLanguage;}
}
public bool OrientImage {
get {return orientImage;}
}
public bool StraightenImage {
get {return straightenImage;}
}
void ButtonCancelClick(object sender, EventArgs e) {
DialogResult = DialogResult.Cancel;
}
void ButtonOKClick(object sender, EventArgs e) {
string selectedString = (string) comboBox_languages.SelectedItem;
if (selectedString != null) {
selectedLanguage = "miLANG_" + selectedString.ToUpper().Replace(" ", "_");
}
orientImage = checkBox_orientImage.Checked;
straightenImage = checkBox_straightenImage.Checked;
DialogResult = DialogResult.OK;
}
}
}

View file

@ -0,0 +1,2 @@
tlbimp Office12\MDIVWCTL.DLL /namespace:MODI12 /out:MODI12.dll
tlbimp Office11\MDIVWCTL.DLL /namespace:MODI11 /out:MODI11.dll

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View file

@ -0,0 +1,66 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Xml;
using System.Xml.Serialization;
namespace RunAtOutput {
/// <summary>
/// Description of Configuration.
/// </summary>
[XmlRoot("RunAtOutput")]
public class Configuration {
public Configuration() {
Commands = new List<Commando>();
}
[XmlElement("Commando")]
public List<Commando> Commands {
get;
set;
}
}
public class Commando {
public Commando() {
}
[XmlAttribute("Name")]
public string Name {
get;
set;
}
[XmlElement("Commandline")]
public string Commandline {
get;
set;
}
[XmlElement("Arguments")]
public string Arguments {
get;
set;
}
[XmlAttribute("Active")]
public bool Active{
get;
set;
}
}
}

View file

@ -0,0 +1,73 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{47F23C86-604E-4CC3-8767-B3D4088F30BB}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<RootNamespace>Greenshot_RunAtOutput_Plugin</RootNamespace>
<AssemblyName>Greenshot-RunAtOutput-Plugin</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SourceAnalysisOverrideSettingsFile>C:\Users\Robin\AppData\Roaming\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<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>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\Greenshot\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="Configuration.cs" />
<Compile Include="RunAtOutput.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SettingsForm.cs" />
<Compile Include="SettingsForm.Designer.cs">
<DependentUpon>SettingsForm.cs</DependentUpon>
</Compile>
<None Include="Properties\AssemblyInfo.cs.template" />
<None Include="runatoutput.properties" />
</ItemGroup>
<PropertyGroup>
<PreBuildEvent>"$(SolutionDir)\tools\TortoiseSVN\SubWCRev.exe" "$(ProjectDir)\" "$(ProjectDir)\Properties\AssemblyInfo.cs.template" "$(ProjectDir)\Properties\AssemblyInfo.cs"</PreBuildEvent>
<PostBuildEvent>mkdir "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)"
copy "$(ProjectDir)bin\$(Configuration)\$(TargetFileName)" "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp"</PostBuildEvent>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
<Name>GreenshotPlugin</Name>
</ProjectReference>
</ItemGroup>
</Project>

View file

@ -0,0 +1,53 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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/>.
*/
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Greenshot.Plugin;
#endregion
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Greenshot-RunAtOutput-Plugin")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Greenshot-RunAtOutput-Plugin")]
[assembly: AssemblyCopyright("Copyright 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
[assembly: PluginAttribute("RunAtOutput.RunAtOutputPlugin", true)]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.$WCREV$")]

View file

@ -0,0 +1,125 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace RunAtOutput {
/// <summary>
/// An Plugin to run commands after an image was written
/// </summary>
public class RunAtOutputPlugin : IGreenshotPlugin {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(RunAtOutputPlugin));
private IGreenshotPluginHost host;
private ICaptureHost captureHost = null;
private PluginAttribute myAttributes;
private Configuration config = new Configuration();
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);
LoadConfig();
}
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");
SettingsForm settingsForm = new SettingsForm(config);
if (settingsForm.ShowDialog() == DialogResult.OK) {
SaveConfig();
}
settingsForm.Dispose();
}
private void LoadConfig() {
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Configuration));
string filename = Path.Combine(host.ConfigurationPath, "RunAtOutputPlugin.xml");
if (File.Exists(filename)) {
using (TextReader reader = new StreamReader(filename)) {
config = (Configuration)xmlSerializer.Deserialize(reader);
}
}
}
private void SaveConfig() {
XmlSerializer xmlSerializer = new XmlSerializer(typeof(Configuration));
string filename = Path.Combine(host.ConfigurationPath, "RunAtOutputPlugin.xml");
using (TextWriter writer = new StreamWriter(filename)) {
xmlSerializer.Serialize(writer, config);
}
}
/// <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(Commando commando in config.Commands) {
if (commando.Active) {
if (commando.Commandline != null && commando.Commandline.Length > 0) {
Process p = new Process();
p.StartInfo.FileName = commando.Commandline;
p.StartInfo.Arguments = String.Format(commando.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

@ -0,0 +1,211 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 RunAtOutput {
partial class SettingsForm {
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Disposes resources used by the form.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing) {
if (components != null) {
components.Dispose();
}
}
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.textBox_commandline = new System.Windows.Forms.TextBox();
this.buttonCancel = new System.Windows.Forms.Button();
this.buttonOk = new System.Windows.Forms.Button();
this.label1 = new System.Windows.Forms.Label();
this.textBox_arguments = new System.Windows.Forms.TextBox();
this.label2 = new System.Windows.Forms.Label();
this.listView1 = new System.Windows.Forms.ListView();
this.columnHeader1 = new System.Windows.Forms.ColumnHeader();
this.columnHeader2 = new System.Windows.Forms.ColumnHeader();
this.button1 = new System.Windows.Forms.Button();
this.button2 = new System.Windows.Forms.Button();
this.label3 = new System.Windows.Forms.Label();
this.textBox_name = new System.Windows.Forms.TextBox();
this.SuspendLayout();
//
// textBox_commandline
//
this.textBox_commandline.Location = new System.Drawing.Point(229, 245);
this.textBox_commandline.Name = "textBox_commandline";
this.textBox_commandline.Size = new System.Drawing.Size(184, 20);
this.textBox_commandline.TabIndex = 2;
//
// buttonCancel
//
this.buttonCancel.Location = new System.Drawing.Point(339, 302);
this.buttonCancel.Name = "buttonCancel";
this.buttonCancel.Size = new System.Drawing.Size(75, 23);
this.buttonCancel.TabIndex = 7;
this.buttonCancel.Text = "Cancel";
this.buttonCancel.UseVisualStyleBackColor = true;
this.buttonCancel.Click += new System.EventHandler(this.ButtonCancelClick);
//
// buttonOk
//
this.buttonOk.Location = new System.Drawing.Point(258, 302);
this.buttonOk.Name = "buttonOk";
this.buttonOk.Size = new System.Drawing.Size(75, 23);
this.buttonOk.TabIndex = 6;
this.buttonOk.Text = "OK";
this.buttonOk.UseVisualStyleBackColor = true;
this.buttonOk.Click += new System.EventHandler(this.ButtonOkClick);
//
// label1
//
this.label1.Location = new System.Drawing.Point(153, 248);
this.label1.Name = "label1";
this.label1.Size = new System.Drawing.Size(56, 17);
this.label1.TabIndex = 3;
this.label1.Text = "Command";
//
// textBox_arguments
//
this.textBox_arguments.Location = new System.Drawing.Point(229, 271);
this.textBox_arguments.Name = "textBox_arguments";
this.textBox_arguments.Size = new System.Drawing.Size(184, 20);
this.textBox_arguments.TabIndex = 3;
//
// label2
//
this.label2.Location = new System.Drawing.Point(153, 274);
this.label2.Name = "label2";
this.label2.Size = new System.Drawing.Size(70, 17);
this.label2.TabIndex = 5;
this.label2.Text = "Arguments";
//
// listView1
//
this.listView1.CheckBoxes = true;
this.listView1.Columns.AddRange(new System.Windows.Forms.ColumnHeader[] {
this.columnHeader1,
this.columnHeader2});
this.listView1.FullRowSelect = true;
this.listView1.Location = new System.Drawing.Point(13, 13);
this.listView1.MultiSelect = false;
this.listView1.Name = "listView1";
this.listView1.Size = new System.Drawing.Size(400, 183);
this.listView1.Sorting = System.Windows.Forms.SortOrder.Ascending;
this.listView1.TabIndex = 0;
this.listView1.UseCompatibleStateImageBehavior = false;
this.listView1.View = System.Windows.Forms.View.Details;
this.listView1.ItemChecked += new System.Windows.Forms.ItemCheckedEventHandler(this.ListView1ItemChecked);
this.listView1.SelectedIndexChanged += new System.EventHandler(this.ListView1ItemSelectionChanged);
//
// columnHeader1
//
this.columnHeader1.Text = "Active";
//
// columnHeader2
//
this.columnHeader2.Text = "Name";
this.columnHeader2.Width = 311;
//
// button1
//
this.button1.Location = new System.Drawing.Point(13, 202);
this.button1.Name = "button1";
this.button1.Size = new System.Drawing.Size(75, 23);
this.button1.TabIndex = 4;
this.button1.Text = "Add";
this.button1.UseVisualStyleBackColor = true;
this.button1.Click += new System.EventHandler(this.ButtonAddClick);
//
// button2
//
this.button2.Location = new System.Drawing.Point(12, 231);
this.button2.Name = "button2";
this.button2.Size = new System.Drawing.Size(75, 23);
this.button2.TabIndex = 5;
this.button2.Text = "Delete";
this.button2.UseVisualStyleBackColor = true;
this.button2.Click += new System.EventHandler(this.ButtonDeleteClick);
//
// label3
//
this.label3.Location = new System.Drawing.Point(154, 222);
this.label3.Name = "label3";
this.label3.Size = new System.Drawing.Size(56, 17);
this.label3.TabIndex = 10;
this.label3.Text = "Name";
//
// textBox_name
//
this.textBox_name.Location = new System.Drawing.Point(230, 219);
this.textBox_name.Name = "textBox_name";
this.textBox_name.Size = new System.Drawing.Size(184, 20);
this.textBox_name.TabIndex = 1;
//
// SettingsForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(426, 336);
this.Controls.Add(this.label3);
this.Controls.Add(this.textBox_name);
this.Controls.Add(this.button2);
this.Controls.Add(this.button1);
this.Controls.Add(this.listView1);
this.Controls.Add(this.label2);
this.Controls.Add(this.textBox_arguments);
this.Controls.Add(this.label1);
this.Controls.Add(this.buttonOk);
this.Controls.Add(this.buttonCancel);
this.Controls.Add(this.textBox_commandline);
this.Name = "SettingsForm";
this.Text = "Command Editor";
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.TextBox textBox_name;
private System.Windows.Forms.Label label3;
private System.Windows.Forms.Button button2;
private System.Windows.Forms.Button button1;
private System.Windows.Forms.ColumnHeader columnHeader2;
private System.Windows.Forms.ColumnHeader columnHeader1;
private System.Windows.Forms.ListView listView1;
private System.Windows.Forms.TextBox textBox_arguments;
private System.Windows.Forms.Label label2;
private System.Windows.Forms.TextBox textBox_commandline;
private System.Windows.Forms.Label label1;
private System.Windows.Forms.Button buttonOk;
private System.Windows.Forms.Button buttonCancel;
}
}

View file

@ -0,0 +1,98 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 RunAtOutput {
/// <summary>
/// Description of SettingsForm.
/// </summary>
public partial class SettingsForm : Form {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(SettingsForm));
private Configuration config;
public SettingsForm(Configuration config) {
this.config = config;
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
UpdateView();
}
void ButtonOkClick(object sender, EventArgs e) {
DialogResult = DialogResult.OK;
}
void ButtonCancelClick(object sender, EventArgs e) {
DialogResult = DialogResult.Cancel;
}
void ShowSelectedItem() {
foreach ( ListViewItem item in listView1.SelectedItems ) {
Commando commando = item.Tag as Commando;
textBox_arguments.Text = commando.Arguments;
textBox_commandline.Text = commando.Commandline;
textBox_name.Text = commando.Name;
}
}
void ButtonAddClick(object sender, EventArgs e) {
Commando commando = new Commando();
commando.Arguments = textBox_arguments.Text;
commando.Commandline = textBox_commandline.Text;
commando.Name = textBox_name.Text;
config.Commands.Add(commando);
UpdateView();
}
void ButtonDeleteClick(object sender, EventArgs e) {
foreach ( ListViewItem item in listView1.SelectedItems ) {
Commando commando = item.Tag as Commando;
config.Commands.Remove(commando);
}
UpdateView();
}
void UpdateView() {
listView1.Items.Clear();
foreach(Commando commando in config.Commands) {
ListViewItem item = new ListViewItem("");
item.SubItems.Add(commando.Name);
item.Checked = commando.Active;
item.Tag = commando;
listView1.Items.Add(item);
}
}
void ListView1ItemSelectionChanged(object sender, EventArgs e) {
ShowSelectedItem();
}
void ListView1ItemChecked(object sender, ItemCheckedEventArgs e) {
Commando commando = e.Item.Tag as Commando;
LOG.Debug("ItemChecked " + commando.Name + " to " + e.Item.Checked);
commando.Active = e.Item.Checked;
}
}
}

View file

@ -0,0 +1,4 @@
active=OptiPNG,Paint.NET
command.Paint.NET=C:\Programme\Paint.NET\PaintDotNet.exe {0}
pattern.OptiPNG=*.png
command.OptiPNG=D:\05018085\downloads\optipng-0.6.4-exe\optipng.exe {0}

View file

@ -0,0 +1,127 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 FixTitle {
/// <summary>
/// An example Plugin so developers can see how they can develop their own plugin
/// </summary>
public class FixTitle : IGreenshotPlugin {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(FixTitle));
private const string CONFIG_FILE_NAME = "titlefix.properties";
private const string ACTIVE_PROPERTY = "active";
private const string REGEXP_PROPERTY = ".regexp";
private const string REPLACE_PROPERTY = ".replace";
private IGreenshotPluginHost host;
private ICaptureHost captureHost = null;
private PluginAttribute myAttributes;
private Properties config = null;
public FixTitle() {
}
/// <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;
LoadConfig();
if (config != null) {
this.host.OnCaptureTaken += new OnCaptureTakenHandler(CaptureTaken);
} else {
LOG.Warn("Not registering FixTitle plugin due to missing configuration");
}
}
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.GetPropertyAsArray(ACTIVE_PROPERTY)) {
string regexpString = config.GetProperty(titleIdentifier + REGEXP_PROPERTY);
string replaceString = config.GetProperty(titleIdentifier + REPLACE_PROPERTY);
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;
}
private void LoadConfig() {
string configfilename = Path.Combine(host.ConfigurationPath, CONFIG_FILE_NAME);
if (File.Exists(configfilename)) {
config = Properties.read(configfilename);
} else {
config = new Properties();
}
// Check if we have a configuration
if (!config.ContainsKey(ACTIVE_PROPERTY)) {
// Create default with FireFox
config.AddProperty("Firefox"+REGEXP_PROPERTY, " - Mozilla Firefox.*");
config.AddProperty("Firefox"+REPLACE_PROPERTY, "");
// and IE
config.AddProperty("IE"+REGEXP_PROPERTY, " - Microsoft Internet Explorer.*");
config.AddProperty("IE"+REPLACE_PROPERTY, "");
// Activate both
config.AddProperty(ACTIVE_PROPERTY, "IE,Firefox");
config.write(configfilename);
}
}
}
}

View file

@ -0,0 +1,66 @@
<Project ToolsVersion="3.5" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<ProjectGuid>{0A07500E-7404-48D7-8789-7EB2A23E0DD5}</ProjectGuid>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">x86</Platform>
<OutputType>Library</OutputType>
<RootNamespace>Greenshot_TitleFix_Plugin</RootNamespace>
<AssemblyName>Greenshot-TitleFix-Plugin</AssemblyName>
<TargetFrameworkVersion>v2.0</TargetFrameworkVersion>
<AppDesignerFolder>Properties</AppDesignerFolder>
<SourceAnalysisOverrideSettingsFile>C:\Dokumente und Einstellungen\05018085\Anwendungsdaten\ICSharpCode/SharpDevelop3.0\Settings.SourceAnalysis</SourceAnalysisOverrideSettingsFile>
<AllowUnsafeBlocks>False</AllowUnsafeBlocks>
<NoStdLib>False</NoStdLib>
<WarningLevel>4</WarningLevel>
<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>
<DebugType>Full</DebugType>
<Optimize>False</Optimize>
<CheckForOverflowUnderflow>True</CheckForOverflowUnderflow>
<DefineConstants>DEBUG;TRACE</DefineConstants>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)' == 'Release' ">
<OutputPath>bin\Release\</OutputPath>
<DebugSymbols>False</DebugSymbols>
<DebugType>None</DebugType>
<Optimize>True</Optimize>
<CheckForOverflowUnderflow>False</CheckForOverflowUnderflow>
<DefineConstants>TRACE</DefineConstants>
</PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup>
<Reference Include="log4net">
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.Windows.Forms" />
</ItemGroup>
<ItemGroup>
<Compile Include="FixTitle.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<None Include="Properties\AssemblyInfo.cs.template" />
</ItemGroup>
<PropertyGroup>
<PostBuildEvent>mkdir "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)"
copy "$(ProjectDir)bin\$(Configuration)\$(TargetFileName)" "$(SolutionDir)bin\$(Configuration)\Plugins\$(ProjectName)\*.gsp"
</PostBuildEvent>
<PreBuildEvent>"$(SolutionDir)\tools\TortoiseSVN\SubWCRev.exe" "$(SolutionDir)\" "$(ProjectDir)\Properties\AssemblyInfo.cs.template" "$(ProjectDir)\Properties\AssemblyInfo.cs"</PreBuildEvent>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\GreenshotPlugin\GreenshotPlugin.csproj">
<Project>{5B924697-4DCD-4F98-85F1-105CB84B7341}</Project>
<Name>GreenshotPlugin</Name>
</ProjectReference>
</ItemGroup>
</Project>

View file

@ -0,0 +1,54 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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/>.
*/
#region Using directives
using System;
using System.Reflection;
using System.Runtime.InteropServices;
using Greenshot.Plugin;
#endregion
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Greenshot-TitleFix-Plugin")]
[assembly: AssemblyDescription("A plugin to fix captured Window Titles")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Greenshot-TitleFix-Plugin")]
[assembly: AssemblyCopyright("Copyright 2010")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// The PluginAttribute describes the "entryType" and if the plugin is configurable
[assembly: PluginAttribute("FixTitle.FixTitle", false)]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// You can specify all the values or you can use the default the Revision and
// Build Numbers by using the '*' as shown below:
[assembly: AssemblyVersion("1.0.0.$WCREV$")]

51
Greenshot/AssemblyInfo.cs Normal file
View file

@ -0,0 +1,51 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly: AssemblyTitle("Greenshot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Greenshot")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// 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.0.0")]

View file

@ -0,0 +1,51 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// Information about this assembly is defined by the following
// attributes.
//
// change them to the information which is associated with the assembly
// you compile.
[assembly: AssemblyTitle("Greenshot")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Greenshot")]
[assembly: AssemblyCopyright("")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// This sets the default COM visibility of types in the assembly to invisible.
// If you need to expose a type to COM, use [ComVisible(true)] on that type.
[assembly: ComVisible(false)]
// The assembly version has following format :
//
// Major.Minor.Build.Revision
//
// 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.0.$WCREV$")]

View file

@ -0,0 +1,320 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
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.Threading;
using System.Windows.Forms;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using GreenshotPlugin.Core;
namespace Greenshot.Configuration {
public enum ScreenshotDestinations {Editor=1, FileDefault=2, FileWithDialog=4, Clipboard=8, Printer=16, EMail=32}
/// <summary>
/// AppConfig is used for loading and saving the configuration. All public fields
/// in this class are serialized with the BinaryFormatter and then saved to the
/// config file. After loading the values from file, SetDefaults iterates over
/// all public fields an sets fields set to null to the default value.
/// </summary>
[Serializable]
public class AppConfig {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(AppConfig));
//private static string loc = Assembly.GetExecutingAssembly().Location;
//private static string oldFilename = Path.Combine(loc.Substring(0,loc.LastIndexOf(@"\")),"config.dat");
private const string CONFIG_FILE_NAME = "config.dat";
private static string configfilepath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),@"Greenshot\");
private static AppConfig instance = null;
public Dictionary<string, object> LastUsedFieldValues = new Dictionary<string, object>();
// the configuration part - all public vars are stored in the config file
// don't use "null" and "0" as default value!
#region general application config
public bool? General_RegisterHotkeys = true;
public bool? General_IsFirstLaunch = true;
#endregion
#region capture config
public bool? Capture_Mousepointer = true;
public bool? Capture_Windows_Interactive = false;
public int Capture_Wait_Time = 100;
public bool? Capture_Complete_Window = false;
public bool? Capture_Window_Content = false;
#endregion
#region user interface config
public string Ui_Language = "";
public bool? Ui_Effects_Flashlight = false;
public bool? Ui_Effects_CameraSound = true;
#endregion
#region output config
public ScreenshotDestinations Output_Destinations = ScreenshotDestinations.Editor;
public string Output_File_Path = Environment.GetFolderPath(Environment.SpecialFolder.Desktop);
public string Output_File_FilenamePattern = "%title%_%YYYY%-%MM%-%DD%_%hh%-%mm%-%ss%";
public string Output_File_Format = ImageFormat.Png.ToString();
public bool? Output_File_CopyPathToClipboard = false;
public int Output_File_JpegQuality = 80;
public bool? Output_File_PromptJpegQuality = false;
public int Output_File_IncrementingNumber = 1;
public string Output_FileAs_Fullpath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"dummy.png");
public bool? Output_Print_PromptOptions = true;
public bool? Output_Print_AllowRotate = true;
public bool? Output_Print_AllowEnlarge = true;
public bool? Output_Print_AllowShrink = true;
public bool? Output_Print_Center = true;
public bool? Output_Print_Timestamp = true;
#endregion
#region editor config
public Size Editor_WindowSize = new Size(540, 380);
public Point Editor_WindowLocation = new Point(100, 100);
public String Editor_WindowState = "Normal";
public Rectangle Editor_Previous_Screenbounds = Rectangle.Empty;
public Color[] Editor_RecentColors = new Color[12];
public Font Editor_Font = null;
#endregion
/// <summary>
/// a private constructor because this is a singleton
/// </summary>
private AppConfig() {
}
/// <summary>
/// get an instance of AppConfig
/// </summary>
/// <returns></returns>
public static AppConfig GetInstance() {
if (instance == null) {
instance = Load();
}
return instance;
}
public static void Reload() {
AppConfig newInstance = Load();
instance.Copy(newInstance);
}
/// <summary>
/// loads the configuration from the config file
/// </summary>
/// <returns>an instance of AppConfig with all values set from the config file</returns>
private static AppConfig Load() {
AppConfig conf;
CheckConfigFile();
string configfilename = Path.Combine(configfilepath, CONFIG_FILE_NAME);
try {
LOG.Debug("Loading configuration from: " + configfilename);
using (FileStream fileStream = File.Open(configfilename, FileMode.Open, FileAccess.Read)) {
BinaryFormatter binaryFormatter = new BinaryFormatter();
conf = (AppConfig) binaryFormatter.Deserialize(fileStream);
}
conf.SetDefaults();
return conf;
} catch (SerializationException e) {
LOG.Error("Problem loading configuration from: " + configfilename, e);
AppConfig config = new AppConfig();
config.Store();
return config;
} catch (Exception e) {
LOG.Error("Problem loading configuration from: " + configfilename, e);
MessageBox.Show(String.Format("Could not load Greenshot's configuration file. Please check access permissions for '{0}'.\n",configfilename),"Error");
Process.GetCurrentProcess().Kill();
}
return null;
}
/// <summary>
/// Checks for the existence of a configuration file.
/// First in greenshot's Applicationdata folder (where it is stored since 0.6),
/// then (if it cannot be found there) in greenshot's program directory (where older
/// versions might have stored it).
/// If the latter is the case, the file is moved to the new location, so that a user does not lose
/// their configuration after upgrading.
/// If there is no file in both locations, a virgin config file is created.
/// </summary>
private static void CheckConfigFile() {
// check if file is in the same location as started from, if this is the case
// we will use this file instead of the Applicationdate folder
// Done for Feature Request #2741508
if (File.Exists(Path.Combine(Application.StartupPath, CONFIG_FILE_NAME))) {
configfilepath = Application.StartupPath;
} else if (!File.Exists(Path.Combine(configfilepath, CONFIG_FILE_NAME))) {
Directory.CreateDirectory(configfilepath);
new AppConfig().Store();
}
}
/// <summary>
/// saves the configuration values to the supplied config file
/// </summary>
public void Store() {
Store(configfilepath);
}
/// <summary>
/// saves the configuration values to the config path
/// </summary>
public void Store(string configpath) {
string configfilename = Path.Combine(configpath, CONFIG_FILE_NAME);
try {
LOG.Debug("Saving configuration to: " + configfilename);
using (FileStream fileStream = File.Open(configfilename, FileMode.Create)) {
BinaryFormatter formatter = new BinaryFormatter();
formatter.Serialize(fileStream, this);
}
} catch (UnauthorizedAccessException e) {
LOG.Error("Problem saving configuration to: " + configfilename, e);
MessageBox.Show(Language.GetInstance().GetFormattedString(LangKey.config_unauthorizedaccess_write,configfilename),Language.GetInstance().GetString(LangKey.error));
}
}
/// <summary>
/// when new fields are added to this class, they are instanced
/// with null by default. this method iterates over all public
/// fields and uses reflection to set them to the proper default value.
/// </summary>
public void SetDefaults() {
Type type = this.GetType();
FieldInfo[] fieldInfos = type.GetFields();
foreach (FieldInfo fi in fieldInfos) {
object o = fi.GetValue(this);
int i;
if (o == null || (int.TryParse(o.ToString(), out i) && i == 0)) {
// found field with value null. setting to default.
AppConfig tmpConf = new AppConfig();
Type tmpType = tmpConf.GetType();
FieldInfo defaultField = tmpType.GetField(fi.Name);
fi.SetValue(this, defaultField.GetValue(tmpConf));
}
}
}
private void Copy(AppConfig newConfig) {
Type type = this.GetType();
// Copy fields
FieldInfo[] fieldInfos = type.GetFields();
foreach (FieldInfo fi in fieldInfos) {
object newValue = fi.GetValue(newConfig);
fi.SetValue(this, newValue);
}
// Update language
if (newConfig.Ui_Language != null && !newConfig.Ui_Language.Equals(Language.GetInstance().CurrentLanguage)) {
string newLang = Language.GetInstance().SetLanguage(newConfig.Ui_Language);
// check if the language was not wat was supplied (near match)
if (newConfig.Ui_Language.Equals(newLang)) {
// Store change
this.Store();
}
}
}
public static Properties GetAvailableProperties() {
Properties properties = new Properties();
Type type = typeof(AppConfig);
FieldInfo[] fieldInfos = type.GetFields();
foreach (FieldInfo fi in fieldInfos) {
Type fieldType = fi.FieldType;
if (fieldType.IsGenericType && fieldType.GetGenericTypeDefinition().Equals(typeof(Nullable<>))) {
// We are dealing with a generic type that is nullable
fieldType = Nullable.GetUnderlyingType(fieldType);
}
if (fieldType == typeof(string) || fieldType == typeof(bool) || fieldType == typeof(int)) {
properties.AddProperty(fi.Name, fieldType.Name);
}
}
return properties;
}
public void SetProperties(Properties properties) {
Type type = this.GetType();
FieldInfo[] fieldInfos = type.GetFields();
foreach(string key in properties.Keys) {
FieldInfo currentField = type.GetField(key);
if (currentField != null) {
object currentValue = currentField.GetValue(this);
LOG.Debug("Before: " + currentField.Name + "=" + currentValue);
if (currentField.FieldType == typeof(string)) {
currentField.SetValue(this, properties.GetProperty(key));
} else if (currentField.FieldType == typeof(bool) ||currentField.FieldType == typeof(bool?)) {
currentField.SetValue(this, properties.GetBoolProperty(key));
} else if (currentField.FieldType == typeof(int) || currentField.FieldType == typeof(int?)) {
currentField.SetValue(this, properties.GetIntProperty(key));
}
LOG.Debug("After: " + currentField.Name + "=" + currentField.GetValue(this));
} else {
LOG.Warn("Configuration for " + key + " not found! (Incorrect key?)");
}
}
}
public void UpdateLastUsedFieldValue(Field f) {
if(f.Value != null) {
string key = GetKeyForField(f);
LastUsedFieldValues[key] = f.Value;
}
}
public Field GetLastUsedValueForField(Field f, object preferredDefaultValue) {
string key = GetKeyForField(f);
if(LastUsedFieldValues.ContainsKey(key)) {
f.Value = LastUsedFieldValues[key];
} else if(preferredDefaultValue != null) {
f.Value = preferredDefaultValue;
}else {
f.Value = f.FieldType.DefaultValue;
}
return f;
}
/// <param name="f"></param>
/// <returns></returns>
/// <param name="f"></param>
/// <returns>the key under which last used value for the Field can be stored/retrieved</returns>
private string GetKeyForField(Field f) {
if(f.Scope == null) {
return f.FieldType.Name;
} else {
return f.FieldType.Name + "-" + f.Scope;
}
}
}
}

View file

@ -0,0 +1,51 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Globalization;
using System.IO;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using System.Xml;
using GreenshotPlugin.Core;
namespace Greenshot.Configuration {
/// <summary>
/// Wrapper for the language container for the Greenshot base.
/// </summary>
public class Language : LanguageContainer, ILanguage {
private static ILanguage uniqueInstance;
private const string LANGUAGE_FILENAME_PATTERN = @"language-*.xml";
public static ILanguage GetInstance() {
if(uniqueInstance == null) {
uniqueInstance = new LanguageContainer();
uniqueInstance.LanguageFilePattern = LANGUAGE_FILENAME_PATTERN;
uniqueInstance.Load();
uniqueInstance.SetLanguage(AppConfig.GetInstance().Ui_Language);
Thread.CurrentThread.CurrentUICulture = new CultureInfo(uniqueInstance.CurrentLanguage);
}
return uniqueInstance;
}
}
}

View file

@ -0,0 +1,191 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Configuration {
public enum LangKey {
about_bugs,
about_donations,
about_host,
about_icons,
about_license,
about_title,
about_translation,
application_title,
bugreport_cancel,
bugreport_info,
bugreport_title,
clipboard_error,
clipboard_inuse,
colorpicker_alpha,
colorpicker_apply,
colorpicker_blue,
colorpicker_green,
colorpicker_htmlcolor,
colorpicker_recentcolors,
colorpicker_red,
colorpicker_title,
colorpicker_transparent,
config_unauthorizedaccess_write,
contextmenu_about,
contextmenu_capturearea,
contextmenu_captureclipboard,
contextmenu_capturefullscreen,
contextmenu_capturelastregion,
contextmenu_capturewindow,
contextmenu_donate,
contextmenu_exit,
contextmenu_help,
contextmenu_openfile,
contextmenu_quicksettings,
contextmenu_settings,
editor_arrange,
editor_arrowheads,
editor_arrowheads_both,
editor_arrowheads_end,
editor_arrowheads_none,
editor_arrowheads_start,
editor_backcolor,
editor_blur_radius,
editor_bold,
editor_brightness,
editor_cancel,
editor_clipboardfailed,
editor_close,
editor_close_on_save,
editor_close_on_save_title,
editor_confirm,
editor_copyimagetoclipboard,
editor_copypathtoclipboard,
editor_copytoclipboard,
editor_crop,
editor_cursortool,
editor_cuttoclipboard,
editor_deleteelement,
editor_downonelevel,
editor_downtobottom,
editor_drawarrow,
editor_drawellipse,
editor_drawhighlighter,
editor_drawline,
editor_drawrectangle,
editor_drawtextbox,
editor_duplicate,
editor_edit,
editor_email,
editor_file,
editor_fontsize,
editor_forecolor,
editor_highlight_area,
editor_highlight_grayscale,
editor_highlight_mode,
editor_highlight_text,
editor_highlight_magnify,
editor_pixel_size,
editor_imagesaved,
editor_italic,
editor_load_objects,
editor_magnification_factor,
editor_obfuscate,
editor_obfuscate_blur,
editor_obfuscate_mode,
editor_obfuscate_pixelize,
editor_object,
editor_opendirinexplorer,
editor_pastefromclipboard,
editor_preview_quality,
editor_print,
editor_save,
editor_save_objects,
editor_saveas,
editor_selectall,
editor_senttoprinter,
editor_shadow,
editor_storedtoclipboard,
editor_thickness,
editor_title,
editor_uponelevel,
editor_uptotop,
error,
error_multipleinstances,
error_nowriteaccess,
error_openfile,
error_openlink,
error_save,
help_title,
jpegqualitydialog_choosejpegquality,
jpegqualitydialog_dontaskagain,
jpegqualitydialog_title,
print_error,
printoptions_allowcenter,
printoptions_allowenlarge,
printoptions_allowrotate,
printoptions_allowshrink,
printoptions_dontaskagain,
printoptions_timestamp,
printoptions_title,
quicksettings_destination_file,
settings_alwaysshowjpegqualitydialog,
settings_alwaysshowprintoptionsdialog,
settings_applicationsettings,
settings_autostartshortcut,
settings_capture,
settings_capture_mousepointer,
settings_capture_windows_interactive,
settings_capture_window_full,
settings_capture_window_content,
settings_copypathtoclipboard,
settings_destination,
settings_destination_clipboard,
settings_destination_editor,
settings_destination_email,
settings_destination_file,
settings_destination_fileas,
settings_destination_printer,
settings_filenamepattern,
settings_general,
settings_jpegquality,
settings_jpegsettings,
settings_language,
settings_message_filenamepattern,
settings_output,
settings_playsound,
settings_preferredfilesettings,
settings_primaryimageformat,
settings_printer,
settings_printoptions,
settings_registerhotkeys,
settings_showflashlight,
settings_skipimageeditor,
settings_storagelocation,
settings_title,
settings_tooltip_filenamepattern,
settings_tooltip_language,
settings_tooltip_primaryimageformat,
settings_tooltip_registerhotkeys,
settings_tooltip_storagelocation,
settings_visualization,
settings_waittime,
tooltip_firststart,
warning,
warning_hotkeys
}
}

View file

@ -0,0 +1,37 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Drawing.Imaging;
using System.Drawing;
using System.Windows.Forms;
using System;
namespace Greenshot.Configuration {
/// <summary>
/// Greenshot's runtime configuration
/// abstract, all properties are public and static
/// </summary>
public abstract class RuntimeConfig {
public static string[] SupportedLanguages = {"en-US","de-DE"};
public static string[] SupportedImageFormats = {ImageFormat.Jpeg.ToString(),ImageFormat.Gif.ToString(),ImageFormat.Png.ToString(),ImageFormat.Bmp.ToString()};
public static string BugTrackerUrl = "https://sourceforge.net/tracker/?func=postadd&group_id=191585&atid=937972&summary=%SUMMARY%&details=%DETAILS%";
public static Rectangle LastCapturedRegion = Rectangle.Empty;
}
}

View file

@ -0,0 +1,41 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
/// <summary>
/// Description of BindableToolStripButton.
/// </summary>
public class BindableToolStripButton : ToolStripButton, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public BindableToolStripButton() :base() {
this.CheckedChanged += new EventHandler(BindableToolStripButton_CheckedChanged);
}
void BindableToolStripButton_CheckedChanged(object sender, EventArgs e) {
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Checked"));
}
}
}

View file

@ -0,0 +1,44 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
/// <summary>
/// A simple ToolStripComboBox implementing INotifyPropertyChanged for data binding
/// </summary>
public class BindableToolStripComboBox : ToolStripComboBox, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public BindableToolStripComboBox() :base() {
this.SelectedIndexChanged += new EventHandler(BindableToolStripComboBox_SelectedIndexChanged);
}
void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e) {
if(PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
}
}
}
}

View file

@ -0,0 +1,68 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
/// <summary>
/// A simple ToolStripDropDownButton implementing INotifyPropertyChanged for data binding.
/// Also, when a DropDownItem is selected, the DropDownButton adops its Tag and Image.
/// The selected tag can be accessed via SelectedTag property.
/// </summary>
public class BindableToolStripDropDownButton : ToolStripDropDownButton, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public BindableToolStripDropDownButton() {
}
public object SelectedTag {
get { if(Tag==null && DropDownItems.Count>0) Tag=DropDownItems[0].Tag; return Tag; }
set { AdoptFromTag(value); }
}
protected override void OnDropDownItemClicked(ToolStripItemClickedEventArgs e) {
ToolStripItem clickedItem = e.ClickedItem;
if(Tag == null || !Tag.Equals(clickedItem.Tag)) {
Tag = clickedItem.Tag;
Image = clickedItem.Image;
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTag"));
}
base.OnDropDownItemClicked(e);
}
private void AdoptFromTag(object tag) {
if(Tag == null || !Tag.Equals(tag)) {
Tag = tag;
foreach(ToolStripItem item in DropDownItems) {
if(item.Tag != null && item.Tag.Equals(tag)) {
Image = item.Image;
break;
}
}
Tag = tag;
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("SelectedTag"));
}
}
}
}

View file

@ -0,0 +1,82 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Windows.Forms;
using Greenshot.Configuration;
namespace Greenshot.Controls {
public class ColorButton : ToolStripButton, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private Color selectedColor = Color.Transparent;
public ColorButton() {
Bitmap bmp = new Bitmap(1,1);
bmp.SetPixel(0,0, selectedColor);
this.Image = bmp;
this.BackgroundImageLayout = ImageLayout.Tile;
Click+= new EventHandler(ColorButtonClick);
}
public Color SelectedColor {
get {return selectedColor;}
set {
//(Image as Bitmap).SetPixel(0,0, value);
selectedColor = value;
Brush brush;
if(value != Color.Transparent) {
brush = new SolidBrush(value);
} else {
brush = new HatchBrush(HatchStyle.Percent50,Color.White, Color.Gray);
}
using (Graphics graphics = Graphics.FromImage(Image)) {
graphics.FillRectangle(brush, new Rectangle(0,13,16,3));
}
// cleanup GDI Object
brush.Dispose();
Invalidate();
}
}
void ColorButtonClick(object sender, EventArgs e) {
ColorDialog colorDialog = ColorDialog.GetInstance();
colorDialog.Color = SelectedColor;
colorDialog.ShowDialog();
if (colorDialog.DialogResult != DialogResult.Cancel) {
if(!colorDialog.Color.Equals(SelectedColor)) {
AppConfig conf = AppConfig.GetInstance();
conf.Editor_RecentColors = colorDialog.RecentColors;
conf.Store();
SelectedColor = colorDialog.Color;
if(PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("SelectedColor"));
}
}
}
}
}
}

View file

@ -0,0 +1,62 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
using System.Drawing;
namespace Greenshot.Controls {
/// <summary>
/// ToolStripComboBox containing installed font families,
/// implementing INotifyPropertyChanged for data binding
/// </summary>
public class FontFamilyComboBox : ToolStripComboBox, INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
public FontFamily FontFamily {
get { return (FontFamily)SelectedItem; }
set {
if(!SelectedItem.Equals(value)) {
SelectedItem = value;
}
}
}
public FontFamilyComboBox() : base()
{
ComboBox.DataSource = FontFamily.Families;
ComboBox.DisplayMember = "Name";
this.SelectedIndexChanged += new EventHandler(BindableToolStripComboBox_SelectedIndexChanged);
}
void BindableToolStripComboBox_SelectedIndexChanged(object sender, EventArgs e)
{
if(PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs("Text"));
PropertyChanged(this, new PropertyChangedEventArgs("FontFamily"));
PropertyChanged(this, new PropertyChangedEventArgs("SelectedIndex"));
PropertyChanged(this, new PropertyChangedEventArgs("SelectedItem"));
}
}
}
}

View file

@ -0,0 +1,64 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
using System.Windows.Forms.Design;
using System.Drawing;
namespace Greenshot.Controls {
/*[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripColorButton : ToolStripControlHost
{
public event EventHandler ValueChanged;
public ToolStripColorButton() :base(new ColorButton())
{
}
public ColorButton ColorButton
{
get {return Control as ColorButton;}
}
public Color SelectedColor
{
get { return ColorButton.SelectedColor; }
set { ColorButton.SelectedColor = value;}
}
protected override void OnSubscribeControlEvents(Control control)
{
base.OnSubscribeControlEvents(control);
ColorButton.SelectedColorChanged += OnSelectedColorChanged;
}
protected override void OnUnsubscribeControlEvents(Control control)
{
base.OnUnsubscribeControlEvents(control);
ColorButton.SelectedColorChanged -= OnSelectedColorChanged;
}
private void OnSelectedColorChanged(object sender, EventArgs e)
{
if(ValueChanged != null) ValueChanged(sender, e);
}
}*/
}

View file

@ -0,0 +1,81 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Windows.Forms;
using System.Windows.Forms.Design;
namespace Greenshot.Controls {
[ToolStripItemDesignerAvailability(ToolStripItemDesignerAvailability.ToolStrip | ToolStripItemDesignerAvailability.StatusStrip)]
public class ToolStripNumericUpDown : ToolStripControlHost, INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public ToolStripNumericUpDown() : base(new NumericUpDown())
{
}
public NumericUpDown NumericUpDown
{
get {return Control as NumericUpDown;}
}
public decimal Value
{
get { return NumericUpDown.Value; }
set { NumericUpDown.Value = value;}
}
public decimal Minimum {
get { return NumericUpDown.Minimum; }
set { NumericUpDown.Minimum = value; }
}
public decimal Maximum {
get { return NumericUpDown.Maximum; }
set { NumericUpDown.Maximum = value; }
}
public decimal Increment {
get { return NumericUpDown.Increment; }
set { NumericUpDown.Increment = value; }
}
public int DecimalPlaces {
get { return NumericUpDown.DecimalPlaces; }
set { NumericUpDown.DecimalPlaces = value; }
}
protected override void OnSubscribeControlEvents(Control control) {
base.OnSubscribeControlEvents(control);
NumericUpDown.ValueChanged += _valueChanged;
}
protected override void OnUnsubscribeControlEvents(Control control) {
base.OnUnsubscribeControlEvents(control);
NumericUpDown.ValueChanged -= _valueChanged;
}
private void _valueChanged(object sender, EventArgs e) {
if(PropertyChanged != null) PropertyChanged(this, new PropertyChangedEventArgs("Value"));
}
}
}

View file

@ -0,0 +1,162 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Drawing2D;
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 {
/// <summary>
/// Description of LineContainer.
/// </summary>
[Serializable()]
public class ArrowContainer : LineContainer {
public enum ArrowHeadCombination { NONE, START_POINT, END_POINT, BOTH };
private static readonly AdjustableArrowCap ARROW_CAP = new AdjustableArrowCap(4, 6);
public ArrowContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.ARROWHEADS));
}
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 ) {
//draw shadow first
int basealpha = 100;
int alpha = basealpha;
int steps = 5;
int currentStep = 1;
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;
g.DrawLine(shadowCapPen,
this.Left + currentStep,
this.Top + currentStep,
this.Left + currentStep + this.Width,
this.Top + currentStep + this.Height);
currentStep++;
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;
g.DrawLine(pen, this.Left, this.Top, this.Left + this.Width, this.Top + this.Height);
}
}
}
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;
}
}
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) {
return false;
}
return distance <= Math.Max(lineThickness / 2, 10);*/
}
}
}

View file

@ -0,0 +1,322 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing {
/// <summary>
/// The BitmapBuffer is exactly what it says, it buffers a Bitmap.
/// And it is possible to Draw on the Bitmap with direct memory access for better performance
/// </summary>
[Serializable()]
public unsafe class BitmapBuffer : IDisposable {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapBuffer));
private Bitmap bitmap;
public Bitmap Bitmap {
get {return bitmap;}
}
[NonSerialized]
private BitmapData bmData;
[NonSerialized]
private Rectangle rect;
[NonSerialized]
private byte* pointer;
[NonSerialized]
private int stride; /* bytes per pixel row */
[NonSerialized]
private int aIndex = -1;
[NonSerialized]
private int rIndex = -1;
[NonSerialized]
private int gIndex = -1;
[NonSerialized]
private int bIndex = -1;
[NonSerialized]
private int bytesPerPixel;
[NonSerialized]
private bool bitsLocked = false;
public Size Size {
get {return rect.Size;}
}
public int Length {
get {return rect.Width*rect.Height;}
}
public int Width {
get {return rect.Width;}
}
public int Height {
get {return rect.Height;}
}
/**
* Constructor with just a Bitmap, the Rectangle is the Bitmap itself
*/
public BitmapBuffer(Bitmap bmp) : this(bmp, Rectangle.Empty) {
}
/**
* Create a BitmapBuffer from a Bitmap and a Rectangle specifying what part from the Bitmap to take
*/
public BitmapBuffer(Bitmap sourceBmp, Rectangle applyRect) {
Rectangle sourceRect = new Rectangle(applyRect.X, applyRect.Y, applyRect.Width, applyRect.Height);
Rectangle bitmapRect = new Rectangle(0,0, sourceBmp.Width, sourceBmp.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;
}
if (SupportsPixelFormat(sourceBmp)) {
// Create copy with supported format
this.bitmap = sourceBmp.Clone(sourceRect, sourceBmp.PixelFormat);
} else {
// When sourceRect is the whole bitmap there is a GDI+ bug in Clone
// Clone will than return the same PixelFormat as the source
// a quick workaround is using new Bitmap which uses a default of Format32bppArgb
if (sourceRect.Equals(bitmapRect)) {
this.bitmap = new Bitmap(sourceBmp);
} else {
this.bitmap = sourceBmp.Clone(sourceRect, PixelFormat.Format24bppRgb);
}
}
// Set "this" rect to location 0,0
// as the Cloned Bitmap is only the part we want to work with
this.rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
}
/**
* Destructor
*/
~BitmapBuffer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
Unlock();
if (disposing) {
if (bitmap != null) {
bitmap.Dispose();
}
}
bitmap = null;
bmData = null;
pointer = null;
}
/**
* This is called when deserializing the object
*/
public BitmapBuffer(SerializationInfo info, StreamingContext ctxt) {
this.bitmap = (Bitmap)info.GetValue("bitmap", typeof(Bitmap));
this.rect = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
// The rest will be set when Lock is called
}
/**
* This is called when serializing the object
*/
public void GetObjectData(SerializationInfo info, StreamingContext ctxt) {
Unlock();
info.AddValue("bitmap", this.bitmap);
}
/**
* Lock the bitmap so we have direct access to the memory
*/
public void Lock() {
if(rect.Width > 0 && rect.Height > 0) {
bmData = bitmap.LockBits(rect, ImageLockMode.ReadWrite, bitmap.PixelFormat);
bitsLocked = true;
System.IntPtr Scan0 = bmData.Scan0;
pointer = (byte*)(void*)Scan0;
PrepareForPixelFormat();
stride = bmData.Stride;
}
}
/**
* Unlock the System Memory
*/
private void Unlock() {
if(bitsLocked) {
bitmap.UnlockBits(bmData);
bitsLocked = false;
}
}
/**
* Draw the stored bitmap to the destionation bitmap at the supplied point
*/
public void DrawTo(Graphics graphics, Point destination) {
DrawTo(graphics, null, destination);
}
/**
* Draw the stored Bitmap on the Destination bitmap with the specified rectangle
* Be aware that the stored bitmap will be resized to the specified rectangle!!
*/
public void DrawTo(Graphics graphics, Rectangle destinationRect) {
DrawTo(graphics, destinationRect, null);
}
/**
* private helper to draw the bitmap
*/
private void DrawTo(Graphics graphics, Rectangle? destinationRect, Point? destination) {
if (destinationRect.HasValue) {
// Does the rect have any pixels?
if (destinationRect.Value.Height <= 0 || destinationRect.Value.Width <= 0) {
return;
}
}
// Make sure this.bitmap is unlocked
Unlock();
if (destinationRect.HasValue) {
LOG.Debug(String.Format("Drawing at: {0},{1} {2},{3}", destinationRect.Value.X, destinationRect.Value.Y, destinationRect.Value.Width, destinationRect.Value.Height));
graphics.DrawImage(this.bitmap, destinationRect.Value);
} else if (destination.HasValue) {
LOG.Debug(String.Format("Drawing at: {0},{1}", destination.Value.X, destination.Value.Y));
graphics.DrawImage(this.bitmap, destination.Value);
}
}
/**
* Retrieve the color at location x,y
* Before the first time this is called the Lock() should be called once!
*/
public Color GetColorAt(int x, int y) {
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
int offset = x*bytesPerPixel+y*stride;
int a = (aIndex==-1) ? 255 : (int)pointer[aIndex+offset];
return Color.FromArgb(a, pointer[rIndex+offset], pointer[gIndex+offset], pointer[bIndex+offset]);
} else {
return Color.Empty;
}
}
/**
* Set the color at location x,y
* Before the first time this is called the Lock() should be called once!
*/
public void SetColorAt(int x, int y, Color color) {
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
int offset = x*bytesPerPixel+y*stride;
if(aIndex!=-1) pointer[aIndex+offset] = color.A;
pointer[rIndex+offset] = color.R;
pointer[gIndex+offset] = color.G;
pointer[bIndex+offset] = color.B;
}
}
/**
* Retrieve the color at location x,y as an array
* Before the first time this is called the Lock() should be called once!
*/
public int[] GetColorArrayAt(int x, int y) {
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
int offset = x*bytesPerPixel+y*stride;
int a = (aIndex==-1) ? 255 : (int)pointer[aIndex+offset];
return new int[]{a, pointer[rIndex+offset], pointer[gIndex+offset], pointer[bIndex+offset]};
} else {
return new int[]{0,0,0,0};
}
}
/**
* Set the color at location x,y as an array
* Before the first time this is called the Lock() should be called once!
*/
public void SetColorArrayAt(int x, int y, int[] colors) {
if(x>=0 && y>=0 && x<rect.Width && y<rect.Height) {
int offset = x*bytesPerPixel+y*stride;
if(aIndex!=-1) pointer[aIndex+offset] = (byte)colors[0];
pointer[rIndex+offset] = (byte)colors[1];
pointer[gIndex+offset] = (byte)colors[2];
pointer[bIndex+offset] = (byte)colors[3];
}
}
/**
* 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));
}
/**
* Set some internal values for accessing the bitmap according to the PixelFormat
*/
private void PrepareForPixelFormat() {
switch(bitmap.PixelFormat) {
case PixelFormat.Format32bppArgb:
bIndex = 0;
gIndex = 1;
rIndex = 2;
aIndex = 3;
bytesPerPixel = 4;
break;
case PixelFormat.Format32bppRgb:
bIndex = 0;
gIndex = 1;
rIndex = 2;
bytesPerPixel = 4;
break;
case PixelFormat.Format24bppRgb:
bIndex = 0;
gIndex = 1;
rIndex = 2;
bytesPerPixel = 3;
break;
default:
throw new FormatException("Bitmap.Pixelformat."+bitmap.PixelFormat+" is currently not supported. Supported: Format32bpp(A)Rgb, Format24bppRgb");
}
}
}
}

View file

@ -0,0 +1,109 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.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 {
/// <summary>
/// Description of BitmapContainer.
/// </summary>
[Serializable()]
public class BitmapContainer : DrawableContainer, IBitmapContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BitmapContainer));
protected Bitmap bitmap;
public BitmapContainer(Surface parent, string filename) : this(parent) {
Load(filename);
}
public BitmapContainer(Surface parent) : base(parent) {
}
public Bitmap Bitmap {
set {
if (bitmap != null) {
bitmap.Dispose();
}
bitmap = (Bitmap)value.Clone();
Width = value.Width;
Height = value.Height;
}
get { return bitmap; }
}
/**
* Destructor
*/
~BitmapContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (bitmap != null) {
bitmap.Dispose();
}
}
bitmap = null;
}
public void Load(string filename) {
if (File.Exists(filename)) {
using (Bitmap fileBitmap = new Bitmap(filename)) {
Bitmap = fileBitmap;
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
}
public override void Draw(Graphics g, RenderMode rm) {
if (bitmap != null) {
g.DrawImage(bitmap, Bounds);
}
}
}
}

View file

@ -0,0 +1,57 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Helpers;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Description of CropContainer.
/// </summary>
public class CropContainer : DrawableContainer {
public CropContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateFieldWithValue(FieldType.FLAGS, FieldType.Flag.CONFIRMABLE));
}
public override void Draw(Graphics g, RenderMode rm) {
using (Brush cropBrush = new SolidBrush(Color.FromArgb(100, 150, 150, 100))) {
Rectangle r = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
Rectangle selectionRect = new Rectangle(r.Left - 1, r.Top - 1, r.Width + 1, r.Height + 1);
DrawSelectionBorder(g, selectionRect);
// top
g.FillRectangle(cropBrush, new Rectangle(0, 0, parent.Width, r.Top));
// left
g.FillRectangle(cropBrush, new Rectangle(0, r.Top, r.Left, r.Height));
// right
g.FillRectangle(cropBrush, new Rectangle(r.Left + r.Width, r.Top, parent.Width - (r.Left + r.Width), r.Height));
// bottom
g.FillRectangle(cropBrush, new Rectangle(0, r.Top + r.Height, parent.Width, parent.Height - (r.Top + r.Height)));
}
}
}
}

View file

@ -0,0 +1,110 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.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 {
/// <summary>
/// Description of CursorContainer.
/// </summary>
[Serializable()]
public class CursorContainer : DrawableContainer, ICursorContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(CursorContainer));
protected Cursor cursor;
public CursorContainer(Surface parent) : base(parent) {
}
public CursorContainer(Surface parent, string filename) : base(parent) {
Load(filename);
}
public Cursor Cursor {
set {
if (cursor != null) {
cursor.Dispose();
}
// Clone cursor (is this correct??)
cursor = new Cursor(value.CopyHandle());
Width = value.Size.Width;
Height = value.Size.Height;
}
get { return cursor; }
}
/**
* Destructor
*/
~CursorContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (cursor != null) {
cursor.Dispose();
}
}
cursor = null;
}
public void Load(string filename) {
if (File.Exists(filename)) {
using (Cursor fileCursor = new Cursor(filename)) {
Cursor = fileCursor;
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
}
public override void Draw(Graphics graphics, RenderMode rm) {
if (cursor != null) {
cursor.DrawStretched(graphics, Bounds);
}
}
}
}

View file

@ -0,0 +1,403 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Data;
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 Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// represents a rectangle, ellipse, label or whatever. Can contain filters, too.
/// serializable for clipboard support
/// Subclasses should fulfill INotifyPropertyChanged contract, i.e. call
/// OnPropertyChanged whenever a public property has been changed.
/// </summary>
[Serializable()]
public abstract class DrawableContainer : AbstractFieldHolderWithChildren, INotifyPropertyChanged, IDrawableContainer {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(DrawableContainer));
[NonSerialized]
private PropertyChangedEventHandler propertyChanged;
public event PropertyChangedEventHandler PropertyChanged {
add { propertyChanged += value; }
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);
}
return ret;
}
}
[NonSerialized]
protected Surface parent;
public ISurface Parent {
get { return parent; }
set { SwitchParent((Surface)value); }
}
[NonSerialized]
protected Label[] grippers;
private bool layoutSuspended = false;
[NonSerialized]
protected Label childLabel;
[NonSerialized]
private bool selected = false;
public bool Selected {
get {return selected;}
set {selected = value; OnPropertyChanged("Selected"); }
}
[NonSerialized]
public EditStatus Status = EditStatus.UNDRAWN;
private int left = 0;
public int Left {
get { return left; }
set { left = value; DoLayout(); OnPropertyChanged("Left"); }
}
private int top = 0;
public int Top {
get { return top; }
set { top = value; DoLayout(); OnPropertyChanged("Top"); }
}
private int width = 0;
public int Width {
get { return width; }
set { width = value; DoLayout(); OnPropertyChanged("Width"); }
}
private int height = 0;
public int Height {
get { return height; }
set { height = value; DoLayout(); OnPropertyChanged("Height"); }
}
public Rectangle Bounds {
get { return GuiRectangle.GetGuiRectangle(left, top, width, height); }
}
public DrawableContainer(Surface parent) {
this.parent = parent;
InitControls();
}
public void Add(IFilter filter) {
AddChild(filter);
}
public void Remove(IFilter filter) {
RemoveChild(filter);
}
public Label GetLabel() {
return childLabel;
}
public void AlignToParent(HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
if (horizontalAlignment == HorizontalAlignment.Left) {
Left = lineThickness/2;
}
if (horizontalAlignment == HorizontalAlignment.Right) {
Left = parent.Width - this.Width - lineThickness/2;
}
if (horizontalAlignment == HorizontalAlignment.Center) {
Left = (parent.Width / 2) - (this.Width / 2) - lineThickness/2;
}
if (verticalAlignment == VerticalAlignment.TOP) {
Top = lineThickness/2;
}
if (verticalAlignment == VerticalAlignment.BOTTOM) {
Top = parent.Height - this.Height - lineThickness/2;
}
if (verticalAlignment == VerticalAlignment.CENTER) {
Top = (parent.Height / 2) - (this.Height / 2) - lineThickness/2;
}
}
public virtual bool InitContent() { return true; }
public virtual void OnDoubleClick() {}
private void InitControls() {
InitGrippers();
childLabel = new Label();
childLabel.BackColor = Color.Transparent;
childLabel.BorderStyle = BorderStyle.None;
childLabel.Cursor = Cursors.SizeAll;
childLabel.MouseDown += new MouseEventHandler(gripperMouseDown);
childLabel.MouseUp += new MouseEventHandler(gripperMouseUp);
childLabel.MouseMove += new MouseEventHandler(childLabelMouseMove);
DoLayout();
}
void InitGrippers() {
grippers = new Label[8];
for(int i=0; i<grippers.Length; i++) {
grippers[i] = new Label();
grippers[i].Name = "gripper" + i;
grippers[i].Width = grippers[i].Height = 5;
grippers[i].BackColor = Color.Black;
grippers[i].MouseDown += new MouseEventHandler(gripperMouseDown);
grippers[i].MouseUp += new MouseEventHandler(gripperMouseUp);
grippers[i].MouseMove += new MouseEventHandler(gripperMouseMove);
grippers[i].Visible = false;
}
grippers[1].Cursor = Cursors.SizeNS;
grippers[3].Cursor = Cursors.SizeWE;
grippers[5].Cursor = Cursors.SizeNS;
grippers[7].Cursor = Cursors.SizeWE;
if(parent != null) parent.Controls.AddRange(grippers); // otherwise we'll attach them in switchParent
}
public void SuspendLayout() {
layoutSuspended = true;
childLabel.SuspendLayout();
}
public void ResumeLayout() {
layoutSuspended = false;
DoLayout();
childLabel.ResumeLayout();
}
private 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];
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;
}
childLabel.Left = this.Left;
childLabel.Top = this.Top;
childLabel.Width = this.Width;
childLabel.Height = this.Height;
}
}
public virtual void Dispose() {
for(int i=0; i<grippers.Length; i++) {
grippers[i].Dispose();
}
childLabel.Dispose();
FieldAggregator aggProps = parent.FieldAggregator;
aggProps.UnbindElement(this);
}
int mx;
int my;
private void gripperMouseDown(object sender, MouseEventArgs e) {
mx = e.X;
my = e.Y;
Status = EditStatus.RESIZING;
parent.Invalidate();
}
private void gripperMouseUp(object sender, MouseEventArgs e) {
Status = EditStatus.IDLE;
parent.Invalidate();
}
private void gripperMouseMove(object sender, MouseEventArgs e) {
if(Status.Equals(EditStatus.RESIZING)) {
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;
}
ResumeLayout();
parent.Invalidate();
}
}
private void childLabelMouseMove(object sender, MouseEventArgs e) {
if (Status.Equals(EditStatus.RESIZING)) {
SuspendLayout();
this.Left += e.X - mx;
this.Top += e.Y - my;
ResumeLayout();
parent.Invalidate();
}
}
public abstract void Draw(Graphics graphics, RenderMode renderMode);
public virtual void DrawContent(Graphics graphics, Bitmap bmp, RenderMode renderMode) {
//if(LOG.IsDebugEnabled) LOG.Debug("Drawing container "+this+" with bounds "+Bounds+" and " + Children.Count + " children and status: "+Status);
if(Children.Count>0) {
if(!Status.Equals(EditStatus.IDLE)) {
DrawSelectionBorder(graphics, Bounds);
} else {
Rectangle effRect = Bounds;
if(!effRect.IsEmpty) {
foreach(IFilter filter in Filters) {
//if(LOG.IsDebugEnabled) LOG.Debug("Applying filter "+filter+" with bounds "+effRect);
filter.Apply(graphics, bmp, effRect, renderMode);
}
}
}
}
Draw(graphics, RenderMode.EDIT);
}
public virtual bool Contains(int x, int y) {
return Bounds.Contains(x,y);
}
public virtual bool ClickableAt(int x, int y) {
Rectangle r = GuiRectangle.GetGuiRectangle(Left, Top, Width, Height);
r.Inflate(5, 5);
return r.Contains(x, y);
}
protected void DrawSelectionBorder(Graphics g, Rectangle rect) {
using (Pen pen = new Pen(Color.MediumSeaGreen)) {
pen.DashPattern = new float[]{1,2};
pen.Width = 1;
g.DrawRectangle(pen, rect);
}
}
public void ShowGrippers() {
for(int i=0; i<grippers.Length; i++) {
if(grippers[i].Enabled) grippers[i].Show();
else grippers[i].Hide();
}
this.ResumeLayout();
}
public void HideGrippers() {
this.SuspendLayout();
for(int i=0; i<grippers.Length; i++) {
grippers[i].Hide();
}
}
public void MoveBy(int dx, int dy) {
this.SuspendLayout();
this.Left += dx;
this.Top += dy;
this.ResumeLayout();
}
private void SwitchParent(Surface newParent) {
if(parent != null) {
for(int i=0; i<grippers.Length; i++) {
parent.Controls.Remove(grippers[i]);
}
} else if(grippers == null) {
InitControls();
}
parent = newParent;
parent.Controls.AddRange(grippers);
foreach(IFilter filter in Filters) {
filter.Parent = this;
}
}
// drawablecontainers are regarded equal if they are of the same type and their bounds are equal. this should be sufficient.
public override bool Equals(object obj) {
bool ret = false;
if(obj != null && GetType().Equals(obj.GetType())) {
DrawableContainer other = obj as DrawableContainer;
if(left==other.left && top==other.top && width==other.width && height==other.height) ret = true;
}
return ret;
}
public override int GetHashCode() {
return left.GetHashCode() ^ top.GetHashCode() ^ width.GetHashCode() ^ height.GetHashCode() ^ GetFields().GetHashCode();
}
protected void OnPropertyChanged(string propertyName) {
if(propertyChanged != null) propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View file

@ -0,0 +1,255 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
using System.Collections.Generic;
using System.Drawing;
using System.Windows.Forms;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Dispatches most of a DrawableContainer's public properties and methods to a list of DrawableContainers.
/// </summary>
[Serializable()]
public class DrawableContainerList : List<DrawableContainer> {
public DrawableContainerList() {
}
public EditStatus Status {
get {
return this[Count-1].Status;
}
set {
foreach(DrawableContainer dc in this) dc.Status = value;
}
}
/// <summary>
/// Gets or sets the selection status of the elements.
/// If several elements are in the list, true is only returned when all elements are selected.
/// </summary>
public bool Selected {
get {
bool ret = true;
foreach(DrawableContainer dc in this) ret &= dc.Selected;
return ret;
}
set {
foreach(DrawableContainer dc in this) dc.Selected = value;
}
}
/// <summary>
/// Gets or sets the parent control of the elements in the list.
/// If there are several elements, the parent control of the last added is returned.
/// </summary>
public ISurface Parent {
get {
if(Count > 0) return this[Count-1].Parent;
return null;
}
set {
foreach(DrawableContainer dc in this) dc.Parent = value;
}
}
/// <summary>
/// Moves all elements in the list by the given amount of pixels.
/// </summary>
/// <param name="dx">pixels to move horizontally</param>
/// <param name="dy">pixels to move vertically</param>
public void MoveBy(int dx, int dy) {
foreach(DrawableContainer dc in this) {
dc.Left += dx;
dc.Top += dy;
}
}
/// <summary>
/// Hides the grippers of all elements in the list.
/// </summary>
public void HideGrippers() {
foreach(DrawableContainer dc in this) {
dc.HideGrippers();
}
}
/// <summary>
/// Shows the grippers of all elements in the list.
/// </summary>
public void ShowGrippers() {
foreach(DrawableContainer dc in this) {
dc.ShowGrippers();
}
}
/// <summary>
/// Indicates whether on of the elements is clickable at the given location
/// </summary>
/// <param name="x">x coordinate to be checked</param>
/// <param name="y">y coordinate to be checked</param>
/// <returns>true if one of the elements in the list is clickable at the given location, false otherwise</returns>
public bool ClickableAt(int x, int y) {
bool ret = false;
foreach(DrawableContainer dc in this) {
ret |= dc.ClickableAt(x, y);
}
return ret;
}
/// <summary>
/// retrieves the topmost element being clickable at the given location
/// </summary>
/// <param name="x">x coordinate to be checked</param>
/// <param name="y">y coordinate to be checked</param>
/// <returns>the topmost element from the list being clickable at the given location, null if there is no clickable element</returns>
public DrawableContainer ClickableElementAt(int x, int y) {
for(int i=Count-1; i>=0; i--) {
if(this[i].ClickableAt(x,y)) return this[i];
}
return null;
}
/// <summary>
/// Dispatches OnDoubleClick to all elements in the list.
/// </summary>
public void OnDoubleClick() {
foreach(DrawableContainer dc in this) {
dc.OnDoubleClick();
}
}
/// <summary>
/// Triggers all elements in the list ot be redrawn.
/// </summary>
/// <param name="g">the related Graphics object</param>
/// <param name="rm">the rendermode in which the element is to be drawn</param>
public void Draw(Graphics g, Bitmap bitmap, RenderMode rm) {
foreach(DrawableContainer dc in this) {
dc.DrawContent(g, bitmap, rm);
}
}
/// <summary>
/// Indicates whether the given list of elements can be pulled up,
/// i.e. whether there is at least one unselected element higher in hierarchy
/// </summary>
/// <param name="elements">list of elements to pull up</param>
/// <returns>true if the elements could be pulled up</returns>
public bool CanPullUp(DrawableContainerList elements) {
if(elements.Count == 0 || elements.Count == this.Count) return false;
foreach(DrawableContainer element in elements) {
if(this.IndexOf(element) < this.Count - elements.Count) return true;
}
return false;
}
/// <summary>
/// Pulls one or several elements up one level in hierarchy (z-index).
/// </summary>
/// <param name="elements">list of elements to pull up</param>
public void PullElementsUp(DrawableContainerList elements) {
for(int i=this.Count-1; i>=0; i--) {
DrawableContainer dc = this[i];
if(elements.Contains(dc)) {
if(Count > (i+1) && !elements.Contains(this[i+1])) SwapElements(i,i+1);
}
}
}
/// <summary>
/// Pulls one or several elements up to the topmost level(s) in hierarchy (z-index).
/// </summary>
/// <param name="elements">of elements to pull to top</param>
public void PullElementsToTop(DrawableContainerList elements) {
DrawableContainer[] dcs = this.ToArray();
for(int i=0; i<dcs.Length; i++) {
DrawableContainer dc = dcs[i];
if(elements.Contains(dc)) {
this.Remove(dc);
this.Add(dc);
}
}
}
/// <summary>
/// Indicates whether the given list of elements can be pushed down,
/// i.e. whether there is at least one unselected element lower in hierarchy
/// </summary>
/// <param name="elements">list of elements to push down</param>
/// <returns>true if the elements could be pushed down</returns>
public bool CanPushDown(DrawableContainerList elements) {
if(elements.Count == 0 || elements.Count == this.Count) return false;
foreach(DrawableContainer element in elements) {
if(this.IndexOf(element) >= elements.Count) return true;
}
return false;
}
/// <summary>
/// Pushes one or several elements down one level in hierarchy (z-index).
/// </summary>
/// <param name="elements">list of elements to push down</param>
public void PushElementsDown(DrawableContainerList elements) {
for(int i=0; i<Count; i++) {
DrawableContainer dc = this[i];
if(elements.Contains(dc)) {
if((i>0) && !elements.Contains(this[i-1])) SwapElements(i,i-1);
}
}
}
/// <summary>
/// Pushes one or several elements down to the bottommost level(s) in hierarchy (z-index).
/// </summary>
/// <param name="elements">of elements to push to bottom</param>
public void PushElementsToBottom(DrawableContainerList elements) {
DrawableContainer[] dcs = this.ToArray();
for(int i=dcs.Length-1; i>=0; i--) {
DrawableContainer dc = dcs[i];
if(elements.Contains(dc)) {
this.Remove(dc);
this.Insert(0, dc);
}
}
}
/// <summary>
/// swaps two elements in hierarchy (z-index),
/// checks both indices to be in range
/// </summary>
/// <param name="index1">index of the 1st element</param>
/// <param name="index2">index of the 2nd element</param>
private void SwapElements(int index1, int index2) {
if(index1 >= 0 && index1 < Count && index2 >= 0 && index2 < Count && index1 != index2) {
DrawableContainer dc = this[index1];
this[index1] = this[index2];
this[index2] = dc;
}
}
}
}

View file

@ -0,0 +1,92 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Description of EllipseContainer.
/// </summary>
[Serializable()]
public class EllipseContainer : DrawableContainer {
public EllipseContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.LINE_THICKNESS));
AddField(FieldFactory.CreateField(FieldType.LINE_COLOR));
AddField(FieldFactory.CreateField(FieldType.FILL_COLOR));
AddField(FieldFactory.CreateField(FieldType.SHADOW));
}
public override void Draw(Graphics graphics, RenderMode renderMode) {
graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor));
// draw shadow before anything else
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) {
int basealpha = 100;
int alpha = basealpha;
int steps = 5;
int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) {
using (Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowPen.Width = lineVisible ? lineThickness : 1;
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(Left + currentStep, Top + currentStep, Width, Height);
graphics.DrawEllipse(shadowPen, shadowRect);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
}
//draw the original shape
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
using (Brush brush = new SolidBrush(fillColor)) {
graphics.FillEllipse(brush, rect);
}
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if (pen.Width > 0) {
graphics.DrawEllipse(pen, rect);
}
}
}
public override bool Contains(int x, int y) {
double xDistanceFromCenter = x - (Left+Width/2);
double yDistanceFromCenter = y - (Top+Height/2);
// 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;
}
}
}

View file

@ -0,0 +1,153 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.Runtime.Serialization;
using Greenshot.Helpers;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Basic IFieldHolder implementation, providing access to a set of fields
/// </summary>
[Serializable()]
public abstract class AbstractFieldHolder : IFieldHolder {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(AbstractFieldHolder));
/// <summary>
/// called when a field's value has changed
/// </summary>
[NonSerialized]
private FieldChangedEventHandler fieldChanged;
public event FieldChangedEventHandler FieldChanged {
add { fieldChanged += value; }
remove{ fieldChanged -= value; }
}
// we keep to Coolections of our fields, dictionary for quick access, list for serialization
// this allows us to use default serialization
[NonSerialized]
private Dictionary<FieldType, Field> fieldsByType = new Dictionary<FieldType, Field>();
private List<Field> fields = new List<Field>();
public AbstractFieldHolder() {}
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
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)); };
fieldsByType[field.FieldType] = field;
}
}
public virtual void AddField(Field field) {
if(fieldsByType != null && fieldsByType.ContainsKey(field.FieldType)) {
if(LOG.IsDebugEnabled) LOG.Debug("A field with of type '"+field.FieldType+"' already exists in this "+GetType()+", will overwrite.");
}
fields.Add(field);
fieldsByType[field.FieldType] = field;
field.PropertyChanged += delegate { if(fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); };
}
public void RemoveField(Field field) {
fields.Remove(field);
fieldsByType.Remove(field.FieldType);
field.PropertyChanged -= delegate { if(fieldChanged != null) fieldChanged(this, new FieldChangedEventArgs(field)); };
}
public List<Field> GetFields() {
return fields;
}
public Field GetField(FieldType fieldType) {
try {
return fieldsByType[fieldType];
} catch(KeyNotFoundException e) {
throw new ArgumentException("Field '"+fieldType+"' does not exist in " + GetType(), e);
}
}
public object GetFieldValue(FieldType fieldType) {
return GetField(fieldType).Value;
}
#region convenience methods to save us some casts outside
public string GetFieldValueAsString(FieldType fieldType) {
return (string)GetFieldValue(fieldType);
}
public int GetFieldValueAsInt(FieldType fieldType) {
return (int)GetFieldValue(fieldType);
}
public decimal GetFieldValueAsDecimal(FieldType fieldType) {
return (decimal)GetFieldValue(fieldType);
}
public double GetFieldValueAsDouble(FieldType fieldType) {
return (double)GetFieldValue(fieldType);
}
public float GetFieldValueAsFloat(FieldType fieldType) {
return (float)GetFieldValue(fieldType);
}
public bool GetFieldValueAsBool(FieldType fieldType) {
return (bool)GetFieldValue(fieldType);
}
public Color GetFieldValueAsColor(FieldType fieldType) {
return (Color)GetFieldValue(fieldType);
}
#endregion
public bool HasField(FieldType fieldType) {
return fieldsByType.ContainsKey(fieldType);
}
public bool HasFieldValue(FieldType fieldType) {
return HasField(fieldType) && fieldsByType[fieldType].HasValue;
}
public void SetFieldValue(FieldType fieldType, object value) {
try {
fieldsByType[fieldType].Value = value;
} catch(KeyNotFoundException e) {
throw new ArgumentException("Field '"+fieldType+"' does not exist in " + GetType(), e);
}
}
protected void OnFieldChanged(object sender, FieldChangedEventArgs e){
if(fieldChanged != null) fieldChanged(sender, e);
}
}
}

View file

@ -0,0 +1,126 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.Runtime.Serialization;
using Greenshot.Helpers;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Basic IFieldHolderWithChildren implementation. Similar to IFieldHolder,
/// but has a List<IFieldHolder> of children.
/// Field values are passed to and from children as well.
/// </summary>
[Serializable()]
public abstract class AbstractFieldHolderWithChildren : AbstractFieldHolder {
FieldChangedEventHandler fieldChangedEventHandler;
[NonSerialized]
private EventHandler childrenChanged;
public event EventHandler ChildrenChanged {
add { childrenChanged += value; }
remove { childrenChanged -= value; }
}
public List<IFieldHolder> Children = new List<IFieldHolder>();
public AbstractFieldHolderWithChildren() {
fieldChangedEventHandler = new FieldChangedEventHandler(OnFieldChanged);
}
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
// listen to changing properties
foreach(IFieldHolder fieldHolder in Children) {
fieldHolder.FieldChanged += fieldChangedEventHandler;
}
if(childrenChanged != null) childrenChanged(this, EventArgs.Empty);
}
public void AddChild(IFieldHolder fieldHolder) {
Children.Add(fieldHolder);
fieldHolder.FieldChanged += fieldChangedEventHandler;
if(childrenChanged != null) childrenChanged(this, EventArgs.Empty);
}
public void RemoveChild(IFieldHolder fieldHolder) {
Children.Remove(fieldHolder);
fieldHolder.FieldChanged -= fieldChangedEventHandler;
if(childrenChanged != null) childrenChanged(this, EventArgs.Empty);
}
public new List<Field> GetFields() {
List<Field> ret = new List<Field>();
ret.AddRange(base.GetFields());
foreach(IFieldHolder fh in Children) {
ret.AddRange(fh.GetFields());
}
return ret;
}
public new Field GetField(FieldType fieldType) {
Field ret = null;
if(base.HasField(fieldType)) {
ret = base.GetField(fieldType);
} else {
foreach(IFieldHolder fh in Children) {
if(fh.HasField(fieldType)) {
ret = fh.GetField(fieldType);
break;
}
}
}
if(ret == null) {
throw new ArgumentException("Field '"+fieldType+"' does not exist in " + GetType());
}
return ret;
}
public new bool HasField(FieldType fieldType) {
bool ret = base.HasField(fieldType);
if(!ret) {
foreach(IFieldHolder fh in Children) {
if(fh.HasField(fieldType)) {
ret = true;
break;
}
}
}
return ret;
}
public new bool HasFieldValue(FieldType fieldType) {
Field f = GetField(fieldType);
return f != null && f.HasValue;
}
public new void SetFieldValue(FieldType fieldType, object value) {
Field f = GetField(fieldType);
if(f != null) f.Value = value;
}
}
}

View file

@ -0,0 +1,47 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Basic IBindingConverter implementation
/// </summary>
public abstract class AbstractBindingConverter<T1,T2> : IBindingConverter
{
public AbstractBindingConverter() {}
public object convert(object o) {
if(o == null) {
return null;
} else if(o is T1) {
return convert((T1)o);
} else if(o is T2) {
return convert((T2)o);
} else {
throw new ArgumentException("Cannot handle argument of type "+o.GetType());
}
}
protected abstract T2 convert(T1 o);
protected abstract T1 convert(T2 o);
}
}

View file

@ -0,0 +1,168 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Reflection;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Bidirectional binding of properties of two INotifyPropertyChanged instances.
/// This implementation synchronizes null values, too. If you do not want this
/// behavior (e.g. when binding to a
/// </summary>
public class BidirectionalBinding
{
private INotifyPropertyChanged object1;
private INotifyPropertyChanged object2;
private string property1;
private string property2;
private bool updatingObject1 = false;
private bool updatingObject2 = false;
private IBindingConverter converter;
private IBindingValidator validator;
/// <summary>
/// Whether or not null values are passed on to the other object.
/// </summary>
protected bool AllowSynchronizeNull = true;
/// <summary>
/// Bind properties of two objects bidirectionally
/// </summary>
/// <param name="object1">Object containing 1st property to bind</param>
/// <param name="property1">Property of 1st object to bind</param>
/// <param name="object2">Object containing 2nd property to bind</param>
/// <param name="property2">Property of 2nd object to bind</param>
public BidirectionalBinding(INotifyPropertyChanged object1, string property1, INotifyPropertyChanged object2, string property2)
{
this.object1 = object1;
this.object2 = object2;
this.property1 = property1;
this.property2 = property2;
this.object1.PropertyChanged += new PropertyChangedEventHandler(Property1Changed);
this.object2.PropertyChanged += new PropertyChangedEventHandler(Property2Changed);
}
/// <summary>
/// Bind properties of two objects bidirectionally, converting the values using a converter
/// </summary>
/// <param name="object1">Object containing 1st property to bind</param>
/// <param name="property1">Property of 1st object to bind</param>
/// <param name="object2">Object containing 2nd property to bind</param>
/// <param name="property2">Property of 2nd object to bind</param>
/// <param name="converter">taking care of converting the synchronzied value to the correct target format and back</param>
public BidirectionalBinding(INotifyPropertyChanged object1, string property1, INotifyPropertyChanged object2, string property2, IBindingConverter converter) : this(object1, property1, object2, property2)
{
this.converter = converter;
}
/// <summary>
/// Bind properties of two objects bidirectionally, converting the values using a converter.
/// Synchronization can be intercepted by adding a validator.
/// </summary>
/// <param name="object1">Object containing 1st property to bind</param>
/// <param name="property1">Property of 1st object to bind</param>
/// <param name="object2">Object containing 2nd property to bind</param>
/// <param name="property2">Property of 2nd object to bind</param>
/// <param name="validator">validator to intercept synchronisation if the value does not match certain criteria</param>
public BidirectionalBinding(INotifyPropertyChanged object1, string property1, INotifyPropertyChanged object2, string property2, IBindingValidator validator) : this(object1, property1, object2, property2)
{
this.validator = validator;
}
/// <summary>
/// Bind properties of two objects bidirectionally, converting the values using a converter.
/// Synchronization can be intercepted by adding a validator.
/// </summary>
/// <param name="object1">Object containing 1st property to bind</param>
/// <param name="property1">Property of 1st object to bind</param>
/// <param name="object2">Object containing 2nd property to bind</param>
/// <param name="property2">Property of 2nd object to bind</param>
/// <param name="converter">taking care of converting the synchronzied value to the correct target format and back</param>
/// <param name="validator">validator to intercept synchronisation if the value does not match certain criteria</param>
public BidirectionalBinding(INotifyPropertyChanged object1, string property1, INotifyPropertyChanged object2, string property2, IBindingConverter converter, IBindingValidator validator) : this(object1, property1, object2, property2, converter)
{
this.validator = validator;
}
public void Property1Changed(object sender, PropertyChangedEventArgs e)
{
if(!updatingObject1 && e.PropertyName.Equals(property1))
{
updatingObject2 = true;
synchronize(object1, property1, object2, property2);
updatingObject2 = false;
}
}
public void Property2Changed(object sender, PropertyChangedEventArgs e)
{
if(!updatingObject2 && e.PropertyName.Equals(property2))
{
updatingObject1 = true;
synchronize(object2, property2, object1, property1);
updatingObject1 = false;
}
}
private void synchronize(INotifyPropertyChanged sourceObject, string sourceProperty, INotifyPropertyChanged targetObject, string targetProperty)
{
PropertyInfo targetPropertyInfo = resolvePropertyInfo(targetObject, targetProperty);
PropertyInfo sourcePropertyInfo = resolvePropertyInfo(sourceObject, sourceProperty);
if(sourcePropertyInfo != null && targetPropertyInfo != null && targetPropertyInfo.CanWrite)
{
object bValue = sourcePropertyInfo.GetValue(sourceObject, null);
if(converter != null && bValue != null) bValue = converter.convert(bValue);
try {
if(validator == null || validator.validate(bValue)) {
targetPropertyInfo.SetValue(targetObject, bValue, null);
}
} catch (Exception e) {
throw new MemberAccessException("Could not set property '"+targetProperty+"' to '"+bValue+"' ["+((bValue!=null)?bValue.GetType().Name:"")+"] on "+targetObject+". Probably other type than expected, IBindingCoverter to the rescue.", e);
}
}
}
private PropertyInfo resolvePropertyInfo(object obj, string property) {
PropertyInfo ret = null;
string[] properties = property.Split(".".ToCharArray());
for(int i=0; i<properties.Length; i++) {
string prop = properties[i];
ret = obj.GetType().GetProperty(prop);
if(ret != null && ret.CanRead && i<prop.Length-1) {
obj = ret.GetValue(obj, null);
}
}
return ret;
}
public IBindingConverter Converter {
get { return converter; }
set { converter = value; }
}
}
}

View file

@ -0,0 +1,47 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Converts decimal to double (%) and vice versa, e.g. 95f <---> 0.95d
/// </summary>
public class DecimalDoublePercentageConverter : AbstractBindingConverter<double, decimal>
{
private static DecimalDoublePercentageConverter uniqueInstance;
private DecimalDoublePercentageConverter() {}
protected override decimal convert(double o) {
return Convert.ToDecimal(o)*100;
}
protected override double convert(decimal o) {
return Convert.ToDouble(o)/100;
}
public static DecimalDoublePercentageConverter GetInstance() {
if(uniqueInstance == null) uniqueInstance = new DecimalDoublePercentageConverter();
return uniqueInstance;
}
}
}

View file

@ -0,0 +1,47 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Converts decimal to float and vice versa.
/// </summary>
public class DecimalFloatConverter : AbstractBindingConverter<float, decimal>
{
private static DecimalFloatConverter uniqueInstance;
private DecimalFloatConverter() {}
protected override decimal convert(float o) {
return Convert.ToDecimal(o);
}
protected override float convert(decimal o) {
return Convert.ToInt16(o);
}
public static DecimalFloatConverter GetInstance() {
if(uniqueInstance == null) uniqueInstance = new DecimalFloatConverter();
return uniqueInstance;
}
}
}

View file

@ -0,0 +1,47 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Converts decimal to int and vice versa.
/// </summary>
public class DecimalIntConverter : AbstractBindingConverter<int, decimal>
{
private static DecimalIntConverter uniqueInstance;
private DecimalIntConverter() {}
protected override decimal convert(int o) {
return Convert.ToDecimal(o);
}
protected override int convert(decimal o) {
return Convert.ToInt16(o);
}
public static DecimalIntConverter GetInstance() {
if(uniqueInstance == null) uniqueInstance = new DecimalIntConverter();
return uniqueInstance;
}
}
}

View file

@ -0,0 +1,34 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Interface for a bidirectional converter, for use with BidirectionalBinding.
/// convert(object) implementation must deal with both directions.
/// see DecimalIntConverter
/// </summary>
public interface IBindingConverter {
object convert(object o);
}
}

View file

@ -0,0 +1,35 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Interface for a bidirectional validator, for use with BidirectionalBinding.
/// Useful if you do not want to synchronize values which would be illegal on
/// one of the bound objects (e.g. null value on some form components)
/// see NotNullValidator
/// </summary>
public interface IBindingValidator {
bool validate(object o);
}
}

View file

@ -0,0 +1,42 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields.Binding {
/// <summary>
/// Validates a value not to be null.
/// </summary>
public class NotNullValidator : IBindingValidator {
private static NotNullValidator uniqueInstance;
private NotNullValidator() {
}
public bool validate(object o) {
return o != null;
}
public static NotNullValidator GetInstance() {
if(uniqueInstance == null) uniqueInstance = new NotNullValidator();
return uniqueInstance;
}
}
}

View file

@ -0,0 +1,122 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Represents a single field of a drawable element, i.e.
/// line thickness of a rectangle.
/// </summary>
[Serializable]
public class Field : INotifyPropertyChanged {
[field:NonSerialized]
public event PropertyChangedEventHandler PropertyChanged;
public object myValue;
public object Value {
get { return myValue; }
set { if(!object.Equals(myValue,value)) {
myValue = value;
if(PropertyChanged!=null) PropertyChanged(this, new PropertyChangedEventArgs("Value")); }
}
}
public FieldType FieldType;
public string Scope;
/// <summary>
/// Constructs a new Field instance, usually you should be using FieldFactory
/// to create Fields.
/// </summary>
/// <param name="fieldType">FieldType of the Field to be created</param>
/// <param name="scope">The scope to which the value of this Field is relevant.
/// Depending on the scope the Field's value may be shared for other elements
/// containing the same FieldType for defaulting to the last used value.
/// When scope is set to a Type (e.g. typeof(RectangleContainer)), its value
/// should not be reused for FieldHolders of another Type (e.g. typeof(EllipseContainer))
/// </param>
public Field(FieldType fieldType, Type scope) {
FieldType = fieldType;
Scope = scope.FullName;
}
public Field(FieldType fieldType, string scope) {
FieldType = fieldType;
Scope = scope;
}
public Field(FieldType fieldType) {
FieldType = fieldType;
}
/// <summary>
/// Returns true if this field holds a value other than null.
/// </summary>
public bool HasValue {
get{ return Value != null; }
}
/// <summary>
/// Creates a flat clone of this Field. The fields value itself is not cloned.
/// </summary>
/// <returns></returns>
public Field Clone() {
Field ret = new Field(FieldType, Scope);
ret.Value = Value;
return ret;
}
public override int GetHashCode() {
int hashCode = 0;
unchecked {
hashCode += 1000000009 * FieldType.GetHashCode();
if (Scope != null)
hashCode += 1000000021 * Scope.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj) {
Field other = obj as Field;
if (other == null) {
return false;
}
return this.FieldType == other.FieldType && object.Equals(this.Scope, other.Scope);
}
public override string ToString() {
return string.Format("[Field FieldType={1} Value={0} Scope={2}]", this.myValue, this.FieldType, this.Scope);
}
}
/// <summary>
/// EventHandler to be used when a field value changes
/// </summary>
public delegate void FieldChangedEventHandler(object sender, FieldChangedEventArgs e);
/// <summary>
/// EventArgs to be used with FieldChangedEventHandler
/// </summary>
public class FieldChangedEventArgs : EventArgs {
public readonly Field Field;
public FieldChangedEventArgs(Field field) {
this.Field = field;
}
}
}

View file

@ -0,0 +1,186 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.ComponentModel;
using System.Collections.Generic;
using Greenshot.Configuration;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Represents the current set of properties for the editor.
/// When one of EditorProperties' properties is updated, the change will be promoted
/// to all bound elements.
/// * If an element is selected:
/// This class represents the element's properties
/// * I n>1 elements are selected:
/// This class represents the properties of all elements.
/// Properties that do not apply for ALL selected elements are null (or 0 respectively)
/// If the property values of the selected elements differ, the value of the last bound element wins.
/// </summary>
public class FieldAggregator : AbstractFieldHolder {
private List<DrawableContainer> boundContainers;
private bool internalUpdateRunning = false;
enum Status {IDLE, BINDING, UPDATING};
private Status status;
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(FieldAggregator));
public FieldAggregator() {
List<Field> fields = FieldFactory.GetDefaultFields();
foreach(Field field in fields) {
AddField(field);
}
boundContainers = new List<DrawableContainer>();
}
public override void AddField(Field field) {
base.AddField(field);
field.PropertyChanged += new PropertyChangedEventHandler(OwnPropertyChanged);
}
public void BindElements(DrawableContainerList dcs) {
foreach(DrawableContainer dc in dcs) {
BindElement(dc);
}
}
public void BindElement(DrawableContainer dc) {
status = Status.BINDING;
if(LOG.IsDebugEnabled) LOG.Debug("Binding element of type "+dc.GetType());
if(!boundContainers.Contains(dc)) {
boundContainers.Add(dc);
status = Status.IDLE;
dc.ChildrenChanged += delegate { UpdateFromBoundElements(); };
UpdateFromBoundElements();
}
}
public void BindAndUpdateElement(DrawableContainer dc) {
UpdateElement(dc);
BindElement(dc);
}
public void UpdateElement(DrawableContainer dc) {
if(LOG.IsDebugEnabled) LOG.Debug("Updating element of type "+dc.GetType());
internalUpdateRunning = true;
foreach(Field field in GetFields()) {
if(dc.HasField(field.FieldType) && field.HasValue) {
//if(LOG.IsDebugEnabled) LOG.Debug(" "+field+ ": "+field.Value);
dc.SetFieldValue(field.FieldType, field.Value);
}
}
internalUpdateRunning = false;
}
public void UnbindElement(DrawableContainer dc) {
if(boundContainers.Contains(dc)) {
if(LOG.IsDebugEnabled) LOG.Debug("Unbinding element of type "+dc.GetType());
boundContainers.Remove(dc);
UpdateFromBoundElements();
}
}
public void Clear() {
ClearFields();
boundContainers.Clear();
UpdateFromBoundElements();
}
/// <summary>
/// sets all field values to null, however does not remove fields
/// </summary>
private void ClearFields() {
internalUpdateRunning = true;
//if(LOG.IsDebugEnabled) LOG.Debug("Clearing fields internally");
foreach(Field field in GetFields()) {
field.Value = null;
//if(LOG.IsDebugEnabled) LOG.Debug(" "+field.GetType()+ ": "+field.Value);
}
internalUpdateRunning = false;
}
/// <summary>
/// Updates this instance using the respective fields from the bound elements.
/// Fields that do not apply to every bound element are set to null, or 0 respectively.
/// All other fields will be set to the field value of the least bound element.
/// </summary>
private void UpdateFromBoundElements() {
if(LOG.IsDebugEnabled) LOG.Debug("Updating from bound elements, status = "+status);
status = Status.UPDATING;
ClearFields();
internalUpdateRunning = true;
foreach(Field f in FindCommonFields()) {
SetFieldValue(f.FieldType,f.Value);
//if(LOG.IsDebugEnabled) LOG.Debug("Updating own field: "+f.FieldType+": "+GetField(f.FieldType).Value);
}
internalUpdateRunning = false;
status = Status.IDLE;
}
private List<Field> FindCommonFields() {
List<Field> ret = null;
if(boundContainers.Count > 0) {
// take all fields from the least selected container...
ret = boundContainers[boundContainers.Count-1].GetFields();
for(int i=0;i<boundContainers.Count-1; i++) {
DrawableContainer dc = boundContainers[i];
List<Field> fieldsToRemove = new List<Field>();
foreach(Field f in ret) {
// ... throw out those that do not apply to one of the other containers
if(!dc.HasField(f.FieldType)) fieldsToRemove.Add(f);
}
foreach(Field f in fieldsToRemove) {
ret.Remove(f);
}
}
}
if(ret == null) ret = new List<Field>();
return ret;
}
public void OwnPropertyChanged(object sender, PropertyChangedEventArgs ea) {
Field f = (Field) sender;
if(!internalUpdateRunning && f.Value!=null) {
foreach(DrawableContainer dc in boundContainers) {
if(f.Scope == null || dc.GetType().FullName.Equals(f.Scope)) {
if(LOG.IsDebugEnabled) LOG.Debug("Updating field: "+f.FieldType+": "+f.Value);
if(dc.HasField(f.FieldType)) {
Field dcf = dc.GetField(f.FieldType);
dcf.Value = f.Value;
// update last used from DC field, so that scope is honored
AppConfig.GetInstance().UpdateLastUsedFieldValue(dcf);
}
}
}
}
}
}
}

View file

@ -0,0 +1,92 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Collections.Generic;
using Greenshot.Configuration;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// In charge for creating Fields for DrawableContainers or Filters.
/// Add new FieldTypes in FieldType.cs
/// </summary>
public class FieldFactory {
private FieldFactory() {}
/// <param name="fieldType">FieldType of the field to construct</param>
/// <returns>a new Field of the given fieldType</returns>
public static Field CreateField(FieldType fieldType) {
return CreateField(fieldType, null, null);
}
/// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="preferredDefaultValue">overwrites the original default value being defined in FieldType</param>
/// <returns>a new Field of the given fieldType and initialValue</returns>
public static Field CreateField(FieldType fieldType, object preferredDefaultValue) {
return CreateField(fieldType, null, preferredDefaultValue);
}
/// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="forcedValue">the value to be inserted, regardless of last used value or default value for this field</param>
/// <returns>a new Field of the given fieldType and initialValue</returns>
public static Field CreateFieldWithValue(FieldType fieldType, object forcedValue) {
Field ret = new Field(fieldType);
ret.Value = forcedValue;
return ret;
}
/// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="scope">FieldType of the field to construct</param>
/// <returns>a new Field of the given fieldType, with the scope of it's value being restricted to the Type scope</returns>
public static Field CreateField(FieldType fieldType, Type scope) {
return CreateField(fieldType, scope, null);
}
/// <param name="fieldType">FieldType of the field to construct</param>
/// <param name="preferredDefaultValue">overwrites the original default value being defined in FieldType</param>
/// <returns>a new Field of the given fieldType and preferredDefaultValue, with the scope of it's value being restricted to the Type scope</returns>
public static Field CreateField(FieldType fieldType, Type scope, object preferredDefaultValue) {
Field ret = null;
if (scope != null) {
ret = new Field(fieldType, scope);
} else {
ret = new Field(fieldType);
}
AppConfig.GetInstance().GetLastUsedValueForField(ret, preferredDefaultValue);
return ret;
}
/// <returns>a List of all available fields with their respective default value</returns>
public static List<Field> GetDefaultFields() {
List<Field> ret = new List<Field>();
foreach(FieldType ft in FieldType.Values) {
Field f = CreateField(ft);
f.Value = ft.DefaultValue;
ret.Add(f);
}
return ret;
}
}
}

View file

@ -0,0 +1,117 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Defines all FieldTypes + their default value.
/// (The additional value is why this is not an enum)
/// </summary>
[Serializable]
public class FieldType {
public static readonly FieldType ARROWHEADS = new FieldType("ARROWHEADS", Greenshot.Drawing.ArrowContainer.ArrowHeadCombination.END_POINT);
public static readonly FieldType BLUR_RADIUS = new FieldType("BLUR_RADIUS", 3);
public static readonly FieldType BRIGHTNESS = new FieldType("BRIGHTNESS", 0.9d);
public static readonly FieldType FILL_COLOR = new FieldType("FILL_COLOR", Color.Transparent);
public static readonly FieldType FONT_BOLD = new FieldType("FONT_BOLD", false);
public static readonly FieldType FONT_FAMILY = new FieldType("FONT_FAMILY", FontFamily.GenericSansSerif.Name);
public static readonly FieldType FONT_ITALIC = new FieldType("FONT_ITALIC", false);
public static readonly FieldType FONT_SIZE = new FieldType("FONT_SIZE", 11f);
public static readonly FieldType HIGHLIGHT_COLOR = new FieldType("HIGHLIGHT_COLOR", Color.Yellow);
public static readonly FieldType LINE_COLOR = new FieldType("LINE_COLOR", Color.Red);
public static readonly FieldType LINE_THICKNESS = new FieldType("LINE_THICKNESS", 1);
public static readonly FieldType MAGNIFICATION_FACTOR = new FieldType("MAGNIFICATION_FACTOR", 2);
public static readonly FieldType PIXEL_SIZE = new FieldType("PIXEL_SIZE", 5);
public static readonly FieldType PREVIEW_QUALITY = new FieldType("PREVIEW_QUALITY", 1.0d);
public static readonly FieldType SHADOW = new FieldType("SHADOW", false);
public static readonly FieldType PREPARED_FILTER_OBFUSCATE = new FieldType("PREPARED_FILTER_OBFUSCATE", FilterContainer.PreparedFilter.PIXELIZE);
public static readonly FieldType PREPARED_FILTER_HIGHLIGHT = new FieldType("PREPARED_FILTER_HIGHLIGHT", FilterContainer.PreparedFilter.TEXT_HIGHTLIGHT);
public static readonly FieldType FLAGS = new FieldType("FLAGS", null);
public static FieldType[] Values = new FieldType[]{
ARROWHEADS,
BLUR_RADIUS,
BRIGHTNESS,
FILL_COLOR,
FONT_BOLD,
FONT_FAMILY,
FONT_ITALIC,
FONT_SIZE,
HIGHLIGHT_COLOR,
LINE_COLOR,
LINE_THICKNESS,
MAGNIFICATION_FACTOR,
PIXEL_SIZE,
PREVIEW_QUALITY,
SHADOW,
PREPARED_FILTER_OBFUSCATE,
PREPARED_FILTER_HIGHLIGHT,
FLAGS
};
[Flags]
public enum Flag {
NONE = 0,
CONFIRMABLE = 1
}
public object DefaultValue;
public string Name;
private FieldType(string name, object defaultValue) {
Name = name;
DefaultValue=defaultValue;
}
public override string ToString() {
return this.Name;
}
public override int GetHashCode()
{
int hashCode = 0;
unchecked {
if (Name != null)
hashCode += 1000000009 * Name.GetHashCode();
}
return hashCode;
}
public override bool Equals(object obj)
{
FieldType other = obj as FieldType;
if (other == null)
return false;
return object.Equals(this.Name,other.Name);
}
public static bool operator ==(FieldType a, FieldType b) {
return object.Equals(a,b);
}
public static bool operator !=(FieldType a, FieldType b) {
return !object.Equals(a,b);
}
}
}

View file

@ -0,0 +1,53 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing.Fields {
/// <summary>
/// Any element holding Fields must provide access to it.
/// AbstractFieldHolder is the basic implementation.
/// If you need the fieldHolder to have child fieldHolders,
/// you should consider using IFieldHolderWithChildren.
/// </summary>
public interface IFieldHolder {
event FieldChangedEventHandler FieldChanged;
void AddField(Field field);
void RemoveField(Field field);
List<Field> GetFields();
Field GetField(FieldType fieldType);
bool HasField(FieldType fieldType);
void SetFieldValue(FieldType fieldType, object value);
}
/// <summary>
/// Extended fieldHolder which has fieldHolder children.
/// Implementations should pass field values to and from
/// their children.
/// AbstractFieldHolderWithChildren is the basic implementation.
/// </summary>
public interface IFieldHolderWithChildren : IFieldHolder {
void AddChild(IFieldHolder fieldHolder);
void RemoveChild(IFieldHolder fieldHolder);
}
}

View file

@ -0,0 +1,90 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Drawing2D;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// empty container for filter-only elements
/// </summary>
[Serializable()]
public class FilterContainer : DrawableContainer {
public enum PreparedFilterMode {OBFUSCATE, HIGHLIGHT};
public enum PreparedFilter {BLUR, PIXELIZE, TEXT_HIGHTLIGHT, AREA_HIGHLIGHT, GRAYSCALE, MAGNIFICATION};
public PreparedFilter Filter {
get { return (PreparedFilter)GetFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT); }
}
public FilterContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.LINE_THICKNESS, GetType()));
AddField(FieldFactory.CreateField(FieldType.LINE_COLOR, GetType()));
AddField(FieldFactory.CreateField(FieldType.SHADOW));
}
public override void Draw(Graphics g, RenderMode rm) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor));
if (shadow && lineVisible) {
//draw shadow first
int basealpha = 100;
int alpha = basealpha;
int steps = 5;
int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) {
using (Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowPen.Width = lineVisible ? lineThickness : 1;
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(
this.Left + currentStep,
this.Top + currentStep,
this.Width,
this.Height);
g.DrawRectangle(shadowPen, shadowRect);
currentStep++;
alpha = alpha - (basealpha / steps);
}
}
}
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if(pen.Width > 0) {
g.DrawRectangle(pen, rect);
}
}
}
}
}

View file

@ -0,0 +1,121 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Drawing;
using System.Runtime.Serialization;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
/// <summary>
/// Graphical filter which can be added to DrawableContainer.
/// Subclasses should fulfill INotifyPropertyChanged contract, i.e. call
/// OnPropertyChanged whenever a public property has been changed.
/// </summary>
namespace Greenshot.Drawing.Filters {
[Serializable()]
public abstract class AbstractFilter : AbstractFieldHolder, IFilter {
[NonSerialized]
private PropertyChangedEventHandler propertyChanged;
public event PropertyChangedEventHandler PropertyChanged {
add { propertyChanged += value; }
remove{ propertyChanged -= value; }
}
private bool invert = false;
public bool Invert {
get { return invert; }
set { invert=value; OnPropertyChanged("Invert"); }
}
protected BitmapBuffer bbb;
protected Rectangle applyRect;
protected DrawableContainer parent;
public DrawableContainer Parent {
get {return parent;}
set {parent = value;}
}
public AbstractFilter(DrawableContainer parent) {
this.parent = parent;
}
public DrawableContainer GetParent() {
return parent;
}
/**
* This method fixes the problem that we can't apply a filter outside the target bitmap,
* therefor the filtered-bitmap will be shifted if we try to draw it outside the target bitmap.
* It will also account for the Invert flag.
*/
protected Rectangle IntersectRectangle(Size applySize, Rectangle rect) {
Rectangle myRect;
if (Invert) {
myRect = new Rectangle(0, 0, applySize.Width, applySize.Height);
} else {
Rectangle applyRect = new Rectangle(0,0, applySize.Width, applySize.Height);
myRect = new Rectangle(rect.X, rect.Y, rect.Width, rect.Height);
myRect.Intersect(applyRect);
}
return myRect;
}
public virtual void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) {
applyRect = IntersectRectangle(applyBitmap.Size, rect);
if (applyRect.Width == 0 || applyRect.Height == 0) {
// nothing to do
return;
}
bbb = new BitmapBuffer(applyBitmap, applyRect);
try {
bbb.Lock();
for(int y=0;y<bbb.Height; y++) {
for(int x=0;x<bbb.Width; x++) {
if(parent.Contains(applyRect.Left+x, applyRect.Top+y) ^ Invert) {
IteratePixel(x, y);
}
}
}
} finally {
bbb.DrawTo(graphics, applyRect.Location);
bbb.Dispose();
bbb = null;
}
}
public void Apply(Graphics graphics, Bitmap bmp, RenderMode renderMode) {
Apply(graphics, bmp, new Rectangle(0, 0, bmp.Width, bmp.Height), renderMode);
}
protected virtual void IteratePixel(int x, int y) {}
protected void OnPropertyChanged(string propertyName) {
if(propertyChanged != null) propertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
}

View file

@ -0,0 +1,241 @@
/// <summary>
/// Parts of this class were taken from BlurEffect.cs of Paint.NET 3.0.1,
/// which was released under MIT license.
/// http://www.getpaint.net
/// Some of this code has been adapted for integration with Greenshot.
/// See Paint.NET copyright notice below.
/// </summary>
/////////////////////////////////////////////////////////////////////////////////
// Paint.NET //
// Copyright (C) Rick Brewster, Tom Jackson, and past contributors. //
// Portions Copyright (C) Microsoft Corporation. All Rights Reserved. //
// See src/Resources/Files/License.txt for full licensing and attribution //
// details. //
// . //
/////////////////////////////////////////////////////////////////////////////////
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;
namespace Greenshot.Drawing.Filters {
[Serializable()]
public class BlurFilter : AbstractFilter {
public double previewQuality;
public double PreviewQuality {
get { return previewQuality; }
set { previewQuality = value; OnPropertyChanged("PreviewQuality"); }
}
public BlurFilter(DrawableContainer parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.BLUR_RADIUS, GetType()));
AddField(FieldFactory.CreateField(FieldType.PREVIEW_QUALITY));
}
public static int[] CreateGaussianBlurRow(int amount) {
int size = 1 + (amount * 2);
int[] weights = new int[size];
for (int i = 0; i <= amount; ++i)
{
// 1 + aa - aa + 2ai - ii
weights[i] = 16 * (i + 1);
weights[weights.Length - i - 1] = weights[i];
}
return weights;
}
public unsafe override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) {
applyRect = IntersectRectangle(applyBitmap.Size, rect);
if (applyRect.Height <= 0 || applyRect.Width <= 0) {
return;
}
int blurRadius = GetFieldValueAsInt(FieldType.BLUR_RADIUS);
double previewQuality = GetFieldValueAsDouble(FieldType.PREVIEW_QUALITY);
// do nothing when nothing can be done!
if (blurRadius < 1) {
return;
}
using (BitmapBuffer bbbDest = new BitmapBuffer(applyBitmap, applyRect)) {
bbbDest.Lock();
using (BitmapBuffer bbbSrc = new BitmapBuffer(applyBitmap, applyRect)) {
bbbSrc.Lock();
Random rand = new Random();
int r = blurRadius;
int[] w = CreateGaussianBlurRow(r);
int wlen = w.Length;
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;
long bSum = 0;
long gSum = 0;
long rSum = 0;
for (int wx = 0; wx < wlen; ++wx) {
int srcX = wx - r;
waSums[wx] = 0;
wcSums[wx] = 0;
aSums[wx] = 0;
bSums[wx] = 0;
gSums[wx] = 0;
rSums[wx] = 0;
if (srcX >= 0 && srcX < bbbDest.Width) {
for (int wy = 0; wy < wlen; ++wy) {
int srcY = y + wy - r;
if (srcY >= 0 && srcY < bbbDest.Height) {
int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY);
int wp = w[wy];
waSums[wx] += wp;
wp *= colors[0] + (colors[0] >> 7);
wcSums[wx] += wp;
wp >>= 8;
aSums[wx] += wp * colors[0];
bSums[wx] += wp * colors[3];
gSums[wx] += wp * colors[2];
rSums[wx] += wp * colors[1];
}
}
int wwx = w[wx];
waSum += wwx * waSums[wx];
wcSum += wwx * wcSums[wx];
aSum += wwx * aSums[wx];
bSum += wwx * bSums[wx];
gSum += wwx * gSums[wx];
rSum += wwx * rSums[wx];
}
}
wcSum >>= 8;
if (waSum == 0 || wcSum == 0) {
SetColorAt(bbbDest, 0, y, new int[]{0,0,0,0});
} else {
int alpha = (int)(aSum / waSum);
int blue = (int)(bSum / wcSum);
int green = (int)(gSum / wcSum);
int red = (int)(rSum / wcSum);
SetColorAt(bbbDest, 0, y, new int[]{alpha, red, green, blue});
}
for (int x = 1; x < applyRect.Width; ++x) {
for (int i = 0; i < wlen - 1; ++i) {
waSums[i] = waSums[i + 1];
wcSums[i] = wcSums[i + 1];
aSums[i] = aSums[i + 1];
bSums[i] = bSums[i + 1];
gSums[i] = gSums[i + 1];
rSums[i] = rSums[i + 1];
}
waSum = 0;
wcSum = 0;
aSum = 0;
bSum = 0;
gSum = 0;
rSum = 0;
int wx;
for (wx = 0; wx < wlen - 1; ++wx) {
long wwx = (long)w[wx];
waSum += wwx * waSums[wx];
wcSum += wwx * wcSums[wx];
aSum += wwx * aSums[wx];
bSum += wwx * bSums[wx];
gSum += wwx * gSums[wx];
rSum += wwx * rSums[wx];
}
wx = wlen - 1;
waSums[wx] = 0;
wcSums[wx] = 0;
aSums[wx] = 0;
bSums[wx] = 0;
gSums[wx] = 0;
rSums[wx] = 0;
int srcX = x + wx - r;
if (srcX >= 0 && srcX < applyRect.Width) {
for (int wy = 0; wy < wlen; ++wy) {
int srcY = y + wy - r;
// only when in EDIT mode, ignore some pixels depending on preview quality
if ((renderMode==RenderMode.EXPORT || rand.NextDouble()<previewQuality) && srcY >= 0 && srcY < applyRect.Height) {
int[] colors = bbbSrc.GetColorArrayAt(srcX, srcY);
int wp = w[wy];
waSums[wx] += wp;
wp *= colors[0] + (colors[0] >> 7);
wcSums[wx] += wp;
wp >>= 8;
aSums[wx] += wp * (long)colors[0];
bSums[wx] += wp * (long)colors[3];
gSums[wx] += wp * (long)colors[2];
rSums[wx] += wp * (long)colors[1];
}
}
int wr = w[wx];
waSum += (long)wr * waSums[wx];
wcSum += (long)wr * wcSums[wx];
aSum += (long)wr * aSums[wx];
bSum += (long)wr * bSums[wx];
gSum += (long)wr * gSums[wx];
rSum += (long)wr * rSums[wx];
}
wcSum >>= 8;
if (waSum == 0 || wcSum == 0) {
SetColorAt(bbbDest, x, y, new int[]{0,0,0,0});
} else {
int alpha = (int)(aSum / waSum);
int blue = (int)(bSum / wcSum);
int green = (int)(gSum / wcSum);
int red = (int)(rSum / wcSum);
SetColorAt(bbbDest, x, y, new int[]{alpha, red, green, blue});
}
}
}
}
bbbDest.DrawTo(graphics, applyRect.Location);
}
}
private void SetColorAt(BitmapBuffer bbb, int x, int y, int[] colors) {
if(parent.Contains(applyRect.Left+x, applyRect.Top+y) ^ Invert) {
bbb.SetColorArrayAt(x, y, colors);
}
}
}
}

View file

@ -0,0 +1,56 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
[Serializable()]
public class BrightnessFilter : AbstractFilter {
private double brightness;
public BrightnessFilter(DrawableContainer parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.BRIGHTNESS, GetType()));
}
protected override void IteratePixel(int x, int y) {
Color color = bbb.GetColorAt(x, y);
int r = Convert.ToInt16(color.R*brightness);
int g = Convert.ToInt16(color.G*brightness);
int b = Convert.ToInt16(color.B*brightness);
r = (r>255) ? 255 : r;
g = (g>255) ? 255 : g;
b = (b>255) ? 255 : b;
bbb.SetColorAt(x, y, Color.FromArgb(color.A, r, g, b));
}
public override void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode) {
brightness = GetFieldValueAsDouble(FieldType.BRIGHTNESS);
base.Apply(graphics, bmp, rect, renderMode);
}
}
}

View file

@ -0,0 +1,231 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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(FieldFactory.CreateField(FieldType.BLUR_RADIUS, GetType()));
}
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

@ -0,0 +1,48 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
/// <summary>
/// Description of GrayscaleFilter.
/// </summary>
[Serializable()]
public class GrayscaleFilter : AbstractFilter {
public GrayscaleFilter(DrawableContainer parent) : base(parent) {
}
protected override void IteratePixel(int x, int y) {
Color color = bbb.GetColorAt(x, y);
int luma = (int)((0.3*color.R) + (0.59*color.G) + (0.11*color.B));
color = Color.FromArgb(luma, luma, luma);
bbb.SetColorAt(x, y, color);
}
public override void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode) {
base.Apply(graphics, bmp, rect, renderMode);
}
}
}

View file

@ -0,0 +1,51 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
[Serializable()]
public class HighlightFilter : AbstractFilter {
[NonSerialized]
private Color highlightColor;
public HighlightFilter(DrawableContainer parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.FILL_COLOR, GetType(), Color.Yellow));
}
protected override void IteratePixel(int x, int y) {
Color color = bbb.GetColorAt(x, y);
color = Color.FromArgb(color.A, Math.Min(highlightColor.R,color.R), Math.Min(highlightColor.G,color.G), Math.Min(highlightColor.B,color.B));
bbb.SetColorAt(x, y, color);
}
public override void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode) {
highlightColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
base.Apply(graphics, bmp, rect, renderMode);
}
}
}

View file

@ -0,0 +1,37 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Drawing;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
public interface IFilter : INotifyPropertyChanged, IFieldHolder {
DrawableContainer Parent {get; set; }
void Apply(Graphics graphics, Bitmap bmp, RenderMode renderMode);
void Apply(Graphics graphics, Bitmap bmp, Rectangle rect, RenderMode renderMode);
DrawableContainer GetParent();
}
}

View file

@ -0,0 +1,65 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
[Serializable()]
public class MagnifierFilter : AbstractFilter {
private BitmapBuffer bbbSrc;
private int magnificationFactor;
public MagnifierFilter(DrawableContainer parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.MAGNIFICATION_FACTOR));
}
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) {
magnificationFactor = GetFieldValueAsInt(FieldType.MAGNIFICATION_FACTOR);
applyRect = IntersectRectangle(applyBitmap.Size, rect);
bbbSrc = new BitmapBuffer(applyBitmap, applyRect);
try {
bbbSrc.Lock();
base.Apply(graphics, applyBitmap, applyRect, renderMode);
} finally {
bbbSrc.Dispose();
bbbSrc = null;
}
}
protected override void IteratePixel(int x, int y) {
int halfWidth = bbb.Size.Width/2;
int halfHeight = bbb.Size.Height/2;
int yDistanceFromCenter = halfHeight-y;
int xDistanceFromCenter = halfWidth-x;
Color color = bbbSrc.GetColorAt(halfWidth-xDistanceFromCenter/magnificationFactor,halfHeight-yDistanceFromCenter/magnificationFactor);
bbb.SetColorAt(x, y, color);
}
}
}

View file

@ -0,0 +1,82 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Runtime.Serialization;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing.Filters {
[Serializable()]
public class PixelizationFilter : AbstractFilter {
public PixelizationFilter(DrawableContainer parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.PIXEL_SIZE));
}
public override void Apply(Graphics graphics, Bitmap applyBitmap, Rectangle rect, RenderMode renderMode) {
applyRect = IntersectRectangle(applyBitmap.Size, rect);
int pixelSize = GetFieldValueAsInt(FieldType.PIXEL_SIZE);
if(pixelSize <= 1 || applyRect.Width == 0 || applyRect.Height == 0) {
// Nothing to do
return;
}
if(applyRect.Width < pixelSize) pixelSize = applyRect.Width;
if(applyRect.Height < pixelSize) pixelSize = applyRect.Height;
using (BitmapBuffer bbbDest = new BitmapBuffer(applyBitmap, applyRect)) {
bbbDest.Lock();
using(BitmapBuffer bbbSrc = new BitmapBuffer(applyBitmap, applyRect)) {
bbbSrc.Lock();
List<Color> colors = new List<Color>();
int halbPixelSize = pixelSize/2;
for(int y=-halbPixelSize;y<bbbSrc.Height+halbPixelSize; y=y+pixelSize) {
for(int x=-halbPixelSize;x<=bbbSrc.Width+halbPixelSize; x=x+pixelSize) {
colors.Clear();
for(int yy=y;yy<y+pixelSize;yy++) {
if (yy >=0 && yy < bbbSrc.Height) {
for(int xx=x;xx<x+pixelSize;xx++) {
colors.Add(bbbSrc.GetColorAt(xx,yy));
}
}
}
Color currentAvgColor = Colors.Mix(colors);
for(int yy=y;yy<=y+pixelSize;yy++) {
if (yy >=0 && yy < bbbSrc.Height) {
for(int xx=x;xx<=x+pixelSize;xx++) {
bbbDest.SetColorAt(xx, yy, currentAvgColor);
}
}
}
}
}
}
bbbDest.DrawTo(graphics, applyRect.Location);
}
}
}
}

View file

@ -0,0 +1,83 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
namespace Greenshot.Drawing {
/// <summary>
/// Description of ObfuscateContainer.
/// </summary>
[Serializable()]
public class HighlightContainer : FilterContainer {
public HighlightContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.PREPARED_FILTER_HIGHLIGHT));
init();
}
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
init();
}
private void init() {
FieldChanged += HighlightContainer_OnFieldChanged;
ConfigurePreparedFilters();
}
protected void HighlightContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) {
if(sender.Equals(this)) {
if (e.Field.FieldType == FieldType.PREPARED_FILTER_HIGHLIGHT) {
ConfigurePreparedFilters();
}
}
}
private void ConfigurePreparedFilters() {
PreparedFilter preset = (PreparedFilter)GetFieldValue(FieldType.PREPARED_FILTER_HIGHLIGHT);
while(Filters.Count>0) {
Remove(Filters[0]);
}
switch(preset) {
case PreparedFilter.TEXT_HIGHTLIGHT:
Add(new HighlightFilter(this));
break;
case PreparedFilter.AREA_HIGHLIGHT:
AbstractFilter bf = new BrightnessFilter(this);
bf.Invert = true;
Add(bf);
bf = new BlurFilter(this);
bf.Invert = true;
Add(bf);
break;
case PreparedFilter.GRAYSCALE:
AbstractFilter f = new GrayscaleFilter(this);
f.Invert = true;
Add(f);
break;
case PreparedFilter.MAGNIFICATION:
Add(new MagnifierFilter(this));
break;
}
}
}
}

View file

@ -0,0 +1,124 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.IO;
using System.Runtime.Serialization;
using System.Text.RegularExpressions;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Description of BitmapContainer.
/// </summary>
[Serializable()]
public class HtmlContainer : DrawableContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(HtmlContainer));
private const string SCRIPT_PATTERN = "<script(.*?)</script>";
private string html = null;
private Bitmap bitmap = null;
private Size lastSize = new Size(0,0);
public HtmlContainer(Surface parent, string html) : this(parent) {
Html = html;
}
public HtmlContainer(Surface parent) : base(parent) {
Width = 100;
Height = 100;
}
private void removeScripts() {
Regex regExRemoveScript = new Regex(SCRIPT_PATTERN);
html = regExRemoveScript.Replace(html, "");
}
public string Html {
set {
html = value;
removeScripts();
lastSize = new Size(0, 0);
RedrawIfNeeded();
}
get { return html; }
}
/**
* Destructor
*/
~HtmlContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (bitmap != null) {
bitmap.Dispose();
}
}
bitmap = null;
}
protected void RedrawIfNeeded() {
if (html == null) {
if (bitmap != null) {
bitmap.Dispose();
}
bitmap = null;
return;
}
if (bitmap == null || lastSize.Height != Height || lastSize.Width != Width) {
bitmap = WebsiteImageGenerator.GetImageFromHTML(html);
if (bitmap != null) {
lastSize = new Size(bitmap.Width, bitmap.Height);
}
}
}
public override void Draw(Graphics g, RenderMode rm) {
RedrawIfNeeded();
if (bitmap != null) {
g.DrawImage(bitmap, Bounds);
}
}
}
}

View file

@ -0,0 +1,108 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.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 {
/// <summary>
/// Description of IconContainer.
/// </summary>
[Serializable()]
public class IconContainer : DrawableContainer, IIconContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(IconContainer));
protected Icon icon;
public IconContainer(Surface parent) : base(parent) {
}
public IconContainer(Surface parent, string filename) : base(parent) {
Load(filename);
}
public Icon Icon {
set {
if (icon != null) {
icon.Dispose();
}
icon = (Icon)value.Clone();
Width = value.Width;
Height = value.Height;
}
get { return icon; }
}
/**
* Destructor
*/
~IconContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (icon != null) {
icon.Dispose();
}
}
icon = null;
}
public void Load(string filename) {
if (File.Exists(filename)) {
using (Icon fileIcon = new Icon(filename)) {
Icon = fileIcon;
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
}
public override void Draw(Graphics graphics, RenderMode rm) {
if (icon != null) {
graphics.DrawIcon(icon, Bounds);
}
}
}
}

View file

@ -0,0 +1,107 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Drawing2D;
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 {
/// <summary>
/// Description of LineContainer.
/// </summary>
[Serializable()]
public class LineContainer : DrawableContainer {
public static readonly int MAX_CLICK_DISTANCE_TOLERANCE = 10;
public LineContainer(Surface parent) : base(parent) {
Init();
AddField(FieldFactory.CreateField(FieldType.LINE_THICKNESS));
AddField(FieldFactory.CreateField(FieldType.LINE_COLOR));
AddField(FieldFactory.CreateField(FieldType.SHADOW));
}
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;
}
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);
if ( shadow && lineThickness > 0 ) {
//draw shadow first
int basealpha = 100;
int alpha = basealpha;
int steps = 5;
int currentStep = 1;
while (currentStep <= steps) {
using (Pen shadowCapPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowCapPen.Width = lineThickness;
g.DrawLine(shadowCapPen,
this.Left + currentStep,
this.Top + currentStep,
this.Left + currentStep + this.Width,
this.Top + currentStep + this.Height);
currentStep++;
alpha = alpha - (basealpha / steps);
}
}
}
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);
}
}
}
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) {
return false;
}
return distance <= Math.Max(lineThickness / 2, MAX_CLICK_DISTANCE_TOLERANCE);
}
}
}

View file

@ -0,0 +1,123 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.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 {
/// <summary>
/// Description of MetafileContainer.
/// </summary>
[Serializable()]
public class MetafileContainer : DrawableContainer, IMetafileContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(MetafileContainer));
protected Metafile metafile;
public MetafileContainer(Surface parent) : base(parent) {
}
public MetafileContainer(Surface parent, string filename) : base(parent) {
Load(filename);
}
public Metafile Metafile {
set {
if (metafile != null) {
metafile.Dispose();
}
metafile = (Metafile)value.Clone();
Height = Math.Abs(value.Height);
if (Height == 0 ) {
Height = 100;
}
Width = Math.Abs(value.Width);
if (Width == 0 ) {
Width = 100;
}
while (Height > parent.Height) {
Height = Height / 4;
Width = Width / 4;
}
while (Width > parent.Width) {
Height = Height / 4;
Width = Width / 4;
}
}
get { return metafile; }
}
/**
* Destructor
*/
~MetafileContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (metafile != null) {
metafile.Dispose();
}
}
metafile = null;
}
public void Load(string filename) {
if (File.Exists(filename)) {
using (Metafile fileMetafile = new Metafile(filename)) {
Metafile = fileMetafile;
LOG.Debug("Loaded file: " + filename + " with resolution: " + Height + "," + Width);
}
}
}
public override void Draw(Graphics graphics, RenderMode rm) {
if (metafile != null) {
graphics.DrawImage(metafile, Bounds);
}
}
}
}

View file

@ -0,0 +1,70 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Runtime.Serialization;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Filters;
namespace Greenshot.Drawing {
/// <summary>
/// Description of ObfuscateContainer.
/// </summary>
[Serializable()]
public class ObfuscateContainer : FilterContainer {
public ObfuscateContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.PREPARED_FILTER_OBFUSCATE));
init();
}
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
init();
}
private void init() {
FieldChanged += ObfuscateContainer_OnFieldChanged;
ConfigurePreparedFilters();
}
protected void ObfuscateContainer_OnFieldChanged(object sender, FieldChangedEventArgs e) {
if(sender.Equals(this)) {
if(e.Field.FieldType == FieldType.PREPARED_FILTER_OBFUSCATE) {
ConfigurePreparedFilters();
}
}
}
private void ConfigurePreparedFilters() {
PreparedFilter preset = (PreparedFilter)GetFieldValue(FieldType.PREPARED_FILTER_OBFUSCATE);
while(Filters.Count>0) {
Remove(Filters[0]);
}
switch(preset) {
case PreparedFilter.BLUR:
Add(new BlurFilter(this));
break;
case PreparedFilter.PIXELIZE:
Add(new PixelizationFilter(this));
break;
}
}
}
}

View file

@ -0,0 +1,90 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Represents a rectangular shape on the Surface
/// </summary>
[Serializable()]
public class RectangleContainer : DrawableContainer {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(RectangleContainer));
public RectangleContainer(Surface parent) : base(parent) {
AddField(FieldFactory.CreateField(FieldType.LINE_THICKNESS));
AddField(FieldFactory.CreateField(FieldType.LINE_COLOR));
AddField(FieldFactory.CreateField(FieldType.FILL_COLOR));
AddField(FieldFactory.CreateField(FieldType.SHADOW));
}
public override void Draw(Graphics g, RenderMode rm) {
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
bool lineVisible = (lineThickness > 0 && Colors.IsVisible(lineColor));
if (shadow && (lineVisible || Colors.IsVisible(fillColor))) {
//draw shadow first
int basealpha = 100;
int alpha = basealpha;
int steps = 5;
int currentStep = lineVisible ? 1 : 0;
while (currentStep <= steps) {
using (Pen shadowPen = new Pen(Color.FromArgb(alpha, 100, 100, 100))) {
shadowPen.Width = lineVisible ? lineThickness : 1;
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(
this.Left + currentStep,
this.Top + currentStep,
this.Width,
this.Height);
g.DrawRectangle(shadowPen, shadowRect);
currentStep++;
alpha = alpha - (basealpha / steps);
}
}
}
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
using (Brush brush = new SolidBrush(fillColor)) {
g.FillRectangle(brush, rect);
}
using (Pen pen = new Pen(lineColor)) {
pen.Width = lineThickness;
if(pen.Width > 0) {
g.DrawRectangle(pen, rect);
}
}
}
}
}

View file

@ -0,0 +1,130 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
namespace Greenshot.Drawing {
public abstract class RoundedRectangle {
public enum RectangleCorners {
None = 0, TopLeft = 1, TopRight = 2,
BottomLeft = 4, BottomRight = 8,
All = TopLeft | TopRight | BottomLeft | BottomRight
}
public static GraphicsPath Create2(int x, int y, int width, int height, int radius) {
GraphicsPath gp = new GraphicsPath();
gp.AddLine(x + radius, y, x + width - (radius * 2), y); // Line
gp.AddArc(x + width - (radius * 2), y, radius * 2, radius * 2, 270, 90); // Corner
gp.AddLine(x + width, y + radius, x + width, y + height - (radius * 2)); // Line
gp.AddArc(x + width - (radius * 2), y + height - (radius * 2), radius * 2, radius * 2, 0, 90); // Corner
gp.AddLine(x + width - (radius * 2), y + height, x + radius, y + height); // Line
gp.AddArc(x, y + height - (radius * 2), radius * 2, radius * 2, 90, 90); // Corner
gp.AddLine(x, y + height - (radius * 2), x, y + radius); // Line
gp.AddArc(x, y, radius * 2, radius * 2, 180, 90); // Corner
gp.CloseFigure();
return gp;
}
public static GraphicsPath Create(int x, int y, int width, int height, int radius, RectangleCorners corners) {
int xw = x + width;
int yh = y + height;
int xwr = xw - radius;
int yhr = yh - radius;
int xr = x + radius;
int yr = y + radius;
int r2 = radius * 2;
int xwr2 = xw - r2;
int yhr2 = yh - r2;
GraphicsPath p = new GraphicsPath();
p.StartFigure();
//Top Left Corner
if ((RectangleCorners.TopLeft & corners) == RectangleCorners.TopLeft) {
p.AddArc(x, y, r2, r2, 180, 90);
} else {
p.AddLine(x, yr, x, y);
p.AddLine(x, y, xr, y);
}
//Top Edge
p.AddLine(xr, y, xwr, y);
//Top Right Corner
if ((RectangleCorners.TopRight & corners) == RectangleCorners.TopRight) {
p.AddArc(xwr2, y, r2, r2, 270, 90);
} else {
p.AddLine(xwr, y, xw, y);
p.AddLine(xw, y, xw, yr);
}
//Right Edge
p.AddLine(xw, yr, xw, yhr);
//Bottom Right Corner
if ((RectangleCorners.BottomRight & corners) == RectangleCorners.BottomRight) {
p.AddArc(xwr2, yhr2, r2, r2, 0, 90);
} else {
p.AddLine(xw, yhr, xw, yh);
p.AddLine(xw, yh, xwr, yh);
}
//Bottom Edge
p.AddLine(xwr, yh, xr, yh);
//Bottom Left Corner
if ((RectangleCorners.BottomLeft & corners) == RectangleCorners.BottomLeft) {
p.AddArc(x, yhr2, r2, r2, 90, 90);
} else {
p.AddLine(xr, yh, x, yh);
p.AddLine(x, yh, x, yhr);
}
//Left Edge
p.AddLine(x, yhr, x, yr);
p.CloseFigure();
return p;
}
public static GraphicsPath Create(Rectangle rect, int radius, RectangleCorners corners) {
return Create(rect.X, rect.Y, rect.Width, rect.Height, radius, corners);
}
public static GraphicsPath Create(int x, int y, int width, int height, int radius) {
return Create(x, y, width, height, radius, RectangleCorners.All);
}
public static GraphicsPath Create(Rectangle rect, int radius) {
return Create(rect.X, rect.Y, rect.Width, rect.Height, radius);
}
public static GraphicsPath Create(int x, int y, int width, int height) {
return Create(x, y, width, height, 5);
}
public static GraphicsPath Create(Rectangle rect) {
return Create(rect.X, rect.Y, rect.Width, rect.Height);
}
}
}

View file

@ -0,0 +1,852 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.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;
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 }
/// <summary>
/// Description of Surface.
/// </summary>
public class Surface : PictureBox, ISurface {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(Surface));
public event SurfaceElementEventHandler MovingElementChanged;
public event SurfaceDrawingModeEventHandler DrawingModeChanged;
public FieldAggregator FieldAggregator = new FieldAggregator();
private AppConfig conf = AppConfig.GetInstance();
private ICaptureDetails captureDetails = null;
private int mX;
private int mY;
private bool mouseDown = false;
private bool draggingInProgress = false;
private DrawableContainer mouseDownElement = null;
private Image originalImage;
private DrawableContainerList elements = new DrawableContainerList();
private DrawableContainerList selectedElements = new DrawableContainerList();
private DrawableContainer drawingElement = null;
private DrawableContainer undrawnElement = null;
private DrawableContainer cropContainer = null;
public bool KeysLocked = false;
private DrawingModes drawingMode = DrawingModes.None;
public DrawingModes DrawingMode {
get {return drawingMode;}
set {
drawingMode = value;
DrawingModeChanged.Invoke(this, drawingMode);
DeselectAllElements();
CreateUndrawnElement();
}
}
public Image OriginalImage {
get { return originalImage; }
}
public ICaptureDetails CaptureDetails {
get {return captureDetails;}
set {captureDetails = value;}
}
public Surface() {
LOG.Debug("Creating a surface!");
SizeMode = PictureBoxSizeMode.AutoSize;
this.MouseDown += new MouseEventHandler(SurfaceMouseDown);
this.MouseUp += new MouseEventHandler(SurfaceMouseUp);
this.MouseMove += new MouseEventHandler(SurfaceMouseMove);
this.MouseDoubleClick += new MouseEventHandler(SurfaceDoubleClick);
this.Paint += new PaintEventHandler(SurfacePaint);
this.AllowDrop = true;
this.DragDrop += new DragEventHandler(OnDragDrop);
this.DragEnter += new DragEventHandler(OnDragEnter);
}
private void SetImage(Image image) {
if (originalImage != null) {
originalImage.Dispose();
}
if (Image != null) {
Image.Dispose();
}
originalImage = new Bitmap(image);
Image = new Bitmap(image);
}
public Surface(Image image) : this() {
LOG.Debug("Got image with dimensions " + image.Width + "," + image.Height + " bpp: " + image.PixelFormat);
SetImage(image);
}
public Surface(ICapture capture) : this(capture.Image) {
if (capture.Cursor != null && capture.CursorVisible) {
SelectElement(AddIconContainer(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y));
}
captureDetails = capture.CaptureDetails;
}
public void SaveElementsToStream(Stream streamWrite) {
try {
BinaryFormatter binaryWrite = new BinaryFormatter();
binaryWrite.Serialize(streamWrite, elements);
} catch (Exception e) {
LOG.Error("Error serializing elements to stream.", e);
}
}
public void LoadElementsFromStream(Stream streamRead) {
try {
BinaryFormatter binaryRead = new BinaryFormatter();
DrawableContainerList loadedElements = (DrawableContainerList) binaryRead.Deserialize(streamRead);
if (loadedElements != null) {
loadedElements.Parent = this;
DeselectAllElements();
AddElements(loadedElements);
SelectElements(loadedElements);
FieldAggregator.BindElements(loadedElements);
}
} catch (Exception e) {
LOG.Error("Error serializing elements from stream.", e);
}
}
private void CreateUndrawnElement() {
if(undrawnElement != null) {
FieldAggregator.UnbindElement(undrawnElement);
}
switch (DrawingMode) {
case DrawingModes.Rect:
undrawnElement = new RectangleContainer(this);
break;
case DrawingModes.Ellipse:
undrawnElement = new EllipseContainer(this);
break;
case DrawingModes.Text:
undrawnElement = new TextContainer(this);
break;
case DrawingModes.Line:
undrawnElement = new LineContainer(this);
break;
case DrawingModes.Arrow:
undrawnElement = new ArrowContainer(this);
break;
case DrawingModes.Highlight:
undrawnElement = new HighlightContainer(this);
break;
case DrawingModes.Obfuscate:
undrawnElement = new ObfuscateContainer(this);
break;
case DrawingModes.Crop:
cropContainer = new CropContainer(this);
undrawnElement = cropContainer;
break;
case DrawingModes.Bitmap:
undrawnElement = new BitmapContainer(this);
break;
case DrawingModes.None:
undrawnElement = null;
break;
}
if (undrawnElement != null) {
FieldAggregator.BindElement(undrawnElement);
}
}
#region Plugin interface implementations
public IBitmapContainer AddBitmapContainer(Bitmap bitmap, int x, int y) {
BitmapContainer bitmapContainer = new BitmapContainer(this);
bitmapContainer.Bitmap = bitmap;
bitmapContainer.Left = x;
bitmapContainer.Top = y;
AddElement(bitmapContainer);
return bitmapContainer;
}
private HtmlContainer AddHtmlContainer(string html, int x, int y) {
HtmlContainer htmlContainer = new HtmlContainer(this);
htmlContainer.Left = x;
htmlContainer.Top = y;
htmlContainer.Html = html;
AddElement(htmlContainer);
return htmlContainer;
}
private UrlContainer AddUrlContainer(string url, int x, int y) {
UrlContainer urlContainer = new UrlContainer(this);
urlContainer.Left = x;
urlContainer.Top = y;
urlContainer.Url = url;
AddElement(urlContainer);
return urlContainer;
}
public IBitmapContainer AddBitmapContainer(string filename, int x, int y) {
BitmapContainer bitmapContainer = new BitmapContainer(this);
bitmapContainer.Load(filename);
bitmapContainer.Left = x;
bitmapContainer.Top = y;
AddElement(bitmapContainer);
return bitmapContainer;
}
public IIconContainer AddIconContainer(Icon icon, int x, int y) {
IconContainer iconContainer = new IconContainer(this);
iconContainer.Icon = icon;
iconContainer.Left = x;
iconContainer.Top = y;
AddElement(iconContainer);
return iconContainer;
}
public IIconContainer AddIconContainer(string filename, int x, int y) {
IconContainer iconContainer = new IconContainer(this);
iconContainer.Load(filename);
iconContainer.Left = x;
iconContainer.Top = y;
AddElement(iconContainer);
return iconContainer;
}
public ICursorContainer AddCursorContainer(Cursor cursor, int x, int y) {
CursorContainer cursorContainer = new CursorContainer(this);
cursorContainer.Cursor = cursor;
cursorContainer.Left = x;
cursorContainer.Top = y;
AddElement(cursorContainer);
return cursorContainer;
}
public ICursorContainer AddCursorContainer(string filename, int x, int y) {
CursorContainer cursorContainer = new CursorContainer(this);
cursorContainer.Load(filename);
cursorContainer.Left = x;
cursorContainer.Top = y;
AddElement(cursorContainer);
return cursorContainer;
}
public IMetafileContainer AddMetafileContainer(string filename, int x, int y) {
MetafileContainer metafileContainer = new MetafileContainer(this);
metafileContainer.Load(filename);
metafileContainer.Left = x;
metafileContainer.Top = y;
AddElement(metafileContainer);
return metafileContainer;
}
public IMetafileContainer AddMetafileContainer(Metafile metafile, int x, int y) {
MetafileContainer metafileContainer = new MetafileContainer(this);
metafileContainer.Metafile = metafile;
metafileContainer.Left = x;
metafileContainer.Top = y;
AddElement(metafileContainer);
return metafileContainer;
}
public ITextContainer AddTextContainer(string text, HorizontalAlignment horizontalAlignment, VerticalAlignment verticalAlignment, FontFamily family, float size, bool italic, bool bold, bool shadow, int borderSize, Color color, Color fillColor) {
TextContainer textContainer = new TextContainer(this);
textContainer.Text = text;
textContainer.SetFieldValue(FieldType.FONT_FAMILY, family.Name);
textContainer.SetFieldValue(FieldType.FONT_BOLD, bold);
textContainer.SetFieldValue(FieldType.FONT_ITALIC, italic);
textContainer.SetFieldValue(FieldType.FONT_SIZE, size);
textContainer.SetFieldValue(FieldType.FILL_COLOR, fillColor);
textContainer.SetFieldValue(FieldType.LINE_COLOR, color);
textContainer.SetFieldValue(FieldType.LINE_THICKNESS, borderSize);
textContainer.SetFieldValue(FieldType.SHADOW, shadow);
// Make sure the Text fits
textContainer.FitToText();
// Align to Surface
textContainer.AlignToParent(horizontalAlignment, verticalAlignment);
//AggregatedProperties.UpdateElement(textContainer);
AddElement(textContainer);
return textContainer;
}
#endregion
#region DragDrop
private List<string> GetFilenames(DragEventArgs e) {
List<string> filenames = new List<string>();
string[] dropFileNames = (string[])e.Data.GetData(DataFormats.FileDrop);
if (dropFileNames != null && dropFileNames.Length > 0) {
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")) {
filenames.Add(filename);
}
}
}
return filenames;
}
private void OnDragEnter(object sender, DragEventArgs e) {
if(LOG.IsDebugEnabled) {
LOG.Debug("DragEnter got following formats: ");
foreach(string format in e.Data.GetFormats()) {
LOG.Debug(format);
}
}
if (draggingInProgress || (e.AllowedEffect & DragDropEffects.Copy) != DragDropEffects.Copy) {
e.Effect=DragDropEffects.None;
} else {
List<string> filenames = GetFilenames(e);
if ( (filenames != null && filenames.Count > 0)
|| e.Data.GetDataPresent(DataFormats.Bitmap, true)
//|| e.Data.GetDataPresent(DataFormats.EnhancedMetafile, true)
) {
e.Effect=DragDropEffects.Copy;
} else {
e.Effect=DragDropEffects.None;
}
}
}
private void OnDragDrop(object sender, DragEventArgs e) {
List<string> filenames = GetFilenames(e);
Point mouse = this.PointToClient(new Point(e.X, e.Y));
if ((filenames != null && filenames.Count > 0)) {
foreach(string filename in filenames) {
LOG.Debug("Drop - filename: " + filename);
AddBitmapContainer(filename, mouse.X, mouse.Y);
mouse.Offset(10, 10);
}
} else if (e.Data.GetDataPresent(DataFormats.Bitmap)) {
AddBitmapContainer((Bitmap)e.Data.GetData(DataFormats.Bitmap, true), mouse.X, mouse.Y);
// } else if (e.Data.GetDataPresent(DataFormats.EnhancedMetafile)) {
// AddBitmapContainer((Image)e.Data.GetData(DataFormats.EnhancedMetafile, true), mouse.X, mouse.Y);
}
}
// private void QueryContinueDragDrop(object sender, QueryContinueDragEventArgs e) {
// LOG.Debug("QueryContinueDrag: " + e.Action);
// if (e.EscapePressed) {
// e.Action = DragAction.Cancel;
// }
// }
//
// private void GiveFeedbackDragDrop(object sender, GiveFeedbackEventArgs e) {
// e.UseDefaultCursors = true;
// }
#endregion
void ApplyCrop() {
Rectangle r = cropContainer.Bounds;
r = Helpers.GuiRectangle.GetGuiRectangle(r.Left, r.Top, r.Width, r.Height);
if (r.Left < 0) r = new Rectangle(0, r.Top, r.Width + r.Left, r.Height);
if (r.Top < 0) r = new Rectangle(r.Left, 0, r.Width, r.Height + r.Top);
if (r.Left + r.Width > Width) r = new Rectangle(r.Left, r.Top, Width - r.Left, r.Height);
if (r.Top + r.Height > Height) r = new Rectangle(r.Left, r.Top, r.Width, Height - r.Top);
if (r.Height > 0 && r.Width > 0) {
// we should not forget to Dispose the images!!
using (Bitmap tmpImage = ((Bitmap)originalImage).Clone(r, originalImage.PixelFormat)) {
tmpImage.SetResolution(originalImage.HorizontalResolution, originalImage.VerticalResolution);
SetImage(tmpImage);
elements.MoveBy(-r.Left, -r.Top);
}
}
}
void SurfaceMouseDown(object sender, MouseEventArgs e) {
mX = e.X; mY = e.Y;
mouseDown = true;
if (cropContainer != null && ((undrawnElement == null) || (undrawnElement != null && DrawingMode != DrawingModes.Crop))) {
RemoveElement(cropContainer);
cropContainer = null;
drawingElement = null;
}
if(drawingElement == null && DrawingMode != DrawingModes.None) {
if (undrawnElement == null) {
DeselectAllElements();
if(undrawnElement == null) {
CreateUndrawnElement();
}
}
drawingElement = undrawnElement;
drawingElement.Status = EditStatus.DRAWING;
undrawnElement = null;
// if a new element has been drawn, set location and register it
if (drawingElement != null) {
drawingElement.PropertyChanged += ElementPropertyChanged;
drawingElement.Left = e.X;
drawingElement.Top = e.Y;
AddElement(drawingElement);
drawingElement.Selected = true;
}
} else {
// check whether an existing element was clicked
// 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(e.X, e.Y);
if(mouseDownElement != null) {
mouseDownElement.Status = EditStatus.MOVING;
}
}
}
void SurfaceMouseUp(object sender, MouseEventArgs e) {
elements.Status = EditStatus.IDLE;
if(mouseDownElement != null) {
mouseDownElement.Status = EditStatus.IDLE;
}
mouseDown = false;
mouseDownElement = null;
if(DrawingMode == DrawingModes.None) { // check whether an existing element was clicked
DrawableContainer element = elements.ClickableElementAt(e.X, e.Y);
bool shiftModifier = (Control.ModifierKeys & Keys.Shift) == Keys.Shift;
if(element != null) {
bool alreadySelected = selectedElements.Contains(element);
if(shiftModifier) {
if(alreadySelected) DeselectElement(element);
else SelectElement(element);
} else {
if(!alreadySelected) {
DeselectAllElements();
SelectElement(element);
}
}
} else if(!shiftModifier) {
DeselectAllElements();
}
}
if (selectedElements.Count > 0) {
selectedElements.ShowGrippers();
selectedElements.Selected = true;
}
if (drawingElement != null) {
if (!drawingElement.InitContent()) {
elements.Remove(drawingElement);
Invalidate();
} else {
if (Math.Abs(drawingElement.Width) < 5 && Math.Abs(drawingElement.Height) < 5) {
drawingElement.Width = 25;
drawingElement.Height = 25;
}
SelectElement(drawingElement);
drawingElement.Selected = true;
}
drawingElement = null;
}
Invalidate();
}
void SurfaceMouseMove(object sender, MouseEventArgs e) {
if (DrawingMode != DrawingModes.None) {
Cursor = Cursors.Cross;
} else {
Cursor = Cursors.Default;
}
if(mouseDown) {
if(mouseDownElement != null) { // an element is currently dragged
selectedElements.HideGrippers();
if(mouseDownElement.Selected) { // dragged element has been selected before -> move all
selectedElements.MoveBy(e.X - mX, e.Y - mY);
} else { // dragged element is not among selected elements -> just move dragged one
mouseDownElement.MoveBy(e.X - mX, e.Y - mY);
}
mX = e.X; mY = e.Y;
Invalidate();
} else if(drawingElement != null) { // an element is currently drawn
drawingElement.Width = e.X - drawingElement.Left;
drawingElement.Height = e.Y - drawingElement.Top;
Invalidate();
// } else {
// // Enable DragDrop
// using (Bitmap bitmapToDrag = GetImageForExport()) {
//
// IDataObject dataObj = new DataObject();
// string filename = Path.GetTempFileName() + ".png";
// try {
// bitmapToDrag.Save(filename, ImageFormat.Png);
// LOG.Debug("FileDrop : " + filename);
// dataObj.SetData("HTML Format", true, "<img src=\"" + filename + "\"/>");
// //dataObj.SetData(DataFormats.FileDrop, new string[] {filename});
// LOG.Debug("Starting DoDragDrop");
// draggingInProgress = true;
// DoDragDrop(dataObj, DragDropEffects.Copy);
// LOG.Debug("Finished DoDragDrop");
// draggingInProgress = false;
// mouseDown = false;
// } catch (Exception ex) {
// LOG.Error("Error in DragDrop: ", ex);
// } finally {
// File.Delete(filename);
// }
// }
}
}
}
void SurfaceDoubleClick(object sender, MouseEventArgs e) {
selectedElements.OnDoubleClick();
Invalidate();
}
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...
// otherwise we would have a problem drawing the image to the surface... :(
using (Graphics graphics = Graphics.FromImage(clone)) {
graphics.DrawImage(originalImage, Point.Empty);
elements.Draw(graphics, (Bitmap)clone, renderMode);
}
return clone;
}
public Image GetImageForExport() {
return GetImage(RenderMode.EXPORT);
}
void SurfacePaint(object sender, PaintEventArgs e) {
Graphics graphics = e.Graphics;
using (Image image = GetImage(RenderMode.EDIT)) {
graphics.DrawImage(image, Point.Empty);
}
// Should be something like this, but due to the filter structure this won't work
//graphics.DrawImage(originalImage, Point.Empty);
//elements.Draw(graphics, (Bitmap)Image, RenderMode.EDIT);
}
public void AddElement(DrawableContainer element) {
elements.Add(element);
element.FieldChanged += element_FieldChanged;
element.PropertyChanged += ElementPropertyChanged;
if(element.Status == EditStatus.UNDRAWN) element.Status = EditStatus.IDLE;
Invalidate();
}
public void RemoveElement(DrawableContainer element) {
DeselectElement(element);
elements.Remove(element);
element.FieldChanged -= element_FieldChanged;
element.PropertyChanged -= ElementPropertyChanged;
element.Dispose();
Invalidate();
}
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;
}
Invalidate();
}
public bool HasSelectedElements() {
return (selectedElements != null && selectedElements.Count > 0);
}
public void RemoveSelectedElements() {
if (HasSelectedElements()) {
foreach (DrawableContainer element in selectedElements) {
elements.Remove(element);
element.FieldChanged -= element_FieldChanged;
element.PropertyChanged -= ElementPropertyChanged;
element.Dispose();
}
selectedElements.Clear();
MovingElementChanged(this, selectedElements);
Invalidate();
}
}
public void CutSelectedElements() {
if (HasSelectedElements()) {
ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), selectedElements);
RemoveSelectedElements();
}
}
public void CopySelectedElements() {
if (HasSelectedElements()) {
ClipboardHelper.SetClipboardData(typeof(DrawableContainerList), selectedElements);
}
}
public void ConfirmSelectedConfirmableElements(bool confirm){
// create new collection so that we can iterate safely (selectedElements might change due with confirm/cancel)
List<DrawableContainer> selectedDCs = new List<DrawableContainer>(selectedElements);
foreach(DrawableContainer dc in selectedDCs){
if(dc.Equals(cropContainer)){
if(confirm) {
ApplyCrop();
}
DrawingMode = DrawingModes.None;
RemoveElement(cropContainer);
cropContainer.Dispose();
}
}
}
public void PasteElementFromClipboard() {
List<string> formats = ClipboardHelper.GetFormats();
if (formats == null || formats.Count == 0) {
return;
}
if (LOG.IsDebugEnabled) {
LOG.Debug("List of clipboard formats available for pasting:");
foreach(string format in formats) {
LOG.Debug("\tgot format: " + format);
}
}
if (formats.Contains(typeof(DrawableContainerList).FullName)) {
DrawableContainerList dcs = (DrawableContainerList)ClipboardHelper.GetClipboardData(typeof(DrawableContainerList));
if (dcs != null) {
dcs.Parent = this;
dcs.MoveBy(10,10);
AddElements(dcs);
FieldAggregator.BindElements(dcs);
DeselectAllElements();
SelectElements(dcs);
}
} else if (Clipboard.ContainsImage()) {
using (Image image = Clipboard.GetImage()) {
if (image != null) {
DeselectAllElements();
IBitmapContainer bitmapContainer = AddBitmapContainer(image as Bitmap, 0, 0);
SelectElement(bitmapContainer);
}
}
} else if ( ClipboardHelper.GetFormats().Contains("HTML Format")) {
HtmlFragment htmlFragment = HtmlFragment.FromClipboard();
DeselectAllElements();
HtmlContainer htmlContainer = AddHtmlContainer(htmlFragment.Fragment, 0, 0);
SelectElement(htmlContainer);
} else if (Clipboard.ContainsText()) {
string text = Clipboard.GetText();
if (text != null) {
if (text.StartsWith("http://")) {
DeselectAllElements();
UrlContainer urlContainer = AddUrlContainer(text, 0, 0);
SelectElement(urlContainer);
} else {
DeselectAllElements();
ITextContainer textContainer = AddTextContainer(text, HorizontalAlignment.Center, VerticalAlignment.CENTER,
FontFamily.GenericSansSerif, 12f, false, false, false, 2, Color.Black, Color.Transparent);
SelectElement(textContainer);
}
}
}
}
public void DuplicateSelectedElements() {
if(LOG.IsDebugEnabled) LOG.Debug("Duplicating "+selectedElements.Count+" selected elements");
DrawableContainerList dcs = (DrawableContainerList)Objects.DeepClone(selectedElements);
dcs.Parent = this;
dcs.MoveBy(10,10);
AddElements(dcs);
DeselectAllElements();
SelectElements(dcs);
}
public void DeselectElement(IDrawableContainer container) {
DrawableContainer element = container as DrawableContainer;
element.HideGrippers();
element.Selected = false;
selectedElements.Remove(element);
FieldAggregator.UnbindElement(element);
if (MovingElementChanged != null) {
MovingElementChanged(this, selectedElements);
}
}
public void DeselectAllElements() {
if (HasSelectedElements()) {
while(selectedElements.Count > 0) {
DrawableContainer element = selectedElements[0];
element.HideGrippers();
element.Selected = false;
selectedElements.Remove(element);
FieldAggregator.UnbindElement(element);
}
if (MovingElementChanged != null) {
MovingElementChanged(this, selectedElements);
}
}
}
public void SelectElement(IDrawableContainer container) {
DrawableContainer element = container as DrawableContainer;
if(!selectedElements.Contains(element)) {
selectedElements.Add(element);
element.ShowGrippers();
element.Selected = true;
FieldAggregator.BindElement(element);
if (MovingElementChanged != null) {
MovingElementChanged(this, selectedElements);
}
Invalidate();
}
}
public void SelectAllElements() {
SelectElements(elements);
}
public void SelectElements(DrawableContainerList elements) {
foreach(DrawableContainer element in elements) {
SelectElement(element);
}
}
public void ProcessCmdKey(Keys k) {
if (selectedElements.Count > 0) {
int px = (k == Keys.Shift) ? 10 : 1;
switch (k) {
case Keys.Left:
selectedElements.MoveBy(-1,0);
break;
case Keys.Left | Keys.Shift:
selectedElements.MoveBy(-10,0);
break;
case Keys.Up:
selectedElements.MoveBy(0,-1);
break;
case Keys.Up | Keys.Shift:
selectedElements.MoveBy(0,-10);
break;
case Keys.Right:
selectedElements.MoveBy(1,0);
break;
case Keys.Right | Keys.Shift:
selectedElements.MoveBy(10,0);
break;
case Keys.Down:
selectedElements.MoveBy(0,1);
break;
case Keys.Down | Keys.Shift:
selectedElements.MoveBy(0,10);
break;
case Keys.PageUp:
elements.PullElementsUp(selectedElements);
break;
case Keys.PageDown:
elements.PushElementsDown(selectedElements);
break;
case Keys.Home:
elements.PullElementsToTop(selectedElements);
break;
case Keys.End:
elements.PushElementsToBottom(selectedElements);
break;
case Keys.Enter:
ConfirmSelectedConfirmableElements(true);
break;
case Keys.Escape:
ConfirmSelectedConfirmableElements(false);
break;
/*case Keys.Delete:
RemoveSelectedElements();
break;*/
default:
return;
}
Invalidate();
}
}
/// <summary>
/// pulls selected elements up one level in hierarchy
/// </summary>
public void PullElementsUp() {
elements.PullElementsUp(selectedElements);
Invalidate();
}
/// <summary>
/// pushes selected elements up to top in hierarchy
/// </summary>
public void PullElementsToTop() {
elements.PullElementsToTop(selectedElements);
Invalidate();
}
/// <summary>
/// pushes selected elements down one level in hierarchy
/// </summary>
public void PushElementsDown() {
elements.PushElementsDown(selectedElements);
Invalidate();
}
/// <summary>
/// pushes selected elements down to bottom in hierarchy
/// </summary>
public void PushElementsToBottom() {
elements.PushElementsToBottom(selectedElements);
Invalidate();
}
/// <summary>
/// indicates whether the selected elements could be pulled up in hierarchy
/// </summary>
/// <returns>true if selected elements could be pulled up, false otherwise</returns>
public bool CanPullSelectionUp() {
return elements.CanPullUp(selectedElements);
}
/// <summary>
/// indicates whether the selected elements could be pushed down in hierarchy
/// </summary>
/// <returns>true if selected elements could be pushed down, false otherwise</returns>
public bool CanPushSelectionDown() {
return elements.CanPushDown(selectedElements);
}
public new void Dispose() {
LOG.Debug("Disposing a surface!");
originalImage.Dispose();
base.Dispose();
}
public void ElementPropertyChanged(object sender, PropertyChangedEventArgs e) {
Invalidate();
}
public void element_FieldChanged(object sender, FieldChangedEventArgs e) {
Invalidate();
}
}
}

View file

@ -0,0 +1,300 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.ComponentModel;
using System.Drawing;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Runtime.Serialization;
using System.Windows.Forms;
using Greenshot.Drawing.Fields;
using Greenshot.Helpers;
using Greenshot.Plugin.Drawing;
namespace Greenshot.Drawing {
/// <summary>
/// Represents a textbox (extends RectangleContainer for border/background support
/// </summary>
[Serializable()]
public class TextContainer : RectangleContainer, ITextContainer {
private bool fontInvalidated = true;
private Font font;
private string text;
public string Text {
get { return text; }
set {
if((text == null && value != null) || !text.Equals(value)) {
text = value;
OnPropertyChanged("Text");
}
}
}
[NonSerialized]
private TextBox textBox;
public TextContainer(Surface parent) : base(parent) {
Init();
Field field = FieldFactory.CreateField(FieldType.FONT_BOLD);
//field.PropertyChanged += FontPropertyChanged;
AddField(field);
AddField(FieldFactory.CreateField(FieldType.FONT_ITALIC));
AddField(FieldFactory.CreateField(FieldType.FONT_FAMILY));
AddField(FieldFactory.CreateField(FieldType.FONT_SIZE));
AddField(FieldFactory.CreateField(FieldType.LINE_COLOR, GetType()));
AddField(FieldFactory.CreateField(FieldType.LINE_THICKNESS, GetType()));
AddField(FieldFactory.CreateField(FieldType.FILL_COLOR, GetType()));
AddField(FieldFactory.CreateField(FieldType.SHADOW));
}
[OnDeserializedAttribute()]
private void OnDeserialized(StreamingContext context) {
Init();
UpdateFont();
}
/**
* Destructor
*/
~TextContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public override void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if(textBox != null) textBox.Dispose();
if(font != null) font.Dispose();
}
textBox = null;
font = null;
}
private void Init() {
CreateTextBox();
this.PropertyChanged += new PropertyChangedEventHandler(TextContainer_PropertyChanged);
this.FieldChanged += new FieldChangedEventHandler(TextContainer_FieldChanged);
}
public void FitToText() {
UpdateFont();
Size textSize = TextRenderer.MeasureText(text, font);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
Width = textSize.Width + lineThickness;
Height = textSize.Height + lineThickness;
}
void TextContainer_PropertyChanged(object sender, PropertyChangedEventArgs e) {
if(e.PropertyName.Equals("Selected")) {
if(!Selected && textBox.Visible) HideTextBox();
else if(Selected && Status==EditStatus.DRAWING) {
ShowTextBox();
}
//else if(!textBox.Visible) ShowTextBox();
}
if(textBox.Visible) {
UpdateTextBoxPosition();
UpdateTextBoxFormat();
textBox.Invalidate();
}
}
void TextContainer_FieldChanged(object sender, FieldChangedEventArgs e)
{
if(textBox.Visible) {
UpdateTextBoxFormat();
textBox.Invalidate();
} else {
UpdateFont();
//Invalidate();
}
font.Dispose();
font = null;
fontInvalidated = true;
}
public override void OnDoubleClick() {
ShowTextBox();
}
private void CreateTextBox() {
textBox = new TextBox();
textBox.Multiline = true;
textBox.AcceptsTab = false;
textBox.AcceptsReturn = false;
textBox.DataBindings.Add("Text", this, "Text", false, DataSourceUpdateMode.OnPropertyChanged);
textBox.LostFocus += new EventHandler(textBox_LostFocus);
textBox.KeyDown += new KeyEventHandler(textBox_KeyDown);
textBox.BorderStyle = BorderStyle.FixedSingle;
textBox.Visible = false;
}
private void ShowTextBox() {
childLabel.Hide();
parent.KeysLocked = true;
parent.Controls.Add(textBox);
textBox.Show();
textBox.Focus();
}
private void HideTextBox() {
childLabel.Show();
parent.Focus();
textBox.Hide();
parent.KeysLocked = false;
parent.Controls.Remove(textBox);
}
private void UpdateFont() {
string fontFamily = GetFieldValueAsString(FieldType.FONT_FAMILY);
bool fontBold = GetFieldValueAsBool(FieldType.FONT_BOLD);
bool fontItalic = GetFieldValueAsBool(FieldType.FONT_ITALIC);
float fontSize = GetFieldValueAsFloat(FieldType.FONT_SIZE);
if(fontInvalidated && fontFamily != null && fontSize != 0) {
FontStyle fs = FontStyle.Regular;
bool hasStyle = false;
using(FontFamily fam = new FontFamily(fontFamily)) {
bool boldAvailable = fam.IsStyleAvailable(FontStyle.Bold);
if(fontBold && boldAvailable) {
fs |= FontStyle.Bold;
hasStyle = true;
}
bool italicAvailable = fam.IsStyleAvailable(FontStyle.Italic);
if(fontItalic && italicAvailable) {
fs |= FontStyle.Italic;
hasStyle = true;
}
if(!hasStyle) {
bool regularAvailable = fam.IsStyleAvailable(FontStyle.Regular);
if(regularAvailable) {
fs = FontStyle.Regular;
} else {
if(boldAvailable) {
fs = FontStyle.Bold;
} else if(italicAvailable) {
fs = FontStyle.Italic;
}
}
}
font = new Font(fam, fontSize, fs, GraphicsUnit.Pixel);
}
fontInvalidated = false;
}
}
private void UpdateTextBoxPosition() {
textBox.Left = this.Left;
textBox.Top = this.Top;
textBox.Width = this.Width;
textBox.Height = this.Height;
}
private void UpdateTextBoxFormat() {
UpdateFont();
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
textBox.ForeColor = lineColor;
textBox.Font = font;
}
void textBox_KeyDown(object sender, KeyEventArgs e) {
// ESC and Enter/Return (w/o Shift) hide text editor
if(e.KeyCode == Keys.Escape || ((e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter) && e.Modifiers != Keys.Shift)) {
HideTextBox();
e.SuppressKeyPress = true;
}
}
void textBox_LostFocus(object sender, EventArgs e) {
HideTextBox();
}
public override void Draw(Graphics g, RenderMode rm) {
base.Draw(g, rm);
UpdateFont();
Rectangle rect = GuiRectangle.GetGuiRectangle(this.Left, this.Top, this.Width, this.Height);
if (Selected && !rm.Equals(RenderMode.EXPORT)) {
DrawSelectionBorder(g, rect);
}
if (text == null || text.Length == 0 ) {
return;
}
// we only draw the shadow if there is no background
bool shadow = GetFieldValueAsBool(FieldType.SHADOW);
Color fillColor = GetFieldValueAsColor(FieldType.FILL_COLOR);
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
int textOffset = (lineThickness>0) ? (int)Math.Ceiling(lineThickness/2d) : 0;
// draw shadow before anything else
if ( shadow && (fillColor == Color.Transparent || fillColor == Color.Empty)) {
int basealpha = 100;
int alpha = basealpha;
int steps = 5;
int currentStep = 1;
while (currentStep <= steps) {
int offset = currentStep;
Rectangle shadowRect = GuiRectangle.GetGuiRectangle(Left + offset, Top + offset, Width, Height);
if(lineThickness>0) shadowRect.Inflate(-textOffset, -textOffset);
using (Brush fontBrush = new SolidBrush(Color.FromArgb(alpha, 100, 100, 100))) {
g.DrawString(text, font, fontBrush, shadowRect);
currentStep++;
alpha = alpha - basealpha / steps;
}
}
}
Color lineColor = GetFieldValueAsColor(FieldType.LINE_COLOR);
Rectangle fontRect = rect;
if(lineThickness>0) fontRect.Inflate(-textOffset,-textOffset);
using (Brush fontBrush = new SolidBrush(lineColor)) {
g.DrawString(text, font, fontBrush, fontRect);
}
}
}
}

View file

@ -0,0 +1,117 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.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 {
/// <summary>
/// Description of BitmapContainer.
/// </summary>
[Serializable()]
public class UrlContainer : DrawableContainer {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(UrlContainer));
protected Bitmap bitmap = null;
protected string url = null;
private Size lastSize = new Size(0, 0);
public UrlContainer(Surface parent, string url) : this(parent) {
Url = url;
}
public UrlContainer(Surface parent) : base(parent) {
Width = 100;
Height = 100;
}
public string Url {
set {
url = value;
lastSize = new Size(0, 0);
RedrawIfNeeded();
}
get { return url; }
}
/**
* Destructor
*/
~UrlContainer() {
Dispose(false);
}
/**
* The public accessible Dispose
* Will call the GarbageCollector to SuppressFinalize, preventing being cleaned twice
*/
public new void Dispose() {
Dispose(true);
base.Dispose();
GC.SuppressFinalize(this);
}
// The bulk of the clean-up code is implemented in Dispose(bool)
/**
* This Dispose is called from the Dispose and the Destructor.
* When disposing==true all non-managed resources should be freed too!
*/
protected virtual void Dispose(bool disposing) {
if (disposing) {
if (bitmap != null) {
bitmap.Dispose();
}
}
bitmap = null;
}
protected void RedrawIfNeeded() {
if (url == null) {
if (bitmap != null) {
bitmap.Dispose();
}
bitmap = null;
return;
}
if (bitmap == null || lastSize.Height != Height || lastSize.Width != Width) {
bitmap = WebsiteImageGenerator.GetImageFromURL(url);
if (bitmap != null) {
lastSize = new Size(bitmap.Width, bitmap.Height);
}
}
}
public override void Draw(Graphics g, RenderMode rm) {
RedrawIfNeeded();
if (bitmap != null) {
g.DrawImage(bitmap, Bounds);
}
}
}
}

255
Greenshot/Forms/AboutForm.Designer.cs generated Normal file
View file

@ -0,0 +1,255 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
using Greenshot.Configuration;
namespace Greenshot {
partial class AboutForm {
/// <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() {
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(AboutForm));
this.lblTitle = new System.Windows.Forms.Label();
this.lblLicense = new System.Windows.Forms.Label();
this.lblHost = new System.Windows.Forms.Label();
this.linkLblLicense = new System.Windows.Forms.LinkLabel();
this.linkLblHost = new System.Windows.Forms.LinkLabel();
this.linkLblBugs = new System.Windows.Forms.LinkLabel();
this.lblBugs = new System.Windows.Forms.Label();
this.linkLblDonations = new System.Windows.Forms.LinkLabel();
this.lblDonations = new System.Windows.Forms.Label();
this.linkLblIcons = new System.Windows.Forms.LinkLabel();
this.lblIcons = new System.Windows.Forms.Label();
this.linkLabel1 = new System.Windows.Forms.LinkLabel();
this.pictureBox1 = new System.Windows.Forms.PictureBox();
this.lblTranslation = new System.Windows.Forms.Label();
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).BeginInit();
this.SuspendLayout();
//
// lblTitle
//
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.TabIndex = 2;
this.lblTitle.Text = "Greenshot x.x.xxx";
//
// lblLicense
//
this.lblLicense.Location = new System.Drawing.Point(109, 34);
this.lblLicense.Name = "lblLicense";
this.lblLicense.Size = new System.Drawing.Size(369, 68);
this.lblLicense.TabIndex = 3;
this.lblLicense.Text = "Copyright (C) 2007 Thomas Braun, Jens Klingen";
//
// lblHost
//
this.lblHost.Location = new System.Drawing.Point(12, 109);
this.lblHost.Name = "lblHost";
this.lblHost.Size = new System.Drawing.Size(466, 23);
this.lblHost.TabIndex = 4;
this.lblHost.Text = "Greenshot is hosted by sourceforge.net at";
//
// linkLblLicense
//
this.linkLblLicense.Location = new System.Drawing.Point(109, 85);
this.linkLblLicense.Name = "linkLblLicense";
this.linkLblLicense.Size = new System.Drawing.Size(369, 23);
this.linkLblLicense.TabIndex = 5;
this.linkLblLicense.TabStop = true;
this.linkLblLicense.Text = "http://www.gnu.org/licenses/gpl.html";
this.linkLblLicense.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelClicked);
//
// linkLblHost
//
this.linkLblHost.Location = new System.Drawing.Point(13, 124);
this.linkLblHost.Name = "linkLblHost";
this.linkLblHost.Size = new System.Drawing.Size(465, 23);
this.linkLblHost.TabIndex = 6;
this.linkLblHost.TabStop = true;
this.linkLblHost.Text = "http://sourceforge.net/projects/greenshot/";
this.linkLblHost.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelClicked);
//
// linkLblBugs
//
this.linkLblBugs.Location = new System.Drawing.Point(13, 162);
this.linkLblBugs.Name = "linkLblBugs";
this.linkLblBugs.Size = new System.Drawing.Size(465, 23);
this.linkLblBugs.TabIndex = 8;
this.linkLblBugs.TabStop = true;
this.linkLblBugs.Text = "http://sourceforge.net/tracker/?group_id=191585&atid=937972";
this.linkLblBugs.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelClicked);
//
// lblBugs
//
this.lblBugs.Location = new System.Drawing.Point(12, 147);
this.lblBugs.Name = "lblBugs";
this.lblBugs.Size = new System.Drawing.Size(466, 23);
this.lblBugs.TabIndex = 7;
this.lblBugs.Text = "Please report bugs to";
//
// linkLblDonations
//
this.linkLblDonations.Location = new System.Drawing.Point(13, 201);
this.linkLblDonations.Name = "linkLblDonations";
this.linkLblDonations.Size = new System.Drawing.Size(465, 23);
this.linkLblDonations.TabIndex = 10;
this.linkLblDonations.TabStop = true;
this.linkLblDonations.Text = "http://getgreenshot.org/support/";
this.linkLblDonations.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelClicked);
//
// lblDonations
//
this.lblDonations.Location = new System.Drawing.Point(12, 186);
this.lblDonations.Name = "lblDonations";
this.lblDonations.Size = new System.Drawing.Size(466, 23);
this.lblDonations.TabIndex = 9;
this.lblDonations.Text = "If you like Greenshot, you might consider donating a dime or two at";
//
// linkLblIcons
//
this.linkLblIcons.Location = new System.Drawing.Point(13, 239);
this.linkLblIcons.Name = "linkLblIcons";
this.linkLblIcons.Size = new System.Drawing.Size(279, 23);
this.linkLblIcons.TabIndex = 12;
this.linkLblIcons.TabStop = true;
this.linkLblIcons.Text = "http://p.yusukekamiyamane.com";
this.linkLblIcons.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelClicked);
//
// lblIcons
//
this.lblIcons.Location = new System.Drawing.Point(12, 224);
this.lblIcons.Name = "lblIcons";
this.lblIcons.Size = new System.Drawing.Size(466, 23);
this.lblIcons.TabIndex = 11;
this.lblIcons.Text = "Greenshot uses icons from / derived from Mark James\' splendid Silk Icon Set on";
//
// linkLabel1
//
this.linkLabel1.Location = new System.Drawing.Point(304, 8);
this.linkLabel1.Name = "linkLabel1";
this.linkLabel1.Size = new System.Drawing.Size(203, 23);
this.linkLabel1.TabIndex = 13;
this.linkLabel1.TabStop = true;
this.linkLabel1.Text = "http://getgreenshot.org";
this.linkLabel1.TextAlign = System.Drawing.ContentAlignment.TopRight;
this.linkLabel1.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLabelClicked);
//
// pictureBox1
//
this.pictureBox1.Image = ((System.Drawing.Image)(resources.GetObject("pictureBox1.Image")));
this.pictureBox1.Location = new System.Drawing.Point(12, 12);
this.pictureBox1.Name = "pictureBox1";
this.pictureBox1.Size = new System.Drawing.Size(90, 90);
this.pictureBox1.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize;
this.pictureBox1.TabIndex = 14;
this.pictureBox1.TabStop = false;
//
// lblTranslation
//
this.lblTranslation.Location = new System.Drawing.Point(12, 262);
this.lblTranslation.Name = "lblTranslation";
this.lblTranslation.Size = new System.Drawing.Size(466, 23);
this.lblTranslation.TabIndex = 15;
this.lblTranslation.Text = "English translation by YOUR_NAME";
//
// AboutForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(519, 293);
this.Controls.Add(this.lblTranslation);
this.Controls.Add(this.pictureBox1);
this.Controls.Add(this.linkLabel1);
this.Controls.Add(this.linkLblIcons);
this.Controls.Add(this.lblIcons);
this.Controls.Add(this.linkLblDonations);
this.Controls.Add(this.lblDonations);
this.Controls.Add(this.linkLblBugs);
this.Controls.Add(this.lblBugs);
this.Controls.Add(this.linkLblHost);
this.Controls.Add(this.linkLblLicense);
this.Controls.Add(this.lblHost);
this.Controls.Add(this.lblLicense);
this.Controls.Add(this.lblTitle);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "AboutForm";
this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen;
this.Text = "AboutForm";
((System.ComponentModel.ISupportInitialize)(this.pictureBox1)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.Label lblTranslation;
private System.Windows.Forms.LinkLabel linkLabel1;
private System.Windows.Forms.Label lblHost;
private System.Windows.Forms.LinkLabel linkLblHost;
private System.Windows.Forms.Label lblDonations;
private System.Windows.Forms.LinkLabel linkLblDonations;
private System.Windows.Forms.Label lblBugs;
private System.Windows.Forms.LinkLabel linkLblBugs;
private System.Windows.Forms.LinkLabel linkLblLicense;
private System.Windows.Forms.LinkLabel linkLblIcons;
private System.Windows.Forms.Label lblIcons;
private System.Windows.Forms.Label lblLicense;
private System.Windows.Forms.Label lblTitle;
private System.Windows.Forms.PictureBox pictureBox1;
void LinkLabelClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) {
openLink((LinkLabel)sender);
}
private void openLink(LinkLabel link) {
try {
link.LinkVisited = true;
System.Diagnostics.Process.Start(link.Text);
} catch (Exception) {
MessageBox.Show(lang.GetString(LangKey.error_openlink),lang.GetString(LangKey.error));
}
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Reflection;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
namespace Greenshot {
/// <summary>
/// Description of AboutForm.
/// </summary>
public partial class AboutForm : Form {
private ILanguage lang;
public AboutForm() {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
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.ToString("0000");
lang = Language.GetInstance();
updateUI();
}
void updateUI() {
this.Text = lang.GetString(LangKey.about_title);
this.lblLicense.Text = lang.GetString(LangKey.about_license);
this.lblHost.Text = lang.GetString(LangKey.about_host);
this.lblBugs.Text = lang.GetString(LangKey.about_bugs);
this.lblDonations.Text = lang.GetString(LangKey.about_donations);
this.lblIcons.Text = lang.GetString(LangKey.about_icons);
this.lblTranslation.Text = lang.GetString(LangKey.about_translation);
}
protected override bool ProcessCmdKey(ref Message msg, Keys keyData) {
try {
if (msg.WParam.ToInt32() == (int)Keys.Escape) {
this.Close();
} else {
return base.ProcessCmdKey(ref msg, keyData);
}
} catch (Exception) {
}
return base.ProcessCmdKey(ref msg,keyData);
}
}
}

View file

@ -0,0 +1,503 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="pictureBox1.Image" type="System.Drawing.Bitmap, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
DhT/B6rDw1pTOdhMAAAAAElFTkSuQmCC
</value>
</data>
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPSkpKSisCAAAAAAAAAQAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFTg9JgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAgAAAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCKAAAACAAAABA
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
</value>
</data>
</root>

118
Greenshot/Forms/BugReportForm.Designer.cs generated Normal file
View file

@ -0,0 +1,118 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 BugReportForm {
/// <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()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(BugReportForm));
this.labelBugReportInfo = new System.Windows.Forms.Label();
this.textBoxDescription = new System.Windows.Forms.TextBox();
this.btnClose = new System.Windows.Forms.Button();
this.linkLblBugs = new System.Windows.Forms.LinkLabel();
this.SuspendLayout();
//
// labelBugReportInfo
//
this.labelBugReportInfo.Location = new System.Drawing.Point(12, 9);
this.labelBugReportInfo.Name = "labelBugReportInfo";
this.labelBugReportInfo.Size = new System.Drawing.Size(481, 141);
this.labelBugReportInfo.TabIndex = 0;
this.labelBugReportInfo.Text = resources.GetString("labelBugReportInfo.Text");
//
// textBoxDescription
//
this.textBoxDescription.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
| System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.textBoxDescription.Location = new System.Drawing.Point(12, 179);
this.textBoxDescription.Multiline = true;
this.textBoxDescription.Name = "textBoxDescription";
this.textBoxDescription.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
this.textBoxDescription.Size = new System.Drawing.Size(504, 232);
this.textBoxDescription.TabIndex = 1;
//
// btnClose
//
this.btnClose.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right)));
this.btnClose.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.btnClose.Location = new System.Drawing.Point(377, 417);
this.btnClose.Name = "btnClose";
this.btnClose.Size = new System.Drawing.Size(139, 23);
this.btnClose.TabIndex = 2;
this.btnClose.Text = "Close";
this.btnClose.UseVisualStyleBackColor = true;
//
// linkLblBugs
//
this.linkLblBugs.Location = new System.Drawing.Point(12, 153);
this.linkLblBugs.Name = "linkLblBugs";
this.linkLblBugs.Size = new System.Drawing.Size(465, 23);
this.linkLblBugs.TabIndex = 9;
this.linkLblBugs.TabStop = true;
this.linkLblBugs.Text = "http://sourceforge.net/tracker/?group_id=191585&atid=937972";
this.linkLblBugs.LinkClicked += new System.Windows.Forms.LinkLabelLinkClickedEventHandler(this.LinkLblBugsLinkClicked);
//
// BugReportForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.CancelButton = this.btnClose;
this.ClientSize = new System.Drawing.Size(528, 452);
this.Controls.Add(this.linkLblBugs);
this.Controls.Add(this.btnClose);
this.Controls.Add(this.textBoxDescription);
this.Controls.Add(this.labelBugReportInfo);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.Name = "BugReportForm";
this.Text = "Error";
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.LinkLabel linkLblBugs;
private System.Windows.Forms.Button btnClose;
private System.Windows.Forms.TextBox textBoxDescription;
private System.Windows.Forms.Label labelBugReportInfo;
}
}

View file

@ -0,0 +1,70 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Net;
using System.Web;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Helpers;
using GreenshotPlugin.Core;
namespace Greenshot.Forms {
public partial class BugReportForm : Form {
private ILanguage lang;
private BugReportForm() {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
lang = Language.GetInstance();
UpdateUI();
}
public BugReportForm(string bugText) {
InitializeComponent();
lang = Language.GetInstance();
UpdateUI();
this.textBoxDescription.Text = bugText;
}
void UpdateUI() {
this.Text = lang.GetString(LangKey.bugreport_title);
this.labelBugReportInfo.Text = lang.GetString(LangKey.bugreport_info);
this.btnClose.Text = lang.GetString(LangKey.bugreport_cancel);
}
void LinkLblBugsLinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e) {
openLink((LinkLabel)sender);
}
private void openLink(LinkLabel link) {
try {
link.LinkVisited = true;
System.Diagnostics.Process.Start(link.Text);
} catch (Exception) {
MessageBox.Show(lang.GetString(LangKey.error_openlink),lang.GetString(LangKey.error));
}
}
}
}

View file

@ -0,0 +1,386 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<data name="labelBugReportInfo.Text" xml:space="preserve">
<value>Sorry, an unexpected error occured.
The good news is: you can help us getting rid of it by filing a bug report.
Please visit the URL below, create a new bug report and paste the contents from the text area into the description.
Also, we would highly appreciate if you could add a short description about the circumstances under which the error occurred.</value>
</data>
<assembly alias="System.Drawing" name="System.Drawing, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" />
<data name="$this.Icon" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>
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
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAPSkpKSisCAAAAAAAAAQAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFTg9JgIAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAgAAAgABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIA
AAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAA
AKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCAAAAAAAApEIAAAAAAACkQgAAAAAAAKRCKAAAACAAAABA
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
</value>
</data>
</root>

84
Greenshot/Forms/CaptureForm.Designer.cs generated Normal file
View file

@ -0,0 +1,84 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 CaptureForm {
/// <summary>
/// Designer variable used to keep track of non-visual components.
/// </summary>
private System.Windows.Forms.PictureBox pictureBox;
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.pictureBox = new System.Windows.Forms.PictureBox();
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).BeginInit();
this.SuspendLayout();
//
// pictureBox
//
this.pictureBox.Dock = System.Windows.Forms.DockStyle.Fill;
this.pictureBox.Location = new System.Drawing.Point(0, 0);
this.pictureBox.Name = "pictureBox";
this.pictureBox.Size = new System.Drawing.Size(0, 0);
this.pictureBox.TabIndex = 1;
this.pictureBox.TabStop = false;
this.pictureBox.MouseMove += new System.Windows.Forms.MouseEventHandler(this.PictureBoxMouseMove);
this.pictureBox.MouseDown += new System.Windows.Forms.MouseEventHandler(this.PictureBoxMouseDown);
this.pictureBox.Paint += new System.Windows.Forms.PaintEventHandler(this.PictureBoxPaint);
this.pictureBox.MouseUp += new System.Windows.Forms.MouseEventHandler(this.PictureBoxMouseUp);
//
// CaptureForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(0, 0);
this.Controls.Add(this.pictureBox);
this.Cursor = System.Windows.Forms.Cursors.Cross;
this.DoubleBuffered = true;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.Name = "CaptureForm";
this.ShowInTaskbar = false;
this.TopMost = true;
this.VisibleChanged += new System.EventHandler(this.CaptureFormVisibleChanged);
this.KeyDown += new System.Windows.Forms.KeyEventHandler(this.CaptureFormKeyDown);
((System.ComponentModel.ISupportInitialize)(this.pictureBox)).EndInit();
this.Visible = false;
this.ResumeLayout(false);
}
}
}

View file

@ -0,0 +1,826 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
using System.Collections.Generic;
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.Core;
namespace Greenshot.Forms {
/// <summary>
/// Description of CaptureForm.
/// </summary>
public partial class CaptureForm : Form, ICaptureHost {
private static log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(CaptureForm));
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;
private bool mouseDown = false;
private Rectangle captureRect = Rectangle.Empty;
private ICapture capture = null;
private AppConfig conf = AppConfig.GetInstance();
private CopyData copyData = null;
private ILanguage lang = Language.GetInstance();
public CaptureForm() {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
// Create a new instance of the class: copyData = new CopyData();
copyData = new CopyData();
// Assign the handle:
copyData.AssignHandle(this.Handle);
// Create the channel to send on:
copyData.Channels.Add("Greenshot");
// Hook up received event:
copyData.DataReceived += new DataReceivedEventHandler(CopyDataDataReceived);
// Make sure the form is hidden (might be overdoing it...)
this.Hide();
}
/// <summary>
/// DataReceivedEventHandler
/// </summary>
/// <param name="sender"></param>
/// <param name="dataReceivedEventArgs"></param>
private void CopyDataDataReceived(object sender, DataReceivedEventArgs dataReceivedEventArgs) {
// Cast the data to the type of object we sent:
DataTransport dataTransport = (DataTransport)dataReceivedEventArgs.Data;
HandleDataTransport(dataTransport);
}
public void HandleDataTransport(DataTransport dataTransport) {
LOG.Debug("Data received, Command = " + dataTransport.Command + ", Data: " + dataTransport.CommandData);
switch(dataTransport.Command) {
case CommandEnum.Exit:
Application.Exit();
break;
case CommandEnum.ReloadConfig:
AppConfig.Reload();
// Even update language when needed
MainForm.instance.UpdateUI();
break;
case CommandEnum.OpenFile:
string filename = dataTransport.CommandData;
if (File.Exists(filename)) {
MakeCapture(filename);
} else {
LOG.Warn("No such file: " + filename);
}
break;
default:
LOG.Error("Unknown command!");
break;
}
}
void DoCaptureFeedback() {
if((bool)conf.Ui_Effects_CameraSound) {
SoundHelper.Play();
}
if((bool)conf.Ui_Effects_Flashlight) {
FlashlightForm flashlightForm = new FlashlightForm();
flashlightForm.Bounds = capture.ScreenBounds;
flashlightForm.FadeIn();
flashlightForm.FadeOut();
flashlightForm.Dispose();
}
}
/// <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);
}
/// <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;
// Delay for the Context menu
System.Threading.Thread.Sleep(conf.Capture_Wait_Time);
// 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.Capture_Mousepointer.HasValue && conf.Capture_Mousepointer.Value);
}
switch(mode) {
case CaptureMode.Window:
capture = WindowCapture.CaptureScreen(capture);
CaptureWithFeedback();
break;
case CaptureMode.ActiveWindow:
CaptureActiveWindow();
finishCapture();
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();
} else if (ClipboardHelper.GetFormats().Contains("HTML Format")) {
HtmlFragment htmlFragment = HtmlFragment.FromClipboard();
text = htmlFragment.Fragment;
clipboardImage = WebsiteImageGenerator.GetImageFromHTML(text);
} else {
text = Clipboard.GetText();
if ((text != null && text.StartsWith("http://"))) {
clipboardImage = WebsiteImageGenerator.GetImageFromURL(text);
}
}
if (clipboardImage != null) {
if (capture != null) {
capture.Image = clipboardImage;
} else {
capture = new Capture(clipboardImage);
}
// 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));
}
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);
HandleCapture();
}
break;
case CaptureMode.Region:
capture = WindowCapture.CaptureScreen(capture);
CaptureWithFeedback();
break;
default:
LOG.Warn("Unknown capture mode: " + mode);
break;
}
}
private ICapture AddConfiguredDestination(ICapture capture) {
if ((conf.Output_Destinations & ScreenshotDestinations.FileDefault) == ScreenshotDestinations.FileDefault) {
capture.CaptureDetails.AddDestination(CaptureDestination.File);
}
if ((conf.Output_Destinations & ScreenshotDestinations.FileWithDialog) == ScreenshotDestinations.FileWithDialog) {
capture.CaptureDetails.AddDestination(CaptureDestination.FileWithDialog);
}
if ((conf.Output_Destinations & ScreenshotDestinations.Clipboard) == ScreenshotDestinations.Clipboard) {
capture.CaptureDetails.AddDestination(CaptureDestination.Clipboard);
}
if ((conf.Output_Destinations & ScreenshotDestinations.Printer) == ScreenshotDestinations.Printer) {
capture.CaptureDetails.AddDestination(CaptureDestination.Printer);
}
if ((conf.Output_Destinations & ScreenshotDestinations.Editor) == ScreenshotDestinations.Editor) {
capture.CaptureDetails.AddDestination(CaptureDestination.Editor);
}
if ((conf.Output_Destinations & ScreenshotDestinations.EMail) == ScreenshotDestinations.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);
// 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!
// 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 filename = FilenameHelper.GetFilenameFromPattern(conf.Output_File_FilenamePattern, conf.Output_File_Format, captureDetails);
fullPath = Path.Combine(conf.Output_File_Path,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, captureDetails);
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;
}
}
// If the editor is opened, let it Dispose the surface!
if (captureDestinations.Contains(CaptureDestination.Editor)) {
ImageEditorForm editor = new ImageEditorForm(surface, outputMade);
if (fullPath != null) {
editor.SetImagePath(fullPath);
}
editor.Show();
editor.Activate();
LOG.Debug("Finished opening Editor");
} 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 finishCapture() {
bool fromWindow = (conf.Capture_Complete_Window.HasValue && conf.Capture_Complete_Window.Value);
// Get title
if (selectedCaptureWindow != null) {
if (capture == null) {
capture = new Capture();
}
capture.CaptureDetails.Title = selectedCaptureWindow.Text;
}
if ( (captureMode == CaptureMode.Window || captureMode == CaptureMode.ActiveWindow) && selectedCaptureWindow != null) {
Image capturedWindowImage = null;
// What type of capturing? (From Screen or from window)
if (fromWindow) {
// "Capture" the windows content
capturedWindowImage = selectedCaptureWindow.Image;
if (capturedWindowImage != null) {
// Fix Cursor location as we don't crop
capture.MoveMouseLocation(-selectedCaptureWindow.Rectangle.Location.X, -selectedCaptureWindow.Rectangle.Location.Y);
// Set the image
capture.Image = capturedWindowImage;
}
}
// If the PrintWindow implementation isn't used or failed we use the image from the screen.
if (capturedWindowImage == null) {
// From screen, take the location of the selected window to copy the content
captureRect = selectedCaptureWindow.Rectangle;
// Cropping capture to the selected rectangle
capture.CropWithScreenCoordinates(captureRect);
// save for re-capturing later and show recapture context menu option
RuntimeConfig.LastCapturedRegion = captureRect;
}
StopCapturing(false);
HandleCapture();
} else if (captureRect.Height > 0 && captureRect.Width > 0) {
// Resizing the captured rectangle (no need to make another capture
capture.CropWithScreenCoordinates(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;
selectedCaptureWindow = null;
if (cleanupCapture && capture != null) {
capture.Dispose();
capture = null;
}
this.Hide();
}
#region key handling
void CaptureFormKeyDown(object sender, KeyEventArgs e) {
if (e.KeyCode == Keys.Escape) {
StopCapturing(true);
} 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));
} else if (e.KeyCode == Keys.PageDown) {
// Extend the selectable rectangles with the "insides" of the current Window
if (captureMode == CaptureMode.Window) {
WindowDetails currentWindow = FindCurrentWindow();
if (currentWindow != null && !currentWindow.HasChildren) {
currentWindow.GetChildren();
} else {
LOG.Warn("No window found!!");
}
}
PictureBoxMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
} else if (e.KeyCode == Keys.Space) {
switch (captureMode) {
case CaptureMode.Region:
captureMode = CaptureMode.Window;
break;
case CaptureMode.Window:
captureMode = CaptureMode.Region;
break;
}
PictureBoxMouseMove(this, new MouseEventArgs(MouseButtons.None, 0, Cursor.Position.X, Cursor.Position.Y, 0));
} else if (e.KeyCode == Keys.Return && captureMode == CaptureMode.Window) {
finishCapture();
}
}
#endregion
private void CaptureActiveWindow() {
LOG.Debug("CaptureActiveWindow");
IntPtr hWnd = User32.GetForegroundWindow();
if (hWnd != null && hWnd != IntPtr.Zero) {
// Make sure the screen is captured in case of errors or if we don't do direct window capturing
capture = WindowCapture.CaptureScreen(capture);
selectedCaptureWindow = new WindowDetails(hWnd);
// Content only
if ((conf.Capture_Window_Content.HasValue && conf.Capture_Window_Content.Value)) {
// Print Tree for debugging
selectedCaptureWindow.PrintTree("");
WindowDetails contentWindow = selectedCaptureWindow.GetContent();
if (contentWindow != null) {
selectedCaptureWindow = contentWindow;
}
}
}
}
#region capture with feedback
private void CaptureWithFeedback() {
windows.Clear();
// Start Enumeration of "active" windows
WindowsEnumerator windowsEnumerator = new WindowsEnumerator();
windowsEnumerator.GetWindows();
foreach(WindowDetails window in windowsEnumerator.Items) {
// Window should be visible and not ourselves
if (window.Visible && !window.Handle.Equals(this.Handle)) {
windows.Add(window);
}
}
this.SuspendLayout();
this.Bounds = capture.ScreenBounds;
pictureBox.Image = capture.Image;
this.Visible = true;
this.ResumeLayout();
this.Focus();
this.Show();
}
/// <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.Rectangle;
if (windowRectangle.Contains(Cursor.Position)) {
WindowDetails selectedChild = null;
// Content only
if ((conf.Capture_Window_Content.HasValue && conf.Capture_Window_Content.Value)) {
WindowDetails childWindow = window.GetContent();
if (childWindow != null && childWindow.Rectangle.Contains(Cursor.Position)) {
return childWindow;
}
}
// Check if Children need to be parsed (only if "pgdn" was used)
if (window.HasChildren) {
foreach(WindowDetails childWindow in window.Children) {
windowRectangle = childWindow.Rectangle;
if (windowRectangle.Contains(Cursor.Position)) {
if (selectedChild == null) {
selectedChild = childWindow;
} else {
int sizeCurrent = childWindow.Rectangle.Height * childWindow.Rectangle.Width;
int sizeSelected = selectedChild.Rectangle.Height * selectedChild.Rectangle.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) {
mX = e.X;
mY = e.Y;
mouseDown = true;
PictureBoxMouseMove(this, e);
}
}
void PictureBoxMouseUp(object sender, MouseEventArgs e) {
if (mouseDown) {
// 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
finishCapture();
} else if (captureRect.Height > 0 && captureRect.Width > 0) {
// correct the GUI width to real width if Region mode
if (captureMode == CaptureMode.Region) {
captureRect.Width += 1;
captureRect.Height += 1;
}
// Go and process the capture
finishCapture();
}
}
}
void PictureBoxMouseMove(object sender, MouseEventArgs e) {
cursorPos.X = e.X;
cursorPos.Y = e.Y;
if (captureMode == CaptureMode.Region && mouseDown) {
captureRect = GuiRectangle.GetGuiRectangle(e.X + this.Left, e.Y + this.Top, mX - e.X, mY - e.Y);
}
// Iterate over the found windows and check if the current location is inside a window
selectedCaptureWindow = FindCurrentWindow();
if (selectedCaptureWindow != null) {
if (capture == null) {
capture = new Capture();
}
capture.CaptureDetails.Title = selectedCaptureWindow.Text;
if (captureMode == CaptureMode.Window) {
captureRect = selectedCaptureWindow.Rectangle;
}
}
pictureBox.Invalidate();
}
void PictureBoxPaint(object sender, PaintEventArgs e) {
Graphics graphics = e.Graphics;
if (capture.Cursor != null && capture.CursorVisible) {
graphics.DrawIcon(capture.Cursor, capture.CursorLocation.X, capture.CursorLocation.Y);
}
if (mouseDown || captureMode == CaptureMode.Window) {
Rectangle screenbounds = capture.ScreenBounds;
captureRect.Intersect(screenbounds); // crop what is outside the screen
Rectangle fixedRect = new Rectangle( captureRect.X, captureRect.Y, captureRect.Width, captureRect.Height );
fixedRect.X += Math.Abs( screenbounds.X );
fixedRect.Y += Math.Abs( screenbounds.Y );
graphics.FillRectangle( OverlayBrush, fixedRect );
graphics.DrawRectangle( OverlayPen, fixedRect );
// rulers
int dist = 8;
using (Font rulerFont = new Font(FontFamily.GenericSansSerif, 8)) {
int hSpace = TextRenderer.MeasureText(captureRect.Width.ToString(), rulerFont).Width + 3;
int vSpace = TextRenderer.MeasureText(captureRect.Height.ToString(), rulerFont).Height + 3;
Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227));
Pen rulerPen = new Pen(Color.SeaGreen);
// horizontal ruler
if (fixedRect.Width > hSpace + 3) {
using (GraphicsPath p = Drawing.RoundedRectangle.Create2(
fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3,
fixedRect.Y - dist - 7,
TextRenderer.MeasureText(captureRect.Width.ToString(), rulerFont).Width - 3,
TextRenderer.MeasureText(captureRect.Width.ToString(), rulerFont).Height,
3)) {
graphics.FillPath(bgBrush, p);
graphics.DrawPath(rulerPen, p);
graphics.DrawString(captureRect.Width.ToString(), rulerFont, rulerPen.Brush, fixedRect.X + (fixedRect.Width / 2 - hSpace / 2) + 3, fixedRect.Y - dist - 7);
graphics.DrawLine(rulerPen, fixedRect.X, fixedRect.Y - dist, fixedRect.X + (fixedRect.Width / 2 - hSpace / 2), fixedRect.Y - dist);
graphics.DrawLine(rulerPen, fixedRect.X + (fixedRect.Width / 2 + hSpace / 2), fixedRect.Y - dist, fixedRect.X + fixedRect.Width, fixedRect.Y - dist);
graphics.DrawLine(rulerPen, fixedRect.X, fixedRect.Y - dist - 3, fixedRect.X, fixedRect.Y - dist + 3);
graphics.DrawLine(rulerPen, fixedRect.X + fixedRect.Width, fixedRect.Y - dist - 3, fixedRect.X + fixedRect.Width, fixedRect.Y - dist + 3);
}
}
// vertical ruler
if (fixedRect.Height > vSpace + 3) {
using (GraphicsPath p = Drawing.RoundedRectangle.Create2(
fixedRect.X - (TextRenderer.MeasureText(captureRect.Height.ToString(), rulerFont).Width) + 1,
fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2,
TextRenderer.MeasureText(captureRect.Height.ToString(), rulerFont).Width - 3,
TextRenderer.MeasureText(captureRect.Height.ToString(), rulerFont).Height - 1,
3)) {
graphics.FillPath(bgBrush, p);
graphics.DrawPath(rulerPen, p);
graphics.DrawString(captureRect.Height.ToString(), rulerFont, rulerPen.Brush, fixedRect.X - (TextRenderer.MeasureText(captureRect.Height.ToString(), rulerFont).Width) + 1, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2) + 2);
graphics.DrawLine(rulerPen, fixedRect.X - dist, fixedRect.Y, fixedRect.X - dist, fixedRect.Y + (fixedRect.Height / 2 - vSpace / 2));
graphics.DrawLine(rulerPen, fixedRect.X - dist, fixedRect.Y + (fixedRect.Height / 2 + vSpace / 2), fixedRect.X - dist, fixedRect.Y + fixedRect.Height);
graphics.DrawLine(rulerPen, fixedRect.X - dist - 3, fixedRect.Y, fixedRect.X - dist + 3, fixedRect.Y);
graphics.DrawLine(rulerPen, fixedRect.X - dist - 3, fixedRect.Y + fixedRect.Height, fixedRect.X - dist + 3, fixedRect.Y + fixedRect.Height);
}
}
rulerPen.Dispose();
bgBrush.Dispose();
}
// Display size of selected rectangle
// Prepare the font and text.
using (Font sizeFont = new Font( FontFamily.GenericSansSerif, 12 )) {
// When capturing a Region we need to add 1 to the height/width for correction
string sizeText = null;
if (captureMode == CaptureMode.Region) {
// correct the GUI width to real width for the shown size
sizeText = (captureRect.Width + 1) + " x " + (captureRect.Height + 1);
} else {
sizeText = captureRect.Width + " x " + captureRect.Height;
}
// Calculate the scaled font size.
SizeF extent = graphics.MeasureString( sizeText, sizeFont );
float hRatio = captureRect.Height / (extent.Height * 2);
float wRatio = captureRect.Width / (extent.Width * 2);
float ratio = ( hRatio < wRatio ? hRatio : wRatio );
float newSize = sizeFont.Size * ratio;
if ( newSize >= 4 ) {
// Only show if 4pt or larger.
if (newSize > 20) {
newSize = 20;
}
// Draw the size.
using (Font newSizeFont = new Font(FontFamily.GenericSansSerif, newSize, FontStyle.Bold)) {
PointF sizeLocation = new PointF( fixedRect.X + ( captureRect.Width / 2) - (TextRenderer.MeasureText(sizeText, sizeFont).Width / 2), fixedRect.Y + (captureRect.Height / 2) - (sizeFont.GetHeight() / 2));
graphics.DrawString(sizeText, sizeFont, Brushes.LightSeaGreen, sizeLocation);
}
}
}
} else {
if (cursorPos.X > 0 || cursorPos.Y > 0) {
using (Pen pen = new Pen(Color.LightSeaGreen)) {
pen.DashStyle = DashStyle.Dot;
Rectangle screenBounds = capture.ScreenBounds;
graphics.DrawLine(pen, cursorPos.X, screenBounds.Y, cursorPos.X, screenBounds.Height);
graphics.DrawLine(pen, screenBounds.X, cursorPos.Y, screenBounds.Width, cursorPos.Y);
}
string xy = cursorPos.X.ToString() + " x " + cursorPos.Y.ToString();
using (Font f = new Font(FontFamily.GenericSansSerif, 8)) {
using (GraphicsPath gp = Drawing.RoundedRectangle.Create2(
cursorPos.X + 5,
cursorPos.Y + 5,
TextRenderer.MeasureText(xy, f).Width - 3,
TextRenderer.MeasureText(xy, f).Height,
3)) {
using (Brush bgBrush = new SolidBrush(Color.FromArgb(200, 217, 240, 227))) {
graphics.FillPath(bgBrush, gp);
}
using (Pen pen = new Pen(Color.SeaGreen)) {
graphics.DrawPath(pen, gp);
Point coordinatePosition = new Point(cursorPos.X + 5, cursorPos.Y + 5);
graphics.DrawString(xy, f, pen.Brush, coordinatePosition);
}
}
}
}
}
}
#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
}
}

259
Greenshot/Forms/ColorDialog.Designer.cs generated Normal file
View file

@ -0,0 +1,259 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 {
partial class ColorDialog : System.Windows.Forms.Form {
/// <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.btnTransparent = new System.Windows.Forms.Button();
this.colorPanel = new System.Windows.Forms.Panel();
this.labelHtmlColor = new System.Windows.Forms.Label();
this.textBoxHtmlColor = new System.Windows.Forms.TextBox();
this.labelRed = new System.Windows.Forms.Label();
this.labelGreen = new System.Windows.Forms.Label();
this.labelBlue = new System.Windows.Forms.Label();
this.textBoxRed = new System.Windows.Forms.TextBox();
this.textBoxGreen = new System.Windows.Forms.TextBox();
this.textBoxBlue = new System.Windows.Forms.TextBox();
this.labelRecentColors = new System.Windows.Forms.Label();
this.textBoxAlpha = new System.Windows.Forms.TextBox();
this.labelAlpha = new System.Windows.Forms.Label();
this.btnApply = new System.Windows.Forms.Button();
this.SuspendLayout();
//
// btnTransparent
//
this.btnTransparent.BackColor = System.Drawing.Color.Transparent;
this.btnTransparent.Location = new System.Drawing.Point(210, 4);
this.btnTransparent.Name = "btnTransparent";
this.btnTransparent.Size = new System.Drawing.Size(78, 23);
this.btnTransparent.TabIndex = 0;
this.btnTransparent.TabStop = false;
this.btnTransparent.Text = "Transparent";
this.btnTransparent.UseVisualStyleBackColor = false;
this.btnTransparent.Click += new System.EventHandler(this.btnTransparentClick);
//
// colorPanel
//
this.colorPanel.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.colorPanel.Location = new System.Drawing.Point(210, 31);
this.colorPanel.Name = "colorPanel";
this.colorPanel.Size = new System.Drawing.Size(78, 23);
this.colorPanel.TabIndex = 1;
//
// labelHtmlColor
//
this.labelHtmlColor.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelHtmlColor.Location = new System.Drawing.Point(210, 57);
this.labelHtmlColor.Name = "labelHtmlColor";
this.labelHtmlColor.Size = new System.Drawing.Size(78, 17);
this.labelHtmlColor.TabIndex = 2;
this.labelHtmlColor.Text = "HTML color";
//
// textBoxHtmlColor
//
this.textBoxHtmlColor.Location = new System.Drawing.Point(210, 71);
this.textBoxHtmlColor.Name = "textBoxHtmlColor";
this.textBoxHtmlColor.Size = new System.Drawing.Size(78, 20);
this.textBoxHtmlColor.TabIndex = 1;
this.textBoxHtmlColor.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxHtmlColor.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxHtmlColor.TextChanged += new System.EventHandler(this.TextBoxHexadecimalTextChanged);
this.textBoxHtmlColor.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
//
// labelRed
//
this.labelRed.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelRed.Location = new System.Drawing.Point(210, 98);
this.labelRed.Name = "labelRed";
this.labelRed.Size = new System.Drawing.Size(78, 18);
this.labelRed.TabIndex = 4;
this.labelRed.Text = "Red";
//
// labelGreen
//
this.labelGreen.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelGreen.Location = new System.Drawing.Point(210, 122);
this.labelGreen.Name = "labelGreen";
this.labelGreen.Size = new System.Drawing.Size(78, 18);
this.labelGreen.TabIndex = 5;
this.labelGreen.Text = "Green";
//
// labelBlue
//
this.labelBlue.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelBlue.Location = new System.Drawing.Point(210, 146);
this.labelBlue.Name = "labelBlue";
this.labelBlue.Size = new System.Drawing.Size(78, 18);
this.labelBlue.TabIndex = 6;
this.labelBlue.Text = "Blue";
//
// textBoxRed
//
this.textBoxRed.Location = new System.Drawing.Point(258, 95);
this.textBoxRed.Name = "textBoxRed";
this.textBoxRed.Size = new System.Drawing.Size(30, 20);
this.textBoxRed.TabIndex = 2;
this.textBoxRed.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxRed.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxRed.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxRed.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged);
this.textBoxRed.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
//
// textBoxGreen
//
this.textBoxGreen.Location = new System.Drawing.Point(258, 119);
this.textBoxGreen.Name = "textBoxGreen";
this.textBoxGreen.Size = new System.Drawing.Size(30, 20);
this.textBoxGreen.TabIndex = 3;
this.textBoxGreen.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxGreen.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxGreen.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxGreen.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged);
this.textBoxGreen.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
//
// textBoxBlue
//
this.textBoxBlue.Location = new System.Drawing.Point(258, 143);
this.textBoxBlue.Name = "textBoxBlue";
this.textBoxBlue.Size = new System.Drawing.Size(30, 20);
this.textBoxBlue.TabIndex = 4;
this.textBoxBlue.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxBlue.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxBlue.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxBlue.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged);
this.textBoxBlue.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
//
// labelRecentColors
//
this.labelRecentColors.Location = new System.Drawing.Point(3, 175);
this.labelRecentColors.Name = "labelRecentColors";
this.labelRecentColors.Size = new System.Drawing.Size(148, 13);
this.labelRecentColors.TabIndex = 10;
this.labelRecentColors.Text = "Recently used colors";
//
// textBoxAlpha
//
this.textBoxAlpha.Location = new System.Drawing.Point(258, 167);
this.textBoxAlpha.Name = "textBoxAlpha";
this.textBoxAlpha.Size = new System.Drawing.Size(30, 20);
this.textBoxAlpha.TabIndex = 5;
this.textBoxAlpha.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
this.textBoxAlpha.Click += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxAlpha.GotFocus += new System.EventHandler(this.TextBoxGotFocus);
this.textBoxAlpha.TextChanged += new System.EventHandler(this.TextBoxRGBTextChanged);
this.textBoxAlpha.KeyDown += new System.Windows.Forms.KeyEventHandler(this.TextBoxKeyDown);
//
// labelAlpha
//
this.labelAlpha.Font = new System.Drawing.Font("Tahoma", 11F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.World);
this.labelAlpha.Location = new System.Drawing.Point(210, 170);
this.labelAlpha.Name = "labelAlpha";
this.labelAlpha.Size = new System.Drawing.Size(78, 18);
this.labelAlpha.TabIndex = 11;
this.labelAlpha.Text = "Alpha";
//
// btnApply
//
this.btnApply.BackColor = System.Drawing.Color.Transparent;
this.btnApply.Location = new System.Drawing.Point(210, 191);
this.btnApply.Name = "btnApply";
this.btnApply.Size = new System.Drawing.Size(78, 23);
this.btnApply.TabIndex = 12;
this.btnApply.TabStop = false;
this.btnApply.Text = "Apply";
this.btnApply.UseVisualStyleBackColor = false;
this.btnApply.Click += new System.EventHandler(this.BtnApplyClick);
//
// ColorDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(292, 218);
this.Controls.Add(this.btnApply);
this.Controls.Add(this.textBoxAlpha);
this.Controls.Add(this.labelAlpha);
this.Controls.Add(this.labelRecentColors);
this.Controls.Add(this.textBoxBlue);
this.Controls.Add(this.textBoxGreen);
this.Controls.Add(this.textBoxRed);
this.Controls.Add(this.labelBlue);
this.Controls.Add(this.labelGreen);
this.Controls.Add(this.labelRed);
this.Controls.Add(this.textBoxHtmlColor);
this.Controls.Add(this.labelHtmlColor);
this.Controls.Add(this.colorPanel);
this.Controls.Add(this.btnTransparent);
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedDialog;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "ColorDialog";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "TestProject";
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.Label labelRed;
private System.Windows.Forms.Label labelGreen;
private System.Windows.Forms.Label labelBlue;
private System.Windows.Forms.TextBox textBoxHtmlColor;
private System.Windows.Forms.Label labelRecentColors;
private System.Windows.Forms.Label labelAlpha;
private System.Windows.Forms.Label labelHtmlColor;
private System.Windows.Forms.Button btnApply;
private System.Windows.Forms.TextBox textBoxAlpha;
private System.Windows.Forms.TextBox textBoxRed;
private System.Windows.Forms.TextBox textBoxGreen;
private System.Windows.Forms.TextBox textBoxBlue;
private System.Windows.Forms.Panel colorPanel;
private System.Windows.Forms.Button btnTransparent;
}
}

View file

@ -0,0 +1,242 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using GreenshotPlugin.Core;
namespace Greenshot {
/// <summary>
/// Description of ColorDialog.
/// </summary>
public partial class ColorDialog {
private static ColorDialog uniqueInstance;
private ColorDialog() {
this.SuspendLayout();
InitializeComponent();
lang = Language.GetInstance();
updateUI();
this.SuspendLayout();
this.createColorPalette(5,5,15,15);
this.createLastUsedColorButtonRow(5,190,15,15);
this.ResumeLayout();
}
public static ColorDialog GetInstance() {
if(uniqueInstance == null) {
uniqueInstance = new ColorDialog();
}
return uniqueInstance;
}
private ILanguage lang;
private List<Button> colorButtons = new List<Button>();
private List<Button> recentColorButtons = new List<Button>();
private List<Color> recentColors = new List<Color>();
private ToolTip toolTip = new ToolTip();
private bool updateInProgress = false;
public Color[] RecentColors {
get {return recentColors.ToArray();}
set {for(int i=0; i<value.Length; i++) {recentColors.Add(value[i]);}updateRecentColorsButtonRow();}
}
public Color Color {
get {return colorPanel.BackColor;}
set {previewColor(value,this);}
}
private void updateUI() {
this.Text = lang.GetString(LangKey.colorpicker_title);
this.btnApply.Text = lang.GetString(LangKey.colorpicker_apply);
this.btnTransparent.Text = lang.GetString(LangKey.colorpicker_transparent);
this.labelHtmlColor.Text = lang.GetString(LangKey.colorpicker_htmlcolor);
this.labelRed.Text = lang.GetString(LangKey.colorpicker_red);
this.labelGreen.Text = lang.GetString(LangKey.colorpicker_green);
this.labelBlue.Text = lang.GetString(LangKey.colorpicker_blue);
this.labelAlpha.Text = lang.GetString(LangKey.colorpicker_alpha);
this.labelRecentColors.Text = lang.GetString(LangKey.colorpicker_recentcolors);
}
#region user interface generation
private void createColorPalette(int x, int y, int w, int h) {
this.createColorButtonColumn(255,0,0, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(255,255/2,0, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(255,255,0, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(255/2,255,0, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(0,255,0, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(0,255,255/2, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(0,255,255, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(0,255/2,255, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(0,0,255, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(255/2,0,255, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(255,0,255, x, y, w, h, 11);
x += w;
this.createColorButtonColumn(255,0,255/2, x, y, w, h, 11);
x += w + 5;
this.createColorButtonColumn(255/2,255/2,255/2, x, y, w, h, 11);
this.Controls.AddRange(this.colorButtons.ToArray());
}
private void createColorButtonColumn(int red, int green, int blue, int x, int y, int w, int h, int shades) {
int shadedColorsNum = (shades - 1) / 2;
for(int i=0; i<=shadedColorsNum; i++) {
colorButtons.Add(createColorButton(red * i / shadedColorsNum, green * i /shadedColorsNum, blue * i / shadedColorsNum, x, y + i * h, w, h));
if(i>0) colorButtons.Add(createColorButton(red + (255 - red) * i / shadedColorsNum, green + (255 - green)* i /shadedColorsNum, blue+ (255 - blue) * i / shadedColorsNum, x, y + (i+shadedColorsNum) * h, w,h));
}
}
private Button createColorButton(int red, int green, int blue, int x, int y, int w, int h) {
return createColorButton(Color.FromArgb(255, red, green, blue), x, y, w, h);
}
private Button createColorButton(Color color, int x, int y, int w, int h) {
Button b = new Button();
b.BackColor = color;
b.FlatAppearance.BorderSize = 0;
b.FlatStyle = FlatStyle.Flat;
b.Location = new Point(x,y);
b.Size = new Size(w,h);
b.TabStop = false;
b.Click += new System.EventHandler(colorButtonClick);
toolTip.SetToolTip(b,ColorTranslator.ToHtml(color)+" | R:"+color.R +", G:"+color.G+", B:"+color.B);
return b;
}
private void createLastUsedColorButtonRow(int x, int y, int w, int h) {
for(int i=0; i<12; i++) {
Button b = this.createColorButton(Color.Transparent, x, y, w, h);
b.Enabled = false;
recentColorButtons.Add(b);
x += w;
}
this.Controls.AddRange(this.recentColorButtons.ToArray());
}
#endregion
#region update user interface
private void updateRecentColorsButtonRow() {
for(int i=0; i<recentColors.Count && i<12; i++) {
recentColorButtons[i].BackColor = recentColors[i];
recentColorButtons[i].Enabled = true;
}
}
private void previewColor(Color c, Control trigger) {
updateInProgress = true;
this.colorPanel.BackColor = c;
if(trigger != this.textBoxHtmlColor) {
this.textBoxHtmlColor.Text = System.Drawing.ColorTranslator.ToHtml(c);
} else {
if(!this.textBoxHtmlColor.Text.StartsWith("#")) {
int selStart = this.textBoxHtmlColor.SelectionStart;
int selLength = this.textBoxHtmlColor.SelectionLength;
this.textBoxHtmlColor.Text = "#" +this.textBoxHtmlColor.Text;
this.textBoxHtmlColor.Select(selStart+1, selLength+1);
}
}
if(trigger != this.textBoxRed && trigger != this.textBoxGreen && trigger != this.textBoxBlue && trigger != this.textBoxAlpha) {
this.textBoxRed.Text = c.R.ToString();
this.textBoxGreen.Text = c.G.ToString();
this.textBoxBlue.Text = c.B.ToString();
this.textBoxAlpha.Text = c.A.ToString();
}
updateInProgress = false;
}
private void addToRecentColors(Color c) {
recentColors.Remove(c);
recentColors.Insert(0, c);
if(recentColors.Count > 12) recentColors.RemoveRange(12,recentColors.Count-12);
updateRecentColorsButtonRow();
}
#endregion
#region textbox event handlers
void TextBoxHexadecimalTextChanged(object sender, System.EventArgs e)
{
if(updateInProgress) return;
TextBox tb = (TextBox) sender;
string t = tb.Text.Replace("#","");
int i = 0;
Int32.TryParse(t, System.Globalization.NumberStyles.AllowHexSpecifier, Thread.CurrentThread.CurrentCulture, out i);
Color c = Color.FromArgb(i);
Color opaqueColor = Color.FromArgb(255, c.R, c.G, c.B);
previewColor(opaqueColor, tb);
}
void TextBoxRGBTextChanged(object sender, System.EventArgs e)
{
if(updateInProgress) return;
TextBox tb = (TextBox) sender;
previewColor(Color.FromArgb(getColorPartIntFromString(textBoxAlpha.Text),getColorPartIntFromString(textBoxRed.Text),getColorPartIntFromString(textBoxGreen.Text),getColorPartIntFromString(textBoxBlue.Text)), tb);
}
void TextBoxGotFocus(object sender, System.EventArgs e) {
this.textBoxHtmlColor.SelectAll();
}
void TextBoxKeyDown(object sender, KeyEventArgs e) {
if(e.KeyCode == Keys.Return || e.KeyCode == Keys.Enter) {
addToRecentColors(colorPanel.BackColor);
}
}
#endregion
#region button event handlers
void colorButtonClick(object sender, System.EventArgs e) {
Button b = (Button) sender;
previewColor(b.BackColor, b);
}
void btnTransparentClick(object sender, System.EventArgs e)
{
colorButtonClick(sender, e);
}
void BtnApplyClick(object sender, System.EventArgs e)
{
this.DialogResult = DialogResult.OK;
this.Hide();
addToRecentColors(colorPanel.BackColor);
}
#endregion
#region helper functions
private int getColorPartIntFromString(string s){
int ret = 0;
Int32.TryParse(s,out ret);
if(ret < 0) ret = 0;
else if(ret > 255) ret = 255;
return ret;
}
#endregion
}
}

View file

@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>

View file

@ -0,0 +1,78 @@
using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows.Forms;
using System.Diagnostics;
namespace GreenShot
{
public delegate void ColorPickerEventHandler(object o, ColorPickerEventArgs e);
public class ColorPickerToolStripButton : System.Windows.Forms.ToolStripButton
{
private Color color;
public Point Offset = new Point(0,0);
public event ColorPickerEventHandler ColorPicked;
private ColorDialog cd;
public ColorPickerToolStripButton()
{
cd = ColorDialog.GetInstance();
this.Click += new System.EventHandler(this.ToolStripButton1Click);
}
public Color Color {
set {color = value;this.Invalidate();}
get {return color;}
}
protected override void OnPaint (PaintEventArgs e) {
base.OnPaint(e);
if(color != null) {
// replace transparent color with selected color
Graphics g = e.Graphics;
//Graphics g = Graphics.FromImage(Image);
ColorMap[] colorMap = new ColorMap[1];
colorMap[0] = new ColorMap();
colorMap[0].OldColor = Color.Magenta;//this.ImageTransparentColor;
colorMap[0].NewColor = color;
ImageAttributes attr = new ImageAttributes();
attr.SetRemapTable(colorMap);
Rectangle rect = new Rectangle(0, 0, Image.Width, Image.Height);
// todo find a way to retrieve transparency offset automatically
// for now, we use the public variable Offset to define this manually
rect.Offset(Offset.X,Offset.Y);
//Image.
Debug.WriteLine("paint!"+this.Text+": "+color);
//ssif(color.Equals(Color.Transparent)) ((Bitmap)Image).MakeTransparent(Color.Magenta);
g.DrawImage(Image, rect, 0, 0, rect.Width, rect.Height, GraphicsUnit.Pixel, attr);
//this.Image.In
}
}
void ToolStripButton1Click(object sender, System.EventArgs e)
{
cd.ShowDialog(this.Owner);
Color = cd.Color;
if(ColorPicked != null) {
ColorPicked(this, new ColorPickerEventArgs(Color, cd.RecentColors));
}
}
}
public class ColorPickerEventArgs : System.EventArgs {
public Color Color;
public Color[] RecentColors;
public ColorPickerEventArgs(Color color, Color[] recentColors) {
Color = color;
RecentColors = recentColors;
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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
{
partial class FlashlightForm : System.Windows.Forms.Form
{
/// <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.SuspendLayout();
//
// FlashlightForm
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.BackColor = System.Drawing.Color.White;
this.ClientSize = new System.Drawing.Size(292, 266);
this.ControlBox = false;
this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "FlashlightForm";
this.ShowIcon = false;
this.ShowInTaskbar = false;
this.Text = "FlashlightForm";
this.TopMost = true;
this.ResumeLayout(false);
}
}
}

View file

@ -0,0 +1,71 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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.Threading;
using System.Windows.Forms;
using Greenshot.Forms;
namespace Greenshot {
/// <summary>
/// Description of FlashlightForm.
/// </summary>
public partial class FlashlightForm : Form {
private int framesPerSecond = 25;
public FlashlightForm() {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
this.TransparencyKey = Color.Magenta;
}
public void FadeIn() {
Opacity = 0;
Show();
Fade(2, 0, 1, 2);
}
public void FadeOut() {
Fade(6, 1, 0, 2);
Hide();
}
private void Fade(int frames, double startOpacity, double targetOpacity, double exponent) {
try {
this.Opacity = startOpacity;
double baseOpacity = Math.Min(startOpacity, targetOpacity);
double diff = Math.Abs(targetOpacity - startOpacity);
double stepWidth= (double)(10) / (double)frames;
double maxValue = Math.Pow(10, exponent);
for(int i=0; i<=frames; i++) {
double x = ((startOpacity < targetOpacity) ? i : frames -i) * stepWidth;
double factor = Math.Pow(x,exponent) / 100;
this.Opacity = baseOpacity + factor * diff;
Thread.Sleep(1000 / framesPerSecond);
}
} catch (Exception e) {
Hide(); // ignore - after all, it's just a visual effect.
log4net.LogManager.GetLogger(typeof(FlashlightForm)).Warn("An exception occured while trying to face FlashlightForm", e);
}
}
}
}

1592
Greenshot/Forms/ImageEditorForm.Designer.cs generated Normal file

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,909 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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;
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.Text.RegularExpressions;
using System.Threading;
using System.Windows.Forms;
using Greenshot.Configuration;
using Greenshot.Drawing;
using Greenshot.Drawing.Fields;
using Greenshot.Drawing.Fields.Binding;
using Greenshot.Help;
using Greenshot.Helpers;
using Greenshot.Plugin;
using GreenshotPlugin.Core;
namespace Greenshot {
/// <summary>
/// Description of ImageEditorForm.
/// </summary>
public partial class ImageEditorForm : Form, IImageEditor {
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ImageEditorForm));
private AppConfig conf = AppConfig.GetInstance();
private ILanguage lang;
private string lastSaveFullPath;
public Surface surface;
private System.Windows.Forms.ToolStripButton[] toolbarButtons;
private static string[] SUPPORTED_CLIPBOARD_FORMATS = {typeof(string).FullName, "Text", "DeviceIndependentBitmap", "Bitmap", typeof(DrawableContainerList).FullName};
private bool originalBoldCheckState = false;
private bool originalItalicCheckState = false;
// Holds state if the image is saved
private bool saved;
// whether part of the editor controls are disabled depending on selected item(s)
private bool controlsDisabledDueToConfirmable = false;
/// <summary>
/// An Implementation for the IImageEditor, this way Plugins have access to the HWND handles wich can be used with Win32 API calls.
/// </summary>
public IWin32Window WindowHandle {
get { return this; }
}
public ImageEditorForm(Surface surface, bool outputMade) {
//
// The InitializeComponent() call is required for Windows Forms designer support.
//
InitializeComponent();
// Restore to previous location
FormHelper.RestoreGeometry(this, conf.Editor_WindowSize, conf.Editor_WindowLocation, conf.Editor_WindowState, conf.Editor_Previous_Screenbounds);
// Intial "saved" flag for asking if the image needs to be save
saved = outputMade;
// resizing the panel is futile, since it is docked. however, it seems
// to fix the bug (?) with the vscrollbar not being able to shrink to
// 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.Invalidated += new InvalidateEventHandler(InvalidatedSurface);
surface.DrawingModeChanged += new SurfaceDrawingModeEventHandler(surface_DrawingModeChanged);
this.fontFamilyComboBox.PropertyChanged += new PropertyChangedEventHandler(FontPropertyChanged);
surface.FieldAggregator.FieldChanged += new FieldChangedEventHandler( FieldAggregatorFieldChanged );
obfuscateModeButton.DropDownItemClicked += FilterPresetDropDownItemClicked;
highlightModeButton.DropDownItemClicked += FilterPresetDropDownItemClicked;
panel1.Controls.Add(surface);
lang = Language.GetInstance();
updateUI();
bindFieldControls();
refreshEditorControls();
toolbarButtons = new ToolStripButton[]{btnCursor,btnRect,btnEllipse,btnText,btnLine,btnArrow,btnHighlight, btnObfuscate, btnCrop};
//toolbarDropDownButtons = new ToolStripDropDownButton[]{btnBlur, btnPixeliate, btnTextHighlighter, btnAreaHighlighter, btnMagnifier};
PluginHelper.instance.CreateImageEditorOpenEvent(this);
pluginToolStripMenuItem.Visible = pluginToolStripMenuItem.DropDownItems.Count > 0;
emailToolStripMenuItem.Enabled = MapiMailMessage.HasMAPI();
}
private void InvalidatedSurface(object sender, InvalidateEventArgs eventArgs) {
saved = false;
}
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;
}
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);
this.btnCursor.Text = lang.GetString(LangKey.editor_cursortool);
this.btnRect.Text = lang.GetString(LangKey.editor_drawrectangle);
this.addRectangleToolStripMenuItem.Text = lang.GetString(LangKey.editor_drawrectangle);
this.btnEllipse.Text = lang.GetString(LangKey.editor_drawellipse);
this.addEllipseToolStripMenuItem.Text = lang.GetString(LangKey.editor_drawellipse);
this.btnText.Text = lang.GetString(LangKey.editor_drawtextbox);
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.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.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.pasteToolStripMenuItem.Text = lang.GetString(LangKey.editor_pastefromclipboard);
this.duplicateToolStripMenuItem.Text = lang.GetString(LangKey.editor_duplicate);
this.arrangeToolStripMenuItem.Text = lang.GetString(LangKey.editor_arrange);
this.upToTopToolStripMenuItem.Text = lang.GetString(LangKey.editor_uptotop);
this.upOneLevelToolStripMenuItem.Text = lang.GetString(LangKey.editor_uponelevel);
this.downOneLevelToolStripMenuItem.Text = lang.GetString(LangKey.editor_downonelevel);
this.downToBottomToolStripMenuItem.Text = lang.GetString(LangKey.editor_downtobottom);
this.btnLineColor.Text = lang.GetString(LangKey.editor_forecolor);
this.btnFillColor.Text = lang.GetString(LangKey.editor_backcolor);
this.lineThicknessLabel.Text = lang.GetString(LangKey.editor_thickness);
this.arrowHeadsDropDownButton.Text = lang.GetString(LangKey.editor_arrowheads);
this.helpToolStripMenuItem.Text = lang.GetString(LangKey.contextmenu_help);
this.helpToolStripMenuItem1.Text = lang.GetString(LangKey.contextmenu_help);
this.btnHelp.Text = lang.GetString(LangKey.contextmenu_help);
this.aboutToolStripMenuItem.Text = lang.GetString(LangKey.contextmenu_about);
this.copyPathMenuItem.Text = lang.GetString(LangKey.editor_copypathtoclipboard);
this.openDirectoryMenuItem.Text = lang.GetString(LangKey.editor_opendirinexplorer);
this.obfuscateModeButton.Text = lang.GetString(LangKey.editor_obfuscate_mode);
this.highlightModeButton.Text = lang.GetString(LangKey.editor_highlight_mode);
this.pixelizeToolStripMenuItem.Text = lang.GetString(LangKey.editor_obfuscate_pixelize);
this.blurToolStripMenuItem.Text = lang.GetString(LangKey.editor_obfuscate_blur);
this.textHighlightMenuItem.Text = lang.GetString(LangKey.editor_highlight_text);
this.areaHighlightMenuItem.Text = lang.GetString(LangKey.editor_highlight_area);
this.grayscaleHighlightMenuItem.Text = lang.GetString(LangKey.editor_highlight_grayscale);
this.magnifyMenuItem.Text = lang.GetString(LangKey.editor_highlight_magnify);
this.blurRadiusLabel.Text = lang.GetString(LangKey.editor_blur_radius);
this.brightnessLabel.Text = lang.GetString(LangKey.editor_brightness);
this.previewQualityLabel.Text = lang.GetString(LangKey.editor_preview_quality);
this.magnificationFactorLabel.Text = lang.GetString(LangKey.editor_magnification_factor);
this.pixelSizeLabel.Text = lang.GetString(LangKey.editor_pixel_size);
this.arrowHeadsLabel.Text = lang.GetString(LangKey.editor_arrowheads);
this.arrowHeadStartMenuItem.Text = lang.GetString(LangKey.editor_arrowheads_start);
this.arrowHeadEndMenuItem.Text = lang.GetString(LangKey.editor_arrowheads_end);
this.arrowHeadBothMenuItem.Text = lang.GetString(LangKey.editor_arrowheads_both);
this.arrowHeadNoneMenuItem.Text = lang.GetString(LangKey.editor_arrowheads_none);
this.shadowButton.Text = lang.GetString(LangKey.editor_shadow);
this.fontSizeLabel.Text = lang.GetString(LangKey.editor_fontsize);
this.fontBoldButton.Text = lang.GetString(LangKey.editor_bold);
this.fontItalicButton.Text = lang.GetString(LangKey.editor_italic);
this.btnConfirm.Text = lang.GetString(LangKey.editor_confirm);
this.btnCancel.Text = lang.GetString(LangKey.editor_cancel);
this.saveElementsToolStripMenuItem.Text = lang.GetString(LangKey.editor_save_objects);
this.loadElementsToolStripMenuItem.Text = lang.GetString(LangKey.editor_load_objects);
}
public ISurface Surface {
get {return surface;}
}
public void SetImagePath(string fullpath) {
this.lastSaveFullPath = fullpath;
if(fullpath == null) return;
updateStatusLabel(lang.GetFormattedString(LangKey.editor_imagesaved,fullpath),fileSavedStatusContextMenu);
this.Text = lang.GetString(LangKey.editor_title) + " - " + Path.GetFileName(fullpath);
this.saveToolStripMenuItem.Enabled = true;
}
void surface_DrawingModeChanged(object source, DrawingModes drawingMode) {
switch (drawingMode) {
case DrawingModes.None:
SetButtonChecked(btnCursor);
break;
case DrawingModes.Ellipse:
SetButtonChecked(btnEllipse);
break;
case DrawingModes.Rect:
SetButtonChecked(btnRect);
break;
case DrawingModes.Text:
SetButtonChecked(btnText);
break;
case DrawingModes.Line:
SetButtonChecked(btnLine);
break;
case DrawingModes.Arrow:
SetButtonChecked(btnArrow);
break;
case DrawingModes.Crop:
SetButtonChecked(btnCrop);
break;
case DrawingModes.Highlight:
SetButtonChecked(btnHighlight);
break;
case DrawingModes.Obfuscate:
SetButtonChecked(btnObfuscate);
break;
}
}
#region plugin interfaces
/**
* Interfaces for plugins, see GreenshotInterface for more details!
*/
public Image GetImageForExport() {
return surface.GetImageForExport();
}
public ICaptureDetails CaptureDetails {
get { return surface.CaptureDetails; }
}
public void SaveToStream(Stream stream, string extension, int quality) {
using (Image image = surface.GetImageForExport()) {
ImageOutput.SaveToStream(image, stream, extension, quality);
}
}
public ToolStripMenuItem GetPluginMenuItem() {
return pluginToolStripMenuItem;
}
#endregion
#region filesystem options
void SaveToolStripMenuItemClick(object sender, System.EventArgs e) {
try {
using (Image img = surface.GetImageForExport()) {
ImageOutput.Save(img, lastSaveFullPath, surface.CaptureDetails);
saved = true;
}
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) {
saved = true;
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);
saved = true;
}
updateStatusLabel(lang.GetString(LangKey.editor_storedtoclipboard));
} catch (Exception) {
updateStatusLabel(lang.GetString(LangKey.editor_clipboardfailed));
}
}
void BtnClipboardClick(object sender, EventArgs e) {
this.CopyImageToClipboardToolStripMenuItemClick(sender, e);
}
void PrintToolStripMenuItemClick(object sender, EventArgs e) {
InvokePrint();
}
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) {
saved = true;
updateStatusLabel(lang.GetFormattedString(LangKey.editor_senttoprinter,ps.PrinterName));
}
}
}
void CloseToolStripMenuItemClick(object sender, System.EventArgs e) {
this.Close();
}
#endregion
#region drawing options
void BtnEllipseClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Ellipse;
refreshFieldControls();
}
void BtnCursorClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.None;
refreshFieldControls();
}
void BtnRectClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Rect;
refreshFieldControls();
}
void BtnTextClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Text;
refreshFieldControls();
}
void BtnLineClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Line;
refreshFieldControls();
}
void BtnArrowClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Arrow;
refreshFieldControls();
}
void BtnCropClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Crop;
refreshFieldControls();
}
void BtnHighlightClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Highlight;
refreshFieldControls();
}
void BtnObfuscateClick(object sender, EventArgs e) {
surface.DrawingMode = DrawingModes.Obfuscate;
refreshFieldControls();
}
void SetButtonChecked(ToolStripButton btn) {
UncheckAllToolButtons();
btn.Checked = true;
}
private void UncheckAllToolButtons() {
foreach (ToolStripButton butt in toolbarButtons) {
butt.Checked = false;
}
}
void AddRectangleToolStripMenuItemClick(object sender, System.EventArgs e) {
BtnRectClick(sender, e);
}
void AddEllipseToolStripMenuItemClick(object sender, System.EventArgs e) {
BtnEllipseClick(sender, e);
}
void AddTextBoxToolStripMenuItemClick(object sender, System.EventArgs e) {
BtnTextClick(sender, e);
}
void DrawLineToolStripMenuItemClick(object sender, System.EventArgs e) {
BtnLineClick(sender, e);
}
void DrawArrowToolStripMenuItemClick(object sender, EventArgs e) {
BtnArrowClick(sender, e);
}
void DrawHighlightToolStripMenuItemClick(object sender, EventArgs e) {
BtnHighlightClick(sender, e);
}
void BlurToolStripMenuItemClick(object sender, EventArgs e) {
BtnObfuscateClick(sender, e);
}
void RemoveObjectToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.RemoveSelectedElements();
}
void BtnDeleteClick(object sender, EventArgs e) {
RemoveObjectToolStripMenuItemClick(sender, e);
}
#endregion
#region copy&paste options
void CutToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.CutSelectedElements();
updateClipboardSurfaceDependencies();
}
void BtnCutClick(object sender, System.EventArgs e) {
CutToolStripMenuItemClick(sender, e);
}
void CopyToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.CopySelectedElements();
updateClipboardSurfaceDependencies();
}
void BtnCopyClick(object sender, System.EventArgs e) {
CopyToolStripMenuItemClick(sender, e);
}
void PasteToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.PasteElementFromClipboard();
updateClipboardSurfaceDependencies();
}
void BtnPasteClick(object sender, System.EventArgs e) {
PasteToolStripMenuItemClick(sender, e);
}
void DuplicateToolStripMenuItemClick(object sender, System.EventArgs e) {
surface.DuplicateSelectedElements();
updateClipboardSurfaceDependencies();
}
#endregion
#region element properties
void UpOneLevelToolStripMenuItemClick(object sender, EventArgs e) {
surface.PullElementsUp();
}
void DownOneLevelToolStripMenuItemClick(object sender, EventArgs e) {
surface.PushElementsDown();
}
void UpToTopToolStripMenuItemClick(object sender, EventArgs e) {
surface.PullElementsToTop();
}
void DownToBottomToolStripMenuItemClick(object sender, EventArgs e) {
surface.PushElementsToBottom();
}
#endregion
#region help
void HelpToolStripMenuItem1Click(object sender, System.EventArgs e) {
new HelpBrowserForm(conf.Ui_Language).Show();
}
void AboutToolStripMenuItemClick(object sender, System.EventArgs e) {
new AboutForm().Show();
}
void PreferencesToolStripMenuItemClick(object sender, System.EventArgs e) {
new SettingsForm().Show();
}
void BtnSettingsClick(object sender, System.EventArgs e) {
PreferencesToolStripMenuItemClick(sender, e);
}
void BtnHelpClick(object sender, System.EventArgs e) {
HelpToolStripMenuItem1Click(sender, e);
}
#endregion
#region image editor event handlers
void ImageEditorFormActivated(object sender, EventArgs e) {
updateClipboardSurfaceDependencies();
}
void ImageEditorFormFormClosing(object sender, FormClosingEventArgs e) {
if (!saved) {
DialogResult result = MessageBox.Show(lang.GetString(LangKey.editor_close_on_save), lang.GetString(LangKey.editor_close_on_save_title), MessageBoxButtons.YesNoCancel, MessageBoxIcon.Question);
if (result.Equals(DialogResult.Cancel)) {
e.Cancel = true;
return;
}
if (result.Equals(DialogResult.Yes)) {
if (lastSaveFullPath != null) {
SaveToolStripMenuItemClick(sender,e);
} else {
SaveAsToolStripMenuItemClick(sender, e);
}
// Check if the save was made, if not it was cancelled so we cancel the closing
if (!saved) {
e.Cancel = true;
return;
}
}
}
// persist our geometry string.
FormHelper.StoreGeometry(this, out conf.Editor_WindowSize, out conf.Editor_WindowLocation, out conf.Editor_WindowState, out conf.Editor_Previous_Screenbounds);
conf.Store();
surface.Dispose();
System.GC.Collect();
}
void ImageEditorFormKeyDown(object sender, KeyEventArgs e) {
// LOG.Debug("Got key event "+e.KeyCode + ", " + e.Modifiers);
// 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)) {
BtnCursorClick(sender, e);
} else if (Keys.R.Equals(e.KeyCode)) {
BtnRectClick(sender, e);
} else if (Keys.E.Equals(e.KeyCode)) {
BtnEllipseClick(sender, e);
} else if (Keys.L.Equals(e.KeyCode)) {
BtnLineClick(sender, e);
} else if (Keys.A.Equals(e.KeyCode)) {
BtnArrowClick(sender, e);
} else if (Keys.T.Equals(e.KeyCode)) {
BtnTextClick(sender, e);
} else if(Keys.H.Equals(e.KeyCode)) {
BtnHighlightClick(sender, e);
} else if(Keys.O.Equals(e.KeyCode)) {
BtnObfuscateClick(sender, e);
} else if(Keys.C.Equals(e.KeyCode)) {
BtnCropClick(sender, e);
}
}
}
#endregion
#region cursor key strokes
protected override bool ProcessCmdKey(ref Message msg, Keys k) {
// disable default key handling if surface has requested a lock
if(!surface.KeysLocked) {
surface.ProcessCmdKey(k);
return base.ProcessCmdKey(ref msg, k);
}
return false;
}
#endregion
#region helpers
private void updateClipboardSurfaceDependencies() {
// check dependencies for the Surface
bool hasItems = surface.HasSelectedElements();
bool actionAllowedForSelection = hasItems && !controlsDisabledDueToConfirmable;
this.cutToolStripMenuItem.Enabled = actionAllowedForSelection;
this.btnCut.Enabled = actionAllowedForSelection;
this.btnCopy.Enabled = actionAllowedForSelection;
this.copyToolStripMenuItem.Enabled = actionAllowedForSelection;
this.duplicateToolStripMenuItem.Enabled = actionAllowedForSelection;
// check dependencies for the Clipboard
bool hasClipboard = ClipboardHelper.ContainsFormat(SUPPORTED_CLIPBOARD_FORMATS);
this.btnPaste.Enabled = hasClipboard && !controlsDisabledDueToConfirmable;
this.pasteToolStripMenuItem.Enabled = hasClipboard && !controlsDisabledDueToConfirmable;
}
#endregion
#region status label handling
private void updateStatusLabel(string text, ContextMenuStrip contextMenu) {
statusLabel.Text = text;
statusStrip1.ContextMenuStrip = contextMenu;
}
private void updateStatusLabel(string text) {
updateStatusLabel(text, null);
}
private void clearStatusLabel() {
updateStatusLabel(null, null);
}
void StatusLabelClicked(object sender, MouseEventArgs e) {
ToolStrip ss = (StatusStrip)((ToolStripStatusLabel)sender).Owner;
if(ss.ContextMenuStrip != null) {
ss.ContextMenuStrip.Show(ss, e.X, e.Y);
}
}
void CopyPathMenuItemClick(object sender, EventArgs e) {
Clipboard.SetText(lastSaveFullPath);
}
void OpenDirectoryMenuItemClick(object sender, EventArgs e) {
ProcessStartInfo psi = new ProcessStartInfo("explorer");
psi.Arguments = Path.GetDirectoryName(lastSaveFullPath);
psi.UseShellExecute = false;
Process p = new Process();
p.StartInfo = psi;
p.Start();
}
#endregion
private void bindFieldControls() {
new BidirectionalBinding(btnFillColor, "SelectedColor", surface.FieldAggregator.GetField(FieldType.FILL_COLOR), "Value", NotNullValidator.GetInstance());
new BidirectionalBinding(btnLineColor, "SelectedColor", surface.FieldAggregator.GetField(FieldType.LINE_COLOR), "Value", NotNullValidator.GetInstance());
new BidirectionalBinding(lineThicknessUpDown, "Value", surface.FieldAggregator.GetField(FieldType.LINE_THICKNESS), "Value", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(blurRadiusUpDown, "Value", surface.FieldAggregator.GetField(FieldType.BLUR_RADIUS), "Value", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(magnificationFactorUpDown, "Value", surface.FieldAggregator.GetField(FieldType.MAGNIFICATION_FACTOR), "Value", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(pixelSizeUpDown, "Value", surface.FieldAggregator.GetField(FieldType.PIXEL_SIZE), "Value", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(brightnessUpDown, "Value", surface.FieldAggregator.GetField(FieldType.BRIGHTNESS), "Value", DecimalDoublePercentageConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(fontFamilyComboBox, "Text", surface.FieldAggregator.GetField(FieldType.FONT_FAMILY), "Value", NotNullValidator.GetInstance());
new BidirectionalBinding(fontSizeUpDown, "Value", surface.FieldAggregator.GetField(FieldType.FONT_SIZE), "Value", DecimalFloatConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(fontBoldButton, "Checked", surface.FieldAggregator.GetField(FieldType.FONT_BOLD), "Value", NotNullValidator.GetInstance());
new BidirectionalBinding(fontItalicButton, "Checked", surface.FieldAggregator.GetField(FieldType.FONT_ITALIC), "Value", NotNullValidator.GetInstance());
new BidirectionalBinding(shadowButton, "Checked", surface.FieldAggregator.GetField(FieldType.SHADOW), "Value", NotNullValidator.GetInstance());
new BidirectionalBinding(previewQualityUpDown, "Value", surface.FieldAggregator.GetField(FieldType.PREVIEW_QUALITY), "Value", DecimalDoublePercentageConverter.GetInstance(), NotNullValidator.GetInstance());
new BidirectionalBinding(obfuscateModeButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_OBFUSCATE), "Value");
new BidirectionalBinding(highlightModeButton, "SelectedTag", surface.FieldAggregator.GetField(FieldType.PREPARED_FILTER_HIGHLIGHT), "Value");
}
/// <summary>
/// shows/hides field controls (2nd toolbar on top) depending on fields of selected elements
/// </summary>
private void refreshFieldControls() {
propertiesToolStrip.SuspendLayout();
if(surface.HasSelectedElements() || surface.DrawingMode != DrawingModes.None) {
FieldAggregator props = surface.FieldAggregator;
btnFillColor.Visible = props.HasFieldValue(FieldType.FILL_COLOR);
btnLineColor.Visible = props.HasFieldValue(FieldType.LINE_COLOR);
lineThicknessLabel.Visible = lineThicknessUpDown.Visible = props.HasFieldValue(FieldType.LINE_THICKNESS);
blurRadiusLabel.Visible = blurRadiusUpDown.Visible = props.HasFieldValue(FieldType.BLUR_RADIUS);
previewQualityLabel.Visible = previewQualityUpDown.Visible = props.HasFieldValue(FieldType.PREVIEW_QUALITY);
magnificationFactorLabel.Visible = magnificationFactorUpDown.Visible = props.HasFieldValue(FieldType.MAGNIFICATION_FACTOR);
pixelSizeLabel.Visible = pixelSizeUpDown.Visible = props.HasFieldValue(FieldType.PIXEL_SIZE);
brightnessLabel.Visible = brightnessUpDown.Visible = props.HasFieldValue(FieldType.BRIGHTNESS);
arrowHeadsLabel.Visible = arrowHeadsDropDownButton.Visible = props.HasFieldValue(FieldType.ARROWHEADS);
fontFamilyComboBox.Visible = props.HasFieldValue(FieldType.FONT_FAMILY);
fontSizeLabel.Visible = fontSizeUpDown.Visible = props.HasFieldValue(FieldType.FONT_SIZE);
fontBoldButton.Visible = props.HasFieldValue(FieldType.FONT_BOLD);
fontItalicButton.Visible = props.HasFieldValue(FieldType.FONT_ITALIC);
shadowButton.Visible = props.HasFieldValue(FieldType.SHADOW);
btnConfirm.Visible = btnCancel.Visible = props.HasFieldValue(FieldType.FLAGS)
&& ((FieldType.Flag)props.GetFieldValue(FieldType.FLAGS)&FieldType.Flag.CONFIRMABLE) == FieldType.Flag.CONFIRMABLE;
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;
}
}
propertiesToolStrip.ResumeLayout();
}
/// <summary>
/// refreshes all editor controls depending on selected elements and their fields
/// </summary>
private void refreshEditorControls() {
FieldAggregator props = surface.FieldAggregator;
// if a confirmable element is selected, we must disable most of the controls
// since we demand confirmation or cancel for confirmable element
if (props.HasFieldValue(FieldType.FLAGS) && ((FieldType.Flag)props.GetFieldValue(FieldType.FLAGS) & FieldType.Flag.CONFIRMABLE) == FieldType.Flag.CONFIRMABLE) {
// disable most controls
if(!controlsDisabledDueToConfirmable) {
ToolStripItemEndisabler.Disable(menuStrip1);
ToolStripItemEndisabler.Disable(toolStrip1);
ToolStripItemEndisabler.Disable(toolStrip2);
ToolStripItemEndisabler.Enable(closeToolStripMenuItem);
ToolStripItemEndisabler.Enable(helpToolStripMenuItem);
ToolStripItemEndisabler.Enable(aboutToolStripMenuItem);
ToolStripItemEndisabler.Enable(preferencesToolStripMenuItem);
controlsDisabledDueToConfirmable = true;
}
} else if(controlsDisabledDueToConfirmable) {
// re-enable disabled controls, confirmable element has either been confirmed or cancelled
ToolStripItemEndisabler.Enable(menuStrip1);
ToolStripItemEndisabler.Enable(toolStrip1);
ToolStripItemEndisabler.Enable(toolStrip2);
controlsDisabledDueToConfirmable = false;
}
// 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;
// en/disablearrage controls depending on hierarchy of selected elements
bool push = actionAllowedForSelection && surface.CanPushSelectionDown();
bool pull = actionAllowedForSelection && surface.CanPullSelectionUp();
this.arrangeToolStripMenuItem.Enabled = (push || pull);
if (this.arrangeToolStripMenuItem.Enabled) {
this.upToTopToolStripMenuItem.Enabled = pull;
this.upOneLevelToolStripMenuItem.Enabled = pull;
this.downToBottomToolStripMenuItem.Enabled = push;
this.downOneLevelToolStripMenuItem.Enabled = push;
}
// finally show/hide field controls depending on the fields of selected elements
refreshFieldControls();
}
void ArrowHeadsToolStripMenuItemClick(object sender, EventArgs e) {
surface.FieldAggregator.GetField(FieldType.ARROWHEADS).Value = (ArrowContainer.ArrowHeadCombination)((ToolStripMenuItem)sender).Tag;
}
void EditToolStripMenuItemClick(object sender, EventArgs e) {
updateClipboardSurfaceDependencies();
}
void FontPropertyChanged(object sender, EventArgs e) {
// in case we forced another FontStyle before, reset it first.
if(originalBoldCheckState != fontBoldButton.Checked) fontBoldButton.Checked = originalBoldCheckState;
if(originalItalicCheckState != fontItalicButton.Checked) fontItalicButton.Checked = originalItalicCheckState;
FontFamily fam = fontFamilyComboBox.FontFamily;
bool boldAvailable = fam.IsStyleAvailable(FontStyle.Bold);
if(!boldAvailable) {
originalBoldCheckState = fontBoldButton.Checked;
fontBoldButton.Checked = false;
}
fontBoldButton.Enabled = boldAvailable;
bool italicAvailable = fam.IsStyleAvailable(FontStyle.Italic);
if(!italicAvailable) fontItalicButton.Checked = false;
fontItalicButton.Enabled = italicAvailable;
bool regularAvailable = fam.IsStyleAvailable(FontStyle.Regular);
if(!regularAvailable) {
if(boldAvailable) {
fontBoldButton.Checked = true;
} else if(italicAvailable) {
fontItalicButton.Checked = true;
}
}
}
void FieldAggregatorFieldChanged(object sender, FieldChangedEventArgs e) {
// in addition to selection, deselection of elements, we need to
// refresh toolbar if prepared filter mode is changed
if(e.Field.FieldType == FieldType.PREPARED_FILTER_HIGHLIGHT) {
refreshFieldControls();
}
}
void FontBoldButtonClick(object sender, EventArgs e) {
originalBoldCheckState = fontBoldButton.Checked;
}
void FontItalicButtonClick(object sender, System.EventArgs e) {
originalItalicCheckState = fontItalicButton.Checked;
}
void ToolBarFocusableElementGotFocus(object sender, System.EventArgs e) {
surface.KeysLocked = true;
}
void ToolBarFocusableElementLostFocus(object sender, System.EventArgs e) {
surface.KeysLocked = false;
}
void SaveElementsToolStripMenuItemClick(object sender, EventArgs e) {
SaveFileDialog saveFileDialog = new SaveFileDialog();
saveFileDialog.Filter = "Greenshot templates (*.gst)|*.gst";
saveFileDialog.FileName = FilenameHelper.GetFilenameWithoutExtensionFromPattern(conf.Output_File_FilenamePattern, surface.CaptureDetails);
DialogResult dialogResult = saveFileDialog.ShowDialog();
if(dialogResult.Equals(DialogResult.OK)) {
using (Stream streamWrite = File.OpenWrite(saveFileDialog.FileName)) {
surface.SaveElementsToStream(streamWrite);
}
}
}
void LoadElementsToolStripMenuItemClick(object sender, EventArgs e) {
OpenFileDialog openFileDialog = new OpenFileDialog();
openFileDialog.Filter = "Greenshot templates (*.gst)|*.gst";
if (openFileDialog.ShowDialog() == DialogResult.OK) {
using (Stream streamRead = File.OpenRead(openFileDialog.FileName)) {
surface.LoadElementsFromStream(streamRead);
}
surface.Refresh();
}
}
void EmailToolStripMenuItemClick(object sender, EventArgs e) {
using (Image img = surface.GetImageForExport()) {
MapiMailMessage.SendImage(img, surface.CaptureDetails);
saved = true;
}
}
void BtnEmailClick(object sender, EventArgs e) {
EmailToolStripMenuItemClick(sender, e);
}
protected void FilterPresetDropDownItemClicked(object sender, ToolStripItemClickedEventArgs e) {
refreshFieldControls();
}
void SelectAllToolStripMenuItemClick(object sender, EventArgs e) {
surface.SelectAllElements();
}
void BtnConfirmClick(object sender, EventArgs e) {
surface.ConfirmSelectedConfirmableElements(true);
refreshFieldControls();
}
void BtnCancelClick(object sender, EventArgs e) {
surface.ConfirmSelectedConfirmableElements(false);
refreshFieldControls();
}
}
}

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,135 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2010 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 {
partial class JpegQualityDialog : System.Windows.Forms.Form {
/// <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()
{
System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(JpegQualityDialog));
this.label_choosejpegquality = new System.Windows.Forms.Label();
this.textBoxJpegQuality = new System.Windows.Forms.TextBox();
this.trackBarJpegQuality = new System.Windows.Forms.TrackBar();
this.checkbox_dontaskagain = new System.Windows.Forms.CheckBox();
this.button_ok = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.trackBarJpegQuality)).BeginInit();
this.SuspendLayout();
//
// label_choosejpegquality
//
this.label_choosejpegquality.Location = new System.Drawing.Point(12, 9);
this.label_choosejpegquality.Name = "label_choosejpegquality";
this.label_choosejpegquality.Size = new System.Drawing.Size(268, 32);
this.label_choosejpegquality.TabIndex = 15;
this.label_choosejpegquality.Text = "Choose JPEG Quality";
//
// textBoxJpegQuality
//
this.textBoxJpegQuality.Location = new System.Drawing.Point(245, 44);
this.textBoxJpegQuality.Name = "textBoxJpegQuality";
this.textBoxJpegQuality.ReadOnly = true;
this.textBoxJpegQuality.Size = new System.Drawing.Size(35, 20);
this.textBoxJpegQuality.TabIndex = 16;
this.textBoxJpegQuality.TextAlign = System.Windows.Forms.HorizontalAlignment.Right;
//
// trackBarJpegQuality
//
this.trackBarJpegQuality.LargeChange = 10;
this.trackBarJpegQuality.Location = new System.Drawing.Point(12, 44);
this.trackBarJpegQuality.Maximum = 100;
this.trackBarJpegQuality.Name = "trackBarJpegQuality";
this.trackBarJpegQuality.Size = new System.Drawing.Size(233, 45);
this.trackBarJpegQuality.TabIndex = 14;
this.trackBarJpegQuality.TickFrequency = 10;
this.trackBarJpegQuality.Scroll += new System.EventHandler(this.TrackBarJpegQualityScroll);
//
// checkbox_dontaskagain
//
this.checkbox_dontaskagain.CheckAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_dontaskagain.ImageAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_dontaskagain.Location = new System.Drawing.Point(12, 81);
this.checkbox_dontaskagain.Name = "checkbox_dontaskagain";
this.checkbox_dontaskagain.Size = new System.Drawing.Size(268, 39);
this.checkbox_dontaskagain.TabIndex = 17;
this.checkbox_dontaskagain.Text = "Save as default quality and do not ask again.";
this.checkbox_dontaskagain.TextAlign = System.Drawing.ContentAlignment.TopLeft;
this.checkbox_dontaskagain.UseVisualStyleBackColor = true;
//
// button_ok
//
this.button_ok.DialogResult = System.Windows.Forms.DialogResult.Cancel;
this.button_ok.Location = new System.Drawing.Point(205, 126);
this.button_ok.Name = "button_ok";
this.button_ok.Size = new System.Drawing.Size(75, 23);
this.button_ok.TabIndex = 18;
this.button_ok.Text = "OK";
this.button_ok.UseVisualStyleBackColor = true;
this.button_ok.Click += new System.EventHandler(this.Button_okClick);
//
// JpegQualityDialog
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.ClientSize = new System.Drawing.Size(299, 161);
this.Controls.Add(this.button_ok);
this.Controls.Add(this.checkbox_dontaskagain);
this.Controls.Add(this.label_choosejpegquality);
this.Controls.Add(this.textBoxJpegQuality);
this.Controls.Add(this.trackBarJpegQuality);
this.Icon = ((System.Drawing.Icon)(resources.GetObject("$this.Icon")));
this.MaximizeBox = false;
this.MinimizeBox = false;
this.Name = "JpegQualityDialog";
this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Hide;
this.Text = "JpegQualityDialog";
((System.ComponentModel.ISupportInitialize)(this.trackBarJpegQuality)).EndInit();
this.ResumeLayout(false);
this.PerformLayout();
}
private System.Windows.Forms.Button button_ok;
private System.Windows.Forms.CheckBox checkbox_dontaskagain;
private System.Windows.Forms.TrackBar trackBarJpegQuality;
private System.Windows.Forms.TextBox textBoxJpegQuality;
private System.Windows.Forms.Label label_choosejpegquality;
}
}

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