From 9a37708b53baf3724671eba02c3b50c7a63169f7 Mon Sep 17 00:00:00 2001
From: Patrick Simpson
Date: Wed, 12 Apr 2017 10:23:52 +0200
Subject: [PATCH] [KOE-244] Added basic progress feature to ribbon, and
disabled sync feature that just increases progress periodically.
---
.../AcaciaZPushPlugin.csproj | 7 +
.../AcaciaZPushPlugin/Features/Features.cs | 3 +-
.../Features/SyncState/FeatureSyncState.cs | 165 ++++++++++++++++++
.../Properties/Resources.Designer.cs | 56 ++++++
.../Properties/Resources.resx | 19 ++
.../Resources/Icons/Progress0.png | Bin 0 -> 295 bytes
.../Resources/Icons/Progress1.png | Bin 0 -> 300 bytes
.../UI/Outlook/CommandElement.cs | 11 +-
.../UI/Outlook/DataProvider.cs | 17 ++
.../AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs | 83 ++++++---
10 files changed, 335 insertions(+), 26 deletions(-)
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Resources/Icons/Progress0.png
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/Resources/Icons/Progress1.png
create mode 100644 src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/DataProvider.cs
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
index f989cbf..186931c 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/AcaciaZPushPlugin.csproj
@@ -287,6 +287,7 @@
SignaturesSettings.cs
+
@@ -337,6 +338,7 @@
+
@@ -618,6 +620,11 @@
+
+
+
+
+
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Features.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Features.cs
index a3166de..7f85a19 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Features.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Features.cs
@@ -38,7 +38,8 @@ namespace Acacia.Features
typeof(SendAs.FeatureSendAs),
typeof(Signatures.FeatureSignatures),
typeof(MeetingRequest.FeatureMeetingRequest),
- typeof(DebugSupport.FeatureDebugSupport)
+ typeof(DebugSupport.FeatureDebugSupport),
+ typeof(SyncState.FeatureSyncState),
};
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs
new file mode 100644
index 0000000..0d840d2
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs
@@ -0,0 +1,165 @@
+/// Copyright 2017 Kopano b.v.
+///
+/// This program is free software: you can redistribute it and/or modify
+/// it under the terms of the GNU Affero General Public License, version 3,
+/// as published by the Free Software Foundation.
+///
+/// This program is distributed in the hope that it will be useful,
+/// but WITHOUT ANY WARRANTY; without even the implied warranty of
+/// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.See the
+/// GNU Affero General Public License for more details.
+///
+/// You should have received a copy of the GNU Affero General Public License
+/// along with this program.If not, see.
+///
+/// Consult LICENSE file for details
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Acacia.Stubs;
+using Acacia.Utils;
+using Acacia.ZPush;
+using Acacia.Features.SharedFolders;
+using Acacia.ZPush.API.SharedFolders;
+using static Acacia.DebugOptions;
+using Acacia.UI.Outlook;
+using System.Drawing;
+
+namespace Acacia.Features.SyncState
+{
+ public class FeatureSyncState : FeatureDisabled, FeatureWithRibbon
+ {
+ private class SyncStateData : DataProvider
+ {
+ private FeatureSyncState _feature;
+
+ ///
+ /// Number in range [0,1]
+ ///
+ private double _syncProgress;
+ public double SyncProgress
+ {
+ get { return _syncProgress; }
+ set
+ {
+ int old = SyncProgressPercent;
+
+ _syncProgress = value;
+
+ if (SyncProgressPercent != old)
+ {
+ // Percentage has changed, update required
+ _feature._button.Invalidate();
+ }
+ }
+ }
+
+ public int SyncProgressPercent
+ {
+ get
+ {
+ return AlignProgress(100);
+ }
+ }
+
+ private int AlignProgress(int steps, double round = 0.5)
+ {
+ int val = (int)Math.Floor(_syncProgress * steps + round);
+ return Math.Min(steps, val);
+ }
+
+ public SyncStateData(FeatureSyncState feature)
+ {
+ this._feature = feature;
+ }
+
+ private static readonly Bitmap[] PROGRESS = CreateProgressImages();
+
+ private const int PROGRESS_STEPS = 20;
+ private static Bitmap[] CreateProgressImages()
+ {
+ Bitmap[] images = new Bitmap[PROGRESS_STEPS + 1];
+
+ Bitmap img0 = Properties.Resources.Progress0;
+ Bitmap img1 = Properties.Resources.Progress1;
+ images[0] = img0;
+ images[PROGRESS_STEPS] = img1;
+
+ // Create a series of images starting with img0, overlayed with part of img1. This shows the progress bar filling up.
+ for (int i = 1; i < PROGRESS_STEPS; ++i)
+ {
+ Bitmap img = new Bitmap(img0);
+ using (var canvas = Graphics.FromImage(img))
+ {
+ int w = img1.Width * i / PROGRESS_STEPS;
+ Rectangle r = new Rectangle(0, 0, w, img0.Height);
+ canvas.DrawImage(img1, r, r, GraphicsUnit.Pixel);
+ canvas.Save();
+ }
+
+ images[i] = img;
+ }
+
+ return images;
+ }
+
+ public Bitmap GetImage(string elementId, bool large)
+ {
+ int index = AlignProgress(PROGRESS_STEPS, 0.05);
+
+ // extra safety check, just in case
+ return (index >= 0 && index <= PROGRESS_STEPS) ? PROGRESS[index] : PROGRESS[0];
+ }
+
+ public string GetLabel(string elementId)
+ {
+ if (SyncProgressPercent == 100)
+ return Properties.Resources.Ribbon_SyncState_Label_Done;
+ return string.Format(Properties.Resources.Ribbon_SyncState_Label, SyncProgressPercent);
+ }
+
+ public string GetScreenTip(string elementId)
+ {
+ return Properties.Resources.Ribbon_SyncState_Screentip;
+ }
+
+ public string GetSuperTip(string elementId)
+ {
+ return Properties.Resources.Ribbon_SyncState_Supertip;
+ }
+ }
+
+ private RibbonButton _button;
+
+ public FeatureSyncState()
+ {
+ }
+
+ public override void Startup()
+ {
+ _button = RegisterButton(this, "Progress", true, ShowSyncState, ZPushBehaviour.None);
+ _button.DataProvider = new SyncStateData(this);
+
+ // Debug timer to increase progress
+ var timer = new System.Windows.Forms.Timer();
+ timer.Interval = 1000;
+ timer.Tick += (o, args) =>
+ {
+ SyncStateData data = (SyncStateData)_button.DataProvider;
+ double val = (data.SyncProgress + 0.05);
+ if (val > 1.01)
+ val = 0;
+ data.SyncProgress = val;
+ };
+ timer.Start();
+
+ }
+
+ private void ShowSyncState()
+ {
+ }
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs
index 76429bb..961bee0 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs
@@ -324,6 +324,26 @@ namespace Acacia.Properties {
}
}
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap Progress0 {
+ get {
+ object obj = ResourceManager.GetObject("Progress0", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
+ ///
+ /// Looks up a localized resource of type System.Drawing.Bitmap.
+ ///
+ internal static System.Drawing.Bitmap Progress1 {
+ get {
+ object obj = ResourceManager.GetObject("Progress1", resourceCulture);
+ return ((System.Drawing.Bitmap)(obj));
+ }
+ }
+
///
/// Looks up a localized resource of type System.Drawing.Bitmap.
///
@@ -745,6 +765,42 @@ namespace Acacia.Properties {
}
}
+ ///
+ /// Looks up a localized string similar to Syncing: {0}%.
+ ///
+ internal static string Ribbon_SyncState_Label {
+ get {
+ return ResourceManager.GetString("Ribbon_SyncState_Label", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Up-to-date.
+ ///
+ internal static string Ribbon_SyncState_Label_Done {
+ get {
+ return ResourceManager.GetString("Ribbon_SyncState_Label_Done", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Synchronisation state.
+ ///
+ internal static string Ribbon_SyncState_Screentip {
+ get {
+ return ResourceManager.GetString("Ribbon_SyncState_Screentip", resourceCulture);
+ }
+ }
+
+ ///
+ /// Looks up a localized string similar to Open the "Synchronisation" dialog, in which the synchronisation state can be viewed and managed..
+ ///
+ internal static string Ribbon_SyncState_Supertip {
+ get {
+ return ResourceManager.GetString("Ribbon_SyncState_Supertip", resourceCulture);
+ }
+ }
+
///
/// Looks up a localized string similar to Kopano.
///
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx
index 93f2739..cf507ad 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx
@@ -457,4 +457,23 @@
There are unsaved changes. Do you really want to to discard these?
+
+ ..\Resources\Icons\Progress0.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ ..\Resources\Icons\Progress1.png;System.Drawing.Bitmap, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a
+
+
+ Syncing: {0}%
+ {0} will be replaced with progress in percent
+
+
+ Up-to-date
+
+
+ Synchronisation state
+
+
+ Open the "Synchronisation" dialog, in which the synchronisation state can be viewed and managed.
+
\ No newline at end of file
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Resources/Icons/Progress0.png b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Resources/Icons/Progress0.png
new file mode 100644
index 0000000000000000000000000000000000000000..132939b827c213f9e60e088910c562821c8fd85d
GIT binary patch
literal 295
zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8Ea{HEjtmSN`?>!lvI6;>1s;*b
z3=EQ2L6~uC#_I;4pk#?_L`iUdT1k0gQ7S`0VrE{6US4X6f{C7io}sY`b95C@(GpJ=
z$B+!?w^ujv9x&ixF??@7&-^0`*94`jz7FmTvtRGKG;8MSlqsns!nJ$9-+3ZibNX-d
w*WYaOi`RYNzgF9vKk0nrv_KN!Mbp=e53jcPh1oo;1-h5P)78&qol`;+0M!(7o&W#<
literal 0
HcmV?d00001
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Resources/Icons/Progress1.png b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Resources/Icons/Progress1.png
new file mode 100644
index 0000000000000000000000000000000000000000..ce01430176dd93ec7d3bbf6c6d86f411e58ae8d2
GIT binary patch
literal 300
zcmeAS@N?(olHy`uVBq!ia0vp^HXzKw1|+Ti+$;i8Ea{HEjtmSN`?>!lvI6;>1s;*b
z3=EQ2L6~uC#_I;4pk#?_L`iUdT1k0gQ7S`0VrE{6US4X6f{C7io}sY`b95C@(MnGj
z$B+!?w^tVmG8+o8IJV|KlQ}BWHgo2_Qx7h>T=>4==PVbeOi3jXuHE~6<`erL
ze}DFV;JJ3UIsUixA>)X0{&_0rBc}zD2rrgiW1Ud9JTfzsTNCJL22WQ%mvv4FO#nBG
BbxZ&N
literal 0
HcmV?d00001
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/CommandElement.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/CommandElement.cs
index eb53650..85748f2 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/CommandElement.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/CommandElement.cs
@@ -35,6 +35,8 @@ namespace Acacia.UI.Outlook
public CheckCommandHandler CheckEnabled;
public CheckCommandHandler CheckVisible;
+ public DataProvider DataProvider { get; set; }
+
public CommandElement(FeatureWithUI feature, string id,
System.Action callback, ZPushBehaviour zpushBehaviour)
{
@@ -65,6 +67,11 @@ namespace Acacia.UI.Outlook
Logger.Instance.Trace(Owner, "Command {0}: Handled", Id);
}
+ public void Invalidate()
+ {
+ UI?.InvalidateCommand(this);
+ }
+
private bool _isEnabled = true;
public bool IsEnabled
{
@@ -78,7 +85,7 @@ namespace Acacia.UI.Outlook
if (_isEnabled != value)
{
_isEnabled = value;
- UI?.InvalidateCommand(this);
+ Invalidate();
}
}
}
@@ -96,7 +103,7 @@ namespace Acacia.UI.Outlook
if (_isVisible != value)
{
_isVisible = value;
- UI?.InvalidateCommand(this);
+ Invalidate();
}
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/DataProvider.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/DataProvider.cs
new file mode 100644
index 0000000..80bd763
--- /dev/null
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/DataProvider.cs
@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Acacia.UI.Outlook
+{
+ public interface DataProvider
+ {
+ string GetLabel(string elementId);
+ string GetScreenTip(string elementId);
+ string GetSuperTip(string elementId);
+ Bitmap GetImage(string elementId, bool large);
+ }
+}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs
index 1f88a94..6fb19e8 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/Outlook/OutlookUI.cs
@@ -242,47 +242,84 @@ namespace Acacia.UI.Outlook
this._officeUI = ribbonUI;
}
+ private class ResourceDataProvider : DataProvider
+ {
+ public Bitmap GetImage(string elementId, bool large)
+ {
+ string id = "Ribbon_" + elementId + (large ? "" : "_Small");
+ object o = Properties.Resources.ResourceManager.GetObject(id);
+ if (o == null)
+ throw new InvalidDataException("Missing image resource " + id);
+ return o as Bitmap;
+ }
+
+ public string GetLabel(string elementId)
+ {
+ return GetString(elementId, "Label");
+ }
+
+ public string GetScreenTip(string elementId)
+ {
+ return GetString(elementId, "Screentip");
+ }
+
+ public string GetSuperTip(string elementId)
+ {
+ return GetString(elementId, "Supertip");
+ }
+
+ private string GetString(string elementId, string suffix)
+ {
+ string id = "Ribbon_" + elementId + "_" + suffix;
+ string s = Properties.Resources.ResourceManager.GetString(id);
+ if (s == null)
+ throw new InvalidDataException("Missing string resource " + id);
+ return s;
+ }
+ }
+
+ private static readonly DataProvider RESOURCE_DATA_PROVIDER = new ResourceDataProvider();
+
+ private CommandElement GetCommand(Office.IRibbonControl control)
+ {
+ CommandElement command = null;
+ _commandIds.TryGetValue(control.Id, out command);
+ return command;
+ }
+
+ private DataProvider GetDataProvider(CommandElement cmd)
+ {
+ return cmd?.DataProvider ?? RESOURCE_DATA_PROVIDER;
+ }
+
public Bitmap getControlImage_large(Office.IRibbonControl control)
{
- return GetControlImage(control, "");
+ CommandElement cmd = GetCommand(control);
+ return GetDataProvider(cmd).GetImage(control.Id, true);
}
public Bitmap getControlImage_normal(Office.IRibbonControl control)
{
- return GetControlImage(control, "_Small");
- }
-
- private Bitmap GetControlImage(Office.IRibbonControl control, string suffix)
- {
- string id = "Ribbon_" + control.Id + suffix;
- object o = Properties.Resources.ResourceManager.GetObject(id);
- if (o == null)
- throw new InvalidDataException("Missing image resource " + id);
- return o as Bitmap;
+ CommandElement cmd = GetCommand(control);
+ return GetDataProvider(cmd).GetImage(control.Id, false);
}
public string getControlLabel(Office.IRibbonControl control)
{
- return GetString(control, "Label");
+ CommandElement cmd = GetCommand(control);
+ return GetDataProvider(cmd).GetLabel(control.Id);
}
public string getControlScreentip(Office.IRibbonControl control)
{
- return GetString(control, "Screentip");
+ CommandElement cmd = GetCommand(control);
+ return GetDataProvider(cmd).GetScreenTip(control.Id);
}
public string getControlSupertip(Office.IRibbonControl control)
{
- return GetString(control, "Supertip");
- }
-
- private string GetString(Office.IRibbonControl control, string suffix)
- {
- string id = "Ribbon_" + control.Id + "_" + suffix;
- string s = Properties.Resources.ResourceManager.GetString(id);
- if (s == null)
- throw new InvalidDataException("Missing string resource " + id);
- return s;
+ CommandElement cmd = GetCommand(control);
+ return GetDataProvider(cmd).GetSuperTip(control.Id);
}
#endregion