mirror of
https://github.com/greenshot/greenshot
synced 2025-07-15 01:23:47 -07:00
Code formatting (indents etc.) to get it consistent, simplify it for contributors.
This commit is contained in:
parent
726644de99
commit
e8c0b307ee
435 changed files with 46647 additions and 39014 deletions
|
@ -25,12 +25,14 @@ using Greenshot.Plugin.Box.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box {
|
namespace Greenshot.Plugin.Box
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImgurConfiguration.
|
/// Description of ImgurConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Box", Description = "Greenshot Box Plugin configuration")]
|
[IniSection("Box", Description = "Greenshot Box Plugin configuration")]
|
||||||
public class BoxConfiguration : IniSection {
|
public class BoxConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat { get; set; }
|
public OutputFormat UploadFormat { get; set; }
|
||||||
|
|
||||||
|
@ -42,6 +44,7 @@ namespace Greenshot.Plugin.Box {
|
||||||
|
|
||||||
[IniProperty("UseSharedLink", Description = "Use the shared link, instead of the private, on the clipboard", DefaultValue = "True")]
|
[IniProperty("UseSharedLink", Description = "Use the shared link, instead of the private, on the clipboard", DefaultValue = "True")]
|
||||||
public bool UseSharedLink { get; set; }
|
public bool UseSharedLink { get; set; }
|
||||||
|
|
||||||
[IniProperty("FolderId", Description = "Folder ID to upload to, only change if you know what you are doing!", DefaultValue = "0")]
|
[IniProperty("FolderId", Description = "Folder ID to upload to, only change if you know what you are doing!", DefaultValue = "0")]
|
||||||
public string FolderId { get; set; }
|
public string FolderId { get; set; }
|
||||||
|
|
||||||
|
@ -51,30 +54,26 @@ namespace Greenshot.Plugin.Box {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not stored
|
/// Not stored
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AccessToken {
|
public string AccessToken { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not stored
|
/// Not stored
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset AccessTokenExpires {
|
public DateTimeOffset AccessTokenExpires { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A form for token
|
/// A form for token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog()
|
||||||
|
{
|
||||||
DialogResult result = new SettingsForm().ShowDialog();
|
DialogResult result = new SettingsForm().ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,10 +24,14 @@ using System.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box {
|
namespace Greenshot.Plugin.Box
|
||||||
public class BoxDestination : AbstractDestination {
|
{
|
||||||
|
public class BoxDestination : AbstractDestination
|
||||||
|
{
|
||||||
private readonly BoxPlugin _plugin;
|
private readonly BoxPlugin _plugin;
|
||||||
public BoxDestination(BoxPlugin plugin) {
|
|
||||||
|
public BoxDestination(BoxPlugin plugin)
|
||||||
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,20 +39,25 @@ namespace Greenshot.Plugin.Box {
|
||||||
|
|
||||||
public override string Description => Language.GetString("box", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("box", LangKey.upload_menu_item);
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(BoxPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(BoxPlugin));
|
||||||
return (Image) resources.GetObject("Box");
|
return (Image) resources.GetObject("Box");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
string uploadUrl = _plugin.Upload(captureDetails, surface);
|
string uploadUrl = _plugin.Upload(captureDetails, surface);
|
||||||
if (uploadUrl != null) {
|
if (uploadUrl != null)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,39 +22,35 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Runtime.Serialization;
|
using System.Runtime.Serialization;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box {
|
namespace Greenshot.Plugin.Box
|
||||||
|
{
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class Authorization {
|
public class Authorization
|
||||||
[DataMember(Name = "access_token")]
|
{
|
||||||
public string AccessToken { get; set; }
|
[DataMember(Name = "access_token")] public string AccessToken { get; set; }
|
||||||
[DataMember(Name = "expires_in")]
|
[DataMember(Name = "expires_in")] public int ExpiresIn { get; set; }
|
||||||
public int ExpiresIn { get; set; }
|
[DataMember(Name = "refresh_token")] public string RefreshToken { get; set; }
|
||||||
[DataMember(Name = "refresh_token")]
|
[DataMember(Name = "token_type")] public string TokenType { get; set; }
|
||||||
public string RefreshToken { get; set; }
|
|
||||||
[DataMember(Name = "token_type")]
|
|
||||||
public string TokenType { get; set; }
|
|
||||||
}
|
|
||||||
[DataContract]
|
|
||||||
public class SharedLink {
|
|
||||||
[DataMember(Name = "url")]
|
|
||||||
public string Url { get; set; }
|
|
||||||
[DataMember(Name = "download_url")]
|
|
||||||
public string DownloadUrl { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class FileEntry {
|
public class SharedLink
|
||||||
[DataMember(Name = "id")]
|
{
|
||||||
public string Id { get; set; }
|
[DataMember(Name = "url")] public string Url { get; set; }
|
||||||
[DataMember(Name = "name")]
|
[DataMember(Name = "download_url")] public string DownloadUrl { get; set; }
|
||||||
public string Name { get; set; }
|
|
||||||
[DataMember(Name = "shared_link")]
|
|
||||||
public SharedLink SharedLink { get; set; }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[DataContract]
|
[DataContract]
|
||||||
public class Upload {
|
public class FileEntry
|
||||||
[DataMember(Name = "entries")]
|
{
|
||||||
public List<FileEntry> Entries { get; set; }
|
[DataMember(Name = "id")] public string Id { get; set; }
|
||||||
|
[DataMember(Name = "name")] public string Name { get; set; }
|
||||||
|
[DataMember(Name = "shared_link")] public SharedLink SharedLink { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
[DataContract]
|
||||||
|
public class Upload
|
||||||
|
{
|
||||||
|
[DataMember(Name = "entries")] public List<FileEntry> Entries { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -30,18 +30,21 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box {
|
namespace Greenshot.Plugin.Box
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the Box base code
|
/// This is the Box base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Box", true)]
|
[Plugin("Box", true)]
|
||||||
public class BoxPlugin : IGreenshotPlugin {
|
public class BoxPlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxPlugin));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(BoxPlugin));
|
||||||
private static BoxConfiguration _config;
|
private static BoxConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _itemPlugInConfig;
|
private ToolStripMenuItem _itemPlugInConfig;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
@ -59,13 +62,14 @@ namespace Greenshot.Plugin.Box {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<BoxConfiguration>();
|
_config = IniConfig.GetIniSection<BoxConfiguration>();
|
||||||
_resources = new ComponentResourceManager(typeof(BoxPlugin));
|
_resources = new ComponentResourceManager(typeof(BoxPlugin));
|
||||||
SimpleServiceProvider.Current.AddService<IDestination>(new BoxDestination(this));
|
SimpleServiceProvider.Current.AddService<IDestination>(new BoxDestination(this));
|
||||||
_itemPlugInConfig = new ToolStripMenuItem {
|
_itemPlugInConfig = new ToolStripMenuItem
|
||||||
|
{
|
||||||
Image = (Image) _resources.GetObject("Box"),
|
Image = (Image) _resources.GetObject("Box"),
|
||||||
Text = Language.GetString("box", LangKey.Configure)
|
Text = Language.GetString("box", LangKey.Configure)
|
||||||
};
|
};
|
||||||
|
@ -76,49 +80,57 @@ namespace Greenshot.Plugin.Box {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLanguageChanged(object sender, EventArgs e) {
|
public void OnLanguageChanged(object sender, EventArgs e)
|
||||||
if (_itemPlugInConfig != null) {
|
{
|
||||||
|
if (_itemPlugInConfig != null)
|
||||||
|
{
|
||||||
_itemPlugInConfig.Text = Language.GetString("box", LangKey.Configure);
|
_itemPlugInConfig.Text = Language.GetString("box", LangKey.Configure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
LOG.Debug("Box Plugin shutdown.");
|
LOG.Debug("Box Plugin shutdown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
public void ConfigMenuClick(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This will be called when the menu item in the Editor is clicked
|
/// This will be called when the menu item in the Editor is clicked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload) {
|
public string Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload)
|
||||||
|
{
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
string url = null;
|
string url = null;
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
||||||
SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
SurfaceContainer imageToUpload = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
||||||
|
|
||||||
new PleaseWaitForm().ShowAndWait("Box", Language.GetString("box", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait("Box", Language.GetString("box", LangKey.communication_wait),
|
||||||
delegate {
|
delegate { url = BoxUtils.UploadToBox(imageToUpload, captureDetails.Title, filename); }
|
||||||
url = BoxUtils.UploadToBox(imageToUpload, captureDetails.Title, filename);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (url != null && _config.AfterUploadLinkToClipBoard) {
|
if (url != null && _config.AfterUploadLinkToClipBoard)
|
||||||
|
{
|
||||||
ClipboardHelper.SetClipboardData(url);
|
ClipboardHelper.SetClipboardData(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.Error("Error uploading.", ex);
|
LOG.Error("Error uploading.", ex);
|
||||||
MessageBox.Show(Language.GetString("box", LangKey.upload_failure) + " " + ex.Message);
|
MessageBox.Show(Language.GetString("box", LangKey.upload_failure) + " " + ex.Message);
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -27,12 +27,13 @@ using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Core.OAuth;
|
using GreenshotPlugin.Core.OAuth;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box {
|
namespace Greenshot.Plugin.Box
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of BoxUtils.
|
/// Description of BoxUtils.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class BoxUtils {
|
public static class BoxUtils
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(BoxUtils));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(BoxUtils));
|
||||||
private static readonly BoxConfiguration Config = IniConfig.GetIniSection<BoxConfiguration>();
|
private static readonly BoxConfiguration Config = IniConfig.GetIniSection<BoxConfiguration>();
|
||||||
private const string UploadFileUri = "https://upload.box.com/api/2.0/files/content";
|
private const string UploadFileUri = "https://upload.box.com/api/2.0/files/content";
|
||||||
|
@ -45,13 +46,16 @@ namespace Greenshot.Plugin.Box {
|
||||||
/// <param name="content"></param>
|
/// <param name="content"></param>
|
||||||
/// <param name="settings">OAuth2Settings</param>
|
/// <param name="settings">OAuth2Settings</param>
|
||||||
/// <returns>response</returns>
|
/// <returns>response</returns>
|
||||||
public static string HttpPut(string url, string content, OAuth2Settings settings) {
|
public static string HttpPut(string url, string content, OAuth2Settings settings)
|
||||||
|
{
|
||||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.PUT, url, settings);
|
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.PUT, url, settings);
|
||||||
|
|
||||||
byte[] data = Encoding.UTF8.GetBytes(content);
|
byte[] data = Encoding.UTF8.GetBytes(content);
|
||||||
using (var requestStream = webRequest.GetRequestStream()) {
|
using (var requestStream = webRequest.GetRequestStream())
|
||||||
|
{
|
||||||
requestStream.Write(data, 0, data.Length);
|
requestStream.Write(data, 0, data.Length);
|
||||||
}
|
}
|
||||||
|
|
||||||
return NetworkHelper.GetResponseAsString(webRequest);
|
return NetworkHelper.GetResponseAsString(webRequest);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,8 +67,8 @@ namespace Greenshot.Plugin.Box {
|
||||||
/// <param name="title">Title of box upload</param>
|
/// <param name="title">Title of box upload</param>
|
||||||
/// <param name="filename">Filename of box upload</param>
|
/// <param name="filename">Filename of box upload</param>
|
||||||
/// <returns>url to uploaded image</returns>
|
/// <returns>url to uploaded image</returns>
|
||||||
public static string UploadToBox(SurfaceContainer image, string title, string filename) {
|
public static string UploadToBox(SurfaceContainer image, string title, string filename)
|
||||||
|
{
|
||||||
// Fill the OAuth2Settings
|
// Fill the OAuth2Settings
|
||||||
var settings = new OAuth2Settings
|
var settings = new OAuth2Settings
|
||||||
{
|
{
|
||||||
|
@ -83,12 +87,17 @@ namespace Greenshot.Plugin.Box {
|
||||||
|
|
||||||
// Copy the settings from the config, which is kept in memory and on the disk
|
// Copy the settings from the config, which is kept in memory and on the disk
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, UploadFileUri, settings);
|
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, UploadFileUri, settings);
|
||||||
IDictionary<string, object> parameters = new Dictionary<string, object>
|
IDictionary<string, object> parameters = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "file", image },
|
{
|
||||||
{ "parent_id", Config.FolderId }
|
"file", image
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parent_id", Config.FolderId
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
NetworkHelper.WriteMultipartFormData(webRequest, parameters);
|
NetworkHelper.WriteMultipartFormData(webRequest, parameters);
|
||||||
|
@ -100,13 +109,17 @@ namespace Greenshot.Plugin.Box {
|
||||||
var upload = JsonSerializer.Deserialize<Upload>(response);
|
var upload = JsonSerializer.Deserialize<Upload>(response);
|
||||||
if (upload?.Entries == null || upload.Entries.Count == 0) return null;
|
if (upload?.Entries == null || upload.Entries.Count == 0) return null;
|
||||||
|
|
||||||
if (Config.UseSharedLink) {
|
if (Config.UseSharedLink)
|
||||||
|
{
|
||||||
string filesResponse = HttpPut(string.Format(FilesUri, upload.Entries[0].Id), "{\"shared_link\": {\"access\": \"open\"}}", settings);
|
string filesResponse = HttpPut(string.Format(FilesUri, upload.Entries[0].Id), "{\"shared_link\": {\"access\": \"open\"}}", settings);
|
||||||
var file = JsonSerializer.Deserialize<FileEntry>(filesResponse);
|
var file = JsonSerializer.Deserialize<FileEntry>(filesResponse);
|
||||||
return file.SharedLink.Url;
|
return file.SharedLink.Url;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"http://www.box.com/files/0/f/0/1/f_{upload.Entries[0].Id}";
|
return $"http://www.box.com/files/0/f/0/1/f_{upload.Entries[0].Id}";
|
||||||
} finally {
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
// Copy the settings back to the config, so they are stored.
|
// Copy the settings back to the config, so they are stored.
|
||||||
Config.RefreshToken = settings.RefreshToken;
|
Config.RefreshToken = settings.RefreshToken;
|
||||||
Config.AccessToken = settings.AccessToken;
|
Config.AccessToken = settings.AccessToken;
|
||||||
|
@ -116,17 +129,20 @@ namespace Greenshot.Plugin.Box {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A simple helper class for the DataContractJsonSerializer
|
/// A simple helper class for the DataContractJsonSerializer
|
||||||
/// </summary>
|
/// </summary>
|
||||||
internal static class JsonSerializer {
|
internal static class JsonSerializer
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Helper method to parse JSON to object
|
/// Helper method to parse JSON to object
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <typeparam name="T"></typeparam>
|
/// <typeparam name="T"></typeparam>
|
||||||
/// <param name="jsonString"></param>
|
/// <param name="jsonString"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static T Deserialize<T>(string jsonString) {
|
public static T Deserialize<T>(string jsonString)
|
||||||
|
{
|
||||||
var deserializer = new DataContractJsonSerializer(typeof(T));
|
var deserializer = new DataContractJsonSerializer(typeof(T));
|
||||||
using var stream = new MemoryStream();
|
using var stream = new MemoryStream();
|
||||||
byte[] content = Encoding.UTF8.GetBytes(jsonString);
|
byte[] content = Encoding.UTF8.GetBytes(jsonString);
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box.Forms {
|
namespace Greenshot.Plugin.Box.Forms
|
||||||
public class BoxForm : GreenshotForm {
|
{
|
||||||
|
public class BoxForm : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,12 +19,15 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Box.Forms {
|
namespace Greenshot.Plugin.Box.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : BoxForm {
|
public partial class SettingsForm : BoxForm
|
||||||
public SettingsForm() {
|
{
|
||||||
|
public SettingsForm()
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
//
|
//
|
||||||
|
|
|
@ -18,8 +18,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
namespace Greenshot.Plugin.Box {
|
|
||||||
public enum LangKey {
|
namespace Greenshot.Plugin.Box
|
||||||
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
upload_failure,
|
upload_failure,
|
||||||
communication_wait,
|
communication_wait,
|
||||||
|
|
|
@ -26,16 +26,21 @@ using GreenshotConfluencePlugin.confluence;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
public class Page {
|
{
|
||||||
public Page(RemotePage page) {
|
public class Page
|
||||||
|
{
|
||||||
|
public Page(RemotePage page)
|
||||||
|
{
|
||||||
Id = page.id;
|
Id = page.id;
|
||||||
Title = page.title;
|
Title = page.title;
|
||||||
SpaceKey = page.space;
|
SpaceKey = page.space;
|
||||||
Url = page.url;
|
Url = page.url;
|
||||||
Content = page.content;
|
Content = page.content;
|
||||||
}
|
}
|
||||||
public Page(RemoteSearchResult searchResult, string space) {
|
|
||||||
|
public Page(RemoteSearchResult searchResult, string space)
|
||||||
|
{
|
||||||
Id = searchResult.id;
|
Id = searchResult.id;
|
||||||
Title = searchResult.title;
|
Title = searchResult.title;
|
||||||
SpaceKey = space;
|
SpaceKey = space;
|
||||||
|
@ -43,53 +48,39 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
Content = searchResult.excerpt;
|
Content = searchResult.excerpt;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Page(RemotePageSummary pageSummary) {
|
public Page(RemotePageSummary pageSummary)
|
||||||
|
{
|
||||||
Id = pageSummary.id;
|
Id = pageSummary.id;
|
||||||
Title = pageSummary.title;
|
Title = pageSummary.title;
|
||||||
SpaceKey = pageSummary.space;
|
SpaceKey = pageSummary.space;
|
||||||
Url = pageSummary.url;
|
Url = pageSummary.url;
|
||||||
}
|
}
|
||||||
public long Id {
|
|
||||||
get;
|
public long Id { get; set; }
|
||||||
set;
|
public string Title { get; set; }
|
||||||
|
public string Url { get; set; }
|
||||||
|
public string Content { get; set; }
|
||||||
|
public string SpaceKey { get; set; }
|
||||||
}
|
}
|
||||||
public string Title {
|
|
||||||
get;
|
public class Space
|
||||||
set;
|
{
|
||||||
}
|
public Space(RemoteSpaceSummary space)
|
||||||
public string Url {
|
{
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
public string Content {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
public string SpaceKey {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
public class Space {
|
|
||||||
public Space(RemoteSpaceSummary space) {
|
|
||||||
Key = space.key;
|
Key = space.key;
|
||||||
Name = space.name;
|
Name = space.name;
|
||||||
}
|
}
|
||||||
public string Key {
|
|
||||||
get;
|
public string Key { get; set; }
|
||||||
set;
|
public string Name { get; set; }
|
||||||
}
|
|
||||||
public string Name {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// For details see the Confluence API site
|
/// For details see the Confluence API site
|
||||||
/// See: http://confluence.atlassian.com/display/CONFDEV/Remote+API+Specification
|
/// See: http://confluence.atlassian.com/display/CONFDEV/Remote+API+Specification
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConfluenceConnector : IDisposable {
|
public class ConfluenceConnector : IDisposable
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ConfluenceConnector));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ConfluenceConnector));
|
||||||
private const string AuthFailedExceptionName = "com.atlassian.confluence.rpc.AuthenticationFailedException";
|
private const string AuthFailedExceptionName = "com.atlassian.confluence.rpc.AuthenticationFailedException";
|
||||||
private const string V2Failed = "AXIS";
|
private const string V2Failed = "AXIS";
|
||||||
|
@ -102,29 +93,37 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
private string _url;
|
private string _url;
|
||||||
private readonly Cache<string, RemotePage> _pageCache = new Cache<string, RemotePage>(60 * Config.Timeout);
|
private readonly Cache<string, RemotePage> _pageCache = new Cache<string, RemotePage>(60 * Config.Timeout);
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
protected void Dispose(bool disposing)
|
||||||
if (_confluence != null) {
|
{
|
||||||
|
if (_confluence != null)
|
||||||
|
{
|
||||||
Logout();
|
Logout();
|
||||||
}
|
}
|
||||||
if (disposing) {
|
|
||||||
if (_confluence != null) {
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (_confluence != null)
|
||||||
|
{
|
||||||
_confluence.Dispose();
|
_confluence.Dispose();
|
||||||
_confluence = null;
|
_confluence = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfluenceConnector(string url, int timeout) {
|
public ConfluenceConnector(string url, int timeout)
|
||||||
|
{
|
||||||
_timeout = timeout;
|
_timeout = timeout;
|
||||||
Init(url);
|
Init(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Init(string url) {
|
private void Init(string url)
|
||||||
|
{
|
||||||
_url = url;
|
_url = url;
|
||||||
_confluence = new ConfluenceSoapServiceService
|
_confluence = new ConfluenceSoapServiceService
|
||||||
{
|
{
|
||||||
|
@ -133,7 +132,8 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
~ConfluenceConnector() {
|
~ConfluenceConnector()
|
||||||
|
{
|
||||||
Dispose(false);
|
Dispose(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,21 +141,29 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
/// 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 bool DoLogin(string user, string password) {
|
private bool DoLogin(string user, string password)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
_credentials = _confluence.login(user, password);
|
_credentials = _confluence.login(user, password);
|
||||||
_loggedInTime = DateTime.Now;
|
_loggedInTime = DateTime.Now;
|
||||||
_loggedIn = true;
|
_loggedIn = true;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
// Check if confluence-v2 caused an error, use v1 instead
|
// Check if confluence-v2 caused an error, use v1 instead
|
||||||
if (e.Message.Contains(V2Failed) && _url.Contains("v2")) {
|
if (e.Message.Contains(V2Failed) && _url.Contains("v2"))
|
||||||
|
{
|
||||||
Init(_url.Replace("v2", "v1"));
|
Init(_url.Replace("v2", "v1"));
|
||||||
return DoLogin(user, password);
|
return DoLogin(user, password);
|
||||||
}
|
}
|
||||||
|
|
||||||
// check if auth failed
|
// check if auth failed
|
||||||
if (e.Message.Contains(AuthFailedExceptionName)) {
|
if (e.Message.Contains(AuthFailedExceptionName))
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not an authentication issue
|
// Not an authentication issue
|
||||||
_loggedIn = false;
|
_loggedIn = false;
|
||||||
_credentials = null;
|
_credentials = null;
|
||||||
|
@ -163,12 +171,15 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
e.Data.Add("url", _url);
|
e.Data.Add("url", _url);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Login() {
|
public void Login()
|
||||||
|
{
|
||||||
Logout();
|
Logout();
|
||||||
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
|
||||||
string systemName = _url.Replace(ConfluenceConfiguration.DEFAULT_POSTFIX1, "");
|
string systemName = _url.Replace(ConfluenceConfiguration.DEFAULT_POSTFIX1, "");
|
||||||
systemName = systemName.Replace(ConfluenceConfiguration.DEFAULT_POSTFIX2, "");
|
systemName = systemName.Replace(ConfluenceConfiguration.DEFAULT_POSTFIX2, "");
|
||||||
|
@ -176,53 +187,73 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
{
|
{
|
||||||
Name = null
|
Name = null
|
||||||
};
|
};
|
||||||
while (dialog.Show(dialog.Name) == DialogResult.OK) {
|
while (dialog.Show(dialog.Name) == DialogResult.OK)
|
||||||
if (DoLogin(dialog.Name, dialog.Password)) {
|
{
|
||||||
if (dialog.SaveChecked) {
|
if (DoLogin(dialog.Name, dialog.Password))
|
||||||
|
{
|
||||||
|
if (dialog.SaveChecked)
|
||||||
|
{
|
||||||
dialog.Confirm(true);
|
dialog.Confirm(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
} else {
|
}
|
||||||
try {
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
dialog.Confirm(false);
|
dialog.Confirm(false);
|
||||||
} catch (ApplicationException e) {
|
}
|
||||||
|
catch (ApplicationException e)
|
||||||
|
{
|
||||||
// exception handling ...
|
// exception handling ...
|
||||||
Log.Error("Problem using the credentials dialog", e);
|
Log.Error("Problem using the credentials dialog", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For every windows version after XP show an incorrect password baloon
|
// For every windows version after XP show an incorrect password baloon
|
||||||
dialog.IncorrectPassword = true;
|
dialog.IncorrectPassword = true;
|
||||||
// Make sure the dialog is display, the password was false!
|
// Make sure the dialog is display, the password was false!
|
||||||
dialog.AlwaysDisplay = true;
|
dialog.AlwaysDisplay = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (ApplicationException e) {
|
}
|
||||||
|
catch (ApplicationException e)
|
||||||
|
{
|
||||||
// exception handling ...
|
// exception handling ...
|
||||||
Log.Error("Problem using the credentials dialog", e);
|
Log.Error("Problem using the credentials dialog", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Logout() {
|
public void Logout()
|
||||||
if (_credentials != null) {
|
{
|
||||||
|
if (_credentials != null)
|
||||||
|
{
|
||||||
_confluence.logout(_credentials);
|
_confluence.logout(_credentials);
|
||||||
_credentials = null;
|
_credentials = null;
|
||||||
_loggedIn = false;
|
_loggedIn = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void CheckCredentials() {
|
private void CheckCredentials()
|
||||||
if (_loggedIn) {
|
{
|
||||||
if (_loggedInTime.AddMinutes(_timeout-1).CompareTo(DateTime.Now) < 0) {
|
if (_loggedIn)
|
||||||
|
{
|
||||||
|
if (_loggedInTime.AddMinutes(_timeout - 1).CompareTo(DateTime.Now) < 0)
|
||||||
|
{
|
||||||
Logout();
|
Logout();
|
||||||
Login();
|
Login();
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Login();
|
Login();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsLoggedIn => _loggedIn;
|
public bool IsLoggedIn => _loggedIn;
|
||||||
|
|
||||||
public void AddAttachment(long pageId, string mime, string comment, string filename, IBinaryContainer image) {
|
public void AddAttachment(long pageId, string mime, string comment, string filename, IBinaryContainer image)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
// Comment is ignored, see: http://jira.atlassian.com/browse/CONF-9395
|
// Comment is ignored, see: http://jira.atlassian.com/browse/CONF-9395
|
||||||
var attachment = new RemoteAttachment
|
var attachment = new RemoteAttachment
|
||||||
|
@ -234,69 +265,88 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
_confluence.addAttachment(_credentials, pageId, attachment, image.ToByteArray());
|
_confluence.addAttachment(_credentials, pageId, attachment, image.ToByteArray());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Page GetPage(string spaceKey, string pageTitle) {
|
public Page GetPage(string spaceKey, string pageTitle)
|
||||||
|
{
|
||||||
RemotePage page = null;
|
RemotePage page = null;
|
||||||
string cacheKey = spaceKey + pageTitle;
|
string cacheKey = spaceKey + pageTitle;
|
||||||
if (_pageCache.Contains(cacheKey)) {
|
if (_pageCache.Contains(cacheKey))
|
||||||
|
{
|
||||||
page = _pageCache[cacheKey];
|
page = _pageCache[cacheKey];
|
||||||
}
|
}
|
||||||
if (page == null) {
|
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
page = _confluence.getPage(_credentials, spaceKey, pageTitle);
|
page = _confluence.getPage(_credentials, spaceKey, pageTitle);
|
||||||
_pageCache.Add(cacheKey, page);
|
_pageCache.Add(cacheKey, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Page(page);
|
return new Page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Page GetPage(long pageId) {
|
public Page GetPage(long pageId)
|
||||||
|
{
|
||||||
RemotePage page = null;
|
RemotePage page = null;
|
||||||
string cacheKey = pageId.ToString();
|
string cacheKey = pageId.ToString();
|
||||||
|
|
||||||
if (_pageCache.Contains(cacheKey)) {
|
if (_pageCache.Contains(cacheKey))
|
||||||
|
{
|
||||||
page = _pageCache[cacheKey];
|
page = _pageCache[cacheKey];
|
||||||
}
|
}
|
||||||
if (page == null) {
|
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
page = _confluence.getPage(_credentials, pageId);
|
page = _confluence.getPage(_credentials, pageId);
|
||||||
_pageCache.Add(cacheKey, page);
|
_pageCache.Add(cacheKey, page);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Page(page);
|
return new Page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Page GetSpaceHomepage(Space spaceSummary) {
|
public Page GetSpaceHomepage(Space spaceSummary)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
RemoteSpace spaceDetail = _confluence.getSpace(_credentials, spaceSummary.Key);
|
RemoteSpace spaceDetail = _confluence.getSpace(_credentials, spaceSummary.Key);
|
||||||
RemotePage page = _confluence.getPage(_credentials, spaceDetail.homePage);
|
RemotePage page = _confluence.getPage(_credentials, spaceDetail.homePage);
|
||||||
return new Page(page);
|
return new Page(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Space> GetSpaceSummaries() {
|
public IEnumerable<Space> GetSpaceSummaries()
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
RemoteSpaceSummary[] spaces = _confluence.getSpaces(_credentials);
|
RemoteSpaceSummary[] spaces = _confluence.getSpaces(_credentials);
|
||||||
foreach(RemoteSpaceSummary space in spaces) {
|
foreach (RemoteSpaceSummary space in spaces)
|
||||||
|
{
|
||||||
yield return new Space(space);
|
yield return new Space(space);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Page> GetPageChildren(Page parentPage) {
|
public IEnumerable<Page> GetPageChildren(Page parentPage)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
RemotePageSummary[] pages = _confluence.getChildren(_credentials, parentPage.Id);
|
RemotePageSummary[] pages = _confluence.getChildren(_credentials, parentPage.Id);
|
||||||
foreach(RemotePageSummary page in pages) {
|
foreach (RemotePageSummary page in pages)
|
||||||
|
{
|
||||||
yield return new Page(page);
|
yield return new Page(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Page> GetPageSummaries(Space space) {
|
public IEnumerable<Page> GetPageSummaries(Space space)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
RemotePageSummary[] pages = _confluence.getPages(_credentials, space.Key);
|
RemotePageSummary[] pages = _confluence.getPages(_credentials, space.Key);
|
||||||
foreach(RemotePageSummary page in pages) {
|
foreach (RemotePageSummary page in pages)
|
||||||
|
{
|
||||||
yield return new Page(page);
|
yield return new Page(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<Page> SearchPages(string query, string space) {
|
public IEnumerable<Page> SearchPages(string query, string space)
|
||||||
|
{
|
||||||
CheckCredentials();
|
CheckCredentials();
|
||||||
foreach(var searchResult in _confluence.search(_credentials, query, 20)) {
|
foreach (var searchResult in _confluence.search(_credentials, query, 20))
|
||||||
|
{
|
||||||
Log.DebugFormat("Got result of type {0}", searchResult.type);
|
Log.DebugFormat("Got result of type {0}", searchResult.type);
|
||||||
if ("page".Equals(searchResult.type))
|
if ("page".Equals(searchResult.type))
|
||||||
{
|
{
|
||||||
|
|
|
@ -23,63 +23,45 @@ using System;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ConfluenceConfiguration.
|
/// Description of ConfluenceConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Serializable]
|
[Serializable]
|
||||||
[IniSection("Confluence", Description = "Greenshot Confluence Plugin configuration")]
|
[IniSection("Confluence", Description = "Greenshot Confluence Plugin configuration")]
|
||||||
public class ConfluenceConfiguration : IniSection {
|
public class ConfluenceConfiguration : IniSection
|
||||||
|
{
|
||||||
public const string DEFAULT_POSTFIX1 = "/rpc/soap-axis/confluenceservice-v1?wsdl";
|
public const string DEFAULT_POSTFIX1 = "/rpc/soap-axis/confluenceservice-v1?wsdl";
|
||||||
public const string DEFAULT_POSTFIX2 = "/rpc/soap-axis/confluenceservice-v2?wsdl";
|
public const string DEFAULT_POSTFIX2 = "/rpc/soap-axis/confluenceservice-v2?wsdl";
|
||||||
public const string DEFAULT_PREFIX = "http://";
|
public const string DEFAULT_PREFIX = "http://";
|
||||||
private const string DEFAULT_URL = DEFAULT_PREFIX + "confluence";
|
private const string DEFAULT_URL = DEFAULT_PREFIX + "confluence";
|
||||||
|
|
||||||
[IniProperty("Url", Description = "Url to Confluence system, including wsdl.", DefaultValue = DEFAULT_URL)]
|
[IniProperty("Url", Description = "Url to Confluence system, including wsdl.", DefaultValue = DEFAULT_URL)]
|
||||||
public string Url {
|
public string Url { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("Timeout", Description = "Session timeout in minutes", DefaultValue = "30")]
|
[IniProperty("Timeout", Description = "Session timeout in minutes", DefaultValue = "30")]
|
||||||
public int Timeout {
|
public int Timeout { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat {
|
public OutputFormat UploadFormat { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("UploadJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
|
[IniProperty("UploadJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
|
||||||
public int UploadJpegQuality {
|
public int UploadJpegQuality { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("UploadReduceColors", Description = "Reduce color amount of the uploaded image to 256", DefaultValue = "False")]
|
[IniProperty("UploadReduceColors", Description = "Reduce color amount of the uploaded image to 256", DefaultValue = "False")]
|
||||||
public bool UploadReduceColors {
|
public bool UploadReduceColors { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("OpenPageAfterUpload", Description = "Open the page where the picture is uploaded after upload", DefaultValue = "True")]
|
[IniProperty("OpenPageAfterUpload", Description = "Open the page where the picture is uploaded after upload", DefaultValue = "True")]
|
||||||
public bool OpenPageAfterUpload {
|
public bool OpenPageAfterUpload { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("CopyWikiMarkupForImageToClipboard", Description = "Copy the Wikimarkup for the recently uploaded image to the Clipboard", DefaultValue = "True")]
|
[IniProperty("CopyWikiMarkupForImageToClipboard", Description = "Copy the Wikimarkup for the recently uploaded image to the Clipboard", DefaultValue = "True")]
|
||||||
public bool CopyWikiMarkupForImageToClipboard {
|
public bool CopyWikiMarkupForImageToClipboard { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("SearchSpaceKey", Description = "Key of last space that was searched for")]
|
[IniProperty("SearchSpaceKey", Description = "Key of last space that was searched for")]
|
||||||
public string SearchSpaceKey {
|
public string SearchSpaceKey { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
[IniProperty("IncludePersonSpaces", Description = "Include personal spaces in the search & browse spaces list", DefaultValue = "False")]
|
[IniProperty("IncludePersonSpaces", Description = "Include personal spaces in the search & browse spaces list", DefaultValue = "False")]
|
||||||
public bool IncludePersonSpaces {
|
public bool IncludePersonSpaces { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -32,121 +32,145 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ConfluenceDestination.
|
/// Description of ConfluenceDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConfluenceDestination : AbstractDestination {
|
public class ConfluenceDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ConfluenceDestination));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ConfluenceDestination));
|
||||||
private static readonly ConfluenceConfiguration ConfluenceConfig = IniConfig.GetIniSection<ConfluenceConfiguration>();
|
private static readonly ConfluenceConfiguration ConfluenceConfig = IniConfig.GetIniSection<ConfluenceConfiguration>();
|
||||||
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
private static readonly Image ConfluenceIcon;
|
private static readonly Image ConfluenceIcon;
|
||||||
private readonly Page _page;
|
private readonly Page _page;
|
||||||
|
|
||||||
static ConfluenceDestination() {
|
static ConfluenceDestination()
|
||||||
|
{
|
||||||
IsInitialized = false;
|
IsInitialized = false;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
Uri confluenceIconUri = new Uri("/GreenshotConfluencePlugin;component/Images/Confluence.ico", UriKind.Relative);
|
Uri confluenceIconUri = new Uri("/GreenshotConfluencePlugin;component/Images/Confluence.ico", UriKind.Relative);
|
||||||
using (Stream iconStream = Application.GetResourceStream(confluenceIconUri)?.Stream)
|
using (Stream iconStream = Application.GetResourceStream(confluenceIconUri)?.Stream)
|
||||||
{
|
{
|
||||||
// TODO: Check what to do with the IImage
|
// TODO: Check what to do with the IImage
|
||||||
ConfluenceIcon = ImageHelper.FromStream(iconStream);
|
ConfluenceIcon = ImageHelper.FromStream(iconStream);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsInitialized = true;
|
IsInitialized = true;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.ErrorFormat("Problem in the confluence static initializer: {0}", ex.Message);
|
Log.ErrorFormat("Problem in the confluence static initializer: {0}", ex.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool IsInitialized
|
public static bool IsInitialized { get; private set; }
|
||||||
|
|
||||||
|
public ConfluenceDestination()
|
||||||
{
|
{
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfluenceDestination() {
|
public ConfluenceDestination(Page page)
|
||||||
}
|
{
|
||||||
|
|
||||||
public ConfluenceDestination(Page page) {
|
|
||||||
_page = page;
|
_page = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation {
|
public override string Designation
|
||||||
get {
|
{
|
||||||
return "Confluence";
|
get { return "Confluence"; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Description {
|
public override string Description
|
||||||
get {
|
{
|
||||||
if (_page == null) {
|
get
|
||||||
|
{
|
||||||
|
if (_page == null)
|
||||||
|
{
|
||||||
return Language.GetString("confluence", LangKey.upload_menu_item);
|
return Language.GetString("confluence", LangKey.upload_menu_item);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return Language.GetString("confluence", LangKey.upload_menu_item) + ": \"" + _page.Title + "\"";
|
return Language.GetString("confluence", LangKey.upload_menu_item) + ": \"" + _page.Title + "\"";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsDynamic {
|
public override bool IsDynamic
|
||||||
get {
|
{
|
||||||
return true;
|
get { return true; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsActive {
|
public override bool IsActive
|
||||||
get {
|
{
|
||||||
return base.IsActive && !string.IsNullOrEmpty(ConfluenceConfig.Url);
|
get { return base.IsActive && !string.IsNullOrEmpty(ConfluenceConfig.Url); }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
return ConfluenceIcon;
|
get { return ConfluenceIcon; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
if (ConfluencePlugin.ConfluenceConnectorNoLogin == null || !ConfluencePlugin.ConfluenceConnectorNoLogin.IsLoggedIn) {
|
{
|
||||||
|
if (ConfluencePlugin.ConfluenceConnectorNoLogin == null || !ConfluencePlugin.ConfluenceConnectorNoLogin.IsLoggedIn)
|
||||||
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<Page> currentPages = ConfluenceUtils.GetCurrentPages();
|
List<Page> currentPages = ConfluenceUtils.GetCurrentPages();
|
||||||
if (currentPages == null || currentPages.Count == 0) {
|
if (currentPages == null || currentPages.Count == 0)
|
||||||
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
foreach(Page currentPage in currentPages) {
|
|
||||||
|
foreach (Page currentPage in currentPages)
|
||||||
|
{
|
||||||
yield return new ConfluenceDestination(currentPage);
|
yield return new ConfluenceDestination(currentPage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
// force password check to take place before the pages load
|
// force password check to take place before the pages load
|
||||||
if (!ConfluencePlugin.ConfluenceConnector.IsLoggedIn) {
|
if (!ConfluencePlugin.ConfluenceConnector.IsLoggedIn)
|
||||||
|
{
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
Page selectedPage = _page;
|
Page selectedPage = _page;
|
||||||
bool openPage = (_page == null) && ConfluenceConfig.OpenPageAfterUpload;
|
bool openPage = (_page == null) && ConfluenceConfig.OpenPageAfterUpload;
|
||||||
string filename = FilenameHelper.GetFilenameWithoutExtensionFromPattern(CoreConfig.OutputFileFilenamePattern, captureDetails);
|
string filename = FilenameHelper.GetFilenameWithoutExtensionFromPattern(CoreConfig.OutputFileFilenamePattern, captureDetails);
|
||||||
if (selectedPage == null) {
|
if (selectedPage == null)
|
||||||
|
{
|
||||||
Forms.ConfluenceUpload confluenceUpload = new Forms.ConfluenceUpload(filename);
|
Forms.ConfluenceUpload confluenceUpload = new Forms.ConfluenceUpload(filename);
|
||||||
bool? dialogResult = confluenceUpload.ShowDialog();
|
bool? dialogResult = confluenceUpload.ShowDialog();
|
||||||
if (dialogResult.HasValue && dialogResult.Value) {
|
if (dialogResult.HasValue && dialogResult.Value)
|
||||||
|
{
|
||||||
selectedPage = confluenceUpload.SelectedPage;
|
selectedPage = confluenceUpload.SelectedPage;
|
||||||
if (confluenceUpload.IsOpenPageSelected) {
|
if (confluenceUpload.IsOpenPageSelected)
|
||||||
|
{
|
||||||
openPage = false;
|
openPage = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
filename = confluenceUpload.Filename;
|
filename = confluenceUpload.Filename;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
string extension = "." + ConfluenceConfig.UploadFormat;
|
string extension = "." + ConfluenceConfig.UploadFormat;
|
||||||
if (!filename.ToLower().EndsWith(extension)) {
|
if (!filename.ToLower().EndsWith(extension))
|
||||||
|
{
|
||||||
filename += extension;
|
filename += extension;
|
||||||
}
|
}
|
||||||
if (selectedPage != null) {
|
|
||||||
|
if (selectedPage != null)
|
||||||
|
{
|
||||||
bool uploaded = Upload(surface, selectedPage, filename, out var errorMessage);
|
bool uploaded = Upload(surface, selectedPage, filename, out var errorMessage);
|
||||||
if (uploaded) {
|
if (uploaded)
|
||||||
if (openPage) {
|
{
|
||||||
|
if (openPage)
|
||||||
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
Process.Start(selectedPage.Url);
|
Process.Start(selectedPage.Url);
|
||||||
|
@ -156,23 +180,32 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = selectedPage.Url;
|
exportInformation.Uri = selectedPage.Url;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
exportInformation.ErrorMessage = errorMessage;
|
exportInformation.ErrorMessage = errorMessage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool Upload(ISurface surfaceToUpload, Page page, string filename, out string errorMessage) {
|
private bool Upload(ISurface surfaceToUpload, Page page, string filename, out string errorMessage)
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(ConfluenceConfig.UploadFormat, ConfluenceConfig.UploadJpegQuality, ConfluenceConfig.UploadReduceColors);
|
{
|
||||||
|
SurfaceOutputSettings outputSettings =
|
||||||
|
new SurfaceOutputSettings(ConfluenceConfig.UploadFormat, ConfluenceConfig.UploadJpegQuality, ConfluenceConfig.UploadReduceColors);
|
||||||
errorMessage = null;
|
errorMessage = null;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("confluence", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("confluence", LangKey.communication_wait),
|
||||||
delegate {
|
delegate
|
||||||
ConfluencePlugin.ConfluenceConnector.AddAttachment(page.Id, "image/" + ConfluenceConfig.UploadFormat.ToString().ToLower(), null, filename, new SurfaceContainer(surfaceToUpload, outputSettings, filename));
|
{
|
||||||
|
ConfluencePlugin.ConfluenceConnector.AddAttachment(page.Id, "image/" + ConfluenceConfig.UploadFormat.ToString().ToLower(), null, filename,
|
||||||
|
new SurfaceContainer(surfaceToUpload, outputSettings, filename));
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
Log.Debug("Uploaded to Confluence.");
|
Log.Debug("Uploaded to Confluence.");
|
||||||
|
@ -180,25 +213,39 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int retryCount = 2;
|
int retryCount = 2;
|
||||||
while (retryCount >= 0) {
|
while (retryCount >= 0)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
Clipboard.SetText("!" + filename + "!");
|
Clipboard.SetText("!" + filename + "!");
|
||||||
break;
|
break;
|
||||||
} catch (Exception ee) {
|
}
|
||||||
if (retryCount == 0) {
|
catch (Exception ee)
|
||||||
|
{
|
||||||
|
if (retryCount == 0)
|
||||||
|
{
|
||||||
Log.Error(ee);
|
Log.Error(ee);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Thread.Sleep(100);
|
Thread.Sleep(100);
|
||||||
}
|
}
|
||||||
} finally {
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
--retryCount;
|
--retryCount;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch(Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
errorMessage = e.Message;
|
errorMessage = e.Message;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,53 +28,70 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the ConfluencePlugin base code
|
/// This is the ConfluencePlugin base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Confluence", true)]
|
[Plugin("Confluence", true)]
|
||||||
public class ConfluencePlugin : IGreenshotPlugin {
|
public class ConfluencePlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ConfluencePlugin));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ConfluencePlugin));
|
||||||
private static ConfluenceConnector _confluenceConnector;
|
private static ConfluenceConnector _confluenceConnector;
|
||||||
private static ConfluenceConfiguration _config;
|
private static ConfluenceConfiguration _config;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
protected void Dispose(bool disposing)
|
||||||
|
{
|
||||||
//if (disposing) {}
|
//if (disposing) {}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void CreateConfluenceConnector() {
|
private static void CreateConfluenceConnector()
|
||||||
if (_confluenceConnector == null) {
|
{
|
||||||
if (_config.Url.Contains("soap-axis")) {
|
if (_confluenceConnector == null)
|
||||||
|
{
|
||||||
|
if (_config.Url.Contains("soap-axis"))
|
||||||
|
{
|
||||||
_confluenceConnector = new ConfluenceConnector(_config.Url, _config.Timeout);
|
_confluenceConnector = new ConfluenceConnector(_config.Url, _config.Timeout);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_confluenceConnector = new ConfluenceConnector(_config.Url + ConfluenceConfiguration.DEFAULT_POSTFIX2, _config.Timeout);
|
_confluenceConnector = new ConfluenceConnector(_config.Url + ConfluenceConfiguration.DEFAULT_POSTFIX2, _config.Timeout);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConfluenceConnector ConfluenceConnectorNoLogin {
|
public static ConfluenceConnector ConfluenceConnectorNoLogin
|
||||||
get {
|
{
|
||||||
return _confluenceConnector;
|
get { return _confluenceConnector; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ConfluenceConnector ConfluenceConnector {
|
public static ConfluenceConnector ConfluenceConnector
|
||||||
get {
|
{
|
||||||
if (_confluenceConnector == null) {
|
get
|
||||||
|
{
|
||||||
|
if (_confluenceConnector == null)
|
||||||
|
{
|
||||||
CreateConfluenceConnector();
|
CreateConfluenceConnector();
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
if (_confluenceConnector != null && !_confluenceConnector.IsLoggedIn) {
|
try
|
||||||
|
{
|
||||||
|
if (_confluenceConnector != null && !_confluenceConnector.IsLoggedIn)
|
||||||
|
{
|
||||||
_confluenceConnector.Login();
|
_confluenceConnector.Login();
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
MessageBox.Show(Language.GetFormattedString("confluence", LangKey.login_error, e.Message));
|
MessageBox.Show(Language.GetFormattedString("confluence", LangKey.login_error, e.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
return _confluenceConnector;
|
return _confluenceConnector;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,29 +99,39 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<ConfluenceConfiguration>();
|
_config = IniConfig.GetIniSection<ConfluenceConfiguration>();
|
||||||
if(_config.IsDirty) {
|
if (_config.IsDirty)
|
||||||
|
{
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
|
try
|
||||||
|
{
|
||||||
TranslationManager.Instance.TranslationProvider = new LanguageXMLTranslationProvider();
|
TranslationManager.Instance.TranslationProvider = new LanguageXMLTranslationProvider();
|
||||||
//resources = new ComponentResourceManager(typeof(ConfluencePlugin));
|
//resources = new ComponentResourceManager(typeof(ConfluencePlugin));
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.ErrorFormat("Problem in ConfluencePlugin.Initialize: {0}", ex.Message);
|
LOG.ErrorFormat("Problem in ConfluencePlugin.Initialize: {0}", ex.Message);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ConfluenceDestination.IsInitialized)
|
if (ConfluenceDestination.IsInitialized)
|
||||||
{
|
{
|
||||||
SimpleServiceProvider.Current.AddService<IDestination>(new ConfluenceDestination());
|
SimpleServiceProvider.Current.AddService<IDestination>(new ConfluenceDestination());
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
LOG.Debug("Confluence Plugin shutdown.");
|
LOG.Debug("Confluence Plugin shutdown.");
|
||||||
if (_confluenceConnector != null) {
|
if (_confluenceConnector != null)
|
||||||
|
{
|
||||||
_confluenceConnector.Logout();
|
_confluenceConnector.Logout();
|
||||||
_confluenceConnector = null;
|
_confluenceConnector = null;
|
||||||
}
|
}
|
||||||
|
@ -113,20 +140,26 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
ConfluenceConfiguration clonedConfig = _config.Clone();
|
ConfluenceConfiguration clonedConfig = _config.Clone();
|
||||||
ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig);
|
ConfluenceConfigurationForm configForm = new ConfluenceConfigurationForm(clonedConfig);
|
||||||
string url = _config.Url;
|
string url = _config.Url;
|
||||||
bool? dialogResult = configForm.ShowDialog();
|
bool? dialogResult = configForm.ShowDialog();
|
||||||
if (dialogResult.HasValue && dialogResult.Value) {
|
if (dialogResult.HasValue && dialogResult.Value)
|
||||||
|
{
|
||||||
// copy the new object to the old...
|
// copy the new object to the old...
|
||||||
clonedConfig.CloneTo(_config);
|
clonedConfig.CloneTo(_config);
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
if (_confluenceConnector != null) {
|
if (_confluenceConnector != null)
|
||||||
if (!url.Equals(_config.Url)) {
|
{
|
||||||
if (_confluenceConnector.IsLoggedIn) {
|
if (!url.Equals(_config.Url))
|
||||||
|
{
|
||||||
|
if (_confluenceConnector.IsLoggedIn)
|
||||||
|
{
|
||||||
_confluenceConnector.Logout();
|
_confluenceConnector.Logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
_confluenceConnector = null;
|
_confluenceConnector = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,76 +26,106 @@ using System.Text.RegularExpressions;
|
||||||
using System.Windows.Automation;
|
using System.Windows.Automation;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ConfluenceUtils.
|
/// Description of ConfluenceUtils.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ConfluenceUtils {
|
public class ConfluenceUtils
|
||||||
|
{
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ConfluenceUtils));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ConfluenceUtils));
|
||||||
|
|
||||||
public static List<Page> GetCurrentPages() {
|
public static List<Page> GetCurrentPages()
|
||||||
|
{
|
||||||
List<Page> pages = new List<Page>();
|
List<Page> pages = new List<Page>();
|
||||||
Regex pageIdRegex = new Regex(@"pageId=(\d+)");
|
Regex pageIdRegex = new Regex(@"pageId=(\d+)");
|
||||||
Regex spacePageRegex = new Regex(@"\/display\/([^\/]+)\/([^#]+)");
|
Regex spacePageRegex = new Regex(@"\/display\/([^\/]+)\/([^#]+)");
|
||||||
foreach(string browserurl in GetBrowserUrls()) {
|
foreach (string browserurl in GetBrowserUrls())
|
||||||
|
{
|
||||||
string url;
|
string url;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
url = Uri.UnescapeDataString(browserurl).Replace("+", " ");
|
url = Uri.UnescapeDataString(browserurl).Replace("+", " ");
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
LOG.WarnFormat("Error processing URL: {0}", browserurl);
|
LOG.WarnFormat("Error processing URL: {0}", browserurl);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchCollection pageIdMatch = pageIdRegex.Matches(url);
|
MatchCollection pageIdMatch = pageIdRegex.Matches(url);
|
||||||
if (pageIdMatch != null && pageIdMatch.Count > 0) {
|
if (pageIdMatch != null && pageIdMatch.Count > 0)
|
||||||
|
{
|
||||||
long pageId = long.Parse(pageIdMatch[0].Groups[1].Value);
|
long pageId = long.Parse(pageIdMatch[0].Groups[1].Value);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
bool pageDouble = false;
|
bool pageDouble = false;
|
||||||
foreach(Page page in pages) {
|
foreach (Page page in pages)
|
||||||
if (page.Id == pageId) {
|
{
|
||||||
|
if (page.Id == pageId)
|
||||||
|
{
|
||||||
pageDouble = true;
|
pageDouble = true;
|
||||||
LOG.DebugFormat("Skipping double page with ID {0}", pageId);
|
LOG.DebugFormat("Skipping double page with ID {0}", pageId);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pageDouble) {
|
|
||||||
|
if (!pageDouble)
|
||||||
|
{
|
||||||
Page page = ConfluencePlugin.ConfluenceConnector.GetPage(pageId);
|
Page page = ConfluencePlugin.ConfluenceConnector.GetPage(pageId);
|
||||||
LOG.DebugFormat("Adding page {0}", page.Title);
|
LOG.DebugFormat("Adding page {0}", page.Title);
|
||||||
pages.Add(page);
|
pages.Add(page);
|
||||||
}
|
}
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
// Preventing security problems
|
// Preventing security problems
|
||||||
LOG.DebugFormat("Couldn't get page details for PageID {0}", pageId);
|
LOG.DebugFormat("Couldn't get page details for PageID {0}", pageId);
|
||||||
LOG.Warn(ex);
|
LOG.Warn(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
MatchCollection spacePageMatch = spacePageRegex.Matches(url);
|
MatchCollection spacePageMatch = spacePageRegex.Matches(url);
|
||||||
if (spacePageMatch != null && spacePageMatch.Count > 0) {
|
if (spacePageMatch != null && spacePageMatch.Count > 0)
|
||||||
if (spacePageMatch[0].Groups.Count >= 2) {
|
{
|
||||||
|
if (spacePageMatch[0].Groups.Count >= 2)
|
||||||
|
{
|
||||||
string space = spacePageMatch[0].Groups[1].Value;
|
string space = spacePageMatch[0].Groups[1].Value;
|
||||||
string title = spacePageMatch[0].Groups[2].Value;
|
string title = spacePageMatch[0].Groups[2].Value;
|
||||||
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(space)) {
|
if (string.IsNullOrEmpty(title) || string.IsNullOrEmpty(space))
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (title.EndsWith("#")) {
|
|
||||||
|
if (title.EndsWith("#"))
|
||||||
|
{
|
||||||
title = title.Substring(0, title.Length - 1);
|
title = title.Substring(0, title.Length - 1);
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
|
try
|
||||||
|
{
|
||||||
bool pageDouble = false;
|
bool pageDouble = false;
|
||||||
foreach(Page page in pages) {
|
foreach (Page page in pages)
|
||||||
if (page.Title.Equals(title)) {
|
{
|
||||||
|
if (page.Title.Equals(title))
|
||||||
|
{
|
||||||
LOG.DebugFormat("Skipping double page with title {0}", title);
|
LOG.DebugFormat("Skipping double page with title {0}", title);
|
||||||
pageDouble = true;
|
pageDouble = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!pageDouble) {
|
|
||||||
|
if (!pageDouble)
|
||||||
|
{
|
||||||
Page page = ConfluencePlugin.ConfluenceConnector.GetPage(space, title);
|
Page page = ConfluencePlugin.ConfluenceConnector.GetPage(space, title);
|
||||||
LOG.DebugFormat("Adding page {0}", page.Title);
|
LOG.DebugFormat("Adding page {0}", page.Title);
|
||||||
pages.Add(page);
|
pages.Add(page);
|
||||||
|
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
// Preventing security problems
|
// Preventing security problems
|
||||||
LOG.DebugFormat("Couldn't get page details for space {0} / title {1}", space, title);
|
LOG.DebugFormat("Couldn't get page details for space {0} / title {1}", space, title);
|
||||||
LOG.Warn(ex);
|
LOG.Warn(ex);
|
||||||
|
@ -103,49 +133,65 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return pages;
|
return pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static IEnumerable<string> GetBrowserUrls() {
|
private static IEnumerable<string> GetBrowserUrls()
|
||||||
|
{
|
||||||
HashSet<string> urls = new HashSet<string>();
|
HashSet<string> urls = new HashSet<string>();
|
||||||
|
|
||||||
// FireFox
|
// FireFox
|
||||||
foreach (WindowDetails window in WindowDetails.GetAllWindows("MozillaWindowClass")) {
|
foreach (WindowDetails window in WindowDetails.GetAllWindows("MozillaWindowClass"))
|
||||||
if (window.Text.Length == 0) {
|
{
|
||||||
continue;
|
if (window.Text.Length == 0)
|
||||||
}
|
{
|
||||||
AutomationElement currentElement = AutomationElement.FromHandle(window.Handle);
|
|
||||||
Condition conditionCustom = new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom), new PropertyCondition(AutomationElement.IsOffscreenProperty, false));
|
|
||||||
for (int i = 5; i > 0 && currentElement != null; i--) {
|
|
||||||
currentElement = currentElement.FindFirst(TreeScope.Children, conditionCustom);
|
|
||||||
}
|
|
||||||
if (currentElement == null) {
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
Condition conditionDocument = new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document), new PropertyCondition(AutomationElement.IsOffscreenProperty, false));
|
AutomationElement currentElement = AutomationElement.FromHandle(window.Handle);
|
||||||
|
Condition conditionCustom = new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Custom),
|
||||||
|
new PropertyCondition(AutomationElement.IsOffscreenProperty, false));
|
||||||
|
for (int i = 5; i > 0 && currentElement != null; i--)
|
||||||
|
{
|
||||||
|
currentElement = currentElement.FindFirst(TreeScope.Children, conditionCustom);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentElement == null)
|
||||||
|
{
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Condition conditionDocument = new AndCondition(new PropertyCondition(AutomationElement.ControlTypeProperty, ControlType.Document),
|
||||||
|
new PropertyCondition(AutomationElement.IsOffscreenProperty, false));
|
||||||
AutomationElement docElement = currentElement.FindFirst(TreeScope.Children, conditionDocument);
|
AutomationElement docElement = currentElement.FindFirst(TreeScope.Children, conditionDocument);
|
||||||
if (docElement == null) {
|
if (docElement == null)
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
foreach (AutomationPattern pattern in docElement.GetSupportedPatterns()) {
|
|
||||||
if (pattern.ProgrammaticName != "ValuePatternIdentifiers.Pattern") {
|
foreach (AutomationPattern pattern in docElement.GetSupportedPatterns())
|
||||||
|
{
|
||||||
|
if (pattern.ProgrammaticName != "ValuePatternIdentifiers.Pattern")
|
||||||
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string url = (docElement.GetCurrentPattern(pattern) as ValuePattern).Current.Value;
|
string url = (docElement.GetCurrentPattern(pattern) as ValuePattern).Current.Value;
|
||||||
if (!string.IsNullOrEmpty(url)) {
|
if (!string.IsNullOrEmpty(url))
|
||||||
|
{
|
||||||
urls.Add(url);
|
urls.Add(url);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach(string url in IEHelper.GetIEUrls().Distinct()) {
|
foreach (string url in IEHelper.GetIEUrls().Distinct())
|
||||||
|
{
|
||||||
urls.Add(url);
|
urls.Add(url);
|
||||||
}
|
}
|
||||||
|
|
||||||
return urls;
|
return urls;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -28,24 +28,32 @@ using System.Reflection;
|
||||||
using System.Windows.Data;
|
using System.Windows.Data;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
public class EnumDisplayer : IValueConverter {
|
{
|
||||||
|
public class EnumDisplayer : IValueConverter
|
||||||
|
{
|
||||||
private Type _type;
|
private Type _type;
|
||||||
private IDictionary _displayValues;
|
private IDictionary _displayValues;
|
||||||
private IDictionary _reverseValues;
|
private IDictionary _reverseValues;
|
||||||
|
|
||||||
public Type Type {
|
public Type Type
|
||||||
|
{
|
||||||
get { return _type; }
|
get { return _type; }
|
||||||
set {
|
set
|
||||||
if (!value.IsEnum) {
|
{
|
||||||
|
if (!value.IsEnum)
|
||||||
|
{
|
||||||
throw new ArgumentException("parameter is not an Enumerated type", nameof(value));
|
throw new ArgumentException("parameter is not an Enumerated type", nameof(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
_type = value;
|
_type = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ReadOnlyCollection<string> DisplayNames {
|
public ReadOnlyCollection<string> DisplayNames
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
var genericTypeDefinition = typeof(Dictionary<,>).GetGenericTypeDefinition();
|
var genericTypeDefinition = typeof(Dictionary<,>).GetGenericTypeDefinition();
|
||||||
if (genericTypeDefinition != null)
|
if (genericTypeDefinition != null)
|
||||||
{
|
{
|
||||||
|
@ -59,38 +67,47 @@ namespace Greenshot.Plugin.Confluence {
|
||||||
}
|
}
|
||||||
|
|
||||||
var fields = _type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
var fields = _type.GetFields(BindingFlags.Public | BindingFlags.Static);
|
||||||
foreach (var field in fields) {
|
foreach (var field in fields)
|
||||||
|
{
|
||||||
DisplayKeyAttribute[] a = (DisplayKeyAttribute[]) field.GetCustomAttributes(typeof(DisplayKeyAttribute), false);
|
DisplayKeyAttribute[] a = (DisplayKeyAttribute[]) field.GetCustomAttributes(typeof(DisplayKeyAttribute), false);
|
||||||
|
|
||||||
string displayKey = GetDisplayKeyValue(a);
|
string displayKey = GetDisplayKeyValue(a);
|
||||||
object enumValue = field.GetValue(null);
|
object enumValue = field.GetValue(null);
|
||||||
|
|
||||||
string displayString;
|
string displayString;
|
||||||
if (displayKey != null && Language.HasKey(displayKey)) {
|
if (displayKey != null && Language.HasKey(displayKey))
|
||||||
|
{
|
||||||
displayString = Language.GetString(displayKey);
|
displayString = Language.GetString(displayKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
displayString = displayKey ?? enumValue.ToString();
|
displayString = displayKey ?? enumValue.ToString();
|
||||||
|
|
||||||
_displayValues.Add(enumValue, displayString);
|
_displayValues.Add(enumValue, displayString);
|
||||||
_reverseValues.Add(displayString, enumValue);
|
_reverseValues.Add(displayString, enumValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new List<string>((IEnumerable<string>) _displayValues.Values).AsReadOnly();
|
return new List<string>((IEnumerable<string>) _displayValues.Values).AsReadOnly();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetDisplayKeyValue(DisplayKeyAttribute[] a) {
|
private static string GetDisplayKeyValue(DisplayKeyAttribute[] a)
|
||||||
if (a == null || a.Length == 0) {
|
{
|
||||||
|
if (a == null || a.Length == 0)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
DisplayKeyAttribute dka = a[0];
|
DisplayKeyAttribute dka = a[0];
|
||||||
return dka.Value;
|
return dka.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture) {
|
object IValueConverter.Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
return _displayValues[value];
|
return _displayValues[value];
|
||||||
}
|
}
|
||||||
|
|
||||||
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
|
object IValueConverter.ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||||
|
{
|
||||||
return _reverseValues[value];
|
return _reverseValues[value];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,20 +21,24 @@
|
||||||
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Forms {
|
namespace Greenshot.Plugin.Confluence.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ConfluenceConfigurationForm.xaml
|
/// Interaction logic for ConfluenceConfigurationForm.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ConfluenceConfigurationForm : Window {
|
public partial class ConfluenceConfigurationForm : Window
|
||||||
|
{
|
||||||
public ConfluenceConfiguration Config { get; }
|
public ConfluenceConfiguration Config { get; }
|
||||||
|
|
||||||
public ConfluenceConfigurationForm(ConfluenceConfiguration config) {
|
public ConfluenceConfigurationForm(ConfluenceConfiguration config)
|
||||||
|
{
|
||||||
DataContext = config;
|
DataContext = config;
|
||||||
Config = config;
|
Config = config;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button_OK_Click(object sender, RoutedEventArgs e) {
|
private void Button_OK_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,8 @@
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Forms {
|
namespace Greenshot.Plugin.Confluence.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ConfluencePagePicker.xaml
|
/// Interaction logic for ConfluencePagePicker.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -29,27 +30,34 @@ namespace Greenshot.Plugin.Confluence.Forms {
|
||||||
{
|
{
|
||||||
private readonly ConfluenceUpload _confluenceUpload;
|
private readonly ConfluenceUpload _confluenceUpload;
|
||||||
|
|
||||||
public ConfluencePagePicker(ConfluenceUpload confluenceUpload, List<Page> pagesToPick) {
|
public ConfluencePagePicker(ConfluenceUpload confluenceUpload, List<Page> pagesToPick)
|
||||||
|
{
|
||||||
_confluenceUpload = confluenceUpload;
|
_confluenceUpload = confluenceUpload;
|
||||||
DataContext = pagesToPick;
|
DataContext = pagesToPick;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PageListView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) {
|
private void PageListView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
SelectionChanged();
|
SelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectionChanged() {
|
private void SelectionChanged()
|
||||||
if (PageListView.HasItems && PageListView.SelectedItems.Count > 0) {
|
{
|
||||||
|
if (PageListView.HasItems && PageListView.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
_confluenceUpload.SelectedPage = (Page) PageListView.SelectedItem;
|
_confluenceUpload.SelectedPage = (Page) PageListView.SelectedItem;
|
||||||
// Make sure the uploader knows we selected an already opened page
|
// Make sure the uploader knows we selected an already opened page
|
||||||
_confluenceUpload.IsOpenPageSelected = true;
|
_confluenceUpload.IsOpenPageSelected = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_confluenceUpload.SelectedPage = null;
|
_confluenceUpload.SelectedPage = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Page_Loaded(object sender, System.Windows.RoutedEventArgs e) {
|
private void Page_Loaded(object sender, System.Windows.RoutedEventArgs e)
|
||||||
|
{
|
||||||
SelectionChanged();
|
SelectionChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,8 @@ using System.Linq;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Forms {
|
namespace Greenshot.Plugin.Confluence.Forms
|
||||||
|
{
|
||||||
public partial class ConfluenceSearch
|
public partial class ConfluenceSearch
|
||||||
{
|
{
|
||||||
private static readonly ConfluenceConfiguration ConfluenceConfig = IniConfig.GetIniSection<ConfluenceConfiguration>();
|
private static readonly ConfluenceConfiguration ConfluenceConfig = IniConfig.GetIniSection<ConfluenceConfiguration>();
|
||||||
|
@ -35,58 +36,76 @@ namespace Greenshot.Plugin.Confluence.Forms {
|
||||||
|
|
||||||
public ObservableCollection<Page> Pages { get; } = new ObservableCollection<Page>();
|
public ObservableCollection<Page> Pages { get; } = new ObservableCollection<Page>();
|
||||||
|
|
||||||
public ConfluenceSearch(ConfluenceUpload confluenceUpload) {
|
public ConfluenceSearch(ConfluenceUpload confluenceUpload)
|
||||||
|
{
|
||||||
_confluenceUpload = confluenceUpload;
|
_confluenceUpload = confluenceUpload;
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
if (ConfluenceConfig.SearchSpaceKey == null) {
|
if (ConfluenceConfig.SearchSpaceKey == null)
|
||||||
|
{
|
||||||
SpaceComboBox.SelectedItem = Spaces.FirstOrDefault();
|
SpaceComboBox.SelectedItem = Spaces.FirstOrDefault();
|
||||||
} else {
|
}
|
||||||
foreach(var space in Spaces) {
|
else
|
||||||
if (space.Key.Equals(ConfluenceConfig.SearchSpaceKey)) {
|
{
|
||||||
|
foreach (var space in Spaces)
|
||||||
|
{
|
||||||
|
if (space.Key.Equals(ConfluenceConfig.SearchSpaceKey))
|
||||||
|
{
|
||||||
SpaceComboBox.SelectedItem = space;
|
SpaceComboBox.SelectedItem = space;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PageListView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e) {
|
private void PageListView_SelectionChanged(object sender, System.Windows.Controls.SelectionChangedEventArgs e)
|
||||||
|
{
|
||||||
SelectionChanged();
|
SelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SelectionChanged() {
|
private void SelectionChanged()
|
||||||
if (PageListView.HasItems && PageListView.SelectedItems.Count > 0) {
|
{
|
||||||
|
if (PageListView.HasItems && PageListView.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
_confluenceUpload.SelectedPage = (Page) PageListView.SelectedItem;
|
_confluenceUpload.SelectedPage = (Page) PageListView.SelectedItem;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
_confluenceUpload.SelectedPage = null;
|
_confluenceUpload.SelectedPage = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Search_Click(object sender, RoutedEventArgs e) {
|
private void Search_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
DoSearch();
|
DoSearch();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DoSearch() {
|
private void DoSearch()
|
||||||
|
{
|
||||||
string spaceKey = (string) SpaceComboBox.SelectedValue;
|
string spaceKey = (string) SpaceComboBox.SelectedValue;
|
||||||
ConfluenceConfig.SearchSpaceKey = spaceKey;
|
ConfluenceConfig.SearchSpaceKey = spaceKey;
|
||||||
Pages.Clear();
|
Pages.Clear();
|
||||||
foreach(var page in ConfluencePlugin.ConfluenceConnector.SearchPages(searchText.Text, spaceKey).OrderBy(p => p.Title)) {
|
foreach (var page in ConfluencePlugin.ConfluenceConnector.SearchPages(searchText.Text, spaceKey).OrderBy(p => p.Title))
|
||||||
|
{
|
||||||
Pages.Add(page);
|
Pages.Add(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchText_KeyDown(object sender, System.Windows.Input.KeyEventArgs e) {
|
private void SearchText_KeyDown(object sender, System.Windows.Input.KeyEventArgs e)
|
||||||
if (e.Key == System.Windows.Input.Key.Return && Search.IsEnabled) {
|
{
|
||||||
|
if (e.Key == System.Windows.Input.Key.Return && Search.IsEnabled)
|
||||||
|
{
|
||||||
DoSearch();
|
DoSearch();
|
||||||
e.Handled = true;
|
e.Handled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Page_Loaded(object sender, RoutedEventArgs e) {
|
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
SelectionChanged();
|
SelectionChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void SearchText_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e) {
|
private void SearchText_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
|
||||||
|
{
|
||||||
Search.IsEnabled = !string.IsNullOrEmpty(searchText.Text);
|
Search.IsEnabled = !string.IsNullOrEmpty(searchText.Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Threading;
|
using System.Windows.Threading;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Forms {
|
namespace Greenshot.Plugin.Confluence.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ConfluenceTreePicker.xaml
|
/// Interaction logic for ConfluenceTreePicker.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -38,28 +39,36 @@ namespace Greenshot.Plugin.Confluence.Forms {
|
||||||
private readonly ConfluenceUpload _confluenceUpload;
|
private readonly ConfluenceUpload _confluenceUpload;
|
||||||
private bool _isInitDone;
|
private bool _isInitDone;
|
||||||
|
|
||||||
public ConfluenceTreePicker(ConfluenceUpload confluenceUpload) {
|
public ConfluenceTreePicker(ConfluenceUpload confluenceUpload)
|
||||||
|
{
|
||||||
_confluenceConnector = ConfluencePlugin.ConfluenceConnector;
|
_confluenceConnector = ConfluencePlugin.ConfluenceConnector;
|
||||||
_confluenceUpload = confluenceUpload;
|
_confluenceUpload = confluenceUpload;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PageTreeViewItem_DoubleClick(object sender, MouseButtonEventArgs eventArgs) {
|
private void PageTreeViewItem_DoubleClick(object sender, MouseButtonEventArgs eventArgs)
|
||||||
|
{
|
||||||
Log.Debug("spaceTreeViewItem_MouseLeftButtonDown is called!");
|
Log.Debug("spaceTreeViewItem_MouseLeftButtonDown is called!");
|
||||||
TreeViewItem clickedItem = eventArgs.Source as TreeViewItem;
|
TreeViewItem clickedItem = eventArgs.Source as TreeViewItem;
|
||||||
if (clickedItem?.Tag is not Page page) {
|
if (clickedItem?.Tag is not Page page)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (clickedItem.HasItems)
|
if (clickedItem.HasItems)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.Debug("Loading pages for page: " + page.Title);
|
Log.Debug("Loading pages for page: " + page.Title);
|
||||||
new Thread(() => {
|
new Thread(() =>
|
||||||
|
{
|
||||||
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart) (() => { ShowBusy.Visibility = Visibility.Visible; }));
|
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart) (() => { ShowBusy.Visibility = Visibility.Visible; }));
|
||||||
var pages = _confluenceConnector.GetPageChildren(page).OrderBy(p => p.Title);
|
var pages = _confluenceConnector.GetPageChildren(page).OrderBy(p => p.Title);
|
||||||
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)(() => {
|
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart) (() =>
|
||||||
foreach(var childPage in pages) {
|
{
|
||||||
|
foreach (var childPage in pages)
|
||||||
|
{
|
||||||
Log.Debug("Adding page: " + childPage.Title);
|
Log.Debug("Adding page: " + childPage.Title);
|
||||||
var pageTreeViewItem = new TreeViewItem
|
var pageTreeViewItem = new TreeViewItem
|
||||||
{
|
{
|
||||||
|
@ -70,32 +79,46 @@ namespace Greenshot.Plugin.Confluence.Forms {
|
||||||
pageTreeViewItem.PreviewMouseDoubleClick += PageTreeViewItem_DoubleClick;
|
pageTreeViewItem.PreviewMouseDoubleClick += PageTreeViewItem_DoubleClick;
|
||||||
pageTreeViewItem.PreviewMouseLeftButtonDown += PageTreeViewItem_Click;
|
pageTreeViewItem.PreviewMouseLeftButtonDown += PageTreeViewItem_Click;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowBusy.Visibility = Visibility.Collapsed;
|
ShowBusy.Visibility = Visibility.Collapsed;
|
||||||
}));
|
}));
|
||||||
}) { Name = "Loading childpages for confluence page " + page.Title }.Start();
|
})
|
||||||
|
{
|
||||||
|
Name = "Loading childpages for confluence page " + page.Title
|
||||||
|
}.Start();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PageTreeViewItem_Click(object sender, MouseButtonEventArgs eventArgs) {
|
private void PageTreeViewItem_Click(object sender, MouseButtonEventArgs eventArgs)
|
||||||
|
{
|
||||||
Log.Debug("pageTreeViewItem_PreviewMouseDoubleClick is called!");
|
Log.Debug("pageTreeViewItem_PreviewMouseDoubleClick is called!");
|
||||||
if (eventArgs.Source is not TreeViewItem clickedItem) {
|
if (eventArgs.Source is not TreeViewItem clickedItem)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Page page = clickedItem.Tag as Page;
|
Page page = clickedItem.Tag as Page;
|
||||||
_confluenceUpload.SelectedPage = page;
|
_confluenceUpload.SelectedPage = page;
|
||||||
if (page != null) {
|
if (page != null)
|
||||||
|
{
|
||||||
Log.Debug("Page selected: " + page.Title);
|
Log.Debug("Page selected: " + page.Title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Page_Loaded(object sender, RoutedEventArgs e) {
|
private void Page_Loaded(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
_confluenceUpload.SelectedPage = null;
|
_confluenceUpload.SelectedPage = null;
|
||||||
if (_isInitDone) {
|
if (_isInitDone)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowBusy.Visibility = Visibility.Visible;
|
ShowBusy.Visibility = Visibility.Visible;
|
||||||
new Thread(() => {
|
new Thread(() =>
|
||||||
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart)(() => {
|
{
|
||||||
foreach (Space space in _confluenceUpload.Spaces) {
|
Dispatcher.BeginInvoke(DispatcherPriority.Normal, (ThreadStart) (() =>
|
||||||
|
{
|
||||||
|
foreach (Space space in _confluenceUpload.Spaces)
|
||||||
|
{
|
||||||
TreeViewItem spaceTreeViewItem = new TreeViewItem
|
TreeViewItem spaceTreeViewItem = new TreeViewItem
|
||||||
{
|
{
|
||||||
Header = space.Name,
|
Header = space.Name,
|
||||||
|
@ -103,7 +126,8 @@ namespace Greenshot.Plugin.Confluence.Forms {
|
||||||
};
|
};
|
||||||
|
|
||||||
// Get homepage
|
// Get homepage
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
Page page = _confluenceConnector.GetSpaceHomepage(space);
|
Page page = _confluenceConnector.GetSpaceHomepage(space);
|
||||||
TreeViewItem pageTreeViewItem = new TreeViewItem
|
TreeViewItem pageTreeViewItem = new TreeViewItem
|
||||||
{
|
{
|
||||||
|
@ -114,14 +138,20 @@ namespace Greenshot.Plugin.Confluence.Forms {
|
||||||
pageTreeViewItem.PreviewMouseLeftButtonDown += PageTreeViewItem_Click;
|
pageTreeViewItem.PreviewMouseLeftButtonDown += PageTreeViewItem_Click;
|
||||||
spaceTreeViewItem.Items.Add(pageTreeViewItem);
|
spaceTreeViewItem.Items.Add(pageTreeViewItem);
|
||||||
ConfluenceTreeView.Items.Add(spaceTreeViewItem);
|
ConfluenceTreeView.Items.Add(spaceTreeViewItem);
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Error("Can't get homepage for space : " + space.Name + " (" + ex.Message + ")");
|
Log.Error("Can't get homepage for space : " + space.Name + " (" + ex.Message + ")");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ShowBusy.Visibility = Visibility.Collapsed;
|
ShowBusy.Visibility = Visibility.Collapsed;
|
||||||
_isInitDone = true;
|
_isInitDone = true;
|
||||||
}));
|
}));
|
||||||
}) { Name = "Loading spaces for confluence"}.Start();
|
})
|
||||||
|
{
|
||||||
|
Name = "Loading spaces for confluence"
|
||||||
|
}.Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -25,91 +25,116 @@ using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Forms {
|
namespace Greenshot.Plugin.Confluence.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Interaction logic for ConfluenceUpload.xaml
|
/// Interaction logic for ConfluenceUpload.xaml
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class ConfluenceUpload : Window {
|
public partial class ConfluenceUpload : Window
|
||||||
|
{
|
||||||
private System.Windows.Controls.Page _pickerPage;
|
private System.Windows.Controls.Page _pickerPage;
|
||||||
public System.Windows.Controls.Page PickerPage {
|
|
||||||
get {
|
public System.Windows.Controls.Page PickerPage
|
||||||
if (_pickerPage == null) {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
if (_pickerPage == null)
|
||||||
|
{
|
||||||
List<Page> pages = ConfluenceUtils.GetCurrentPages();
|
List<Page> pages = ConfluenceUtils.GetCurrentPages();
|
||||||
if (pages != null && pages.Count > 0) {
|
if (pages != null && pages.Count > 0)
|
||||||
|
{
|
||||||
_pickerPage = new ConfluencePagePicker(this, pages);
|
_pickerPage = new ConfluencePagePicker(this, pages);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return _pickerPage;
|
return _pickerPage;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private System.Windows.Controls.Page _searchPage;
|
private System.Windows.Controls.Page _searchPage;
|
||||||
public System.Windows.Controls.Page SearchPage {
|
|
||||||
|
public System.Windows.Controls.Page SearchPage
|
||||||
|
{
|
||||||
get { return _searchPage ??= new ConfluenceSearch(this); }
|
get { return _searchPage ??= new ConfluenceSearch(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private System.Windows.Controls.Page _browsePage;
|
private System.Windows.Controls.Page _browsePage;
|
||||||
public System.Windows.Controls.Page BrowsePage {
|
|
||||||
|
public System.Windows.Controls.Page BrowsePage
|
||||||
|
{
|
||||||
get { return _browsePage ??= new ConfluenceTreePicker(this); }
|
get { return _browsePage ??= new ConfluenceTreePicker(this); }
|
||||||
}
|
}
|
||||||
|
|
||||||
private Page _selectedPage;
|
private Page _selectedPage;
|
||||||
public Page SelectedPage {
|
|
||||||
|
public Page SelectedPage
|
||||||
|
{
|
||||||
get => _selectedPage;
|
get => _selectedPage;
|
||||||
set {
|
set
|
||||||
|
{
|
||||||
_selectedPage = value;
|
_selectedPage = value;
|
||||||
Upload.IsEnabled = _selectedPage != null;
|
Upload.IsEnabled = _selectedPage != null;
|
||||||
IsOpenPageSelected = false;
|
IsOpenPageSelected = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsOpenPageSelected {
|
public bool IsOpenPageSelected { get; set; }
|
||||||
get;
|
public string Filename { get; set; }
|
||||||
set;
|
|
||||||
}
|
|
||||||
public string Filename {
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private static DateTime _lastLoad = DateTime.Now;
|
private static DateTime _lastLoad = DateTime.Now;
|
||||||
private static IList<Space> _spaces;
|
private static IList<Space> _spaces;
|
||||||
public IList<Space> Spaces {
|
|
||||||
get {
|
public IList<Space> Spaces
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
UpdateSpaces();
|
UpdateSpaces();
|
||||||
while (_spaces == null) {
|
while (_spaces == null)
|
||||||
|
{
|
||||||
Thread.Sleep(300);
|
Thread.Sleep(300);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _spaces;
|
return _spaces;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ConfluenceUpload(string filename) {
|
public ConfluenceUpload(string filename)
|
||||||
|
{
|
||||||
Filename = filename;
|
Filename = filename;
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
UpdateSpaces();
|
UpdateSpaces();
|
||||||
if (PickerPage == null) {
|
if (PickerPage == null)
|
||||||
|
{
|
||||||
PickerTab.Visibility = Visibility.Collapsed;
|
PickerTab.Visibility = Visibility.Collapsed;
|
||||||
SearchTab.IsSelected = true;
|
SearchTab.IsSelected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateSpaces() {
|
private void UpdateSpaces()
|
||||||
if (_spaces != null && DateTime.Now.AddMinutes(-60).CompareTo(_lastLoad) > 0) {
|
{
|
||||||
|
if (_spaces != null && DateTime.Now.AddMinutes(-60).CompareTo(_lastLoad) > 0)
|
||||||
|
{
|
||||||
// Reset
|
// Reset
|
||||||
_spaces = null;
|
_spaces = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if load is needed
|
// Check if load is needed
|
||||||
if (_spaces == null) {
|
if (_spaces == null)
|
||||||
(new Thread(() => {
|
{
|
||||||
|
(new Thread(() =>
|
||||||
|
{
|
||||||
_spaces = ConfluencePlugin.ConfluenceConnector.GetSpaceSummaries().OrderBy(s => s.Name).ToList();
|
_spaces = ConfluencePlugin.ConfluenceConnector.GetSpaceSummaries().OrderBy(s => s.Name).ToList();
|
||||||
_lastLoad = DateTime.Now;
|
_lastLoad = DateTime.Now;
|
||||||
}) { Name = "Loading spaces for confluence"}).Start();
|
})
|
||||||
|
{
|
||||||
|
Name = "Loading spaces for confluence"
|
||||||
|
}).Start();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Upload_Click(object sender, RoutedEventArgs e) {
|
private void Upload_Click(object sender, RoutedEventArgs e)
|
||||||
|
{
|
||||||
DialogResult = true;
|
DialogResult = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence {
|
namespace Greenshot.Plugin.Confluence
|
||||||
public enum LangKey {
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
login_error,
|
login_error,
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
communication_wait
|
communication_wait
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
namespace Greenshot.Plugin.Confluence.Support {
|
namespace Greenshot.Plugin.Confluence.Support
|
||||||
public interface ITranslationProvider {
|
{
|
||||||
|
public interface ITranslationProvider
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Translates the specified key.
|
/// Translates the specified key.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -43,9 +43,9 @@ namespace Greenshot.Plugin.Confluence.Support
|
||||||
manager = new LanguageChangedEventManager();
|
manager = new LanguageChangedEventManager();
|
||||||
SetCurrentManager(managerType, manager);
|
SetCurrentManager(managerType, manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
return manager;
|
return manager;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,17 +1,22 @@
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Support {
|
namespace Greenshot.Plugin.Confluence.Support
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
///
|
///
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class LanguageXMLTranslationProvider : ITranslationProvider {
|
public class LanguageXMLTranslationProvider : ITranslationProvider
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// See <see cref="ITranslationProvider.Translate" />
|
/// See <see cref="ITranslationProvider.Translate" />
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public object Translate(string key) {
|
public object Translate(string key)
|
||||||
if (Language.HasKey("confluence", key)) {
|
{
|
||||||
|
if (Language.HasKey("confluence", key))
|
||||||
|
{
|
||||||
return Language.GetString("confluence", key);
|
return Language.GetString("confluence", key);
|
||||||
}
|
}
|
||||||
|
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,18 @@
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Support {
|
namespace Greenshot.Plugin.Confluence.Support
|
||||||
public class TranslationData : IWeakEventListener, INotifyPropertyChanged {
|
{
|
||||||
|
public class TranslationData : IWeakEventListener, INotifyPropertyChanged
|
||||||
|
{
|
||||||
private readonly string _key;
|
private readonly string _key;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Initializes a new instance of the <see cref="TranslationData"/> class.
|
/// Initializes a new instance of the <see cref="TranslationData"/> class.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="key">The key.</param>
|
/// <param name="key">The key.</param>
|
||||||
public TranslationData( string key) {
|
public TranslationData(string key)
|
||||||
|
{
|
||||||
_key = key;
|
_key = key;
|
||||||
LanguageChangedEventManager.AddListener(TranslationManager.Instance, this);
|
LanguageChangedEventManager.AddListener(TranslationManager.Instance, this);
|
||||||
}
|
}
|
||||||
|
@ -19,7 +22,8 @@ namespace Greenshot.Plugin.Confluence.Support {
|
||||||
/// Releases unmanaged resources and performs other cleanup operations before the
|
/// Releases unmanaged resources and performs other cleanup operations before the
|
||||||
/// <see cref="TranslationData"/> is reclaimed by garbage collection.
|
/// <see cref="TranslationData"/> is reclaimed by garbage collection.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
~TranslationData() {
|
~TranslationData()
|
||||||
|
{
|
||||||
LanguageChangedEventManager.RemoveListener(TranslationManager.Instance, this);
|
LanguageChangedEventManager.RemoveListener(TranslationManager.Instance, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,6 +36,7 @@ namespace Greenshot.Plugin.Confluence.Support {
|
||||||
OnLanguageChanged(sender, e);
|
OnLanguageChanged(sender, e);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Confluence.Support {
|
namespace Greenshot.Plugin.Confluence.Support
|
||||||
public class TranslationManager {
|
{
|
||||||
|
public class TranslationManager
|
||||||
|
{
|
||||||
private static TranslationManager _translationManager;
|
private static TranslationManager _translationManager;
|
||||||
|
|
||||||
public event EventHandler LanguageChanged;
|
public event EventHandler LanguageChanged;
|
||||||
|
@ -29,11 +31,14 @@ namespace Greenshot.Plugin.Confluence.Support {
|
||||||
|
|
||||||
public ITranslationProvider TranslationProvider { get; set; }
|
public ITranslationProvider TranslationProvider { get; set; }
|
||||||
|
|
||||||
public object Translate(string key) {
|
public object Translate(string key)
|
||||||
|
{
|
||||||
object translatedValue = TranslationProvider?.Translate(key);
|
object translatedValue = TranslationProvider?.Translate(key);
|
||||||
if( translatedValue != null) {
|
if (translatedValue != null)
|
||||||
|
{
|
||||||
return translatedValue;
|
return translatedValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $"!{key}!";
|
return $"!{key}!";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,12 +25,16 @@ using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Dropbox {
|
namespace Greenshot.Plugin.Dropbox
|
||||||
internal class DropboxDestination : AbstractDestination {
|
{
|
||||||
|
internal class DropboxDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
||||||
|
|
||||||
private readonly DropboxPlugin _plugin;
|
private readonly DropboxPlugin _plugin;
|
||||||
public DropboxDestination(DropboxPlugin plugin) {
|
|
||||||
|
public DropboxDestination(DropboxPlugin plugin)
|
||||||
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,23 +42,29 @@ namespace Greenshot.Plugin.Dropbox {
|
||||||
|
|
||||||
public override string Description => Language.GetString("dropbox", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("dropbox", LangKey.upload_menu_item);
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(DropboxPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(DropboxPlugin));
|
||||||
return (Image) resources.GetObject("Dropbox");
|
return (Image) resources.GetObject("Dropbox");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ExportInformation ExportCapture(bool manually, ISurface surface, ICaptureDetails captureDetails) {
|
public override ExportInformation ExportCapture(bool manually, ISurface surface, ICaptureDetails captureDetails)
|
||||||
|
{
|
||||||
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
||||||
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
||||||
if (uploaded) {
|
if (uploaded)
|
||||||
|
{
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
if (DropboxConfig.AfterUploadLinkToClipBoard) {
|
if (DropboxConfig.AfterUploadLinkToClipBoard)
|
||||||
|
{
|
||||||
ClipboardHelper.SetClipboardData(uploadUrl);
|
ClipboardHelper.SetClipboardData(uploadUrl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,18 +29,21 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Dropbox {
|
namespace Greenshot.Plugin.Dropbox
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the Dropbox base code
|
/// This is the Dropbox base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Dropbox", true)]
|
[Plugin("Dropbox", true)]
|
||||||
public class DropboxPlugin : IGreenshotPlugin {
|
public class DropboxPlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxPlugin));
|
||||||
private static DropboxPluginConfiguration _config;
|
private static DropboxPluginConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _itemPlugInConfig;
|
private ToolStripMenuItem _itemPlugInConfig;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
@ -56,8 +59,8 @@ namespace Greenshot.Plugin.Dropbox {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
_config = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
||||||
_resources = new ComponentResourceManager(typeof(DropboxPlugin));
|
_resources = new ComponentResourceManager(typeof(DropboxPlugin));
|
||||||
|
@ -74,44 +77,49 @@ namespace Greenshot.Plugin.Dropbox {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLanguageChanged(object sender, EventArgs e) {
|
public void OnLanguageChanged(object sender, EventArgs e)
|
||||||
if (_itemPlugInConfig != null) {
|
{
|
||||||
|
if (_itemPlugInConfig != null)
|
||||||
|
{
|
||||||
_itemPlugInConfig.Text = Language.GetString("dropbox", LangKey.Configure);
|
_itemPlugInConfig.Text = Language.GetString("dropbox", LangKey.Configure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
Log.Debug("Dropbox Plugin shutdown.");
|
Log.Debug("Dropbox Plugin shutdown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
public void ConfigMenuClick(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This will be called when the menu item in the Editor is clicked
|
/// This will be called when the menu item in the Editor is clicked
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl)
|
||||||
|
{
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
bool result = false;
|
bool result = false;
|
||||||
new PleaseWaitForm().ShowAndWait("Dropbox", Language.GetString("dropbox", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait("Dropbox", Language.GetString("dropbox", LangKey.communication_wait),
|
||||||
delegate
|
delegate { result = DropboxUtils.UploadToDropbox(surfaceToUpload, outputSettings, captureDetails); }
|
||||||
{
|
|
||||||
result = DropboxUtils.UploadToDropbox(surfaceToUpload, outputSettings, captureDetails);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
return result;
|
return result;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.Error(e);
|
Log.Error(e);
|
||||||
MessageBox.Show(Language.GetString("dropbox", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("dropbox", LangKey.upload_failure) + " " + e.Message);
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -25,12 +25,14 @@ using Greenshot.Plugin.Dropbox.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Dropbox {
|
namespace Greenshot.Plugin.Dropbox
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImgurConfiguration.
|
/// Description of ImgurConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Dropbox", Description = "Greenshot Dropbox Plugin configuration")]
|
[IniSection("Dropbox", Description = "Greenshot Dropbox Plugin configuration")]
|
||||||
public class DropboxPluginConfiguration : IniSection {
|
public class DropboxPluginConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat { get; set; }
|
public OutputFormat UploadFormat { get; set; }
|
||||||
|
|
||||||
|
@ -57,11 +59,14 @@ namespace Greenshot.Plugin.Dropbox {
|
||||||
/// A form for token
|
/// A form for token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog()
|
||||||
|
{
|
||||||
DialogResult result = new SettingsForm().ShowDialog();
|
DialogResult result = new SettingsForm().ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,15 +29,18 @@ using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Dropbox {
|
namespace Greenshot.Plugin.Dropbox
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of DropboxUtils.
|
/// Description of DropboxUtils.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class DropboxUtils {
|
public class DropboxUtils
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxUtils));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(DropboxUtils));
|
||||||
private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
private static readonly DropboxPluginConfiguration DropboxConfig = IniConfig.GetIniSection<DropboxPluginConfiguration>();
|
||||||
|
|
||||||
private DropboxUtils() {
|
private DropboxUtils()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public static bool UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, ICaptureDetails captureDetails)
|
public static bool UploadToDropbox(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, ICaptureDetails captureDetails)
|
||||||
|
@ -62,13 +65,21 @@ namespace Greenshot.Plugin.Dropbox {
|
||||||
|
|
||||||
IDictionary<string, object> arguments = new Dictionary<string, object>
|
IDictionary<string, object> arguments = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "autorename", true },
|
{
|
||||||
{ "mute", true },
|
"autorename", true
|
||||||
{ "path", "/" + filename.Replace(Path.DirectorySeparatorChar, '\\')}
|
},
|
||||||
|
{
|
||||||
|
"mute", true
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"path", "/" + filename.Replace(Path.DirectorySeparatorChar, '\\')
|
||||||
|
}
|
||||||
};
|
};
|
||||||
IDictionary<string, object> headers = new Dictionary<string, object>
|
IDictionary<string, object> headers = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "Dropbox-API-Arg", JsonConvert.SerializeObject(arguments)}
|
{
|
||||||
|
"Dropbox-API-Arg", JsonConvert.SerializeObject(arguments)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, "https://content.dropboxapi.com/2/files/upload", oauth2Settings);
|
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, "https://content.dropboxapi.com/2/files/upload", oauth2Settings);
|
||||||
|
|
||||||
|
@ -78,10 +89,13 @@ namespace Greenshot.Plugin.Dropbox {
|
||||||
var response = JsonConvert.DeserializeObject<IDictionary<string, string>>(responseString);
|
var response = JsonConvert.DeserializeObject<IDictionary<string, string>>(responseString);
|
||||||
return response.ContainsKey("id");
|
return response.ContainsKey("id");
|
||||||
}
|
}
|
||||||
catch (Exception ex) {
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Error("Upload error: ", ex);
|
Log.Error("Upload error: ", ex);
|
||||||
throw;
|
throw;
|
||||||
} finally {
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
DropboxConfig.RefreshToken = oauth2Settings.RefreshToken;
|
DropboxConfig.RefreshToken = oauth2Settings.RefreshToken;
|
||||||
DropboxConfig.AccessToken = oauth2Settings.AccessToken;
|
DropboxConfig.AccessToken = oauth2Settings.AccessToken;
|
||||||
DropboxConfig.AccessTokenExpires = oauth2Settings.AccessTokenExpires;
|
DropboxConfig.AccessTokenExpires = oauth2Settings.AccessTokenExpires;
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Dropbox.Forms {
|
namespace Greenshot.Plugin.Dropbox.Forms
|
||||||
public class DropboxForm : GreenshotForm {
|
{
|
||||||
|
public class DropboxForm : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,12 +19,15 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Dropbox.Forms {
|
namespace Greenshot.Plugin.Dropbox.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : DropboxForm {
|
public partial class SettingsForm : DropboxForm
|
||||||
public SettingsForm() {
|
{
|
||||||
|
public SettingsForm()
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
//
|
//
|
||||||
|
@ -32,6 +35,5 @@ namespace Greenshot.Plugin.Dropbox.Forms {
|
||||||
AcceptButton = buttonOK;
|
AcceptButton = buttonOK;
|
||||||
CancelButton = buttonCancel;
|
CancelButton = buttonCancel;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,8 +18,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
namespace Greenshot.Plugin.Dropbox {
|
|
||||||
public enum LangKey {
|
namespace Greenshot.Plugin.Dropbox
|
||||||
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
upload_failure,
|
upload_failure,
|
||||||
communication_wait,
|
communication_wait,
|
||||||
|
|
|
@ -25,31 +25,42 @@ using System.IO;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.ExternalCommand {
|
namespace Greenshot.Plugin.ExternalCommand
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of FlickrConfiguration.
|
/// Description of FlickrConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("ExternalCommand", Description = "Greenshot ExternalCommand Plugin configuration")]
|
[IniSection("ExternalCommand", Description = "Greenshot ExternalCommand Plugin configuration")]
|
||||||
public class ExternalCommandConfiguration : IniSection {
|
public class ExternalCommandConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("Commands", Description = "The commands that are available.")]
|
[IniProperty("Commands", Description = "The commands that are available.")]
|
||||||
public List<string> Commands { get; set; }
|
public List<string> Commands { get; set; }
|
||||||
|
|
||||||
[IniProperty("RedirectStandardError", Description = "Redirect the standard error of all external commands, used to output as warning to the greenshot.log.", DefaultValue = "true")]
|
[IniProperty("RedirectStandardError", Description = "Redirect the standard error of all external commands, used to output as warning to the greenshot.log.",
|
||||||
|
DefaultValue = "true")]
|
||||||
public bool RedirectStandardError { get; set; }
|
public bool RedirectStandardError { get; set; }
|
||||||
|
|
||||||
[IniProperty("RedirectStandardOutput", Description = "Redirect the standard output of all external commands, used for different other functions (more below).", DefaultValue = "true")]
|
[IniProperty("RedirectStandardOutput", Description = "Redirect the standard output of all external commands, used for different other functions (more below).",
|
||||||
|
DefaultValue = "true")]
|
||||||
public bool RedirectStandardOutput { get; set; }
|
public bool RedirectStandardOutput { get; set; }
|
||||||
|
|
||||||
[IniProperty("ShowStandardOutputInLog", Description = "Depends on 'RedirectStandardOutput': Show standard output of all external commands to the Greenshot log, this can be usefull for debugging.", DefaultValue = "false")]
|
[IniProperty("ShowStandardOutputInLog",
|
||||||
|
Description = "Depends on 'RedirectStandardOutput': Show standard output of all external commands to the Greenshot log, this can be usefull for debugging.",
|
||||||
|
DefaultValue = "false")]
|
||||||
public bool ShowStandardOutputInLog { get; set; }
|
public bool ShowStandardOutputInLog { get; set; }
|
||||||
|
|
||||||
[IniProperty("ParseForUri", Description = "Depends on 'RedirectStandardOutput': Parse the output and take the first found URI, if a URI is found than clicking on the notify bubble goes there.", DefaultValue = "true")]
|
[IniProperty("ParseForUri",
|
||||||
|
Description = "Depends on 'RedirectStandardOutput': Parse the output and take the first found URI, if a URI is found than clicking on the notify bubble goes there.",
|
||||||
|
DefaultValue = "true")]
|
||||||
public bool ParseOutputForUri { get; set; }
|
public bool ParseOutputForUri { get; set; }
|
||||||
|
|
||||||
[IniProperty("OutputToClipboard", Description = "Depends on 'RedirectStandardOutput': Place the standard output on the clipboard.", DefaultValue = "false")]
|
[IniProperty("OutputToClipboard", Description = "Depends on 'RedirectStandardOutput': Place the standard output on the clipboard.", DefaultValue = "false")]
|
||||||
public bool OutputToClipboard { get; set; }
|
public bool OutputToClipboard { get; set; }
|
||||||
|
|
||||||
[IniProperty("UriToClipboard", Description = "Depends on 'RedirectStandardOutput' & 'ParseForUri': If an URI is found in the standard input, place it on the clipboard. (This overwrites the output from OutputToClipboard setting.)", DefaultValue = "true")]
|
[IniProperty("UriToClipboard",
|
||||||
|
Description =
|
||||||
|
"Depends on 'RedirectStandardOutput' & 'ParseForUri': If an URI is found in the standard input, place it on the clipboard. (This overwrites the output from OutputToClipboard setting.)",
|
||||||
|
DefaultValue = "true")]
|
||||||
public bool UriToClipboard { get; set; }
|
public bool UriToClipboard { get; set; }
|
||||||
|
|
||||||
[IniProperty("Commandline", Description = "The commandline for the output command.")]
|
[IniProperty("Commandline", Description = "The commandline for the output command.")]
|
||||||
|
@ -71,13 +82,19 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
private const string PaintDotNet = "Paint.NET";
|
private const string PaintDotNet = "Paint.NET";
|
||||||
private static readonly string PaintDotNetPath;
|
private static readonly string PaintDotNetPath;
|
||||||
private static readonly bool HasPaintDotNet;
|
private static readonly bool HasPaintDotNet;
|
||||||
static ExternalCommandConfiguration() {
|
|
||||||
try {
|
static ExternalCommandConfiguration()
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
PaintPath = PluginUtils.GetExePath("pbrush.exe");
|
PaintPath = PluginUtils.GetExePath("pbrush.exe");
|
||||||
HasPaint = !string.IsNullOrEmpty(PaintPath) && File.Exists(PaintPath);
|
HasPaint = !string.IsNullOrEmpty(PaintPath) && File.Exists(PaintPath);
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
// Ignore
|
// Ignore
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
PaintDotNetPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Paint.NET\PaintDotNet.exe");
|
PaintDotNetPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles), @"Paint.NET\PaintDotNet.exe");
|
||||||
|
@ -99,6 +116,7 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Commands.Remove(command);
|
Commands.Remove(command);
|
||||||
Commandline.Remove(command);
|
Commandline.Remove(command);
|
||||||
Argument.Remove(command);
|
Argument.Remove(command);
|
||||||
|
|
|
@ -31,17 +31,24 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.ExternalCommand {
|
namespace Greenshot.Plugin.ExternalCommand
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of OCRDestination.
|
/// Description of OCRDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ExternalCommandDestination : AbstractDestination {
|
public class ExternalCommandDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ExternalCommandDestination));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(ExternalCommandDestination));
|
||||||
private static readonly Regex URI_REGEXP = new Regex(@"((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)");
|
|
||||||
|
private static readonly Regex URI_REGEXP =
|
||||||
|
new Regex(
|
||||||
|
@"((([A-Za-z]{3,9}:(?:\/\/)?)(?:[\-;:&=\+\$,\w]+@)?[A-Za-z0-9\.\-]+|(?:www\.|[\-;:&=\+\$,\w]+@)[A-Za-z0-9\.\-]+)((?:\/[\+~%\/\.\w\-_]*)?\??(?:[\-\+=&;%@\.\w_]*)#?(?:[\.\!\/\\\w]*))?)");
|
||||||
|
|
||||||
private static readonly ExternalCommandConfiguration config = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
private static readonly ExternalCommandConfiguration config = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
||||||
private readonly string _presetCommand;
|
private readonly string _presetCommand;
|
||||||
|
|
||||||
public ExternalCommandDestination(string commando) {
|
public ExternalCommandDestination(string commando)
|
||||||
|
{
|
||||||
_presetCommand = commando;
|
_presetCommand = commando;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -49,27 +56,33 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
|
|
||||||
public override string Description => _presetCommand;
|
public override string Description => _presetCommand;
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Image DisplayIcon => IconCache.IconForCommand(_presetCommand);
|
public override Image DisplayIcon => 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();
|
outputSettings.PreventGreenshotFormat();
|
||||||
|
|
||||||
if (_presetCommand != null) {
|
if (_presetCommand != null)
|
||||||
if (!config.RunInbackground.ContainsKey(_presetCommand)) {
|
{
|
||||||
|
if (!config.RunInbackground.ContainsKey(_presetCommand))
|
||||||
|
{
|
||||||
config.RunInbackground.Add(_presetCommand, true);
|
config.RunInbackground.Add(_presetCommand, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool runInBackground = config.RunInbackground[_presetCommand];
|
bool runInBackground = config.RunInbackground[_presetCommand];
|
||||||
string fullPath = captureDetails.Filename ?? ImageOutput.SaveNamedTmpFile(surface, captureDetails, outputSettings);
|
string fullPath = captureDetails.Filename ?? ImageOutput.SaveNamedTmpFile(surface, captureDetails, outputSettings);
|
||||||
|
|
||||||
string output;
|
string output;
|
||||||
string error;
|
string error;
|
||||||
if (runInBackground) {
|
if (runInBackground)
|
||||||
|
{
|
||||||
Thread commandThread = new Thread(delegate()
|
Thread commandThread = new Thread(delegate()
|
||||||
{
|
{
|
||||||
CallExternalCommand(exportInformation, fullPath, out output, out error);
|
CallExternalCommand(exportInformation, fullPath, out output, out error);
|
||||||
|
@ -82,11 +95,14 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
commandThread.SetApartmentState(ApartmentState.STA);
|
commandThread.SetApartmentState(ApartmentState.STA);
|
||||||
commandThread.Start();
|
commandThread.Start();
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
CallExternalCommand(exportInformation, fullPath, out output, out error);
|
CallExternalCommand(exportInformation, fullPath, out output, out error);
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,32 +114,44 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
/// <param name="fullPath"></param>
|
/// <param name="fullPath"></param>
|
||||||
/// <param name="output"></param>
|
/// <param name="output"></param>
|
||||||
/// <param name="error"></param>
|
/// <param name="error"></param>
|
||||||
private void CallExternalCommand(ExportInformation exportInformation, string fullPath, out string output, out string error) {
|
private void CallExternalCommand(ExportInformation exportInformation, string fullPath, out string output, out string error)
|
||||||
|
{
|
||||||
output = null;
|
output = null;
|
||||||
error = null;
|
error = null;
|
||||||
try {
|
try
|
||||||
if (CallExternalCommand(_presetCommand, fullPath, out output, out error) == 0) {
|
{
|
||||||
|
if (CallExternalCommand(_presetCommand, fullPath, out output, out error) == 0)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
if (!string.IsNullOrEmpty(output)) {
|
if (!string.IsNullOrEmpty(output))
|
||||||
|
{
|
||||||
MatchCollection uriMatches = URI_REGEXP.Matches(output);
|
MatchCollection uriMatches = URI_REGEXP.Matches(output);
|
||||||
// Place output on the clipboard before the URI, so if one is found this overwrites
|
// Place output on the clipboard before the URI, so if one is found this overwrites
|
||||||
if (config.OutputToClipboard) {
|
if (config.OutputToClipboard)
|
||||||
|
{
|
||||||
ClipboardHelper.SetClipboardData(output);
|
ClipboardHelper.SetClipboardData(output);
|
||||||
}
|
}
|
||||||
if (uriMatches.Count > 0) {
|
|
||||||
|
if (uriMatches.Count > 0)
|
||||||
|
{
|
||||||
exportInformation.Uri = uriMatches[0].Groups[1].Value;
|
exportInformation.Uri = uriMatches[0].Groups[1].Value;
|
||||||
LOG.InfoFormat("Got URI : {0} ", exportInformation.Uri);
|
LOG.InfoFormat("Got URI : {0} ", exportInformation.Uri);
|
||||||
if (config.UriToClipboard) {
|
if (config.UriToClipboard)
|
||||||
|
{
|
||||||
ClipboardHelper.SetClipboardData(exportInformation.Uri);
|
ClipboardHelper.SetClipboardData(exportInformation.Uri);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
LOG.WarnFormat("Error calling external command: {0} ", output);
|
LOG.WarnFormat("Error calling external command: {0} ", output);
|
||||||
exportInformation.ExportMade = false;
|
exportInformation.ExportMade = false;
|
||||||
exportInformation.ErrorMessage = error;
|
exportInformation.ErrorMessage = error;
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = false;
|
exportInformation.ExportMade = false;
|
||||||
exportInformation.ErrorMessage = ex.Message;
|
exportInformation.ErrorMessage = ex.Message;
|
||||||
LOG.WarnFormat("Error calling external command: {0} ", exportInformation.ErrorMessage);
|
LOG.WarnFormat("Error calling external command: {0} ", exportInformation.ErrorMessage);
|
||||||
|
@ -138,18 +166,27 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
/// <param name="output"></param>
|
/// <param name="output"></param>
|
||||||
/// <param name="error"></param>
|
/// <param name="error"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
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) {
|
}
|
||||||
try {
|
catch (Win32Exception w32Ex)
|
||||||
|
{
|
||||||
|
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)
|
||||||
|
{
|
||||||
ex.Data.Add("commandline", config.Commandline[_presetCommand]);
|
ex.Data.Add("commandline", config.Commandline[_presetCommand]);
|
||||||
ex.Data.Add("arguments", config.Argument[_presetCommand]);
|
ex.Data.Add("arguments", config.Argument[_presetCommand]);
|
||||||
throw;
|
throw;
|
||||||
|
@ -165,7 +202,8 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
/// <param name="output"></param>
|
/// <param name="output"></param>
|
||||||
/// <param name="error"></param>
|
/// <param name="error"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private int CallExternalCommand(string commando, string fullPath, string verb, out string output, out string error) {
|
private int CallExternalCommand(string commando, string fullPath, string verb, out string output, out string error)
|
||||||
|
{
|
||||||
string commandline = config.Commandline[commando];
|
string commandline = config.Commandline[commando];
|
||||||
string arguments = config.Argument[commando];
|
string arguments = config.Argument[commando];
|
||||||
output = null;
|
output = null;
|
||||||
|
@ -183,33 +221,46 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
process.StartInfo.FileName = FilenameHelper.FillCmdVariables(commandline, true);
|
process.StartInfo.FileName = FilenameHelper.FillCmdVariables(commandline, true);
|
||||||
process.StartInfo.Arguments = FormatArguments(arguments, fullPath);
|
process.StartInfo.Arguments = FormatArguments(arguments, fullPath);
|
||||||
process.StartInfo.UseShellExecute = false;
|
process.StartInfo.UseShellExecute = false;
|
||||||
if (config.RedirectStandardOutput) {
|
if (config.RedirectStandardOutput)
|
||||||
|
{
|
||||||
process.StartInfo.RedirectStandardOutput = true;
|
process.StartInfo.RedirectStandardOutput = true;
|
||||||
}
|
}
|
||||||
if (config.RedirectStandardError) {
|
|
||||||
|
if (config.RedirectStandardError)
|
||||||
|
{
|
||||||
process.StartInfo.RedirectStandardError = true;
|
process.StartInfo.RedirectStandardError = true;
|
||||||
}
|
}
|
||||||
if (verb != null) {
|
|
||||||
|
if (verb != null)
|
||||||
|
{
|
||||||
process.StartInfo.Verb = verb;
|
process.StartInfo.Verb = verb;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.InfoFormat("Starting : {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
LOG.InfoFormat("Starting : {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
||||||
process.Start();
|
process.Start();
|
||||||
process.WaitForExit();
|
process.WaitForExit();
|
||||||
if (config.RedirectStandardOutput) {
|
if (config.RedirectStandardOutput)
|
||||||
|
{
|
||||||
output = process.StandardOutput.ReadToEnd();
|
output = process.StandardOutput.ReadToEnd();
|
||||||
if (config.ShowStandardOutputInLog && output.Trim().Length > 0) {
|
if (config.ShowStandardOutputInLog && output.Trim().Length > 0)
|
||||||
|
{
|
||||||
LOG.InfoFormat("Output:\n{0}", output);
|
LOG.InfoFormat("Output:\n{0}", output);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (config.RedirectStandardError) {
|
|
||||||
|
if (config.RedirectStandardError)
|
||||||
|
{
|
||||||
error = process.StandardError.ReadToEnd();
|
error = process.StandardError.ReadToEnd();
|
||||||
if (error.Trim().Length > 0) {
|
if (error.Trim().Length > 0)
|
||||||
|
{
|
||||||
LOG.WarnFormat("Error:\n{0}", error);
|
LOG.WarnFormat("Error:\n{0}", error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.InfoFormat("Finished : {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
LOG.InfoFormat("Finished : {0} {1}", process.StartInfo.FileName, process.StartInfo.Arguments);
|
||||||
return process.ExitCode;
|
return process.ExitCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.ExternalCommand {
|
namespace Greenshot.Plugin.ExternalCommand
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class is needed for design-time resolving of the language files
|
/// This class is needed for design-time resolving of the language files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ExternalCommandForm : GreenshotForm {
|
public class ExternalCommandForm : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -55,6 +55,7 @@ namespace Greenshot.Plugin.ExternalCommand
|
||||||
_itemPlugInRoot.Dispose();
|
_itemPlugInRoot.Dispose();
|
||||||
_itemPlugInRoot = null;
|
_itemPlugInRoot = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IDestination> Destinations()
|
private IEnumerable<IDestination> Destinations()
|
||||||
{
|
{
|
||||||
foreach (string command in ExternalCommandConfig.Commands)
|
foreach (string command in ExternalCommandConfig.Commands)
|
||||||
|
@ -77,17 +78,20 @@ namespace Greenshot.Plugin.ExternalCommand
|
||||||
// Fix it
|
// Fix it
|
||||||
ExternalCommandConfig.RunInbackground.Add(command, true);
|
ExternalCommandConfig.RunInbackground.Add(command, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ExternalCommandConfig.Argument.ContainsKey(command))
|
if (!ExternalCommandConfig.Argument.ContainsKey(command))
|
||||||
{
|
{
|
||||||
Log.WarnFormat("Found missing argument for {0}", command);
|
Log.WarnFormat("Found missing argument for {0}", command);
|
||||||
// Fix it
|
// Fix it
|
||||||
ExternalCommandConfig.Argument.Add(command, "{0}");
|
ExternalCommandConfig.Argument.Add(command, "{0}");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ExternalCommandConfig.Commandline.ContainsKey(command))
|
if (!ExternalCommandConfig.Commandline.ContainsKey(command))
|
||||||
{
|
{
|
||||||
Log.WarnFormat("Found missing commandline for {0}", command);
|
Log.WarnFormat("Found missing commandline for {0}", command);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
string commandline = FilenameHelper.FillVariables(ExternalCommandConfig.Commandline[command], true);
|
string commandline = FilenameHelper.FillVariables(ExternalCommandConfig.Commandline[command], true);
|
||||||
commandline = FilenameHelper.FillCmdVariables(commandline, true);
|
commandline = FilenameHelper.FillCmdVariables(commandline, true);
|
||||||
|
|
||||||
|
@ -96,8 +100,10 @@ namespace Greenshot.Plugin.ExternalCommand
|
||||||
Log.WarnFormat("Found 'invalid' commandline {0} for command {1}", ExternalCommandConfig.Commandline[command], command);
|
Log.WarnFormat("Found 'invalid' commandline {0} for command {1}", ExternalCommandConfig.Commandline[command], command);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -114,11 +120,13 @@ namespace Greenshot.Plugin.ExternalCommand
|
||||||
commandsToDelete.Add(command);
|
commandsToDelete.Add(command);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// cleanup
|
// cleanup
|
||||||
foreach (string command in commandsToDelete)
|
foreach (string command in commandsToDelete)
|
||||||
{
|
{
|
||||||
ExternalCommandConfig.Delete(command);
|
ExternalCommandConfig.Delete(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleServiceProvider.Current.AddService(Destinations());
|
SimpleServiceProvider.Current.AddService(Destinations());
|
||||||
|
|
||||||
_itemPlugInRoot = new ToolStripMenuItem();
|
_itemPlugInRoot = new ToolStripMenuItem();
|
||||||
|
|
|
@ -25,22 +25,31 @@ using System.IO;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.ExternalCommand {
|
namespace Greenshot.Plugin.ExternalCommand
|
||||||
public static class IconCache {
|
{
|
||||||
|
public static class IconCache
|
||||||
|
{
|
||||||
private static readonly ExternalCommandConfiguration config = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
private static readonly ExternalCommandConfiguration config = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(IconCache));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(IconCache));
|
||||||
|
|
||||||
public static Image IconForCommand(string commandName) {
|
public static Image IconForCommand(string commandName)
|
||||||
|
{
|
||||||
Image icon = null;
|
Image icon = null;
|
||||||
if (commandName != null) {
|
if (commandName != null)
|
||||||
if (config.Commandline.ContainsKey(commandName) && File.Exists(config.Commandline[commandName])) {
|
{
|
||||||
try {
|
if (config.Commandline.ContainsKey(commandName) && File.Exists(config.Commandline[commandName]))
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
icon = PluginUtils.GetCachedExeIcon(config.Commandline[commandName], 0);
|
icon = PluginUtils.GetCachedExeIcon(config.Commandline[commandName], 0);
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.Warn("Problem loading icon for " + config.Commandline[commandName], ex);
|
LOG.Warn("Problem loading icon for " + config.Commandline[commandName], ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return icon;
|
return icon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,14 +24,17 @@ using System.Drawing;
|
||||||
using System.Windows.Forms;
|
using System.Windows.Forms;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.ExternalCommand {
|
namespace Greenshot.Plugin.ExternalCommand
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of SettingsForm.
|
/// Description of SettingsForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : ExternalCommandForm {
|
public partial class SettingsForm : ExternalCommandForm
|
||||||
|
{
|
||||||
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
||||||
|
|
||||||
public SettingsForm() {
|
public SettingsForm()
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
//
|
//
|
||||||
|
@ -41,65 +44,83 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
UpdateView();
|
UpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonOkClick(object sender, EventArgs e) {
|
private void ButtonOkClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonAddClick(object sender, EventArgs e) {
|
private void ButtonAddClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
var form = new SettingsFormDetail(null);
|
var form = new SettingsFormDetail(null);
|
||||||
form.ShowDialog();
|
form.ShowDialog();
|
||||||
|
|
||||||
UpdateView();
|
UpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonDeleteClick(object sender, EventArgs e) {
|
private void ButtonDeleteClick(object sender, EventArgs e)
|
||||||
foreach(ListViewItem item in listView1.SelectedItems) {
|
{
|
||||||
|
foreach (ListViewItem item in listView1.SelectedItems)
|
||||||
|
{
|
||||||
string commando = item.Tag as string;
|
string commando = item.Tag as string;
|
||||||
|
|
||||||
ExternalCommandConfig.Delete(commando);
|
ExternalCommandConfig.Delete(commando);
|
||||||
}
|
}
|
||||||
|
|
||||||
UpdateView();
|
UpdateView();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateView() {
|
private void UpdateView()
|
||||||
|
{
|
||||||
listView1.Items.Clear();
|
listView1.Items.Clear();
|
||||||
if(ExternalCommandConfig.Commands != null) {
|
if (ExternalCommandConfig.Commands != null)
|
||||||
|
{
|
||||||
listView1.ListViewItemSorter = new ListviewComparer();
|
listView1.ListViewItemSorter = new ListviewComparer();
|
||||||
ImageList imageList = new ImageList();
|
ImageList imageList = new ImageList();
|
||||||
listView1.SmallImageList = imageList;
|
listView1.SmallImageList = imageList;
|
||||||
int imageNr = 0;
|
int imageNr = 0;
|
||||||
foreach(string commando in ExternalCommandConfig.Commands) {
|
foreach (string commando in ExternalCommandConfig.Commands)
|
||||||
|
{
|
||||||
ListViewItem item;
|
ListViewItem item;
|
||||||
Image iconForExe = IconCache.IconForCommand(commando);
|
Image iconForExe = IconCache.IconForCommand(commando);
|
||||||
if(iconForExe != null) {
|
if (iconForExe != null)
|
||||||
|
{
|
||||||
imageList.Images.Add(iconForExe);
|
imageList.Images.Add(iconForExe);
|
||||||
item = new ListViewItem(commando, imageNr++);
|
item = new ListViewItem(commando, imageNr++);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
item = new ListViewItem(commando);
|
item = new ListViewItem(commando);
|
||||||
}
|
}
|
||||||
|
|
||||||
item.Tag = commando;
|
item.Tag = commando;
|
||||||
listView1.Items.Add(item);
|
listView1.Items.Add(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Fix for bug #1484, getting an ArgumentOutOfRangeException as there is nothing selected but the edit button was still active.
|
// Fix for bug #1484, getting an ArgumentOutOfRangeException as there is nothing selected but the edit button was still active.
|
||||||
button_edit.Enabled = listView1.SelectedItems.Count > 0;
|
button_edit.Enabled = listView1.SelectedItems.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListView1ItemSelectionChanged(object sender, EventArgs e) {
|
private void ListView1ItemSelectionChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
button_edit.Enabled = listView1.SelectedItems.Count > 0;
|
button_edit.Enabled = listView1.SelectedItems.Count > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonEditClick(object sender, EventArgs e) {
|
private void ButtonEditClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
ListView1DoubleClick(sender, e);
|
ListView1DoubleClick(sender, e);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ListView1DoubleClick(object sender, EventArgs e) {
|
private void ListView1DoubleClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
// Safety check for bug #1484
|
// Safety check for bug #1484
|
||||||
bool selectionActive = listView1.SelectedItems.Count > 0;
|
bool selectionActive = listView1.SelectedItems.Count > 0;
|
||||||
if(!selectionActive) {
|
if (!selectionActive)
|
||||||
|
{
|
||||||
button_edit.Enabled = false;
|
button_edit.Enabled = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string commando = listView1.SelectedItems[0].Tag as string;
|
string commando = listView1.SelectedItems[0].Tag as string;
|
||||||
|
|
||||||
var form = new SettingsFormDetail(commando);
|
var form = new SettingsFormDetail(commando);
|
||||||
|
@ -109,12 +130,17 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ListviewComparer : System.Collections.IComparer {
|
public class ListviewComparer : System.Collections.IComparer
|
||||||
public int Compare(object x, object y) {
|
{
|
||||||
if(!(x is ListViewItem)) {
|
public int Compare(object x, object y)
|
||||||
|
{
|
||||||
|
if (!(x is ListViewItem))
|
||||||
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
if(!(y is ListViewItem)) {
|
|
||||||
|
if (!(y is ListViewItem))
|
||||||
|
{
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,52 +26,64 @@ using System.Windows.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.ExternalCommand {
|
namespace Greenshot.Plugin.ExternalCommand
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of SettingsFormDetail.
|
/// Description of SettingsFormDetail.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsFormDetail : ExternalCommandForm {
|
public partial class SettingsFormDetail : ExternalCommandForm
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(SettingsFormDetail));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(SettingsFormDetail));
|
||||||
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
private static readonly ExternalCommandConfiguration ExternalCommandConfig = IniConfig.GetIniSection<ExternalCommandConfiguration>();
|
||||||
|
|
||||||
private readonly string _commando;
|
private readonly string _commando;
|
||||||
private readonly int _commandIndex;
|
private readonly int _commandIndex;
|
||||||
|
|
||||||
public SettingsFormDetail(string commando) {
|
public SettingsFormDetail(string commando)
|
||||||
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
AcceptButton = buttonOk;
|
AcceptButton = buttonOk;
|
||||||
CancelButton = buttonCancel;
|
CancelButton = buttonCancel;
|
||||||
_commando = commando;
|
_commando = commando;
|
||||||
|
|
||||||
if(commando != null) {
|
if (commando != null)
|
||||||
|
{
|
||||||
textBox_name.Text = commando;
|
textBox_name.Text = commando;
|
||||||
textBox_commandline.Text = ExternalCommandConfig.Commandline[commando];
|
textBox_commandline.Text = ExternalCommandConfig.Commandline[commando];
|
||||||
textBox_arguments.Text = ExternalCommandConfig.Argument[commando];
|
textBox_arguments.Text = ExternalCommandConfig.Argument[commando];
|
||||||
_commandIndex = ExternalCommandConfig.Commands.FindIndex(s => s == commando);
|
_commandIndex = ExternalCommandConfig.Commands.FindIndex(s => s == commando);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
textBox_arguments.Text = "\"{0}\"";
|
textBox_arguments.Text = "\"{0}\"";
|
||||||
}
|
}
|
||||||
|
|
||||||
OkButtonState();
|
OkButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonOkClick(object sender, EventArgs e) {
|
private void ButtonOkClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
string commandName = textBox_name.Text;
|
string commandName = textBox_name.Text;
|
||||||
string commandLine = textBox_commandline.Text;
|
string commandLine = textBox_commandline.Text;
|
||||||
string arguments = textBox_arguments.Text;
|
string arguments = textBox_arguments.Text;
|
||||||
if(_commando != null) {
|
if (_commando != null)
|
||||||
|
{
|
||||||
ExternalCommandConfig.Commands[_commandIndex] = commandName;
|
ExternalCommandConfig.Commands[_commandIndex] = commandName;
|
||||||
ExternalCommandConfig.Commandline.Remove(_commando);
|
ExternalCommandConfig.Commandline.Remove(_commando);
|
||||||
ExternalCommandConfig.Commandline.Add(commandName, commandLine);
|
ExternalCommandConfig.Commandline.Add(commandName, commandLine);
|
||||||
ExternalCommandConfig.Argument.Remove(_commando);
|
ExternalCommandConfig.Argument.Remove(_commando);
|
||||||
ExternalCommandConfig.Argument.Add(commandName, arguments);
|
ExternalCommandConfig.Argument.Add(commandName, arguments);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ExternalCommandConfig.Commands.Add(commandName);
|
ExternalCommandConfig.Commands.Add(commandName);
|
||||||
ExternalCommandConfig.Commandline.Add(commandName, commandLine);
|
ExternalCommandConfig.Commandline.Add(commandName, commandLine);
|
||||||
ExternalCommandConfig.Argument.Add(commandName, arguments);
|
ExternalCommandConfig.Argument.Add(commandName, arguments);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Button3Click(object sender, EventArgs e) {
|
private void Button3Click(object sender, EventArgs e)
|
||||||
|
{
|
||||||
var openFileDialog = new OpenFileDialog
|
var openFileDialog = new OpenFileDialog
|
||||||
{
|
{
|
||||||
Filter = "Executables (*.exe, *.bat, *.com)|*.exe; *.bat; *.com|All files (*)|*",
|
Filter = "Executables (*.exe, *.bat, *.com)|*.exe; *.bat; *.com|All files (*)|*",
|
||||||
|
@ -89,35 +101,47 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
Log.WarnFormat("Can't get the initial path via {0}", textBox_commandline.Text);
|
Log.WarnFormat("Can't get the initial path via {0}", textBox_commandline.Text);
|
||||||
Log.Warn("Exception: ", ex);
|
Log.Warn("Exception: ", ex);
|
||||||
}
|
}
|
||||||
if(initialPath != null && Directory.Exists(initialPath)) {
|
|
||||||
|
if (initialPath != null && Directory.Exists(initialPath))
|
||||||
|
{
|
||||||
openFileDialog.InitialDirectory = initialPath;
|
openFileDialog.InitialDirectory = initialPath;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
initialPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
|
initialPath = Environment.GetFolderPath(Environment.SpecialFolder.ProgramFiles);
|
||||||
openFileDialog.InitialDirectory = initialPath;
|
openFileDialog.InitialDirectory = initialPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.DebugFormat("Starting OpenFileDialog at {0}", initialPath);
|
Log.DebugFormat("Starting OpenFileDialog at {0}", initialPath);
|
||||||
if(openFileDialog.ShowDialog() == DialogResult.OK) {
|
if (openFileDialog.ShowDialog() == DialogResult.OK)
|
||||||
|
{
|
||||||
textBox_commandline.Text = openFileDialog.FileName;
|
textBox_commandline.Text = openFileDialog.FileName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OkButtonState() {
|
private void OkButtonState()
|
||||||
|
{
|
||||||
// Assume OK
|
// Assume OK
|
||||||
buttonOk.Enabled = true;
|
buttonOk.Enabled = true;
|
||||||
textBox_name.BackColor = Color.White;
|
textBox_name.BackColor = Color.White;
|
||||||
textBox_commandline.BackColor = Color.White;
|
textBox_commandline.BackColor = Color.White;
|
||||||
textBox_arguments.BackColor = Color.White;
|
textBox_arguments.BackColor = Color.White;
|
||||||
// Is there a text in the name field
|
// Is there a text in the name field
|
||||||
if(string.IsNullOrEmpty(textBox_name.Text)) {
|
if (string.IsNullOrEmpty(textBox_name.Text))
|
||||||
|
{
|
||||||
buttonOk.Enabled = false;
|
buttonOk.Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if commandname is unique
|
// Check if commandname is unique
|
||||||
if(_commando == null && !string.IsNullOrEmpty(textBox_name.Text) && ExternalCommandConfig.Commands.Contains(textBox_name.Text)) {
|
if (_commando == null && !string.IsNullOrEmpty(textBox_name.Text) && ExternalCommandConfig.Commands.Contains(textBox_name.Text))
|
||||||
|
{
|
||||||
buttonOk.Enabled = false;
|
buttonOk.Enabled = false;
|
||||||
textBox_name.BackColor = Color.Red;
|
textBox_name.BackColor = Color.Red;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Is there a text in the commandline field
|
// Is there a text in the commandline field
|
||||||
if(string.IsNullOrEmpty(textBox_commandline.Text)) {
|
if (string.IsNullOrEmpty(textBox_commandline.Text))
|
||||||
|
{
|
||||||
buttonOk.Enabled = false;
|
buttonOk.Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,6 +158,7 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
textBox_commandline.BackColor = Color.Red;
|
textBox_commandline.BackColor = Color.Red;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Are the arguments in a valid format?
|
// Are the arguments in a valid format?
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -149,11 +174,13 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void textBox_name_TextChanged(object sender, EventArgs e) {
|
private void textBox_name_TextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
OkButtonState();
|
OkButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void textBox_commandline_TextChanged(object sender, EventArgs e) {
|
private void textBox_commandline_TextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
OkButtonState();
|
OkButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -161,6 +188,5 @@ namespace Greenshot.Plugin.ExternalCommand {
|
||||||
{
|
{
|
||||||
OkButtonState();
|
OkButtonState();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,17 +24,21 @@ using Greenshot.Plugin.Flickr.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Flickr {
|
namespace Greenshot.Plugin.Flickr
|
||||||
public enum SafetyLevel {
|
{
|
||||||
|
public enum SafetyLevel
|
||||||
|
{
|
||||||
Safe = 1,
|
Safe = 1,
|
||||||
Moderate = 2,
|
Moderate = 2,
|
||||||
Restricted = 3
|
Restricted = 3
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of FlickrConfiguration.
|
/// Description of FlickrConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Flickr", Description = "Greenshot Flickr Plugin configuration")]
|
[IniSection("Flickr", Description = "Greenshot Flickr Plugin configuration")]
|
||||||
public class FlickrConfiguration : IniSection {
|
public class FlickrConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("flickrIsPublic", Description = "IsPublic.", DefaultValue = "true")]
|
[IniProperty("flickrIsPublic", Description = "IsPublic.", DefaultValue = "true")]
|
||||||
public bool IsPublic { get; set; }
|
public bool IsPublic { get; set; }
|
||||||
|
|
||||||
|
@ -64,6 +68,7 @@ namespace Greenshot.Plugin.Flickr {
|
||||||
|
|
||||||
[IniProperty("FlickrToken", Description = "The Flickr token", Encrypted = true, ExcludeIfNull = true)]
|
[IniProperty("FlickrToken", Description = "The Flickr token", Encrypted = true, ExcludeIfNull = true)]
|
||||||
public string FlickrToken { get; set; }
|
public string FlickrToken { get; set; }
|
||||||
|
|
||||||
[IniProperty("FlickrTokenSecret", Description = "The Flickr token secret", Encrypted = true, ExcludeIfNull = true)]
|
[IniProperty("FlickrTokenSecret", Description = "The Flickr token secret", Encrypted = true, ExcludeIfNull = true)]
|
||||||
public string FlickrTokenSecret { get; set; }
|
public string FlickrTokenSecret { get; set; }
|
||||||
|
|
||||||
|
@ -71,11 +76,14 @@ namespace Greenshot.Plugin.Flickr {
|
||||||
/// A form for token
|
/// A form for token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog()
|
||||||
|
{
|
||||||
DialogResult result = new SettingsForm().ShowDialog();
|
DialogResult result = new SettingsForm().ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,14 @@ using System.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Flickr {
|
namespace Greenshot.Plugin.Flickr
|
||||||
public class FlickrDestination : AbstractDestination {
|
{
|
||||||
|
public class FlickrDestination : AbstractDestination
|
||||||
|
{
|
||||||
private readonly FlickrPlugin _plugin;
|
private readonly FlickrPlugin _plugin;
|
||||||
public FlickrDestination(FlickrPlugin plugin) {
|
|
||||||
|
public FlickrDestination(FlickrPlugin plugin)
|
||||||
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,20 +39,25 @@ namespace Greenshot.Plugin.Flickr {
|
||||||
|
|
||||||
public override string Description => Language.GetString("flickr", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("flickr", LangKey.upload_menu_item);
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(FlickrPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(FlickrPlugin));
|
||||||
return (Image) resources.GetObject("flickr");
|
return (Image) resources.GetObject("flickr");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
||||||
if (uploaded) {
|
if (uploaded)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -37,24 +37,31 @@ namespace Greenshot.Plugin.Flickr
|
||||||
/// This is the Flickr base code
|
/// This is the Flickr base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Flickr", true)]
|
[Plugin("Flickr", true)]
|
||||||
public class FlickrPlugin : IGreenshotPlugin {
|
public class FlickrPlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(FlickrPlugin));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(FlickrPlugin));
|
||||||
private static FlickrConfiguration _config;
|
private static FlickrConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _itemPlugInConfig;
|
private ToolStripMenuItem _itemPlugInConfig;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
protected void Dispose(bool disposing)
|
||||||
if (!disposing) {
|
{
|
||||||
|
if (!disposing)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_itemPlugInConfig == null) {
|
|
||||||
|
if (_itemPlugInConfig == null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_itemPlugInConfig.Dispose();
|
_itemPlugInConfig.Dispose();
|
||||||
_itemPlugInConfig = null;
|
_itemPlugInConfig = null;
|
||||||
}
|
}
|
||||||
|
@ -62,7 +69,8 @@ namespace Greenshot.Plugin.Flickr
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<FlickrConfiguration>();
|
_config = IniConfig.GetIniSection<FlickrConfiguration>();
|
||||||
_resources = new ComponentResourceManager(typeof(FlickrPlugin));
|
_resources = new ComponentResourceManager(typeof(FlickrPlugin));
|
||||||
|
@ -79,52 +87,67 @@ namespace Greenshot.Plugin.Flickr
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLanguageChanged(object sender, EventArgs e) {
|
public void OnLanguageChanged(object sender, EventArgs e)
|
||||||
if (_itemPlugInConfig != null) {
|
{
|
||||||
|
if (_itemPlugInConfig != null)
|
||||||
|
{
|
||||||
_itemPlugInConfig.Text = Language.GetString("flickr", LangKey.Configure);
|
_itemPlugInConfig.Text = Language.GetString("flickr", LangKey.Configure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
Log.Debug("Flickr Plugin shutdown.");
|
Log.Debug("Flickr Plugin shutdown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
public void ConfigMenuClick(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surface, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surface, out string uploadUrl)
|
||||||
|
{
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, false);
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
string flickrUrl = null;
|
string flickrUrl = null;
|
||||||
new PleaseWaitForm().ShowAndWait("Flickr", Language.GetString("flickr", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait("Flickr", Language.GetString("flickr", LangKey.communication_wait),
|
||||||
delegate {
|
delegate
|
||||||
|
{
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(_config.UploadFormat, captureDetails));
|
||||||
flickrUrl = FlickrUtils.UploadToFlickr(surface, outputSettings, captureDetails.Title, filename);
|
flickrUrl = FlickrUtils.UploadToFlickr(surface, outputSettings, captureDetails.Title, filename);
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (flickrUrl == null) {
|
if (flickrUrl == null)
|
||||||
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadUrl = flickrUrl;
|
uploadUrl = flickrUrl;
|
||||||
|
|
||||||
if (_config.AfterUploadLinkToClipBoard) {
|
if (_config.AfterUploadLinkToClipBoard)
|
||||||
|
{
|
||||||
ClipboardHelper.SetClipboardData(flickrUrl);
|
ClipboardHelper.SetClipboardData(flickrUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.Error("Error uploading.", e);
|
Log.Error("Error uploading.", e);
|
||||||
MessageBox.Show(Language.GetString("flickr", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("flickr", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,21 +30,27 @@ using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Flickr {
|
namespace Greenshot.Plugin.Flickr
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of FlickrUtils.
|
/// Description of FlickrUtils.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class FlickrUtils {
|
public static class FlickrUtils
|
||||||
|
{
|
||||||
private static readonly ILog LOG = LogManager.GetLogger(typeof(FlickrUtils));
|
private static readonly ILog LOG = LogManager.GetLogger(typeof(FlickrUtils));
|
||||||
private static readonly FlickrConfiguration config = IniConfig.GetIniSection<FlickrConfiguration>();
|
private static readonly FlickrConfiguration config = IniConfig.GetIniSection<FlickrConfiguration>();
|
||||||
private const string FLICKR_API_BASE_URL = "https://api.flickr.com/services/";
|
private const string FLICKR_API_BASE_URL = "https://api.flickr.com/services/";
|
||||||
|
|
||||||
private const string FLICKR_UPLOAD_URL = FLICKR_API_BASE_URL + "upload/";
|
private const string FLICKR_UPLOAD_URL = FLICKR_API_BASE_URL + "upload/";
|
||||||
|
|
||||||
// OAUTH
|
// OAUTH
|
||||||
private const string FLICKR_OAUTH_BASE_URL = FLICKR_API_BASE_URL + "oauth/";
|
private const string FLICKR_OAUTH_BASE_URL = FLICKR_API_BASE_URL + "oauth/";
|
||||||
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}_o.{4}";
|
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";
|
||||||
|
@ -58,7 +64,8 @@ namespace Greenshot.Plugin.Flickr {
|
||||||
/// <param name="title"></param>
|
/// <param name="title"></param>
|
||||||
/// <param name="filename"></param>
|
/// <param name="filename"></param>
|
||||||
/// <returns>url to image</returns>
|
/// <returns>url to image</returns>
|
||||||
public static string UploadToFlickr(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
public static string UploadToFlickr(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename)
|
||||||
|
{
|
||||||
var oAuth = new OAuthSession(FlickrCredentials.ConsumerKey, FlickrCredentials.ConsumerSecret)
|
var oAuth = new OAuthSession(FlickrCredentials.ConsumerKey, FlickrCredentials.ConsumerSecret)
|
||||||
{
|
{
|
||||||
BrowserSize = new Size(520, 800),
|
BrowserSize = new Size(520, 800),
|
||||||
|
@ -70,70 +77,116 @@ namespace Greenshot.Plugin.Flickr {
|
||||||
Token = config.FlickrToken,
|
Token = config.FlickrToken,
|
||||||
TokenSecret = config.FlickrTokenSecret
|
TokenSecret = config.FlickrTokenSecret
|
||||||
};
|
};
|
||||||
if (string.IsNullOrEmpty(oAuth.Token)) {
|
if (string.IsNullOrEmpty(oAuth.Token))
|
||||||
if (!oAuth.Authorize()) {
|
{
|
||||||
|
if (!oAuth.Authorize())
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(oAuth.Token)) {
|
|
||||||
|
if (!string.IsNullOrEmpty(oAuth.Token))
|
||||||
|
{
|
||||||
config.FlickrToken = oAuth.Token;
|
config.FlickrToken = oAuth.Token;
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(oAuth.TokenSecret)) {
|
|
||||||
|
if (!string.IsNullOrEmpty(oAuth.TokenSecret))
|
||||||
|
{
|
||||||
config.FlickrTokenSecret = oAuth.TokenSecret;
|
config.FlickrTokenSecret = oAuth.TokenSecret;
|
||||||
}
|
}
|
||||||
|
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
|
try
|
||||||
|
{
|
||||||
IDictionary<string, object> signedParameters = new Dictionary<string, object>
|
IDictionary<string, object> signedParameters = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "content_type", "2" }, // Screenshot
|
{
|
||||||
{ "tags", "Greenshot" },
|
"content_type", "2"
|
||||||
{ "is_public", config.IsPublic ? "1" : "0" },
|
}, // Screenshot
|
||||||
{ "is_friend", config.IsFriend ? "1" : "0" },
|
{
|
||||||
{ "is_family", config.IsFamily ? "1" : "0" },
|
"tags", "Greenshot"
|
||||||
{ "safety_level", $"{(int)config.SafetyLevel}" },
|
},
|
||||||
{ "hidden", config.HiddenFromSearch ? "1" : "2" }
|
{
|
||||||
|
"is_public", config.IsPublic ? "1" : "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_friend", config.IsFriend ? "1" : "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"is_family", config.IsFamily ? "1" : "0"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"safety_level", $"{(int) config.SafetyLevel}"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"hidden", config.HiddenFromSearch ? "1" : "2"
|
||||||
|
}
|
||||||
};
|
};
|
||||||
IDictionary<string, object> otherParameters = new Dictionary<string, object>
|
IDictionary<string, object> otherParameters = new Dictionary<string, object>
|
||||||
{
|
{
|
||||||
{ "photo", new SurfaceContainer(surfaceToUpload, outputSettings, filename) }
|
{
|
||||||
|
"photo", new SurfaceContainer(surfaceToUpload, outputSettings, filename)
|
||||||
|
}
|
||||||
};
|
};
|
||||||
string response = oAuth.MakeOAuthRequest(HTTPMethod.POST, FLICKR_UPLOAD_URL, signedParameters, otherParameters, null);
|
string response = oAuth.MakeOAuthRequest(HTTPMethod.POST, FLICKR_UPLOAD_URL, signedParameters, otherParameters, null);
|
||||||
string photoId = GetPhotoId(response);
|
string photoId = GetPhotoId(response);
|
||||||
|
|
||||||
// Get Photo Info
|
// Get Photo Info
|
||||||
signedParameters = new Dictionary<string, object> { { "photo_id", photoId } };
|
signedParameters = new Dictionary<string, object>
|
||||||
|
{
|
||||||
|
{
|
||||||
|
"photo_id", photoId
|
||||||
|
}
|
||||||
|
};
|
||||||
string photoInfo = oAuth.MakeOAuthRequest(HTTPMethod.POST, FLICKR_GET_INFO_URL, signedParameters, null, null);
|
string photoInfo = oAuth.MakeOAuthRequest(HTTPMethod.POST, FLICKR_GET_INFO_URL, signedParameters, null, null);
|
||||||
return GetUrl(photoInfo);
|
return GetUrl(photoInfo);
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.Error("Upload error: ", ex);
|
LOG.Error("Upload error: ", ex);
|
||||||
throw;
|
throw;
|
||||||
} finally {
|
}
|
||||||
if (!string.IsNullOrEmpty(oAuth.Token)) {
|
finally
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(oAuth.Token))
|
||||||
|
{
|
||||||
config.FlickrToken = oAuth.Token;
|
config.FlickrToken = oAuth.Token;
|
||||||
}
|
}
|
||||||
if (!string.IsNullOrEmpty(oAuth.TokenSecret)) {
|
|
||||||
|
if (!string.IsNullOrEmpty(oAuth.TokenSecret))
|
||||||
|
{
|
||||||
config.FlickrTokenSecret = oAuth.TokenSecret;
|
config.FlickrTokenSecret = oAuth.TokenSecret;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetUrl(string response) {
|
private static string GetUrl(string response)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.LoadXml(response);
|
doc.LoadXml(response);
|
||||||
if (config.UsePageLink) {
|
if (config.UsePageLink)
|
||||||
|
{
|
||||||
XmlNodeList nodes = doc.GetElementsByTagName("url");
|
XmlNodeList nodes = doc.GetElementsByTagName("url");
|
||||||
if (nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
var xmlNode = nodes.Item(0);
|
var xmlNode = nodes.Item(0);
|
||||||
if (xmlNode != null) {
|
if (xmlNode != null)
|
||||||
|
{
|
||||||
return xmlNode.InnerText;
|
return xmlNode.InnerText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
XmlNodeList nodes = doc.GetElementsByTagName("photo");
|
XmlNodeList nodes = doc.GetElementsByTagName("photo");
|
||||||
if (nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
var item = nodes.Item(0);
|
var item = nodes.Item(0);
|
||||||
if (item?.Attributes != null) {
|
if (item?.Attributes != null)
|
||||||
|
{
|
||||||
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;
|
||||||
|
@ -143,26 +196,36 @@ namespace Greenshot.Plugin.Flickr {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.Error("Error parsing Flickr Response.", ex);
|
LOG.Error("Error parsing Flickr Response.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static string GetPhotoId(string response) {
|
private static string GetPhotoId(string response)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.LoadXml(response);
|
doc.LoadXml(response);
|
||||||
XmlNodeList nodes = doc.GetElementsByTagName("photoid");
|
XmlNodeList nodes = doc.GetElementsByTagName("photoid");
|
||||||
if (nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
var xmlNode = nodes.Item(0);
|
var xmlNode = nodes.Item(0);
|
||||||
if (xmlNode != null) {
|
if (xmlNode != null)
|
||||||
|
{
|
||||||
return xmlNode.InnerText;
|
return xmlNode.InnerText;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
LOG.Error("Error parsing Flickr Response.", ex);
|
LOG.Error("Error parsing Flickr Response.", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Flickr.Forms {
|
namespace Greenshot.Plugin.Flickr.Forms
|
||||||
public class FlickrForm : GreenshotForm {
|
{
|
||||||
|
public class FlickrForm : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,12 +19,15 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Flickr.Forms {
|
namespace Greenshot.Plugin.Flickr.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : FlickrForm {
|
public partial class SettingsForm : FlickrForm
|
||||||
public SettingsForm() {
|
{
|
||||||
|
public SettingsForm()
|
||||||
|
{
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
//
|
//
|
||||||
|
@ -32,6 +35,5 @@ namespace Greenshot.Plugin.Flickr.Forms {
|
||||||
CancelButton = buttonCancel;
|
CancelButton = buttonCancel;
|
||||||
AcceptButton = buttonOK;
|
AcceptButton = buttonOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,8 +18,11 @@
|
||||||
* You should have received a copy of the GNU General Public License
|
* You should have received a copy of the GNU General Public License
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
namespace Greenshot.Plugin.Flickr {
|
|
||||||
public enum LangKey {
|
namespace Greenshot.Plugin.Flickr
|
||||||
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
upload_failure,
|
upload_failure,
|
||||||
communication_wait,
|
communication_wait,
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos.Forms {
|
namespace Greenshot.Plugin.GooglePhotos.Forms
|
||||||
public class GooglePhotosForm : GreenshotForm {
|
{
|
||||||
|
public class GooglePhotosForm : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -18,12 +18,13 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos.Forms {
|
namespace Greenshot.Plugin.GooglePhotos.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : GooglePhotosForm {
|
public partial class SettingsForm : GooglePhotosForm
|
||||||
|
{
|
||||||
public SettingsForm()
|
public SettingsForm()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -33,6 +34,5 @@ namespace Greenshot.Plugin.GooglePhotos.Forms {
|
||||||
CancelButton = buttonCancel;
|
CancelButton = buttonCancel;
|
||||||
AcceptButton = buttonOK;
|
AcceptButton = buttonOK;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -24,12 +24,14 @@ using Greenshot.Plugin.GooglePhotos.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos {
|
namespace Greenshot.Plugin.GooglePhotos
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of GooglePhotosConfiguration.
|
/// Description of GooglePhotosConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("GooglePhotos", Description = "Greenshot GooglePhotos Plugin configuration")]
|
[IniSection("GooglePhotos", Description = "Greenshot GooglePhotos Plugin configuration")]
|
||||||
public class GooglePhotosConfiguration : IniSection {
|
public class GooglePhotosConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat { get; set; }
|
public OutputFormat UploadFormat { get; set; }
|
||||||
|
|
||||||
|
@ -38,57 +40,42 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
|
|
||||||
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send GooglePhotos link to clipboard.", DefaultValue = "true")]
|
[IniProperty("AfterUploadLinkToClipBoard", Description = "After upload send GooglePhotos link to clipboard.", DefaultValue = "true")]
|
||||||
public bool AfterUploadLinkToClipBoard { get; set; }
|
public bool AfterUploadLinkToClipBoard { get; set; }
|
||||||
|
|
||||||
[IniProperty("AddFilename", Description = "Is the filename passed on to GooglePhotos", DefaultValue = "False")]
|
[IniProperty("AddFilename", Description = "Is the filename passed on to GooglePhotos", DefaultValue = "False")]
|
||||||
public bool AddFilename {
|
public bool AddFilename { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[IniProperty("UploadUser", Description = "The GooglePhotos user to upload to", DefaultValue = "default")]
|
[IniProperty("UploadUser", Description = "The GooglePhotos user to upload to", DefaultValue = "default")]
|
||||||
public string UploadUser {
|
public string UploadUser { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[IniProperty("UploadAlbum", Description = "The GooglePhotos album to upload to", DefaultValue = "default")]
|
[IniProperty("UploadAlbum", Description = "The GooglePhotos album to upload to", DefaultValue = "default")]
|
||||||
public string UploadAlbum {
|
public string UploadAlbum { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
[IniProperty("RefreshToken", Description = "GooglePhotos authorization refresh Token", Encrypted = true)]
|
[IniProperty("RefreshToken", Description = "GooglePhotos authorization refresh Token", Encrypted = true)]
|
||||||
public string RefreshToken {
|
public string RefreshToken { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not stored
|
/// Not stored
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string AccessToken {
|
public string AccessToken { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Not stored
|
/// Not stored
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public DateTimeOffset AccessTokenExpires {
|
public DateTimeOffset AccessTokenExpires { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A form for token
|
/// A form for token
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog()
|
||||||
|
{
|
||||||
DialogResult result = new SettingsForm().ShowDialog();
|
DialogResult result = new SettingsForm().ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -23,10 +23,14 @@ using System.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos {
|
namespace Greenshot.Plugin.GooglePhotos
|
||||||
public class GooglePhotosDestination : AbstractDestination {
|
{
|
||||||
|
public class GooglePhotosDestination : AbstractDestination
|
||||||
|
{
|
||||||
private readonly GooglePhotosPlugin _plugin;
|
private readonly GooglePhotosPlugin _plugin;
|
||||||
public GooglePhotosDestination(GooglePhotosPlugin plugin) {
|
|
||||||
|
public GooglePhotosDestination(GooglePhotosPlugin plugin)
|
||||||
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,20 +38,25 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
|
|
||||||
public override string Description => Language.GetString("googlephotos", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("googlephotos", LangKey.upload_menu_item);
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(GooglePhotosPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(GooglePhotosPlugin));
|
||||||
return (Image) resources.GetObject("GooglePhotos");
|
return (Image) resources.GetObject("GooglePhotos");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
bool uploaded = _plugin.Upload(captureDetails, surface, out var uploadUrl);
|
||||||
if (uploaded) {
|
if (uploaded)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,18 +29,21 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos {
|
namespace Greenshot.Plugin.GooglePhotos
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the GooglePhotos base code
|
/// This is the GooglePhotos base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("GooglePhotos", true)]
|
[Plugin("GooglePhotos", true)]
|
||||||
public class GooglePhotosPlugin : IGreenshotPlugin {
|
public class GooglePhotosPlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(GooglePhotosPlugin));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(GooglePhotosPlugin));
|
||||||
private static GooglePhotosConfiguration _config;
|
private static GooglePhotosConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _itemPlugInRoot;
|
private ToolStripMenuItem _itemPlugInRoot;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
@ -56,7 +59,8 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
SimpleServiceProvider.Current.AddService<IDestination>(new GooglePhotosDestination(this));
|
SimpleServiceProvider.Current.AddService<IDestination>(new GooglePhotosDestination(this));
|
||||||
|
|
||||||
// Get configuration
|
// Get configuration
|
||||||
|
@ -74,13 +78,16 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLanguageChanged(object sender, EventArgs e) {
|
public void OnLanguageChanged(object sender, EventArgs e)
|
||||||
if (_itemPlugInRoot != null) {
|
{
|
||||||
|
if (_itemPlugInRoot != null)
|
||||||
|
{
|
||||||
_itemPlugInRoot.Text = Language.GetString("googlephotos", LangKey.Configure);
|
_itemPlugInRoot.Text = Language.GetString("googlephotos", LangKey.Configure);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
Log.Debug("GooglePhotos Plugin shutdown.");
|
Log.Debug("GooglePhotos Plugin shutdown.");
|
||||||
Language.LanguageChanged -= OnLanguageChanged;
|
Language.LanguageChanged -= OnLanguageChanged;
|
||||||
//host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened);
|
//host.OnImageEditorOpen -= new OnImageEditorOpenHandler(ImageEditorOpened);
|
||||||
|
@ -89,17 +96,21 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ConfigMenuClick(object sender, EventArgs eventArgs) {
|
public void ConfigMenuClick(object sender, EventArgs eventArgs)
|
||||||
|
{
|
||||||
Configure();
|
Configure();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl)
|
||||||
|
{
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
string url = null;
|
string url = null;
|
||||||
new PleaseWaitForm().ShowAndWait("GooglePhotos", Language.GetString("googlephotos", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait("GooglePhotos", Language.GetString("googlephotos", LangKey.communication_wait),
|
||||||
delegate
|
delegate
|
||||||
|
@ -110,14 +121,19 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
);
|
);
|
||||||
uploadUrl = url;
|
uploadUrl = url;
|
||||||
|
|
||||||
if (uploadUrl != null && _config.AfterUploadLinkToClipBoard) {
|
if (uploadUrl != null && _config.AfterUploadLinkToClipBoard)
|
||||||
|
{
|
||||||
ClipboardHelper.SetClipboardData(uploadUrl);
|
ClipboardHelper.SetClipboardData(uploadUrl);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.Error("Error uploading.", e);
|
Log.Error("Error uploading.", e);
|
||||||
MessageBox.Show(Language.GetString("googlephotos", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("googlephotos", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,20 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos {
|
namespace Greenshot.Plugin.GooglePhotos
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of GooglePhotosUtils.
|
/// Description of GooglePhotosUtils.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class GooglePhotosUtils {
|
public static class GooglePhotosUtils
|
||||||
|
{
|
||||||
private const string GooglePhotosScope = "https://picasaweb.google.com/data/";
|
private const string GooglePhotosScope = "https://picasaweb.google.com/data/";
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(GooglePhotosUtils));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(GooglePhotosUtils));
|
||||||
private static readonly GooglePhotosConfiguration Config = IniConfig.GetIniSection<GooglePhotosConfiguration>();
|
private static readonly GooglePhotosConfiguration Config = IniConfig.GetIniSection<GooglePhotosConfiguration>();
|
||||||
private const string AuthUrl = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={ClientId}&redirect_uri={RedirectUrl}&state={State}&scope=" + GooglePhotosScope;
|
|
||||||
|
private const string AuthUrl = "https://accounts.google.com/o/oauth2/auth?response_type=code&client_id={ClientId}&redirect_uri={RedirectUrl}&state={State}&scope=" +
|
||||||
|
GooglePhotosScope;
|
||||||
|
|
||||||
private const string TokenUrl = "https://www.googleapis.com/oauth2/v3/token";
|
private const string TokenUrl = "https://www.googleapis.com/oauth2/v3/token";
|
||||||
private const string UploadUrl = "https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}";
|
private const string UploadUrl = "https://picasaweb.google.com/data/feed/api/user/{0}/albumid/{1}";
|
||||||
|
|
||||||
|
@ -46,7 +51,8 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
/// <param name="title">string</param>
|
/// <param name="title">string</param>
|
||||||
/// <param name="filename">string</param>
|
/// <param name="filename">string</param>
|
||||||
/// <returns>GooglePhotosResponse</returns>
|
/// <returns>GooglePhotosResponse</returns>
|
||||||
public static string UploadToGooglePhotos(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
public static string UploadToGooglePhotos(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename)
|
||||||
|
{
|
||||||
// Fill the OAuth2Settings
|
// Fill the OAuth2Settings
|
||||||
var settings = new OAuth2Settings
|
var settings = new OAuth2Settings
|
||||||
{
|
{
|
||||||
|
@ -63,18 +69,23 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
|
|
||||||
// Copy the settings from the config, which is kept in memory and on the disk
|
// Copy the settings from the config, which is kept in memory and on the disk
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, string.Format(UploadUrl, Config.UploadUser, Config.UploadAlbum), settings);
|
var webRequest = OAuth2Helper.CreateOAuth2WebRequest(HTTPMethod.POST, string.Format(UploadUrl, Config.UploadUser, Config.UploadAlbum), settings);
|
||||||
if (Config.AddFilename) {
|
if (Config.AddFilename)
|
||||||
|
{
|
||||||
webRequest.Headers.Add("Slug", NetworkHelper.EscapeDataString(filename));
|
webRequest.Headers.Add("Slug", NetworkHelper.EscapeDataString(filename));
|
||||||
}
|
}
|
||||||
|
|
||||||
SurfaceContainer container = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
SurfaceContainer container = new SurfaceContainer(surfaceToUpload, outputSettings, filename);
|
||||||
container.Upload(webRequest);
|
container.Upload(webRequest);
|
||||||
|
|
||||||
string response = NetworkHelper.GetResponseAsString(webRequest);
|
string response = NetworkHelper.GetResponseAsString(webRequest);
|
||||||
|
|
||||||
return ParseResponse(response);
|
return ParseResponse(response);
|
||||||
} finally {
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
// Copy the settings back to the config, so they are stored.
|
// Copy the settings back to the config, so they are stored.
|
||||||
Config.RefreshToken = settings.RefreshToken;
|
Config.RefreshToken = settings.RefreshToken;
|
||||||
Config.AccessToken = settings.AccessToken;
|
Config.AccessToken = settings.AccessToken;
|
||||||
|
@ -89,31 +100,43 @@ namespace Greenshot.Plugin.GooglePhotos {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static string ParseResponse(string response) {
|
public static string ParseResponse(string response)
|
||||||
if (response == null) {
|
{
|
||||||
|
if (response == null)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
|
try
|
||||||
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.LoadXml(response);
|
doc.LoadXml(response);
|
||||||
XmlNodeList nodes = doc.GetElementsByTagName("link", "*");
|
XmlNodeList nodes = doc.GetElementsByTagName("link", "*");
|
||||||
if(nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
string url = null;
|
string url = null;
|
||||||
foreach(XmlNode node in nodes) {
|
foreach (XmlNode node in nodes)
|
||||||
if (node.Attributes != null) {
|
{
|
||||||
|
if (node.Attributes != null)
|
||||||
|
{
|
||||||
url = node.Attributes["href"].Value;
|
url = node.Attributes["href"].Value;
|
||||||
string rel = node.Attributes["rel"].Value;
|
string rel = node.Attributes["rel"].Value;
|
||||||
// Pictures with rel="http://schemas.google.com/photos/2007#canonical" are the direct link
|
// Pictures with rel="http://schemas.google.com/photos/2007#canonical" are the direct link
|
||||||
if (rel != null && rel.EndsWith("canonical")) {
|
if (rel != null && rel.EndsWith("canonical"))
|
||||||
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return url;
|
return url;
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.ErrorFormat("Could not parse GooglePhotos response due to error {0}, response was: {1}", e.Message, response);
|
Log.ErrorFormat("Could not parse GooglePhotos response due to error {0}, response was: {1}", e.Message, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,7 +18,8 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.GooglePhotos {
|
namespace Greenshot.Plugin.GooglePhotos
|
||||||
|
{
|
||||||
public enum LangKey
|
public enum LangKey
|
||||||
{
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
|
|
|
@ -21,10 +21,12 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur.Forms {
|
namespace Greenshot.Plugin.Imgur.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class is needed for design-time resolving of the language files
|
/// This class is needed for design-time resolving of the language files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ImgurForm : GreenshotForm {
|
public class ImgurForm : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -27,18 +27,21 @@ using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur.Forms {
|
namespace Greenshot.Plugin.Imgur.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Imgur history form
|
/// Imgur history form
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public sealed partial class ImgurHistory : ImgurForm {
|
public sealed partial class ImgurHistory : ImgurForm
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurHistory));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurHistory));
|
||||||
private readonly GreenshotColumnSorter _columnSorter;
|
private readonly GreenshotColumnSorter _columnSorter;
|
||||||
private static readonly object Lock = new object();
|
private static readonly object Lock = new object();
|
||||||
private static readonly ImgurConfiguration Config = IniConfig.GetIniSection<ImgurConfiguration>();
|
private static readonly ImgurConfiguration Config = IniConfig.GetIniSection<ImgurConfiguration>();
|
||||||
private static ImgurHistory _instance;
|
private static ImgurHistory _instance;
|
||||||
|
|
||||||
public static void ShowHistory() {
|
public static void ShowHistory()
|
||||||
|
{
|
||||||
lock (Lock)
|
lock (Lock)
|
||||||
{
|
{
|
||||||
if (ImgurUtils.IsHistoryLoadingNeeded())
|
if (ImgurUtils.IsHistoryLoadingNeeded())
|
||||||
|
@ -54,15 +57,18 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
{
|
{
|
||||||
_instance = new ImgurHistory();
|
_instance = new ImgurHistory();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_instance.Visible)
|
if (!_instance.Visible)
|
||||||
{
|
{
|
||||||
_instance.Show();
|
_instance.Show();
|
||||||
}
|
}
|
||||||
|
|
||||||
_instance.Redraw();
|
_instance.Redraw();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ImgurHistory() {
|
private ImgurHistory()
|
||||||
|
{
|
||||||
ManualLanguageApply = true;
|
ManualLanguageApply = true;
|
||||||
//
|
//
|
||||||
// The InitializeComponent() call is required for Windows Forms designer support.
|
// The InitializeComponent() call is required for Windows Forms designer support.
|
||||||
|
@ -76,26 +82,36 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
_columnSorter.SortColumn = 3;
|
_columnSorter.SortColumn = 3;
|
||||||
_columnSorter.Order = SortOrder.Descending;
|
_columnSorter.Order = SortOrder.Descending;
|
||||||
Redraw();
|
Redraw();
|
||||||
if (listview_imgur_uploads.Items.Count > 0) {
|
if (listview_imgur_uploads.Items.Count > 0)
|
||||||
|
{
|
||||||
listview_imgur_uploads.Items[0].Selected = true;
|
listview_imgur_uploads.Items[0].Selected = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ApplyLanguage();
|
ApplyLanguage();
|
||||||
if (Config.Credits > 0) {
|
if (Config.Credits > 0)
|
||||||
|
{
|
||||||
Text = Text + " (" + Config.Credits + " credits)";
|
Text = Text + " (" + Config.Credits + " credits)";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Redraw() {
|
private void Redraw()
|
||||||
|
{
|
||||||
// Should fix Bug #3378699
|
// Should fix Bug #3378699
|
||||||
pictureBox1.Image = pictureBox1.ErrorImage;
|
pictureBox1.Image = pictureBox1.ErrorImage;
|
||||||
listview_imgur_uploads.BeginUpdate();
|
listview_imgur_uploads.BeginUpdate();
|
||||||
listview_imgur_uploads.Items.Clear();
|
listview_imgur_uploads.Items.Clear();
|
||||||
listview_imgur_uploads.Columns.Clear();
|
listview_imgur_uploads.Columns.Clear();
|
||||||
string[] columns = { "hash", "title", "deleteHash", "Date"};
|
string[] columns =
|
||||||
foreach (string column in columns) {
|
{
|
||||||
|
"hash", "title", "deleteHash", "Date"
|
||||||
|
};
|
||||||
|
foreach (string column in columns)
|
||||||
|
{
|
||||||
listview_imgur_uploads.Columns.Add(column);
|
listview_imgur_uploads.Columns.Add(column);
|
||||||
}
|
}
|
||||||
foreach (ImgurInfo imgurInfo in Config.runtimeImgurHistory.Values) {
|
|
||||||
|
foreach (ImgurInfo imgurInfo in Config.runtimeImgurHistory.Values)
|
||||||
|
{
|
||||||
var item = new ListViewItem(imgurInfo.Hash)
|
var item = new ListViewItem(imgurInfo.Hash)
|
||||||
{
|
{
|
||||||
Tag = imgurInfo
|
Tag = imgurInfo
|
||||||
|
@ -105,7 +121,9 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
item.SubItems.Add(imgurInfo.Timestamp.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo));
|
item.SubItems.Add(imgurInfo.Timestamp.ToString("yyyy-MM-dd HH:mm:ss", DateTimeFormatInfo.InvariantInfo));
|
||||||
listview_imgur_uploads.Items.Add(item);
|
listview_imgur_uploads.Items.Add(item);
|
||||||
}
|
}
|
||||||
for (int i = 0; i < columns.Length; i++) {
|
|
||||||
|
for (int i = 0; i < columns.Length; i++)
|
||||||
|
{
|
||||||
listview_imgur_uploads.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
|
listview_imgur_uploads.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,17 +134,22 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
clipboardButton.Enabled = false;
|
clipboardButton.Enabled = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void Listview_imgur_uploadsSelectedIndexChanged(object sender, EventArgs e) {
|
private void Listview_imgur_uploadsSelectedIndexChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
pictureBox1.Image = pictureBox1.ErrorImage;
|
pictureBox1.Image = pictureBox1.ErrorImage;
|
||||||
if (listview_imgur_uploads.SelectedItems.Count > 0) {
|
if (listview_imgur_uploads.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
deleteButton.Enabled = true;
|
deleteButton.Enabled = true;
|
||||||
openButton.Enabled = true;
|
openButton.Enabled = true;
|
||||||
clipboardButton.Enabled = true;
|
clipboardButton.Enabled = true;
|
||||||
if (listview_imgur_uploads.SelectedItems.Count == 1) {
|
if (listview_imgur_uploads.SelectedItems.Count == 1)
|
||||||
|
{
|
||||||
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[0].Tag;
|
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[0].Tag;
|
||||||
pictureBox1.Image = imgurInfo.Image;
|
pictureBox1.Image = imgurInfo.Image;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
pictureBox1.Image = pictureBox1.ErrorImage;
|
pictureBox1.Image = pictureBox1.ErrorImage;
|
||||||
deleteButton.Enabled = false;
|
deleteButton.Enabled = false;
|
||||||
openButton.Enabled = false;
|
openButton.Enabled = false;
|
||||||
|
@ -134,48 +157,60 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DeleteButtonClick(object sender, EventArgs e) {
|
private void DeleteButtonClick(object sender, EventArgs e)
|
||||||
if (listview_imgur_uploads.SelectedItems.Count > 0) {
|
{
|
||||||
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) {
|
if (listview_imgur_uploads.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++)
|
||||||
|
{
|
||||||
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[i].Tag;
|
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[i].Tag;
|
||||||
DialogResult result = MessageBox.Show(Language.GetFormattedString("imgur", LangKey.delete_question, imgurInfo.Title), Language.GetFormattedString("imgur", LangKey.delete_title, imgurInfo.Hash), MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
DialogResult result = MessageBox.Show(Language.GetFormattedString("imgur", LangKey.delete_question, imgurInfo.Title),
|
||||||
|
Language.GetFormattedString("imgur", LangKey.delete_title, imgurInfo.Hash), MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
if (result != DialogResult.Yes)
|
if (result != DialogResult.Yes)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should fix Bug #3378699
|
// Should fix Bug #3378699
|
||||||
pictureBox1.Image = pictureBox1.ErrorImage;
|
pictureBox1.Image = pictureBox1.ErrorImage;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
new PleaseWaitForm().ShowAndWait("Imgur", Language.GetString("imgur", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait("Imgur", Language.GetString("imgur", LangKey.communication_wait),
|
||||||
delegate {
|
delegate { ImgurUtils.DeleteImgurImage(imgurInfo); }
|
||||||
ImgurUtils.DeleteImgurImage(imgurInfo);
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Warn("Problem communicating with Imgur: ", ex);
|
Log.Warn("Problem communicating with Imgur: ", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
imgurInfo.Dispose();
|
imgurInfo.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Redraw();
|
Redraw();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClipboardButtonClick(object sender, EventArgs e) {
|
private void ClipboardButtonClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
StringBuilder links = new StringBuilder();
|
StringBuilder links = new StringBuilder();
|
||||||
if (listview_imgur_uploads.SelectedItems.Count > 0) {
|
if (listview_imgur_uploads.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++)
|
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++)
|
||||||
{
|
{
|
||||||
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[i].Tag;
|
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[i].Tag;
|
||||||
links.AppendLine(Config.UsePageLink ? imgurInfo.Page : imgurInfo.Original);
|
links.AppendLine(Config.UsePageLink ? imgurInfo.Page : imgurInfo.Original);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ClipboardHelper.SetClipboardData(links.ToString());
|
ClipboardHelper.SetClipboardData(links.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ClearHistoryButtonClick(object sender, EventArgs e) {
|
private void ClearHistoryButtonClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
DialogResult result = MessageBox.Show(Language.GetString("imgur", LangKey.clear_question), "Imgur", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
DialogResult result = MessageBox.Show(Language.GetString("imgur", LangKey.clear_question), "Imgur", MessageBoxButtons.YesNo, MessageBoxIcon.Question);
|
||||||
if (result == DialogResult.Yes) {
|
if (result == DialogResult.Yes)
|
||||||
|
{
|
||||||
Config.runtimeImgurHistory.Clear();
|
Config.runtimeImgurHistory.Clear();
|
||||||
Config.ImgurUploadHistory.Clear();
|
Config.ImgurUploadHistory.Clear();
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
|
@ -188,21 +223,28 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
Hide();
|
Hide();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OpenButtonClick(object sender, EventArgs e) {
|
private void OpenButtonClick(object sender, EventArgs e)
|
||||||
if (listview_imgur_uploads.SelectedItems.Count > 0) {
|
{
|
||||||
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++) {
|
if (listview_imgur_uploads.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < listview_imgur_uploads.SelectedItems.Count; i++)
|
||||||
|
{
|
||||||
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[i].Tag;
|
ImgurInfo imgurInfo = (ImgurInfo) listview_imgur_uploads.SelectedItems[i].Tag;
|
||||||
System.Diagnostics.Process.Start(imgurInfo.Page);
|
System.Diagnostics.Process.Start(imgurInfo.Page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void listview_imgur_uploads_ColumnClick(object sender, ColumnClickEventArgs e) {
|
private void listview_imgur_uploads_ColumnClick(object sender, ColumnClickEventArgs e)
|
||||||
|
{
|
||||||
// Determine if clicked column is already the column that is being sorted.
|
// Determine if clicked column is already the column that is being sorted.
|
||||||
if (e.Column == _columnSorter.SortColumn) {
|
if (e.Column == _columnSorter.SortColumn)
|
||||||
|
{
|
||||||
// Reverse the current sort direction for this column.
|
// Reverse the current sort direction for this column.
|
||||||
_columnSorter.Order = _columnSorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
|
_columnSorter.Order = _columnSorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Set the column number that is to be sorted; default to ascending.
|
// Set the column number that is to be sorted; default to ascending.
|
||||||
_columnSorter.SortColumn = e.Column;
|
_columnSorter.SortColumn = e.Column;
|
||||||
_columnSorter.Order = SortOrder.Ascending;
|
_columnSorter.Order = SortOrder.Ascending;
|
||||||
|
|
|
@ -21,11 +21,13 @@
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur.Forms {
|
namespace Greenshot.Plugin.Imgur.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : ImgurForm {
|
public partial class SettingsForm : ImgurForm
|
||||||
|
{
|
||||||
public SettingsForm()
|
public SettingsForm()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
@ -38,7 +40,8 @@ namespace Greenshot.Plugin.Imgur.Forms {
|
||||||
historyButton.Enabled = ImgurUtils.IsHistoryLoadingNeeded();
|
historyButton.Enabled = ImgurUtils.IsHistoryLoadingNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ButtonHistoryClick(object sender, EventArgs e) {
|
private void ButtonHistoryClick(object sender, EventArgs e)
|
||||||
|
{
|
||||||
ImgurHistory.ShowHistory();
|
ImgurHistory.ShowHistory();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,25 +26,32 @@ using Greenshot.Plugin.Imgur.Forms;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur {
|
namespace Greenshot.Plugin.Imgur
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImgurConfiguration.
|
/// Description of ImgurConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Imgur", Description = "Greenshot Imgur Plugin configuration")]
|
[IniSection("Imgur", Description = "Greenshot Imgur Plugin configuration")]
|
||||||
public class ImgurConfiguration : IniSection {
|
public class ImgurConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("ImgurApi3Url", Description = "Url to Imgur system.", DefaultValue = "https://api.imgur.com/3")]
|
[IniProperty("ImgurApi3Url", Description = "Url to Imgur system.", DefaultValue = "https://api.imgur.com/3")]
|
||||||
public string ImgurApi3Url { get; set; }
|
public string ImgurApi3Url { get; set; }
|
||||||
|
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat { get; set; }
|
public OutputFormat UploadFormat { get; set; }
|
||||||
|
|
||||||
[IniProperty("UploadJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
|
[IniProperty("UploadJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
|
||||||
public int UploadJpegQuality { get; set; }
|
public int UploadJpegQuality { get; set; }
|
||||||
|
|
||||||
[IniProperty("UploadReduceColors", Description = "Reduce color amount of the uploaded image to 256", DefaultValue = "False")]
|
[IniProperty("UploadReduceColors", Description = "Reduce color amount of the uploaded image to 256", DefaultValue = "False")]
|
||||||
public bool UploadReduceColors { get; set; }
|
public bool UploadReduceColors { get; set; }
|
||||||
|
|
||||||
[IniProperty("CopyLinkToClipboard", Description = "Copy the link, which one is controlled by the UsePageLink, on the clipboard", DefaultValue = "True")]
|
[IniProperty("CopyLinkToClipboard", Description = "Copy the link, which one is controlled by the UsePageLink, on the clipboard", DefaultValue = "True")]
|
||||||
public bool CopyLinkToClipboard { get; set; }
|
public bool CopyLinkToClipboard { get; set; }
|
||||||
|
|
||||||
[IniProperty("UsePageLink", Description = "Use pagelink instead of direct link on the clipboard", DefaultValue = "False")]
|
[IniProperty("UsePageLink", Description = "Use pagelink instead of direct link on the clipboard", DefaultValue = "False")]
|
||||||
public bool UsePageLink { get; set; }
|
public bool UsePageLink { get; set; }
|
||||||
|
|
||||||
[IniProperty("AnonymousAccess", Description = "Use anonymous access to Imgur", DefaultValue = "true")]
|
[IniProperty("AnonymousAccess", Description = "Use anonymous access to Imgur", DefaultValue = "true")]
|
||||||
public bool AnonymousAccess { get; set; }
|
public bool AnonymousAccess { get; set; }
|
||||||
|
|
||||||
|
@ -63,8 +70,10 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
|
|
||||||
[IniProperty("AddTitle", Description = "Is the title passed on to Imgur", DefaultValue = "False")]
|
[IniProperty("AddTitle", Description = "Is the title passed on to Imgur", DefaultValue = "False")]
|
||||||
public bool AddTitle { get; set; }
|
public bool AddTitle { get; set; }
|
||||||
|
|
||||||
[IniProperty("AddFilename", Description = "Is the filename passed on to Imgur", DefaultValue = "False")]
|
[IniProperty("AddFilename", Description = "Is the filename passed on to Imgur", DefaultValue = "False")]
|
||||||
public bool AddFilename { get; set; }
|
public bool AddFilename { get; set; }
|
||||||
|
|
||||||
[IniProperty("FilenamePattern", Description = "Filename for the Imgur upload", DefaultValue = "${capturetime:d\"yyyyMMdd-HHmm\"}")]
|
[IniProperty("FilenamePattern", Description = "Filename for the Imgur upload", DefaultValue = "${capturetime:d\"yyyyMMdd-HHmm\"}")]
|
||||||
public string FilenamePattern { get; set; }
|
public string FilenamePattern { get; set; }
|
||||||
|
|
||||||
|
@ -73,10 +82,7 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
|
|
||||||
// Not stored, only run-time!
|
// Not stored, only run-time!
|
||||||
public Dictionary<string, ImgurInfo> runtimeImgurHistory = new Dictionary<string, ImgurInfo>();
|
public Dictionary<string, ImgurInfo> runtimeImgurHistory = new Dictionary<string, ImgurInfo>();
|
||||||
public int Credits {
|
public int Credits { get; set; }
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Supply values we can't put as defaults
|
/// Supply values we can't put as defaults
|
||||||
|
@ -94,7 +100,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// A form for username/password
|
/// A form for username/password
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog()
|
||||||
|
{
|
||||||
SettingsForm settingsForm = new SettingsForm();
|
SettingsForm settingsForm = new SettingsForm();
|
||||||
DialogResult result = settingsForm.ShowDialog();
|
DialogResult result = settingsForm.ShowDialog();
|
||||||
return result == DialogResult.OK;
|
return result == DialogResult.OK;
|
||||||
|
|
|
@ -24,14 +24,17 @@ using System.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur {
|
namespace Greenshot.Plugin.Imgur
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of ImgurDestination.
|
/// Description of ImgurDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ImgurDestination : AbstractDestination {
|
public class ImgurDestination : AbstractDestination
|
||||||
|
{
|
||||||
private readonly ImgurPlugin _plugin;
|
private readonly ImgurPlugin _plugin;
|
||||||
|
|
||||||
public ImgurDestination(ImgurPlugin plugin) {
|
public ImgurDestination(ImgurPlugin plugin)
|
||||||
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,17 +42,21 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
|
|
||||||
public override string Description => Language.GetString("imgur", LangKey.upload_menu_item);
|
public override string Description => Language.GetString("imgur", LangKey.upload_menu_item);
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(ImgurPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(ImgurPlugin));
|
||||||
return (Image) resources.GetObject("Imgur");
|
return (Image) resources.GetObject("Imgur");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)
|
||||||
{
|
{
|
||||||
ExportMade = _plugin.Upload(captureDetails, surface, out var uploadUrl), Uri = uploadUrl
|
ExportMade = _plugin.Upload(captureDetails, surface, out var uploadUrl),
|
||||||
|
Uri = uploadUrl
|
||||||
};
|
};
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
|
|
|
@ -32,13 +32,10 @@ namespace Greenshot.Plugin.Imgur
|
||||||
{
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurInfo));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurInfo));
|
||||||
|
|
||||||
public string Hash
|
public string Hash { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private string _deleteHash;
|
private string _deleteHash;
|
||||||
|
|
||||||
public string DeleteHash
|
public string DeleteHash
|
||||||
{
|
{
|
||||||
get { return _deleteHash; }
|
get { return _deleteHash; }
|
||||||
|
@ -49,55 +46,24 @@ namespace Greenshot.Plugin.Imgur
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Title
|
public string Title { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string ImageType
|
public string ImageType { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTime Timestamp
|
public DateTime Timestamp { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Original
|
public string Original { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Page
|
public string Page { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SmallSquare
|
public string SmallSquare { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string LargeThumbnail
|
public string LargeThumbnail { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string DeletePage
|
public string DeletePage { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
private Image _image;
|
private Image _image;
|
||||||
|
|
||||||
public Image Image
|
public Image Image
|
||||||
{
|
{
|
||||||
get { return _image; }
|
get { return _image; }
|
||||||
|
@ -129,8 +95,10 @@ namespace Greenshot.Plugin.Imgur
|
||||||
{
|
{
|
||||||
_image?.Dispose();
|
_image?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
_image = null;
|
_image = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ImgurInfo ParseResponse(string response)
|
public static ImgurInfo ParseResponse(string response)
|
||||||
{
|
{
|
||||||
Log.Debug(response);
|
Log.Debug(response);
|
||||||
|
@ -154,26 +122,31 @@ namespace Greenshot.Plugin.Imgur
|
||||||
{
|
{
|
||||||
imgurInfo.Hash = nodes.Item(0)?.InnerText;
|
imgurInfo.Hash = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("hash");
|
nodes = doc.GetElementsByTagName("hash");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
imgurInfo.Hash = nodes.Item(0)?.InnerText;
|
imgurInfo.Hash = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("deletehash");
|
nodes = doc.GetElementsByTagName("deletehash");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
imgurInfo.DeleteHash = nodes.Item(0)?.InnerText;
|
imgurInfo.DeleteHash = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("type");
|
nodes = doc.GetElementsByTagName("type");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
imgurInfo.ImageType = nodes.Item(0)?.InnerText;
|
imgurInfo.ImageType = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("title");
|
nodes = doc.GetElementsByTagName("title");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
imgurInfo.Title = nodes.Item(0)?.InnerText;
|
imgurInfo.Title = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("datetime");
|
nodes = doc.GetElementsByTagName("datetime");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -184,17 +157,20 @@ namespace Greenshot.Plugin.Imgur
|
||||||
imgurInfo.Timestamp = epoch.AddSeconds(secondsSince).DateTime;
|
imgurInfo.Timestamp = epoch.AddSeconds(secondsSince).DateTime;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("original");
|
nodes = doc.GetElementsByTagName("original");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
imgurInfo.Original = nodes.Item(0)?.InnerText.Replace("http:", "https:");
|
imgurInfo.Original = nodes.Item(0)?.InnerText.Replace("http:", "https:");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version 3 API only has Link
|
// Version 3 API only has Link
|
||||||
nodes = doc.GetElementsByTagName("link");
|
nodes = doc.GetElementsByTagName("link");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
imgurInfo.Original = nodes.Item(0)?.InnerText.Replace("http:", "https:");
|
imgurInfo.Original = nodes.Item(0)?.InnerText.Replace("http:", "https:");
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("imgur_page");
|
nodes = doc.GetElementsByTagName("imgur_page");
|
||||||
if (nodes.Count > 0)
|
if (nodes.Count > 0)
|
||||||
{
|
{
|
||||||
|
@ -205,6 +181,7 @@ namespace Greenshot.Plugin.Imgur
|
||||||
// Version 3 doesn't have a page link in the response
|
// Version 3 doesn't have a page link in the response
|
||||||
imgurInfo.Page = $"https://imgur.com/{imgurInfo.Hash}";
|
imgurInfo.Page = $"https://imgur.com/{imgurInfo.Hash}";
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("small_square");
|
nodes = doc.GetElementsByTagName("small_square");
|
||||||
imgurInfo.SmallSquare = nodes.Count > 0 ? nodes.Item(0)?.InnerText : $"http://i.imgur.com/{imgurInfo.Hash}s.png";
|
imgurInfo.SmallSquare = nodes.Count > 0 ? nodes.Item(0)?.InnerText : $"http://i.imgur.com/{imgurInfo.Hash}s.png";
|
||||||
}
|
}
|
||||||
|
@ -212,6 +189,7 @@ namespace Greenshot.Plugin.Imgur
|
||||||
{
|
{
|
||||||
Log.ErrorFormat("Could not parse Imgur response due to error {0}, response was: {1}", e.Message, response);
|
Log.ErrorFormat("Could not parse Imgur response due to error {0}, response was: {1}", e.Message, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return imgurInfo;
|
return imgurInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,37 +32,46 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur {
|
namespace Greenshot.Plugin.Imgur
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the ImgurPlugin code
|
/// This is the ImgurPlugin code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Imgur", true)]
|
[Plugin("Imgur", true)]
|
||||||
public class ImgurPlugin : IGreenshotPlugin {
|
public class ImgurPlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurPlugin));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurPlugin));
|
||||||
private static ImgurConfiguration _config;
|
private static ImgurConfiguration _config;
|
||||||
private ComponentResourceManager _resources;
|
private ComponentResourceManager _resources;
|
||||||
private ToolStripMenuItem _historyMenuItem;
|
private ToolStripMenuItem _historyMenuItem;
|
||||||
private ToolStripMenuItem _itemPlugInConfig;
|
private ToolStripMenuItem _itemPlugInConfig;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void Dispose(bool disposing) {
|
protected virtual void Dispose(bool disposing)
|
||||||
if (disposing) {
|
{
|
||||||
if (_historyMenuItem != null) {
|
if (disposing)
|
||||||
|
{
|
||||||
|
if (_historyMenuItem != null)
|
||||||
|
{
|
||||||
_historyMenuItem.Dispose();
|
_historyMenuItem.Dispose();
|
||||||
_historyMenuItem = null;
|
_historyMenuItem = null;
|
||||||
}
|
}
|
||||||
if (_itemPlugInConfig != null) {
|
|
||||||
|
if (_itemPlugInConfig != null)
|
||||||
|
{
|
||||||
_itemPlugInConfig.Dispose();
|
_itemPlugInConfig.Dispose();
|
||||||
_itemPlugInConfig = null;
|
_itemPlugInConfig = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IDestination> Destinations() {
|
private IEnumerable<IDestination> Destinations()
|
||||||
|
{
|
||||||
yield return new ImgurDestination(this);
|
yield return new ImgurDestination(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -70,7 +79,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
// Get configuration
|
// Get configuration
|
||||||
_config = IniConfig.GetIniSection<ImgurConfiguration>();
|
_config = IniConfig.GetIniSection<ImgurConfiguration>();
|
||||||
_resources = new ComponentResourceManager(typeof(ImgurPlugin));
|
_resources = new ComponentResourceManager(typeof(ImgurPlugin));
|
||||||
|
@ -83,15 +93,11 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
// Provide the IDestination
|
// Provide the IDestination
|
||||||
SimpleServiceProvider.Current.AddService(Destinations());
|
SimpleServiceProvider.Current.AddService(Destinations());
|
||||||
_historyMenuItem = new ToolStripMenuItem(Language.GetString("imgur", LangKey.history));
|
_historyMenuItem = new ToolStripMenuItem(Language.GetString("imgur", LangKey.history));
|
||||||
_historyMenuItem.Click += delegate {
|
_historyMenuItem.Click += delegate { ImgurHistory.ShowHistory(); };
|
||||||
ImgurHistory.ShowHistory();
|
|
||||||
};
|
|
||||||
itemPlugInRoot.DropDownItems.Add(_historyMenuItem);
|
itemPlugInRoot.DropDownItems.Add(_historyMenuItem);
|
||||||
|
|
||||||
_itemPlugInConfig = new ToolStripMenuItem(Language.GetString("imgur", LangKey.configure));
|
_itemPlugInConfig = new ToolStripMenuItem(Language.GetString("imgur", LangKey.configure));
|
||||||
_itemPlugInConfig.Click += delegate {
|
_itemPlugInConfig.Click += delegate { _config.ShowConfigDialog(); };
|
||||||
_config.ShowConfigDialog();
|
|
||||||
};
|
|
||||||
itemPlugInRoot.DropDownItems.Add(_itemPlugInConfig);
|
itemPlugInRoot.DropDownItems.Add(_itemPlugInConfig);
|
||||||
|
|
||||||
PluginUtils.AddToContextMenu(itemPlugInRoot);
|
PluginUtils.AddToContextMenu(itemPlugInRoot);
|
||||||
|
@ -102,20 +108,26 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void OnLanguageChanged(object sender, EventArgs e) {
|
public void OnLanguageChanged(object sender, EventArgs e)
|
||||||
if (_itemPlugInConfig != null) {
|
{
|
||||||
|
if (_itemPlugInConfig != null)
|
||||||
|
{
|
||||||
_itemPlugInConfig.Text = Language.GetString("imgur", LangKey.configure);
|
_itemPlugInConfig.Text = Language.GetString("imgur", LangKey.configure);
|
||||||
}
|
}
|
||||||
if (_historyMenuItem != null) {
|
|
||||||
|
if (_historyMenuItem != null)
|
||||||
|
{
|
||||||
_historyMenuItem.Text = Language.GetString("imgur", LangKey.history);
|
_historyMenuItem.Text = Language.GetString("imgur", LangKey.history);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void UpdateHistoryMenuItem() {
|
private void UpdateHistoryMenuItem()
|
||||||
|
{
|
||||||
if (_historyMenuItem == null)
|
if (_historyMenuItem == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var form = SimpleServiceProvider.Current.GetInstance<Form>();
|
var form = SimpleServiceProvider.Current.GetInstance<Form>();
|
||||||
|
@ -126,18 +138,25 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (_config?.ImgurUploadHistory != null && _config.ImgurUploadHistory.Count > 0) {
|
|
||||||
|
if (_config?.ImgurUploadHistory != null && _config.ImgurUploadHistory.Count > 0)
|
||||||
|
{
|
||||||
historyMenuItem.Enabled = true;
|
historyMenuItem.Enabled = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
historyMenuItem.Enabled = false;
|
historyMenuItem.Enabled = false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Error("Error loading history", ex);
|
Log.Error("Error loading history", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Shutdown() {
|
public virtual void Shutdown()
|
||||||
|
{
|
||||||
Log.Debug("Imgur Plugin shutdown.");
|
Log.Debug("Imgur Plugin shutdown.");
|
||||||
Language.LanguageChanged -= OnLanguageChanged;
|
Language.LanguageChanged -= OnLanguageChanged;
|
||||||
}
|
}
|
||||||
|
@ -145,7 +164,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public virtual void Configure() {
|
public virtual void Configure()
|
||||||
|
{
|
||||||
_config.ShowConfigDialog();
|
_config.ShowConfigDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -156,9 +176,11 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// <param name="surfaceToUpload">ISurface</param>
|
/// <param name="surfaceToUpload">ISurface</param>
|
||||||
/// <param name="uploadUrl">out string for the url</param>
|
/// <param name="uploadUrl">out string for the url</param>
|
||||||
/// <returns>true if the upload succeeded</returns>
|
/// <returns>true if the upload succeeded</returns>
|
||||||
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl) {
|
public bool Upload(ICaptureDetails captureDetails, ISurface surfaceToUpload, out string uploadUrl)
|
||||||
|
{
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, _config.UploadReduceColors);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(_config.UploadFormat, _config.UploadJpegQuality, _config.UploadReduceColors);
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilenameFromPattern(_config.FilenamePattern, _config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilenameFromPattern(_config.FilenamePattern, _config.UploadFormat, captureDetails));
|
||||||
ImgurInfo imgurInfo = null;
|
ImgurInfo imgurInfo = null;
|
||||||
|
|
||||||
|
@ -167,7 +189,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
delegate
|
delegate
|
||||||
{
|
{
|
||||||
imgurInfo = ImgurUtils.UploadToImgur(surfaceToUpload, outputSettings, captureDetails.Title, filename);
|
imgurInfo = ImgurUtils.UploadToImgur(surfaceToUpload, outputSettings, captureDetails.Title, filename);
|
||||||
if (imgurInfo != null && _config.AnonymousAccess) {
|
if (imgurInfo != null && _config.AnonymousAccess)
|
||||||
|
{
|
||||||
Log.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash);
|
Log.InfoFormat("Storing imgur upload for hash {0} and delete hash {1}", imgurInfo.Hash, imgurInfo.DeleteHash);
|
||||||
_config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash);
|
_config.ImgurUploadHistory.Add(imgurInfo.Hash, imgurInfo.DeleteHash);
|
||||||
_config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo);
|
_config.runtimeImgurHistory.Add(imgurInfo.Hash, imgurInfo);
|
||||||
|
@ -176,11 +199,14 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
if (imgurInfo != null) {
|
if (imgurInfo != null)
|
||||||
|
{
|
||||||
// TODO: Optimize a second call for export
|
// TODO: Optimize a second call for export
|
||||||
using (Image tmpImage = surfaceToUpload.GetImageForExport()) {
|
using (Image tmpImage = surfaceToUpload.GetImageForExport())
|
||||||
|
{
|
||||||
imgurInfo.Image = ImageHelper.CreateThumbnail(tmpImage, 90, 90);
|
imgurInfo.Image = ImageHelper.CreateThumbnail(tmpImage, 90, 90);
|
||||||
}
|
}
|
||||||
|
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
|
|
||||||
if (_config.UsePageLink)
|
if (_config.UsePageLink)
|
||||||
|
@ -191,12 +217,12 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
{
|
{
|
||||||
uploadUrl = imgurInfo.Original;
|
uploadUrl = imgurInfo.Original;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(uploadUrl) && _config.CopyLinkToClipboard)
|
if (!string.IsNullOrEmpty(uploadUrl) && _config.CopyLinkToClipboard)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
ClipboardHelper.SetClipboardData(uploadUrl);
|
ClipboardHelper.SetClipboardData(uploadUrl);
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -204,12 +230,16 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.Error("Error uploading.", e);
|
Log.Error("Error uploading.", e);
|
||||||
MessageBox.Show(Language.GetString("imgur", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("imgur", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
|
|
||||||
uploadUrl = null;
|
uploadUrl = null;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,11 +30,13 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur {
|
namespace Greenshot.Plugin.Imgur
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// A collection of Imgur helper methods
|
/// A collection of Imgur helper methods
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static class ImgurUtils {
|
public static class ImgurUtils
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurUtils));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(ImgurUtils));
|
||||||
private const string SmallUrlPattern = "http://i.imgur.com/{0}s.jpg";
|
private const string SmallUrlPattern = "http://i.imgur.com/{0}s.jpg";
|
||||||
private static readonly ImgurConfiguration Config = IniConfig.GetIniSection<ImgurConfiguration>();
|
private static readonly ImgurConfiguration Config = IniConfig.GetIniSection<ImgurConfiguration>();
|
||||||
|
@ -45,14 +47,16 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
public static bool IsHistoryLoadingNeeded()
|
public static bool IsHistoryLoadingNeeded()
|
||||||
{
|
{
|
||||||
Log.InfoFormat("Checking if imgur cache loading needed, configuration has {0} imgur hashes, loaded are {1} hashes.", Config.ImgurUploadHistory.Count, Config.runtimeImgurHistory.Count);
|
Log.InfoFormat("Checking if imgur cache loading needed, configuration has {0} imgur hashes, loaded are {1} hashes.", Config.ImgurUploadHistory.Count,
|
||||||
|
Config.runtimeImgurHistory.Count);
|
||||||
return Config.runtimeImgurHistory.Count != Config.ImgurUploadHistory.Count;
|
return Config.runtimeImgurHistory.Count != Config.ImgurUploadHistory.Count;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Load the complete history of the imgur uploads, with the corresponding information
|
/// Load the complete history of the imgur uploads, with the corresponding information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public static void LoadHistory() {
|
public static void LoadHistory()
|
||||||
|
{
|
||||||
if (!IsHistoryLoadingNeeded())
|
if (!IsHistoryLoadingNeeded())
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
|
@ -61,8 +65,10 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
bool saveNeeded = false;
|
bool saveNeeded = false;
|
||||||
|
|
||||||
// Load the ImUr history
|
// Load the ImUr history
|
||||||
foreach (string hash in Config.ImgurUploadHistory.Keys.ToList()) {
|
foreach (string hash in Config.ImgurUploadHistory.Keys.ToList())
|
||||||
if (Config.runtimeImgurHistory.ContainsKey(hash)) {
|
{
|
||||||
|
if (Config.runtimeImgurHistory.ContainsKey(hash))
|
||||||
|
{
|
||||||
// Already loaded
|
// Already loaded
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -71,18 +77,24 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
{
|
{
|
||||||
var deleteHash = Config.ImgurUploadHistory[hash];
|
var deleteHash = Config.ImgurUploadHistory[hash];
|
||||||
ImgurInfo imgurInfo = RetrieveImgurInfo(hash, deleteHash);
|
ImgurInfo imgurInfo = RetrieveImgurInfo(hash, deleteHash);
|
||||||
if (imgurInfo != null) {
|
if (imgurInfo != null)
|
||||||
|
{
|
||||||
RetrieveImgurThumbnail(imgurInfo);
|
RetrieveImgurThumbnail(imgurInfo);
|
||||||
Config.runtimeImgurHistory[hash] = imgurInfo;
|
Config.runtimeImgurHistory[hash] = imgurInfo;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Log.InfoFormat("Deleting unknown ImgUr {0} from config, delete hash was {1}.", hash, deleteHash);
|
Log.InfoFormat("Deleting unknown ImgUr {0} from config, delete hash was {1}.", hash, deleteHash);
|
||||||
Config.ImgurUploadHistory.Remove(hash);
|
Config.ImgurUploadHistory.Remove(hash);
|
||||||
Config.runtimeImgurHistory.Remove(hash);
|
Config.runtimeImgurHistory.Remove(hash);
|
||||||
saveNeeded = true;
|
saveNeeded = true;
|
||||||
}
|
}
|
||||||
} catch (WebException wE) {
|
}
|
||||||
|
catch (WebException wE)
|
||||||
|
{
|
||||||
bool redirected = false;
|
bool redirected = false;
|
||||||
if (wE.Status == WebExceptionStatus.ProtocolError) {
|
if (wE.Status == WebExceptionStatus.ProtocolError)
|
||||||
|
{
|
||||||
HttpWebResponse response = (HttpWebResponse) wE.Response;
|
HttpWebResponse response = (HttpWebResponse) wE.Response;
|
||||||
|
|
||||||
if (response.StatusCode == HttpStatusCode.Forbidden)
|
if (response.StatusCode == HttpStatusCode.Forbidden)
|
||||||
|
@ -90,22 +102,30 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
Log.Error("Imgur loading forbidden", wE);
|
Log.Error("Imgur loading forbidden", wE);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Image no longer available?
|
// Image no longer available?
|
||||||
if (response.StatusCode == HttpStatusCode.Redirect) {
|
if (response.StatusCode == HttpStatusCode.Redirect)
|
||||||
|
{
|
||||||
Log.InfoFormat("ImgUr image for hash {0} is no longer available, removing it from the history", hash);
|
Log.InfoFormat("ImgUr image for hash {0} is no longer available, removing it from the history", hash);
|
||||||
Config.ImgurUploadHistory.Remove(hash);
|
Config.ImgurUploadHistory.Remove(hash);
|
||||||
Config.runtimeImgurHistory.Remove(hash);
|
Config.runtimeImgurHistory.Remove(hash);
|
||||||
redirected = true;
|
redirected = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!redirected) {
|
|
||||||
|
if (!redirected)
|
||||||
|
{
|
||||||
Log.Error("Problem loading ImgUr history for hash " + hash, wE);
|
Log.Error("Problem loading ImgUr history for hash " + hash, wE);
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.Error("Problem loading ImgUr history for hash " + hash, e);
|
Log.Error("Problem loading ImgUr history for hash " + hash, e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (saveNeeded) {
|
|
||||||
|
if (saveNeeded)
|
||||||
|
{
|
||||||
// Save needed changes
|
// Save needed changes
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
|
@ -115,7 +135,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// Use this to make sure Imgur knows from where the upload comes.
|
/// Use this to make sure Imgur knows from where the upload comes.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="webRequest"></param>
|
/// <param name="webRequest"></param>
|
||||||
private static void SetClientId(HttpWebRequest webRequest) {
|
private static void SetClientId(HttpWebRequest webRequest)
|
||||||
|
{
|
||||||
webRequest.Headers.Add("Authorization", "Client-ID " + ImgurCredentials.CONSUMER_KEY);
|
webRequest.Headers.Add("Authorization", "Client-ID " + ImgurCredentials.CONSUMER_KEY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,27 +149,36 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// <param name="title">Title</param>
|
/// <param name="title">Title</param>
|
||||||
/// <param name="filename">Filename</param>
|
/// <param name="filename">Filename</param>
|
||||||
/// <returns>ImgurInfo with details</returns>
|
/// <returns>ImgurInfo with details</returns>
|
||||||
public static ImgurInfo UploadToImgur(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename) {
|
public static ImgurInfo UploadToImgur(ISurface surfaceToUpload, SurfaceOutputSettings outputSettings, string title, string filename)
|
||||||
|
{
|
||||||
IDictionary<string, object> otherParameters = new Dictionary<string, object>();
|
IDictionary<string, object> otherParameters = new Dictionary<string, object>();
|
||||||
// add title
|
// add title
|
||||||
if (title != null && Config.AddTitle) {
|
if (title != null && Config.AddTitle)
|
||||||
|
{
|
||||||
otherParameters["title"] = title;
|
otherParameters["title"] = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
// add filename
|
// add filename
|
||||||
if (filename != null && Config.AddFilename) {
|
if (filename != null && Config.AddFilename)
|
||||||
|
{
|
||||||
otherParameters["name"] = filename;
|
otherParameters["name"] = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
string responseString = null;
|
string responseString = null;
|
||||||
if (Config.AnonymousAccess) {
|
if (Config.AnonymousAccess)
|
||||||
|
{
|
||||||
// add key, we only use the other parameters for the AnonymousAccess
|
// add key, we only use the other parameters for the AnonymousAccess
|
||||||
//otherParameters.Add("key", IMGUR_ANONYMOUS_API_KEY);
|
//otherParameters.Add("key", IMGUR_ANONYMOUS_API_KEY);
|
||||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(Config.ImgurApi3Url + "/upload.xml?" + NetworkHelper.GenerateQueryParameters(otherParameters), HTTPMethod.POST);
|
HttpWebRequest webRequest =
|
||||||
|
NetworkHelper.CreateWebRequest(Config.ImgurApi3Url + "/upload.xml?" + NetworkHelper.GenerateQueryParameters(otherParameters), HTTPMethod.POST);
|
||||||
webRequest.ContentType = "image/" + outputSettings.Format;
|
webRequest.ContentType = "image/" + outputSettings.Format;
|
||||||
webRequest.ServicePoint.Expect100Continue = false;
|
webRequest.ServicePoint.Expect100Continue = false;
|
||||||
|
|
||||||
SetClientId(webRequest);
|
SetClientId(webRequest);
|
||||||
try {
|
try
|
||||||
using (var requestStream = webRequest.GetRequestStream()) {
|
{
|
||||||
|
using (var requestStream = webRequest.GetRequestStream())
|
||||||
|
{
|
||||||
ImageOutput.SaveToStream(surfaceToUpload, requestStream, outputSettings);
|
ImageOutput.SaveToStream(surfaceToUpload, requestStream, outputSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -160,12 +190,15 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
using StreamReader reader = new StreamReader(responseStream, true);
|
using StreamReader reader = new StreamReader(responseStream, true);
|
||||||
responseString = reader.ReadToEnd();
|
responseString = reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Error("Upload to imgur gave an exception: ", ex);
|
Log.Error("Upload to imgur gave an exception: ", ex);
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
var oauth2Settings = new OAuth2Settings
|
var oauth2Settings = new OAuth2Settings
|
||||||
{
|
{
|
||||||
AuthUrlPattern = "https://api.imgur.com/oauth2/authorize?response_type=token&client_id={ClientId}&state={State}",
|
AuthUrlPattern = "https://api.imgur.com/oauth2/authorize?response_type=token&client_id={ClientId}&state={State}",
|
||||||
|
@ -201,10 +234,12 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
IniConfig.Save();
|
IniConfig.Save();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (string.IsNullOrEmpty(responseString))
|
if (string.IsNullOrEmpty(responseString))
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImgurInfo.ParseResponse(responseString);
|
return ImgurInfo.ParseResponse(responseString);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,11 +247,14 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// Retrieve the thumbnail of an imgur image
|
/// Retrieve the thumbnail of an imgur image
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imgurInfo"></param>
|
/// <param name="imgurInfo"></param>
|
||||||
public static void RetrieveImgurThumbnail(ImgurInfo imgurInfo) {
|
public static void RetrieveImgurThumbnail(ImgurInfo imgurInfo)
|
||||||
if (imgurInfo.SmallSquare == null) {
|
{
|
||||||
|
if (imgurInfo.SmallSquare == null)
|
||||||
|
{
|
||||||
Log.Warn("Imgur URL was null, not retrieving thumbnail.");
|
Log.Warn("Imgur URL was null, not retrieving thumbnail.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo.SmallSquare);
|
Log.InfoFormat("Retrieving Imgur image for {0} with url {1}", imgurInfo.Hash, imgurInfo.SmallSquare);
|
||||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(string.Format(SmallUrlPattern, imgurInfo.Hash), HTTPMethod.GET);
|
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(string.Format(SmallUrlPattern, imgurInfo.Hash), HTTPMethod.GET);
|
||||||
webRequest.ServicePoint.Expect100Continue = false;
|
webRequest.ServicePoint.Expect100Continue = false;
|
||||||
|
@ -237,7 +275,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// <param name="hash"></param>
|
/// <param name="hash"></param>
|
||||||
/// <param name="deleteHash"></param>
|
/// <param name="deleteHash"></param>
|
||||||
/// <returns>ImgurInfo</returns>
|
/// <returns>ImgurInfo</returns>
|
||||||
public static ImgurInfo RetrieveImgurInfo(string hash, string deleteHash) {
|
public static ImgurInfo RetrieveImgurInfo(string hash, string deleteHash)
|
||||||
|
{
|
||||||
string url = Config.ImgurApi3Url + "/image/" + hash + ".xml";
|
string url = Config.ImgurApi3Url + "/image/" + hash + ".xml";
|
||||||
Log.InfoFormat("Retrieving Imgur info for {0} with url {1}", hash, url);
|
Log.InfoFormat("Retrieving Imgur info for {0} with url {1}", hash, url);
|
||||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url, HTTPMethod.GET);
|
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url, HTTPMethod.GET);
|
||||||
|
@ -254,14 +293,20 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
using StreamReader reader = new StreamReader(responseStream, true);
|
using StreamReader reader = new StreamReader(responseStream, true);
|
||||||
responseString = reader.ReadToEnd();
|
responseString = reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
} catch (WebException wE) {
|
}
|
||||||
if (wE.Status == WebExceptionStatus.ProtocolError) {
|
catch (WebException wE)
|
||||||
if (((HttpWebResponse)wE.Response).StatusCode == HttpStatusCode.NotFound) {
|
{
|
||||||
|
if (wE.Status == WebExceptionStatus.ProtocolError)
|
||||||
|
{
|
||||||
|
if (((HttpWebResponse) wE.Response).StatusCode == HttpStatusCode.NotFound)
|
||||||
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
ImgurInfo imgurInfo = null;
|
ImgurInfo imgurInfo = null;
|
||||||
if (responseString != null)
|
if (responseString != null)
|
||||||
{
|
{
|
||||||
|
@ -269,6 +314,7 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
imgurInfo = ImgurInfo.ParseResponse(responseString);
|
imgurInfo = ImgurInfo.ParseResponse(responseString);
|
||||||
imgurInfo.DeleteHash = deleteHash;
|
imgurInfo.DeleteHash = deleteHash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return imgurInfo;
|
return imgurInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -276,16 +322,19 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// Delete an imgur image, this is done by specifying the delete hash
|
/// Delete an imgur image, this is done by specifying the delete hash
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="imgurInfo"></param>
|
/// <param name="imgurInfo"></param>
|
||||||
public static void DeleteImgurImage(ImgurInfo imgurInfo) {
|
public static void DeleteImgurImage(ImgurInfo imgurInfo)
|
||||||
|
{
|
||||||
Log.InfoFormat("Deleting Imgur image for {0}", imgurInfo.DeleteHash);
|
Log.InfoFormat("Deleting Imgur image for {0}", imgurInfo.DeleteHash);
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
string url = Config.ImgurApi3Url + "/image/" + imgurInfo.DeleteHash + ".xml";
|
string url = Config.ImgurApi3Url + "/image/" + imgurInfo.DeleteHash + ".xml";
|
||||||
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url, HTTPMethod.DELETE);
|
HttpWebRequest webRequest = NetworkHelper.CreateWebRequest(url, HTTPMethod.DELETE);
|
||||||
webRequest.ServicePoint.Expect100Continue = false;
|
webRequest.ServicePoint.Expect100Continue = false;
|
||||||
SetClientId(webRequest);
|
SetClientId(webRequest);
|
||||||
string responseString = null;
|
string responseString = null;
|
||||||
using (WebResponse response = webRequest.GetResponse()) {
|
using (WebResponse response = webRequest.GetResponse())
|
||||||
|
{
|
||||||
LogRateLimitInfo(response);
|
LogRateLimitInfo(response);
|
||||||
var responseStream = response.GetResponseStream();
|
var responseStream = response.GetResponseStream();
|
||||||
if (responseStream != null)
|
if (responseStream != null)
|
||||||
|
@ -294,15 +343,21 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
responseString = reader.ReadToEnd();
|
responseString = reader.ReadToEnd();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Log.InfoFormat("Delete result: {0}", responseString);
|
Log.InfoFormat("Delete result: {0}", responseString);
|
||||||
} catch (WebException wE) {
|
}
|
||||||
|
catch (WebException wE)
|
||||||
|
{
|
||||||
// Allow "Bad request" this means we already deleted it
|
// Allow "Bad request" this means we already deleted it
|
||||||
if (wE.Status == WebExceptionStatus.ProtocolError) {
|
if (wE.Status == WebExceptionStatus.ProtocolError)
|
||||||
if (((HttpWebResponse)wE.Response).StatusCode != HttpStatusCode.BadRequest) {
|
{
|
||||||
|
if (((HttpWebResponse) wE.Response).StatusCode != HttpStatusCode.BadRequest)
|
||||||
|
{
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure we remove it from the history, if no error occurred
|
// Make sure we remove it from the history, if no error occurred
|
||||||
Config.runtimeImgurHistory.Remove(imgurInfo.Hash);
|
Config.runtimeImgurHistory.Remove(imgurInfo.Hash);
|
||||||
Config.ImgurUploadHistory.Remove(imgurInfo.Hash);
|
Config.ImgurUploadHistory.Remove(imgurInfo.Hash);
|
||||||
|
@ -314,8 +369,10 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="nameValues"></param>
|
/// <param name="nameValues"></param>
|
||||||
/// <param name="key"></param>
|
/// <param name="key"></param>
|
||||||
private static void LogHeader(IDictionary<string, string> nameValues, string key) {
|
private static void LogHeader(IDictionary<string, string> nameValues, string key)
|
||||||
if (nameValues.ContainsKey(key)) {
|
{
|
||||||
|
if (nameValues.ContainsKey(key))
|
||||||
|
{
|
||||||
Log.InfoFormat("{0}={1}", key, nameValues[key]);
|
Log.InfoFormat("{0}={1}", key, nameValues[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -324,13 +381,17 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
/// Log the current rate-limit information
|
/// Log the current rate-limit information
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="response"></param>
|
/// <param name="response"></param>
|
||||||
private static void LogRateLimitInfo(WebResponse response) {
|
private static void LogRateLimitInfo(WebResponse response)
|
||||||
|
{
|
||||||
IDictionary<string, string> nameValues = new Dictionary<string, string>();
|
IDictionary<string, string> nameValues = new Dictionary<string, string>();
|
||||||
foreach (string key in response.Headers.AllKeys) {
|
foreach (string key in response.Headers.AllKeys)
|
||||||
if (!nameValues.ContainsKey(key)) {
|
{
|
||||||
|
if (!nameValues.ContainsKey(key))
|
||||||
|
{
|
||||||
nameValues.Add(key, response.Headers[key]);
|
nameValues.Add(key, response.Headers[key]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LogHeader(nameValues, "X-RateLimit-Limit");
|
LogHeader(nameValues, "X-RateLimit-Limit");
|
||||||
LogHeader(nameValues, "X-RateLimit-Remaining");
|
LogHeader(nameValues, "X-RateLimit-Remaining");
|
||||||
LogHeader(nameValues, "X-RateLimit-UserLimit");
|
LogHeader(nameValues, "X-RateLimit-UserLimit");
|
||||||
|
@ -340,7 +401,8 @@ namespace Greenshot.Plugin.Imgur {
|
||||||
LogHeader(nameValues, "X-RateLimit-ClientRemaining");
|
LogHeader(nameValues, "X-RateLimit-ClientRemaining");
|
||||||
|
|
||||||
// Update the credits in the config, this is shown in a form
|
// Update the credits in the config, this is shown in a form
|
||||||
if (nameValues.ContainsKey("X-RateLimit-Remaining") && int.TryParse(nameValues["X-RateLimit-Remaining"], out var credits)) {
|
if (nameValues.ContainsKey("X-RateLimit-Remaining") && int.TryParse(nameValues["X-RateLimit-Remaining"], out var credits))
|
||||||
|
{
|
||||||
Config.Credits = credits;
|
Config.Credits = credits;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Imgur {
|
namespace Greenshot.Plugin.Imgur
|
||||||
public enum LangKey {
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
upload_failure,
|
upload_failure,
|
||||||
communication_wait,
|
communication_wait,
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace Greenshot.Plugin.Jira
|
||||||
{
|
{
|
||||||
cacheItemPolicy.UpdateCallback = UpdateCallback;
|
cacheItemPolicy.UpdateCallback = UpdateCallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ActivateRemovedCallback)
|
if (ActivateRemovedCallback)
|
||||||
{
|
{
|
||||||
cacheItemPolicy.RemovedCallback = RemovedCallback;
|
cacheItemPolicy.RemovedCallback = RemovedCallback;
|
||||||
|
|
|
@ -30,15 +30,18 @@ using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira.Forms {
|
namespace Greenshot.Plugin.Jira.Forms
|
||||||
public partial class JiraForm : Form {
|
{
|
||||||
|
public partial class JiraForm : Form
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraForm));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraForm));
|
||||||
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 CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
|
|
||||||
public JiraForm(JiraConnector jiraConnector) {
|
public JiraForm(JiraConnector jiraConnector)
|
||||||
|
{
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Icon = GreenshotResources.GetGreenshotIcon();
|
Icon = GreenshotResources.GetGreenshotIcon();
|
||||||
AcceptButton = uploadButton;
|
AcceptButton = uploadButton;
|
||||||
|
@ -70,6 +73,7 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
{
|
{
|
||||||
MessageBox.Show(Language.GetFormattedString("jira", LangKey.login_error, e.Message));
|
MessageBox.Show(Language.GetFormattedString("jira", LangKey.login_error, e.Message));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (_jiraConnector.IsLoggedIn)
|
if (_jiraConnector.IsLoggedIn)
|
||||||
{
|
{
|
||||||
var filters = await _jiraConnector.GetFavoriteFiltersAsync();
|
var filters = await _jiraConnector.GetFavoriteFiltersAsync();
|
||||||
|
@ -79,8 +83,10 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
{
|
{
|
||||||
jiraFilterBox.Items.Add(filter);
|
jiraFilterBox.Items.Add(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
jiraFilterBox.SelectedIndex = 0;
|
jiraFilterBox.SelectedIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChangeModus(true);
|
ChangeModus(true);
|
||||||
if (_jiraConnector.Monitor.RecentJiras.Any())
|
if (_jiraConnector.Monitor.RecentJiras.Any())
|
||||||
{
|
{
|
||||||
|
@ -91,44 +97,53 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void InitializeComponentText() {
|
private void InitializeComponentText()
|
||||||
|
{
|
||||||
label_jirafilter.Text = Language.GetString("jira", LangKey.label_jirafilter);
|
label_jirafilter.Text = Language.GetString("jira", LangKey.label_jirafilter);
|
||||||
label_comment.Text = Language.GetString("jira", LangKey.label_comment);
|
label_comment.Text = Language.GetString("jira", LangKey.label_comment);
|
||||||
label_filename.Text = Language.GetString("jira", LangKey.label_filename);
|
label_filename.Text = Language.GetString("jira", LangKey.label_filename);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void ChangeModus(bool enabled) {
|
private void ChangeModus(bool enabled)
|
||||||
|
{
|
||||||
jiraFilterBox.Enabled = enabled;
|
jiraFilterBox.Enabled = enabled;
|
||||||
jiraListView.Enabled = enabled;
|
jiraListView.Enabled = enabled;
|
||||||
jiraFilenameBox.Enabled = enabled;
|
jiraFilenameBox.Enabled = enabled;
|
||||||
jiraCommentBox.Enabled = enabled;
|
jiraCommentBox.Enabled = enabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetFilename(string filename) {
|
public void SetFilename(string filename)
|
||||||
|
{
|
||||||
jiraFilenameBox.Text = filename;
|
jiraFilenameBox.Text = filename;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Issue GetJiraIssue() {
|
public Issue GetJiraIssue()
|
||||||
|
{
|
||||||
return _selectedIssue;
|
return _selectedIssue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task UploadAsync(IBinaryContainer attachment) {
|
public async Task UploadAsync(IBinaryContainer attachment)
|
||||||
|
{
|
||||||
attachment.Filename = jiraFilenameBox.Text;
|
attachment.Filename = jiraFilenameBox.Text;
|
||||||
await _jiraConnector.AttachAsync(_selectedIssue.Key, attachment);
|
await _jiraConnector.AttachAsync(_selectedIssue.Key, attachment);
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(jiraCommentBox.Text)) {
|
if (!string.IsNullOrEmpty(jiraCommentBox.Text))
|
||||||
|
{
|
||||||
await _jiraConnector.AddCommentAsync(_selectedIssue.Key, jiraCommentBox.Text);
|
await _jiraConnector.AddCommentAsync(_selectedIssue.Key, jiraCommentBox.Text);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void JiraFilterBox_SelectedIndexChanged(object sender, EventArgs e) {
|
private async void JiraFilterBox_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
if (_jiraConnector.IsLoggedIn) {
|
{
|
||||||
|
if (_jiraConnector.IsLoggedIn)
|
||||||
|
{
|
||||||
uploadButton.Enabled = false;
|
uploadButton.Enabled = false;
|
||||||
var filter = (Filter) jiraFilterBox.SelectedItem;
|
var filter = (Filter) jiraFilterBox.SelectedItem;
|
||||||
if (filter == null) {
|
if (filter == null)
|
||||||
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
IList<Issue> issues = null;
|
IList<Issue> issues = null;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -141,25 +156,33 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
}
|
}
|
||||||
|
|
||||||
jiraListView.Items.Clear();
|
jiraListView.Items.Clear();
|
||||||
if (issues?.Count > 0) {
|
if (issues?.Count > 0)
|
||||||
|
{
|
||||||
jiraListView.Columns.Clear();
|
jiraListView.Columns.Clear();
|
||||||
LangKey[] columns = { LangKey.column_issueType, LangKey.column_id, LangKey.column_created, LangKey.column_assignee, LangKey.column_reporter, LangKey.column_summary };
|
LangKey[] columns =
|
||||||
|
{
|
||||||
|
LangKey.column_issueType, LangKey.column_id, LangKey.column_created, LangKey.column_assignee, LangKey.column_reporter, LangKey.column_summary
|
||||||
|
};
|
||||||
foreach (LangKey column in columns)
|
foreach (LangKey column in columns)
|
||||||
{
|
{
|
||||||
if (!Language.TryGetString("jira", column, out var translation))
|
if (!Language.TryGetString("jira", column, out var translation))
|
||||||
{
|
{
|
||||||
translation = string.Empty;
|
translation = string.Empty;
|
||||||
}
|
}
|
||||||
|
|
||||||
jiraListView.Columns.Add(translation);
|
jiraListView.Columns.Add(translation);
|
||||||
}
|
}
|
||||||
|
|
||||||
var scaledIconSize = DpiHelper.ScaleWithDpi(CoreConfig.IconSize, DpiHelper.GetDpi(Handle));
|
var scaledIconSize = DpiHelper.ScaleWithDpi(CoreConfig.IconSize, DpiHelper.GetDpi(Handle));
|
||||||
var imageList = new ImageList {
|
var imageList = new ImageList
|
||||||
|
{
|
||||||
ImageSize = scaledIconSize
|
ImageSize = scaledIconSize
|
||||||
};
|
};
|
||||||
jiraListView.SmallImageList = imageList;
|
jiraListView.SmallImageList = imageList;
|
||||||
jiraListView.LargeImageList = imageList;
|
jiraListView.LargeImageList = imageList;
|
||||||
|
|
||||||
foreach (var issue in issues) {
|
foreach (var issue in issues)
|
||||||
|
{
|
||||||
var item = new ListViewItem
|
var item = new ListViewItem
|
||||||
{
|
{
|
||||||
Tag = issue
|
Tag = issue
|
||||||
|
@ -187,6 +210,7 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
{
|
{
|
||||||
jiraListView.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
|
jiraListView.AutoResizeColumn(i, ColumnHeaderAutoResizeStyle.ColumnContent);
|
||||||
}
|
}
|
||||||
|
|
||||||
jiraListView.Invalidate();
|
jiraListView.Invalidate();
|
||||||
jiraListView.Update();
|
jiraListView.Update();
|
||||||
}
|
}
|
||||||
|
@ -196,22 +220,30 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void JiraListView_SelectedIndexChanged(object sender, EventArgs e) {
|
private void JiraListView_SelectedIndexChanged(object sender, EventArgs e)
|
||||||
if (jiraListView.SelectedItems.Count > 0) {
|
{
|
||||||
|
if (jiraListView.SelectedItems.Count > 0)
|
||||||
|
{
|
||||||
_selectedIssue = (Issue) jiraListView.SelectedItems[0].Tag;
|
_selectedIssue = (Issue) jiraListView.SelectedItems[0].Tag;
|
||||||
jiraKey.Text = _selectedIssue.Key;
|
jiraKey.Text = _selectedIssue.Key;
|
||||||
uploadButton.Enabled = true;
|
uploadButton.Enabled = true;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
uploadButton.Enabled = false;
|
uploadButton.Enabled = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void JiraListView_ColumnClick(object sender, ColumnClickEventArgs e) {
|
private void JiraListView_ColumnClick(object sender, ColumnClickEventArgs e)
|
||||||
|
{
|
||||||
// Determine if clicked column is already the column that is being sorted.
|
// Determine if clicked column is already the column that is being sorted.
|
||||||
if (e.Column == _columnSorter.SortColumn) {
|
if (e.Column == _columnSorter.SortColumn)
|
||||||
|
{
|
||||||
// Reverse the current sort direction for this column.
|
// Reverse the current sort direction for this column.
|
||||||
_columnSorter.Order = _columnSorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
|
_columnSorter.Order = _columnSorter.Order == SortOrder.Ascending ? SortOrder.Descending : SortOrder.Ascending;
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Set the column number that is to be sorted; default to ascending.
|
// Set the column number that is to be sorted; default to ascending.
|
||||||
_columnSorter.SortColumn = e.Column;
|
_columnSorter.SortColumn = e.Column;
|
||||||
_columnSorter.Order = SortOrder.Ascending;
|
_columnSorter.Order = SortOrder.Ascending;
|
||||||
|
@ -221,13 +253,16 @@ namespace Greenshot.Plugin.Jira.Forms {
|
||||||
jiraListView.Sort();
|
jiraListView.Sort();
|
||||||
}
|
}
|
||||||
|
|
||||||
private async void JiraKeyTextChanged(object sender, EventArgs e) {
|
private async void JiraKeyTextChanged(object sender, EventArgs e)
|
||||||
|
{
|
||||||
string jiranumber = jiraKey.Text;
|
string jiranumber = jiraKey.Text;
|
||||||
uploadButton.Enabled = false;
|
uploadButton.Enabled = false;
|
||||||
int dashIndex = jiranumber.IndexOf('-');
|
int dashIndex = jiranumber.IndexOf('-');
|
||||||
if (dashIndex > 0 && jiranumber.Length > dashIndex+1) {
|
if (dashIndex > 0 && jiranumber.Length > dashIndex + 1)
|
||||||
|
{
|
||||||
_selectedIssue = await _jiraConnector.GetIssueAsync(jiraKey.Text);
|
_selectedIssue = await _jiraConnector.GetIssueAsync(jiraKey.Text);
|
||||||
if (_selectedIssue != null) {
|
if (_selectedIssue != null)
|
||||||
|
{
|
||||||
uploadButton.Enabled = true;
|
uploadButton.Enabled = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,9 @@
|
||||||
|
|
||||||
using GreenshotPlugin.Controls;
|
using GreenshotPlugin.Controls;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira.Forms {
|
namespace Greenshot.Plugin.Jira.Forms
|
||||||
public class JiraFormBase : GreenshotForm {
|
{
|
||||||
|
public class JiraFormBase : GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,11 +19,13 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira.Forms {
|
namespace Greenshot.Plugin.Jira.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : JiraFormBase {
|
public partial class SettingsForm : JiraFormBase
|
||||||
|
{
|
||||||
public SettingsForm()
|
public SettingsForm()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
@ -22,12 +22,14 @@
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira {
|
namespace Greenshot.Plugin.Jira
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of JiraConfiguration.
|
/// Description of JiraConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Jira", Description = "Greenshot Jira Plugin configuration")]
|
[IniSection("Jira", Description = "Greenshot Jira Plugin configuration")]
|
||||||
public class JiraConfiguration : IniSection {
|
public class JiraConfiguration : IniSection
|
||||||
|
{
|
||||||
public const string DefaultPrefix = "http://";
|
public const string DefaultPrefix = "http://";
|
||||||
private const string DefaultUrl = DefaultPrefix + "jira";
|
private const string DefaultUrl = DefaultPrefix + "jira";
|
||||||
|
|
||||||
|
|
|
@ -34,14 +34,18 @@ using Dapplo.Jira.SvgWinForms.Converters;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira {
|
namespace Greenshot.Plugin.Jira
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This encapsulates the JiraClient 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 sealed class JiraConnector : IDisposable {
|
public sealed 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));
|
||||||
private static readonly JiraConfiguration JiraConfig = IniConfig.GetIniSection<JiraConfiguration>();
|
private static readonly JiraConfiguration JiraConfig = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
|
|
||||||
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
private static readonly CoreConfiguration CoreConfig = IniConfig.GetIniSection<CoreConfiguration>();
|
||||||
|
|
||||||
// Used to remove the wsdl information from the old SOAP Uri
|
// Used to remove the wsdl information from the old SOAP Uri
|
||||||
public const string DefaultPostfix = "/rpc/soap/jirasoapservice-v2?wsdl";
|
public const string DefaultPostfix = "/rpc/soap/jirasoapservice-v2?wsdl";
|
||||||
private IJiraClient _jiraClient;
|
private IJiraClient _jiraClient;
|
||||||
|
@ -57,20 +61,25 @@ namespace Greenshot.Plugin.Jira {
|
||||||
if (args.PropertyName == nameof(CoreConfig.IconSize))
|
if (args.PropertyName == nameof(CoreConfig.IconSize))
|
||||||
{
|
{
|
||||||
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
||||||
jiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.ScaledIconSize.Width, Height = CoreConfig.ScaledIconSize.Height });
|
jiraConnector._jiraClient?.Behaviour.SetConfig(new SvgConfiguration
|
||||||
|
{
|
||||||
|
Width = CoreConfig.ScaledIconSize.Width,
|
||||||
|
Height = CoreConfig.ScaledIconSize.Height
|
||||||
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dispose, logout the users
|
/// Dispose, logout the users
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
if (_jiraClient != null)
|
if (_jiraClient != null)
|
||||||
{
|
{
|
||||||
Logout();
|
Logout();
|
||||||
}
|
}
|
||||||
|
|
||||||
FavIcon?.Dispose();
|
FavIcon?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -99,8 +108,13 @@ namespace Greenshot.Plugin.Jira {
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
_jiraClient = JiraClient.Create(new Uri(JiraConfig.Url));
|
_jiraClient = JiraClient.Create(new Uri(JiraConfig.Url));
|
||||||
_jiraClient.Behaviour.SetConfig(new SvgConfiguration { Width = CoreConfig.ScaledIconSize.Width, Height = CoreConfig.ScaledIconSize.Height });
|
_jiraClient.Behaviour.SetConfig(new SvgConfiguration
|
||||||
|
{
|
||||||
|
Width = CoreConfig.ScaledIconSize.Width,
|
||||||
|
Height = CoreConfig.ScaledIconSize.Height
|
||||||
|
});
|
||||||
_jiraClient.SetBasicAuthentication(user, password);
|
_jiraClient.SetBasicAuthentication(user, password);
|
||||||
|
|
||||||
_issueTypeBitmapCache = new IssueTypeBitmapCache(_jiraClient);
|
_issueTypeBitmapCache = new IssueTypeBitmapCache(_jiraClient);
|
||||||
|
@ -126,6 +140,7 @@ namespace Greenshot.Plugin.Jira {
|
||||||
Log.Warn("Exception details: ", ex2);
|
Log.Warn("Exception details: ", ex2);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -134,45 +149,58 @@ namespace Greenshot.Plugin.Jira {
|
||||||
/// 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(CancellationToken cancellationToken = default) {
|
public async Task LoginAsync(CancellationToken cancellationToken = default)
|
||||||
|
{
|
||||||
Logout();
|
Logout();
|
||||||
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)
|
||||||
{
|
{
|
||||||
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, cancellationToken)) {
|
{
|
||||||
if (credentialsDialog.SaveChecked) {
|
if (await DoLoginAsync(credentialsDialog.Name, credentialsDialog.Password, cancellationToken))
|
||||||
|
{
|
||||||
|
if (credentialsDialog.SaveChecked)
|
||||||
|
{
|
||||||
credentialsDialog.Confirm(true);
|
credentialsDialog.Confirm(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
IsLoggedIn = true;
|
IsLoggedIn = true;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Login failed, confirm this
|
// Login failed, confirm this
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
credentialsDialog.Confirm(false);
|
credentialsDialog.Confirm(false);
|
||||||
} catch (ApplicationException e) {
|
}
|
||||||
|
catch (ApplicationException e)
|
||||||
|
{
|
||||||
// exception handling ...
|
// exception handling ...
|
||||||
Log.Error("Problem using the credentials dialog", e);
|
Log.Error("Problem using the credentials dialog", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
// For every windows version after XP show an incorrect password baloon
|
// For every windows version after XP show an incorrect password baloon
|
||||||
credentialsDialog.IncorrectPassword = true;
|
credentialsDialog.IncorrectPassword = true;
|
||||||
// Make sure the dialog is display, the password was false!
|
// Make sure the dialog is display, the password was false!
|
||||||
credentialsDialog.AlwaysDisplay = true;
|
credentialsDialog.AlwaysDisplay = true;
|
||||||
}
|
}
|
||||||
} catch (ApplicationException e) {
|
}
|
||||||
|
catch (ApplicationException e)
|
||||||
|
{
|
||||||
// exception handling ...
|
// exception handling ...
|
||||||
Log.Error("Problem using the credentials dialog", e);
|
Log.Error("Problem using the credentials dialog", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// End the session, if there was one
|
/// End the session, if there was one
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Logout() {
|
public void Logout()
|
||||||
|
{
|
||||||
if (_jiraClient == null || !IsLoggedIn) return;
|
if (_jiraClient == null || !IsLoggedIn) return;
|
||||||
Monitor.Dispose();
|
Monitor.Dispose();
|
||||||
IsLoggedIn = false;
|
IsLoggedIn = false;
|
||||||
|
@ -183,8 +211,10 @@ namespace Greenshot.Plugin.Jira {
|
||||||
/// 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(CancellationToken cancellationToken = default) {
|
private async Task CheckCredentialsAsync(CancellationToken cancellationToken = default)
|
||||||
if (!IsLoggedIn) {
|
{
|
||||||
|
if (!IsLoggedIn)
|
||||||
|
{
|
||||||
await LoginAsync(cancellationToken);
|
await LoginAsync(cancellationToken);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -256,7 +286,10 @@ namespace Greenshot.Plugin.Jira {
|
||||||
public async Task<IList<Issue>> SearchAsync(Filter filter, CancellationToken cancellationToken = default)
|
public async Task<IList<Issue>> SearchAsync(Filter filter, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
await CheckCredentialsAsync(cancellationToken);
|
await CheckCredentialsAsync(cancellationToken);
|
||||||
var searchResult = await _jiraClient.Issue.SearchAsync(filter.Jql, null, new[] { "summary", "reporter", "assignee", "created", "issuetype" }, null, cancellationToken).ConfigureAwait(false);
|
var searchResult = await _jiraClient.Issue.SearchAsync(filter.Jql, null, new[]
|
||||||
|
{
|
||||||
|
"summary", "reporter", "assignee", "created", "issuetype"
|
||||||
|
}, null, cancellationToken).ConfigureAwait(false);
|
||||||
return searchResult.Issues;
|
return searchResult.Issues;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,27 +34,33 @@ using GreenshotPlugin.IniFile;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira {
|
namespace Greenshot.Plugin.Jira
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of JiraDestination.
|
/// Description of JiraDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class JiraDestination : AbstractDestination {
|
public class JiraDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(JiraDestination));
|
||||||
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
private static readonly JiraConfiguration Config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
private readonly Issue _jiraIssue;
|
private readonly Issue _jiraIssue;
|
||||||
|
|
||||||
public JiraDestination(Issue jiraIssue = null) {
|
public JiraDestination(Issue jiraIssue = null)
|
||||||
|
{
|
||||||
_jiraIssue = jiraIssue;
|
_jiraIssue = jiraIssue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation => "Jira";
|
public override string Designation => "Jira";
|
||||||
|
|
||||||
public override string Description {
|
public override string Description
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_jiraIssue?.Fields?.Summary == null) {
|
if (_jiraIssue?.Fields?.Summary == null)
|
||||||
|
{
|
||||||
return Language.GetString("jira", LangKey.upload_menu_item);
|
return Language.GetString("jira", LangKey.upload_menu_item);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Format the title of this destination
|
// Format the title of this destination
|
||||||
return _jiraIssue.Key + ": " + _jiraIssue.Fields.Summary.Substring(0, Math.Min(20, _jiraIssue.Fields.Summary.Length));
|
return _jiraIssue.Key + ": " + _jiraIssue.Fields.Summary.Substring(0, Math.Min(20, _jiraIssue.Fields.Summary.Length));
|
||||||
}
|
}
|
||||||
|
@ -64,7 +70,8 @@ namespace Greenshot.Plugin.Jira {
|
||||||
|
|
||||||
public override bool IsDynamic => true;
|
public override bool IsDynamic => true;
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
Image displayIcon = null;
|
Image displayIcon = null;
|
||||||
|
@ -83,16 +90,19 @@ namespace Greenshot.Plugin.Jira {
|
||||||
Log.Warn($"Problem loading issue type for {_jiraIssue.Key}, ignoring", ex);
|
Log.Warn($"Problem loading issue type for {_jiraIssue.Key}, ignoring", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayIcon == null)
|
if (displayIcon == null)
|
||||||
{
|
{
|
||||||
displayIcon = jiraConnector.FavIcon;
|
displayIcon = jiraConnector.FavIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayIcon == null)
|
if (displayIcon == null)
|
||||||
{
|
{
|
||||||
var resources = new ComponentResourceManager(typeof(JiraPlugin));
|
var resources = new ComponentResourceManager(typeof(JiraPlugin));
|
||||||
displayIcon = (Image) resources.GetObject("Jira");
|
displayIcon = (Image) resources.GetObject("Jira");
|
||||||
}
|
}
|
||||||
|
|
||||||
return displayIcon;
|
return displayIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,22 +110,27 @@ namespace Greenshot.Plugin.Jira {
|
||||||
public override IEnumerable<IDestination> DynamicDestinations()
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
{
|
{
|
||||||
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
||||||
if (jiraConnector == null || !jiraConnector.IsLoggedIn) {
|
if (jiraConnector == null || !jiraConnector.IsLoggedIn)
|
||||||
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var jiraDetails in jiraConnector.Monitor.RecentJiras)
|
foreach (var jiraDetails in jiraConnector.Monitor.RecentJiras)
|
||||||
{
|
{
|
||||||
yield return new JiraDestination(jiraDetails.JiraIssue);
|
yield return new JiraDestination(jiraDetails.JiraIssue);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surfaceToUpload, ICaptureDetails captureDetails) {
|
public override ExportInformation ExportCapture(bool manuallyInitiated, ISurface surfaceToUpload, ICaptureDetails captureDetails)
|
||||||
|
{
|
||||||
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
ExportInformation exportInformation = new ExportInformation(Designation, Description);
|
||||||
string filename = Path.GetFileName(FilenameHelper.GetFilename(Config.UploadFormat, captureDetails));
|
string filename = Path.GetFileName(FilenameHelper.GetFilename(Config.UploadFormat, captureDetails));
|
||||||
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(Config.UploadFormat, Config.UploadJpegQuality, Config.UploadReduceColors);
|
SurfaceOutputSettings outputSettings = new SurfaceOutputSettings(Config.UploadFormat, Config.UploadJpegQuality, Config.UploadReduceColors);
|
||||||
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
||||||
if (_jiraIssue != null) {
|
if (_jiraIssue != null)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
||||||
async () =>
|
async () =>
|
||||||
|
@ -128,31 +143,37 @@ namespace Greenshot.Plugin.Jira {
|
||||||
Log.DebugFormat("Uploaded to Jira {0}", _jiraIssue.Key);
|
Log.DebugFormat("Uploaded to Jira {0}", _jiraIssue.Key);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = surfaceToUpload.UploadUrl;
|
exportInformation.Uri = surfaceToUpload.UploadUrl;
|
||||||
} catch (Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
var jiraForm = new JiraForm(jiraConnector);
|
var jiraForm = new JiraForm(jiraConnector);
|
||||||
jiraForm.SetFilename(filename);
|
jiraForm.SetFilename(filename);
|
||||||
var dialogResult = jiraForm.ShowDialog();
|
var dialogResult = jiraForm.ShowDialog();
|
||||||
if (dialogResult == DialogResult.OK) {
|
if (dialogResult == DialogResult.OK)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
surfaceToUpload.UploadUrl = jiraConnector.JiraBaseUri.AppendSegments("browse", jiraForm.GetJiraIssue().Key).AbsoluteUri;
|
surfaceToUpload.UploadUrl = jiraConnector.JiraBaseUri.AppendSegments("browse", jiraForm.GetJiraIssue().Key).AbsoluteUri;
|
||||||
// Run upload in the background
|
// Run upload in the background
|
||||||
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait(Description, Language.GetString("jira", LangKey.communication_wait),
|
||||||
async () =>
|
async () => { await jiraForm.UploadAsync(new SurfaceContainer(surfaceToUpload, outputSettings, filename)); }
|
||||||
{
|
|
||||||
await jiraForm.UploadAsync(new SurfaceContainer(surfaceToUpload, outputSettings, filename));
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
Log.DebugFormat("Uploaded to Jira {0}", jiraForm.GetJiraIssue().Key);
|
Log.DebugFormat("Uploaded to Jira {0}", jiraForm.GetJiraIssue().Key);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = surfaceToUpload.UploadUrl;
|
exportInformation.Uri = surfaceToUpload.UploadUrl;
|
||||||
} catch(Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
MessageBox.Show(Language.GetString("jira", LangKey.upload_failure) + " " + e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surfaceToUpload);
|
ProcessExport(exportInformation, surfaceToUpload);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,37 +31,17 @@ namespace Greenshot.Plugin.Jira
|
||||||
FirstSeenAt = SeenAt = DateTimeOffset.Now;
|
FirstSeenAt = SeenAt = DateTimeOffset.Now;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ProjectKey
|
public string ProjectKey { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string Id
|
public string Id { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public string JiraKey => ProjectKey + "-" + Id;
|
public string JiraKey => ProjectKey + "-" + Id;
|
||||||
|
|
||||||
public Issue JiraIssue
|
public Issue JiraIssue { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset FirstSeenAt
|
public DateTimeOffset FirstSeenAt { get; private set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
private set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public DateTimeOffset SeenAt
|
public DateTimeOffset SeenAt { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int CompareTo(JiraDetails other)
|
public int CompareTo(JiraDetails other)
|
||||||
{
|
{
|
||||||
|
|
|
@ -25,16 +25,8 @@ namespace Greenshot.Plugin.Jira
|
||||||
{
|
{
|
||||||
public class JiraEventArgs : EventArgs
|
public class JiraEventArgs : EventArgs
|
||||||
{
|
{
|
||||||
public JiraEventTypes EventType
|
public JiraEventTypes EventType { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
|
|
||||||
public JiraDetails Details
|
public JiraDetails Details { get; set; }
|
||||||
{
|
|
||||||
get;
|
|
||||||
set;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -31,7 +31,6 @@ using GreenshotPlugin.Hooking;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira
|
namespace Greenshot.Plugin.Jira
|
||||||
{
|
{
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class will monitor all _jira activity by registering for title changes
|
/// This class will monitor all _jira activity by registering for title changes
|
||||||
/// It keeps a list of the last "accessed" jiras, and makes it easy to upload to one.
|
/// It keeps a list of the last "accessed" jiras, and makes it easy to upload to one.
|
||||||
|
@ -44,7 +43,9 @@ namespace Greenshot.Plugin.Jira
|
||||||
private readonly WindowsTitleMonitor _monitor;
|
private readonly WindowsTitleMonitor _monitor;
|
||||||
private readonly IList<IJiraClient> _jiraInstances = new List<IJiraClient>();
|
private readonly IList<IJiraClient> _jiraInstances = new List<IJiraClient>();
|
||||||
private readonly IDictionary<string, IJiraClient> _projectJiraClientMap = new Dictionary<string, IJiraClient>();
|
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())
|
// 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>();
|
||||||
|
|
||||||
|
@ -79,6 +80,7 @@ namespace Greenshot.Plugin.Jira
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// free managed resources
|
// free managed resources
|
||||||
_monitor.TitleChangeEvent -= MonitorTitleChangeEvent;
|
_monitor.TitleChangeEvent -= MonitorTitleChangeEvent;
|
||||||
_monitor.Dispose();
|
_monitor.Dispose();
|
||||||
|
@ -143,8 +145,13 @@ namespace Greenshot.Plugin.Jira
|
||||||
var issue = await jiraClient.Issue.GetAsync(jiraDetails.JiraKey).ConfigureAwait(false);
|
var issue = await jiraClient.Issue.GetAsync(jiraDetails.JiraKey).ConfigureAwait(false);
|
||||||
jiraDetails.JiraIssue = issue;
|
jiraDetails.JiraIssue = issue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send event
|
// Send event
|
||||||
JiraEvent?.Invoke(this, new JiraEventArgs { Details = jiraDetails, EventType = JiraEventTypes.DetectedNewJiraIssue });
|
JiraEvent?.Invoke(this, new JiraEventArgs
|
||||||
|
{
|
||||||
|
Details = jiraDetails,
|
||||||
|
EventType = JiraEventTypes.DetectedNewJiraIssue
|
||||||
|
});
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
|
@ -163,11 +170,13 @@ namespace Greenshot.Plugin.Jira
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var jiraKeyMatch = _jiraKeyPattern.Match(windowTitle);
|
var jiraKeyMatch = _jiraKeyPattern.Match(windowTitle);
|
||||||
if (!jiraKeyMatch.Success)
|
if (!jiraKeyMatch.Success)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Found a possible JIRA title
|
// Found a possible JIRA title
|
||||||
var jiraKey = jiraKeyMatch.Value;
|
var jiraKey = jiraKeyMatch.Value;
|
||||||
var jiraKeyParts = jiraKey.Split('-');
|
var jiraKeyParts = jiraKey.Split('-');
|
||||||
|
@ -184,11 +193,16 @@ namespace Greenshot.Plugin.Jira
|
||||||
currentJiraDetails.SeenAt = DateTimeOffset.Now;
|
currentJiraDetails.SeenAt = DateTimeOffset.Now;
|
||||||
|
|
||||||
// Notify the order change
|
// Notify the order change
|
||||||
JiraEvent?.Invoke(this, new JiraEventArgs { Details = currentJiraDetails, EventType = JiraEventTypes.OrderChanged });
|
JiraEvent?.Invoke(this, new JiraEventArgs
|
||||||
|
{
|
||||||
|
Details = currentJiraDetails,
|
||||||
|
EventType = JiraEventTypes.OrderChanged
|
||||||
|
});
|
||||||
// Nothing else to do
|
// Nothing else to do
|
||||||
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// We detected an unknown JIRA, so add it to our list
|
// We detected an unknown JIRA, so add it to our list
|
||||||
currentJiraDetails = new JiraDetails
|
currentJiraDetails = new JiraDetails
|
||||||
{
|
{
|
||||||
|
@ -205,6 +219,7 @@ namespace Greenshot.Plugin.Jira
|
||||||
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Now we can get the title from JIRA itself
|
// Now we can get the title from JIRA itself
|
||||||
// ReSharper disable once UnusedVariable
|
// ReSharper disable once UnusedVariable
|
||||||
var updateTitleTask = DetectedNewJiraIssueAsync(currentJiraDetails);
|
var updateTitleTask = DetectedNewJiraIssueAsync(currentJiraDetails);
|
||||||
|
|
|
@ -30,21 +30,25 @@ using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
using log4net;
|
using log4net;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira {
|
namespace Greenshot.Plugin.Jira
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the JiraPlugin base code
|
/// This is the JiraPlugin base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[Plugin("Jira", true)]
|
[Plugin("Jira", true)]
|
||||||
public class JiraPlugin : IGreenshotPlugin {
|
public class JiraPlugin : IGreenshotPlugin
|
||||||
|
{
|
||||||
private static readonly ILog Log = LogManager.GetLogger(typeof(JiraPlugin));
|
private static readonly ILog Log = LogManager.GetLogger(typeof(JiraPlugin));
|
||||||
private JiraConfiguration _config;
|
private JiraConfiguration _config;
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
protected void Dispose(bool disposing)
|
||||||
|
{
|
||||||
if (disposing)
|
if (disposing)
|
||||||
{
|
{
|
||||||
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
||||||
|
@ -56,7 +60,8 @@ namespace Greenshot.Plugin.Jira {
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
// Register configuration (don't need the configuration itself)
|
// Register configuration (don't need the configuration itself)
|
||||||
_config = IniConfig.GetIniSection<JiraConfiguration>();
|
_config = IniConfig.GetIniSection<JiraConfiguration>();
|
||||||
|
|
||||||
|
@ -94,7 +99,8 @@ namespace Greenshot.Plugin.Jira {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
Log.Debug("Jira Plugin shutdown.");
|
Log.Debug("Jira Plugin shutdown.");
|
||||||
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
||||||
jiraConnector?.Logout();
|
jiraConnector?.Logout();
|
||||||
|
@ -103,18 +109,19 @@ namespace Greenshot.Plugin.Jira {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
string url = _config.Url;
|
string url = _config.Url;
|
||||||
if (ShowConfigDialog()) {
|
if (ShowConfigDialog())
|
||||||
|
{
|
||||||
// check for re-login
|
// check for re-login
|
||||||
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
var jiraConnector = SimpleServiceProvider.Current.GetInstance<JiraConnector>();
|
||||||
if (jiraConnector != null && jiraConnector.IsLoggedIn && !string.IsNullOrEmpty(url)) {
|
if (jiraConnector != null && jiraConnector.IsLoggedIn && !string.IsNullOrEmpty(url))
|
||||||
if (!url.Equals(_config.Url)) {
|
|
||||||
jiraConnector.Logout();
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
{
|
||||||
await jiraConnector.LoginAsync();
|
if (!url.Equals(_config.Url))
|
||||||
});
|
{
|
||||||
|
jiraConnector.Logout();
|
||||||
|
Task.Run(async () => { await jiraConnector.LoginAsync(); });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -132,6 +139,7 @@ namespace Greenshot.Plugin.Jira {
|
||||||
{
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Jira {
|
namespace Greenshot.Plugin.Jira
|
||||||
public enum LangKey {
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
column_assignee,
|
column_assignee,
|
||||||
column_created,
|
column_created,
|
||||||
|
|
|
@ -114,6 +114,7 @@ namespace Greenshot.Plugin.Jira
|
||||||
case LogLevels.Warn:
|
case LogLevels.Warn:
|
||||||
return log.IsWarnEnabled;
|
return log.IsWarnEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
// Copyright (c) Dapplo and contributors. All rights reserved.
|
// Copyright (c) Dapplo and contributors. All rights reserved.
|
||||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office.Com
|
namespace Greenshot.Plugin.Office.Com
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
|
@ -38,6 +38,7 @@ namespace Greenshot.Plugin.Office.Com
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Do not catch an exception from this.
|
// Do not catch an exception from this.
|
||||||
// You may want to remove these guards depending on
|
// You may want to remove these guards depending on
|
||||||
// what you think the semantics should be.
|
// what you think the semantics should be.
|
||||||
|
@ -45,6 +46,7 @@ namespace Greenshot.Plugin.Office.Com
|
||||||
{
|
{
|
||||||
Marshal.ReleaseComObject(ComObject);
|
Marshal.ReleaseComObject(ComObject);
|
||||||
}
|
}
|
||||||
|
|
||||||
ComObject = default;
|
ComObject = default;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ namespace Greenshot.Plugin.Office.Com
|
||||||
{
|
{
|
||||||
return clsId;
|
return clsId;
|
||||||
}
|
}
|
||||||
|
|
||||||
return clsId;
|
return clsId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,29 +28,37 @@ using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office.Destinations {
|
namespace Greenshot.Plugin.Office.Destinations
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PowerpointDestination.
|
/// Description of PowerpointDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class ExcelDestination : AbstractDestination {
|
public class ExcelDestination : AbstractDestination
|
||||||
|
{
|
||||||
private const int IconApplication = 0;
|
private const int IconApplication = 0;
|
||||||
private const int IconWorkbook = 1;
|
private const int IconWorkbook = 1;
|
||||||
private static readonly string ExePath;
|
private static readonly string ExePath;
|
||||||
private readonly string _workbookName;
|
private readonly string _workbookName;
|
||||||
|
|
||||||
static ExcelDestination() {
|
static ExcelDestination()
|
||||||
|
{
|
||||||
ExePath = PluginUtils.GetExePath("EXCEL.EXE");
|
ExePath = PluginUtils.GetExePath("EXCEL.EXE");
|
||||||
if (ExePath != null && File.Exists(ExePath)) {
|
if (ExePath != null && File.Exists(ExePath))
|
||||||
|
{
|
||||||
WindowDetails.AddProcessToExcludeFromFreeze("excel");
|
WindowDetails.AddProcessToExcludeFromFreeze("excel");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ExePath = null;
|
ExePath = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExcelDestination() {
|
public ExcelDestination()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public ExcelDestination(string workbookName) {
|
public ExcelDestination(string workbookName)
|
||||||
|
{
|
||||||
_workbookName = workbookName;
|
_workbookName = workbookName;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -66,31 +74,42 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
|
|
||||||
public override Image DisplayIcon => PluginUtils.GetCachedExeIcon(ExePath, !string.IsNullOrEmpty(_workbookName) ? IconWorkbook : IconApplication);
|
public override Image DisplayIcon => PluginUtils.GetCachedExeIcon(ExePath, !string.IsNullOrEmpty(_workbookName) ? IconWorkbook : IconApplication);
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
foreach (string workbookName in ExcelExporter.GetWorkbooks()) {
|
{
|
||||||
|
foreach (string workbookName in ExcelExporter.GetWorkbooks())
|
||||||
|
{
|
||||||
yield return new ExcelDestination(workbookName);
|
yield return new ExcelDestination(workbookName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
bool createdFile = false;
|
bool createdFile = false;
|
||||||
string imageFile = captureDetails.Filename;
|
string imageFile = captureDetails.Filename;
|
||||||
if (imageFile == null || surface.Modified || !Regex.IsMatch(imageFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) {
|
if (imageFile == null || surface.Modified || !Regex.IsMatch(imageFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
||||||
|
{
|
||||||
imageFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
imageFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
||||||
createdFile = true;
|
createdFile = true;
|
||||||
}
|
}
|
||||||
if (_workbookName != null) {
|
|
||||||
|
if (_workbookName != null)
|
||||||
|
{
|
||||||
ExcelExporter.InsertIntoExistingWorkbook(_workbookName, imageFile, surface.Image.Size);
|
ExcelExporter.InsertIntoExistingWorkbook(_workbookName, imageFile, surface.Image.Size);
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ExcelExporter.InsertIntoNewWorkbook(imageFile, surface.Image.Size);
|
ExcelExporter.InsertIntoNewWorkbook(imageFile, surface.Image.Size);
|
||||||
}
|
}
|
||||||
|
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
// Cleanup imageFile if we created it here, so less tmp-files are generated and left
|
// Cleanup imageFile if we created it here, so less tmp-files are generated and left
|
||||||
if (createdFile) {
|
if (createdFile)
|
||||||
|
{
|
||||||
ImageOutput.DeleteNamedTmpFile(imageFile);
|
ImageOutput.DeleteNamedTmpFile(imageFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,10 @@ using Greenshot.Plugin.Office.OfficeExport.Entities;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office.Destinations {
|
namespace Greenshot.Plugin.Office.Destinations
|
||||||
public class OneNoteDestination : AbstractDestination {
|
{
|
||||||
|
public class OneNoteDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WordDestination));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(WordDestination));
|
||||||
private const int ICON_APPLICATION = 0;
|
private const int ICON_APPLICATION = 0;
|
||||||
public const string DESIGNATION = "OneNote";
|
public const string DESIGNATION = "OneNote";
|
||||||
|
@ -37,87 +39,105 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
private readonly OneNotePage page;
|
private readonly OneNotePage page;
|
||||||
private readonly OneNoteExporter _oneNoteExporter = new OneNoteExporter();
|
private readonly OneNoteExporter _oneNoteExporter = new OneNoteExporter();
|
||||||
|
|
||||||
static OneNoteDestination() {
|
static OneNoteDestination()
|
||||||
|
{
|
||||||
exePath = PluginUtils.GetExePath("ONENOTE.EXE");
|
exePath = PluginUtils.GetExePath("ONENOTE.EXE");
|
||||||
if (exePath != null && File.Exists(exePath)) {
|
if (exePath != null && File.Exists(exePath))
|
||||||
|
{
|
||||||
WindowDetails.AddProcessToExcludeFromFreeze("onenote");
|
WindowDetails.AddProcessToExcludeFromFreeze("onenote");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
exePath = null;
|
exePath = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OneNoteDestination() {
|
public OneNoteDestination()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public OneNoteDestination(OneNotePage page) {
|
public OneNoteDestination(OneNotePage page)
|
||||||
|
{
|
||||||
this.page = page;
|
this.page = page;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation {
|
public override string Designation
|
||||||
get {
|
{
|
||||||
return DESIGNATION;
|
get { return DESIGNATION; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Description {
|
public override string Description
|
||||||
get {
|
{
|
||||||
if (page == null) {
|
get
|
||||||
|
{
|
||||||
|
if (page == null)
|
||||||
|
{
|
||||||
return "Microsoft OneNote";
|
return "Microsoft OneNote";
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
return page.DisplayName;
|
return page.DisplayName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int Priority {
|
public override int Priority
|
||||||
get {
|
{
|
||||||
return 4;
|
get { return 4; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsDynamic {
|
public override bool IsDynamic
|
||||||
get {
|
{
|
||||||
return true;
|
get { return true; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool IsActive {
|
public override bool IsActive
|
||||||
get {
|
{
|
||||||
return base.IsActive && exePath != null;
|
get { return base.IsActive && exePath != null; }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
return PluginUtils.GetCachedExeIcon(exePath, ICON_APPLICATION);
|
get { return PluginUtils.GetCachedExeIcon(exePath, ICON_APPLICATION); }
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
foreach (OneNotePage page in _oneNoteExporter.GetPages()) {
|
{
|
||||||
|
foreach (OneNotePage page in _oneNoteExporter.GetPages())
|
||||||
|
{
|
||||||
yield return new OneNoteDestination(page);
|
yield return new OneNoteDestination(page);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
|
|
||||||
if (page == null) {
|
if (page == null)
|
||||||
try {
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
exportInformation.ExportMade = _oneNoteExporter.ExportToNewPage(surface);
|
exportInformation.ExportMade = _oneNoteExporter.ExportToNewPage(surface);
|
||||||
} catch(Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
exportInformation.ErrorMessage = ex.Message;
|
exportInformation.ErrorMessage = ex.Message;
|
||||||
LOG.Error(ex);
|
LOG.Error(ex);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
try {
|
else
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
exportInformation.ExportMade = _oneNoteExporter.ExportToPage(surface, page);
|
exportInformation.ExportMade = _oneNoteExporter.ExportToPage(surface, page);
|
||||||
} catch(Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
exportInformation.ErrorMessage = ex.Message;
|
exportInformation.ErrorMessage = ex.Message;
|
||||||
LOG.Error(ex);
|
LOG.Error(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,11 +32,13 @@ using GreenshotPlugin.Interfaces.Plugin;
|
||||||
using Microsoft.Office.Interop.Outlook;
|
using Microsoft.Office.Interop.Outlook;
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office.Destinations {
|
namespace Greenshot.Plugin.Office.Destinations
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of OutlookDestination.
|
/// Description of OutlookDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class OutlookDestination : AbstractDestination {
|
public class OutlookDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(OutlookDestination));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(OutlookDestination));
|
||||||
private const int IconApplication = 0;
|
private const int IconApplication = 0;
|
||||||
private const int IconMeeting = 2;
|
private const int IconMeeting = 2;
|
||||||
|
@ -50,17 +52,25 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
private readonly OlObjectClass _outlookInspectorType;
|
private readonly OlObjectClass _outlookInspectorType;
|
||||||
private readonly OutlookEmailExporter _outlookEmailExporter = new();
|
private readonly OutlookEmailExporter _outlookEmailExporter = new();
|
||||||
|
|
||||||
static OutlookDestination() {
|
static OutlookDestination()
|
||||||
if (HasOutlook()) {
|
{
|
||||||
|
if (HasOutlook())
|
||||||
|
{
|
||||||
IsActiveFlag = true;
|
IsActiveFlag = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
ExePath = PluginUtils.GetExePath("OUTLOOK.EXE");
|
ExePath = PluginUtils.GetExePath("OUTLOOK.EXE");
|
||||||
if (ExePath != null && File.Exists(ExePath)) {
|
if (ExePath != null && File.Exists(ExePath))
|
||||||
|
{
|
||||||
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
|
WindowDetails.AddProcessToExcludeFromFreeze("outlook");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ExePath = GetOutlookExePath();
|
ExePath = GetOutlookExePath();
|
||||||
}
|
}
|
||||||
if (ExePath == null) {
|
|
||||||
|
if (ExePath == null)
|
||||||
|
{
|
||||||
IsActiveFlag = false;
|
IsActiveFlag = false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -79,13 +89,16 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return File.Exists(outlookPath);
|
return File.Exists(outlookPath);
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutlookDestination() {
|
public OutlookDestination()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutlookDestination(string outlookInspectorCaption, OlObjectClass outlookInspectorType) {
|
public OutlookDestination(string outlookInspectorCaption, OlObjectClass outlookInspectorType)
|
||||||
|
{
|
||||||
_outlookInspectorCaption = outlookInspectorCaption;
|
_outlookInspectorCaption = outlookInspectorCaption;
|
||||||
_outlookInspectorType = outlookInspectorType;
|
_outlookInspectorType = outlookInspectorType;
|
||||||
}
|
}
|
||||||
|
@ -102,25 +115,32 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
|
|
||||||
public override Keys EditorShortcutKeys => Keys.Control | Keys.E;
|
public override Keys EditorShortcutKeys => Keys.Control | Keys.E;
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_outlookInspectorCaption == null)
|
if (_outlookInspectorCaption == null)
|
||||||
{
|
{
|
||||||
return PluginUtils.GetCachedExeIcon(ExePath, IconApplication);
|
return PluginUtils.GetCachedExeIcon(ExePath, IconApplication);
|
||||||
}
|
}
|
||||||
if (OlObjectClass.olAppointment.Equals(_outlookInspectorType)) {
|
|
||||||
|
if (OlObjectClass.olAppointment.Equals(_outlookInspectorType))
|
||||||
|
{
|
||||||
// Make sure we loaded the icon, maybe the configuration has been changed!
|
// Make sure we loaded the icon, maybe the configuration has been changed!
|
||||||
return PluginUtils.GetCachedExeIcon(ExePath, IconMeeting);
|
return PluginUtils.GetCachedExeIcon(ExePath, IconMeeting);
|
||||||
}
|
}
|
||||||
|
|
||||||
return MailIcon;
|
return MailIcon;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
|
{
|
||||||
IDictionary<string, OlObjectClass> inspectorCaptions = _outlookEmailExporter.RetrievePossibleTargets();
|
IDictionary<string, OlObjectClass> inspectorCaptions = _outlookEmailExporter.RetrievePossibleTargets();
|
||||||
if (inspectorCaptions != null) {
|
if (inspectorCaptions != null)
|
||||||
foreach (string inspectorCaption in inspectorCaptions.Keys) {
|
{
|
||||||
|
foreach (string inspectorCaption in inspectorCaptions.Keys)
|
||||||
|
{
|
||||||
yield return new OutlookDestination(inspectorCaption, inspectorCaptions[inspectorCaption]);
|
yield return new OutlookDestination(inspectorCaption, inspectorCaptions[inspectorCaption]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -133,49 +153,69 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
/// <param name="surface"></param>
|
/// <param name="surface"></param>
|
||||||
/// <param name="captureDetails"></param>
|
/// <param name="captureDetails"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
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);
|
||||||
// Outlook logic
|
// Outlook logic
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) {
|
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
||||||
|
{
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Log.InfoFormat("Using already available file: {0}", tmpFile);
|
Log.InfoFormat("Using already available file: {0}", tmpFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create a attachment name for the image
|
// Create a attachment name for the image
|
||||||
string attachmentName = captureDetails.Title;
|
string attachmentName = captureDetails.Title;
|
||||||
if (!string.IsNullOrEmpty(attachmentName)) {
|
if (!string.IsNullOrEmpty(attachmentName))
|
||||||
|
{
|
||||||
attachmentName = attachmentName.Trim();
|
attachmentName = attachmentName.Trim();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set default if non is set
|
// Set default if non is set
|
||||||
if (string.IsNullOrEmpty(attachmentName)) {
|
if (string.IsNullOrEmpty(attachmentName))
|
||||||
|
{
|
||||||
attachmentName = "Greenshot Capture";
|
attachmentName = "Greenshot Capture";
|
||||||
}
|
}
|
||||||
|
|
||||||
// Make sure it's "clean" so it doesn't corrupt the header
|
// Make sure it's "clean" so it doesn't corrupt the header
|
||||||
attachmentName = Regex.Replace(attachmentName, @"[^\x20\d\w]", string.Empty);
|
attachmentName = Regex.Replace(attachmentName, @"[^\x20\d\w]", string.Empty);
|
||||||
|
|
||||||
if (_outlookInspectorCaption != null) {
|
if (_outlookInspectorCaption != null)
|
||||||
|
{
|
||||||
_outlookEmailExporter.ExportToInspector(_outlookInspectorCaption, tmpFile, attachmentName);
|
_outlookEmailExporter.ExportToInspector(_outlookInspectorCaption, tmpFile, attachmentName);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
} else {
|
}
|
||||||
if (!manuallyInitiated) {
|
else
|
||||||
|
{
|
||||||
|
if (!manuallyInitiated)
|
||||||
|
{
|
||||||
var inspectorCaptions = _outlookEmailExporter.RetrievePossibleTargets();
|
var inspectorCaptions = _outlookEmailExporter.RetrievePossibleTargets();
|
||||||
if (inspectorCaptions != null && inspectorCaptions.Count > 0) {
|
if (inspectorCaptions != null && inspectorCaptions.Count > 0)
|
||||||
|
{
|
||||||
var destinations = new List<IDestination>
|
var destinations = new List<IDestination>
|
||||||
{
|
{
|
||||||
new OutlookDestination()
|
new OutlookDestination()
|
||||||
};
|
};
|
||||||
foreach (string inspectorCaption in inspectorCaptions.Keys) {
|
foreach (string inspectorCaption in inspectorCaptions.Keys)
|
||||||
|
{
|
||||||
destinations.Add(new OutlookDestination(inspectorCaption, inspectorCaptions[inspectorCaption]));
|
destinations.Add(new OutlookDestination(inspectorCaption, inspectorCaptions[inspectorCaption]));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
|
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
|
||||||
return ShowPickerMenu(false, surface, captureDetails, destinations);
|
return ShowPickerMenu(false, surface, captureDetails, destinations);
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
exportInformation.ExportMade = _outlookEmailExporter.ExportToOutlook(OfficeConfig.OutlookEmailFormat, tmpFile, FilenameHelper.FillPattern(OfficeConfig.EmailSubjectPattern, captureDetails, false), attachmentName, OfficeConfig.EmailTo, OfficeConfig.EmailCC, OfficeConfig.EmailBCC, null);
|
else
|
||||||
|
{
|
||||||
|
exportInformation.ExportMade = _outlookEmailExporter.ExportToOutlook(OfficeConfig.OutlookEmailFormat, tmpFile,
|
||||||
|
FilenameHelper.FillPattern(OfficeConfig.EmailSubjectPattern, captureDetails, false), attachmentName, OfficeConfig.EmailTo, OfficeConfig.EmailCC,
|
||||||
|
OfficeConfig.EmailBCC, null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,11 +29,13 @@ using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office.Destinations {
|
namespace Greenshot.Plugin.Office.Destinations
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PowerpointDestination.
|
/// Description of PowerpointDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PowerpointDestination : AbstractDestination {
|
public class PowerpointDestination : AbstractDestination
|
||||||
|
{
|
||||||
private const int IconApplication = 0;
|
private const int IconApplication = 0;
|
||||||
private const int IconPresentation = 1;
|
private const int IconPresentation = 1;
|
||||||
|
|
||||||
|
@ -41,30 +43,39 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
private readonly string _presentationName;
|
private readonly string _presentationName;
|
||||||
private readonly PowerpointExporter _powerpointExporter = new PowerpointExporter();
|
private readonly PowerpointExporter _powerpointExporter = new PowerpointExporter();
|
||||||
|
|
||||||
static PowerpointDestination() {
|
static PowerpointDestination()
|
||||||
|
{
|
||||||
ExePath = PluginUtils.GetExePath("POWERPNT.EXE");
|
ExePath = PluginUtils.GetExePath("POWERPNT.EXE");
|
||||||
if (ExePath != null && File.Exists(ExePath)) {
|
if (ExePath != null && File.Exists(ExePath))
|
||||||
|
{
|
||||||
WindowDetails.AddProcessToExcludeFromFreeze("powerpnt");
|
WindowDetails.AddProcessToExcludeFromFreeze("powerpnt");
|
||||||
} else {
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
ExePath = null;
|
ExePath = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public PowerpointDestination() {
|
public PowerpointDestination()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public PowerpointDestination(string presentationName) {
|
public PowerpointDestination(string presentationName)
|
||||||
|
{
|
||||||
_presentationName = presentationName;
|
_presentationName = presentationName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation => "Powerpoint";
|
public override string Designation => "Powerpoint";
|
||||||
|
|
||||||
public override string Description {
|
public override string Description
|
||||||
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
if (_presentationName == null) {
|
if (_presentationName == null)
|
||||||
|
{
|
||||||
return "Microsoft Powerpoint";
|
return "Microsoft Powerpoint";
|
||||||
}
|
}
|
||||||
|
|
||||||
return _presentationName;
|
return _presentationName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -75,9 +86,12 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
|
|
||||||
public override bool IsActive => base.IsActive && ExePath != null;
|
public override bool IsActive => base.IsActive && ExePath != null;
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
if (!string.IsNullOrEmpty(_presentationName)) {
|
get
|
||||||
|
{
|
||||||
|
if (!string.IsNullOrEmpty(_presentationName))
|
||||||
|
{
|
||||||
return PluginUtils.GetCachedExeIcon(ExePath, IconPresentation);
|
return PluginUtils.GetCachedExeIcon(ExePath, IconPresentation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,37 +99,55 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
foreach (string presentationName in _powerpointExporter.GetPowerpointPresentations()) {
|
{
|
||||||
|
foreach (string presentationName in _powerpointExporter.GetPowerpointPresentations())
|
||||||
|
{
|
||||||
yield return new PowerpointDestination(presentationName);
|
yield return new PowerpointDestination(presentationName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
Size imageSize = Size.Empty;
|
Size imageSize = Size.Empty;
|
||||||
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) {
|
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
||||||
|
{
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
||||||
imageSize = surface.Image.Size;
|
imageSize = surface.Image.Size;
|
||||||
}
|
}
|
||||||
if (_presentationName != null) {
|
|
||||||
|
if (_presentationName != null)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = _powerpointExporter.ExportToPresentation(_presentationName, tmpFile, imageSize, captureDetails.Title);
|
exportInformation.ExportMade = _powerpointExporter.ExportToPresentation(_presentationName, tmpFile, imageSize, captureDetails.Title);
|
||||||
} else {
|
}
|
||||||
if (!manuallyInitiated) {
|
else
|
||||||
|
{
|
||||||
|
if (!manuallyInitiated)
|
||||||
|
{
|
||||||
var presentations = _powerpointExporter.GetPowerpointPresentations().ToList();
|
var presentations = _powerpointExporter.GetPowerpointPresentations().ToList();
|
||||||
if (presentations != null && presentations.Count > 0) {
|
if (presentations != null && presentations.Count > 0)
|
||||||
var destinations = new List<IDestination> {new PowerpointDestination()};
|
{
|
||||||
foreach (string presentation in presentations) {
|
var destinations = new List<IDestination>
|
||||||
|
{
|
||||||
|
new PowerpointDestination()
|
||||||
|
};
|
||||||
|
foreach (string presentation in presentations)
|
||||||
|
{
|
||||||
destinations.Add(new PowerpointDestination(presentation));
|
destinations.Add(new PowerpointDestination(presentation));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
|
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
|
||||||
return ShowPickerMenu(false, surface, captureDetails, destinations);
|
return ShowPickerMenu(false, surface, captureDetails, destinations);
|
||||||
}
|
}
|
||||||
} else if (!exportInformation.ExportMade) {
|
}
|
||||||
|
else if (!exportInformation.ExportMade)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = _powerpointExporter.InsertIntoNewPresentation(tmpFile, imageSize, captureDetails.Title);
|
exportInformation.ExportMade = _powerpointExporter.InsertIntoNewPresentation(tmpFile, imageSize, captureDetails.Title);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -30,29 +30,35 @@ using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office.Destinations {
|
namespace Greenshot.Plugin.Office.Destinations
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of EmailDestination.
|
/// Description of EmailDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class WordDestination : AbstractDestination {
|
public class WordDestination : AbstractDestination
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(WordDestination));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(WordDestination));
|
||||||
private const int IconApplication = 0;
|
private const int IconApplication = 0;
|
||||||
private const int IconDocument = 1;
|
private const int IconDocument = 1;
|
||||||
private static readonly string ExePath;
|
private static readonly string ExePath;
|
||||||
private readonly string _documentCaption;
|
private readonly string _documentCaption;
|
||||||
private readonly WordExporter _wordExporter = new WordExporter();
|
private readonly WordExporter _wordExporter = new WordExporter();
|
||||||
static WordDestination() {
|
|
||||||
|
static WordDestination()
|
||||||
|
{
|
||||||
ExePath = PluginUtils.GetExePath("WINWORD.EXE");
|
ExePath = PluginUtils.GetExePath("WINWORD.EXE");
|
||||||
if (ExePath != null && !File.Exists(ExePath)) {
|
if (ExePath != null && !File.Exists(ExePath))
|
||||||
|
{
|
||||||
ExePath = null;
|
ExePath = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public WordDestination() {
|
public WordDestination()
|
||||||
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public WordDestination(string wordCaption) {
|
public WordDestination(string wordCaption)
|
||||||
|
{
|
||||||
_documentCaption = wordCaption;
|
_documentCaption = wordCaption;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -68,62 +74,88 @@ namespace Greenshot.Plugin.Office.Destinations {
|
||||||
|
|
||||||
public override Image DisplayIcon => PluginUtils.GetCachedExeIcon(ExePath, !string.IsNullOrEmpty(_documentCaption) ? IconDocument : IconApplication);
|
public override Image DisplayIcon => PluginUtils.GetCachedExeIcon(ExePath, !string.IsNullOrEmpty(_documentCaption) ? IconDocument : IconApplication);
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
foreach (string wordCaption in _wordExporter.GetWordDocuments()) {
|
{
|
||||||
|
foreach (string wordCaption in _wordExporter.GetWordDocuments())
|
||||||
|
{
|
||||||
yield return new WordDestination(wordCaption);
|
yield return new WordDestination(wordCaption);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
||||||
string tmpFile = captureDetails.Filename;
|
string tmpFile = captureDetails.Filename;
|
||||||
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$")) {
|
if (tmpFile == null || surface.Modified || !Regex.IsMatch(tmpFile, @".*(\.png|\.gif|\.jpg|\.jpeg|\.tiff|\.bmp)$"))
|
||||||
|
{
|
||||||
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
tmpFile = ImageOutput.SaveNamedTmpFile(surface, captureDetails, new SurfaceOutputSettings().PreventGreenshotFormat());
|
||||||
}
|
}
|
||||||
if (_documentCaption != null) {
|
|
||||||
try {
|
if (_documentCaption != null)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
_wordExporter.InsertIntoExistingDocument(_documentCaption, tmpFile);
|
_wordExporter.InsertIntoExistingDocument(_documentCaption, tmpFile);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
} catch (Exception) {
|
}
|
||||||
try {
|
catch (Exception)
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
_wordExporter.InsertIntoExistingDocument(_documentCaption, tmpFile);
|
_wordExporter.InsertIntoExistingDocument(_documentCaption, tmpFile);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Error(ex);
|
Log.Error(ex);
|
||||||
// TODO: Change to general logic in ProcessExport
|
// TODO: Change to general logic in ProcessExport
|
||||||
surface.SendMessageEvent(this, SurfaceMessageTyp.Error, Language.GetFormattedString("destination_exportfailed", Description));
|
surface.SendMessageEvent(this, SurfaceMessageTyp.Error, Language.GetFormattedString("destination_exportfailed", Description));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
if (!manuallyInitiated) {
|
else
|
||||||
|
{
|
||||||
|
if (!manuallyInitiated)
|
||||||
|
{
|
||||||
var documents = _wordExporter.GetWordDocuments().ToList();
|
var documents = _wordExporter.GetWordDocuments().ToList();
|
||||||
if (documents != null && documents.Count > 0) {
|
if (documents != null && documents.Count > 0)
|
||||||
|
{
|
||||||
var destinations = new List<IDestination>
|
var destinations = new List<IDestination>
|
||||||
{
|
{
|
||||||
new WordDestination()
|
new WordDestination()
|
||||||
};
|
};
|
||||||
foreach (string document in documents) {
|
foreach (string document in documents)
|
||||||
|
{
|
||||||
destinations.Add(new WordDestination(document));
|
destinations.Add(new WordDestination(document));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
|
// Return the ExportInformation from the picker without processing, as this indirectly comes from us self
|
||||||
return ShowPickerMenu(false, surface, captureDetails, destinations);
|
return ShowPickerMenu(false, surface, captureDetails, destinations);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
try {
|
|
||||||
|
try
|
||||||
|
{
|
||||||
_wordExporter.InsertIntoNewDocument(tmpFile, null, null);
|
_wordExporter.InsertIntoNewDocument(tmpFile, null, null);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
} catch(Exception) {
|
}
|
||||||
|
catch (Exception)
|
||||||
|
{
|
||||||
// Retry once, just in case
|
// Retry once, just in case
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
_wordExporter.InsertIntoNewDocument(tmpFile, null, null);
|
_wordExporter.InsertIntoNewDocument(tmpFile, null, null);
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
} catch (Exception ex) {
|
}
|
||||||
|
catch (Exception ex)
|
||||||
|
{
|
||||||
Log.Error(ex);
|
Log.Error(ex);
|
||||||
// TODO: Change to general logic in ProcessExport
|
// TODO: Change to general logic in ProcessExport
|
||||||
surface.SendMessageEvent(this, SurfaceMessageTyp.Error, Language.GetFormattedString("destination_exportfailed", Description));
|
surface.SendMessageEvent(this, SurfaceMessageTyp.Error, Language.GetFormattedString("destination_exportfailed", Description));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
Binary file not shown.
|
@ -23,32 +23,40 @@ using Greenshot.Plugin.Office.OfficeInterop;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
using Microsoft.Office.Interop.PowerPoint;
|
using Microsoft.Office.Interop.PowerPoint;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office {
|
namespace Greenshot.Plugin.Office
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of CoreConfiguration.
|
/// Description of CoreConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Office", Description = "Greenshot Office configuration")]
|
[IniSection("Office", Description = "Greenshot Office configuration")]
|
||||||
public class OfficeConfiguration : IniSection {
|
public class OfficeConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("OutlookEmailFormat", Description = "Default type for emails. (Text, HTML)", DefaultValue = "HTML")]
|
[IniProperty("OutlookEmailFormat", Description = "Default type for emails. (Text, HTML)", DefaultValue = "HTML")]
|
||||||
public EmailFormat OutlookEmailFormat { get; set; }
|
public EmailFormat OutlookEmailFormat { get; set; }
|
||||||
|
|
||||||
[IniProperty("EmailSubjectPattern", Description = "Email subject pattern, works like the OutputFileFilenamePattern", DefaultValue = "${title}")]
|
[IniProperty("EmailSubjectPattern", Description = "Email subject pattern, works like the OutputFileFilenamePattern", DefaultValue = "${title}")]
|
||||||
public string EmailSubjectPattern { get; set; }
|
public string EmailSubjectPattern { get; set; }
|
||||||
|
|
||||||
[IniProperty("EmailTo", Description = "Default value for the to in emails that are created", DefaultValue = "")]
|
[IniProperty("EmailTo", Description = "Default value for the to in emails that are created", DefaultValue = "")]
|
||||||
public string EmailTo { get; set; }
|
public string EmailTo { get; set; }
|
||||||
|
|
||||||
[IniProperty("EmailCC", Description = "Default value for the CC in emails that are created", DefaultValue = "")]
|
[IniProperty("EmailCC", Description = "Default value for the CC in emails that are created", DefaultValue = "")]
|
||||||
public string EmailCC { get; set; }
|
public string EmailCC { get; set; }
|
||||||
|
|
||||||
[IniProperty("EmailBCC", Description = "Default value for the BCC in emails that are created", DefaultValue = "")]
|
[IniProperty("EmailBCC", Description = "Default value for the BCC in emails that are created", DefaultValue = "")]
|
||||||
public string EmailBCC { get; set; }
|
public string EmailBCC { get; set; }
|
||||||
|
|
||||||
[IniProperty("OutlookAllowExportInMeetings", Description = "For Outlook: Allow export in meeting items", DefaultValue = "False")]
|
[IniProperty("OutlookAllowExportInMeetings", Description = "For Outlook: Allow export in meeting items", DefaultValue = "False")]
|
||||||
public bool OutlookAllowExportInMeetings { get; set; }
|
public bool OutlookAllowExportInMeetings { get; set; }
|
||||||
|
|
||||||
[IniProperty("WordLockAspectRatio", Description = "For Word: Lock the aspect ratio of the image", DefaultValue = "True")]
|
[IniProperty("WordLockAspectRatio", Description = "For Word: Lock the aspect ratio of the image", DefaultValue = "True")]
|
||||||
public bool WordLockAspectRatio { get; set; }
|
public bool WordLockAspectRatio { get; set; }
|
||||||
|
|
||||||
[IniProperty("PowerpointLockAspectRatio", Description = "For Powerpoint: Lock the aspect ratio of the image", DefaultValue = "True")]
|
[IniProperty("PowerpointLockAspectRatio", Description = "For Powerpoint: Lock the aspect ratio of the image", DefaultValue = "True")]
|
||||||
public bool PowerpointLockAspectRatio { get; set; }
|
public bool PowerpointLockAspectRatio { get; set; }
|
||||||
[IniProperty("PowerpointSlideLayout", Description = "For Powerpoint: Slide layout, changing this to a wrong value will fallback on ppLayoutBlank!!", DefaultValue = "ppLayoutPictureWithCaption")]
|
|
||||||
public PpSlideLayout PowerpointSlideLayout { get; set; }
|
|
||||||
|
|
||||||
|
[IniProperty("PowerpointSlideLayout", Description = "For Powerpoint: Slide layout, changing this to a wrong value will fallback on ppLayoutBlank!!",
|
||||||
|
DefaultValue = "ppLayoutPictureWithCaption")]
|
||||||
|
public PpSlideLayout PowerpointSlideLayout { get; set; }
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -34,6 +34,7 @@ namespace Greenshot.Plugin.Office.OfficeExport.Entities
|
||||||
{
|
{
|
||||||
return string.Format("{0} / {1}", Parent.Name, Name);
|
return string.Format("{0} / {1}", Parent.Name, Name);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Format("{0} / {1} / {2}", Parent.Parent.Name, Parent.Name, Name);
|
return string.Format("{0} / {1} / {2}", Parent.Parent.Name, Parent.Name, Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -53,10 +53,12 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// Ignore, probably no excel running
|
// Ignore, probably no excel running
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (excelApplication?.ComObject != null)
|
if (excelApplication?.ComObject != null)
|
||||||
{
|
{
|
||||||
InitializeVariables(excelApplication);
|
InitializeVariables(excelApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
return excelApplication;
|
return excelApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,6 +73,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
excelApplication = DisposableCom.Create(new Application());
|
excelApplication = DisposableCom.Create(new Application());
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVariables(excelApplication);
|
InitializeVariables(excelApplication);
|
||||||
return excelApplication;
|
return excelApplication;
|
||||||
}
|
}
|
||||||
|
@ -108,6 +111,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Version.TryParse(excelApplication.ComObject.Version, out _excelVersion))
|
if (!Version.TryParse(excelApplication.ComObject.Version, out _excelVersion))
|
||||||
{
|
{
|
||||||
LOG.Warn("Assuming Excel version 1997.");
|
LOG.Warn("Assuming Excel version 1997.");
|
||||||
|
@ -195,5 +199,4 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
InsertIntoExistingWorkbook(workbook, tmpFile, imageSize);
|
InsertIntoExistingWorkbook(workbook, tmpFile, imageSize);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -38,7 +38,10 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
public class OneNoteExporter
|
public class OneNoteExporter
|
||||||
{
|
{
|
||||||
private const string XmlImageContent = "<one:Image format=\"png\"><one:Size width=\"{1}.0\" height=\"{2}.0\" isSetByUser=\"true\" /><one:Data>{0}</one:Data></one:Image>";
|
private const string XmlImageContent = "<one:Image format=\"png\"><one:Size width=\"{1}.0\" height=\"{2}.0\" isSetByUser=\"true\" /><one:Data>{0}</one:Data></one:Image>";
|
||||||
private const string XmlOutline = "<?xml version=\"1.0\"?><one:Page xmlns:one=\"{2}\" ID=\"{1}\"><one:Title><one:OE><one:T><![CDATA[{3}]]></one:T></one:OE></one:Title>{0}</one:Page>";
|
|
||||||
|
private const string XmlOutline =
|
||||||
|
"<?xml version=\"1.0\"?><one:Page xmlns:one=\"{2}\" ID=\"{1}\"><one:Title><one:OE><one:T><![CDATA[{3}]]></one:T></one:OE></one:Title>{0}</one:Page>";
|
||||||
|
|
||||||
private const string OnenoteNamespace2010 = "http://schemas.microsoft.com/office/onenote/2010/onenote";
|
private const string OnenoteNamespace2010 = "http://schemas.microsoft.com/office/onenote/2010/onenote";
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OneNoteExporter));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OneNoteExporter));
|
||||||
|
|
||||||
|
@ -107,6 +110,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Warn("Unable to navigate to the target page", ex);
|
LOG.Warn("Unable to navigate to the target page", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -126,6 +130,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// Ignore, probably no OneNote running
|
// Ignore, probably no OneNote running
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return oneNoteApplication;
|
return oneNoteApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -140,6 +145,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
oneNoteApplication = DisposableCom.Create(new Application());
|
oneNoteApplication = DisposableCom.Create(new Application());
|
||||||
}
|
}
|
||||||
|
|
||||||
return oneNoteApplication;
|
return oneNoteApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -183,6 +189,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("one:Section".Equals(xmlReader.Name))
|
if ("one:Section".Equals(xmlReader.Name))
|
||||||
{
|
{
|
||||||
string id = xmlReader.GetAttribute("ID");
|
string id = xmlReader.GetAttribute("ID");
|
||||||
|
@ -196,6 +203,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if ("one:Page".Equals(xmlReader.Name))
|
if ("one:Page".Equals(xmlReader.Name))
|
||||||
{
|
{
|
||||||
// Skip deleted items
|
// Skip deleted items
|
||||||
|
@ -214,6 +222,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
page.IsCurrentlyViewed = "true".Equals(xmlReader.GetAttribute("isCurrentlyViewed"));
|
page.IsCurrentlyViewed = "true".Equals(xmlReader.GetAttribute("isCurrentlyViewed"));
|
||||||
pages.Add(page);
|
pages.Add(page);
|
||||||
}
|
}
|
||||||
|
@ -233,20 +242,24 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
if (cEx.ErrorCode == unchecked((int) 0x8002801D))
|
if (cEx.ErrorCode == unchecked((int) 0x8002801D))
|
||||||
{
|
{
|
||||||
LOG.Warn("Wrong registry keys, to solve this remove the OneNote key as described here: http://microsoftmercenary.com/wp/outlook-excel-interop-calls-breaking-solved/");
|
LOG.Warn(
|
||||||
|
"Wrong registry keys, to solve this remove the OneNote key as described here: http://microsoftmercenary.com/wp/outlook-excel-interop-calls-breaking-solved/");
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.Warn("Problem retrieving onenote destinations, ignoring: ", cEx);
|
LOG.Warn("Problem retrieving onenote destinations, ignoring: ", cEx);
|
||||||
}
|
}
|
||||||
catch (Exception ex)
|
catch (Exception ex)
|
||||||
{
|
{
|
||||||
LOG.Warn("Problem retrieving onenote destinations, ignoring: ", ex);
|
LOG.Warn("Problem retrieving onenote destinations, ignoring: ", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
pages.Sort((page1, page2) =>
|
pages.Sort((page1, page2) =>
|
||||||
{
|
{
|
||||||
if (page1.IsCurrentlyViewed || page2.IsCurrentlyViewed)
|
if (page1.IsCurrentlyViewed || page2.IsCurrentlyViewed)
|
||||||
{
|
{
|
||||||
return page2.IsCurrentlyViewed.CompareTo(page1.IsCurrentlyViewed);
|
return page2.IsCurrentlyViewed.CompareTo(page1.IsCurrentlyViewed);
|
||||||
}
|
}
|
||||||
|
|
||||||
return string.Compare(page1.DisplayName, page2.DisplayName, StringComparison.Ordinal);
|
return string.Compare(page1.DisplayName, page2.DisplayName, StringComparison.Ordinal);
|
||||||
});
|
});
|
||||||
return pages;
|
return pages;
|
||||||
|
@ -264,6 +277,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReSharper disable once RedundantAssignment
|
// ReSharper disable once RedundantAssignment
|
||||||
string unfiledNotesPath = "";
|
string unfiledNotesPath = "";
|
||||||
oneNoteApplication.ComObject.GetSpecialLocation(specialLocation, out unfiledNotesPath);
|
oneNoteApplication.ComObject.GetSpecialLocation(specialLocation, out unfiledNotesPath);
|
||||||
|
@ -285,6 +299,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string id = xmlReader.GetAttribute("ID");
|
string id = xmlReader.GetAttribute("ID");
|
||||||
string path = xmlReader.GetAttribute("path");
|
string path = xmlReader.GetAttribute("path");
|
||||||
if (unfiledNotesPath.Equals(path))
|
if (unfiledNotesPath.Equals(path))
|
||||||
|
@ -301,6 +316,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -47,7 +47,9 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
private const string ProfilesKey = @"Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\";
|
private const string ProfilesKey = @"Software\Microsoft\Windows NT\CurrentVersion\Windows Messaging Subsystem\Profiles\";
|
||||||
private const string AccountKey = "9375CFF0413111d3B88A00104B2A6676";
|
private const string AccountKey = "9375CFF0413111d3B88A00104B2A6676";
|
||||||
private const string NewSignatureValue = "New Signature";
|
private const string NewSignatureValue = "New Signature";
|
||||||
|
|
||||||
private const string DefaultProfileValue = "DefaultProfile";
|
private const string DefaultProfileValue = "DefaultProfile";
|
||||||
|
|
||||||
// Schema definitions for the MAPI properties, see: http://msdn.microsoft.com/en-us/library/aa454438.aspx and: http://msdn.microsoft.com/en-us/library/bb446117.aspx
|
// Schema definitions for the MAPI properties, see: http://msdn.microsoft.com/en-us/library/aa454438.aspx and: http://msdn.microsoft.com/en-us/library/bb446117.aspx
|
||||||
private const string AttachmentContentId = @"http://schemas.microsoft.com/mapi/proptag/0x3712001E";
|
private const string AttachmentContentId = @"http://schemas.microsoft.com/mapi/proptag/0x3712001E";
|
||||||
|
|
||||||
|
@ -90,6 +92,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return ExportToInspector(null, activeExplorer, mailItem.Class, mailItem, tmpFile, attachmentName);
|
return ExportToInspector(null, activeExplorer, mailItem.Class, mailItem, tmpFile, attachmentName);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case AppointmentItem appointmentItem:
|
case AppointmentItem appointmentItem:
|
||||||
if ((_outlookVersion.Major >= (int) OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
|
if ((_outlookVersion.Major >= (int) OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
|
||||||
|
@ -99,6 +102,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
return ExportToInspector(null, activeExplorer, appointmentItem.Class, null, tmpFile, attachmentName);
|
return ExportToInspector(null, activeExplorer, appointmentItem.Class, null, tmpFile, attachmentName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -110,6 +114,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.DebugFormat("Got {0} inspectors to check", inspectors.ComObject.Count);
|
LOG.DebugFormat("Got {0} inspectors to check", inspectors.ComObject.Count);
|
||||||
for (int i = 1; i <= inspectors.ComObject.Count; i++)
|
for (int i = 1; i <= inspectors.ComObject.Count; i++)
|
||||||
{
|
{
|
||||||
|
@ -130,6 +135,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ExportToInspector(inspector, null, mailItem.Class, mailItem, tmpFile, attachmentName);
|
return ExportToInspector(inspector, null, mailItem.Class, mailItem, tmpFile, attachmentName);
|
||||||
|
@ -138,6 +144,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Error($"Export to {currentCaption} failed.", exExport);
|
LOG.Error($"Export to {currentCaption} failed.", exExport);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case AppointmentItem appointmentItem:
|
case AppointmentItem appointmentItem:
|
||||||
if ((_outlookVersion.Major >= (int) OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
|
if ((_outlookVersion.Major >= (int) OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
|
||||||
|
@ -153,6 +160,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// skip, can't export to olAppointment
|
// skip, can't export to olAppointment
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
return ExportToInspector(inspector, null, appointmentItem.Class, null, tmpFile, attachmentName);
|
return ExportToInspector(inspector, null, appointmentItem.Class, null, tmpFile, attachmentName);
|
||||||
|
@ -161,6 +169,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Error($"Export to {currentCaption} failed.", exExport);
|
LOG.Error($"Export to {currentCaption} failed.", exExport);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
continue;
|
continue;
|
||||||
|
@ -168,6 +177,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +191,8 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
/// <param name="explorer"></param>
|
/// <param name="explorer"></param>
|
||||||
/// <param name="itemClass"></param>
|
/// <param name="itemClass"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private bool ExportToInspector(IDisposableCom<_Inspector> inspector, IDisposableCom<_Explorer> explorer, OlObjectClass itemClass, MailItem mailItem, string tmpFile, string attachmentName)
|
private bool ExportToInspector(IDisposableCom<_Inspector> inspector, IDisposableCom<_Explorer> explorer, OlObjectClass itemClass, MailItem mailItem, string tmpFile,
|
||||||
|
string attachmentName)
|
||||||
{
|
{
|
||||||
bool isMail = OlObjectClass.olMail.Equals(itemClass);
|
bool isMail = OlObjectClass.olMail.Equals(itemClass);
|
||||||
bool isAppointment = OlObjectClass.olAppointment.Equals(itemClass);
|
bool isAppointment = OlObjectClass.olAppointment.Equals(itemClass);
|
||||||
|
@ -190,6 +201,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
LOG.Warn("Item is no mail or appointment.");
|
LOG.Warn("Item is no mail or appointment.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// Make sure the inspector is activated, only this way the word editor is active!
|
// Make sure the inspector is activated, only this way the word editor is active!
|
||||||
|
@ -200,6 +212,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
isTextFormat = OlBodyFormat.olFormatPlain.Equals(mailItem.BodyFormat);
|
isTextFormat = OlBodyFormat.olFormatPlain.Equals(mailItem.BodyFormat);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isAppointment || !isTextFormat)
|
if (isAppointment || !isTextFormat)
|
||||||
{
|
{
|
||||||
// Check for wordmail, if so use the wordexporter
|
// Check for wordmail, if so use the wordexporter
|
||||||
|
@ -219,6 +232,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
wordDocument = DisposableCom.Create(tmpWordDocument);
|
wordDocument = DisposableCom.Create(tmpWordDocument);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wordDocument != null)
|
if (wordDocument != null)
|
||||||
{
|
{
|
||||||
using (wordDocument)
|
using (wordDocument)
|
||||||
|
@ -248,6 +262,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
LOG.Info("Trying export for outlook < 2007.");
|
LOG.Info("Trying export for outlook < 2007.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Only use mailitem as it should be filled!!
|
// Only use mailitem as it should be filled!!
|
||||||
if (mailItem != null)
|
if (mailItem != null)
|
||||||
{
|
{
|
||||||
|
@ -341,9 +356,11 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
caption = explorer.ComObject.Caption;
|
caption = explorer.ComObject.Caption;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.Warn($"Problem while trying to add attachment to Item '{caption}'", ex);
|
LOG.Warn($"Problem while trying to add attachment to Item '{caption}'", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
if (inspector != null)
|
if (inspector != null)
|
||||||
|
@ -360,6 +377,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
LOG.Warn("Problem activating inspector/explorer: ", ex);
|
LOG.Warn("Problem activating inspector/explorer: ", ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.Debug("Finished!");
|
LOG.Debug("Finished!");
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -376,27 +394,32 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
/// <param name="cc"></param>
|
/// <param name="cc"></param>
|
||||||
/// <param name="bcc"></param>
|
/// <param name="bcc"></param>
|
||||||
/// <param name="url"></param>
|
/// <param name="url"></param>
|
||||||
private void ExportToNewEmail(IDisposableCom<Application> outlookApplication, EmailFormat format, string tmpFile, string subject, string attachmentName, string to, string cc, string bcc, string url)
|
private void ExportToNewEmail(IDisposableCom<Application> outlookApplication, EmailFormat format, string tmpFile, string subject, string attachmentName, string to,
|
||||||
|
string cc, string bcc, string url)
|
||||||
{
|
{
|
||||||
using var newItem = DisposableCom.Create((MailItem) outlookApplication.ComObject.CreateItem(OlItemType.olMailItem));
|
using var newItem = DisposableCom.Create((MailItem) outlookApplication.ComObject.CreateItem(OlItemType.olMailItem));
|
||||||
if (newItem == null)
|
if (newItem == null)
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var newMail = newItem.ComObject;
|
var newMail = newItem.ComObject;
|
||||||
newMail.Subject = subject;
|
newMail.Subject = subject;
|
||||||
if (!string.IsNullOrEmpty(to))
|
if (!string.IsNullOrEmpty(to))
|
||||||
{
|
{
|
||||||
newMail.To = to;
|
newMail.To = to;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(cc))
|
if (!string.IsNullOrEmpty(cc))
|
||||||
{
|
{
|
||||||
newMail.CC = cc;
|
newMail.CC = cc;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(bcc))
|
if (!string.IsNullOrEmpty(bcc))
|
||||||
{
|
{
|
||||||
newMail.BCC = bcc;
|
newMail.BCC = bcc;
|
||||||
}
|
}
|
||||||
|
|
||||||
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
|
newMail.BodyFormat = OlBodyFormat.olFormatHTML;
|
||||||
string bodyString = null;
|
string bodyString = null;
|
||||||
// Read the default signature, if nothing found use empty email
|
// Read the default signature, if nothing found use empty email
|
||||||
|
@ -408,6 +431,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Error("Problem reading signature!", e);
|
LOG.Error("Problem reading signature!", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (format)
|
switch (format)
|
||||||
{
|
{
|
||||||
case EmailFormat.Text:
|
case EmailFormat.Text:
|
||||||
|
@ -421,9 +445,11 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
bodyString = "";
|
bodyString = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
newMail.Body = bodyString;
|
newMail.Body = bodyString;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
string contentId = Path.GetFileName(tmpFile);
|
string contentId = Path.GetFileName(tmpFile);
|
||||||
|
@ -456,6 +482,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
href = $"<A HREF=\"{url}\">";
|
href = $"<A HREF=\"{url}\">";
|
||||||
hrefEnd = "</A>";
|
hrefEnd = "</A>";
|
||||||
}
|
}
|
||||||
|
|
||||||
string htmlImgEmbedded = $"<BR/>{href}<IMG border=0 hspace=0 alt=\"{attachmentName}\" align=baseline src=\"cid:{contentId}\">{hrefEnd}<BR/>";
|
string htmlImgEmbedded = $"<BR/>{href}<IMG border=0 hspace=0 alt=\"{attachmentName}\" align=baseline src=\"cid:{contentId}\">{hrefEnd}<BR/>";
|
||||||
string fallbackBody = $"<HTML><BODY>{htmlImgEmbedded}</BODY></HTML>";
|
string fallbackBody = $"<HTML><BODY>{htmlImgEmbedded}</BODY></HTML>";
|
||||||
if (bodyString == null)
|
if (bodyString == null)
|
||||||
|
@ -482,9 +509,11 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
bodyString = fallbackBody;
|
bodyString = fallbackBody;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
newMail.HTMLBody = bodyString;
|
newMail.HTMLBody = bodyString;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
// So not save, otherwise the email is always stored in Draft folder.. (newMail.Save();)
|
// So not save, otherwise the email is always stored in Draft folder.. (newMail.Save();)
|
||||||
newMail.Display(false);
|
newMail.Display(false);
|
||||||
|
|
||||||
|
@ -528,12 +557,14 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
exported = true;
|
exported = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return exported;
|
return exported;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
LOG.Error("Error while creating an outlook mail item: ", e);
|
LOG.Error("Error while creating an outlook mail item: ", e);
|
||||||
}
|
}
|
||||||
|
|
||||||
return exported;
|
return exported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -548,6 +579,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
outlookApplication = DisposableCom.Create(new Application());
|
outlookApplication = DisposableCom.Create(new Application());
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVariables(outlookApplication);
|
InitializeVariables(outlookApplication);
|
||||||
return outlookApplication;
|
return outlookApplication;
|
||||||
}
|
}
|
||||||
|
@ -568,10 +600,12 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// Ignore, probably no outlook running
|
// Ignore, probably no outlook running
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((outlookApplication != null) && (outlookApplication.ComObject != null))
|
if ((outlookApplication != null) && (outlookApplication.ComObject != null))
|
||||||
{
|
{
|
||||||
InitializeVariables(outlookApplication);
|
InitializeVariables(outlookApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
return outlookApplication;
|
return outlookApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -587,6 +621,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
string defaultProfile = (string) profilesKey.GetValue(DefaultProfileValue);
|
string defaultProfile = (string) profilesKey.GetValue(DefaultProfileValue);
|
||||||
LOG.DebugFormat("defaultProfile={0}", defaultProfile);
|
LOG.DebugFormat("defaultProfile={0}", defaultProfile);
|
||||||
using var profileKey = profilesKey.OpenSubKey(defaultProfile + @"\" + AccountKey, false);
|
using var profileKey = profilesKey.OpenSubKey(defaultProfile + @"\" + AccountKey, false);
|
||||||
|
@ -604,6 +639,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
string signatureName = "";
|
string signatureName = "";
|
||||||
foreach (byte b in val)
|
foreach (byte b in val)
|
||||||
{
|
{
|
||||||
|
@ -612,6 +648,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
signatureName += (char) b;
|
signatureName += (char) b;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.DebugFormat("Found email signature: {0}", signatureName);
|
LOG.DebugFormat("Found email signature: {0}", signatureName);
|
||||||
var extension = format switch
|
var extension = format switch
|
||||||
{
|
{
|
||||||
|
@ -628,6 +665,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -642,11 +680,13 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Version.TryParse(outlookApplication.ComObject.Version, out _outlookVersion))
|
if (!Version.TryParse(outlookApplication.ComObject.Version, out _outlookVersion))
|
||||||
{
|
{
|
||||||
LOG.Warn("Assuming outlook version 1997.");
|
LOG.Warn("Assuming outlook version 1997.");
|
||||||
_outlookVersion = new Version((int) OfficeVersions.Office97, 0, 0, 0);
|
_outlookVersion = new Version((int) OfficeVersions.Office97, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Preventing retrieval of currentUser if Outlook is older than 2007
|
// Preventing retrieval of currentUser if Outlook is older than 2007
|
||||||
if (_outlookVersion.Major >= (int) OfficeVersions.Office2007)
|
if (_outlookVersion.Major >= (int) OfficeVersions.Office2007)
|
||||||
{
|
{
|
||||||
|
@ -657,6 +697,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
using var currentUser = DisposableCom.Create(mapiNamespace.ComObject.CurrentUser);
|
using var currentUser = DisposableCom.Create(mapiNamespace.ComObject.CurrentUser);
|
||||||
_currentUser = currentUser.ComObject.Name;
|
_currentUser = currentUser.ComObject.Name;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG.InfoFormat("Current user: {0}", _currentUser);
|
LOG.InfoFormat("Current user: {0}", _currentUser);
|
||||||
}
|
}
|
||||||
catch (Exception exNs)
|
catch (Exception exNs)
|
||||||
|
@ -701,6 +742,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
inspectorCaptions.Add(caption, mailItem.Class);
|
inspectorCaptions.Add(caption, mailItem.Class);
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case AppointmentItem appointmentItem:
|
case AppointmentItem appointmentItem:
|
||||||
if ((_outlookVersion.Major >= (int) OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
|
if ((_outlookVersion.Major >= (int) OfficeVersions.Office2010) && _officeConfiguration.OutlookAllowExportInMeetings)
|
||||||
|
@ -710,6 +752,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
inspectorCaptions.Add(caption, appointmentItem.Class);
|
inspectorCaptions.Add(caption, appointmentItem.Class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -740,6 +783,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
inspectorCaptions.Add(caption, mailItem.Class);
|
inspectorCaptions.Add(caption, mailItem.Class);
|
||||||
break;
|
break;
|
||||||
case AppointmentItem appointmentItem:
|
case AppointmentItem appointmentItem:
|
||||||
|
@ -756,6 +800,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// skip, can't export to olAppointment
|
// skip, can't export to olAppointment
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
inspectorCaptions.Add(caption, appointmentItem.Class);
|
inspectorCaptions.Add(caption, appointmentItem.Class);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -769,6 +814,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Warn("Problem retrieving word destinations, ignoring: ", ex);
|
LOG.Warn("Problem retrieving word destinations, ignoring: ", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return inspectorCaptions;
|
return inspectorCaptions;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -60,6 +60,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
left = pageSetup.ComObject.SlideWidth / 2 - imageSize.Width / 2f;
|
left = pageSetup.ComObject.SlideWidth / 2 - imageSize.Width / 2f;
|
||||||
top = pageSetup.ComObject.SlideHeight / 2 - imageSize.Height / 2f;
|
top = pageSetup.ComObject.SlideHeight / 2 - imageSize.Height / 2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
float width = imageSize.Width;
|
float width = imageSize.Width;
|
||||||
float height = imageSize.Height;
|
float height = imageSize.Height;
|
||||||
IDisposableCom<Shape> shapeForCaption = null;
|
IDisposableCom<Shape> shapeForCaption = null;
|
||||||
|
@ -86,6 +87,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
shapeForLocation.ComObject.Left = left;
|
shapeForLocation.ComObject.Left = left;
|
||||||
}
|
}
|
||||||
|
|
||||||
shapeForLocation.ComObject.Width = imageSize.Width;
|
shapeForLocation.ComObject.Width = imageSize.Width;
|
||||||
|
|
||||||
if (height > shapeForLocation.ComObject.Height)
|
if (height > shapeForLocation.ComObject.Height)
|
||||||
|
@ -98,6 +100,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
top = shapeForLocation.ComObject.Top + shapeForLocation.ComObject.Height / 2 - imageSize.Height / 2f;
|
top = shapeForLocation.ComObject.Top + shapeForLocation.ComObject.Height / 2 - imageSize.Height / 2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
shapeForLocation.ComObject.Height = imageSize.Height;
|
shapeForLocation.ComObject.Height = imageSize.Height;
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
|
@ -106,6 +109,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
using var slides = DisposableCom.Create(presentation.ComObject.Slides);
|
using var slides = DisposableCom.Create(presentation.ComObject.Slides);
|
||||||
slide = DisposableCom.Create(slides.ComObject.Add(slides.ComObject.Count + 1, PpSlideLayout.ppLayoutBlank));
|
slide = DisposableCom.Create(slides.ComObject.Add(slides.ComObject.Count + 1, PpSlideLayout.ppLayoutBlank));
|
||||||
}
|
}
|
||||||
|
|
||||||
using (var shapes = DisposableCom.Create(slide.ComObject.Shapes))
|
using (var shapes = DisposableCom.Create(slide.ComObject.Shapes))
|
||||||
{
|
{
|
||||||
using var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, width, height));
|
using var shape = DisposableCom.Create(shapes.ComObject.AddPicture(tmpFile, MsoTriState.msoFalse, MsoTriState.msoTrue, 0, 0, width, height));
|
||||||
|
@ -117,20 +121,24 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
shape.ComObject.LockAspectRatio = MsoTriState.msoFalse;
|
shape.ComObject.LockAspectRatio = MsoTriState.msoFalse;
|
||||||
}
|
}
|
||||||
|
|
||||||
shape.ComObject.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
|
shape.ComObject.ScaleHeight(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
|
||||||
shape.ComObject.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
|
shape.ComObject.ScaleWidth(1, MsoTriState.msoTrue, MsoScaleFrom.msoScaleFromMiddle);
|
||||||
if (hasScaledWidth)
|
if (hasScaledWidth)
|
||||||
{
|
{
|
||||||
shape.ComObject.Width = width;
|
shape.ComObject.Width = width;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hasScaledHeight)
|
if (hasScaledHeight)
|
||||||
{
|
{
|
||||||
shape.ComObject.Height = height;
|
shape.ComObject.Height = height;
|
||||||
}
|
}
|
||||||
|
|
||||||
shape.ComObject.Left = left;
|
shape.ComObject.Left = left;
|
||||||
shape.ComObject.Top = top;
|
shape.ComObject.Top = top;
|
||||||
shape.ComObject.AlternativeText = title;
|
shape.ComObject.AlternativeText = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (shapeForCaption != null)
|
if (shapeForCaption != null)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
|
@ -148,6 +156,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
LOG.Warn("Problem setting the title to a text-range", ex);
|
LOG.Warn("Problem setting the title to a text-range", ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Activate/Goto the slide
|
// Activate/Goto the slide
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -194,10 +203,12 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!presentation.ComObject.Name.StartsWith(presentationName))
|
if (!presentation.ComObject.Name.StartsWith(presentationName))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
AddPictureToPresentation(presentation, tmpFile, imageSize, title);
|
AddPictureToPresentation(presentation, tmpFile, imageSize, title);
|
||||||
|
@ -209,6 +220,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -223,6 +235,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
powerPointApplication = DisposableCom.Create(new Application());
|
powerPointApplication = DisposableCom.Create(new Application());
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVariables(powerPointApplication);
|
InitializeVariables(powerPointApplication);
|
||||||
return powerPointApplication;
|
return powerPointApplication;
|
||||||
}
|
}
|
||||||
|
@ -243,10 +256,12 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// Ignore, probably no PowerPoint running
|
// Ignore, probably no PowerPoint running
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (powerPointApplication?.ComObject != null)
|
if (powerPointApplication?.ComObject != null)
|
||||||
{
|
{
|
||||||
InitializeVariables(powerPointApplication);
|
InitializeVariables(powerPointApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
return powerPointApplication;
|
return powerPointApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,10 +286,12 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (presentation.ComObject.ReadOnly == MsoTriState.msoTrue)
|
if (presentation.ComObject.ReadOnly == MsoTriState.msoTrue)
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAfter2003())
|
if (IsAfter2003())
|
||||||
{
|
{
|
||||||
if (presentation.ComObject.Final)
|
if (presentation.ComObject.Final)
|
||||||
|
@ -282,6 +299,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yield return presentation.ComObject.Name;
|
yield return presentation.ComObject.Name;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -296,6 +314,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Version.TryParse(powerpointApplication.ComObject.Version, out _powerpointVersion))
|
if (!Version.TryParse(powerpointApplication.ComObject.Version, out _powerpointVersion))
|
||||||
{
|
{
|
||||||
LOG.Warn("Assuming Powerpoint version 1997.");
|
LOG.Warn("Assuming Powerpoint version 1997.");
|
||||||
|
@ -332,6 +351,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return isPictureAdded;
|
return isPictureAdded;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -340,5 +360,4 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
return _powerpointVersion.Major > (int) OfficeVersions.Office2003;
|
return _powerpointVersion.Major > (int) OfficeVersions.Office2003;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
|
@ -53,6 +53,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
|
shape.ComObject.LockAspectRatio = MsoTriState.msoTrue;
|
||||||
}
|
}
|
||||||
|
|
||||||
selection.ComObject.InsertAfter("\r\n");
|
selection.ComObject.InsertAfter("\r\n");
|
||||||
selection.ComObject.MoveDown(WdUnits.wdLine, 1, Type.Missing);
|
selection.ComObject.MoveDown(WdUnits.wdLine, 1, Type.Missing);
|
||||||
return shape;
|
return shape;
|
||||||
|
@ -69,6 +70,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
wordApplication = DisposableCom.Create(new Application());
|
wordApplication = DisposableCom.Create(new Application());
|
||||||
}
|
}
|
||||||
|
|
||||||
InitializeVariables(wordApplication);
|
InitializeVariables(wordApplication);
|
||||||
return wordApplication;
|
return wordApplication;
|
||||||
}
|
}
|
||||||
|
@ -89,10 +91,12 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
// Ignore, probably no word running
|
// Ignore, probably no word running
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((wordApplication != null) && (wordApplication.ComObject != null))
|
if ((wordApplication != null) && (wordApplication.ComObject != null))
|
||||||
{
|
{
|
||||||
InitializeVariables(wordApplication);
|
InitializeVariables(wordApplication);
|
||||||
}
|
}
|
||||||
|
|
||||||
return wordApplication;
|
return wordApplication;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -116,6 +120,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (IsAfter2003())
|
if (IsAfter2003())
|
||||||
{
|
{
|
||||||
if (document.ComObject.Final)
|
if (document.ComObject.Final)
|
||||||
|
@ -139,6 +144,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!Version.TryParse(wordApplication.ComObject.Version, out _wordVersion))
|
if (!Version.TryParse(wordApplication.ComObject.Version, out _wordVersion))
|
||||||
{
|
{
|
||||||
LOG.Warn("Assuming Word version 1997.");
|
LOG.Warn("Assuming Word version 1997.");
|
||||||
|
@ -172,6 +178,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -184,7 +191,8 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
/// <param name="address">string</param>
|
/// <param name="address">string</param>
|
||||||
/// <param name="tooltip">string with the tooltip of the image</param>
|
/// <param name="tooltip">string with the tooltip of the image</param>
|
||||||
/// <returns>bool</returns>
|
/// <returns>bool</returns>
|
||||||
internal bool InsertIntoExistingDocument(IDisposableCom<Application> wordApplication, IDisposableCom<_Document> wordDocument, string tmpFile, string address, string tooltip)
|
internal bool InsertIntoExistingDocument(IDisposableCom<Application> wordApplication, IDisposableCom<_Document> wordDocument, string tmpFile, string address,
|
||||||
|
string tooltip)
|
||||||
{
|
{
|
||||||
// Bug #1517: image will be inserted into that document, where the focus was last. It will not inserted into the chosen one.
|
// Bug #1517: image will be inserted into that document, where the focus was last. It will not inserted into the chosen one.
|
||||||
// Solution: Make sure the selected document is active, otherwise the insert will be made in a different document!
|
// Solution: Make sure the selected document is active, otherwise the insert will be made in a different document!
|
||||||
|
@ -204,6 +212,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
LOG.InfoFormat("No selection to insert {0} into found.", tmpFile);
|
LOG.InfoFormat("No selection to insert {0} into found.", tmpFile);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add Picture
|
// Add Picture
|
||||||
using (var shape = AddPictureToSelection(selection, tmpFile))
|
using (var shape = AddPictureToSelection(selection, tmpFile))
|
||||||
{
|
{
|
||||||
|
@ -214,6 +223,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
screentip = tooltip;
|
screentip = tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks);
|
using var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks);
|
||||||
|
@ -225,6 +235,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
// When called for Outlook, the follow error is created: This object model command is not available in e-mail
|
// When called for Outlook, the follow error is created: This object model command is not available in e-mail
|
||||||
|
@ -245,6 +256,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
LOG.WarnFormat("Couldn't set zoom to 100, error: {0}", e.Message);
|
LOG.WarnFormat("Couldn't set zoom to 100, error: {0}", e.Message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wordApplication.ComObject.Activate();
|
wordApplication.ComObject.Activate();
|
||||||
|
@ -254,6 +266,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Warn("Error activating word application", ex);
|
LOG.Warn("Error activating word application", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wordDocument.ComObject.Activate();
|
wordDocument.ComObject.Activate();
|
||||||
|
@ -263,6 +276,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Warn("Error activating word document", ex);
|
LOG.Warn("Error activating word document", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -279,6 +293,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
wordApplication.ComObject.Visible = true;
|
wordApplication.ComObject.Visible = true;
|
||||||
wordApplication.ComObject.Activate();
|
wordApplication.ComObject.Activate();
|
||||||
// Create new Document
|
// Create new Document
|
||||||
|
@ -299,6 +314,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
screentip = tooltip;
|
screentip = tooltip;
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks);
|
using var hyperlinks = DisposableCom.Create(wordDocument.ComObject.Hyperlinks);
|
||||||
|
@ -313,6 +329,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
wordDocument.ComObject.Activate();
|
wordDocument.ComObject.Activate();
|
||||||
|
@ -322,6 +339,7 @@ namespace Greenshot.Plugin.Office.OfficeExport
|
||||||
{
|
{
|
||||||
LOG.Warn("Error activating word document", ex);
|
LOG.Warn("Error activating word document", ex);
|
||||||
}
|
}
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
using var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow);
|
using var activeWindow = DisposableCom.Create(wordDocument.ComObject.ActiveWindow);
|
||||||
|
|
|
@ -28,6 +28,7 @@ namespace Greenshot.Plugin.Office.OfficeInterop
|
||||||
/// Use the plain text format
|
/// Use the plain text format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Text,
|
Text,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Use HTML format
|
/// Use HTML format
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -28,26 +28,32 @@ namespace Greenshot.Plugin.Office.OfficeInterop
|
||||||
/// Office 97
|
/// Office 97
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Office97 = 8,
|
Office97 = 8,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Office 2003
|
/// Office 2003
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Office2003 = 11,
|
Office2003 = 11,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Office 2007
|
/// Office 2007
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Office2007 = 12,
|
Office2007 = 12,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Office 2010
|
/// Office 2010
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Office2010 = 14,
|
Office2010 = 14,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Office 2013
|
/// Office 2013
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Office2013 = 15,
|
Office2013 = 15,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Office 2016
|
/// Office 2016
|
||||||
/// </summary>
|
/// </summary>
|
||||||
Office2016 = 16,
|
Office2016 = 16,
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Office 2019
|
/// Office 2019
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|
|
@ -26,7 +26,8 @@ using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
using GreenshotPlugin.Interfaces.Plugin;
|
using GreenshotPlugin.Interfaces.Plugin;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Office {
|
namespace Greenshot.Plugin.Office
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This is the OfficePlugin base code
|
/// This is the OfficePlugin base code
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -35,59 +36,87 @@ namespace Greenshot.Plugin.Office {
|
||||||
{
|
{
|
||||||
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OfficePlugin));
|
private static readonly log4net.ILog LOG = log4net.LogManager.GetLogger(typeof(OfficePlugin));
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
|
{
|
||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void Dispose(bool disposing) {
|
protected void Dispose(bool disposing)
|
||||||
|
{
|
||||||
// Do nothing
|
// Do nothing
|
||||||
}
|
}
|
||||||
|
|
||||||
private IEnumerable<IDestination> Destinations() {
|
private IEnumerable<IDestination> Destinations()
|
||||||
|
{
|
||||||
IDestination destination;
|
IDestination destination;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
destination = new ExcelDestination();
|
destination = new ExcelDestination();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
destination = null;
|
destination = null;
|
||||||
}
|
}
|
||||||
if (destination != null) {
|
|
||||||
|
if (destination != null)
|
||||||
|
{
|
||||||
yield return destination;
|
yield return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
destination = new PowerpointDestination();
|
destination = new PowerpointDestination();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
destination = null;
|
destination = null;
|
||||||
}
|
}
|
||||||
if (destination != null) {
|
|
||||||
|
if (destination != null)
|
||||||
|
{
|
||||||
yield return destination;
|
yield return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
destination = new WordDestination();
|
destination = new WordDestination();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
destination = null;
|
destination = null;
|
||||||
}
|
}
|
||||||
if (destination != null) {
|
|
||||||
|
if (destination != null)
|
||||||
|
{
|
||||||
yield return destination;
|
yield return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
destination = new OutlookDestination();
|
destination = new OutlookDestination();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
destination = null;
|
destination = null;
|
||||||
}
|
}
|
||||||
if (destination != null) {
|
|
||||||
|
if (destination != null)
|
||||||
|
{
|
||||||
yield return destination;
|
yield return destination;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
destination = new OneNoteDestination();
|
destination = new OneNoteDestination();
|
||||||
} catch {
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
destination = null;
|
destination = null;
|
||||||
}
|
}
|
||||||
if (destination != null) {
|
|
||||||
|
if (destination != null)
|
||||||
|
{
|
||||||
yield return destination;
|
yield return destination;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -97,19 +126,22 @@ namespace Greenshot.Plugin.Office {
|
||||||
/// Implementation of the IGreenshotPlugin.Initialize
|
/// Implementation of the IGreenshotPlugin.Initialize
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
/// <returns>true if plugin is initialized, false if not (doesn't show)</returns>
|
||||||
public bool Initialize() {
|
public bool Initialize()
|
||||||
|
{
|
||||||
SimpleServiceProvider.Current.AddService(Destinations());
|
SimpleServiceProvider.Current.AddService(Destinations());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Shutdown() {
|
public void Shutdown()
|
||||||
|
{
|
||||||
LOG.Debug("Office Plugin shutdown.");
|
LOG.Debug("Office Plugin shutdown.");
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Implementation of the IPlugin.Configure
|
/// Implementation of the IPlugin.Configure
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public void Configure() {
|
public void Configure()
|
||||||
|
{
|
||||||
throw new NotImplementedException();
|
throw new NotImplementedException();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,10 +19,12 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Photobucket.Forms {
|
namespace Greenshot.Plugin.Photobucket.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// This class is needed for design-time resolving of the language files
|
/// This class is needed for design-time resolving of the language files
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PhotobucketForm : GreenshotPlugin.Controls.GreenshotForm {
|
public class PhotobucketForm : GreenshotPlugin.Controls.GreenshotForm
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -19,11 +19,13 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Photobucket.Forms {
|
namespace Greenshot.Plugin.Photobucket.Forms
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PasswordRequestForm.
|
/// Description of PasswordRequestForm.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class SettingsForm : PhotobucketForm {
|
public partial class SettingsForm : PhotobucketForm
|
||||||
|
{
|
||||||
public SettingsForm()
|
public SettingsForm()
|
||||||
{
|
{
|
||||||
//
|
//
|
||||||
|
|
|
@ -19,8 +19,10 @@
|
||||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Photobucket {
|
namespace Greenshot.Plugin.Photobucket
|
||||||
public enum LangKey {
|
{
|
||||||
|
public enum LangKey
|
||||||
|
{
|
||||||
upload_menu_item,
|
upload_menu_item,
|
||||||
upload_failure,
|
upload_failure,
|
||||||
communication_wait,
|
communication_wait,
|
||||||
|
|
|
@ -25,26 +25,35 @@ using GreenshotPlugin.Controls;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.IniFile;
|
using GreenshotPlugin.IniFile;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Photobucket {
|
namespace Greenshot.Plugin.Photobucket
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PhotobucketConfiguration.
|
/// Description of PhotobucketConfiguration.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
[IniSection("Photobucket", Description = "Greenshot Photobucket Plugin configuration")]
|
[IniSection("Photobucket", Description = "Greenshot Photobucket Plugin configuration")]
|
||||||
public class PhotobucketConfiguration : IniSection {
|
public class PhotobucketConfiguration : IniSection
|
||||||
|
{
|
||||||
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
[IniProperty("UploadFormat", Description = "What file type to use for uploading", DefaultValue = "png")]
|
||||||
public OutputFormat UploadFormat { get; set; }
|
public OutputFormat UploadFormat { get; set; }
|
||||||
|
|
||||||
[IniProperty("UploadJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
|
[IniProperty("UploadJpegQuality", Description = "JPEG file save quality in %.", DefaultValue = "80")]
|
||||||
public int UploadJpegQuality { get; set; }
|
public int UploadJpegQuality { get; set; }
|
||||||
|
|
||||||
[IniProperty("UploadReduceColors", Description = "Reduce color amount of the uploaded image to 256", DefaultValue = "False")]
|
[IniProperty("UploadReduceColors", Description = "Reduce color amount of the uploaded image to 256", DefaultValue = "False")]
|
||||||
public bool UploadReduceColors { get; set; }
|
public bool UploadReduceColors { get; set; }
|
||||||
|
|
||||||
[IniProperty("UsePageLink", Description = "Use pagelink instead of direct link on the clipboard", DefaultValue = "False")]
|
[IniProperty("UsePageLink", Description = "Use pagelink instead of direct link on the clipboard", DefaultValue = "False")]
|
||||||
public bool UsePageLink { get; set; }
|
public bool UsePageLink { get; set; }
|
||||||
|
|
||||||
[IniProperty("Token", Description = "The Photobucket token", Encrypted = true, ExcludeIfNull = true)]
|
[IniProperty("Token", Description = "The Photobucket token", Encrypted = true, ExcludeIfNull = true)]
|
||||||
public string Token { get; set; }
|
public string Token { get; set; }
|
||||||
|
|
||||||
[IniProperty("TokenSecret", Description = "The Photobucket token secret", Encrypted = true, ExcludeIfNull = true)]
|
[IniProperty("TokenSecret", Description = "The Photobucket token secret", Encrypted = true, ExcludeIfNull = true)]
|
||||||
public string TokenSecret { get; set; }
|
public string TokenSecret { get; set; }
|
||||||
|
|
||||||
[IniProperty("SubDomain", Description = "The Photobucket api subdomain", Encrypted = true, ExcludeIfNull = true)]
|
[IniProperty("SubDomain", Description = "The Photobucket api subdomain", Encrypted = true, ExcludeIfNull = true)]
|
||||||
public string SubDomain { get; set; }
|
public string SubDomain { get; set; }
|
||||||
|
|
||||||
[IniProperty("Username", Description = "The Photobucket api username", ExcludeIfNull = true)]
|
[IniProperty("Username", Description = "The Photobucket api username", ExcludeIfNull = true)]
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
|
@ -52,18 +61,19 @@ namespace Greenshot.Plugin.Photobucket {
|
||||||
/// A form for username/password
|
/// A form for username/password
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
/// <returns>bool true if OK was pressed, false if cancel</returns>
|
||||||
public bool ShowConfigDialog() {
|
public bool ShowConfigDialog()
|
||||||
|
{
|
||||||
SettingsForm settingsForm = null;
|
SettingsForm settingsForm = null;
|
||||||
|
|
||||||
new PleaseWaitForm().ShowAndWait("Photobucket", Language.GetString("photobucket", LangKey.communication_wait),
|
new PleaseWaitForm().ShowAndWait("Photobucket", Language.GetString("photobucket", LangKey.communication_wait),
|
||||||
delegate {
|
delegate { settingsForm = new SettingsForm(); }
|
||||||
settingsForm = new SettingsForm();
|
|
||||||
}
|
|
||||||
);
|
);
|
||||||
DialogResult result = settingsForm.ShowDialog();
|
DialogResult result = settingsForm.ShowDialog();
|
||||||
if (result == DialogResult.OK) {
|
if (result == DialogResult.OK)
|
||||||
|
{
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,11 +25,13 @@ using System.Drawing;
|
||||||
using GreenshotPlugin.Core;
|
using GreenshotPlugin.Core;
|
||||||
using GreenshotPlugin.Interfaces;
|
using GreenshotPlugin.Interfaces;
|
||||||
|
|
||||||
namespace Greenshot.Plugin.Photobucket {
|
namespace Greenshot.Plugin.Photobucket
|
||||||
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PhotobucketDestination.
|
/// Description of PhotobucketDestination.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PhotobucketDestination : AbstractDestination {
|
public class PhotobucketDestination : AbstractDestination
|
||||||
|
{
|
||||||
private readonly PhotobucketPlugin _plugin;
|
private readonly PhotobucketPlugin _plugin;
|
||||||
private readonly string _albumPath;
|
private readonly string _albumPath;
|
||||||
|
|
||||||
|
@ -38,24 +40,31 @@ namespace Greenshot.Plugin.Photobucket {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="plugin"></param>
|
/// <param name="plugin"></param>
|
||||||
/// <param name="albumPath">path to the album, null for default</param>
|
/// <param name="albumPath">path to the album, null for default</param>
|
||||||
public PhotobucketDestination(PhotobucketPlugin plugin, string albumPath = null) {
|
public PhotobucketDestination(PhotobucketPlugin plugin, string albumPath = null)
|
||||||
|
{
|
||||||
_plugin = plugin;
|
_plugin = plugin;
|
||||||
_albumPath = albumPath;
|
_albumPath = albumPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Designation => "Photobucket";
|
public override string Designation => "Photobucket";
|
||||||
|
|
||||||
public override string Description {
|
public override string Description
|
||||||
get {
|
{
|
||||||
if (_albumPath != null) {
|
get
|
||||||
|
{
|
||||||
|
if (_albumPath != null)
|
||||||
|
{
|
||||||
return _albumPath;
|
return _albumPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Language.GetString("photobucket", LangKey.upload_menu_item);
|
return Language.GetString("photobucket", LangKey.upload_menu_item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Image DisplayIcon {
|
public override Image DisplayIcon
|
||||||
get {
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
ComponentResourceManager resources = new ComponentResourceManager(typeof(PhotobucketPlugin));
|
ComponentResourceManager resources = new ComponentResourceManager(typeof(PhotobucketPlugin));
|
||||||
return (Image) resources.GetObject("Photobucket");
|
return (Image) resources.GetObject("Photobucket");
|
||||||
}
|
}
|
||||||
|
@ -63,9 +72,11 @@ namespace Greenshot.Plugin.Photobucket {
|
||||||
|
|
||||||
public override bool IsDynamic => true;
|
public override bool IsDynamic => true;
|
||||||
|
|
||||||
public override IEnumerable<IDestination> DynamicDestinations() {
|
public override IEnumerable<IDestination> DynamicDestinations()
|
||||||
|
{
|
||||||
IList<string> albums = null;
|
IList<string> albums = null;
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
albums = PhotobucketUtils.RetrievePhotobucketAlbums();
|
albums = PhotobucketUtils.RetrievePhotobucketAlbums();
|
||||||
}
|
}
|
||||||
catch
|
catch
|
||||||
|
@ -73,10 +84,13 @@ namespace Greenshot.Plugin.Photobucket {
|
||||||
// ignored
|
// ignored
|
||||||
}
|
}
|
||||||
|
|
||||||
if (albums == null || albums.Count == 0) {
|
if (albums == null || albums.Count == 0)
|
||||||
|
{
|
||||||
yield break;
|
yield break;
|
||||||
}
|
}
|
||||||
foreach (string album in albums) {
|
|
||||||
|
foreach (string album in albums)
|
||||||
|
{
|
||||||
yield return new PhotobucketDestination(_plugin, album);
|
yield return new PhotobucketDestination(_plugin, album);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,13 +102,16 @@ namespace Greenshot.Plugin.Photobucket {
|
||||||
/// <param name="surface"></param>
|
/// <param name="surface"></param>
|
||||||
/// <param name="captureDetails"></param>
|
/// <param name="captureDetails"></param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
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);
|
||||||
bool uploaded = _plugin.Upload(captureDetails, surface, _albumPath, out var uploadUrl);
|
bool uploaded = _plugin.Upload(captureDetails, surface, _albumPath, out var uploadUrl);
|
||||||
if (uploaded) {
|
if (uploaded)
|
||||||
|
{
|
||||||
exportInformation.ExportMade = true;
|
exportInformation.ExportMade = true;
|
||||||
exportInformation.Uri = uploadUrl;
|
exportInformation.Uri = uploadUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
ProcessExport(exportInformation, surface);
|
ProcessExport(exportInformation, surface);
|
||||||
return exportInformation;
|
return exportInformation;
|
||||||
}
|
}
|
||||||
|
|
|
@ -27,7 +27,8 @@ namespace Greenshot.Plugin.Photobucket
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Description of PhotobucketInfo.
|
/// Description of PhotobucketInfo.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public class PhotobucketInfo {
|
public class PhotobucketInfo
|
||||||
|
{
|
||||||
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PhotobucketInfo));
|
private static readonly log4net.ILog Log = log4net.LogManager.GetLogger(typeof(PhotobucketInfo));
|
||||||
|
|
||||||
public string Original { get; set; }
|
public string Original { get; set; }
|
||||||
|
@ -41,27 +42,37 @@ namespace Greenshot.Plugin.Photobucket
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="response">XML</param>
|
/// <param name="response">XML</param>
|
||||||
/// <returns>PhotobucketInfo object</returns>
|
/// <returns>PhotobucketInfo object</returns>
|
||||||
public static PhotobucketInfo FromUploadResponse(string response) {
|
public static PhotobucketInfo FromUploadResponse(string response)
|
||||||
|
{
|
||||||
Log.Debug(response);
|
Log.Debug(response);
|
||||||
PhotobucketInfo photobucketInfo = new PhotobucketInfo();
|
PhotobucketInfo photobucketInfo = new PhotobucketInfo();
|
||||||
try {
|
try
|
||||||
|
{
|
||||||
XmlDocument doc = new XmlDocument();
|
XmlDocument doc = new XmlDocument();
|
||||||
doc.LoadXml(response);
|
doc.LoadXml(response);
|
||||||
var nodes = doc.GetElementsByTagName("url");
|
var nodes = doc.GetElementsByTagName("url");
|
||||||
if(nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
photobucketInfo.Original = nodes.Item(0)?.InnerText;
|
photobucketInfo.Original = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("browseurl");
|
nodes = doc.GetElementsByTagName("browseurl");
|
||||||
if(nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
photobucketInfo.Page = nodes.Item(0)?.InnerText;
|
photobucketInfo.Page = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
|
|
||||||
nodes = doc.GetElementsByTagName("thumb");
|
nodes = doc.GetElementsByTagName("thumb");
|
||||||
if(nodes.Count > 0) {
|
if (nodes.Count > 0)
|
||||||
|
{
|
||||||
photobucketInfo.Thumbnail = nodes.Item(0)?.InnerText;
|
photobucketInfo.Thumbnail = nodes.Item(0)?.InnerText;
|
||||||
}
|
}
|
||||||
} catch(Exception e) {
|
}
|
||||||
|
catch (Exception e)
|
||||||
|
{
|
||||||
Log.ErrorFormat("Could not parse Photobucket response due to error {0}, response was: {1}", e.Message, response);
|
Log.ErrorFormat("Could not parse Photobucket response due to error {0}, response was: {1}", e.Message, response);
|
||||||
}
|
}
|
||||||
|
|
||||||
return photobucketInfo;
|
return photobucketInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue