Merge pull request #58 from greenshot/release/1.2.9BF2

Release/1.2.9 bf2
This commit is contained in:
Robin Krom 2017-01-29 21:15:05 +01:00 committed by GitHub
commit db9bf12e0c
52 changed files with 1029 additions and 452 deletions

View file

@ -68,8 +68,10 @@ namespace Greenshot.Controls {
} }
private void ColorButtonClick(object sender, EventArgs e) { private void ColorButtonClick(object sender, EventArgs e) {
ColorDialog colorDialog = ColorDialog.GetInstance(); var colorDialog = new ColorDialog
colorDialog.Color = SelectedColor; {
Color = SelectedColor
};
// Using the parent to make sure the dialog doesn't show on another window // Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent); colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult == DialogResult.Cancel) if (colorDialog.DialogResult == DialogResult.Cancel)

View file

@ -66,8 +66,10 @@ namespace Greenshot.Controls {
} }
private void ColorButtonClick(object sender, EventArgs e) { private void ColorButtonClick(object sender, EventArgs e) {
ColorDialog colorDialog = ColorDialog.GetInstance(); var colorDialog = new ColorDialog
colorDialog.Color = SelectedColor; {
Color = SelectedColor
};
// Using the parent to make sure the dialog doesn't show on another window // Using the parent to make sure the dialog doesn't show on another window
colorDialog.ShowDialog(Parent.Parent); colorDialog.ShowDialog(Parent.Parent);
if (colorDialog.DialogResult == DialogResult.Cancel) if (colorDialog.DialogResult == DialogResult.Cancel)

View file

@ -115,6 +115,7 @@ namespace Greenshot.Destinations {
pattern = "greenshot ${capturetime}"; pattern = "greenshot ${capturetime}";
} }
string filename = FilenameHelper.GetFilenameFromPattern(pattern, CoreConfig.OutputFileFormat, captureDetails); string filename = FilenameHelper.GetFilenameFromPattern(pattern, CoreConfig.OutputFileFormat, captureDetails);
CoreConfig.ValidateAndCorrectOutputFilePath();
string filepath = FilenameHelper.FillVariables(CoreConfig.OutputFilePath, false); string filepath = FilenameHelper.FillVariables(CoreConfig.OutputFilePath, false);
try { try {
fullPath = Path.Combine(filepath, filename); fullPath = Path.Combine(filepath, filename);

View file

@ -27,6 +27,7 @@ using Greenshot.Plugin.Drawing;
using GreenshotPlugin.Interfaces.Drawing; using GreenshotPlugin.Interfaces.Drawing;
using System.Collections.Generic; using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Linq;
namespace Greenshot.Drawing.Fields namespace Greenshot.Drawing.Fields
{ {
@ -203,7 +204,7 @@ namespace Greenshot.Drawing.Fields
{ {
return; return;
} }
foreach (var drawableContainer1 in _boundContainers) foreach (var drawableContainer1 in _boundContainers.ToList())
{ {
var drawableContainer = (DrawableContainer) drawableContainer1; var drawableContainer = (DrawableContainer) drawableContainer1;
if (!drawableContainer.HasField(field.FieldType)) if (!drawableContainer.HasField(field.FieldType))

View file

@ -56,9 +56,10 @@ namespace Greenshot.Drawing
/// <summary> /// <summary>
/// Restore the target gripper /// Restore the target gripper
/// </summary> /// </summary>
/// <param name="context"></param> /// <param name="streamingContext">StreamingContext</param>
protected override void OnDeserialized(StreamingContext context) protected override void OnDeserialized(StreamingContext streamingContext)
{ {
base.OnDeserialized(streamingContext);
InitAdorner(Color.Green, _storedTargetGripperLocation); InitAdorner(Color.Green, _storedTargetGripperLocation);
} }
#endregion #endregion
@ -303,7 +304,6 @@ namespace Greenshot.Drawing
tail.Dispose(); tail.Dispose();
// Draw the text // Draw the text
UpdateFormat();
DrawText(graphics, rect, lineThickness, lineColor, shadow, StringFormat, Text, Font); DrawText(graphics, rect, lineThickness, lineColor, shadow, StringFormat, Text, Font);
} }

View file

@ -272,15 +272,22 @@ namespace Greenshot.Drawing
_parent.Controls.Add(_textBox); _parent.Controls.Add(_textBox);
} }
EnsureTextBoxContrast(); EnsureTextBoxContrast();
if (_textBox != null)
{
_textBox.Show(); _textBox.Show();
_textBox.Focus(); _textBox.Focus();
} }
}
/// <summary> /// <summary>
/// Makes textbox background dark if text color is very bright /// Makes textbox background dark if text color is very bright
/// </summary> /// </summary>
private void EnsureTextBoxContrast() private void EnsureTextBoxContrast()
{ {
if (_textBox == null)
{
return;
}
Color lc = GetFieldValueAsColor(FieldType.LINE_COLOR); Color lc = GetFieldValueAsColor(FieldType.LINE_COLOR);
if (lc.R > 203 && lc.G > 203 && lc.B > 203) if (lc.R > 203 && lc.G > 203 && lc.B > 203)
{ {
@ -295,7 +302,7 @@ namespace Greenshot.Drawing
private void HideTextBox() private void HideTextBox()
{ {
_parent.Focus(); _parent.Focus();
_textBox.Hide(); _textBox?.Hide();
_parent.KeysLocked = false; _parent.KeysLocked = false;
_parent.Controls.Remove(_textBox); _parent.Controls.Remove(_textBox);
} }
@ -424,6 +431,10 @@ namespace Greenshot.Drawing
/// </summary> /// </summary>
private void UpdateTextBoxPosition() private void UpdateTextBoxPosition()
{ {
if (_textBox == null)
{
return;
}
int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS); int lineThickness = GetFieldValueAsInt(FieldType.LINE_THICKNESS);
int lineWidth = (int)Math.Floor(lineThickness / 2d); int lineWidth = (int)Math.Floor(lineThickness / 2d);

View file

@ -34,10 +34,9 @@ namespace Greenshot {
/// Description of ColorDialog. /// Description of ColorDialog.
/// </summary> /// </summary>
public partial class ColorDialog : BaseForm { public partial class ColorDialog : BaseForm {
private static ColorDialog _uniqueInstance;
private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>(); private static readonly EditorConfiguration EditorConfig = IniConfig.GetIniSection<EditorConfiguration>();
private ColorDialog() { public ColorDialog() {
SuspendLayout(); SuspendLayout();
InitializeComponent(); InitializeComponent();
SuspendLayout(); SuspendLayout();
@ -47,11 +46,6 @@ namespace Greenshot {
UpdateRecentColorsButtonRow(); UpdateRecentColorsButtonRow();
} }
public static ColorDialog GetInstance()
{
return _uniqueInstance ?? (_uniqueInstance = new ColorDialog());
}
private readonly List<Button> _colorButtons = new List<Button>(); private readonly List<Button> _colorButtons = new List<Button>();
private readonly List<Button> _recentColorButtons = new List<Button>(); private readonly List<Button> _recentColorButtons = new List<Button>();
private readonly ToolTip _toolTip = new ToolTip(); private readonly ToolTip _toolTip = new ToolTip();

View file

@ -21,7 +21,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing; using System.Drawing;
using System.Drawing.Drawing2D; using System.Drawing.Drawing2D;
using System.IO; using System.IO;
@ -864,9 +863,11 @@ namespace Greenshot {
RotateCwToolstripButtonClick(sender, e); RotateCwToolstripButtonClick(sender, e);
break; break;
case Keys.Add: // Ctrl + + case Keys.Add: // Ctrl + +
case Keys.Oemplus: // Ctrl + +
EnlargeCanvasToolStripMenuItemClick(sender, e); EnlargeCanvasToolStripMenuItemClick(sender, e);
break; break;
case Keys.Subtract: // Ctrl + - case Keys.Subtract: // Ctrl + -
case Keys.OemMinus: // Ctrl + -
ShrinkCanvasToolStripMenuItemClick(sender, e); ShrinkCanvasToolStripMenuItemClick(sender, e);
break; break;
} }
@ -1001,24 +1002,12 @@ namespace Greenshot {
} }
private void OpenDirectoryMenuItemClick(object sender, EventArgs e) { private void OpenDirectoryMenuItemClick(object sender, EventArgs e) {
var path = Path.GetDirectoryName(_surface.LastSaveFullPath); ExplorerHelper.OpenInExplorer(_surface.LastSaveFullPath);
if (path == null)
{
return;
}
var processStartInfo = new ProcessStartInfo("explorer")
{
Arguments = path,
UseShellExecute = false
};
using (var process = new Process()) {
process.StartInfo = processStartInfo;
process.Start();
}
} }
#endregion #endregion
private void BindFieldControls() { private void BindFieldControls() {
// TODO: This is actually risky, if there are no references than the objects may be garbage collected
new BidirectionalBinding(btnFillColor, "SelectedColor", _surface.FieldAggregator.GetField(FieldType.FILL_COLOR), "Value", NotNullValidator.GetInstance()); 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(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(lineThicknessUpDown, "Value", _surface.FieldAggregator.GetField(FieldType.LINE_THICKNESS), "Value", DecimalIntConverter.GetInstance(), NotNullValidator.GetInstance());

View file

@ -1307,46 +1307,11 @@ namespace Greenshot {
private void NotifyIconClick(ClickActions clickAction) { private void NotifyIconClick(ClickActions clickAction) {
switch (clickAction) { switch (clickAction) {
case ClickActions.OPEN_LAST_IN_EXPLORER: case ClickActions.OPEN_LAST_IN_EXPLORER:
string path = _conf.OutputFileAsFullpath; Contextmenu_OpenRecent(this, null);
if (!File.Exists(path)) {
string lastFilePath = Path.GetDirectoryName(_conf.OutputFileAsFullpath);
if (!string.IsNullOrEmpty(lastFilePath) && Directory.Exists(lastFilePath)) {
path = lastFilePath;
}
}
if (path == null) {
string configPath = FilenameHelper.FillVariables(_conf.OutputFilePath, false);
if (Directory.Exists(configPath)) {
path = configPath;
}
}
if (path != null) {
try {
// Check if path is a directory
if (Directory.Exists(path))
{
using (Process.Start(path))
{
}
}
// Check if path is a file
else if (File.Exists(path))
{
// Start the explorer process and select the file
using (var explorer = Process.Start("explorer.exe", $"/select,\"{path}\""))
{
explorer?.WaitForInputIdle(500);
}
}
} catch (Exception ex) {
// Make sure we show what we tried to open in the exception
ex.Data.Add("path", path);
throw;
}
}
break; break;
case ClickActions.OPEN_LAST_IN_EDITOR: case ClickActions.OPEN_LAST_IN_EDITOR:
_conf.ValidateAndCorrectOutputFileAsFullpath();
if (File.Exists(_conf.OutputFileAsFullpath)) { if (File.Exists(_conf.OutputFileAsFullpath)) {
CaptureHelper.CaptureFile(_conf.OutputFileAsFullpath, DestinationHelper.GetDestination(EditorDestination.DESIGNATION)); CaptureHelper.CaptureFile(_conf.OutputFileAsFullpath, DestinationHelper.GetDestination(EditorDestination.DESIGNATION));
} }
@ -1364,25 +1329,40 @@ namespace Greenshot {
/// <summary> /// <summary>
/// The Contextmenu_OpenRecent currently opens the last know save location /// The Contextmenu_OpenRecent currently opens the last know save location
/// </summary> /// </summary>
private void Contextmenu_OpenRecent(object sender, EventArgs eventArgs) { private void Contextmenu_OpenRecent(object sender, EventArgs eventArgs)
string path = FilenameHelper.FillVariables(_conf.OutputFilePath, false); {
_conf.ValidateAndCorrectOutputFilePath();
_conf.ValidateAndCorrectOutputFileAsFullpath();
string path = _conf.OutputFileAsFullpath;
if (!File.Exists(path))
{
path = FilenameHelper.FillVariables(_conf.OutputFilePath, false);
// Fix for #1470, problems with a drive which is no longer available // Fix for #1470, problems with a drive which is no longer available
try { try
{
string lastFilePath = Path.GetDirectoryName(_conf.OutputFileAsFullpath); string lastFilePath = Path.GetDirectoryName(_conf.OutputFileAsFullpath);
if (lastFilePath != null && Directory.Exists(lastFilePath)) { if (lastFilePath != null && Directory.Exists(lastFilePath))
{
path = lastFilePath; path = lastFilePath;
} else if (!Directory.Exists(path)) { }
else if (!Directory.Exists(path))
{
// What do I open when nothing can be found? Right, nothing... // What do I open when nothing can be found? Right, nothing...
return; return;
} }
} catch (Exception ex) { }
catch (Exception ex)
{
LOG.Warn("Couldn't open the path to the last exported file, taking default.", ex); LOG.Warn("Couldn't open the path to the last exported file, taking default.", ex);
} }
LOG.Debug("DoubleClick was called! Starting: " + path); }
try { try
Process.Start(path); {
} catch (Exception ex) { ExplorerHelper.OpenInExplorer(path);
}
catch (Exception ex)
{
// Make sure we show what we tried to open in the exception // Make sure we show what we tried to open in the exception
ex.Data.Add("path", path); ex.Data.Add("path", path);
LOG.Warn("Couldn't open the path to the last exported file", ex); LOG.Warn("Couldn't open the path to the last exported file", ex);

View file

@ -275,7 +275,9 @@
<None Include="Languages\help-nl-NL.html"> <None Include="Languages\help-nl-NL.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Languages\help-nn-NO.html" /> <None Include="Languages\help-nn-NO.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\help-pl-PL.html"> <None Include="Languages\help-pl-PL.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -303,9 +305,9 @@
<None Include="Languages\language-el-GR.xml"> <None Include="Languages\language-el-GR.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<EmbeddedResource Include="Languages\language-en-US.xml"> <None Include="Languages\language-en-US.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</EmbeddedResource> </None>
<None Include="Languages\language-es-ES.xml"> <None Include="Languages\language-es-ES.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -318,7 +320,9 @@
<None Include="Languages\language-fr-FR.xml"> <None Include="Languages\language-fr-FR.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Languages\language-fr-QC.xml" /> <None Include="Languages\language-fr-QC.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-he-IL.xml"> <None Include="Languages\language-he-IL.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -340,7 +344,9 @@
<None Include="Languages\language-nl-NL.xml"> <None Include="Languages\language-nl-NL.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
<None Include="Languages\language-nn-NO.xml" /> <None Include="Languages\language-nn-NO.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-pl-PL.xml"> <None Include="Languages\language-pl-PL.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None> </None>
@ -402,6 +408,40 @@
<Name>GreenshotPlugin</Name> <Name>GreenshotPlugin</Name>
</ProjectReference> </ProjectReference>
</ItemGroup> </ItemGroup>
<ItemGroup>
<None Include="Languages\language-kab-DZ.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<ItemGroup>
<None Include="Languages\help-ko-KR.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\help-pt-PT.html">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-ca-CA.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-da-DK.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-de-x-franconia.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-et-EE.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-id-ID.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-lv-LV.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
<None Include="Languages\language-sl-SI.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</None>
</ItemGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<PropertyGroup> <PropertyGroup>
<PreBuildEvent> <PreBuildEvent>

View file

@ -507,63 +507,17 @@ namespace Greenshot.Helpers {
return; return;
} }
ISurface surface = eventArgs.Surface; ISurface surface = eventArgs.Surface;
if (surface != null && eventArgs.MessageType == SurfaceMessageTyp.FileSaved) { if (surface != null)
if (!string.IsNullOrEmpty(surface.LastSaveFullPath)) {
string errorMessage = null;
var path = Path.GetDirectoryName(surface.LastSaveFullPath);
try {
if (path != null)
{ {
var processStartInfo = new ProcessStartInfo("explorer.exe") switch (eventArgs.MessageType)
{ {
Arguments = path, case SurfaceMessageTyp.FileSaved:
UseShellExecute = false ExplorerHelper.OpenInExplorer(surface.LastSaveFullPath);
}; break;
using (var process = new Process()) { case SurfaceMessageTyp.UploadedUri:
process.StartInfo = processStartInfo;
process.Start();
}
}
} catch (Exception ex) {
errorMessage = ex.Message;
}
// Added fallback for when the explorer can't be found
if (errorMessage != null) {
try {
string windowsPath = Environment.GetEnvironmentVariable("SYSTEMROOT");
if (windowsPath != null)
{
string explorerPath = Path.Combine(windowsPath, "explorer.exe");
if (File.Exists(explorerPath))
{
var lastSaveDirectory = Path.GetDirectoryName(surface.LastSaveFullPath);
if (lastSaveDirectory != null)
{
var processStartInfo = new ProcessStartInfo(explorerPath)
{
Arguments = lastSaveDirectory,
UseShellExecute = false
};
using (var process = new Process()) {
process.StartInfo = processStartInfo;
process.Start();
}
}
errorMessage = null;
}
}
}
catch
{
// ignored
}
}
if (errorMessage != null) {
MessageBox.Show($"{errorMessage}\r\nexplorer.exe {surface.LastSaveFullPath}", "explorer.exe", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
} else if (!string.IsNullOrEmpty(surface?.UploadUrl)) {
Process.Start(surface.UploadUrl); Process.Start(surface.UploadUrl);
break;
}
} }
Log.DebugFormat("Deregistering the BalloonTipClicked"); Log.DebugFormat("Deregistering the BalloonTipClicked");
RemoveEventHandler(sender, e); RemoveEventHandler(sender, e);
@ -852,7 +806,7 @@ namespace Greenshot.Helpers {
// Restore the window making sure it's visible! // Restore the window making sure it's visible!
windowToCapture.Restore(); windowToCapture.Restore();
} else { } else {
windowToCapture.ToForeground(); windowToCapture.ToForeground(false);
} }
tmpCapture = windowToCapture.CaptureGdiWindow(captureForWindow); tmpCapture = windowToCapture.CaptureGdiWindow(captureForWindow);
if (tmpCapture != null) { if (tmpCapture != null) {
@ -954,7 +908,7 @@ namespace Greenshot.Helpers {
_capture.CaptureDetails.DpiY = graphics.DpiY; _capture.CaptureDetails.DpiY = graphics.DpiY;
} }
// Set previouslyActiveWindow as foreground window // Set previouslyActiveWindow as foreground window
previouslyActiveWindow?.ToForeground(); previouslyActiveWindow?.ToForeground(false);
if (_capture.CaptureDetails != null) { if (_capture.CaptureDetails != null) {
((Bitmap) _capture.Image)?.SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY); ((Bitmap) _capture.Image)?.SetResolution(_capture.CaptureDetails.DpiX, _capture.CaptureDetails.DpiY);
} }

View file

@ -36,8 +36,8 @@ namespace Greenshot.Experimental {
public static class UpdateHelper { public static class UpdateHelper {
private static readonly ILog Log = LogManager.GetLogger(typeof(UpdateHelper)); private static readonly ILog Log = LogManager.GetLogger(typeof(UpdateHelper));
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
private const string StableDownloadLink = "http://getgreenshot.org/downloads/"; private const string StableDownloadLink = "https://getgreenshot.org/downloads/";
private const string VersionHistoryLink = "http://getgreenshot.org/version-history/"; private const string VersionHistoryLink = "https://getgreenshot.org/version-history/";
private static readonly object LockObject = new object(); private static readonly object LockObject = new object();
private static RssFile _latestGreenshot; private static RssFile _latestGreenshot;
private static string _downloadLink = StableDownloadLink; private static string _downloadLink = StableDownloadLink;

View file

@ -0,0 +1,309 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.2.0.58" languagegroup="1">
<resources>
<resource name="about_bugs">Azen ibugen ar</resource>
<resource name="about_donations">Ma tḥemled Greenshot, Mudd-aɣ-d afus :</resource>
<resource name="about_host">Greenshot yezdeɣ di sourceforge.net di</resource>
<resource name="about_icons">Tignitin i d-yekkan seg uqettun n tignitin Fugue n Kamiyamane Yuusuke (Creative Commons Attribution 3.0 license)</resource>
<resource name="about_license">Copyright © 2007-2015 Thomas Braun, Jens Klingen, Robin Krom
Greenshot yettunefk-d S WAR ṬMANA. d aseɣẓan ilelli i tzemreḍ ad tezuzreḍ s kra n tewtilin.
Talqayt ɣef GNU General Public License :</resource>
<resource name="about_title">Ɣef Greenshot</resource>
<resource name="application_title">Greenshot - afecku ifazen n tuṭṭfa n ugdil</resource>
<resource name="bugreport_cancel">Mdel</resource>
<resource name="bugreport_info">Suref-aɣ, teḍra-d tuccḍa.
Isali yelhan, tzemreḍ ad tmuddeḍ afus akken ad nefru uguren ma yella tuzned-d aneqqis n ibugen.
Rzu ma ulac aɣilif ar tensa URL daw-a, rnu aneqqis amaynur sakin senteḍ agbur-agi di temnaṭ-agi n uḍris.
Rnu agzul yettwagzan akked telɣut i twalad tlaq akken ad nwali ugur.
Rnu ɣur-s, nḥemmel aṭas ma yella tesneqdeḍ aneqqis igebren ugur-agi. (Tzemreḍ ad tesqedceḍ afecku n unadi akken ad id-tafeḍ s zreb.) Tanemmirt :)</resource>
<resource name="bugreport_title">Tuccḍa</resource>
<resource name="CANCEL">Sefsex</resource>
<resource name="clipboard_error">Teḍra-d tuccḍa di tira n ɣef afus.</resource>
<resource name="clipboard_inuse">Greenshot ur izmir ara ad yeru ɣef afus acku akala {0} isewḥel anekcum.</resource>
<resource name="clipboard_noimage">Ur izmir ara ad d-yaf tugna ɣef afus.</resource>
<resource name="ClipboardFormat.BITMAP">Windows Bitmap</resource>
<resource name="ClipboardFormat.DIB">Amasal n tugna amunan ɣef yibenk (DIB)</resource>
<resource name="ClipboardFormat.HTML">HTML</resource>
<resource name="ClipboardFormat.HTMLDATAURL">HTML s tugniwin s srid</resource>
<resource name="ClipboardFormat.PNG">PNG</resource>
<resource name="colorpicker_alpha">Alpha</resource>
<resource name="colorpicker_apply">Snes</resource>
<resource name="colorpicker_blue">Amidadi</resource>
<resource name="colorpicker_green">Azegzaw</resource>
<resource name="colorpicker_htmlcolor">Ini HTML</resource>
<resource name="colorpicker_recentcolors">Initen ineggura</resource>
<resource name="colorpicker_red">Azeggaɣ</resource>
<resource name="colorpicker_title">Fren ini</resource>
<resource name="colorpicker_transparent">Afrawan</resource>
<resource name="com_rejected">Taniɣert {0} tugi anekcum n Greenshot, tasfaylu n udiwenni ahat yeldi. Mdel asfaylu n udewenni sakin ɛreḍ tikelt-nniḍen.</resource>
<resource name="com_rejected_title">Anekcum n Greenshot yettwagdel</resource>
<resource name="config_unauthorizedaccess_write">Ur izmir ara ad isekles afaylu n twila n Greenshot. Ma ulac aɣilif senqed izerfan n '{0}'.</resource>
<resource name="contextmenu_about">Ɣef Greenshot</resource>
<resource name="contextmenu_capturearea">Ṭṭef tamnaṭ</resource>
<resource name="contextmenu_captureclipboard">Ldi Tugna yellan Ɣef afus</resource>
<resource name="contextmenu_capturefullscreen">Ṭṭef akk agdil</resource>
<resource name="contextmenu_capturefullscreen_all">Akk</resource>
<resource name="contextmenu_capturefullscreen_bottom">akesser</resource>
<resource name="contextmenu_capturefullscreen_left">azelmaḍ</resource>
<resource name="contextmenu_capturefullscreen_right">ayeffus</resource>
<resource name="contextmenu_capturefullscreen_top">awriran</resource>
<resource name="contextmenu_captureie">Ṭṭef Internet Explorer</resource>
<resource name="contextmenu_captureiefromlist">Ṭṭef Internet Explorer si tebdart agi</resource>
<resource name="contextmenu_capturelastregion">Ṭṭef tamnaṭ taneggarut</resource>
<resource name="contextmenu_capturewindow">Ṭṭef asfaylu urmid</resource>
<resource name="contextmenu_capturewindowfromlist">Ṭṭef asfaylu urmid si tebdart agi</resource>
<resource name="contextmenu_donate">Mudd afus i Greenshot</resource>
<resource name="contextmenu_exit">Ffeɣ</resource>
<resource name="contextmenu_help">Tallelt</resource>
<resource name="contextmenu_openfile">Ldi tugna seg ufaylu</resource>
<resource name="contextmenu_openrecentcapture">Ldi adig n usekles aneggaru</resource>
<resource name="contextmenu_quicksettings">Ismenyifen iruraden</resource>
<resource name="contextmenu_settings">Ismenyifen...</resource>
<resource name="destination_exportfailed">Tuccḍa deg usnirem ɣer {0}.Ma ulac aɣilif ɛreḍ tikelt nniḍen.</resource>
<resource name="editor_align_bottom">D akesser</resource>
<resource name="editor_align_center">Di tlemmast</resource>
<resource name="editor_align_horizontal">Areyyec aglawan</resource>
<resource name="editor_align_left">Reyyec s azelmaḍ</resource>
<resource name="editor_align_middle">Di tlemmast</resource>
<resource name="editor_align_right">Reyyec s ayeffus</resource>
<resource name="editor_align_top">D asawen</resource>
<resource name="editor_align_vertical">Areyyec ubdid</resource>
<resource name="editor_arrange">Suddes</resource>
<resource name="editor_arrowheads">Iqeṛṛa n ineccaben</resource>
<resource name="editor_arrowheads_both">I sin</resource>
<resource name="editor_arrowheads_end">Taneqqiṭ n tagara</resource>
<resource name="editor_arrowheads_none">Ula yiwen</resource>
<resource name="editor_arrowheads_start">Taneqqiṭ n tazwara</resource>
<resource name="editor_autocrop">Aseggem awurman</resource>
<resource name="editor_backcolor">Ini n taččart</resource>
<resource name="editor_blur_radius">Aqqaṛ n udaɛmec</resource>
<resource name="editor_bold">Zur</resource>
<resource name="editor_border">Rnu leryuf</resource>
<resource name="editor_brightness">Tafat</resource>
<resource name="editor_cancel">Sefsex</resource>
<resource name="editor_clipboardfailed">Teḍra-d tuccḍa deg unekcum ɣef afus. Ɛreḍ tikelt -nniḍen.</resource>
<resource name="editor_close">Mdel</resource>
<resource name="editor_close_on_save">Tebɣiḍ ad teselkseḍ tuṭṭfa n ugdil?</resource>
<resource name="editor_close_on_save_title">Sekles tugna?</resource>
<resource name="editor_confirm">Sentem</resource>
<resource name="editor_copyimagetoclipboard">Nɣel tugna ɣef afus</resource>
<resource name="editor_copypathtoclipboard">Nɣel abrid ɣef afus</resource>
<resource name="editor_copytoclipboard">Nɣel</resource>
<resource name="editor_counter">Rnu Amesmiḍan</resource>
<resource name="editor_crop">Seggem (C)</resource>
<resource name="editor_cursortool">Afecku n ufran (ESC)</resource>
<resource name="editor_cuttoclipboard">Gzem</resource>
<resource name="editor_deleteelement">Kkes</resource>
<resource name="editor_downonelevel">Ṣub</resource>
<resource name="editor_downtobottom">Deg ugilal</resource>
<resource name="editor_drawarrow">Suneɣ aneccab (A)</resource>
<resource name="editor_drawellipse">Suneɣ taglayt (E)</resource>
<resource name="editor_drawfreehand">Suneɣ s ufus (F)</resource>
<resource name="editor_drawhighlighter">Derrer (H)</resource>
<resource name="editor_drawline">Suneɣ izirig (L)</resource>
<resource name="editor_drawrectangle">Suneɣ asrem(R)</resource>
<resource name="editor_drawtextbox">Rnu asfaylu n uḍris (T)</resource>
<resource name="editor_dropshadow_darkness">Tebrek n tili</resource>
<resource name="editor_dropshadow_offset">Asiẓi</resource>
<resource name="editor_dropshadow_settings">Iɣewwaṛen n tili</resource>
<resource name="editor_dropshadow_thickness">Tuzert n tili</resource>
<resource name="editor_duplicate">Sleg aferdis yettwafernen</resource>
<resource name="editor_edit">Taẓrigt</resource>
<resource name="editor_effects">Isemda</resource>
<resource name="editor_email">Imayl</resource>
<resource name="editor_file">Afaylu</resource>
<resource name="editor_fontsize">Teɣzi</resource>
<resource name="editor_forecolor">Ini n izirig</resource>
<resource name="editor_grayscale">Tifesniwin n umumed</resource>
<resource name="editor_highlight_area">Jerreḍ tamnaṭ</resource>
<resource name="editor_highlight_grayscale">Tifesniwin n umumed</resource>
<resource name="editor_highlight_magnify">Semɣeṛ</resource>
<resource name="editor_highlight_mode">Askar n ujerreḍ</resource>
<resource name="editor_highlight_text">Sebrureq aḍris</resource>
<resource name="editor_image_shadow">Tili yettwarfden</resource>
<resource name="editor_imagesaved">Tugna tettwasekles ara {0}.</resource>
<resource name="editor_insertwindow">Ger asfaylu</resource>
<resource name="editor_invert">Tti initen</resource>
<resource name="editor_italic">Uknan</resource>
<resource name="editor_load_objects">Sali-d tiɣawsiwin seg ufaylu</resource>
<resource name="editor_magnification_factor">Amesker n usuzer</resource>
<resource name="editor_match_capture_size">Seggem amasal n tuṭṭfa n ugdil</resource>
<resource name="editor_obfuscate">Sdaɛmumec (O)</resource>
<resource name="editor_obfuscate_blur">Sdeɛmumec</resource>
<resource name="editor_obfuscate_mode">Askar n usdaɛmumec</resource>
<resource name="editor_obfuscate_pixelize">Piksilizi</resource>
<resource name="editor_object">Taɣawsa</resource>
<resource name="editor_opendirinexplorer">Ldi akaram n unaram Windows</resource>
<resource name="editor_pastefromclipboard">Sented</resource>
<resource name="editor_pixel_size">Teɣzu n upiksil</resource>
<resource name="editor_preview_quality">Taɣara n teskant</resource>
<resource name="editor_print">Siggez</resource>
<resource name="editor_redo">Err-d {0}</resource>
<resource name="editor_resetsize">Wennez teɣzi</resource>
<resource name="editor_resize">Snifel tahri/teɣzi</resource>
<resource name="editor_resize_aspectratio">Eǧǧ afmiḍi Teɣ / Teh</resource>
<resource name="editor_resize_height">Awrir</resource>
<resource name="editor_resize_percent">Afmiḍi</resource>
<resource name="editor_resize_pixel">Ipiksilen</resource>
<resource name="editor_resize_settings">Iqewwaṛen n usnufel n Tehri/Teɣzi</resource>
<resource name="editor_resize_width">Tehri</resource>
<resource name="editor_rotateccw">Zzi s azelmaḍ</resource>
<resource name="editor_rotatecw">Zzi s ayeffus</resource>
<resource name="editor_save">Sekles</resource>
<resource name="editor_save_objects">Sekles tiɣawsiwin deg ufaylu</resource>
<resource name="editor_saveas">Sekles s yisem...</resource>
<resource name="editor_selectall">Fren akk</resource>
<resource name="editor_senttoprinter">Tamhelt n usiggez tettwazen ɣer '{0}'.</resource>
<resource name="editor_shadow">Tili tettwarfed</resource>
<resource name="editor_speechbubble">tačuffiṭ n uḍris</resource>
<resource name="editor_storedtoclipboard">Tugna tetwasers ɣef afus.</resource>
<resource name="editor_thickness">Tuzert n izirig</resource>
<resource name="editor_title">Greenshot Amaẓrag n tugniwin</resource>
<resource name="editor_torn_edge">Leryuf qqeṛsen</resource>
<resource name="editor_tornedge_all">Seɣres akk idisan</resource>
<resource name="editor_tornedge_bottom">Snes aseɣres ukesser</resource>
<resource name="editor_tornedge_horizontaltoothrange">Aglawan : azilal n tuɣmas</resource>
<resource name="editor_tornedge_left">Snes aseɣres deg uzelmaḍ</resource>
<resource name="editor_tornedge_right">Snes aseɣres deg uyeffus</resource>
<resource name="editor_tornedge_settings">Aswel n leryuf</resource>
<resource name="editor_tornedge_shadow">Sefek tili</resource>
<resource name="editor_tornedge_toothsize">Teɣzi n tuɣmas</resource>
<resource name="editor_tornedge_top">Snes acerrig d asawen</resource>
<resource name="editor_tornedge_verticaltoothrange">Ubdid : Azilal n tuɣmas</resource>
<resource name="editor_undo">Sefsex {0}</resource>
<resource name="editor_uponelevel">Rfed</resource>
<resource name="editor_uptotop">Deg uɣawas amenzu</resource>
<resource name="EmailFormat.MAPI">Amsaɣ MAPI</resource>
<resource name="EmailFormat.OUTLOOK_HTML">Outlook s HTML</resource>
<resource name="EmailFormat.OUTLOOK_TXT">Outlook s uḍris</resource>
<resource name="error">Tuccḍa</resource>
<resource name="error_multipleinstances">Tummant n Greenshot tettuselkam yakan.</resource>
<resource name="error_nowriteaccess">Ur izmir ara ad isekles afaylu ara {0}.
Ma ulac aɣilif senqed tuffart n ukaram n usekles.</resource>
<resource name="error_openfile">afaylu "{0}" ur izmir ara ad yettwaldi.</resource>
<resource name="error_openlink">Ur izmir ara ad d-yelid aseɣwen '{0}'.</resource>
<resource name="error_save">Ur izmir ara ad isekles tuṭṭfa n ugdil. Ma ulac aɣilif, aff-d akaram ilaqen !</resource>
<resource name="error_save_invalid_chars">Isem n ukaram neɣ isem n ufaylu yettusirwen mačči d ameɣtu. Seɣti taneɣruft n yisem n ufaylu, sakin ɛreḍ tikelt-nniḍen.</resource>
<resource name="expertsettings">Amazzag</resource>
<resource name="expertsettings_autoreducecolors">Tugna s 8 s ibiten ma yella amḍan n initen &lt; 256 i tugna n &gt; 8 n ibiten</resource>
<resource name="expertsettings_checkunstableupdates">Senqed ileqman urkiden</resource>
<resource name="expertsettings_clipboardformats">Imasalen n ɣef afus</resource>
<resource name="expertsettings_counter">Amḍan i $(NUM) di tneɣruft n ufaylu</resource>
<resource name="expertsettings_enableexpert">Ẓriɣ d acu xeddmeɣ!</resource>
<resource name="expertsettings_footerpattern">Taneɣruft n uḍar n usebter</resource>
<resource name="expertsettings_minimizememoryfootprint">Adsil n tkatut yettusemẓi, acukan timellit tuder (ur lhi ara).</resource>
<resource name="expertsettings_optimizeforrdp">Asesfer i useqdec s tnarit tanmeggagt</resource>
<resource name="expertsettings_reuseeditorifpossible">Seqdec amaẓrag ma tzemreḍ</resource>
<resource name="expertsettings_suppresssavedialogatclose">Kkes asfaylu n udiwenni n usekles deg umdal n umazrag</resource>
<resource name="expertsettings_thumbnailpreview">Asfaylu aqmamaḍ deg umuɣ asatal (i Windows Vista akked Windows 7)</resource>
<resource name="exported_to">Yettusifeḍ ar : {0}</resource>
<resource name="exported_to_error">Teḍra-d tuccḍa deg usifeḍ n {0} :</resource>
<resource name="help_title">Tallalt n Greenshot</resource>
<resource name="hotkeys">Inegzumen n unasiw</resource>
<resource name="jpegqualitydialog_choosejpegquality">Ma ulac aɣilif, fren taɣara n tugna JPEG.</resource>
<resource name="OK">Ih</resource>
<resource name="print_error">Teḍra-d tuccḍa deeg usiggez.</resource>
<resource name="printoptions_allowcenter">Slemmes ɣef usebter</resource>
<resource name="printoptions_allowenlarge">Sehrew ar tisektiwin n usebter</resource>
<resource name="printoptions_allowrotate">Zzi tasaggazt akken tella tnila n usebter</resource>
<resource name="printoptions_allowshrink">Senɣes ar tsektiwin n usebter</resource>
<resource name="printoptions_colors">Iɣewwaṛen n usiggez s yiniten</resource>
<resource name="printoptions_dontaskagain">Sekles iɣewwaṛen amzun d azalen imezwar, ur d-sutur ara tikelt nniḍen.</resource>
<resource name="printoptions_inverted">Siggez s tuttya n yiniten</resource>
<resource name="printoptions_layout">Iɣewwaṛen n trusi n usebter</resource>
<resource name="printoptions_printcolor">Asiggez s initen</resource>
<resource name="printoptions_printgrayscale">Sekmer asiggez s uswir n tfesniwin n umumad</resource>
<resource name="printoptions_printmonochrome">Sekmer asiggez s aberkan/amellal</resource>
<resource name="printoptions_timestamp">Siggez azemz d wakud deg uḍaṛ n usebter</resource>
<resource name="printoptions_title">Greenshot - Iɣewwaṛen n tsaggazt</resource>
<resource name="qualitydialog_dontaskagain">Sekles am tɣara tamezwert udiɣ ur d(sutur ara tikelt-nniḍen</resource>
<resource name="qualitydialog_title">Greenshot - Taɣara</resource>
<resource name="quicksettings_destination_file">Sekles srid (seqdec iɣewwaṛen n tuffɣa)</resource>
<resource name="settings_alwaysshowprintoptionsdialog">Sken srid asfaylu n udiwenni n usiggez.</resource>
<resource name="settings_alwaysshowqualitydialog">Sken asfaylu n udiwenni n tɣaṛa n yal asekles</resource>
<resource name="settings_applicationsettings">Iɣewwaṛen n usnas</resource>
<resource name="settings_autostartshortcut">Senker Greenshot di tnekra n Windows</resource>
<resource name="settings_capture">Tuṭṭfa</resource>
<resource name="settings_capture_mousepointer">Ṭṭef taḥnaccaṭ n tɣerdayt</resource>
<resource name="settings_capture_windows_interactive">Seqdec askar amyigawan n tuṭṭfa n usfaylu</resource>
<resource name="settings_checkperiod">Azilal n usenqed n ileqman s wussan (0=ulac usenqed)</resource>
<resource name="settings_configureplugin">Swel</resource>
<resource name="settings_copypathtoclipboard">Nɣel abrid ar ufaylu ɣef afus di yal asekles</resource>
<resource name="settings_destination">Taniɣert n tuṭṭfa n ugdil</resource>
<resource name="settings_destination_clipboard">Ɣef afus</resource>
<resource name="settings_destination_editor">Ldi deg umaẓrag n tugniwin</resource>
<resource name="settings_destination_email">Imayl</resource>
<resource name="settings_destination_file">Sekles s srid (s useqdec n iɣewwaṛen daw-a)</resource>
<resource name="settings_destination_fileas">Sekles s yisem (sken asfaylu n udiwenni)</resource>
<resource name="settings_destination_picker">Fren taniɣert tamussant</resource>
<resource name="settings_destination_printer">Ar tsaggazt</resource>
<resource name="settings_editor">Amaẓrag</resource>
<resource name="settings_filenamepattern">Taneɣruft n ufaylu</resource>
<resource name="settings_general">Amatu</resource>
<resource name="settings_iconsize">Teɣzi n tignitin</resource>
<resource name="settings_iecapture">Tuṭṭfa n Internet Explorer</resource>
<resource name="settings_jpegquality">Taɣara JPEG</resource>
<resource name="settings_language">Tutlayt</resource>
<resource name="settings_message_filenamepattern">Imuttiyen-agi ad ttwasemselsin s wudem awurman di tneqruft inek:
${YYYY} aseggass s 4
${MM} aggur s 2 n izwilen
${DD} jass s 2 n izwilen
${hh} asrag s n 2 izwilen
${mm} tisdatin s 2 n izwilen
${ss} tasinin s 2 n izwilen
${NUM} Incrément sur 6 n izwilen
${title} Azwel n usfaylu
${user} isem n useqdac Windows
${domain} Taɣult Windows
${hostname} Isem n usenneftaɣ n uselkim
Tzemreḍ daɣen ad teǧǧeḍ Greenshot ad yernu ikaramen s wudem amussan, s useqdec n uslac(\) akken ad tfeṛqeḍ gar ikaramen aekked ifuyla.
Amedya: taneqruft ${YYYY}-${MM}-${DD}\${hh}-${mm}-${ss}
ad yernu akaram i wass amiran deg adig n usekles amezwer, amedya 2008-06-29, isem n ufaylu igebren tuṭṭfa n ugdil ad tettwabnu qef usrag
amiran, amedya 11_58_32 (akked usiɣzef yettwamlen deg iɣewwaṛen)</resource>
<resource name="settings_network">Aẓeṭṭa akked ileqman</resource>
<resource name="settings_output">Tuffɣa</resource>
<resource name="settings_playsound">Urar imesli n usagu n tewlafin</resource>
<resource name="settings_plugins">Isiɣzaf</resource>
<resource name="settings_plugins_createdby">Yerna-t</resource>
<resource name="settings_plugins_dllpath">Abrid DLL</resource>
<resource name="settings_plugins_name">Isem</resource>
<resource name="settings_plugins_version">Lqem</resource>
<resource name="settings_preferredfilesettings">Ismenyifen n usekles</resource>
<resource name="settings_primaryimageformat">Amasal n tugna</resource>
<resource name="settings_printer">Tasaggazt</resource>
<resource name="settings_printoptions">Iɣewwaṛen n usiggez</resource>
<resource name="settings_qualitysettings">Iɣewwaṛen n tɣara</resource>
<resource name="settings_reducecolors">Senɣes amḍan n yiniten ar 256 ma yela aṭas</resource>
<resource name="settings_registerhotkeys">Sekles inegzumen n unasiw</resource>
<resource name="settings_showflashlight">Zlem agdil</resource>
<resource name="settings_shownotify">Sken alɣu</resource>
<resource name="settings_storagelocation">Sniles asekles</resource>
<resource name="settings_title">Iɣewwaṛen</resource>
<resource name="settings_tooltip_filenamepattern">Taneɣruft yettwasqedcen i usirew n yesmawen n ifuyla deg usekles n tuṭṭfiwin n ugdil</resource>
<resource name="settings_tooltip_language">Tutlayt tamezwert n ugrudem n useqdac n Greenshot</resource>
<resource name="settings_tooltip_primaryimageformat">Amasal n tugna tamezwert</resource>
<resource name="settings_tooltip_registerhotkeys">Ad d-yemmel ma yellai negzumen n unasiw Sigg. agd, Ctrl+Sigg. agdil, Alt+Sigg. agdil ttwaḥerren i Greenshot ticki yettuselkam.</resource>
<resource name="settings_tooltip_storagelocation">Akaram anida ttwakelsent tuṭṭfiwin inek n ugdil. (Eǧǧ-it d ilem akken ad tseklseḍ ɣef tnarit)</resource>
<resource name="settings_usedefaultproxy">Seqdec apṛuksi n unagraw amezwer</resource>
<resource name="settings_visualization">Isemda</resource>
<resource name="settings_waittime">Millitasinin n uraǧu send tuṭṭfa</resource>
<resource name="settings_window_capture_mode">Aska n tuṭṭfa n usfaylu (aɣanib Aero)</resource>
<resource name="settings_windowscapture">Ṭṭef asfaylu urmid</resource>
<resource name="settings_zoom">Sken tasemɣart</resource>
<resource name="tooltip_firststart">Sit s tqeffalt n uyeffus dagi sakin senned ɣef tqeffalt {0}.</resource>
<resource name="update_found">Yella lqem-nniḍen n Greenshot! Tebɣid ad tsidreḍ Greenshot {0} ?</resource>
<resource name="wait_ie_capture">Ma ulac aɣilif, rǧu arama tfuk tuṭṭfa n ugdil n usebter Internet Explorer...</resource>
<resource name="warning">Ɣur-k</resource>
<resource name="warning_hotkeys">Anegzum n unasiw "{0}" ur yettwakles ara. Ugur-agi ahat yekka-d seg ufecku-nniḍen iseqdacen yiwen n unegzum n unasiw. Tzemreḍ ahat ad tesnifleḍ inegzumen inek n unasiw neɣ ad tsenseḍ/ad tesnifleḍ aseɣẓan iseqdacen anegzum.
Akk timahilin n Greenshot sttenkarent daɣen s srid seg umuɣ umniḍ n tignit n temnaṭ n ulɣu n unagraw.</resource>
<resource name="WindowCaptureMode.Aero">Seqdec ini udmawan</resource>
<resource name="WindowCaptureMode.AeroTransparent">Ḥrez tafrawant</resource>
<resource name="WindowCaptureMode.Auto">Awurman</resource>
<resource name="WindowCaptureMode.GDI">Seqdec ini amezwer</resource>
<resource name="WindowCaptureMode.Screen">Akken i d-yettban</resource>
</resources>
</language>

View file

@ -9,6 +9,38 @@ All details to our tickets can be found here: https://greenshot.atlassian.net
@DETAILVERSION@ @DETAILVERSION@
Bugs fixed:
* [BUG-2051] - Scroll-lock button not usable as hotkey
* [BUG-2056] - Cannot export to external command Paint.NET if .greenshot format is used
* [BUG-2081] - Canvas resize (Ctrl + / Ctrl -) only works via numpad keys
* [BUG-2093] - Shadow effects not rendering correctly on Windows 10
* [BUG-2095] - 'Save as' doesn't remember last saved directory (after restart)
* [BUG-2097] - Window border is not captured on Windows 10
* [BUG-2102] - InvalidOperationException when selecting a color
* [BUG-2104] - Speechbubble can't be used after copy/paste
* [BUG-2105] - Window border is not captured on Windows 10
* [BUG-2108] - Capture last region doesn't work
* [BUG-2109] - Double-click on textbox causes NullReferenceException
* [BUG-2111] - Drag and Drop image file on editor doesn't work
* [BUG-2114] - Storage location reset to default if not available during start
* [BUG-2115] - Error while trying to upload screen shot to Jira
* [BUG-2116] - MemberAccessException when opening the color dialog
* [BUG-2119] - crash on editing (dragged line)
* [BUG-2120] - Greenshot Editor Canvas Changed to White Screen
* [BUG-2121] - NullReferenceException when moving text
* [BUG-2122] - Jira Plugin: Crash when uploading to Jira
* [BUG-2124] - Flickr plugin generates wrong image link
* [BUG-2125] - Send to OneNote does not work
* [BUG-2126] - MemberAccessException during un-DropShadow of Ellipse
* [FEATURE-998] - Opening last capture in explorer should select/jump to the file
* [FEATURE-992] - When reusing the editor, it is not brought to the front (second try)
Added Taqbaylit as a new language.
1.2.9.112-9bc62ac RELEASE
This is a bugfix release for the Greenshot 1.2.9.104-3721c10 RELEASE This is a bugfix release for the Greenshot 1.2.9.104-3721c10 RELEASE
Bugs fixed: Bugs fixed:

View file

@ -50,6 +50,7 @@ Source: ..\..\Languages\*id-ID*; Excludes: "*installer*,*website*"; DestDir: {ap
Source: ..\..\Languages\*it-IT*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\itIT; Flags: overwritereadonly ignoreversion replacesameversion; Source: ..\..\Languages\*it-IT*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\itIT; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*ja-JP*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\jaJP; Flags: overwritereadonly ignoreversion replacesameversion; Source: ..\..\Languages\*ja-JP*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\jaJP; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*ko-KR*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\koKR; Flags: overwritereadonly ignoreversion replacesameversion; Source: ..\..\Languages\*ko-KR*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\koKR; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*kab-DZ*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\kabDZ; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*lt-LT*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\ltLT; Flags: overwritereadonly ignoreversion replacesameversion; Source: ..\..\Languages\*lt-LT*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\ltLT; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*lv-LV*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\lvLV; Flags: overwritereadonly ignoreversion replacesameversion; Source: ..\..\Languages\*lv-LV*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\lvLV; Flags: overwritereadonly ignoreversion replacesameversion;
Source: ..\..\Languages\*nn-NO*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\nnNO; Flags: overwritereadonly ignoreversion replacesameversion; Source: ..\..\Languages\*nn-NO*; Excludes: "*installer*,*website*"; DestDir: {app}\Languages; Components: languages\nnNO; Flags: overwritereadonly ignoreversion replacesameversion;
@ -391,6 +392,7 @@ Name: "languages\idID"; Description: "Bahasa Indonesia"; Types: full custom; Fla
Name: "languages\itIT"; Description: "Italiano"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('1') Name: "languages\itIT"; Description: "Italiano"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('1')
Name: "languages\jaJP"; Description: "日本語"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('7') Name: "languages\jaJP"; Description: "日本語"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('7')
Name: "languages\koKR"; Description: "한국의"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('8') Name: "languages\koKR"; Description: "한국의"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('8')
Name: "languages\kabDZ"; Description: "Taqbaylit"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('8')
Name: "languages\ltLT"; Description: "Lietuvių"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('3') Name: "languages\ltLT"; Description: "Lietuvių"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('3')
Name: "languages\lvLV"; Description: "Latviski"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('3') Name: "languages\lvLV"; Description: "Latviski"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('3')
Name: "languages\nnNO"; Description: "Nynorsk"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('1') Name: "languages\nnNO"; Description: "Nynorsk"; Types: full custom; Flags: disablenouninstallwarning; Check: hasLanguageGroup('1')

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="communication_wait">Taɣwaylt tetteddu akked umeẓlu n usekles s srid. Ṛǧu ma ulac aɣilif...</resource>
<resource name="Configure">Swel Box</resource>
<resource name="label_AfterUpload">Deffir n usider/asali</resource>
<resource name="label_AfterUploadLinkToClipBoard">Nɣel aseɣwen ɣef afus</resource>
<resource name="label_upload_format">Amasal tugna</resource>
<resource name="settings_title">Iɣewwaṛen n usekles s srid</resource>
<resource name="upload_failure">Teḍra-d tuccḍa deg usali ɣer usekles s srid :</resource>
<resource name="upload_menu_item">Sali ɣer usekles s srid</resource>
<resource name="upload_success">Tugna tuli ɣer usekles srid !</resource>
</resources>
</language>

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="browse_pages">Inig</resource>
<resource name="CANCEL">Sefsex</resource>
<resource name="copy_wikimarkup">Nɣel Wikimarkup ɣef afus</resource>
<resource name="filename">Afaylu</resource>
<resource name="include_person_spaces">Seddu imeḍqan idiganen deg unagi akked tunigin</resource>
<resource name="label_password">Awal uffir</resource>
<resource name="label_timeout">Akud n uṛaǧu</resource>
<resource name="label_url">Tansa Url</resource>
<resource name="label_user">Aseqdac</resource>
<resource name="loading">Aggway n isefka n Confluence, Rǧu ma ulac aɣilif...</resource>
<resource name="login_error">Teḍra-d tuccḍa deg usesteb : {0}</resource>
<resource name="login_title">Sekcem ma ulac aɣilif, isefka yinek n usesteb confluence</resource>
<resource name="OK">Ih</resource>
<resource name="open_page_after_upload">Ldi asebter ticki yemmed usali</resource>
<resource name="open_pages">Ldi isebtar</resource>
<resource name="plugin_settings">Iɣewwaṛen n Confluence</resource>
<resource name="search">Nadi</resource>
<resource name="search_pages">Nadi deg isebtar</resource>
<resource name="search_text">Nadi aḍris</resource>
<resource name="upload">Sali</resource>
<resource name="upload_failure">Teḍra-d tuccḍa deg usali ɣer Confluence :</resource>
<resource name="upload_format">Sali amasal</resource>
<resource name="upload_menu_item">Sali ɣef Confluence</resource>
<resource name="upload_success">Tugna tuli ɣer Confluence !</resource>
</resources>
</language>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="communication_wait">Taɣwalt tetteddu akked Dropbox. Ṛǧu ma ulac aɣilif...</resource>
<resource name="Configure">Swel Dropbox</resource>
<resource name="label_AfterUpload">Ticki yemmad usali</resource>
<resource name="label_AfterUploadLinkToClipBoard">Nɣel aseɣwen ɣef afus</resource>
<resource name="label_upload_format">Amasal tugna</resource>
<resource name="settings_title">Iɣewwaṛen n Dropbox</resource>
<resource name="upload_failure">Teḍra-d tuccḍa deg usali ɣer Dropbox :</resource>
<resource name="upload_menu_item">Sali ɣer Dropbox</resource>
<resource name="upload_success">Tugna tuli ɣer Dropbox !</resource>
</resources>
</language>

View file

@ -43,32 +43,20 @@ namespace ExternalCommand {
_presetCommand = commando; _presetCommand = commando;
} }
public override string Designation { public override string Designation => "External " + _presetCommand.Replace(',','_');
get {
return "External " + _presetCommand.Replace(',','_');
}
}
public override string Description { public override string Description => _presetCommand;
get {
return _presetCommand;
}
}
public override IEnumerable<IDestination> DynamicDestinations() { public override IEnumerable<IDestination> DynamicDestinations() {
yield break; yield break;
} }
public override Image DisplayIcon { public override Image DisplayIcon => IconCache.IconForCommand(_presetCommand);
get {
return IconCache.IconForCommand(_presetCommand);
}
}
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) { public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surface, ICaptureDetails captureDetails) {
ExportInformation exportInformation = new ExportInformation(Designation, Description); ExportInformation exportInformation = new ExportInformation(Designation, Description);
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(); SurfaceOutputSettings outputSettings = new SurfaceOutputSettings();
outputSettings.PreventGreenshotFormat();
if (_presetCommand != null) { if (_presetCommand != null) {
if (!config.RunInbackground.ContainsKey(_presetCommand)) { if (!config.RunInbackground.ContainsKey(_presetCommand)) {
@ -154,12 +142,12 @@ namespace ExternalCommand {
private int CallExternalCommand(string commando, string fullPath, out string output, out string error) { private int CallExternalCommand(string commando, string fullPath, out string output, out string error) {
try { try {
return CallExternalCommand(commando, fullPath, null, out output, out error); return CallExternalCommand(commando, fullPath, null, out output, out error);
} catch (Win32Exception w32ex) { } catch (Win32Exception w32Ex) {
try { try {
return CallExternalCommand(commando, fullPath, "runas", out output, out error); return CallExternalCommand(commando, fullPath, "runas", out output, out error);
} catch { } catch {
w32ex.Data.Add("commandline", config.Commandline[_presetCommand]); w32Ex.Data.Add("commandline", config.Commandline[_presetCommand]);
w32ex.Data.Add("arguments", config.Argument[_presetCommand]); w32Ex.Data.Add("arguments", config.Argument[_presetCommand]);
throw; throw;
} }
} catch (Exception ex) { } catch (Exception ex) {

View file

@ -0,0 +1,35 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0">
<resources>
<resource name="contextmenu_configure">
Tawila n tludna tizɣaṛayin
</resource>
<resource name="settings_title">
Tawila n tladna tazɣarayt
</resource>
<resource name="settings_detail_title">
Tawila n tladna
</resource>
<resource name="settings_new">
Amaynut
</resource>
<resource name="settings_delete">
Kkes
</resource>
<resource name="settings_edit">
Ẓreg
</resource>
<resource name="label_name">
Isem
</resource>
<resource name="label_command">
Taladna
</resource>
<resource name="label_argument">
Tiɣira
</resource>
<resource name="label_information">
{0} d isem n ufaylu n tuṭṭfa yinek n ugdil
</resource>
</resources>
</language>

View file

@ -42,7 +42,7 @@ namespace GreenshotFlickrPlugin {
private const string FLICKR_ACCESS_TOKEN_URL = FLICKR_OAUTH_BASE_URL + "access_token"; private const string FLICKR_ACCESS_TOKEN_URL = FLICKR_OAUTH_BASE_URL + "access_token";
private const string FLICKR_AUTHORIZE_URL = FLICKR_OAUTH_BASE_URL + "authorize"; private const string FLICKR_AUTHORIZE_URL = FLICKR_OAUTH_BASE_URL + "authorize";
private const string FLICKR_REQUEST_TOKEN_URL = FLICKR_OAUTH_BASE_URL + "request_token"; private const string FLICKR_REQUEST_TOKEN_URL = FLICKR_OAUTH_BASE_URL + "request_token";
private const string FLICKR_FARM_URL = "https://farm{0}.staticflickr.com/{1}/{2}_{3}.jpg"; private const string FLICKR_FARM_URL = "https://farm{0}.staticflickr.com/{1}/{2}_{3}_o.{4}";
// REST // REST
private const string FLICKR_REST_URL = FLICKR_API_BASE_URL + "rest/"; private const string FLICKR_REST_URL = FLICKR_API_BASE_URL + "rest/";
private const string FLICKR_GET_INFO_URL = FLICKR_REST_URL + "?method=flickr.photos.getInfo"; private const string FLICKR_GET_INFO_URL = FLICKR_REST_URL + "?method=flickr.photos.getInfo";
@ -131,8 +131,9 @@ namespace GreenshotFlickrPlugin {
string farmId = item.Attributes["farm"].Value; string farmId = item.Attributes["farm"].Value;
string serverId = item.Attributes["server"].Value; string serverId = item.Attributes["server"].Value;
string photoId = item.Attributes["id"].Value; string photoId = item.Attributes["id"].Value;
string secret = item.Attributes["secret"].Value; string originalsecret = item.Attributes["originalsecret"].Value;
return string.Format(FLICKR_FARM_URL, farmId, serverId, photoId, secret); string originalFormat = item.Attributes["originalformat"].Value;
return string.Format(FLICKR_FARM_URL, farmId, serverId, photoId, originalsecret, originalFormat);
} }
} }
} }

View file

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.2.0.58" languagegroup="1">
<resources prefix="Flickr">
<resource name="label_HiddenFromSearch">
Yettwaffer seg unadi
</resource>
<resource name="label_SafetyLevel">
Aswir aɣelsan
</resource>
<resource name="label_AfterUploadLinkToClipBoard">
Cudd ɣef afus
</resource>
<resource name="label_AfterUpload">
Seld asali
</resource>
<resource name="Configure">
Swel Flickr
</resource>
<resource name="upload_menu_item">
Sali ar Flickr
</resource>
<resource name="settings_title">
Iɣewwaṛen n Flickr
</resource>
<resource name="upload_success">
Tugna tuli akken iwata ar Flickr!
</resource>
<resource name="upload_failure">
Teḍra-d tuccḍa deg usali ar Flickr:
</resource>
<resource name="label_upload_format">
Amasal n tugna
</resource>
<resource name="communication_wait">
Taɣwalt tetteddu akked Flickr. Rǧu ma ulac aɣilif...
</resource>
<resource name="public">
Azayez
</resource>
<resource name="family">
Tawacult
</resource>
<resource name="friend">
Amdakkel
</resource>
</resources>
</language>

View file

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.2.0.58" languagegroup="1">
<resources prefix="Imgur">
<resource name="upload_menu_item">
Sali ar Imgur
</resource>
<resource name="settings_title">
Iɣewwaṛen n Imgur
</resource>
<resource name="label_url">
Tansa Url
</resource>
<resource name="OK">
IH
</resource>
<resource name="CANCEL">
Sefsex
</resource>
<resource name="upload_success">
Tugna tuli akken i wata ar Imgur!
</resource>
<resource name="upload_failure">
Teḍra-d tuccḍa deg usali ar Imgur:
</resource>
<resource name="label_upload_format">
Amasal n tugna
</resource>
<resource name="communication_wait">
Taɣwalt tetteddu akked Imgur. Ma ulac aɣilif, ṛǧu...
</resource>
<resource name="delete_question">
Tebɣiḍ ad tekksed tugna {0} si Imgur?
</resource>
<resource name="clear_question">
Tebɣiḍ ad tekkseḍ Are you sure you want to delete the local Imgur history?
</resource>
<resource name="delete_title">
Kkes Imgur {0}
</resource>
<resource name="anonymous_access">
Seqdec anekcum udrig
</resource>
<resource name="use_page_link">
Seqdec aseɣwen n usebter deg umḍiq n useɣwenn tuggna ɣef afus
</resource>
<resource name="history">
Amazray
</resource>
<resource name="configure">
Swel
</resource>
</resources>
</language>

View file

@ -29,7 +29,7 @@ using System;
using System.Runtime.Caching; using System.Runtime.Caching;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapplo.Log.Facade; using Dapplo.Log;
#endregion #endregion

View file

@ -36,7 +36,6 @@ namespace GreenshotJiraPlugin.Forms {
private readonly JiraConnector _jiraConnector; private readonly JiraConnector _jiraConnector;
private Issue _selectedIssue; private Issue _selectedIssue;
private readonly GreenshotColumnSorter _columnSorter; private readonly GreenshotColumnSorter _columnSorter;
private static readonly JiraConfiguration JiraConfig = IniConfig.GetIniSection<JiraConfiguration>();
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>(); private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
public JiraForm(JiraConnector jiraConnector) { public JiraForm(JiraConnector jiraConnector) {
@ -161,14 +160,21 @@ namespace GreenshotJiraPlugin.Forms {
jiraListView.LargeImageList = imageList; jiraListView.LargeImageList = imageList;
foreach (var issue in issues) { foreach (var issue in issues) {
var issueIcon = await _jiraConnector.GetIssueTypeBitmapAsync(issue);
imageList.Images.Add(issueIcon);
var item = new ListViewItem var item = new ListViewItem
{ {
Tag = issue, Tag = issue
ImageIndex = imageList.Images.Count - 1
}; };
try
{
var issueIcon = await _jiraConnector.GetIssueTypeBitmapAsync(issue);
imageList.Images.Add(issueIcon);
item.ImageIndex = imageList.Images.Count - 1;
}
catch (Exception ex)
{
Log.Warn("Problem loading issue type, ignoring", ex);
}
item.SubItems.Add(issue.Key); item.SubItems.Add(issue.Key);
item.SubItems.Add(issue.Fields.Created.ToString("d", DateTimeFormatInfo.InvariantInfo)); item.SubItems.Add(issue.Fields.Created.ToString("d", DateTimeFormatInfo.InvariantInfo));
item.SubItems.Add(issue.Fields.Assignee?.DisplayName); item.SubItems.Add(issue.Fields.Assignee?.DisplayName);

View file

@ -34,32 +34,42 @@
</PropertyGroup> </PropertyGroup>
<Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" /> <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.Targets" />
<ItemGroup> <ItemGroup>
<Reference Include="Dapplo.HttpExtensions, Version=0.5.43.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Dapplo.HttpExtensions, Version=0.6.17.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.HttpExtensions.0.5.43\lib\net45\Dapplo.HttpExtensions.dll</HintPath> <HintPath>..\packages\Dapplo.HttpExtensions.0.6.17\lib\net45\Dapplo.HttpExtensions.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Dapplo.Jira, Version=0.1.65.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Dapplo.Jira, Version=0.5.12.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Jira.0.1.65\lib\net45\Dapplo.Jira.dll</HintPath> <HintPath>..\packages\Dapplo.Jira.0.5.12\lib\net45\Dapplo.Jira.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="Dapplo.Log.Facade, Version=0.5.4.0, Culture=neutral, processorArchitecture=MSIL"> <Reference Include="Dapplo.Log, Version=1.0.23.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\packages\Dapplo.Log.Facade.0.5.4\lib\net45\Dapplo.Log.Facade.dll</HintPath> <HintPath>..\packages\Dapplo.Log.1.0.23\lib\net45\Dapplo.Log.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="log4net"> <Reference Include="log4net">
<HintPath>..\Greenshot\Lib\log4net.dll</HintPath> <HintPath>..\Greenshot\Lib\log4net.dll</HintPath>
</Reference> </Reference>
<Reference Include="Svg, Version=2.2.1.38382, Culture=neutral, PublicKeyToken=12a0bac221edeae2, processorArchitecture=MSIL"> <Reference Include="Microsoft.VisualBasic" />
<HintPath>..\packages\Svg.2.2.2\lib\net35\Svg.dll</HintPath> <Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="Svg, Version=2.2.1.39233, Culture=neutral, PublicKeyToken=12a0bac221edeae2, processorArchitecture=MSIL">
<HintPath>..\packages\Svg.2.3.0\lib\net35\Svg.dll</HintPath>
<Private>True</Private> <Private>True</Private>
</Reference> </Reference>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Drawing" /> <Reference Include="System.Drawing" />
<Reference Include="System.Net.Http" /> <Reference Include="System.Net.Http" />
<Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Runtime.Caching" /> <Reference Include="System.Runtime.Caching" />
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.ServiceModel" />
<Reference Include="System.Web.Services" /> <Reference Include="System.Web.Services" />
<Reference Include="System.Windows.Forms" /> <Reference Include="System.Windows.Forms" />
<Reference Include="System.Xaml" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="System.Xml.Linq" />
<Reference Include="WindowsBase" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Compile Include="AsyncMemoryCache.cs" /> <Compile Include="AsyncMemoryCache.cs" />
@ -94,7 +104,6 @@
<Compile Include="LanguageKeys.cs" /> <Compile Include="LanguageKeys.cs" />
<Compile Include="Log4NetLogger.cs" /> <Compile Include="Log4NetLogger.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="SvgBitmapHttpContentConverter.cs" />
<Compile Include="SvgImage.cs" /> <Compile Include="SvgImage.cs" />
<None Include="Languages\language_jiraplugin-de-DE.xml"> <None Include="Languages\language_jiraplugin-de-DE.xml">
<CopyToOutputDirectory>Always</CopyToOutputDirectory> <CopyToOutputDirectory>Always</CopyToOutputDirectory>

View file

@ -33,11 +33,11 @@ namespace GreenshotJiraPlugin
/// </summary> /// </summary>
public class IssueTypeBitmapCache : AsyncMemoryCache<IssueType, Bitmap> public class IssueTypeBitmapCache : AsyncMemoryCache<IssueType, Bitmap>
{ {
private readonly JiraApi _jiraApi; private readonly IJiraClient _jiraClient;
public IssueTypeBitmapCache(JiraApi jiraApi) public IssueTypeBitmapCache(IJiraClient jiraClient)
{ {
_jiraApi = jiraApi; _jiraClient = jiraClient;
// Set the expire timeout to an hour // Set the expire timeout to an hour
ExpireTimeSpan = TimeSpan.FromHours(4); ExpireTimeSpan = TimeSpan.FromHours(4);
} }
@ -49,7 +49,7 @@ namespace GreenshotJiraPlugin
protected override async Task<Bitmap> CreateAsync(IssueType issueType, CancellationToken cancellationToken = new CancellationToken()) protected override async Task<Bitmap> CreateAsync(IssueType issueType, CancellationToken cancellationToken = new CancellationToken())
{ {
return await _jiraApi.GetUriContentAsync<Bitmap>(issueType.IconUri, cancellationToken).ConfigureAwait(false); return await _jiraClient.Server.GetUriContentAsync<Bitmap>(issueType.IconUri, cancellationToken).ConfigureAwait(false);
} }
} }
} }

View file

@ -24,19 +24,20 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.IO; using System.IO;
using System.Linq;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Forms; using System.Windows.Forms;
using Dapplo.HttpExtensions; using Dapplo.HttpExtensions;
using Dapplo.HttpExtensions.Extensions;
using Dapplo.Jira; using Dapplo.Jira;
using Dapplo.Jira.Converters;
using Dapplo.Jira.Entities; using Dapplo.Jira.Entities;
using Greenshot.IniFile; using Greenshot.IniFile;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
namespace GreenshotJiraPlugin { namespace GreenshotJiraPlugin {
/// <summary> /// <summary>
/// This encapsulates the JiraApi to make it possible to change as less old Greenshot code as needed /// This encapsulates the JiraClient to make it possible to change as less old Greenshot code as needed
/// </summary> /// </summary>
public class JiraConnector : IDisposable { public class JiraConnector : IDisposable {
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraConnector)); private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraConnector));
@ -47,27 +48,19 @@ namespace GreenshotJiraPlugin {
private DateTimeOffset _loggedInTime = DateTimeOffset.MinValue; private DateTimeOffset _loggedInTime = DateTimeOffset.MinValue;
private bool _loggedIn; private bool _loggedIn;
private readonly int _timeout; private readonly int _timeout;
private JiraApi _jiraApi; private IJiraClient _jiraClient;
private IssueTypeBitmapCache _issueTypeBitmapCache; private IssueTypeBitmapCache _issueTypeBitmapCache;
private static readonly SvgBitmapHttpContentConverter SvgBitmapHttpContentConverterInstance = new SvgBitmapHttpContentConverter();
/// <summary> /// <summary>
/// Initialize some basic stuff, in the case the SVG to bitmap converter /// Initialize some basic stuff, in the case the SVG to bitmap converter
/// </summary> /// </summary>
static JiraConnector() static JiraConnector()
{ {
if (HttpExtensionsGlobals.HttpContentConverters.All(x => x.GetType() != typeof(SvgBitmapHttpContentConverter)))
{
HttpExtensionsGlobals.HttpContentConverters.Add(SvgBitmapHttpContentConverterInstance);
}
SvgBitmapHttpContentConverterInstance.Width = CoreConfig.IconSize.Width;
SvgBitmapHttpContentConverterInstance.Height = CoreConfig.IconSize.Height;
CoreConfig.PropertyChanged += (sender, args) => CoreConfig.PropertyChanged += (sender, args) =>
{ {
if (args.PropertyName == nameof(CoreConfig.IconSize)) if (args.PropertyName == nameof(CoreConfig.IconSize))
{ {
SvgBitmapHttpContentConverterInstance.Width = CoreConfig.IconSize.Width; JiraPlugin.Instance.JiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.IconSize.Width, Height = CoreConfig.IconSize.Height });
SvgBitmapHttpContentConverterInstance.Height = CoreConfig.IconSize.Height;
} }
}; };
@ -77,7 +70,7 @@ namespace GreenshotJiraPlugin {
/// Dispose, logout the users /// Dispose, logout the users
/// </summary> /// </summary>
public void Dispose() { public void Dispose() {
if (_jiraApi != null) if (_jiraClient != null)
{ {
Task.Run(async () => await LogoutAsync()).Wait(); Task.Run(async () => await LogoutAsync()).Wait();
} }
@ -104,25 +97,27 @@ namespace GreenshotJiraPlugin {
/// Internal login which catches the exceptions /// Internal login which catches the exceptions
/// </summary> /// </summary>
/// <returns>true if login was done sucessfully</returns> /// <returns>true if login was done sucessfully</returns>
private async Task<bool> DoLoginAsync(string user, string password) private async Task<bool> DoLoginAsync(string user, string password, CancellationToken cancellationToken = default(CancellationToken))
{ {
if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(password)) if (string.IsNullOrEmpty(user) || string.IsNullOrEmpty(password))
{ {
return false; return false;
} }
_jiraApi = new JiraApi(new Uri(JiraConfig.Url)); _jiraClient = JiraClient.Create(new Uri(JiraConfig.Url));
_issueTypeBitmapCache = new IssueTypeBitmapCache(_jiraApi); _jiraClient.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.IconSize.Width, Height = CoreConfig.IconSize.Height });
_issueTypeBitmapCache = new IssueTypeBitmapCache(_jiraClient);
LoginInfo loginInfo; LoginInfo loginInfo;
try try
{ {
loginInfo = await _jiraApi.StartSessionAsync(user, password); loginInfo = await _jiraClient.Session.StartAsync(user, password, cancellationToken);
Monitor = new JiraMonitor(); Monitor = new JiraMonitor();
await Monitor.AddJiraInstanceAsync(_jiraApi); await Monitor.AddJiraInstanceAsync(_jiraClient, cancellationToken);
var favIconUri = _jiraApi.JiraBaseUri.AppendSegments("favicon.ico"); var favIconUri = _jiraClient.JiraBaseUri.AppendSegments("favicon.ico");
try try
{ {
FavIcon = await _jiraApi.GetUriContentAsync<Bitmap>(favIconUri); FavIcon = await _jiraClient.Server.GetUriContentAsync<Bitmap>(favIconUri, cancellationToken);
} }
catch (Exception ex) catch (Exception ex)
{ {
@ -142,8 +137,8 @@ namespace GreenshotJiraPlugin {
/// If there are credentials, call the real login. /// If there are credentials, call the real login.
/// </summary> /// </summary>
/// <returns>Task</returns> /// <returns>Task</returns>
public async Task LoginAsync() { public async Task LoginAsync(CancellationToken cancellationToken = default(CancellationToken)) {
await LogoutAsync(); await LogoutAsync(cancellationToken);
try { try {
// Get the system name, so the user knows where to login to // Get the system name, so the user knows where to login to
var credentialsDialog = new CredentialsDialog(JiraConfig.Url) var credentialsDialog = new CredentialsDialog(JiraConfig.Url)
@ -151,7 +146,7 @@ namespace GreenshotJiraPlugin {
Name = null Name = null
}; };
while (credentialsDialog.Show(credentialsDialog.Name) == DialogResult.OK) { while (credentialsDialog.Show(credentialsDialog.Name) == DialogResult.OK) {
if (await DoLoginAsync(credentialsDialog.Name, credentialsDialog.Password)) { if (await DoLoginAsync(credentialsDialog.Name, credentialsDialog.Password, cancellationToken)) {
if (credentialsDialog.SaveChecked) { if (credentialsDialog.SaveChecked) {
credentialsDialog.Confirm(true); credentialsDialog.Confirm(true);
} }
@ -181,11 +176,11 @@ namespace GreenshotJiraPlugin {
/// <summary> /// <summary>
/// End the session, if there was one /// End the session, if there was one
/// </summary> /// </summary>
public async Task LogoutAsync() { public async Task LogoutAsync(CancellationToken cancellationToken = default(CancellationToken)) {
if (_jiraApi != null && _loggedIn) if (_jiraClient != null && _loggedIn)
{ {
Monitor.Dispose(); Monitor.Dispose();
await _jiraApi.EndSessionAsync(); await _jiraClient.Session.EndAsync(cancellationToken);
_loggedIn = false; _loggedIn = false;
} }
} }
@ -195,14 +190,14 @@ namespace GreenshotJiraPlugin {
/// Do not use ConfigureAwait to call this, as it will move await from the UI thread. /// Do not use ConfigureAwait to call this, as it will move await from the UI thread.
/// </summary> /// </summary>
/// <returns></returns> /// <returns></returns>
private async Task CheckCredentialsAsync() { private async Task CheckCredentialsAsync(CancellationToken cancellationToken = default(CancellationToken)) {
if (_loggedIn) { if (_loggedIn) {
if (_loggedInTime.AddMinutes(_timeout-1).CompareTo(DateTime.Now) < 0) { if (_loggedInTime.AddMinutes(_timeout-1).CompareTo(DateTime.Now) < 0) {
await LogoutAsync(); await LogoutAsync(cancellationToken);
await LoginAsync(); await LoginAsync(cancellationToken);
} }
} else { } else {
await LoginAsync(); await LoginAsync(cancellationToken);
} }
} }
@ -210,23 +205,24 @@ namespace GreenshotJiraPlugin {
/// Get the favourite filters /// Get the favourite filters
/// </summary> /// </summary>
/// <returns>List with filters</returns> /// <returns>List with filters</returns>
public async Task<IList<Filter>> GetFavoriteFiltersAsync() public async Task<IList<Filter>> GetFavoriteFiltersAsync(CancellationToken cancellationToken = default(CancellationToken))
{ {
await CheckCredentialsAsync(); await CheckCredentialsAsync(cancellationToken);
return await _jiraApi.GetFavoriteFiltersAsync().ConfigureAwait(false); return await _jiraClient.Filter.GetFavoritesAsync(cancellationToken).ConfigureAwait(false);
} }
/// <summary> /// <summary>
/// Get the issue for a key /// Get the issue for a key
/// </summary> /// </summary>
/// <param name="issueKey">Jira issue key</param> /// <param name="issueKey">Jira issue key</param>
/// <param name="cancellationToken">CancellationToken</param>
/// <returns>Issue</returns> /// <returns>Issue</returns>
public async Task<Issue> GetIssueAsync(string issueKey) public async Task<Issue> GetIssueAsync(string issueKey, CancellationToken cancellationToken = default(CancellationToken))
{ {
await CheckCredentialsAsync(); await CheckCredentialsAsync(cancellationToken);
try try
{ {
return await _jiraApi.GetIssueAsync(issueKey).ConfigureAwait(false); return await _jiraClient.Issue.GetAsync(issueKey, cancellationToken).ConfigureAwait(false);
} }
catch catch
{ {
@ -243,12 +239,12 @@ namespace GreenshotJiraPlugin {
/// <returns></returns> /// <returns></returns>
public async Task AttachAsync(string issueKey, IBinaryContainer content, CancellationToken cancellationToken = default(CancellationToken)) public async Task AttachAsync(string issueKey, IBinaryContainer content, CancellationToken cancellationToken = default(CancellationToken))
{ {
await CheckCredentialsAsync(); await CheckCredentialsAsync(cancellationToken);
using (var memoryStream = new MemoryStream()) using (var memoryStream = new MemoryStream())
{ {
content.WriteToStream(memoryStream); content.WriteToStream(memoryStream);
memoryStream.Seek(0, SeekOrigin.Begin); memoryStream.Seek(0, SeekOrigin.Begin);
await _jiraApi.AttachAsync(issueKey, memoryStream, content.Filename, content.ContentType, cancellationToken).ConfigureAwait(false); await _jiraClient.Attachment.AttachAsync(issueKey, memoryStream, content.Filename, content.ContentType, cancellationToken).ConfigureAwait(false);
} }
} }
@ -261,8 +257,8 @@ namespace GreenshotJiraPlugin {
/// <param name="cancellationToken">CancellationToken</param> /// <param name="cancellationToken">CancellationToken</param>
public async Task AddCommentAsync(string issueKey, string body, string visibility = null, CancellationToken cancellationToken = default(CancellationToken)) public async Task AddCommentAsync(string issueKey, string body, string visibility = null, CancellationToken cancellationToken = default(CancellationToken))
{ {
await CheckCredentialsAsync(); await CheckCredentialsAsync(cancellationToken);
await _jiraApi.AddCommentAsync(issueKey, body, visibility, cancellationToken).ConfigureAwait(false); await _jiraClient.Issue.AddCommentAsync(issueKey, body, visibility, cancellationToken).ConfigureAwait(false);
} }
/// <summary> /// <summary>
@ -273,8 +269,8 @@ namespace GreenshotJiraPlugin {
/// <returns></returns> /// <returns></returns>
public async Task<IList<Issue>> SearchAsync(Filter filter, CancellationToken cancellationToken = default(CancellationToken)) public async Task<IList<Issue>> SearchAsync(Filter filter, CancellationToken cancellationToken = default(CancellationToken))
{ {
await CheckCredentialsAsync(); await CheckCredentialsAsync(cancellationToken);
var searchResult = await _jiraApi.SearchAsync(filter.Jql, 20, new[] { "summary", "reporter", "assignee", "created", "issuetype" }, cancellationToken).ConfigureAwait(false); var searchResult = await _jiraClient.Issue.SearchAsync(filter.Jql, 20, new[] { "summary", "reporter", "assignee", "created", "issuetype" }, cancellationToken).ConfigureAwait(false);
return searchResult.Issues; return searchResult.Issues;
} }
@ -292,7 +288,7 @@ namespace GreenshotJiraPlugin {
/// <summary> /// <summary>
/// Get the base uri /// Get the base uri
/// </summary> /// </summary>
public Uri JiraBaseUri => _jiraApi.JiraBaseUri; public Uri JiraBaseUri => _jiraClient.JiraBaseUri;
/// <summary> /// <summary>
/// Is the user "logged in? /// Is the user "logged in?

View file

@ -77,10 +77,18 @@ namespace GreenshotJiraPlugin {
if (jiraConnector != null) if (jiraConnector != null)
{ {
if (_jiraIssue != null) if (_jiraIssue != null)
{
// Try to get the issue type as icon
try
{ {
displayIcon = jiraConnector.GetIssueTypeBitmapAsync(_jiraIssue).Result; displayIcon = jiraConnector.GetIssueTypeBitmapAsync(_jiraIssue).Result;
} }
else catch (Exception ex)
{
Log.Warn($"Problem loading issue type for {_jiraIssue.Key}, ignoring", ex);
}
}
if (displayIcon == null)
{ {
displayIcon = jiraConnector.FavIcon; displayIcon = jiraConnector.FavIcon;
} }

View file

@ -26,7 +26,7 @@ using System.Text.RegularExpressions;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapplo.Jira; using Dapplo.Jira;
using Dapplo.Log.Facade; using Dapplo.Log;
using GreenshotJiraPlugin.Hooking; using GreenshotJiraPlugin.Hooking;
namespace GreenshotJiraPlugin namespace GreenshotJiraPlugin
@ -42,9 +42,10 @@ namespace GreenshotJiraPlugin
private static readonly LogSource Log = new LogSource(); private static readonly LogSource Log = new LogSource();
private readonly Regex _jiraKeyPattern = new Regex(@"[A-Z][A-Z0-9]+\-[0-9]+"); private readonly Regex _jiraKeyPattern = new Regex(@"[A-Z][A-Z0-9]+\-[0-9]+");
private readonly WindowsTitleMonitor _monitor; private readonly WindowsTitleMonitor _monitor;
private readonly IList<JiraApi> _jiraInstances = new List<JiraApi>(); private readonly IList<IJiraClient> _jiraInstances = new List<IJiraClient>();
private readonly IDictionary<string, JiraApi> _projectJiraApiMap = new Dictionary<string, JiraApi>(); private readonly IDictionary<string, IJiraClient> _projectJiraClientMap = new Dictionary<string, IJiraClient>();
private readonly int _maxEntries; private readonly int _maxEntries;
// TODO: Add issues from issueHistory (JQL -> Where.IssueKey.InIssueHistory())
private IDictionary<string, JiraDetails> _recentJiras = new Dictionary<string, JiraDetails>(); private IDictionary<string, JiraDetails> _recentJiras = new Dictionary<string, JiraDetails>();
/// <summary> /// <summary>
@ -92,10 +93,10 @@ namespace GreenshotJiraPlugin
/// Retrieve the API belonging to a JiraDetails /// Retrieve the API belonging to a JiraDetails
/// </summary> /// </summary>
/// <param name="jiraDetails"></param> /// <param name="jiraDetails"></param>
/// <returns>JiraAPI</returns> /// <returns>IJiraClient</returns>
public JiraApi GetJiraApiForKey(JiraDetails jiraDetails) public IJiraClient GetJiraClientForKey(JiraDetails jiraDetails)
{ {
return _projectJiraApiMap[jiraDetails.ProjectKey]; return _projectJiraClientMap[jiraDetails.ProjectKey];
} }
/// <summary> /// <summary>
@ -116,17 +117,17 @@ namespace GreenshotJiraPlugin
/// </summary> /// </summary>
/// <param name="jiraInstance"></param> /// <param name="jiraInstance"></param>
/// <param name="token"></param> /// <param name="token"></param>
public async Task AddJiraInstanceAsync(JiraApi jiraInstance, CancellationToken token = default(CancellationToken)) public async Task AddJiraInstanceAsync(IJiraClient jiraInstance, CancellationToken token = default(CancellationToken))
{ {
_jiraInstances.Add(jiraInstance); _jiraInstances.Add(jiraInstance);
var projects = await jiraInstance.GetProjectsAsync(token).ConfigureAwait(false); var projects = await jiraInstance.Project.GetAllAsync(cancellationToken: token).ConfigureAwait(false);
if (projects != null) if (projects != null)
{ {
foreach (var project in projects) foreach (var project in projects)
{ {
if (!_projectJiraApiMap.ContainsKey(project.Key)) if (!_projectJiraClientMap.ContainsKey(project.Key))
{ {
_projectJiraApiMap.Add(project.Key, jiraInstance); _projectJiraClientMap.Add(project.Key, jiraInstance);
} }
} }
} }
@ -141,10 +142,10 @@ namespace GreenshotJiraPlugin
{ {
try try
{ {
JiraApi jiraApi; IJiraClient jiraClient;
if (_projectJiraApiMap.TryGetValue(jiraDetails.ProjectKey, out jiraApi)) if (_projectJiraClientMap.TryGetValue(jiraDetails.ProjectKey, out jiraClient))
{ {
var issue = await jiraApi.GetIssueAsync(jiraDetails.JiraKey).ConfigureAwait(false); var issue = await jiraClient.Issue.GetAsync(jiraDetails.JiraKey).ConfigureAwait(false);
jiraDetails.JiraIssue = issue; jiraDetails.JiraIssue = issue;
} }
// Send event // Send event
@ -178,9 +179,9 @@ namespace GreenshotJiraPlugin
var projectKey = jiraKeyParts[0]; var projectKey = jiraKeyParts[0];
var jiraId = jiraKeyParts[1]; var jiraId = jiraKeyParts[1];
JiraApi jiraApi; IJiraClient jiraClient;
// Check if we have a JIRA instance with a project for this key // Check if we have a JIRA instance with a project for this key
if (_projectJiraApiMap.TryGetValue(projectKey, out jiraApi)) if (_projectJiraClientMap.TryGetValue(projectKey, out jiraClient))
{ {
// We have found a project for this _jira key, so it must be a valid & known JIRA // We have found a project for this _jira key, so it must be a valid & known JIRA
JiraDetails currentJiraDetails; JiraDetails currentJiraDetails;
@ -207,8 +208,7 @@ namespace GreenshotJiraPlugin
if (_recentJiras.Count > _maxEntries) if (_recentJiras.Count > _maxEntries)
{ {
// Add it to the list of recent Jiras // Add it to the list of recent Jiras
IList<JiraDetails> clonedList = new List<JiraDetails>(_recentJiras.Values); _recentJiras = (from jiraDetails in _recentJiras.Values.ToList()
_recentJiras = (from jiraDetails in clonedList
orderby jiraDetails.SeenAt descending orderby jiraDetails.SeenAt descending
select jiraDetails).Take(_maxEntries).ToDictionary(jd => jd.JiraKey, jd => jd); select jiraDetails).Take(_maxEntries).ToDictionary(jd => jd.JiraKey, jd => jd);
} }

View file

@ -24,7 +24,9 @@ using Greenshot.IniFile;
using Greenshot.Plugin; using Greenshot.Plugin;
using System; using System;
using System.Threading.Tasks; using System.Threading.Tasks;
using Dapplo.Log.Facade; using Dapplo.Log;
using Greenshot.Forms;
using Greenshot.Helpers;
using GreenshotJiraPlugin.Forms; using GreenshotJiraPlugin.Forms;
using GreenshotPlugin.Core; using GreenshotPlugin.Core;
using log4net; using log4net;
@ -57,6 +59,22 @@ namespace GreenshotJiraPlugin {
public JiraPlugin() { public JiraPlugin() {
_instance = this; _instance = this;
// Added to prevent Greenshot from shutting down when there was an exception in a Task
TaskScheduler.UnobservedTaskException += (sender, args) =>
{
try
{
Exception exceptionToLog = args.Exception;
string exceptionText = EnvironmentInfo.BuildReport(exceptionToLog);
Log.Error("Exception caught in the UnobservedTaskException handler.");
Log.Error(exceptionText);
new BugReportForm(exceptionText).ShowDialog();
}
finally
{
args.SetObserved();
}
};
} }
public IEnumerable<IDestination> Destinations() { public IEnumerable<IDestination> Destinations() {

View file

@ -19,7 +19,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/ */
using Dapplo.Log.Facade; using Dapplo.Log;
using log4net; using log4net;
namespace GreenshotJiraPlugin namespace GreenshotJiraPlugin

View file

@ -1,126 +0,0 @@
/*
* Greenshot - a free and open source screenshot tool
* Copyright (C) 2007-2016 Thomas Braun, Jens Klingen, Robin Krom
*
* For more information see: http://getgreenshot.org/
* The Greenshot project is hosted on GitHub https://github.com/greenshot/greenshot
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 1 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.Drawing;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using Dapplo.HttpExtensions;
using Dapplo.HttpExtensions.ContentConverter;
using Dapplo.HttpExtensions.Extensions;
using Dapplo.HttpExtensions.Support;
using Dapplo.Log.Facade;
using System.Net.Http;
using System.Net.Http.Headers;
namespace GreenshotJiraPlugin
{
/// <summary>
/// This adds SVG image support for the Jira Plugin
/// </summary>
public class SvgBitmapHttpContentConverter : IHttpContentConverter
{
private static readonly LogSource Log = new LogSource();
private static readonly IList<string> SupportedContentTypes = new List<string>();
static SvgBitmapHttpContentConverter()
{
SupportedContentTypes.Add(MediaTypes.Svg.EnumValueOf());
}
/// <inheritdoc />
public int Order => 0;
public int Width { get; set; }
public int Height { get; set; }
/// <summary>
/// This checks if the HttpContent can be converted to a Bitmap and is assignable to the specified Type
/// </summary>
/// <param name="typeToConvertTo">This should be something we can assign Bitmap to</param>
/// <param name="httpContent">HttpContent to process</param>
/// <returns>true if it can convert</returns>
public bool CanConvertFromHttpContent(Type typeToConvertTo, HttpContent httpContent)
{
if (typeToConvertTo == typeof(object) || !typeToConvertTo.IsAssignableFrom(typeof(Bitmap)))
{
return false;
}
var httpBehaviour = HttpBehaviour.Current;
return !httpBehaviour.ValidateResponseContentType || SupportedContentTypes.Contains(httpContent.GetContentType());
}
/// <inheritdoc />
public async Task<object> ConvertFromHttpContentAsync(Type resultType, HttpContent httpContent, CancellationToken cancellationToken = default(CancellationToken))
{
if (!CanConvertFromHttpContent(resultType, httpContent))
{
var exMessage = "CanConvertFromHttpContent resulted in false, ConvertFromHttpContentAsync is not supposed to be called.";
Log.Error().WriteLine(exMessage);
throw new NotSupportedException(exMessage);
}
using (var memoryStream = (MemoryStream) await StreamHttpContentConverter.Instance.ConvertFromHttpContentAsync(typeof(MemoryStream), httpContent, cancellationToken).ConfigureAwait(false))
{
Log.Debug().WriteLine("Creating a Bitmap from the SVG.");
var svgImage = new SvgImage(memoryStream)
{
Height = Height,
Width = Width
};
return svgImage.Image;
}
}
/// <inheritdoc />
public bool CanConvertToHttpContent(Type typeToConvert, object content)
{
return false;
}
/// <inheritdoc />
public HttpContent ConvertToHttpContent(Type typeToConvert, object content)
{
return null;
}
/// <inheritdoc />
public void AddAcceptHeadersForType(Type resultType, HttpRequestMessage httpRequestMessage)
{
if (resultType == null)
{
throw new ArgumentNullException(nameof(resultType));
}
if (httpRequestMessage == null)
{
throw new ArgumentNullException(nameof(httpRequestMessage));
}
if (resultType == typeof(object) || !resultType.IsAssignableFrom(typeof(Bitmap)))
{
return;
}
httpRequestMessage.Headers.Accept.Add(new MediaTypeWithQualityHeaderValue(MediaTypes.Svg.EnumValueOf()));
Log.Debug().WriteLine("Modified the header(s) of the HttpRequestMessage: Accept: {0}", httpRequestMessage.Headers.Accept);
}
}
}

View file

@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="CANCEL">Sefsex</resource>
<resource name="column_assignee">Bénéficiaire</resource>
<resource name="column_created">Yettwarna</resource>
<resource name="column_id">Asulay</resource>
<resource name="column_reporter">Azen</resource>
<resource name="column_summary">Agzul</resource>
<resource name="communication_wait">Asiweḍ n isefka ɣer JIRA, ṛǧu ma ulac aɣilif...</resource>
<resource name="label_comment">Awennit</resource>
<resource name="label_filename">Afaylu</resource>
<resource name="label_jira">JIRA</resource>
<resource name="label_jirafilter">Imzizdeg JIRA</resource>
<resource name="label_upload_format">Amasal tugna</resource>
<resource name="label_url">Tansa Url</resource>
<resource name="login_error">Teḍra-d tucḍa deg usesteb : {0}</resource>
<resource name="login_title">Ma ulac aɣilif sekcem isulayen Jira</resource>
<resource name="OK">IH</resource>
<resource name="settings_title">Iɣewwaṛen Jira</resource>
<resource name="upload_failure">Teḍra-d tuccḍa deg usal ɣer Jira :</resource>
<resource name="upload_menu_item">Sali ɣer Jira</resource>
<resource name="upload_success">Tugna tuli ɣer Jira akken iwata !</resource>
</resources>
</language>

View file

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="Dapplo.HttpExtensions" version="0.5.43" targetFramework="net45" /> <package id="Dapplo.HttpExtensions" version="0.6.17" targetFramework="net45" />
<package id="Dapplo.Jira" version="0.1.65" targetFramework="net45" /> <package id="Dapplo.Jira" version="0.5.12" targetFramework="net45" />
<package id="Dapplo.Log.Facade" version="0.5.4" targetFramework="net45" /> <package id="Dapplo.Log" version="1.0.23" targetFramework="net45" />
<package id="LibZ.Tool" version="1.2.0.0" targetFramework="net45" /> <package id="LibZ.Tool" version="1.2.0.0" targetFramework="net45" />
<package id="Svg" version="2.2.2" targetFramework="net45" /> <package id="Svg" version="2.3.0" targetFramework="net45" />
</packages> </packages>

View file

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="language">Tutlayt i OCR</resource>
<resource name="orient_image">Wehhi tugna</resource>
<resource name="straighten_image">Seggwem tugna</resource>
</resources>
</language>

View file

@ -45,7 +45,8 @@ namespace Greenshot.Interop.Office {
OneNotePage newPage = new OneNotePage(); OneNotePage newPage = new OneNotePage();
string unfiledNotesSectionId = GetSectionId(oneNoteApplication, SpecialLocation.slUnfiledNotesSection); string unfiledNotesSectionId = GetSectionId(oneNoteApplication, SpecialLocation.slUnfiledNotesSection);
if(unfiledNotesSectionId != null) { if(unfiledNotesSectionId != null) {
string pageId; // ReSharper disable once RedundantAssignment
string pageId = "";
oneNoteApplication.CreateNewPage(unfiledNotesSectionId, out pageId, NewPageStyle.npsDefault); oneNoteApplication.CreateNewPage(unfiledNotesSectionId, out pageId, NewPageStyle.npsDefault);
newPage.ID = pageId; newPage.ID = pageId;
// Set the new name, this is automatically done in the export to page // Set the new name, this is automatically done in the export to page
@ -106,10 +107,12 @@ namespace Greenshot.Interop.Office {
if(oneNoteApplication == null) { if(oneNoteApplication == null) {
return null; return null;
} }
string unfiledNotesPath; // ReSharper disable once RedundantAssignment
string unfiledNotesPath = "";
oneNoteApplication.GetSpecialLocation(specialLocation, out unfiledNotesPath); oneNoteApplication.GetSpecialLocation(specialLocation, out unfiledNotesPath);
string notebookXml; // ReSharper disable once RedundantAssignment
string notebookXml = "";
oneNoteApplication.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010); oneNoteApplication.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010);
if(!string.IsNullOrEmpty(notebookXml)) { if(!string.IsNullOrEmpty(notebookXml)) {
Log.Debug(notebookXml); Log.Debug(notebookXml);
@ -144,7 +147,8 @@ namespace Greenshot.Interop.Office {
try { try {
using (IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance<IOneNoteApplication>()) { using (IOneNoteApplication oneNoteApplication = COMWrapper.GetOrCreateInstance<IOneNoteApplication>()) {
if (oneNoteApplication != null) { if (oneNoteApplication != null) {
string notebookXml; // ReSharper disable once RedundantAssignment
string notebookXml = "";
oneNoteApplication.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010); oneNoteApplication.GetHierarchy("", HierarchyScope.hsPages, out notebookXml, XMLSchema.xs2010);
if (!string.IsNullOrEmpty(notebookXml)) { if (!string.IsNullOrEmpty(notebookXml)) {
Log.Debug(notebookXml); Log.Debug(notebookXml);
@ -215,7 +219,7 @@ namespace Greenshot.Interop.Office {
if(p1.IsCurrentlyViewed || p2.IsCurrentlyViewed) { if(p1.IsCurrentlyViewed || p2.IsCurrentlyViewed) {
return p2.IsCurrentlyViewed.CompareTo(p1.IsCurrentlyViewed); return p2.IsCurrentlyViewed.CompareTo(p1.IsCurrentlyViewed);
} }
return String.Compare(p1.DisplayName, p2.DisplayName, StringComparison.Ordinal); return string.Compare(p1.DisplayName, p2.DisplayName, StringComparison.Ordinal);
}); });
return pages; return pages;
} }

View file

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="0.8.0">
<resources>
<resource name="upload_menu_item">
Sali ɣer Photobucket
</resource>
<resource name="settings_title">
Iɣewwaṛen n Photobucket
</resource>
<resource name="label_use_proxy">
Seqdec apṛuksi
</resource>
<resource name="upload_success">
Tugna tuli akken iwata ɣer Photobucket !
</resource>
<resource name="upload_failure">
Teḍra-d tuccḍa deg usali ɣer Photobucket:
</resource>
<resource name="label_upload_format">
Amasal n tugna
</resource>
<resource name="upload_wait">
Asali ɣer Photobucket, Ṛǧu ma ulac aɣilif...
</resource>
<resource name="configure">
Swel Photobucket
</resource>
</resources>
</language>

View file

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<language description="Taqbaylit" ietf="kab-DZ" version="1.0.0" languagegroup="">
<resources>
<resource name="communication_wait">S tidett tebɣiḍ ad tekkseḍ amazray adigan n Picasa ?...</resource>
<resource name="Configure">Swel Picasa</resource>
<resource name="label_AfterUpload">Ticki yemmed usali</resource>
<resource name="label_AfterUploadLinkToClipBoard">Nɣel aseɣwen ɣef afus</resource>
<resource name="label_upload_format">Amsal n tugna</resource>
<resource name="settings_title">Iɣewwaṛen Picasa</resource>
<resource name="upload_failure">Teḍra-d tuccḍa deg usali ɣer Picasa :</resource>
<resource name="upload_menu_item">Sali ɣer Picasa</resource>
<resource name="upload_success">Tugna tuli ɣer Picasa !</resource>
</resources>
</language>

View file

@ -20,7 +20,6 @@
*/ */
using System; using System;
using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
@ -49,15 +48,6 @@ namespace GreenshotPlugin.Controls {
private const uint WM_HOTKEY = 0x312; private const uint WM_HOTKEY = 0x312;
private static IntPtr _hotkeyHwnd; private static IntPtr _hotkeyHwnd;
// static HotkeyControl() {
// StringBuilder keyName = new StringBuilder();
// for(uint sc = 0; sc < 500; sc++) {
// if (GetKeyNameText(sc << 16, keyName, 100) != 0) {
// LOG.DebugFormat("SC {0} = {1}", sc, keyName);
// }
// }
// }
[SuppressMessage("ReSharper", "InconsistentNaming")] [SuppressMessage("ReSharper", "InconsistentNaming")]
public enum Modifiers : uint { public enum Modifiers : uint {
NONE = 0, NONE = 0,
@ -96,8 +86,8 @@ namespace GreenshotPlugin.Controls {
// ArrayLists used to enforce the use of proper modifiers. // ArrayLists used to enforce the use of proper modifiers.
// Shift+A isn't a valid hotkey, for instance, as it would screw up when the user is typing. // Shift+A isn't a valid hotkey, for instance, as it would screw up when the user is typing.
private readonly ArrayList _needNonShiftModifier; private readonly IList<int> _needNonShiftModifier = new List<int>();
private readonly ArrayList _needNonAltGrModifier; private readonly IList<int> _needNonAltGrModifier = new List<int>();
private readonly ContextMenu _dummy = new ContextMenu(); private readonly ContextMenu _dummy = new ContextMenu();
@ -138,9 +128,6 @@ namespace GreenshotPlugin.Controls {
KeyUp += HotkeyControl_KeyUp; KeyUp += HotkeyControl_KeyUp;
KeyDown += HotkeyControl_KeyDown; KeyDown += HotkeyControl_KeyDown;
// Fill the ArrayLists that contain all invalid hotkey combinations
_needNonShiftModifier = new ArrayList();
_needNonAltGrModifier = new ArrayList();
PopulateModifierLists(); PopulateModifierLists();
} }
@ -180,8 +167,6 @@ namespace GreenshotPlugin.Controls {
_needNonShiftModifier.Add((int)Keys.Return); _needNonShiftModifier.Add((int)Keys.Return);
_needNonShiftModifier.Add((int)Keys.Escape); _needNonShiftModifier.Add((int)Keys.Escape);
_needNonShiftModifier.Add((int)Keys.NumLock); _needNonShiftModifier.Add((int)Keys.NumLock);
_needNonShiftModifier.Add((int)Keys.Scroll);
_needNonShiftModifier.Add((int)Keys.Pause);
// Ctrl+Alt + 0 - 9 // Ctrl+Alt + 0 - 9
for (Keys k = Keys.D0; k <= Keys.D9; k++) { for (Keys k = Keys.D0; k <= Keys.D9; k++) {

View file

@ -68,6 +68,7 @@ namespace GreenshotPlugin.Controls {
ApplyFilterOptions(); ApplyFilterOptions();
string initialDirectory = null; string initialDirectory = null;
try { try {
conf.ValidateAndCorrectOutputFileAsFullpath();
initialDirectory = Path.GetDirectoryName(conf.OutputFileAsFullpath); initialDirectory = Path.GetDirectoryName(conf.OutputFileAsFullpath);
} catch { } catch {
LOG.WarnFormat("OutputFileAsFullpath was set to {0}, ignoring due to problem in path.", conf.OutputFileAsFullpath); LOG.WarnFormat("OutputFileAsFullpath was set to {0}, ignoring due to problem in path.", conf.OutputFileAsFullpath);

View file

@ -813,10 +813,10 @@ EndSelection:<<<<<<<4
string[] dropFileNames = (string[]) dataObject.GetData(DataFormats.FileDrop); string[] dropFileNames = (string[]) dataObject.GetData(DataFormats.FileDrop);
if (dropFileNames != null && dropFileNames.Length > 0) if (dropFileNames != null && dropFileNames.Length > 0)
{ {
return dropFileNames.Where(filename => !string.IsNullOrEmpty(filename)) return dropFileNames
.Where(filename => !string.IsNullOrEmpty(filename))
.Where(Path.HasExtension) .Where(Path.HasExtension)
.Select(filename => Path.GetExtension(filename).ToLowerInvariant()) .Where(filename => ImageHelper.StreamConverters.Keys.Contains(Path.GetExtension(filename).ToLowerInvariant().Substring(1)));
.Where(ext => ImageHelper.StreamConverters.Keys.Contains(ext));
} }
return Enumerable.Empty<string>(); return Enumerable.Empty<string>();
} }

View file

@ -263,6 +263,9 @@ namespace GreenshotPlugin.Core {
[IniProperty("LastCapturedRegion", Description = "The last used region, for reuse in the capture last region")] [IniProperty("LastCapturedRegion", Description = "The last used region, for reuse in the capture last region")]
public Rectangle LastCapturedRegion { get; set; } public Rectangle LastCapturedRegion { get; set; }
[IniProperty("Win10BorderCrop", Description = "The capture is cropped with these settings, e.g. when you don't want to color around it -1,-1"), DefaultValue("0,0")]
public Size Win10BorderCrop { get; set; }
private Size _iconSize; private Size _iconSize;
[IniProperty("IconSize", Description = "Defines the size of the icons (e.g. for the buttons in the editor), default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")] [IniProperty("IconSize", Description = "Defines the size of the icons (e.g. for the buttons in the editor), default value 16,16 anything bigger will cause scaling", DefaultValue = "16,16")]
public Size IconSize { public Size IconSize {
@ -339,9 +342,8 @@ namespace GreenshotPlugin.Core {
case "OutputFileAsFullpath": case "OutputFileAsFullpath":
if (IniConfig.IsPortable) { if (IniConfig.IsPortable) {
return Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots\dummy.png"); return Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots\dummy.png");
} else {
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"dummy.png");
} }
return Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Desktop),"dummy.png");
case "OutputFilePath": case "OutputFilePath":
if (IniConfig.IsPortable) { if (IniConfig.IsPortable) {
string pafOutputFilePath = Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots"); string pafOutputFilePath = Path.Combine(Application.StartupPath, @"..\..\Documents\Pictures\Greenshots");
@ -512,13 +514,27 @@ namespace GreenshotPlugin.Core {
if (WebRequestReadWriteTimeout < 1) { if (WebRequestReadWriteTimeout < 1) {
WebRequestReadWriteTimeout = 100; WebRequestReadWriteTimeout = 100;
} }
}
// Added for BUG-1992, reset the OutputFilePath / OutputFileAsFullpath if they don't exist (e.g. the configuration is used on a different PC) /// <summary>
/// Validate the OutputFilePath, and if this is not correct it will be set to the default
/// Added for BUG-1992, reset the OutputFilePath / OutputFileAsFullpath if they don't exist (e.g. the configuration is used on a different PC)
/// </summary>
public void ValidateAndCorrectOutputFilePath()
{
if (!Directory.Exists(OutputFilePath)) if (!Directory.Exists(OutputFilePath))
{ {
OutputFilePath = GetDefault(nameof(OutputFilePath)) as string; OutputFilePath = GetDefault(nameof(OutputFilePath)) as string;
} }
if (!File.Exists(OutputFileAsFullpath)) }
/// <summary>
/// Validate the OutputFileAsFullpath, and if this is not correct it will be set to the default
/// Added for BUG-1992, reset the OutputFilePath / OutputFileAsFullpath if they don't exist (e.g. the configuration is used on a different PC)
/// </summary>
public void ValidateAndCorrectOutputFileAsFullpath()
{
var outputFilePath = Path.GetDirectoryName(OutputFileAsFullpath);
if (outputFilePath == null || (!File.Exists(OutputFileAsFullpath) && !Directory.Exists(outputFilePath)))
{ {
OutputFileAsFullpath = GetDefault(nameof(OutputFileAsFullpath)) as string; OutputFileAsFullpath = GetDefault(nameof(OutputFileAsFullpath)) as string;
} }

View file

@ -0,0 +1,54 @@
using System;
using System.Diagnostics;
using System.IO;
namespace GreenshotPlugin.Core
{
/// <summary>
/// Simple utility for the explorer
/// </summary>
public static class ExplorerHelper
{
/// <summary>
/// Open the path in the windows explorer.
/// If the path is a directory, it will just open the explorer with that directory.
/// If the path is a file, the explorer is opened with the directory and the file is selected.
/// </summary>
/// <param name="path">Path to file or directory</param>
public static bool OpenInExplorer(string path)
{
if (path == null)
{
return false;
}
try
{
// Check if path is a directory
if (Directory.Exists(path))
{
using (Process.Start(path))
{
return true;
}
}
// Check if path is a file
if (File.Exists(path))
{
// Start the explorer process and select the file
using (var explorer = Process.Start("explorer.exe", $"/select,\"{path}\""))
{
explorer?.WaitForInputIdle(500);
return true;
}
}
}
catch (Exception ex)
{
// Make sure we show what we tried to open in the exception
ex.Data.Add("path", path);
throw;
}
return false;
}
}
}

View file

@ -105,7 +105,7 @@ namespace GreenshotPlugin.Core {
bool useMemoryStream = false; bool useMemoryStream = false;
MemoryStream memoryStream = null; MemoryStream memoryStream = null;
if (outputSettings.Format == OutputFormat.greenshot && surface == null) { if (outputSettings.Format == OutputFormat.greenshot && surface == null) {
throw new ArgumentException("Surface needs to be se when using OutputFormat.Greenshot"); throw new ArgumentException("Surface needs to be set when using OutputFormat.Greenshot");
} }
try { try {

View file

@ -44,7 +44,7 @@ namespace GreenshotPlugin.Core {
private const string LanguageFilenamePattern = @"language*.xml"; private const string LanguageFilenamePattern = @"language*.xml";
private static readonly Regex PrefixRegexp = new Regex(@"language_([a-zA-Z0-9]+).*"); private static readonly Regex PrefixRegexp = new Regex(@"language_([a-zA-Z0-9]+).*");
private static readonly Regex IetfCleanRegexp = new Regex(@"[^a-zA-Z]+"); private static readonly Regex IetfCleanRegexp = new Regex(@"[^a-zA-Z]+");
private static readonly Regex IetfRegexp = new Regex(@"^.*([a-zA-Z]{2}-[a-zA-Z]{2})\.xml$"); private static readonly Regex IetfRegexp = new Regex(@"^.*([a-zA-Z]{2,3}-[a-zA-Z]{2})\.xml$");
private const string LanguageGroupsKey = @"SYSTEM\CurrentControlSet\Control\Nls\Language Groups"; private const string LanguageGroupsKey = @"SYSTEM\CurrentControlSet\Control\Nls\Language Groups";
private static readonly IList<string> UnsupportedLanguageGroups = new List<string>(); private static readonly IList<string> UnsupportedLanguageGroups = new List<string>();
private static readonly IDictionary<string, string> Resources = new Dictionary<string, string>(); private static readonly IDictionary<string, string> Resources = new Dictionary<string, string>();
@ -341,8 +341,10 @@ namespace GreenshotPlugin.Core {
xmlDocument.Load(languageFilePath); xmlDocument.Load(languageFilePath);
XmlNodeList nodes = xmlDocument.GetElementsByTagName("language"); XmlNodeList nodes = xmlDocument.GetElementsByTagName("language");
if (nodes.Count > 0) { if (nodes.Count > 0) {
LanguageFile languageFile = new LanguageFile(); LanguageFile languageFile = new LanguageFile
languageFile.Filepath = languageFilePath; {
Filepath = languageFilePath
};
XmlNode node = nodes.Item(0); XmlNode node = nodes.Item(0);
if (node?.Attributes != null) if (node?.Attributes != null)
{ {

View file

@ -770,7 +770,7 @@ namespace GreenshotPlugin.Core {
{ {
// Somehow DWM doesn't calculate it corectly, there is a 1 pixel border around the capture // Somehow DWM doesn't calculate it corectly, there is a 1 pixel border around the capture
// Remove this border, currently it's fixed but TODO: Make it depend on the OS? // Remove this border, currently it's fixed but TODO: Make it depend on the OS?
windowRect.Inflate(-1, -1); windowRect.Inflate(Conf.Win10BorderCrop);
_previousWindowRectangle = windowRect; _previousWindowRectangle = windowRect;
_lastWindowRectangleRetrieveTime = now; _lastWindowRectangleRetrieveTime = now;
return windowRect; return windowRect;
@ -1001,7 +1001,7 @@ namespace GreenshotPlugin.Core {
// TODO: Also 8.x? // TODO: Also 8.x?
if (Environment.OSVersion.IsWindows10()) if (Environment.OSVersion.IsWindows10())
{ {
captureRectangle.Inflate(-1, -1); captureRectangle.Inflate(Conf.Win10BorderCrop);
} }
if (autoMode) { if (autoMode) {
@ -1254,32 +1254,46 @@ namespace GreenshotPlugin.Core {
/// <summary> /// <summary>
/// Set the window as foreground window /// Set the window as foreground window
/// </summary> /// </summary>
public static void ToForeground(IntPtr handle) /// <param name="handle">hWnd of the window to bring to the foreground</param>
/// <param name="workaround">bool with true to use a trick to really bring the window to the foreground</param>
public static void ToForeground(IntPtr handle, bool workaround = true)
{ {
// Do nothing if the window is already in the foreground var window = new WindowDetails(handle);
if (User32.GetForegroundWindow() == handle) // Nothing we can do if it's not visible!
if (!window.Visible)
{ {
return; return;
} }
if (window.Iconic)
const byte ALT = 0xA4; {
const int EXTENDEDKEY = 0x1; window.Iconic = false;
const int KEYUP = 0x2; while (window.Iconic)
{
Application.DoEvents();
}
}
// See https://msdn.microsoft.com/en-us/library/windows/desktop/ms633539(v=vs.85).aspx
if (workaround)
{
const byte alt = 0xA4;
const int extendedkey = 0x1;
const int keyup = 0x2;
// Simulate an "ALT" key press. // Simulate an "ALT" key press.
User32.keybd_event(ALT, 0x45, EXTENDEDKEY | 0, 0); User32.keybd_event(alt, 0x45, extendedkey | 0, 0);
// Simulate an "ALT" key release. // Simulate an "ALT" key release.
User32.keybd_event(ALT, 0x45, EXTENDEDKEY | KEYUP, 0); User32.keybd_event(alt, 0x45, extendedkey | keyup, 0);
}
// Show window in forground. // Show window in forground.
User32.BringWindowToTop(handle);
User32.SetForegroundWindow(handle); User32.SetForegroundWindow(handle);
} }
/// <summary> /// <summary>
/// Set the window as foreground window /// Set the window as foreground window
/// </summary> /// </summary>
public void ToForeground() { /// <param name="workaround">true to use a workaround, otherwise the window might only flash</param>
ToForeground(Handle); public void ToForeground(bool workaround = true) {
ToForeground(Handle, workaround);
} }
/// <summary> /// <summary>

View file

@ -43,6 +43,7 @@
<Compile Include="Controls\GreenshotRadioButton.cs"> <Compile Include="Controls\GreenshotRadioButton.cs">
<SubType>Component</SubType> <SubType>Component</SubType>
</Compile> </Compile>
<Compile Include="Core\ExplorerHelper.cs" />
<Compile Include="Effects\AdjustEffect.cs" /> <Compile Include="Effects\AdjustEffect.cs" />
<Compile Include="Effects\BorderEffect.cs" /> <Compile Include="Effects\BorderEffect.cs" />
<Compile Include="Core\CaptureHandler.cs" /> <Compile Include="Core\CaptureHandler.cs" />

View file

@ -98,8 +98,15 @@ namespace Greenshot.Plugin {
ReduceColors = reduceColors; ReduceColors = reduceColors;
} }
public SurfaceOutputSettings PreventGreenshotFormat() { /// <summary>
if (Format == OutputFormat.greenshot) { /// BUG-2056 reported a logical issue, using greenshot format as the default causes issues with the external commands.
/// </summary>
/// <returns>this for fluent API usage</returns>
public SurfaceOutputSettings PreventGreenshotFormat()
{
// If OutputFormat is Greenshot, use PNG instead.
if (Format == OutputFormat.greenshot)
{
Format = OutputFormat.png; Format = OutputFormat.png;
} }
return this; return this;

View file

@ -171,11 +171,16 @@ namespace GreenshotPlugin.UnmanagedHelpers {
/// </summary> /// </summary>
/// <param name="radius"></param> /// <param name="radius"></param>
/// <returns>false if blur is not possible</returns> /// <returns>false if blur is not possible</returns>
public static bool IsBlurPossible(int radius) { public static bool IsBlurPossible(int radius)
{
if (!_isBlurEnabled) { if (!_isBlurEnabled) {
return false; return false;
} }
return Environment.OSVersion.Version.Minor < 2 || radius >= 20; if (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor < 2)
{
return true;
}
return Environment.OSVersion.Version.Major > 6 && radius >= 20;
} }
/// <summary> /// <summary>

View file

@ -70,8 +70,11 @@ namespace GreenshotWin10Plugin
using (var logoStream = new MemoryRandomAccessStream()) using (var logoStream = new MemoryRandomAccessStream())
using (var thumbnailStream = new MemoryRandomAccessStream()) using (var thumbnailStream = new MemoryRandomAccessStream())
{ {
var outputSettings = new SurfaceOutputSettings();
outputSettings.PreventGreenshotFormat();
// Create capture for export // Create capture for export
ImageOutput.SaveToStream(surface, imageStream, new SurfaceOutputSettings()); ImageOutput.SaveToStream(surface, imageStream, outputSettings);
imageStream.Position = 0; imageStream.Position = 0;
Log.Info("Created RandomAccessStreamReference for the image"); Log.Info("Created RandomAccessStreamReference for the image");
var imageRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(imageStream); var imageRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(imageStream);
@ -83,7 +86,7 @@ namespace GreenshotWin10Plugin
{ {
using (var thumbnail = ImageHelper.CreateThumbnail(tmpImageForThumbnail, 240, 160)) using (var thumbnail = ImageHelper.CreateThumbnail(tmpImageForThumbnail, 240, 160))
{ {
ImageOutput.SaveToStream(thumbnail, null, thumbnailStream, new SurfaceOutputSettings()); ImageOutput.SaveToStream(thumbnail, null, thumbnailStream, outputSettings);
thumbnailStream.Position = 0; thumbnailStream.Position = 0;
thumbnailRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(thumbnailStream); thumbnailRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(thumbnailStream);
Log.Info("Created RandomAccessStreamReference for the thumbnail"); Log.Info("Created RandomAccessStreamReference for the thumbnail");
@ -94,7 +97,7 @@ namespace GreenshotWin10Plugin
{ {
using (var logoThumbnail = ImageHelper.CreateThumbnail(logo, 30, 30)) using (var logoThumbnail = ImageHelper.CreateThumbnail(logo, 30, 30))
{ {
ImageOutput.SaveToStream(logoThumbnail, null, logoStream, new SurfaceOutputSettings()); ImageOutput.SaveToStream(logoThumbnail, null, logoStream, outputSettings);
logoStream.Position = 0; logoStream.Position = 0;
logoRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(logoStream); logoRandomAccessStreamReference = RandomAccessStreamReference.CreateFromStream(logoStream);
Log.Info("Created RandomAccessStreamReference for the logo"); Log.Info("Created RandomAccessStreamReference for the logo");

View file

@ -1,7 +1,7 @@
version: 1.2.9.{build} version: 1.2.9.{build}
branches: branches:
only: only:
- release/1.2.9 - release/1.2.9BF2
skip_tags: true skip_tags: true
configuration: Release configuration: Release
platform: Any CPU platform: Any CPU
@ -38,7 +38,7 @@ environment:
secure: bjKXhFZkDqaq98XBrz5oQKQfT8CLpuv2ZAiBIwkzloaAPUs97b5yx6h/xFaE4NLS secure: bjKXhFZkDqaq98XBrz5oQKQfT8CLpuv2ZAiBIwkzloaAPUs97b5yx6h/xFaE4NLS
credentials_picasa_consumer_secret: credentials_picasa_consumer_secret:
secure: yNptTpmJWypbu9alOQtetxU66drr2FKxoPflNgRJdag= secure: yNptTpmJWypbu9alOQtetxU66drr2FKxoPflNgRJdag=
build_type: UNSTABLE build_type: RELEASE
rsakey: rsakey:
secure: GNomwdlwZOCyd8d7xEWTnMVs1lpOeHvF+tlnvcbXGovLRtwAp2Ufu0r7paGY7BHGGkIs2WE7xUfyQ9UauVB+58JZ6fwVega8ucUgVJhl4x0QQNN2d6sULUhHfhuEHmxw+FDO/FxKFE6Lmf+ZRY+OGiw0wKIl4qD7mGRHcDQTipNEsTbau8HzqRVCdu3dx7pODC61DlsbO71xLF7UlqnmuZE+91Zz3V6AgaqE246n1499d6bXBYw1AH+8opNnKDFLnTHf7hUVcZn9mj6tKZXeTCuVUOr/SVQcgHKxlBlqzhfaEkxCR5GPtzQRqwDMxEycmFvj2wNP/sie6UEGhQxE4YMCc2OgqNOkpc5BbP/fxLr/SLFOEf1XXzTWCFMhsgpHx7TZbgQH26sa0rK/xaBRacZlwAaNk7V2nFZT7TebYEFy6zWNr9Y+IyeXIofj42XQTNXv8d8hyh+UYLByVEFYRf2DnActQkZQyNdWjZ+CxDV50QSZZs8FT3IIqraHYKsj2ITAN5LrUtWCi7bpNJL0UGo0EJiB2i0bp++tEAAwyrCljxI8d4bbGl/flHk/xd+ysQPnomndijeObjguEzqT8pyXZluSZhF+lI50mIDhMdtdAfMi5yn5RW7P6NWOSlC8xgQQgMZylsuSvRflKbEd/gsoDyEOnakNcdH2jekt9OD6GnuYM7iHkbMC89LBZ0VaHNGvCC+BQXdGUG7O9R3NthZcDXE7q7xbtGRB5ncVQDRfKoT5HVfiV6bSDrcfRODiuR59mZgiSYtZG+3kQWYUKn2wagvZKckGukA0SlOuTRCKZhgLcVHhWeRWeGE3iJ8K6BeHf2EgB8Qr6ayTyTUjBcn+u4qqWKgkvG4qRavlvrBSdMrAXWIKE8vSq1od0A2ZzP6+HCsrkuUR+HFfpE2dpjeckoa5vATQgyn8j5x11iIOB9HnT3YKbZ0aTU4rQgYMJXA/fPcgKDGkAPdgtGbQLssy/mwSdsXBYtMgEcs7vI9laR8Ik+NK2dbFHGFPnxS43WToGyKBxojt8SZbgPJXm22WRrN1+9AZvvhI7/mpZiEE7HWgNRClZYuqbfCMpelLGvVq832OLjelrWMJ0XBVNHnOw0p8qZKI1UpqQJXX1nL8j3JttEVHsfryIanM03kNDL0dX1VAKECKUMCVQ6i6tG4VWsR0C2JccPJ3PSoPgo5KMJhuZNaBoiPjZ2eaMREV6vUYbBYzrvdDQzUcE2stacREl4eJzGJ4GP5h08GQmIirGF/SCyZV1CadAbKZVjqb70XpIbE6NT/+84O82LZR4ui5KgTAv87lTZgvNJ7LxM7rRg1awj/iBxQeARNJxuPMPlk1CVx8Z3091UdL1K1avPKa85lCRwCkDKLcJPO9tlqi4dVjCrwpoCJkQMm3fbTl/BgHn00/RsnFZ2qfl5m2DyF+XuaOPauzsRdLUFAC4h44qoUuzRb4Pv6RFhN5CI4fddRKafNBHU9f69UCkO080/hIjTdj0+bpr4oNY4UEi80huyJY/c0iUPE8o48qBB8F3cW30SwhPmuphn4/18lB8GEwEPqoatmli4QRaDFUCUf9Hj0DEUqEAya/OHOW7/PvWcw/l/ZaIMUpOZ6q0xvPDAXokFRJAWzZhG7hNbWNEzQ3f/BjlYlYsBtMY0JUU8mH6YxwIzIGbHiLTBC0OglH0rDd5W+3NaUG9FZ//o9MAP5j2QqwSuFWXppbigh4zk+h17eJn5zhld7dtvOr+YmgYULj6NFIDKBZHUJdqLYScVzdc1p812FCCBcLmmw4RnwuF+RldHixTdy4UZ17T/hD4OLpWCINl9lUAficC0OFeLJLHxFW6Em8SCbZ3aUtFDIQD8oTqzUHZhGWYF2ukrOc8Dzm4FQ8xy3BhqfntTod1gwoilIirsP/z+GGMnTltkqiqK+gCmkVOfICwNFmHltZeJrmDQ4YU5abR09Yr1TaAk3CzWjV1XGBaf/oek0+tFkMOtZNdFRdlzLLE90PsZZFFnZhFBoNoOhYnMB9K2VqgEpJs0nXvF6qBOllptcpBYUYMzMdb0Ggu6m1d/phxuBuOsm+Xtr0Zw8Xd0vxIOQNDGsskCDIEUYWYajw2i66MmRPRyFEennXfLA0WIPpztXvfsrKjf42rjE3RukBsRff1Sci68cel4fGfmvj2y7gW0Tt secure: GNomwdlwZOCyd8d7xEWTnMVs1lpOeHvF+tlnvcbXGovLRtwAp2Ufu0r7paGY7BHGGkIs2WE7xUfyQ9UauVB+58JZ6fwVega8ucUgVJhl4x0QQNN2d6sULUhHfhuEHmxw+FDO/FxKFE6Lmf+ZRY+OGiw0wKIl4qD7mGRHcDQTipNEsTbau8HzqRVCdu3dx7pODC61DlsbO71xLF7UlqnmuZE+91Zz3V6AgaqE246n1499d6bXBYw1AH+8opNnKDFLnTHf7hUVcZn9mj6tKZXeTCuVUOr/SVQcgHKxlBlqzhfaEkxCR5GPtzQRqwDMxEycmFvj2wNP/sie6UEGhQxE4YMCc2OgqNOkpc5BbP/fxLr/SLFOEf1XXzTWCFMhsgpHx7TZbgQH26sa0rK/xaBRacZlwAaNk7V2nFZT7TebYEFy6zWNr9Y+IyeXIofj42XQTNXv8d8hyh+UYLByVEFYRf2DnActQkZQyNdWjZ+CxDV50QSZZs8FT3IIqraHYKsj2ITAN5LrUtWCi7bpNJL0UGo0EJiB2i0bp++tEAAwyrCljxI8d4bbGl/flHk/xd+ysQPnomndijeObjguEzqT8pyXZluSZhF+lI50mIDhMdtdAfMi5yn5RW7P6NWOSlC8xgQQgMZylsuSvRflKbEd/gsoDyEOnakNcdH2jekt9OD6GnuYM7iHkbMC89LBZ0VaHNGvCC+BQXdGUG7O9R3NthZcDXE7q7xbtGRB5ncVQDRfKoT5HVfiV6bSDrcfRODiuR59mZgiSYtZG+3kQWYUKn2wagvZKckGukA0SlOuTRCKZhgLcVHhWeRWeGE3iJ8K6BeHf2EgB8Qr6ayTyTUjBcn+u4qqWKgkvG4qRavlvrBSdMrAXWIKE8vSq1od0A2ZzP6+HCsrkuUR+HFfpE2dpjeckoa5vATQgyn8j5x11iIOB9HnT3YKbZ0aTU4rQgYMJXA/fPcgKDGkAPdgtGbQLssy/mwSdsXBYtMgEcs7vI9laR8Ik+NK2dbFHGFPnxS43WToGyKBxojt8SZbgPJXm22WRrN1+9AZvvhI7/mpZiEE7HWgNRClZYuqbfCMpelLGvVq832OLjelrWMJ0XBVNHnOw0p8qZKI1UpqQJXX1nL8j3JttEVHsfryIanM03kNDL0dX1VAKECKUMCVQ6i6tG4VWsR0C2JccPJ3PSoPgo5KMJhuZNaBoiPjZ2eaMREV6vUYbBYzrvdDQzUcE2stacREl4eJzGJ4GP5h08GQmIirGF/SCyZV1CadAbKZVjqb70XpIbE6NT/+84O82LZR4ui5KgTAv87lTZgvNJ7LxM7rRg1awj/iBxQeARNJxuPMPlk1CVx8Z3091UdL1K1avPKa85lCRwCkDKLcJPO9tlqi4dVjCrwpoCJkQMm3fbTl/BgHn00/RsnFZ2qfl5m2DyF+XuaOPauzsRdLUFAC4h44qoUuzRb4Pv6RFhN5CI4fddRKafNBHU9f69UCkO080/hIjTdj0+bpr4oNY4UEi80huyJY/c0iUPE8o48qBB8F3cW30SwhPmuphn4/18lB8GEwEPqoatmli4QRaDFUCUf9Hj0DEUqEAya/OHOW7/PvWcw/l/ZaIMUpOZ6q0xvPDAXokFRJAWzZhG7hNbWNEzQ3f/BjlYlYsBtMY0JUU8mH6YxwIzIGbHiLTBC0OglH0rDd5W+3NaUG9FZ//o9MAP5j2QqwSuFWXppbigh4zk+h17eJn5zhld7dtvOr+YmgYULj6NFIDKBZHUJdqLYScVzdc1p812FCCBcLmmw4RnwuF+RldHixTdy4UZ17T/hD4OLpWCINl9lUAficC0OFeLJLHxFW6Em8SCbZ3aUtFDIQD8oTqzUHZhGWYF2ukrOc8Dzm4FQ8xy3BhqfntTod1gwoilIirsP/z+GGMnTltkqiqK+gCmkVOfICwNFmHltZeJrmDQ4YU5abR09Yr1TaAk3CzWjV1XGBaf/oek0+tFkMOtZNdFRdlzLLE90PsZZFFnZhFBoNoOhYnMB9K2VqgEpJs0nXvF6qBOllptcpBYUYMzMdb0Ggu6m1d/phxuBuOsm+Xtr0Zw8Xd0vxIOQNDGsskCDIEUYWYajw2i66MmRPRyFEennXfLA0WIPpztXvfsrKjf42rjE3RukBsRff1Sci68cel4fGfmvj2y7gW0Tt
before_build: before_build: