diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUITask.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUITask.cs index ee700ea..85dc15f 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUITask.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Controls/KUITask.cs @@ -485,6 +485,11 @@ namespace Acacia.Controls return Chain(new KUITask(TaskExecutor.TaskContextParam(func, TaskExecutor.OptionHelper(false, true, inUI)), false)); } + public KUITask OnSuccess(Action func, bool inUI = false) + { + return Chain(new KUITask(TaskExecutor.Param(func, TaskExecutor.OptionHelper(false, true, inUI)), false)); + } + public KUITask OnSuccess(Func func, bool inUI = false) { return Chain(new KUITask(TaskExecutor.Param(func, TaskExecutor.OptionHelper(false, true, inUI)), false)); diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs index 3148295..8d339fb 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/FeatureOutOfOffice.cs @@ -103,7 +103,7 @@ namespace Acacia.Features.OutOfOffice } } - private void StoreOOFSettings(ZPushAccount account, ActiveSync.SettingsOOF settings) + internal void StoreOOFSettings(ZPushAccount account, ActiveSync.SettingsOOF settings) { account.SetFeatureData(this, "OOF", settings); if (_button != null) @@ -115,141 +115,21 @@ namespace Acacia.Features.OutOfOffice ZPushAccount account = Watcher.CurrentZPushAccount(); if (account != null) { - try - { - // Fetch the current status - ActiveSync.SettingsOOF settings; - - try - { - settings = ProgressDialog.Execute("OOFGet", - (ct) => - { - using (ZPushConnection con = new ZPushConnection(account, ct)) - return con.Execute(new ActiveSync.SettingsOOFGet()); - } - ); - } - catch (System.Exception e) - { - Logger.Instance.Warning(this, "Exception getting OOF state: {0}", e); - if (MessageBox.Show( - Properties.Resources.OOFGet_Failed, - Properties.Resources.OOFGet_Title, - MessageBoxButtons.OKCancel, - MessageBoxIcon.Error - ) != DialogResult.OK) - { - return; - } - else - { - // Initialise default settings - settings = new ActiveSync.SettingsOOF(); - settings.Message = new ActiveSync.OOFMessage[3]; - } - } - - // Store them for later use - StoreOOFSettings(account, settings); - - // Show the dialog - ShowOOFDialog(account, settings); - } - catch(System.Exception e) - { - Logger.Instance.Warning(this, "Exception: {0}", e); - } + // Show the dialog, let it fetch the settings + ShowOOFDialog(account, null); } } + /// + /// Shows the OOF dialog. + /// + /// The account. + /// The setttings, or null, in which case the settings will be retrieved private void ShowOOFDialog(ZPushAccount account, ActiveSync.SettingsOOF settings) { - // Show dialog - if (new OutOfOfficeDialog(this, account, settings).ShowDialog() != DialogResult.OK) - return; - - try - { - // Store settings - ActiveSync.SettingsOOF actualSettings = ProgressDialog.Execute("OOFSet", - (ct) => - { - using (ZPushConnection connection = new ZPushConnection(account, ct)) - { - // Set the OOF state. This always seems to return ok, so we fetch the settings - // again, to see what happend - connection.Execute(new ActiveSync.SettingsOOFSet(settings)); - - // Fetch the OOF state - return connection.Execute(new ActiveSync.SettingsOOFGet()); - } - } - ); - - // Store them for later use - StoreOOFSettings(account, actualSettings); - - // Check what happened - string message; - MessageBoxIcon messageIcon; - if (settings.State == ActiveSync.OOFState.Disabled) - { - // Tried to disable. - if (actualSettings.State != ActiveSync.OOFState.Disabled) - { - // It's an error if its not actually disabled - message = Properties.Resources.OOFSet_DisableFailed; - messageIcon = MessageBoxIcon.Error; - } - else - { - // All good - message = Properties.Resources.OOFSet_Disabled; - messageIcon = MessageBoxIcon.Information; - } - } - else if (actualSettings.State == ActiveSync.OOFState.Disabled) - { - // It's an error if the state is set to disabled when we tried to enable - message = Properties.Resources.OOFSet_EnableFailed; - messageIcon = MessageBoxIcon.Error; - } - else - { - // All good - if (actualSettings.State == ActiveSync.OOFState.EnabledTimeBased) - { - message = string.Format(Properties.Resources.OOFSet_EnabledTimeBased, - actualSettings.From, actualSettings.Till); - } - else - { - message = Properties.Resources.OOFSet_Enabled; - } - messageIcon = MessageBoxIcon.Information; - - // It's okay if the state is not the same, but it deserves a message - if (actualSettings.State != settings.State) - { - message = Properties.Resources.OOFSet_DifferentState + message; - messageIcon = MessageBoxIcon.Warning; - } - } - - Logger.Instance.Debug(this, "OOF state updated: {0}, {1}", message, messageIcon); - MessageBox.Show(message, - Properties.Resources.OOFSet_Title, - MessageBoxButtons.OK, - messageIcon - ); - } - catch (System.Exception e) - { - ErrorUtil.HandleErrorNew(this, "Exception in OOFSet", e, - Properties.Resources.OOFSet_Title, Properties.Resources.OOFSet_Failed); - } + OutOfOfficeDialog dialog = new OutOfOfficeDialog(this, account, settings); + dialog.ShowDialog(); } /// diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.Designer.cs index f2ac927..ee2551a 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.Designer.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.Designer.cs @@ -29,9 +29,11 @@ private void InitializeComponent() { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(OutOfOfficeDialog)); - this.tableGlobal = new System.Windows.Forms.TableLayoutPanel(); + this._layout = new System.Windows.Forms.TableLayoutPanel(); + this._busyHider = new Acacia.Controls.KBusyHider(); + this._layoutForm = new System.Windows.Forms.TableLayoutPanel(); this.chkEnable = new System.Windows.Forms.CheckBox(); - this.tableDates = new System.Windows.Forms.TableLayoutPanel(); + this._layoutDates = new System.Windows.Forms.TableLayoutPanel(); this.radioNoTime = new System.Windows.Forms.RadioButton(); this.radioTime = new System.Windows.Forms.RadioButton(); this.dateFrom = new System.Windows.Forms.DateTimePicker(); @@ -43,24 +45,38 @@ this.tableTextEntry = new System.Windows.Forms.TableLayoutPanel(); this.labelBody = new System.Windows.Forms.Label(); this.textBody = new System.Windows.Forms.TextBox(); - this.flowButtons = new System.Windows.Forms.FlowLayoutPanel(); - this.btnCancel = new System.Windows.Forms.Button(); - this.btnSave = new System.Windows.Forms.Button(); - this.tableGlobal.SuspendLayout(); - this.tableDates.SuspendLayout(); + this._buttons = new Acacia.Controls.KDialogButtons(); + this._layout.SuspendLayout(); + this._busyHider.SuspendLayout(); + this._layoutForm.SuspendLayout(); + this._layoutDates.SuspendLayout(); this.groupTextEntry.SuspendLayout(); this.tableTextEntry.SuspendLayout(); - this.flowButtons.SuspendLayout(); this.SuspendLayout(); // - // tableGlobal + // _layout // - resources.ApplyResources(this.tableGlobal, "tableGlobal"); - this.tableGlobal.Controls.Add(this.chkEnable, 0, 0); - this.tableGlobal.Controls.Add(this.tableDates, 0, 1); - this.tableGlobal.Controls.Add(this.groupTextEntry, 0, 2); - this.tableGlobal.Controls.Add(this.flowButtons, 0, 3); - this.tableGlobal.Name = "tableGlobal"; + resources.ApplyResources(this._layout, "_layout"); + this._layout.Controls.Add(this._busyHider, 0, 0); + this._layout.Controls.Add(this._buttons, 0, 1); + this._layout.Name = "_layout"; + // + // _busyHider + // + this._busyHider.Busy = false; + this._busyHider.BusyText = null; + this._busyHider.Cancellation = null; + this._busyHider.Controls.Add(this._layoutForm); + resources.ApplyResources(this._busyHider, "_busyHider"); + this._busyHider.Name = "_busyHider"; + // + // _layoutForm + // + resources.ApplyResources(this._layoutForm, "_layoutForm"); + this._layoutForm.Controls.Add(this.chkEnable, 0, 0); + this._layoutForm.Controls.Add(this._layoutDates, 0, 1); + this._layoutForm.Controls.Add(this.groupTextEntry, 0, 2); + this._layoutForm.Name = "_layoutForm"; // // chkEnable // @@ -69,23 +85,23 @@ this.chkEnable.UseVisualStyleBackColor = true; this.chkEnable.CheckedChanged += new System.EventHandler(this.chkEnable_CheckedChanged); // - // tableDates + // _layoutDates // - resources.ApplyResources(this.tableDates, "tableDates"); - this.tableDates.Controls.Add(this.radioNoTime, 0, 0); - this.tableDates.Controls.Add(this.radioTime, 0, 1); - this.tableDates.Controls.Add(this.dateFrom, 1, 1); - this.tableDates.Controls.Add(this.timeFrom, 2, 1); - this.tableDates.Controls.Add(this.labelTill, 0, 2); - this.tableDates.Controls.Add(this.dateTill, 1, 2); - this.tableDates.Controls.Add(this.timeTill, 2, 2); - this.tableDates.Name = "tableDates"; + resources.ApplyResources(this._layoutDates, "_layoutDates"); + this._layoutDates.Controls.Add(this.radioNoTime, 0, 0); + this._layoutDates.Controls.Add(this.radioTime, 0, 1); + this._layoutDates.Controls.Add(this.dateFrom, 1, 1); + this._layoutDates.Controls.Add(this.timeFrom, 2, 1); + this._layoutDates.Controls.Add(this.labelTill, 0, 2); + this._layoutDates.Controls.Add(this.dateTill, 1, 2); + this._layoutDates.Controls.Add(this.timeTill, 2, 2); + this._layoutDates.Name = "_layoutDates"; // // radioNoTime // resources.ApplyResources(this.radioNoTime, "radioNoTime"); this.radioNoTime.Checked = true; - this.tableDates.SetColumnSpan(this.radioNoTime, 3); + this._layoutDates.SetColumnSpan(this.radioNoTime, 3); this.radioNoTime.Name = "radioNoTime"; this.radioNoTime.TabStop = true; this.radioNoTime.UseVisualStyleBackColor = true; @@ -128,6 +144,7 @@ this.timeTill.Format = System.Windows.Forms.DateTimePickerFormat.Custom; this.timeTill.Name = "timeTill"; this.timeTill.ShowUpDown = true; + this.timeTill.ValueChanged += new System.EventHandler(this.timeTill_ValueChanged); // // groupTextEntry // @@ -153,73 +170,60 @@ this.textBody.AcceptsReturn = true; resources.ApplyResources(this.textBody, "textBody"); this.textBody.Name = "textBody"; + this.textBody.TextChanged += new System.EventHandler(this.textBody_TextChanged); // - // flowButtons + // _buttons // - resources.ApplyResources(this.flowButtons, "flowButtons"); - this.flowButtons.Controls.Add(this.btnCancel); - this.flowButtons.Controls.Add(this.btnSave); - this.flowButtons.Name = "flowButtons"; - // - // btnCancel - // - resources.ApplyResources(this.btnCancel, "btnCancel"); - this.btnCancel.DialogResult = System.Windows.Forms.DialogResult.Cancel; - this.btnCancel.Name = "btnCancel"; - this.btnCancel.UseVisualStyleBackColor = true; - // - // btnSave - // - resources.ApplyResources(this.btnSave, "btnSave"); - this.btnSave.DialogResult = System.Windows.Forms.DialogResult.OK; - this.btnSave.Name = "btnSave"; - this.btnSave.UseVisualStyleBackColor = true; + resources.ApplyResources(this._buttons, "_buttons"); + this._buttons.ButtonSize = null; + this._buttons.Cancellation = null; + this._buttons.HasApply = true; + this._buttons.IsDirty = false; + this._buttons.Name = "_buttons"; + this._buttons.Apply += new System.EventHandler(this._buttons_Apply); // // OutOfOfficeDialog // - this.AcceptButton = this.btnSave; resources.ApplyResources(this, "$this"); this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.CancelButton = this.btnCancel; - this.Controls.Add(this.tableGlobal); - this.MaximizeBox = false; - this.MinimizeBox = false; + this.BusyHider = this._busyHider; + this.Controls.Add(this._layout); + this.DialogButtons = this._buttons; this.Name = "OutOfOfficeDialog"; - this.ShowInTaskbar = false; - this.SizeGripStyle = System.Windows.Forms.SizeGripStyle.Show; - this.FormClosed += new System.Windows.Forms.FormClosedEventHandler(this.OutOfOfficeDialog_FormClosed); - this.tableGlobal.ResumeLayout(false); - this.tableGlobal.PerformLayout(); - this.tableDates.ResumeLayout(false); - this.tableDates.PerformLayout(); + this.DirtyFormClosing += new System.Windows.Forms.FormClosingEventHandler(this.OutOfOfficeDialog_DirtyFormClosing); + this.Shown += new System.EventHandler(this.OutOfOfficeDialog_Shown); + this._layout.ResumeLayout(false); + this._layout.PerformLayout(); + this._busyHider.ResumeLayout(false); + this._layoutForm.ResumeLayout(false); + this._layoutForm.PerformLayout(); + this._layoutDates.ResumeLayout(false); + this._layoutDates.PerformLayout(); this.groupTextEntry.ResumeLayout(false); this.groupTextEntry.PerformLayout(); this.tableTextEntry.ResumeLayout(false); this.tableTextEntry.PerformLayout(); - this.flowButtons.ResumeLayout(false); - this.flowButtons.PerformLayout(); this.ResumeLayout(false); } #endregion - - private System.Windows.Forms.TableLayoutPanel tableGlobal; + private System.Windows.Forms.TableLayoutPanel _layout; + private Controls.KDialogButtons _buttons; + private System.Windows.Forms.TableLayoutPanel _layoutForm; private System.Windows.Forms.CheckBox chkEnable; + private System.Windows.Forms.TableLayoutPanel _layoutDates; private System.Windows.Forms.RadioButton radioNoTime; - private System.Windows.Forms.GroupBox groupTextEntry; - private System.Windows.Forms.FlowLayoutPanel flowButtons; - private System.Windows.Forms.Button btnCancel; - private System.Windows.Forms.Button btnSave; - private System.Windows.Forms.TableLayoutPanel tableDates; private System.Windows.Forms.RadioButton radioTime; private System.Windows.Forms.DateTimePicker dateFrom; + private System.Windows.Forms.DateTimePicker timeFrom; + private System.Windows.Forms.Label labelTill; private System.Windows.Forms.DateTimePicker dateTill; + private System.Windows.Forms.DateTimePicker timeTill; + private System.Windows.Forms.GroupBox groupTextEntry; private System.Windows.Forms.TableLayoutPanel tableTextEntry; private System.Windows.Forms.Label labelBody; private System.Windows.Forms.TextBox textBody; - private System.Windows.Forms.DateTimePicker timeFrom; - private System.Windows.Forms.DateTimePicker timeTill; - private System.Windows.Forms.Label labelTill; + private Controls.KBusyHider _busyHider; } } \ No newline at end of file diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.cs index 9f483dc..5b8a7e6 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.cs @@ -1,4 +1,6 @@ -/// Copyright 2016 Kopano b.v. + +using Acacia.Controls; +/// 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,10 +15,10 @@ /// along with this program.If not, see. /// /// Consult LICENSE file for details - using Acacia.UI; using Acacia.Utils; using Acacia.ZPush; +using Acacia.ZPush.Connect; using System; using System.Collections.Generic; using System.ComponentModel; @@ -31,17 +33,24 @@ using System.Windows.Forms; namespace Acacia.Features.OutOfOffice { - public partial class OutOfOfficeDialog : KopanoDialog + public partial class OutOfOfficeDialog : KDialogNew { + private readonly FeatureOutOfOffice _feature; + private readonly ZPushAccount _account; private ActiveSync.SettingsOOF _settings; - private readonly bool _haveTimes; + private bool _haveTimes; + /// /// Set if an old date is fetched from the settings. In this case, the date limit is relaxed to allow setting it. /// - private readonly bool _haveOldDate; + private bool _haveOldDate; - public OutOfOfficeDialog(FeatureOutOfOffice owner, ZPushAccount account, ActiveSync.SettingsOOF settings) + #region Init + + public OutOfOfficeDialog(FeatureOutOfOffice feature, ZPushAccount account, ActiveSync.SettingsOOF settings) { + this._feature = feature; + this._account = account; this._settings = settings; InitializeComponent(); @@ -66,16 +75,33 @@ namespace Acacia.Features.OutOfOffice // Enable controls chkEnable_CheckedChanged(chkEnable, null); radioTime_CheckedChanged(radioTime, null); + } + private void OutOfOfficeDialog_Shown(object sender, EventArgs e) + { + if (_settings == null) + { + // If the settings are not yet available, load them + LoadSettings(); + } + else + { + // Otherwise initialise them now + InitSettings(); + } + } + + private void InitSettings() + { // Hide time options, only if it is known that these are not supported _haveTimes = _settings.SupportsTimes != false; if (!_haveTimes) { - tableDates.Visible = false; + _layoutDates.Visible = false; } // Load settings - switch(owner.GetEffectiveState(settings)) + switch(_feature.GetEffectiveState(_settings)) { case ActiveSync.OOFState.Disabled: chkEnable.Checked = false; @@ -88,95 +114,61 @@ namespace Acacia.Features.OutOfOffice chkEnable.Checked = true; radioTime.Checked = true; - _haveOldDate = settings.Till.Value.CompareTo(DateTime.Today) <= 0; - dateFrom.Value = settings.From.Value; - timeFrom.Value = settings.From.Value; + _haveOldDate = _settings.Till.Value.CompareTo(DateTime.Today) <= 0; + dateFrom.Value = _settings.From.Value; + timeFrom.Value = _settings.From.Value; - dateTill.Value = settings.Till.Value; - timeTill.Value = settings.Till.Value; + dateTill.Value = _settings.Till.Value; + timeTill.Value = _settings.Till.Value; break; } - textBody.Text = settings.Message[(int)ActiveSync.OOFTarget.Internal]?.Message; + textBody.Text = _settings.Message[(int)ActiveSync.OOFTarget.Internal]?.Message; // Set up limits SetTillTimeLimit(); } + #endregion + + #region Event handlers + private void chkEnable_CheckedChanged(object sender, EventArgs e) { - tableDates.Enabled = chkEnable.Checked; + _layoutDates.Enabled = chkEnable.Checked; groupTextEntry.Enabled = chkEnable.Checked; + CheckDirty(); } private void radioTime_CheckedChanged(object sender, EventArgs e) { dateFrom.Enabled = timeFrom.Enabled = radioTime.Checked; dateTill.Enabled = timeTill.Enabled = radioTime.Checked; + CheckDirty(); } - private void OutOfOfficeDialog_FormClosed(object sender, FormClosedEventArgs e) - { - // Save the settings - _settings.From = null; - _settings.Till = null; - - if (chkEnable.Checked) - { - if (radioNoTime.Checked || !_haveTimes) - { - _settings.State = ActiveSync.OOFState.Enabled; - } - else - { - _settings.State = ActiveSync.OOFState.EnabledTimeBased; - _settings.From = GetDateTime(dateFrom, timeFrom); - _settings.Till = GetDateTime(dateTill, timeTill); - } - } - else - { - _settings.State = ActiveSync.OOFState.Disabled; - } - - // Always set the message, so it's stored - string message = textBody.Text; - for (int i = 0; i < 3; ++i) - { - _settings.Message[i] = new ActiveSync.OOFMessage(); - _settings.Message[i].Message = message; - } - } - - private DateTime GetDateTime(DateTimePicker dateControl, DateTimePicker timeControl) - { - DateTime date = dateControl.Value; - DateTime time = timeControl.Value; - DateTime combined = new DateTime(date.Year, date.Month, date.Day); - combined = combined.Add(time.TimeOfDay); - return combined; - } - - #region Date/Time checking - private void dateFrom_ValueChanged(object sender, EventArgs e) { SetTillTimeLimit(); + CheckDirty(); } private void timeFrom_ValueChanged(object sender, EventArgs e) { SetTillTimeLimit(); + CheckDirty(); } private void dateTill_ValueChanged(object sender, EventArgs e) { SetTillTimeLimit(); + CheckDirty(); } private void timeTill_ValueChanged(object sender, EventArgs e) { SetTillTimeLimit(); + CheckDirty(); } private void SetTillTimeLimit() @@ -195,6 +187,212 @@ namespace Acacia.Features.OutOfOffice } } + private void textBody_TextChanged(object sender, EventArgs e) + { + CheckDirty(); + } + + private void CheckDirty() + { + ActiveSync.SettingsOOF settings = GetSettings(); + _buttons.IsDirty = _settings != null && !_settings.Equals(settings); + } + + private void OutOfOfficeDialog_DirtyFormClosing(object sender, FormClosingEventArgs e) + { + // Require confirmation before closing a dirty form + e.Cancel = MessageBox.Show(Properties.Resources.OOF_Unsaved_Changes, + Text, + MessageBoxButtons.YesNo, + MessageBoxIcon.Question + ) != DialogResult.Yes; + } + + #endregion + + #region Settings + + private ActiveSync.SettingsOOF GetSettings() + { + ActiveSync.SettingsOOF settings = new ActiveSync.SettingsOOF(true); + + if (chkEnable.Checked) + { + if (radioNoTime.Checked || !_haveTimes) + { + settings.State = ActiveSync.OOFState.Enabled; + } + else + { + settings.State = ActiveSync.OOFState.EnabledTimeBased; + settings.From = GetDateTime(dateFrom, timeFrom); + settings.Till = GetDateTime(dateTill, timeTill); + } + } + else + { + settings.State = ActiveSync.OOFState.Disabled; + } + + // Always set the message, so it's stored + string message = textBody.Text; + for (int i = 0; i < 3; ++i) + { + settings.Message[i] = new ActiveSync.OOFMessage(); + settings.Message[i].Message = message; + } + + return settings; + } + + private DateTime GetDateTime(DateTimePicker dateControl, DateTimePicker timeControl) + { + DateTime date = dateControl.Value; + DateTime time = timeControl.Value; + DateTime combined = new DateTime(date.Year, date.Month, date.Day); + combined = combined.Add(time.TimeOfDay); + return combined; + } + + #endregion + + #region Load and save + + private void LoadSettings() + { + BusyText = Properties.Resources.OOFGet_Label; + KUITask + .New((ctx) => + { + using (ZPushConnection con = new ZPushConnection(_account, ctx.CancellationToken)) + { + _settings = con.Execute(new ActiveSync.SettingsOOFGet()); + } + }) + .OnSuccess(InitSettings, true) + .OnError((e) => + { + Logger.Instance.Warning(this, "Exception getting OOF state: {0}", e); + if (MessageBox.Show( + Properties.Resources.OOFGet_Failed, + Properties.Resources.OOFGet_Title, + MessageBoxButtons.OKCancel, + MessageBoxIcon.Error + ) != DialogResult.OK) + { + DialogResult = DialogResult.Cancel; + } + else + { + // Initialise default settings + _settings = new ActiveSync.SettingsOOF(true); + InitSettings(); + } + }) + .Start(this) + ; + } + + private void _buttons_Apply(object sender, EventArgs e) + { + BusyText = Properties.Resources.OOFSet_Label; + ActiveSync.SettingsOOF currentSettings = GetSettings(); + KUITask + .New((ctx) => + { + using (ZPushConnection connection = new ZPushConnection(_account, ctx.CancellationToken)) + { + // Set the OOF state. This always seems to return ok, so we fetch the settings + // again, to see what happend + connection.Execute(new ActiveSync.SettingsOOFSet(currentSettings)); + + // Fetch the OOF state + return connection.Execute(new ActiveSync.SettingsOOFGet()); + } + }) + .OnSuccess((appliedSettings) => + { + // Store them for later use + _feature.StoreOOFSettings(_account, appliedSettings); + + // Check what happened + string message; + MessageBoxIcon messageIcon; + if (currentSettings.State == ActiveSync.OOFState.Disabled) + { + // Tried to disable. + if (appliedSettings.State != ActiveSync.OOFState.Disabled) + { + // It's an error if its not actually disabled + message = Properties.Resources.OOFSet_DisableFailed; + messageIcon = MessageBoxIcon.Error; + } + else + { + // All good + message = Properties.Resources.OOFSet_Disabled; + messageIcon = MessageBoxIcon.Information; + } + } + else if (appliedSettings.State == ActiveSync.OOFState.Disabled) + { + // It's an error if the state is set to disabled when we tried to enable + message = Properties.Resources.OOFSet_EnableFailed; + messageIcon = MessageBoxIcon.Error; + } + else + { + // All good + if (appliedSettings.State == ActiveSync.OOFState.EnabledTimeBased) + { + message = string.Format(Properties.Resources.OOFSet_EnabledTimeBased, + appliedSettings.From, appliedSettings.Till); + } + else + { + message = Properties.Resources.OOFSet_Enabled; + } + messageIcon = MessageBoxIcon.Information; + + // It's okay if the state is not the same, but it deserves a message + if (appliedSettings.State != currentSettings.State) + { + message = Properties.Resources.OOFSet_DifferentState + message; + messageIcon = MessageBoxIcon.Warning; + } + } + + Logger.Instance.Debug(this, "OOF state updated: {0}, {1}", message, messageIcon); + MessageBox.Show(message, + Properties.Resources.OOFSet_Title, + MessageBoxButtons.OK, + messageIcon + ); + + if (messageIcon == MessageBoxIcon.Information) + { + // All good, close the dialog + _buttons.IsDirty = false; + DialogResult = DialogResult.OK; + } + else + { + // There was a problem, initialise the dialog to what's set. + _settings = appliedSettings; + InitSettings(); + CheckDirty(); + } + + }, true) + .OnError((x) => + { + ErrorUtil.HandleErrorNew(this, "Exception in OOFSet", x, + Properties.Resources.OOFSet_Title, Properties.Resources.OOFSet_Failed); + }) + .Start(this) + ; + } + #endregion } } diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.resx index dc89762..d58dd9c 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.resx +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Features/OutOfOffice/OutOfOfficeDialog.resx @@ -117,26 +117,29 @@ System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - Top, Bottom, Left, Right - - + + 1 + + 1 True + + + NoControl + - 2, 2 + 6, 5 - 2, 2, 2, 2 + 6, 5, 6, 5 - 197, 17 + 515, 36 0 @@ -151,21 +154,21 @@ System.Windows.Forms.CheckBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableGlobal + _layoutForm 0 - + Top, Bottom, Left, Right - + True - + GrowAndShrink - + 3 @@ -174,14 +177,17 @@ True + + NoControl + - 18, 2 + 48, 5 - 18, 2, 2, 2 + 48, 5, 6, 5 - 109, 17 + 279, 36 1 @@ -196,7 +202,7 @@ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 0 @@ -207,14 +213,17 @@ True + + NoControl + - 18, 23 + 48, 51 - 18, 2, 2, 2 + 48, 5, 6, 5 - 45, 20 + 108, 38 2 @@ -229,19 +238,19 @@ System.Windows.Forms.RadioButton, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 1 - 67, 23 + 170, 51 - 2, 2, 2, 2 + 6, 5, 6, 5 - 128, 20 + 334, 38 3 @@ -253,7 +262,7 @@ System.Windows.Forms.DateTimePicker, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 2 @@ -262,13 +271,13 @@ HH:mm - 199, 23 + 516, 51 - 2, 2, 2, 2 + 6, 5, 6, 5 - 66, 20 + 170, 38 4 @@ -280,7 +289,7 @@ System.Windows.Forms.DateTimePicker, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 3 @@ -291,14 +300,17 @@ True + + NoControl + - 33, 45 + 89, 94 - 33, 0, 2, 0 + 89, 0, 6, 0 - 30, 24 + 69, 48 7 @@ -316,19 +328,19 @@ System.Windows.Forms.Label, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 4 - 67, 47 + 170, 99 - 2, 2, 2, 2 + 6, 5, 6, 5 - 128, 20 + 334, 38 5 @@ -340,7 +352,7 @@ System.Windows.Forms.DateTimePicker, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 5 @@ -349,13 +361,13 @@ HH:mm - 199, 47 + 516, 99 - 2, 2, 2, 2 + 6, 5, 6, 5 - 66, 20 + 170, 38 6 @@ -367,40 +379,40 @@ System.Windows.Forms.DateTimePicker, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableDates + _layoutDates 6 - - 0, 21 + + 0, 46 - + 0, 0, 0, 0 - + 3 - - 323, 69 + + 863, 142 - + 1 - - tableDates + + _layoutDates - + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - tableGlobal + + _layoutForm - + 1 - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="radioNoTime" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="radioTime" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="dateFrom" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="timeFrom" Row="1" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="labelTill" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="dateTill" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="timeTill" Row="2" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0,AutoSize,0,Absolute,15" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings> + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="radioNoTime" Row="0" RowSpan="1" Column="0" ColumnSpan="3" /><Control Name="radioTime" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="dateFrom" Row="1" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="timeFrom" Row="1" RowSpan="1" Column="2" ColumnSpan="1" /><Control Name="labelTill" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="dateTill" Row="2" RowSpan="1" Column="1" ColumnSpan="1" /><Control Name="timeTill" Row="2" RowSpan="1" Column="2" ColumnSpan="1" /></Controls><Columns Styles="AutoSize,0,AutoSize,0,AutoSize,0,Absolute,41" /><Rows Styles="AutoSize,0,AutoSize,0,AutoSize,0" /></TableLayoutSettings> Top, Bottom, Left, Right @@ -423,14 +435,17 @@ True + + NoControl + - 2, 5 + 6, 12 - 2, 5, 2, 0 + 6, 12, 6, 0 - 286, 13 + 756, 32 2 @@ -454,10 +469,10 @@ Top, Bottom, Left, Right - 2, 20 + 6, 49 - 2, 2, 2, 2 + 6, 5, 6, 5 True @@ -466,7 +481,7 @@ Vertical - 309, 128 + 823, 358 8 @@ -484,16 +499,16 @@ 1 - 3, 11 + 9, 26 - 2, 2, 2, 2 + 6, 5, 6, 5 2 - 313, 150 + 835, 412 0 @@ -511,19 +526,19 @@ 0 - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelBody" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBody" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,Percent,100,Absolute,20,Absolute,20" /></TableLayoutSettings> + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="labelBody" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="textBody" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,Percent,100,Absolute,48,Absolute,48" /></TableLayoutSettings> - 2, 92 + 6, 193 - 2, 2, 2, 2 + 6, 5, 6, 5 - 2, 2, 2, 2 + 6, 5, 6, 5 - 319, 167 + 851, 453 2 @@ -535,148 +550,151 @@ System.Windows.Forms.GroupBox, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - tableGlobal + _layoutForm 2 - - Top, Bottom, Left, Right + + Fill - - True + + 0, 0 - - 256, 2 + + 6, 5, 6, 5 - - 2, 2, 2, 2 + + 3 - - 61, 27 + + 863, 651 - - 10 - - - Cancel - - - btnCancel - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - flowButtons - - - 0 - - - True - - - 191, 2 - - - 2, 2, 2, 2 - - - 61, 27 - - - 9 - - - Save - - - btnSave - - - System.Windows.Forms.Button, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - flowButtons - - + 1 - - RightToLeft + + _layoutForm - - 2, 263 - - - 2, 2, 2, 2 - - - 319, 31 - - - 3 - - - flowButtons - - - System.Windows.Forms.FlowLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - - tableGlobal - - - 3 - - - 4, 4 - - - 2, 2, 2, 2 - - - 4 - - - 323, 296 - - - 0 - - - tableGlobal - - + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 - - $this + + _busyHider - + 0 - - <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="chkEnable" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="tableDates" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="groupTextEntry" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="flowButtons" Row="3" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100,AutoSize,0,Absolute,16" /></TableLayoutSettings> + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="chkEnable" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_layoutDates" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="groupTextEntry" Row="2" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="AutoSize,0,AutoSize,0,Percent,100,Absolute,20" /></TableLayoutSettings> + + + Fill + + + 3, 3 + + + 863, 651 + + + 3 + + + + + + _busyHider + + + Acacia.Controls.KBusyHider, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + + + _layout + + + 0 + + + True + + + GrowAndShrink + + + Fill + + + 6, 662 + + + 6, 5, 6, 5 + + + 857, 54 + + + 4 + + + _buttons + + + Acacia.Controls.KDialogButtons, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + + + _layout + + + 1 + + + Fill + + + 10, 9 + + + 2 + + + 869, 721 + + + 1 + + + _layout + + + System.Windows.Forms.TableLayoutPanel, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + $this + + + 0 + + + <?xml version="1.0" encoding="utf-16"?><TableLayoutSettings><Controls><Control Name="_busyHider" Row="0" RowSpan="1" Column="0" ColumnSpan="1" /><Control Name="_buttons" Row="1" RowSpan="1" Column="0" ColumnSpan="1" /></Controls><Columns Styles="Percent,100" /><Rows Styles="Percent,100,AutoSize,0,Absolute,20" /></TableLayoutSettings> True - 6, 13 + 16, 31 - 333, 310 + 889, 739 - 2, 2, 2, 2 + 6, 5, 6, 5 - 348, 345 + 884, 727 - 4, 4, 4, 4 + 10, 9, 10, 9 CenterParent @@ -688,6 +706,6 @@ OutOfOfficeDialog - Acacia.UI.KopanoDialog, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null + Acacia.Controls.KDialogNew, Kopano, Version=0.1.0.0, Culture=neutral, PublicKeyToken=null \ No newline at end of file diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs index 8b28773..76429bb 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.Designer.cs @@ -187,6 +187,15 @@ namespace Acacia.Properties { } } + /// + /// Looks up a localized string similar to There are unsaved changes. Do you really want to to discard these?. + /// + internal static string OOF_Unsaved_Changes { + get { + return ResourceManager.GetString("OOF_Unsaved_Changes", resourceCulture); + } + } + /// /// Looks up a localized string similar to Unable to retrieve Out of Office settings. You can still enable or disable Out of Office, but applying the settings might fail.. /// diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx index 7070fd8..93f2739 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Properties/Resources.resx @@ -454,4 +454,7 @@ Signatures + + There are unsaved changes. Do you really want to to discard these? + \ No newline at end of file diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/KopanoDialog.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/KopanoDialog.cs index a2e3fbf..c96d86f 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/KopanoDialog.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/UI/KopanoDialog.cs @@ -23,6 +23,7 @@ using System.Windows.Forms; namespace Acacia.UI { + // TODO: remove when Debug and SettingsDialog are rewritten. public class KopanoDialog : Form { public KopanoDialog() diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ActiveSync.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ActiveSync.cs index 69934f4..625f62c 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ActiveSync.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/ActiveSync.cs @@ -92,6 +92,21 @@ namespace Acacia.Utils public class OOFMessage { public string Message { get; set; } + + public override bool Equals(object obj) + { + if (obj is string) + return Message.Equals(obj); + else if (obj is OOFMessage) + return Message.Equals(((OOFMessage)obj).Message); + else + return false; + } + + public override int GetHashCode() + { + return Message.GetHashCode(); + } } public class SettingsOOF : Response @@ -99,9 +114,54 @@ namespace Acacia.Utils public OOFState State { get; set; } public DateTime? From { get; set; } public DateTime? Till { get; set; } - public OOFMessage[] Message {get; set;} + public OOFMessage[] Message {get; private set;} public bool? SupportsTimes { get; set; } + public SettingsOOF() + { + + } + + public SettingsOOF(bool initMessage) + { + if (initMessage) + Message = new OOFMessage[3]; + } + + public override bool Equals(object obj) + { + SettingsOOF rhs = obj as SettingsOOF; + if (rhs == null) + return false; + + if (State != rhs.State) + return false; + + // Check the times only if they are used + if (State == OOFState.EnabledTimeBased) + { + if (!From.Equals(rhs.From)) + return false; + if (!Till.Equals(rhs.Till)) + return false; + } + + // Check the messages only if they are used + if (State != OOFState.Disabled) + { + // Only one entry is effectively used + if (!Message[0].NullSafeEquals(rhs.Message[0])) + return false; + } + + return true; + } + + public override int GetHashCode() + { + return base.GetHashCode(); + } + protected override void ParseResponseBody(ActiveSync.RequestBase request, ZPushConnection.Response response) { // Check capabilities diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/CollectionUtil.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/CollectionUtil.cs index 81747a6..2f506ba 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/CollectionUtil.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/CollectionUtil.cs @@ -24,6 +24,28 @@ namespace Acacia.Utils { public static class CollectionUtil { + public static bool EnumEquals(this IEnumerable first, IEnumerable second) + { + if (first == second) return true; + if ((first == null) || (second == null)) return false; + + var i1 = first.GetEnumerator(); + var i2 = second.GetEnumerator(); + + while (i1.MoveNext()) + { + if (!i2.MoveNext()) + return false; + + if (!i1.Current.NullSafeEquals(i2.Current)) + return false; + } + + if (i2.MoveNext()) + return false; + return true; + } + /// /// Checks if both collections contain the same elements, not necessarily in the same order. /// diff --git a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs index fdbcca5..84b17c1 100644 --- a/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs +++ b/src/AcaciaZPushPlugin/AcaciaZPushPlugin/Utils/Util.cs @@ -29,7 +29,7 @@ namespace Acacia.Utils { public static class Util { - public static bool NullSafeEquals(ObjType a, ObjType b) + public static bool NullSafeEquals(this ObjType a, ObjType b) { if (System.Object.ReferenceEquals(a, b)) {