public void RemoveSharedStore(ZPushAccount account, GABUser shareUser)
        {
            // Find the store
            Logger.Instance.Trace(this, "Request to remove shared store: {0} - {1}", account, shareUser.UserName);
            ZPushAccount share = account.FindSharedAccount(shareUser.UserName);

            if (share == null)
            {
                Logger.Instance.Warning(this, "Shared store not found: {0} - {1}", account, shareUser.UserName);
                return;
            }

            Logger.Instance.Trace(this, "Removing shared store: {0} - {1}", account, share);
            try
            {
                string path = share.Account.BackingFilePath;
                ThisAddIn.Instance.Stores.RemoveStore(share.Account.Store);

                // Clean up the .ost
                // TODO: this always fails

                /*if (path != null && path.EndsWith(".ost"))
                 * {
                 *  Logger.Instance.Trace(this, "Removing .ost: {0}", path);
                 *
                 *  System.IO.File.Delete(path);
                 * }*/
            }
            catch (Exception e)
            {
                Logger.Instance.Error(this, "Error removing shared store: {0}: {1}", share, e);
            }
        }
Пример #2
0
        public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string text,
                             Dictionary <BackendId, SharedFolder> currentFolders)
            :
            base(text)
        {
            this._initialShares = currentFolders;
            this._feature       = folders.Feature;
            this._gab           = gab;
            this._user          = user;

            // Create an empty current state. When loading the nodes, the shares will be added. This has the benefit of
            // cleaning up automatically any obsolote shares.
            this._currentShares = new Dictionary <BackendId, SharedFolder>();

            ChildLoader = new UserFolderLoader(this, folders, user);
            ChildLoader.ReloadOnCloseOpen = true;
            HasCheckBox = false;

            // TODO: better icons, better way of handling this
            ImageIndex = user == GABUser.USER_PUBLIC ? 0 : 11;

            // Reloader
            _reloader           = new KAnimator();
            _reloader.Animation = Properties.Resources.TreeLoading;
            _reloader.Visible   = false;
            _reloader.Click    += (s, e) =>
            {
                ChildLoader.Reload();
            };
            Control = _reloader;
        }
        public string FindSendAsAddress(ZPushAccount zpush, GABUser user)
        {
            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())
                    {
                        Logger.Instance.Trace(this, "GAB Search for send-as {0}: {1}", zpush, result);
                        if (result != null)
                        {
                            // Try resolving by email
                            Logger.Instance.Trace(this, "Resolving send-as by email address {0}: {1}", user.UserName, result.Email1Address);
                            return(result.Email1Address);
                        }
                    }
                }
            }
            else
            {
                Logger.Instance.Warning(this, "GAB handler not found for account: {0}", zpush);
            }

            Logger.Instance.Warning(this, "Unable to resolve send-as: {0}", user.UserName);
            return(null);
        }
Пример #4
0
 public void SetCurrentShares(GABUser store, ICollection <SharedFolder> shares, CancellationToken?cancel = null)
 {
     using (ZPushWebServiceDevice deviceService = _connection.DeviceService)
     {
         deviceService.Execute(new AdditionalFolderSetListRequest(store, shares));
     }
 }
Пример #5
0
 public void OpenShare(ZPushAccount account, GABUser store, bool showReminders)
 {
     _shares.Add(new Share()
     {
         account = account, store = store, showReminders = showReminders
     });
 }
Пример #6
0
        private void AddUserFolders(GABUser user, 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);
                }

                // Add the node
                node = new StoreTreeNode(_folders, gabLookup.GAB,
                                         user, user.DisplayName, currentShares ?? new Dictionary <BackendId, SharedFolder>());
                node.DirtyChanged += UserSharesChanged;
                _userFolders.Add(user, node);
                kTreeFolders.RootNodes.Add(node);
            }

            if (select)
            {
                FocusNode(node);
            }
        }
 private string GetSecondLine(GABUser item)
 {
     if (item is NotFoundGABUser)
     {
         return(NotFoundText);
     }
     else
     {
         return(item.EmailAddress);
     }
 }
Пример #8
0
 public void RemoveSharesForStore(GABUser store, ICollection <SharedFolder> removed)
 {
     foreach (SharedFolder folder in removed)
     {
         if (folder.SyncId != null)
         {
             _account.SetSendAsAddress(folder.SyncId, null);
         }
         _account.SetSendAsAddress(folder.BackendId, null);
     }
 }
Пример #9
0
        /// <summary>
        /// Sets all shares for the specified store.
        /// </summary>
        public void SetSharesForStore(GABUser store, ICollection <SharedFolder> shares, CancellationToken?cancel)
        {
            // Make sure reminders are updated as soon as possible
            UpdateReminders(shares);
            _api.SetCurrentShares(store, shares, cancel);

            // Commit changes
            if (_query != null)
            {
                _query.Commit();
            }
        }
        protected override void OnDrawItem(DrawItemEventArgs e)
        {
            GABUser item = (GABUser)e.Item;

            // Draw the background
            if (e.State == DrawItemState.Selected)
            {
                // If the item is selected, we don't want the separating border to get selected too.
                // So draw the normal background in the border area
                Rectangle rect = e.Bounds;
                rect.Y      = rect.Bottom - BorderPadding.Vertical - BorderThickness;
                rect.Height = BorderPadding.Vertical + BorderThickness;
                new System.Windows.Forms.DrawItemEventArgs(e.Graphics, e.Font, rect, e.Index, DrawItemState.None).DrawBackground();

                // And the selected background in the item area.
                rect.Y      = e.Bounds.Y;
                rect.Height = e.Bounds.Height - BorderPadding.Vertical - BorderThickness;
                new System.Windows.Forms.DrawItemEventArgs(e.Graphics, e.Font, rect, e.Index, DrawItemState.Selected).DrawBackground();
            }
            else
            {
                e.DrawBackground();
            }

            // Get the sizes
            Size nameSize  = TextRenderer.MeasureText(e.Graphics, item.FullName, Font);
            Size loginSize = TextRenderer.MeasureText(e.Graphics, item.UserName, Font);
            Size emailSize = TextRenderer.MeasureText(e.Graphics, item.EmailAddress, Font);

            // Draw the full name top-left
            Point pt = e.Bounds.TopLeft();

            pt.Y += ItemPadding.Top;
            pt.X += ItemPadding.Left;
            TextRenderer.DrawText(e.Graphics, item.FullName, Font, pt, e.ForeColor);

            // Draw the username top-right
            pt.X = e.Bounds.Right - loginSize.Width - ItemPadding.Right;
            TextRenderer.DrawText(e.Graphics, item.UserName, Font, pt, e.ForeColor);

            // Draw the email below
            pt.Y += Math.Max(nameSize.Height, loginSize.Height) + NameSpacing.Height;
            pt.X  = e.Bounds.X + ItemPadding.Left;

            TextRenderer.DrawText(e.Graphics, GetSecondLine(item), Font, pt, e.ForeColor);

            // Draw a separator line
            if (e.Index < DisplayItemCount - 1)
            {
                int lineY = e.Bounds.Bottom - 1 - BorderThickness - BorderPadding.Bottom;
                e.Graphics.DrawLine(Pens.LightGray, BorderPadding.Left, lineY, e.Bounds.Width - BorderPadding.Right, lineY);
            }
        }
Пример #11
0
        public StoreTreeNode(SharedFoldersManager folders, GABHandler gab, GABUser user, string sendAsAddress, string text,
                             Dictionary <BackendId, SharedFolder> currentFolders, bool isShared, bool showRemindersWholeStore)
            :
            base(text)
        {
            this._initialShares = currentFolders;
            // Patch in send as address
            foreach (SharedFolder share in _initialShares.Values)
            {
                if (string.IsNullOrWhiteSpace(share.SendAsAddress))
                {
                    share.SendAsAddress = sendAsAddress;
                }
            }
            this._feature       = folders.Feature;
            this._featureSendAs = ThisAddIn.Instance.GetFeature <FeatureSendAs>();
            this._account       = folders.Account;
            this._gab           = gab;
            this._user          = user;
            this._sendAsAddress = sendAsAddress;
            this.IsReadOnly     = false;
            this._isShared      = isShared;

            // Create an empty current state. When loading the nodes, the shares will be added. This has the benefit of
            // cleaning up automatically any obsolote shares.
            this._currentShares = new Dictionary <BackendId, SharedFolder>();

            ChildLoader = new UserFolderLoader(this, folders, user);
            ChildLoader.ReloadOnCloseOpen = true;
            // Can only open the whole store if it's supported and there's an email address, as that's needed to open it
            // However, if it's already opened, we can remove it without the email address
            HasCheckBox = folders.SupportsWholeStore && (!string.IsNullOrWhiteSpace(user.EmailAddress) || isShared);
            ApplyReadOnly(this, IsReadOnly);

            // TODO: better icons, better way of handling this
            ImageIndex = user == GABUser.USER_PUBLIC ? 0 : 11;

            // Reloader
            _reloader           = new KAnimator();
            _reloader.Animation = Properties.Resources.TreeLoading;
            _reloader.Visible   = false;
            _reloader.Click    += (s, e) =>
            {
                ChildLoader.Reload();
            };
            Control = _reloader;

            // Set up sharing
            WantShare            = isShared;
            ShowRemindersInitial = showRemindersWholeStore;
            ShowReminders        = ShowRemindersInitial;
        }
        protected override void OnMeasureItem(MeasureItemEventArgs e)
        {
            GABUser item = (GABUser)e.Item;

            Size nameSize  = TextRenderer.MeasureText(e.Graphics, item.FullName, Font);
            Size loginSize = TextRenderer.MeasureText(e.Graphics, item.UserName, Font);
            Size emailSize = TextRenderer.MeasureText(e.Graphics, GetSecondLine(item), Font);

            e.ItemWidth = Math.Max(emailSize.Width, nameSize.Width + loginSize.Width + NameSpacing.Width) +
                          ItemPadding.Horizontal;
            e.ItemHeight = emailSize.Height + Math.Max(nameSize.Height, loginSize.Height) +
                           ItemPadding.Vertical +
                           NameSpacing.Height +
                           BorderThickness + BorderPadding.Vertical;
        }
Пример #13
0
        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);
        }
Пример #14
0
        public ICollection <AvailableFolder> GetUserFolders(GABUser user)
        {
            using (ZPushWebServiceInfo infoService = _connection.InfoService)
            {
                // Fetch raw folder list
                List <AvailableFolder> folders = infoService.Execute(new ListUserFoldersRequest(user.UserName));

                // Construct the tree
                Dictionary <SyncId, AvailableFolder> foldersByServerId = folders.ToDictionary((x) => x.ServerId);
                List <AvailableFolder> rootNodes = new List <AvailableFolder>();
                foreach (AvailableFolder folder in folders)
                {
                    AvailableFolder parent;

                    // Add to root nodes or parent
                    if (folder.ParentId.IsNone)
                    {
                        rootNodes.Add(folder);
                        parent = null;
                    }
                    else if (!foldersByServerId.ContainsKey(folder.ParentId))
                    {
                        // Ignore the node if the parent is not available
                        Logger.Instance.Warning(this, "Missing parent node: {0}", folder.ParentId);
                        continue;
                    }
                    else
                    {
                        parent = foldersByServerId[folder.ParentId];
                        parent.Children.Add(folder);
                    }

                    folder.FixupSoap(parent, user);
                }

                // Return the root nodes
                return(rootNodes);
            }
        }
Пример #15
0
        /// <summary>
        /// Sets all shares for the specified store.
        /// </summary>
        public void SetSharesForStore(GABUser store, ICollection <SharedFolder> shares, CancellationToken?cancel)
        {
            // Make sure reminders are updated as soon as possible
            UpdateReminders(shares);

            // Store the send-as addresses
            foreach (SharedFolder share in shares)
            {
                if (share.CanSendAs)
                {
                    _account.SetSendAsAddress(share.BackendId, share.FlagSendAsOwner ? share.SendAsAddress : null);
                }
            }

            // Update the shares
            _api.SetCurrentShares(store, shares, cancel);

            // Commit changes
            if (_query != null)
            {
                _query.Commit();
            }
        }
        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);
            }
        }
 protected override void OnSelectedItemChanged()
 {
     _selectedUser = (GABUser)SelectedItem?.Item;
     // If the tab key was used to select, the user wants to click open
     SelectedUserChanged?.Invoke(this, new SelectedUserEventArgs(_selectedUser, GetCommitSource() != CommitSource.KeyTab));
 }
Пример #18
0
 public ICollection <AvailableFolder> GetStoreFolders(GABUser store)
 {
     return(_api.GetUserFolders(store));
 }
Пример #19
0
 /// <summary>
 /// Fixes up data not serialised by soap.
 /// </summary>
 public void FixupSoap(AvailableFolder parent, GABUser store)
 {
     this.Parent = parent;
     this.Store  = store;
 }
Пример #20
0
 public AdditionalFolderSetListRequest(GABUser store, ICollection <SharedFolder> shares)
 {
     Parameters.Add("store", store.UserName);
     Parameters.Add("folders", shares);
 }
Пример #21
0
 public UserFolderLoader(StoreTreeNode parent, SharedFoldersManager folders, GABUser user) : base(parent)
 {
     this._folders = folders;
     this.User     = user;
 }
 public SelectedUserEventArgs(GABUser selectedUser, bool isChosen)
 {
     this.SelectedUser = selectedUser;
     this.IsChosen     = isChosen;
 }
Пример #23
0
 public void OpenShare(ZPushAccount account, GABUser store)
 {
     _shares.Add(new KeyValuePair <ZPushAccount, GABUser>(account, store));
 }
 protected override void OnTextChanged(EventArgs e)
 {
     base.OnTextChanged(e);
     _selectedUser = string.IsNullOrEmpty(Text) ? null : new GABUser(Text);
     SelectedUserChanged?.Invoke(this, new SelectedUserEventArgs(_selectedUser, false));
 }