15a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira/**
25a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * Copyright (c) 2012, Google Inc.
35a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira *
45a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * Licensed under the Apache License, Version 2.0 (the "License");
55a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * you may not use this file except in compliance with the License.
65a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * You may obtain a copy of the License at
75a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira *
85a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira *     http://www.apache.org/licenses/LICENSE-2.0
95a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira *
105a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * Unless required by applicable law or agreed to in writing, software
115a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * distributed under the License is distributed on an "AS IS" BASIS,
125a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
135a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * See the License for the specific language governing permissions and
145a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira * limitations under the License.
155a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira */
165a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereirapackage com.android.mail.compose;
175a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
185a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport android.content.Context;
1992551d057965689f1952faeb06763f0762bc717fMindy Pereiraimport android.text.TextUtils;
205a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport android.util.AttributeSet;
215a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport android.view.View;
225a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport android.widget.AdapterView;
235a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport android.widget.AdapterView.OnItemSelectedListener;
245a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport android.widget.Spinner;
255a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
265a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport com.android.mail.providers.Account;
27c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrookimport com.android.mail.providers.Message;
2892551d057965689f1952faeb06763f0762bc717fMindy Pereiraimport com.android.mail.providers.ReplyFromAccount;
295a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport com.android.mail.utils.AccountUtils;
301883b346928322a9f045bc5b7426ddcd6af9beb3Mindy Pereiraimport com.google.common.annotations.VisibleForTesting;
3162de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereiraimport com.google.common.collect.ImmutableList;
32e25b33e0251bf8b0d9d3616b30b1bb02856e4bb6Paul Westbrookimport com.google.common.collect.Lists;
335a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
345a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereiraimport java.util.List;
355a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
365a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereirapublic class FromAddressSpinner extends Spinner implements OnItemSelectedListener {
375a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    private List<Account> mAccounts;
3892551d057965689f1952faeb06763f0762bc717fMindy Pereira    private ReplyFromAccount mAccount;
39e25b33e0251bf8b0d9d3616b30b1bb02856e4bb6Paul Westbrook    private final List<ReplyFromAccount> mReplyFromAccounts = Lists.newArrayList();
405a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    private OnAccountChangedListener mAccountChangedListener;
415a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
425a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    public FromAddressSpinner(Context context) {
435a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        this(context, null);
445a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
455a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
465a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    public FromAddressSpinner(Context context, AttributeSet set) {
475a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        super(context, set);
485a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
495a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
5092551d057965689f1952faeb06763f0762bc717fMindy Pereira    public void setCurrentAccount(ReplyFromAccount account) {
515a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        mAccount = account;
525f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira        selectCurrentAccount();
535f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira    }
545f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira
555f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira    private void selectCurrentAccount() {
565f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira        if (mAccount == null) {
575f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira            return;
585f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira        }
5962de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        int currentIndex = 0;
6062de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        for (ReplyFromAccount acct : mReplyFromAccounts) {
6189bae5713b830ec1182073de22c3091d3613ac3eMindy Pereira            if (TextUtils.equals(mAccount.name, acct.name)
6289bae5713b830ec1182073de22c3091d3613ac3eMindy Pereira                    && TextUtils.equals(mAccount.address, acct.address)) {
635f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira                setSelection(currentIndex, true);
6462de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira                break;
6562de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira            }
6662de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira            currentIndex++;
6762de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        }
685a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
695a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
709a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira    public ReplyFromAccount getMatchingReplyFromAccount(String accountString) {
719a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira        if (!TextUtils.isEmpty(accountString)) {
729a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira            for (ReplyFromAccount acct : mReplyFromAccounts) {
73bb036ff794f022bba2f501e155ef9c412e0e452eTony Mantler                // TODO: Do not key off ReplyFromAccount.name b/11292541
749a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira                if (accountString.equals(acct.name)) {
759a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira                    return acct;
769a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira                }
779a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira            }
789a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira        }
799a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira        return null;
809a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira    }
819a42bb4f11c502dd5c2cf92249ac214a6c2f1a70Mindy Pereira
8292551d057965689f1952faeb06763f0762bc717fMindy Pereira    public ReplyFromAccount getCurrentAccount() {
835a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        return mAccount;
845a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
855a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
8662de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira    /**
8762de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira     * @param action Action being performed; if this is COMPOSE, show all
8862de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira     *            accounts. Otherwise, show just the account this was launched
8962de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira     *            with.
9062de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira     * @param currentAccount Account used to launch activity.
91c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook     * @param syncingAccounts
9262de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira     */
93c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook    public void initialize(int action, Account currentAccount, Account[] syncingAccounts,
94c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                Message refMessage) {
95c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook        final List<Account> accounts = AccountUtils.mergeAccountLists(mAccounts,
96c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                syncingAccounts, true /* prioritizeAccountList */);
9762de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        if (action == ComposeActivity.COMPOSE) {
98c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook            mAccounts = accounts;
9962de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        } else {
100c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook            // First assume that we are going to use the current account as the reply account
101c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook            Account replyAccount = currentAccount;
102c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook
103c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook            if (refMessage != null && refMessage.accountUri != null) {
104c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                // This is a reply or forward of a message access through the "combined" account.
105c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                // We want to make sure that the real account is in the spinner
106c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                for (Account account : accounts) {
107c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                    if (account.uri.equals(refMessage.accountUri)) {
108c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                        replyAccount = account;
109c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                        break;
110c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                    }
111c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook                }
112c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook            }
113c97ec3e157f1b2a30ebdc96ba9c6007f2f719aa6Paul Westbrook            mAccounts = ImmutableList.of(replyAccount);
11462de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        }
1155a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        initFromSpinner();
1165a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
1175a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
1181883b346928322a9f045bc5b7426ddcd6af9beb3Mindy Pereira    @VisibleForTesting
1191883b346928322a9f045bc5b7426ddcd6af9beb3Mindy Pereira    protected void initFromSpinner() {
1205a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        // If there are not yet any accounts in the cached synced accounts
1215a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        // because this is the first time mail was opened, and it was opened
12265b06f52e5b6336493388923be88bdd2ded4e1d1mindyp        // directly to the compose activity, don't bother populating the reply
1235a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        // from spinner yet.
1245a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        if (mAccounts == null || mAccounts.size() == 0) {
1255a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira            return;
1265a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        }
1275a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        FromAddressSpinnerAdapter adapter = new FromAddressSpinnerAdapter(getContext());
1285a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
129e25b33e0251bf8b0d9d3616b30b1bb02856e4bb6Paul Westbrook        mReplyFromAccounts.clear();
13092551d057965689f1952faeb06763f0762bc717fMindy Pereira        for (Account account : mAccounts) {
1311617481de7c1f9b8dfcd25ba9828e933cf9d5490Andy Huang            mReplyFromAccounts.addAll(account.getReplyFroms());
13292551d057965689f1952faeb06763f0762bc717fMindy Pereira        }
13362de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        adapter.addAccounts(mReplyFromAccounts);
1345a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
1355a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        setAdapter(adapter);
1365f034b7a0d1bad66c45abf5d7ab64d89f5aaa48cMindy Pereira        selectCurrentAccount();
1375a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        setOnItemSelectedListener(this);
13862de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira    }
13962de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira
14062de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira    public List<ReplyFromAccount> getReplyFromAccounts() {
14162de1b104635b09e7f00b0941268ba1fa5460ddbMindy Pereira        return mReplyFromAccounts;
1425a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
1435a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
1445a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    public void setOnAccountChangedListener(OnAccountChangedListener listener) {
1455a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        mAccountChangedListener = listener;
1465a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
1475a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
1485a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    @Override
1495a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
15092551d057965689f1952faeb06763f0762bc717fMindy Pereira        ReplyFromAccount selection = (ReplyFromAccount) getItemAtPosition(position);
151bb036ff794f022bba2f501e155ef9c412e0e452eTony Mantler        // TODO: Do not key off ReplyFromAccount.name b/11292541
15275f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira        if (!selection.name.equals(mAccount.name)) {
1535a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira            mAccount = selection;
1545a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira            mAccountChangedListener.onAccountChanged();
1555a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        }
1565a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
1575a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
1585a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    @Override
1595a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    public void onNothingSelected(AdapterView<?> parent) {
1605a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        // Do nothing.
1615a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
1625a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira
16375f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira    /**
16475f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira     * Classes that want to know when a different account in the
16575f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira     * FromAddressSpinner has been selected should implement this interface.
16675f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira     * Note: if the user chooses the same account as the one that has already
16775f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira     * been selected, this method will not be called.
16875f66634dd18cc8d8e6f40c4573c0edf0a0343efMindy Pereira     */
1695a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    public static interface OnAccountChangedListener {
1705a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira        public void onAccountChanged();
1715a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira    }
1725a85e2b7485a5c407c581219fe1b44417f050529Mindy Pereira}
173