From 8c08363b1f5d8596520dc4272cf97a85f40716d0 Mon Sep 17 00:00:00 2001
From: Patrick Simpson
Date: Wed, 28 Feb 2018 17:00:51 +0200
Subject: [PATCH] [KOE-76] Implemented per-account sync timeframe in sync
dialog
---
.../AcaciaZPushPlugin/Controls/KDialogNew.cs | 1 +
.../Features/Signatures/FeatureSignatures.cs | 14 +-
.../Features/SyncState/FeatureSyncState.cs | 45 ++-
.../SyncState/SyncStateDialog.Designer.cs | 70 +++-
.../Features/SyncState/SyncStateDialog.cs | 66 +++-
.../Features/SyncState/SyncStateDialog.resx | 327 +++++++++++++-----
.../Features/WebApp/FeatureWebApp.cs | 4 +-
.../AcaciaZPushPlugin/Native/IOlkAccount.cs | 7 +-
.../AcaciaZPushPlugin/Native/MAPI/Property.cs | 9 +
.../AcaciaZPushPlugin/OutlookConstants.cs | 11 +-
.../AcaciaZPushPlugin/Stubs/IAccount.cs | 26 +-
.../Stubs/OutlookWrappers/AccountWrapper.cs | 109 +++---
.../AcaciaZPushPlugin/Utils/RegistryUtil.cs | 11 +
.../AcaciaZPushPlugin/ZPush/ZPushAccount.cs | 113 +++++-
.../AcaciaZPushPlugin/ZPush/ZPushTypes.cs | 13 +
15 files changed, 613 insertions(+), 213 deletions(-)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDialogNew.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDialogNew.cs
index 778e652..7bde0f3 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDialogNew.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KDialogNew.cs
@@ -70,6 +70,7 @@ namespace Acacia.Controls
#endregion
#region KUITaskProgress
+
// TODO: if BusyHider is not set, pop up dialogs
public string BusyText
{
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs
index e2c0576..08c956d 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/Signatures/FeatureSignatures.cs
@@ -134,7 +134,7 @@ namespace Acacia.Features.Signatures
if (serverSignatureHash != null)
{
Logger.Instance.Trace(this, "Checking signature hash for account {0}: {1}", account, serverSignatureHash);
- if (serverSignatureHash == account.Account.LocalSignaturesHash)
+ if (serverSignatureHash == account.LocalSignaturesHash)
return;
}
@@ -145,7 +145,7 @@ namespace Acacia.Features.Signatures
string hash = FetchSignatures(account);
// Store updated hash
- account.Account.LocalSignaturesHash = hash;
+ account.LocalSignaturesHash = hash;
Logger.Instance.Debug(this, "Updated signatures: {0}: {1}", account, hash);
}
catch (Exception e)
@@ -206,13 +206,13 @@ namespace Acacia.Features.Signatures
}
// Set default signatures if available and none are set
- if (!string.IsNullOrEmpty(result.new_message) && ShouldSetSignature(account.Account.SignatureNewMessage))
+ if (!string.IsNullOrEmpty(result.new_message) && ShouldSetSignature(account.SignatureNewMessage))
{
- account.Account.SignatureNewMessage = fullNames[result.new_message];
+ account.SignatureNewMessage = fullNames[result.new_message];
}
- if (!string.IsNullOrEmpty(result.replyforward_message) && ShouldSetSignature(account.Account.SignatureReplyForwardMessage))
+ if (!string.IsNullOrEmpty(result.replyforward_message) && ShouldSetSignature(account.SignatureReplyForwardMessage))
{
- account.Account.SignatureReplyForwardMessage = fullNames[result.replyforward_message];
+ account.SignatureReplyForwardMessage = fullNames[result.replyforward_message];
}
return result.hash;
@@ -291,7 +291,7 @@ namespace Acacia.Features.Signatures
private void GAB_SyncFinished(GABHandler gab)
{
- ReplacePlaceholders(gab, gab.ActiveAccount.Account.SignatureNewMessage, gab.ActiveAccount.Account.SignatureNewMessage);
+ ReplacePlaceholders(gab, gab.ActiveAccount.SignatureNewMessage, gab.ActiveAccount.SignatureNewMessage);
}
private void ReplacePlaceholders(GABHandler gab, params string[] signatures)
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs
index 1c0921b..136c3ad 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/FeatureSyncState.cs
@@ -1,4 +1,4 @@
-/// Copyright 2017 Kopano b.v.
+/// Copyright 2018 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,
@@ -576,10 +576,13 @@ namespace Acacia.Features.SyncState
if (_dialog != null)
return;
+ // Get the current account. If no Z-Push account is selected, the dialog will open for all accounts.
+ ZPushAccount account = Watcher.CurrentZPushAccount();
+
// Ramp up the checking schedule while the dialog is open
// The other check sets per-account schedules, we use the global one, so they should't interfere.
TimeSpan? old = Watcher.Sync.SetTaskSchedule(_task, null, CheckPeriodDialogEffective, true);
- SyncStateDialog dlg = new SyncStateDialog(this);
+ SyncStateDialog dlg = new SyncStateDialog(this, account);
dlg.FormClosed += (s, e) =>
{
// Restore the schedule
@@ -733,5 +736,43 @@ namespace Acacia.Features.SyncState
{
return new SyncStateImpl(this, account == null ? Watcher.Accounts.GetAccounts().ToArray() : new ZPushAccount[] { account });
}
+
+
+ private class SetDeviceOptionsRequest : SoapRequest
+ {
+ public SetDeviceOptionsRequest(SyncTimeFrame timeFrame)
+ {
+ Parameters.Add("filtertype", (int)timeFrame);
+ }
+ }
+
+ public void SetDeviceOptions(ZPushAccount account, SyncTimeFrame timeFrame)
+ {
+
+ try
+ {
+ Logger.Instance.Debug(this, "Setting sync time frame for {0} to {1}", account, timeFrame);
+
+ // First set the server value.
+ using (ZPushConnection connection = account.Connect())
+ using (ZPushWebServiceDevice deviceService = connection.DeviceService)
+ {
+ deviceService.Execute(new SetDeviceOptionsRequest(timeFrame));
+ }
+
+ // And the local value
+ account.SyncTimeFrame = timeFrame;
+ Logger.Instance.Debug(this, "Set sync time frame for {0} to {1}", account, timeFrame);
+
+ // Sync
+ ThisAddIn.Instance.SendReceive(account.Account);
+ }
+ catch (Exception x)
+ {
+ Logger.Instance.Warning(this, "Exception setting sync time frame for {0} to {1}: {2}", account, timeFrame, x);
+ }
+
+
+ }
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.Designer.cs
index 4c3a2dd..ea558fa 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.Designer.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.Designer.cs
@@ -38,6 +38,11 @@
this._labelProgress = new System.Windows.Forms.Label();
this.progress = new Acacia.Controls.KProgressBar();
this.textRemaining = new System.Windows.Forms.Label();
+ this._labelTimeFrame = new System.Windows.Forms.Label();
+ this._layoutTimeFrameButtons = new System.Windows.Forms.TableLayoutPanel();
+ this.comboTimeFrame = new System.Windows.Forms.ComboBox();
+ this.buttonApplyTimeFrame = new System.Windows.Forms.Button();
+ this.buttonResetTimeFrame = new System.Windows.Forms.Button();
this._labelResync = new System.Windows.Forms.Label();
this.buttonGAB = new Acacia.Controls.KHintButton();
this.buttonSignatures = new Acacia.Controls.KHintButton();
@@ -46,6 +51,7 @@
this._labelResyncOption = new System.Windows.Forms.Label();
this._layout.SuspendLayout();
this._layoutMain.SuspendLayout();
+ this._layoutTimeFrameButtons.SuspendLayout();
this.SuspendLayout();
//
// _layout
@@ -73,12 +79,14 @@
this._layoutMain.Controls.Add(this._labelProgress, 0, 1);
this._layoutMain.Controls.Add(this.progress, 1, 1);
this._layoutMain.Controls.Add(this.textRemaining, 1, 2);
- this._layoutMain.Controls.Add(this._labelResync, 0, 3);
- this._layoutMain.Controls.Add(this.buttonGAB, 1, 3);
- this._layoutMain.Controls.Add(this.buttonSignatures, 1, 4);
- this._layoutMain.Controls.Add(this.buttonServerData, 1, 5);
- this._layoutMain.Controls.Add(this.buttonFullResync, 1, 6);
- this._layoutMain.Controls.Add(this._labelResyncOption, 1, 7);
+ this._layoutMain.Controls.Add(this._labelTimeFrame, 0, 3);
+ this._layoutMain.Controls.Add(this._layoutTimeFrameButtons, 1, 3);
+ this._layoutMain.Controls.Add(this._labelResync, 0, 6);
+ this._layoutMain.Controls.Add(this.buttonGAB, 1, 6);
+ this._layoutMain.Controls.Add(this.buttonSignatures, 1, 7);
+ this._layoutMain.Controls.Add(this.buttonServerData, 1, 8);
+ this._layoutMain.Controls.Add(this.buttonFullResync, 1, 9);
+ this._layoutMain.Controls.Add(this._labelResyncOption, 1, 10);
this._layoutMain.Name = "_layoutMain";
//
// _labelRemaining
@@ -121,6 +129,50 @@
this.textRemaining.BackColor = System.Drawing.SystemColors.Window;
this.textRemaining.Name = "textRemaining";
//
+ // _labelTimeFrame
+ //
+ resources.ApplyResources(this._labelTimeFrame, "_labelTimeFrame");
+ this._labelTimeFrame.Name = "_labelTimeFrame";
+ //
+ // _layoutTimeFrameButtons
+ //
+ resources.ApplyResources(this._layoutTimeFrameButtons, "_layoutTimeFrameButtons");
+ this._layoutTimeFrameButtons.Controls.Add(this.comboTimeFrame, 0, 0);
+ this._layoutTimeFrameButtons.Controls.Add(this.buttonApplyTimeFrame, 2, 0);
+ this._layoutTimeFrameButtons.Controls.Add(this.buttonResetTimeFrame, 1, 0);
+ this._layoutTimeFrameButtons.Name = "_layoutTimeFrameButtons";
+ //
+ // comboTimeFrame
+ //
+ resources.ApplyResources(this.comboTimeFrame, "comboTimeFrame");
+ this.comboTimeFrame.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
+ this.comboTimeFrame.FormattingEnabled = true;
+ this.comboTimeFrame.Items.AddRange(new object[] {
+ resources.GetString("comboTimeFrame.Items"),
+ resources.GetString("comboTimeFrame.Items1"),
+ resources.GetString("comboTimeFrame.Items2"),
+ resources.GetString("comboTimeFrame.Items3"),
+ resources.GetString("comboTimeFrame.Items4"),
+ resources.GetString("comboTimeFrame.Items5"),
+ resources.GetString("comboTimeFrame.Items6"),
+ resources.GetString("comboTimeFrame.Items7")});
+ this.comboTimeFrame.Name = "comboTimeFrame";
+ this.comboTimeFrame.SelectedIndexChanged += new System.EventHandler(this.comboTimeFrame_SelectedIndexChanged);
+ //
+ // buttonApplyTimeFrame
+ //
+ resources.ApplyResources(this.buttonApplyTimeFrame, "buttonApplyTimeFrame");
+ this.buttonApplyTimeFrame.Name = "buttonApplyTimeFrame";
+ this.buttonApplyTimeFrame.UseVisualStyleBackColor = true;
+ this.buttonApplyTimeFrame.Click += new System.EventHandler(this.buttonApplyTimeFrame_Click);
+ //
+ // buttonResetTimeFrame
+ //
+ resources.ApplyResources(this.buttonResetTimeFrame, "buttonResetTimeFrame");
+ this.buttonResetTimeFrame.Name = "buttonResetTimeFrame";
+ this.buttonResetTimeFrame.UseVisualStyleBackColor = true;
+ this.buttonResetTimeFrame.Click += new System.EventHandler(this.buttonResetTimeFrame_Click);
+ //
// _labelResync
//
resources.ApplyResources(this._labelResync, "_labelResync");
@@ -179,6 +231,7 @@
this._layout.PerformLayout();
this._layoutMain.ResumeLayout(false);
this._layoutMain.PerformLayout();
+ this._layoutTimeFrameButtons.ResumeLayout(false);
this.ResumeLayout(false);
this.PerformLayout();
@@ -201,5 +254,10 @@
private System.Windows.Forms.Label _labelResyncOption;
private System.Windows.Forms.Label _labelResync;
private Controls.KHintButton buttonGAB;
+ private System.Windows.Forms.Label _labelTimeFrame;
+ private System.Windows.Forms.ComboBox comboTimeFrame;
+ private System.Windows.Forms.TableLayoutPanel _layoutTimeFrameButtons;
+ private System.Windows.Forms.Button buttonApplyTimeFrame;
+ private System.Windows.Forms.Button buttonResetTimeFrame;
}
}
\ No newline at end of file
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.cs
index bf9ebd7..a27609c 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.cs
@@ -1,4 +1,4 @@
-/// Copyright 2017 Kopano b.v.
+/// Copyright 2018 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,
@@ -25,6 +25,7 @@ using System.Windows.Forms;
using Acacia.UI;
using Acacia.Controls;
using Acacia.ZPush;
+using Acacia.ZPush.Connect;
namespace Acacia.Features.SyncState
{
@@ -35,7 +36,15 @@ namespace Acacia.Features.SyncState
private readonly Button[] _syncButtons;
- public SyncStateDialog(FeatureSyncState feature)
+ private ZPushAccount SelectedAccount
+ {
+ get
+ {
+ return comboAccounts.SelectedItem as ZPushAccount;
+ }
+ }
+
+ public SyncStateDialog(FeatureSyncState feature, ZPushAccount currentAccount)
{
InitializeComponent();
@@ -50,6 +59,8 @@ namespace Acacia.Features.SyncState
// Add the accounts
foreach (ZPushAccount account in ThisAddIn.Instance.Watcher.Accounts.GetAccounts())
comboAccounts.Items.Add(account);
+ if (currentAccount != null)
+ comboAccounts.SelectedItem = currentAccount;
}
private void ShowHint(object sender, KHintButton.HintEventArgs e)
@@ -57,12 +68,60 @@ namespace Acacia.Features.SyncState
_labelResyncOption.Text = e.Hint ?? string.Empty;
}
+ #region Sync time frame
+
private void comboAccounts_SelectedIndexChanged(object sender, EventArgs e)
{
- _syncState = _feature.GetSyncState(comboAccounts.SelectedItem as ZPushAccount);
+ _syncState = _feature.GetSyncState(SelectedAccount);
+ _labelTimeFrame.Enabled = comboTimeFrame.Enabled = SelectedAccount != null;
+
+ if (SelectedAccount == null)
+ comboTimeFrame.SelectedIndex = 0;
+ else
+ comboTimeFrame.SelectedIndex = (int)SelectedAccount.SyncTimeFrame;
+
UpdateUI();
}
+ private void comboTimeFrame_SelectedIndexChanged(object sender, EventArgs e)
+ {
+ CheckTimeFrameDirty();
+ }
+
+ private void CheckTimeFrameDirty()
+ {
+ if (SelectedAccount != null)
+ {
+ SyncTimeFrame timeFrame = (SyncTimeFrame)comboTimeFrame.SelectedIndex;
+ bool isDirty = timeFrame != SelectedAccount.SyncTimeFrame;
+ buttonApplyTimeFrame.Enabled = buttonResetTimeFrame.Enabled = isDirty;
+ }
+ else
+ {
+ buttonApplyTimeFrame.Enabled = buttonResetTimeFrame.Enabled = false;
+ }
+ }
+
+ private void buttonResetTimeFrame_Click(object sender, EventArgs e)
+ {
+ if (SelectedAccount != null)
+ comboTimeFrame.SelectedIndex = (int)SelectedAccount.SyncTimeFrame;
+ }
+
+ private void buttonApplyTimeFrame_Click(object sender, EventArgs e)
+ {
+ if (SelectedAccount != null)
+ {
+ Busy = true;
+
+ // TODO: do this in the background
+ _feature.SetDeviceOptions(SelectedAccount, (SyncTimeFrame)comboTimeFrame.SelectedIndex);
+ CheckTimeFrameDirty();
+ }
+ }
+
+ #endregion
+
private static readonly string[] OPTION_TEXT =
{
Properties.Resources.SyncState_Resync_Body_GAB,
@@ -150,5 +209,6 @@ namespace Acacia.Features.SyncState
progress.Value = 100;
}
}
+
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.resx
index a9dc4f6..54b2bbf 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.resx
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/SyncState/SyncStateDialog.resx
@@ -139,13 +139,13 @@
- 5, 711
+ 2, 344
- 5, 5, 5, 5
+ 2, 2, 2, 2
- 889, 54
+ 333, 35
0
@@ -181,13 +181,10 @@
NoControl
- 8, 129
-
-
- 8, 0, 8, 0
+ 3, 59
- 203, 60
+ 77, 25
5
@@ -217,13 +214,10 @@
Fill
- 8, 0
-
-
- 8, 0, 8, 0
+ 3, 0
- 203, 53
+ 77, 27
0
@@ -256,16 +250,13 @@
All Z-Push accounts
- 227, 7
-
-
- 8, 7, 8, 7
+ 86, 3
- 648, 39
+ 242, 21
- 1
+ 0
comboAccounts
@@ -286,13 +277,10 @@
Fill
- 8, 53
-
-
- 8, 0, 8, 0
+ 3, 27
- 203, 76
+ 77, 32
2
@@ -319,16 +307,13 @@
Fill
- 227, 60
-
-
- 8, 7, 8, 7
+ 86, 30
- 648, 62
+ 242, 26
- 3
+ 1
progress
@@ -349,19 +334,19 @@
Fill
- 227, 136
+ 86, 62
- 8, 7, 8, 7
+ 3, 3, 3, 3
- 8, 7, 8, 7
+ 3, 3, 3, 3
- 648, 46
+ 242, 19
- 7
+ 2
textRemaining
@@ -375,6 +360,183 @@
5
+
+ True
+
+
+ Fill
+
+
+ 3, 84
+
+
+ 77, 28
+
+
+ 9
+
+
+ Synchronise
+
+
+ MiddleLeft
+
+
+ _labelTimeFrame
+
+
+ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ _layoutMain
+
+
+ 6
+
+
+ True
+
+
+ 3
+
+
+ Fill
+
+
+ Popup
+
+
+ all
+
+
+ 1 day
+
+
+ 3 days
+
+
+ 1 week
+
+
+ 2 weeks
+
+
+ 1 month
+
+
+ 3 months
+
+
+ 6 months
+
+
+ 3, 3
+
+
+ 102, 21
+
+
+ 0
+
+
+ comboTimeFrame
+
+
+ System.Windows.Forms.ComboBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ _layoutTimeFrameButtons
+
+
+ 0
+
+
+ 181, 2
+
+
+ 3, 2, 3, 3
+
+
+ 64, 23
+
+
+ 2
+
+
+ Apply
+
+
+ buttonApplyTimeFrame
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ _layoutTimeFrameButtons
+
+
+ 1
+
+
+ 111, 2
+
+
+ 3, 2, 3, 3
+
+
+ 64, 23
+
+
+ 1
+
+
+ Reset
+
+
+ buttonResetTimeFrame
+
+
+ System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ _layoutTimeFrameButtons
+
+
+ 2
+
+
+ Fill
+
+
+ 83, 84
+
+
+ 0, 0, 0, 0
+
+
+ 1
+
+
+ 248, 28
+
+
+ 3
+
+
+ _layoutTimeFrameButtons
+
+
+ System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089
+
+
+ _layoutMain
+
+
+ 7
+
+
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="comboTimeFrame" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonApplyTimeFrame" Row="0" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="buttonResetTimeFrame" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="Percent,100,AutoSize,0,AutoSize,0" /><Rows Styles="AutoSize,0" /></TableLayoutSettings>
+
True
@@ -382,13 +544,10 @@
Fill
- 8, 189
-
-
- 8, 0, 8, 0
+ 3, 132
- 203, 70
+ 77, 35
8
@@ -409,7 +568,7 @@
_layoutMain
- 6
+ 8
True
@@ -427,19 +586,16 @@
NoControl
- 227, 196
-
-
- 8, 7, 8, 7
+ 86, 135
- 8, 7, 8, 7
+ 3, 3, 3, 3
- 648, 56
+ 242, 29
- 0
+ 4
Global Address Book
@@ -454,7 +610,7 @@
_layoutMain
- 7
+ 9
True
@@ -472,19 +628,16 @@
NoControl
- 227, 266
-
-
- 8, 7, 8, 7
+ 86, 170
- 8, 7, 8, 7
+ 3, 3, 3, 3
- 648, 56
+ 242, 29
- 1
+ 5
Signatures
@@ -499,7 +652,7 @@
_layoutMain
- 8
+ 10
True
@@ -517,19 +670,16 @@
NoControl
- 227, 336
-
-
- 8, 7, 8, 7
+ 86, 205
- 8, 7, 8, 7
+ 3, 3, 3, 3
- 648, 56
+ 242, 29
- 2
+ 6
Server Data
@@ -544,7 +694,7 @@
_layoutMain
- 9
+ 11
True
@@ -562,19 +712,16 @@
NoControl
- 227, 406
-
-
- 8, 7, 8, 7
+ 86, 240
- 8, 7, 8, 7
+ 3, 3, 3, 3
- 648, 56
+ 242, 29
- 3
+ 7
Full Resynchronisation
@@ -589,22 +736,19 @@
_layoutMain
- 10
+ 12
Fill
- 227, 469
-
-
- 8, 0, 8, 0
+ 86, 272
- 0, 14, 0, 0
+ 0, 6, 0, 0
- 648, 223
+ 242, 64
4
@@ -619,22 +763,19 @@
_layoutMain
- 11
+ 13
Fill
- 8, 7
-
-
- 8, 7, 8, 7
+ 3, 3
- 8
+ 11
- 883, 692
+ 331, 336
1
@@ -652,7 +793,7 @@
1
- <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_labelRemaining" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_labelAccount" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboAccounts" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelProgress" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="progress" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textRemaining" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelResync" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonGAB" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonSignatures" Row="4" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonServerData" Row="5" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonFullResync" Row="6" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelResyncOption" Row="7" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Percent,100" /></TableLayoutSettings>
+ <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_labelRemaining" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_labelAccount" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="comboAccounts" Row="0" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelProgress" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="progress" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="textRemaining" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelTimeFrame" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_layoutTimeFrameButtons" Row="3" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelResync" Row="6" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="buttonGAB" Row="6" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonSignatures" Row="7" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonServerData" Row="8" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="buttonFullResync" Row="9" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="_labelResyncOption" Row="10" RowSpan="1" Column="1" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Absolute,20,AutoSize,0,AutoSize,0,AutoSize,0,AutoSize,0,Percent,100" /></TableLayoutSettings>
Fill
@@ -660,14 +801,11 @@
0, 0
-
- 8, 7, 8, 7
-
2
- 899, 770
+ 337, 381
0
@@ -691,16 +829,13 @@
True
- 16, 31
+ 6, 13
True
- 899, 770
-
-
- 8, 7, 8, 7
+ 337, 381
CenterParent
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/WebApp/FeatureWebApp.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/WebApp/FeatureWebApp.cs
index 4ec7dc8..b09e6b0 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/WebApp/FeatureWebApp.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/WebApp/FeatureWebApp.cs
@@ -1,6 +1,4 @@
-
-using Acacia.Native.MAPI;
-/// Copyright 2016 Kopano b.v.
+/// Copyright 2018 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,
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/IOlkAccount.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/IOlkAccount.cs
index 9b504a3..0117330 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/IOlkAccount.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/IOlkAccount.cs
@@ -8,12 +8,17 @@ using System.Threading.Tasks;
namespace Acacia.Native
{
- [StructLayout(LayoutKind.Sequential)]
+ [StructLayout(LayoutKind.Explicit)]
unsafe public struct ACCT_VARIANT
{
+ [FieldOffset(0), MarshalAs(UnmanagedType.U4)]
public uint dwType;
+ [FieldOffset(8)]
public char* lpszW;
+
+ [FieldOffset(8), MarshalAs(UnmanagedType.U4)]
+ public uint dw;
}
[ComImport]
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/MAPI/Property.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/MAPI/Property.cs
index 2e9d401..cb509b4 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/MAPI/Property.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Native/MAPI/Property.cs
@@ -55,6 +55,15 @@ namespace Acacia.Native.MAPI
return new SearchQuery.PropertyIdentifier(this);
}
+ public static PropTag FromValue(ushort prop, PropType type)
+ {
+ return new PropTag()
+ {
+ prop = prop,
+ type = type
+ };
+ }
+
public static PropTag FromInt(int v)
{
return new PropTag()
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs
index 480cb8a..133c6d6 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/OutlookConstants.cs
@@ -1,4 +1,6 @@
-/// Copyright 2016 Kopano b.v.
+
+using Acacia.Native.MAPI;
+/// Copyright 2016 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,
@@ -13,7 +15,6 @@
/// along with this program.If not, see.
///
/// Consult LICENSE file for details
-
using System;
using System.Collections.Generic;
using System.Linq;
@@ -45,9 +46,15 @@ namespace Acacia
public const string REG_VAL_REPLY_FORWARD_SIGNATURE = "Reply-Forward Signature";
public const string REG_VAL_CURRENT_SIGNATURE = "KOE Signature Digest";
+ public const string REG_VAL_SYNC_TIMEFRAME = "KOE SyncTimeFrame";
+ public const string REG_VAL_SYNC_SLIDER = "EAS SyncSlider";
public const string REG_VAL_NEXT_ACCOUNT_ID = "NextAccountID";
public const string REG_VAL_KOE_SHARE_FOR = "KOE Share For";
+ public static readonly PropTag PROP_NEW_MESSAGE_SIGNATURE = PropTag.FromValue(0x0016, PropType.UNICODE);
+ public static readonly PropTag PROP_REPLY_SIGNATURE = PropTag.FromValue(0x0017, PropType.UNICODE);
+ public static readonly PropTag PROP_SYNC_1_MONTH = PropTag.FromValue(0x2103, PropType.LONG);
+
#endregion
#region PREFIXES
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs
index dd29666..9042aaa 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/IAccount.cs
@@ -1,4 +1,6 @@
-/// Copyright 2017 Kopano b.v.
+
+using Acacia.Native.MAPI;
+/// 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,
@@ -13,7 +15,6 @@
/// along with this program.If not, see.
///
/// Consult LICENSE file for details
-
using System;
using System.Collections.Generic;
using System.Linq;
@@ -54,25 +55,8 @@ namespace Acacia.Stubs
string BackingFilePath { get; }
- // TODO: this is really a Z-Push thing, but it's here to store it in the registry
- string LocalSignaturesHash
- {
- get;
- set;
- }
+ string RegistryBaseKey { get; }
- string SignatureNewMessage
- {
- get;
- set;
- }
-
- string SignatureReplyForwardMessage
- {
- get;
- set;
- }
-
- string ShareFor {get;}
+ void SetAccountProp(PropTag prop, object value);
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs
index 36ef412..8687038 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Stubs/OutlookWrappers/AccountWrapper.cs
@@ -1,7 +1,5 @@
-using Acacia.Native;
-using Acacia.Native.MAPI;
-/// Copyright 2017 Kopano b.v.
+/// Copyright 2018 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,
@@ -17,6 +15,8 @@ using Acacia.Native.MAPI;
///
/// Consult LICENSE file for details
using Acacia.Utils;
+using Acacia.Native;
+using Acacia.Native.MAPI;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
@@ -207,55 +207,6 @@ namespace Acacia.Stubs.OutlookWrappers
}
}
- public string LocalSignaturesHash
- {
- get
- {
- return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_CURRENT_SIGNATURE, null);
- }
- set
- {
- RegistryUtil.SetValueString(_regPath, OutlookConstants.REG_VAL_CURRENT_SIGNATURE, value);
- }
- }
- public string SignatureNewMessage
- {
- get
- {
- return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_NEW_SIGNATURE, null);
- }
- set
- {
- // TODO: constant for account
- SetAccountProp(PropTag.FromInt(0x0016001F), value);
- }
- }
-
- unsafe private void SetAccountProp(PropTag propTag, string value)
- {
- // Use IOlkAccount to notify while we're running
- // IOlkAccount can only be accessed on main thread
- ThisAddIn.Instance.InUI(() =>
- {
- using (ComRelease com = new ComRelease())
- {
- NSOutlook.Account account = com.Add(FindAccountObject());
- IOlkAccount olk = com.Add(account.IOlkAccount);
-
- fixed (char* ptr = value.ToCharArray())
- {
- ACCT_VARIANT val = new ACCT_VARIANT()
- {
- dwType = (uint)PropType.UNICODE,
- lpszW = ptr
- };
- olk.SetProp(propTag, &val);
- olk.SaveChanges(0);
- }
- }
- });
- }
-
private NSOutlook.Account FindAccountObject()
{
using (ComRelease com = new ComRelease())
@@ -272,26 +223,50 @@ namespace Acacia.Stubs.OutlookWrappers
return null;
}
- public string SignatureReplyForwardMessage
- {
- get
- {
- return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_REPLY_FORWARD_SIGNATURE, null);
- }
- set
- {
- SetAccountProp(PropTag.FromInt(0x0017001F), value);
- }
- }
- public string ShareFor
+ unsafe public void SetAccountProp(PropTag propTag, object value)
{
- get
+ // Use IOlkAccount to notify while we're running
+ // IOlkAccount can only be accessed on main thread
+ ThisAddIn.Instance.InUI(() =>
{
- return RegistryUtil.GetValueString(_regPath, OutlookConstants.REG_VAL_KOE_SHARE_FOR, null);
- }
+ using (ComRelease com = new ComRelease())
+ {
+ NSOutlook.Account account = com.Add(FindAccountObject());
+ IOlkAccount olk = com.Add(account.IOlkAccount);
+
+ switch(propTag.type)
+ {
+ case PropType.UNICODE:
+ fixed (char* ptr = ((string)value).ToCharArray())
+ {
+ ACCT_VARIANT val = new ACCT_VARIANT()
+ {
+ dwType = (uint)PropType.UNICODE,
+ lpszW = ptr
+ };
+ olk.SetProp(propTag, &val);
+ olk.SaveChanges(0);
+ }
+ break;
+ case PropType.LONG:
+ {
+ ACCT_VARIANT val = new ACCT_VARIANT()
+ {
+ dwType = (uint)PropType.LONG,
+ dw = (uint)value
+ };
+ olk.SetProp(propTag, &val);
+ olk.SaveChanges(0);
+ break;
+ }
+ }
+ }
+ });
}
#endregion
+
+ public string RegistryBaseKey { get { return _regPath; } }
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/RegistryUtil.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/RegistryUtil.cs
index 4eb4aa2..5718137 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/RegistryUtil.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/RegistryUtil.cs
@@ -45,6 +45,17 @@ namespace Acacia.Utils
Registry.SetValue(keyPath, valueName, value);
}
+ public static int GetValueDword(string keyPath, string valueName, int defaultValue)
+ {
+ object o = Registry.GetValue(keyPath, valueName, defaultValue);
+ return (int)o;
+ }
+
+ public static void SetValueDword(string keyPath, string valueName, int value)
+ {
+ Registry.SetValue(keyPath, valueName, value);
+ }
+
public static string RegToString(object o)
{
if (o is byte[])
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs
index 0e00160..3339a30 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushAccount.cs
@@ -1,4 +1,5 @@
-/// Copyright 2016 Kopano b.v.
+
+/// Copyright 2018 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,
@@ -13,7 +14,6 @@
/// along with this program.If not, see.
///
/// Consult LICENSE file for details
-
using Acacia.Stubs;
using Acacia.Stubs.OutlookWrappers;
using Acacia.Utils;
@@ -28,6 +28,9 @@ using System.Security;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
+using Acacia.Native;
+using Acacia.Native.MAPI;
+using NSOutlook = Microsoft.Office.Interop.Outlook;
namespace Acacia.ZPush
{
@@ -213,7 +216,10 @@ namespace Acacia.ZPush
public string ShareFor
{
- get { return Account.ShareFor; }
+ get
+ {
+ return RegistryUtil.GetValueString(Account.RegistryBaseKey, OutlookConstants.REG_VAL_KOE_SHARE_FOR, null);
+ }
}
public string ShareUserName
@@ -235,10 +241,10 @@ namespace Acacia.ZPush
{
get
{
- if (Account.ShareFor == null)
+ if (ShareFor == null)
return null;
- return _zPushAccounts.GetAccount(Account.ShareFor);
+ return _zPushAccounts.GetAccount(ShareFor);
}
}
@@ -284,5 +290,102 @@ namespace Acacia.ZPush
}
#endregion
+
+ #region Signatures
+
+ public string LocalSignaturesHash
+ {
+ get
+ {
+ return RegistryUtil.GetValueString(Account.RegistryBaseKey, OutlookConstants.REG_VAL_CURRENT_SIGNATURE, null);
+ }
+ set
+ {
+ RegistryUtil.SetValueString(Account.RegistryBaseKey, OutlookConstants.REG_VAL_CURRENT_SIGNATURE, value);
+ }
+ }
+
+ public string SignatureNewMessage
+ {
+ get
+ {
+ return RegistryUtil.GetValueString(Account.RegistryBaseKey, OutlookConstants.REG_VAL_NEW_SIGNATURE, null);
+ }
+ set
+ {
+ Account.SetAccountProp(OutlookConstants.PROP_NEW_MESSAGE_SIGNATURE, value);
+ }
+ }
+
+ public string SignatureReplyForwardMessage
+ {
+ get
+ {
+ return RegistryUtil.GetValueString(Account.RegistryBaseKey, OutlookConstants.REG_VAL_REPLY_FORWARD_SIGNATURE, null);
+ }
+ set
+ {
+ Account.SetAccountProp(OutlookConstants.PROP_REPLY_SIGNATURE, value);
+ }
+ }
+
+ #endregion
+
+ #region Sync time frame
+
+ public SyncTimeFrame SyncTimeFrame
+ {
+ get
+ {
+ int val = RegistryUtil.GetValueDword(Account.RegistryBaseKey, OutlookConstants.REG_VAL_SYNC_TIMEFRAME, -1);
+ // Check for default (Outlook) values
+ if (val < 0)
+ {
+ if (EASSyncOneMonth)
+ return SyncTimeFrame.MONTH_1;
+ return SyncTimeFrame.ALL;
+ }
+
+ SyncTimeFrame frame = (SyncTimeFrame)val;
+ // If the timeframe exceeds one month, but Outlook is set to one month, only one month will be synced.
+ if (!IsSyncOneMonthOrLess(frame) && EASSyncOneMonth)
+ return SyncTimeFrame.MONTH_1;
+ return frame;
+ }
+
+ set
+ {
+ if (value != SyncTimeFrame)
+ {
+ // Set the outlook property
+ EASSyncOneMonth = IsSyncOneMonthOrLess(value);
+ // And the registry value
+ RegistryUtil.SetValueDword(Account.RegistryBaseKey, OutlookConstants.REG_VAL_SYNC_TIMEFRAME, (int)value);
+ }
+ }
+ }
+
+ private bool EASSyncOneMonth
+ {
+ get
+ {
+ return RegistryUtil.GetValueDword(Account.RegistryBaseKey, OutlookConstants.REG_VAL_SYNC_SLIDER, -1) == 1;
+ }
+
+ set
+ {
+ if (value != EASSyncOneMonth)
+ {
+ Account.SetAccountProp(OutlookConstants.PROP_SYNC_1_MONTH, value ? (uint)1 : (uint)0);
+ }
+ }
+ }
+
+ private bool IsSyncOneMonthOrLess(SyncTimeFrame sync)
+ {
+ return sync <= SyncTimeFrame.MONTH_1 && sync != SyncTimeFrame.ALL;
+ }
+
+ #endregion
}
}
diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs
index a5bd0ad..1834d23 100644
--- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs
+++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/ZPush/ZPushTypes.cs
@@ -132,4 +132,17 @@ namespace Acacia.ZPush
#endregion
}
+
+ public enum SyncTimeFrame
+ {
+ // The order of this is to match the Z-Push settings
+ ALL,
+ DAY_1,
+ DAY_3,
+ WEEK_1,
+ WEEK_2,
+ MONTH_1,
+ MONTH_3,
+ MONTH_6
+ }
}