private void SyncStalled(ZPushAccount account) { ThisAddIn.Instance.InUI(() => { if (MessageBox.Show(ThisAddIn.Instance.Window, string.Format(Properties.Resources.SyncState_Stalled_Body, account.DisplayName), string.Format(Properties.Resources.SyncState_Stalled_Caption, account.DisplayName), MessageBoxButtons.YesNo, MessageBoxIcon.Error ) == DialogResult.Yes) { IRestarter restarter = ThisAddIn.Instance.Restarter(); restarter.ResyncAccounts(account); restarter.Restart(); } }); }
public SharedFoldersDialog(FeatureSharedFolders feature, ZPushAccount account, SyncId initial = null) { // If this is a shared store, open the account it's a share for, with the request account as the initial if (account.ShareFor != null) { _initialAccount = account; account = account.ShareForAccount; } this._account = account; this._feature = feature; this._featureSendAs = ThisAddIn.Instance.GetFeature <FeatureSendAs>(); this._folders = feature.Manage(account); this._initialSyncId = initial; InitializeComponent(); // TODO: make a specialised class out of this this.kTreeFolders.Images = new OutlookImageList( "NewFolder", // Other "JunkEmailMarkAsNotJunk", // Inbox "GoDrafts", // Drafts "RecycleBin", // WasteBasket "ReceiveMenu", // SentMail "NewFolder", // Outbox "ShowTaskPage", // Task "ShowAppointmentPage", // Appointment "ShowContactPage", // Contact "NewNote", // Note "ShowJournalPage", // Journal "LastModifiedBy" // Store ).Images; // Set the check manager kTreeFolders.CheckManager = new ShareCheckManager(); // Add the email address to the title Text = string.Format(Text, account.Account.SmtpAddress); // Set up options ShowOptions(new KTreeNode[0]); // Set up user selector gabLookup.GAB = FeatureGAB.FindGABForAccount(account); }
/// <summary> /// Invoked by AccountWatcher on start-up to notify of the oof status. /// </summary> public void OnOOFSettings(ZPushAccount account, ActiveSync.SettingsOOF oof) { // Store them for later use StoreOOFSettings(account, oof); // Show a message if OOF is enabled if (IsOOFEnabled(oof)) { if (MessageBox.Show( string.Format(Properties.Resources.OOFStartup_Message, account.Account.SmtpAddress), Properties.Resources.OOFStartup_Title, MessageBoxButtons.YesNo, MessageBoxIcon.Question ) == DialogResult.Yes) { ShowOOFDialog(account, oof); } } }
private void ZPushChannelAvailable(IFolder folder) { using (IStore store = folder.GetStore()) { Logger.Instance.Debug(this, "Z-Push channel available: {0} on {1}", folder, store.DisplayName); ZPushAccount account = Watcher.Accounts.GetAccount(folder); if (account != null) { account.LinkedGABFolder(folder); RegisterGABAccount(account, folder); } else { Logger.Instance.Warning(this, "Z-Push channel account not found: {0} on {1}", folder, store.DisplayName); } Logger.Instance.Debug(this, "Z-Push channel available done"); } }
private void AccountDiscovered(ZPushAccount zpush) { Logger.Instance.Info(this, "Account discovered: {0}", zpush.DisplayName); _domains.Add(zpush.Account.DomainName); zpush.ConfirmedChanged += (z) => { Logger.Instance.Debug(this, "Account discovered and confirmed: {0} -> {1}: {2}", zpush.DisplayName, zpush.Confirmed, zpush.GABFolder); if (zpush.Confirmed == ZPushAccount.ConfirmationType.IsZPush && !string.IsNullOrEmpty(zpush.GABFolder)) { Logger.Instance.Debug(this, "Account discovered, listening for folder: {0} -> {1}: {2}", zpush.DisplayName, zpush.Confirmed, zpush.GABFolder); // Set up the Z-Push channel listener ZPushChannel channel = ZPushChannels.Get(this, zpush, zpush.GABFolder); channel.Available += ZPushChannelAvailable; channel.Start(); } }; }
private void CheckSyncState(ZPushAccount account) { // TODO: we probably want one invocation for all accounts using (ZPushConnection connection = account.Connect()) using (ZPushWebServiceDevice deviceService = connection.DeviceService) { // Fetch DeviceDetails details = deviceService.Execute(new GetDeviceDetailsRequest()); if (details != null) { bool wasSyncing = false; // Create or update session SyncSession session = account.GetFeatureData <SyncSession>(this, null); if (session == null) { session = new SyncSession(this, account); } else { wasSyncing = session.IsSyncing; } session.Add(details); // Store with the account account.SetFeatureData(this, null, session); if (wasSyncing != session.IsSyncing) { // Sync state has changed, update the schedule Watcher.Sync.SetTaskSchedule(_task, account, session.IsSyncing ? CheckPeriodSync : (TimeSpan?)null); } } } // Update the total for all accounts UpdateTotalSyncState(); // Check for stalls CheckSyncStalled(account); }
internal IRecipient FindSendAsSender(ZPushAccount zpush, GABUser user) { // First try a simple resolve, this will work if the username is unique IRecipient recip = ThisAddIn.Instance.ResolveRecipient(user.UserName); if (recip != null) { // If it's resolved, we're good. Otherwise dispose and continue if (recip.IsResolved) { return(recip); } else { recip.Dispose(); } } // Search through GAB to find the user if (GABLookup) { GABHandler handler = FeatureGAB.FindGABForAccount(zpush); if (handler != null && handler.Contacts != null) { // Look for the email address. If found, use the account associated with the GAB using (ISearch <IContactItem> search = handler.Contacts.Search <IContactItem>()) { search.AddField("urn:schemas:contacts:customerid").SetOperation(SearchOperation.Equal, user.UserName); using (IContactItem result = search.SearchOne()) { if (result != null) { // Try resolving by email return(ThisAddIn.Instance.ResolveRecipient(result.Email1Address)); } } } } } return(null); }
private void OpenWebApp() { ZPushAccount account = Watcher.CurrentZPushAccount(); if (account == null) { return; } // Get the url string url = AutoDiscover(account); if (url == null) { return; } // Open the browser System.Diagnostics.Process.Start(url); }
private void CheckUpgradesGabSynced(GABHandler gab) { ThisAddIn.Instance.InUI(() => { ZPushAccount account = gab.ActiveAccount; ICollection <SharedFolder> shares = _sharedFolders.GetCachedFolders(account); if (shares == null) { using (SharedFoldersManager manager = _sharedFolders.Manage(account)) { shares = manager.GetCurrentShares(null); } } if (shares != null) { UpdateSendAsAddresses(account, shares, true); } }, false); }
private void MailEvents_ItemSend(IMailItem item, ref bool cancel) { using (IStore store = item.GetStore()) { ZPushAccount zpush = Watcher.Accounts.GetAccount(store); if (zpush != null) { string address = item.SenderEmailAddress; if (address != null && address != zpush.Account.SmtpAddress) { Logger.Instance.Trace(this, "SendAs: {0}: {1}", address, item.SenderName); item.SetProperty(Constants.ZPUSH_SEND_AS, address); if (item.SenderName != null) { item.SetProperty(Constants.ZPUSH_SEND_AS_NAME, item.SenderName); } } } } }
public SharedFolder GetSharedFolder(IFolder folder) { if (folder == null) { return(null); } // Check that we can get the id SyncId folderId = folder.SyncId; Logger.Instance.Trace(this, "GetSharedFolder1: {0}", folderId); if (folderId == null || !folderId.IsCustom) { return(null); } // Get the ZPush account ZPushAccount account = Watcher.Accounts.GetAccount(folder); Logger.Instance.Trace(this, "GetSharedFolder2: {0}", account); if (account == null) { return(null); } // Get the shared folders Dictionary <SyncId, SharedFolder> shared = account.GetFeatureData <Dictionary <SyncId, SharedFolder> >(this, KEY_SHARES); Logger.Instance.Trace(this, "GetSharedFolder3: {0}", shared?.Count); if (shared == null) { return(null); } SharedFolder share = null; shared.TryGetValue(folderId, out share); Logger.Instance.Trace(this, "GetSharedFolder4: {0}", share); return(share); }
/// <summary> /// Fetches the signatures for the account. /// </summary> /// <param name="account">The account.</param> /// <returns>The signature hash</returns> private string FetchSignatures(ZPushAccount account) { Logger.Instance.Debug(this, "Fetching signatures for account {0}", account); using (ZPushConnection connection = account.Connect()) using (ZPushWebServiceInfo infoService = connection.InfoService) { Logger.Instance.Trace(this, "Executing request: {0}", account); GetSignatures result = infoService.Execute(new GetSignaturesRequest()); Logger.Instance.Trace(this, "Executed request: {0} -> {1}", account, result); // Store the signatures Dictionary <object, string> fullNames = new Dictionary <object, string>(); using (ISignatures signatures = ThisAddIn.Instance.GetSignatures()) { Logger.Instance.Trace(this, "Storing signatures: {0}", account); foreach (Signature signature in result.all.Values) { Logger.Instance.Trace(this, "Storing signature: {0}: {1}", account, signature); string name = StoreSignature(signatures, account, signature); Logger.Instance.Trace(this, "Stored signature: {0}: {1}: {2}", account, name, signature); fullNames.Add(signature.id, name); } } // Set default signatures if available and none are set if (!string.IsNullOrEmpty(result.new_message) && ShouldSetSignature(account.SignatureNewMessage)) { Logger.Instance.Trace(this, "Setting signature new message: {0}: {1}", account, result.new_message); account.SignatureNewMessage = fullNames[result.new_message]; } if (!string.IsNullOrEmpty(result.replyforward_message) && ShouldSetSignature(account.SignatureReplyForwardMessage)) { Logger.Instance.Trace(this, "Setting signature reply message: {0}: {1}", account, result.replyforward_message); account.SignatureReplyForwardMessage = fullNames[result.replyforward_message]; } Logger.Instance.Trace(this, "Signature synced: {0}: {1}", account, result.hash); return(result.hash); } }
private IRecipient FindSendAsSender(ZPushAccount zpush, IFolder folder) { SyncId syncId = folder.SyncId; if (syncId != null) { string address = zpush.GetSendAsAddress(syncId); if (address == null) { // Check if it should have an address SharedFolder shared = _sharedFolders?.GetSharedFolder(folder); if (shared?.FlagSendAsOwner == true) { // See if we can get it now address = FindSendAsAddress(zpush, shared); if (address == null) { // Should have it, error MessageBox.Show(ThisAddIn.Instance.Window, Properties.Resources.SharedFolders_SendAsFailed_Label, Properties.Resources.SharedFolders_SendAsFailed_Title, MessageBoxButtons.OK, MessageBoxIcon.Error ); } } } if (address != null) { IRecipient resolved = ThisAddIn.Instance.ResolveRecipient(address); if (resolved != null) { return(resolved); } } } return(null); }
public SyncStateDialog(FeatureSyncState feature, ZPushAccount currentAccount) { InitializeComponent(); // Ensure these are in sync with ResyncOption _syncButtons = new Button[] { buttonGAB, buttonSignatures, buttonServerData, buttonFullResync }; this._feature = feature; comboAccounts.SelectedIndex = 0; // Add the accounts foreach (ZPushAccount account in ThisAddIn.Instance.Watcher.Accounts.GetAccounts()) { comboAccounts.Items.Add(account); } if (currentAccount != null) { comboAccounts.SelectedItem = currentAccount; } }
private void AddUserFolders(GABUser user, ZPushAccount wholeStore, Dictionary <BackendId, SharedFolder> currentShares, bool select) { if (user == null) { return; } // If the user is already fetched, reuse the node StoreTreeNode node; if (!_userFolders.TryGetValue(user, out node)) { if (!user.HasFullName) { // Try to fill in the full name user = gabLookup.LookupExact(user.UserName); } string sendAsAddress = _featureSendAs?.FindSendAsAddress(_account, user); // Add the node node = new StoreTreeNode(_folders, gabLookup.GAB, user, sendAsAddress, user.DisplayName, currentShares ?? new Dictionary <BackendId, SharedFolder>(), wholeStore != null, wholeStore?.ShowReminders == true); node.DirtyChanged += UserSharesChanged; node.CheckStateChanged += WholeStoreShareChanged; _userFolders.Add(user, node); kTreeFolders.RootNodes.Add(node); } if (select) { FocusNode(node, !_folders.SupportsWholeStore); } }
/// <summary> /// Creates an instance with a dedicated connection. /// </summary> /// <param name="account">The account which will be connected to</param> public SharedFoldersAPI(ZPushAccount account) : this(account.Connect(), true) { }
public bool SupportsSyncTimeFrame(ZPushAccount account) { return(account?.ZPushVersion?.IsAtLeast(2, 4) == true); }
internal void UpdateSendAsAddresses(ZPushAccount zpush, ICollection <SharedFolder> shares) { UpdateSendAsAddresses(zpush, shares, false); }
private void Watcher_AccountDiscovered(ZPushAccount account) { // Start an autodiscover for each account AutoDiscover(account); }
public void OpenShare(ZPushAccount account, GABUser store) { _shares.Add(new KeyValuePair <ZPushAccount, GABUser>(account, store)); }
private void dialogButtons_Apply(object sender, EventArgs e) { int folderCount = 0; // Check if all fields are properly set foreach (StoreTreeNode storeNode in _userFolders.Values) { // Check totals folderCount += storeNode.CurrentShares.Count(); // Check modified folders if (storeNode.IsDirty) { foreach (SharedFolder folder in storeNode.CurrentShares) { // Check if the send-as address has been resolved (or entered) correctly if (folder.FlagSendAsOwner && string.IsNullOrWhiteSpace(folder.SendAsAddress)) { // Find the tree node KTreeNode folderNode = storeNode.FindNode(folder); if (folderNode != null) { // See if we can obtain it from a parent TryInitSendAsAddressParent(folderNode as FolderTreeNode); if (!string.IsNullOrWhiteSpace(folder.SendAsAddress)) { continue; } // If the node is already selected, explicitly warn about the send-as address // Otherwise, selecting it will pop up the warning if (folderNode.IsSelected) { TryInitSendAsAddress(); } else { FocusNode(folderNode, false); } } return; } } } } // Check total number of folders if (folderCount >= _feature.MaxFolderCount) { MessageBox.Show(ThisAddIn.Instance.Window, Properties.Resources.SharedFolders_TooManyFolders_Body, Properties.Resources.SharedFolders_TooManyFolders_Title, MessageBoxButtons.OK, MessageBoxIcon.Error ); // And don't apply anything return; } BusyText = Properties.Resources.SharedFolders_Applying_Label; KUITask.New((ctx) => { // We reuse the same busy indicationg for all calls. A count is kept to ensure it's removed. ApplyState state = new ApplyState(); foreach (StoreTreeNode storeNode in _userFolders.Values) { // Check modified folders if (storeNode.IsDirty) { ctx.AddBusy(1); ++state.folders; // Check removed shares _folders.RemoveSharesForStore(storeNode.User, storeNode.RemovedShares); // Set shares _folders.SetSharesForStore(storeNode.User, storeNode.CurrentShares, ctx.CancellationToken); } // And modified stores if (storeNode.IsWholeStoreDirty) { state.stores.Add(storeNode); } } return(state); }) .OnSuccess((ctx, state) => { // Update UI state foreach (StoreTreeNode storeNode in _userFolders.Values) { if (storeNode.IsDirty) { storeNode.ChangesApplied(); } } ctx.AddBusy(-state.folders); List <ZPushAccount> syncAdditional = new List <ZPushAccount>(); // Handle stores if (state.stores.Count > 0) { List <StoreTreeNode> add = new List <StoreTreeNode>(); // Remove any unshared store foreach (StoreTreeNode store in state.stores) { if (store.WantShare) { // Check if it must be added if (!store.IsShared) { add.Add(store); } // Update reminders for existing stores if (store.ShowReminders != store.ShowRemindersInitial) { ZPushAccount storeAccount = store.WholeStoreAccount; if (storeAccount != null) { storeAccount.ShowReminders = store.ShowReminders; syncAdditional.Add(storeAccount); // Update UI state store.ShowRemindersInitial = store.ShowReminders; WholeStoreShareChanged(store); } } continue; } else { // Remove it _feature.RemoveSharedStore(_account, store.User); store.IsShared = false; WholeStoreShareChanged(store); } } // Check for any new stores if (add.Count > 0) { bool restart = MessageBox.Show(ThisAddIn.Instance.Window, Properties.Resources.SharedFolders_WholeStoreRestart_Body, Properties.Resources.SharedFolders_WholeStoreRestart_Title, MessageBoxButtons.OKCancel, MessageBoxIcon.Information ) == DialogResult.OK; // Reset state. Also do this when restarting, to avoid warning message about unsaved changes foreach (StoreTreeNode node in state.stores) { node.WantShare = node.IsShared; } if (!restart) { return; } // Restart IRestarter restarter = ThisAddIn.Instance.Restarter(); restarter.CloseWindows = true; foreach (StoreTreeNode node in state.stores) { restarter.OpenShare(_account, node.User, node.ShowReminders); } restarter.Restart(); } // Update UI state foreach (StoreTreeNode storeNode in _userFolders.Values) { storeNode.ChangesApplied(); } CheckDirty(); } // Sync accounts foreach (ZPushAccount account in syncAdditional) { _feature.Sync(account); } if (state.folders != 0) { // Sync account _feature.Sync(_account); // Show success ShowCompletion(Properties.Resources.SharedFolders_Applying_Success); } }, true) .OnError((x) => { ErrorUtil.HandleErrorNew(typeof(FeatureSharedFolders), "Exception applying shared folders for account {0}", x, Properties.Resources.SharedFolders_Applying_Title, Properties.Resources.SharedFolders_Applying_Failure, _account.DisplayName); }) .Start(this); }
public void Sync(ZPushAccount account) { account.Account.SendReceive(new AcaciaTask(null, this, "SyncShares", () => SyncShares(account))); }
internal SharedFoldersManager Manage(ZPushAccount account) { return(new SharedFoldersManager(this, account)); }
public void ManageFolder(ZPushAccount account, SyncId folderId) { new SharedFoldersDialog(this, account, folderId).ShowDialog(); }
public Request(ZPushAccount account, CancellationToken cancel) { this._account = account; this._cancel = cancel; this._client = CreateClient(account); }
public SyncSession(FeatureSyncState feature, ZPushAccount account) { this._feature = feature; this._account = account; }
/// <summary> /// Returns a SyncState for the specified account, or all accounts. /// </summary> /// <param name="account">The account, or null to fetch a SyncState for all accounts</param> public SyncState GetSyncState(ZPushAccount account) { return(new SyncStateImpl(this, account == null ? Watcher.Accounts.GetAccounts().ToArray() : new ZPushAccount[] { account })); }
public SharedFoldersManager(FeatureSharedFolders featureSharedFolders, ZPushAccount account) { this._feature = featureSharedFolders; this._account = account; _api = new SharedFoldersAPI(account); }
private void Watcher_AccountDiscovered(ZPushAccount account) { account.ConfirmedChanged += Account_ConfirmedChanged; }
public void AddAccount(ZPushAccount account, IFolder folder) { _accounts.Add(account); _accountFolders.Add(folder); }