public WriteNewMessageNotification(Account currentAccount, string subject, string textBody, string htmlBody, Dictionary<string, string> savedAttachments, Dictionary<string, string> cidAttachments)
 {
     CurrentAccount = currentAccount;
     Subject = "FW: " + subject;
     TextBody = textBody;
     HtmlBody = htmlBody;
     SavedAttachments = savedAttachments;
     CidAttachments = cidAttachments;
 }
        public AccountViewModel(Account account)
        {
            if (account == null)
            {
                throw new ArgumentNullException("account", "AccountViewModel constructor was expecting an Account object; received null.");
            }

            Account = account;
            MailboxViewModelTree = ConstructMailboxViewModelTree(Account.Mailboxes.ToList());

            Account.PropertyChanged += HandleModelPropertyChanged;
            Account.Mailboxes.CollectionChanged += HandleMailboxListChanged;
        }
        public bool DeleteAccount(Account account)
        {
            string error;
            bool success = DatabaseManager.DeleteAccount(account, out error);
            if (!success)
            {
                Error = error;
                return false;
            }

            Accounts.Remove(account);
            GlobalEventAggregator.Instance.GetEvent<AccountDeletedEvent>().Publish(account.AccountName);

            return true;
        }
        // Returns true if successfully added the account. False, otherwise.
        public bool AddAccount(Account account)
        {
            string error;
            bool success = DatabaseManager.InsertAccount(account, out error);
            if (success)
            {
                Accounts.Add(account);
                BeginSyncMailboxList(account);
                GlobalEventAggregator.Instance.GetEvent<NewAccountAddedEvent>().Publish(account);
            }
            else
            {
                Error = error;
            }

            return success;
        }
        // Updates the mailbox tree in the specified account with ones from the server.
        // Also updates the database to reflect the change.
        private void BeginSyncMailboxList(Account account)
        {
            Task.Factory.StartNew(() => {
                List<Mailbox> localMailboxes = DatabaseManager.GetMailboxes(account.AccountName);

                ImapClient imapClient = new ImapClient(account);
                if (imapClient.Connect())
                {
                    List<Mailbox> serverMailboxes = imapClient.ListMailboxes();

                    var comparer = new CompareMailbox();
                    var localNotServer = localMailboxes.Except(serverMailboxes, comparer).ToList();
                    var serverNotLocal = serverMailboxes.Except(localMailboxes, comparer).ToList();

                    if (localNotServer.Count > 0 || serverNotLocal.Count > 0)
                    {
                        account.Mailboxes.Clear();
                        account.Mailboxes.AddRange(serverMailboxes);

                        if (localNotServer.Count > 0)
                        {
                            DatabaseManager.DeleteMailboxes(localNotServer);
                        }
                        if (serverNotLocal.Count > 0)
                        {
                            DatabaseManager.InsertMailboxes(serverNotLocal);
                        }
                    }

                    imapClient.Disconnect();
                }

                while (!Common.Globals.BootStrapperLoaded)
                {
                    // We don't want to fire this event before the subscribers are ready.
                    // There must be a better way to handle these sort of things.
                    Thread.Sleep(50);
                }
                GlobalEventAggregator.Instance.GetEvent<MailboxListSyncFinishedEvent>().Publish(account);
            });
        }
 private void HandleAccountSelection(Account selectedAccount)
 {
     this.selectedAccount = selectedAccount;
 }
 private void HandleAccountAdded(Account obj)
 {
     RaiseCanExecuteChanged();
 }
 public SmtpClient(Account account, OutgoingEmail email)
 {
     Account = account;
     NewEmail = email;
 }
 public SmtpClient(Account account)
 {
     Account = account;
 }
 public WriteNewMessageNotification(Account currentAccount)
 {
     CurrentAccount = currentAccount;
 }
        private void HandleNewAccountAddedEvent(Account newAccount)
        {
            if (newAccount == null)
            {
                throw new ArgumentNullException("newAccount");
            }

            AccountViewModel newAccountViewModel = new AccountViewModel(newAccount);
            Application.Current.Dispatcher.Invoke(() =>
            {
                AccountViewModels.Add(newAccountViewModel);
            });
        }
 public ImapClient(Account account)
 {
     Account = account;
 }
        private void SyncExistingMessageHeaders(Account account, string mailboxName, ImapClient imapClientOnSelectedStatus, int firstUid, int lastUid)
        {
            Trace.WriteLine("SyncExistingMessageHeaders: Mailbox(" + mailboxName + "), UIDs(" + firstUid + ", " + lastUid + ")");

            // Decrement this at every exit point.
            openSyncOps.AddOrUpdate(account.AccountName, 1, (k, v) => v + 1);

            // Delete all messages that have been deleted from server.
            List<int> serverUids = new List<int>();
            bool searchSuccess = imapClientOnSelectedStatus.SearchUids("ALL", serverUids);
            if (searchSuccess)
            {
                List<string> keysToDelete = new List<string>();
                foreach (KeyValuePair<string, Message> entry in MessagesDico)
                {
                    Message msg = entry.Value;
                    if (msg.AccountName == account.AccountName &&
                        msg.MailboxPath == mailboxName &&
                        !serverUids.Contains(msg.Uid))
                    {
                        keysToDelete.Add(entry.Key);
                    }
                }

                List<Message> msgsDeleted = new List<Message>();
                foreach (string key in keysToDelete)
                {
                    Message msg = MessagesDico[key];
                    MessagesDico.Remove(key);
                    OnMessageRemoved(msg);
                    msgsDeleted.Add(msg);
                }

                DatabaseManager.DeleteMessages(msgsDeleted);
            }

            // Now synchronize the remaining messages.
            int messagesCount = lastUid - firstUid + 1;
            int downloadChunk = this.downloadChunkSize;
            int startUid = lastUid - downloadChunk + 1;
            int endUid = lastUid;

            while (endUid >= firstUid)
            {
                int abort = 0;
                if (abortLatches.TryGetValue(account.AccountName, out abort) && abort == 1)
                {
                    Trace.WriteLine("Aborting sync...");
                    openSyncOps.AddOrUpdate(account.AccountName, 0, (k, v) => v - 1);
                    return;
                }

                if (startUid < firstUid)
                {
                    startUid = firstUid;
                }
                List<Message> serverMsgs = imapClientOnSelectedStatus.FetchHeaders(startUid, endUid - startUid + 1, true);
                if (serverMsgs.Count > 0)
                {
                    List<Message> messagesAdded = new List<Message>();
                    foreach (Message serverMsg in serverMsgs)
                    {
                        Message localMsg;
                        if (MessagesDico.TryGetValue(serverMsg.UniqueKeyString, out localMsg))
                        {
                            // A local copy exists. Update its flags.
                            if (localMsg.FlagString != serverMsg.FlagString)
                            {
                                localMsg.FlagString = serverMsg.FlagString;
                                OnMessageModified(localMsg);
                            }
                        }
                        else
                        {
                            MessagesDico.Add(serverMsg.UniqueKeyString, serverMsg);
                            OnMessageAdded(serverMsg);
                            messagesAdded.Add(serverMsg);
                        }
                    }
                    DatabaseManager.StoreMessages(messagesAdded);
                }

                endUid = startUid - 1;
                startUid = endUid - downloadChunk + 1;
            }

            openSyncOps.AddOrUpdate(account.AccountName, 0, (k, v) => v - 1);
        }
        private void SyncNewMessageHeaders(Account account, string mailboxName, ImapClient imapClientOnSelectedStatus, int firstUid, int lastUid)
        {
            Trace.WriteLine("SyncNewMessageHeaders: Mailbox(" + mailboxName + "), UIDs(" + firstUid + ", " + lastUid + ")");

            // Decrement this at every exit point.
            openSyncOps.AddOrUpdate(account.AccountName, 1, (k, v) => v + 1);

            int messagesCount = lastUid - firstUid + 1;
            int downloadChunk = this.downloadChunkSize;
            int startUid = lastUid - downloadChunk + 1;
            int endUid = lastUid;

            while (endUid >= firstUid)
            {
                int abort = 0;
                if (abortLatches.TryGetValue(account.AccountName, out abort) && abort == 1)
                {
                    Trace.WriteLine("Aborting sync...");
                    openSyncOps.AddOrUpdate(account.AccountName, 0, (k, v) => v - 1);
                    return;
                }

                if (startUid < firstUid)
                {
                    startUid = firstUid;
                }
                List<Message> msgs = imapClientOnSelectedStatus.FetchHeaders(startUid, endUid - startUid + 1, true);
                if (msgs.Count > 0)
                {
                    foreach (Message msg in msgs)
                    {
                        if (!MessagesDico.ContainsKey(msg.UniqueKeyString))
                        {
                            MessagesDico.Add(msg.UniqueKeyString, msg);
                            OnMessageAdded(msg);
                        }
                    }
                    DatabaseManager.StoreMessages(msgs);
                }

                endUid = startUid - 1;
                startUid = endUid - downloadChunk + 1;
            }

            openSyncOps.AddOrUpdate(account.AccountName, 0, (k, v) => v - 1);
        }
        private void SyncMessage(Account account, string mailboxName)
        {
            int abort = 0;
            if (abortLatches.TryGetValue(account.AccountName, out abort) && abort == 1)
            {
                // Abort sync.
                return;
            }

            ImapClient imapClient = new ImapClient(account);
            if (!imapClient.Connect())
            {
                Trace.WriteLine(imapClient.Error);
                return;
            }

            ExamineResult status;
            bool readOnly = true;
            if (!imapClient.SelectMailbox(mailboxName, readOnly, out status))
            {
                Debug.WriteLine("MessageManager.SyncMessage(): Unable to select mailbox " + mailboxName + ".\n" + imapClient.Error);
                imapClient.Disconnect();
                return;
            }

            int localLargestUid = DatabaseManager.GetMaxUid(account.AccountName, mailboxName);

            // Download the recent message headers that have never been downloaded yet.
            int serverLargestUid = status.UidNext - 1;
            if (serverLargestUid > localLargestUid)
            {
                SyncNewMessageHeaders(account, mailboxName, imapClient, localLargestUid + 1, serverLargestUid);
            }

            // Sync changes to the existing message headers (flags, etc.).
            if (localLargestUid > 0)
            {
                SyncExistingMessageHeaders(account, mailboxName, imapClient, 1, localLargestUid);
            }

            imapClient.Disconnect();
        }
 // Syncs messages one mailbox at a time.
 private async void SyncMessagesMultipleMailboxes(Account account, List<string> mailboxNames)
 {
     foreach (string mailboxName in mailboxNames)
     {
         await Task.Run(() => { SyncMessage(account, mailboxName); });
     }
 }
        private void BeginSyncMessages(Account account)
        {
            Trace.WriteLine("BeginSyncMessages: " + account.AccountName);
            abortLatches.AddOrUpdate(account.AccountName, 0, (k, v) => v = 0);

            List<Mailbox> mailboxes = DatabaseManager.GetMailboxes(account.AccountName);

            for (int i = mailboxes.Count - 1; i >= 0; --i)
            {
                if (mailboxes[i].Flags.Contains(@"\Noselect"))
                {
                    mailboxes.RemoveAt(i);
                }
            }

            // Sync inbox immediately from a separate thread.
            foreach (Mailbox mailbox in mailboxes)
            {
                if (mailbox.MailboxName.ToLower() == "inbox")
                {
                    Task.Run(() => { SyncMessage(account, mailbox.DirectoryPath); });
                    BeginMonitor(account, mailbox.DirectoryPath);
                    mailboxes.Remove(mailbox);
                    break;
                }
            }

            // Sync the other mailboxes one at a time.
            List<string> mailboxNames = new List<string>();
            foreach (Mailbox mbox in mailboxes)
            {
                mailboxNames.Add(mbox.DirectoryPath);
            }
            SyncMessagesMultipleMailboxes(account, mailboxNames);
        }
        private void Submit()
        {
            if (AccountValidated)
            {
                Account account = new Account();
                account.AccountName = EmailAddress;
                account.EmailAddress = EmailAddress;
                account.ImapLoginName = LoginName;
                account.ImapLoginPassword = LoginPassword;
                account.ImapServerName = ImapServerName;
                account.ImapPortNumber = Convert.ToInt32(ImapPortString);
                account.SmtpLoginName = LoginName;
                account.SmtpLoginPassword = LoginPassword;
                account.SmtpServerName = SmtpServerName;
                account.SmtpPortNumber = Convert.ToInt32(SmtpPortString);

                AccountManager accountManager = AccountManager.Instance;
                bool success = accountManager.AddAccount(account);
                if (success)
                {
                    FinishInteraction();
                }
                else
                {
                    Message = accountManager.Error;
                }
            }
        }
        private void BeginMonitor(Account account, string mailboxName)
        {
            Trace.WriteLine("BeginMonitor " + account.AccountName);
            ImapClient imapClient = new ImapClient(account);
            if (!imapClient.Connect())
            {
                Debug.WriteLine(imapClient.Error);
                return;
            }

            imapClient.NewMessageAtServer += HandleNewMessageAtServer;
            imapClient.MessageDeletedAtServer += HandleMessageDeletedAtServer;
            imapClient.MessageSeenAtServer += HandleMessageSeenAtServer;
            imapClient.MessageUnseenAtServer += HandleMessageUnseenAtServer;
            imapClient.BeginMonitor(mailboxName);
        }
        private void HandleMailboxListSyncFinished(Account account)
        {
            // Don't change selection if an item is already selected.
            if (SelectedTreeViewItem != null)
            {
                return;
            }

            // Select the first mailbox.
            foreach (AccountViewModel accountVm in AccountViewModels)
            {
                if (accountVm.Account.AccountName == account.AccountName)
                {
                    Application.Current.Dispatcher.Invoke(() => {
                        if (accountVm.MailboxViewModelTree.Count > 0)
                        {
                            accountVm.MailboxViewModelTree[0].IsSelected = true;
                        }
                    });
                    break;
                }
            }
        }
 public NewAccountValidator(Account account)
 {
     Account = account;
 }
 private void HandleMailboxListSyncFinished(Account account)
 {
     BeginSyncMessages(account);
 }
        private void ValidateConnection()
        {
            int imapPortNumber = -1;
            int smtpPortNumber = -1;
            string numberPattern = @"^\d+$";
            Regex numberChecker = new Regex(numberPattern);
            if (numberChecker.IsMatch(ImapPortString))
            {
                imapPortNumber = Convert.ToInt32(ImapPortString);
                if (imapPortNumber >= 0 && imapPortNumber <= 65536)
                {
                    ImapPortStringValidated = true;
                }
            }

            if (numberChecker.IsMatch(SmtpPortString))
            {
                smtpPortNumber = Convert.ToInt32(SmtpPortString);
                if (smtpPortNumber >= 0 && smtpPortNumber <= 65536)
                {
                    SmtpPortStringValidated = true;
                }
            }

            if (AllInputValidated)
            {
                Account tempAccount = new Account()
                {
                    ImapServerName = ImapServerName,
                    ImapPortNumber = imapPortNumber,
                    ImapLoginName = LoginName,
                    ImapLoginPassword = LoginPassword,
                    SmtpServerName = SmtpServerName,
                    SmtpPortNumber = smtpPortNumber,
                    SmtpLoginName = LoginName,
                    SmtpLoginPassword = LoginPassword
                };

                NewAccountValidator validator = new NewAccountValidator(tempAccount);

                if (validator.Validate())
                {
                    AccountValidated = true;
                    Message = "Validated";
                }
                else
                {
                    AccountValidated = false;
                    ValidationFailed = true;
                    Message = validator.Error;
                }
            }
        }
 public MessageContentViewNotification(Account account, Mailbox mailbox, Message message)
 {
     SelectedAccount = account;
     SelectedMailbox = mailbox;
     SelectedMessage = message;
 }