1 /* 2 * Copyright (C) 2011 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package com.android.email.activity; 18 19 import android.content.Context; 20 import android.content.Loader; 21 import android.database.Cursor; 22 import android.util.Log; 23 import android.view.LayoutInflater; 24 import android.view.View; 25 import android.view.ViewGroup; 26 import android.widget.CursorAdapter; 27 import android.widget.TextView; 28 29 import com.android.email.Email; 30 import com.android.email.FolderProperties; 31 import com.android.email.data.ThrottlingCursorLoader; 32 import com.android.emailcommon.Logging; 33 import com.android.emailcommon.provider.Account; 34 import com.android.emailcommon.provider.EmailContent.MailboxColumns; 35 import com.android.emailcommon.provider.HostAuth; 36 import com.android.emailcommon.provider.Mailbox; 37 import com.android.emailcommon.utility.Utility; 38 39 /** 40 * Cursor adapter for the "move to mailbox" dialog. 41 * TODO We've detached this class from {@link MailboxFragmentAdapter} and {@link MailboxFragmentAdapter}. 42 * Depending upon the UX for the dialog and nested folders, we may want to bring these three 43 * adapter classes back into alignment. 44 */ 45 class MailboxMoveToAdapter extends CursorAdapter { 46 /** Selection for all mailboxes in an account */ 47 private static final String ALL_MAILBOX_SELECTION = MailboxColumns.ACCOUNT_KEY + "=?" 48 + " AND " + Mailbox.USER_VISIBLE_MAILBOX_SELECTION; 49 /** Selection for valid target mailboxes */ 50 private static final String TARGET_MAILBOX_SELECTION = 51 MailboxColumns.TYPE + " NOT IN (" + Mailbox.TYPE_DRAFTS + "," 52 + Mailbox.TYPE_OUTBOX + "," + Mailbox.TYPE_SENT + "," + Mailbox.TYPE_TRASH + ") AND (" 53 + MailboxColumns.FLAGS + " & " + Mailbox.FLAG_ACCEPTS_MOVED_MAIL + " != 0)"; 54 /** Selection to exclude a mailbox ID */ 55 private static final String EXCLUDE_MAILBOX_SELECTION = 56 MailboxColumns.ID + "!=?"; 57 /** The main selection to populate the "move to" dialog */ 58 private static final String MOVE_TO_SELECTION = 59 ALL_MAILBOX_SELECTION 60 + " AND " + TARGET_MAILBOX_SELECTION 61 + " AND " + EXCLUDE_MAILBOX_SELECTION; 62 /** Projection that uses the server id column as the mailbox name */ 63 private static final String[] MOVE_TO_PROJECTION_SERVER_ID = new String[] { 64 MailboxColumns.ID, 65 MailboxColumns.ID + " AS org_mailbox_id", 66 MailboxColumns.SERVER_ID, 67 MailboxColumns.TYPE, 68 }; 69 /** Projection that uses the display name column as the mailbox name */ 70 private static final String[] MOVE_TO_PROJECTION_DISPLAY_NAME = new String[] { 71 MailboxColumns.ID, 72 MailboxColumns.ID + " AS org_mailbox_id", 73 MailboxColumns.DISPLAY_NAME, 74 MailboxColumns.TYPE, 75 }; 76 /** Sort order for special mailboxes */ 77 private static final String MOVE_TO_ORDER_BY_STATIC = 78 "CASE " + MailboxColumns.TYPE 79 + " WHEN " + Mailbox.TYPE_INBOX + " THEN 0" 80 + " WHEN " + Mailbox.TYPE_JUNK + " THEN 1" 81 + " ELSE 10 END"; 82 /** Server id sort order */ 83 private static final String MOVE_TO_ORDER_BY_SERVER_ID = 84 MOVE_TO_ORDER_BY_STATIC 85 // All other mailboxes are shown in alphabetical order. 86 + ", " + MailboxColumns.SERVER_ID; 87 /** Display name sort order */ 88 private static final String MOVE_TO_ORDER_BY_DISPLAY_NAME = 89 MOVE_TO_ORDER_BY_STATIC 90 // All other mailboxes are shown in alphabetical order. 91 + ", " + MailboxColumns.DISPLAY_NAME; 92 93 // Column 0 is only for ListView; we don't use it in our code. 94 private static final int COLUMN_ID = 1; 95 private static final int COLUMN_MAILBOX_NAME = 2; 96 private static final int COLUMN_TYPE = 3; 97 98 /** Cached layout inflater */ 99 private final LayoutInflater mInflater; 100 101 public MailboxMoveToAdapter(Context context) { 102 super(context, null, 0 /* flags; no content observer */); 103 mInflater = LayoutInflater.from(context); 104 } 105 106 @Override 107 public void bindView(View view, Context context, Cursor cursor) { 108 TextView t = (TextView) view; 109 t.setText(getDisplayText(context, cursor)); 110 } 111 112 @Override 113 public View newView(Context context, Cursor cursor, ViewGroup parent) { 114 return mInflater.inflate(android.R.layout.simple_list_item_1, parent, false); 115 } 116 117 static Loader<Cursor> createLoader(Context context, long accountId, long mailboxId) { 118 if (Logging.DEBUG_LIFECYCLE && Email.DEBUG) { 119 Log.d(Logging.LOG_TAG, "MailboxDialogAdapter#createLoader accountId=" + accountId 120 + ", mailboxId=" + mailboxId); 121 } 122 return new MailboxMoveToLoader(context, accountId, mailboxId); 123 } 124 125 /** 126 * Returns the mailbox name to display in the dialog list. If the mailbox is of 127 * certain, well known, types, use a predefined name. Otherwise, use the server 128 * provided name. 129 */ 130 private static String getDisplayText(Context context, Cursor cursor) { 131 final int type = cursor.getInt(COLUMN_TYPE); 132 final long mailboxId = cursor.getLong(COLUMN_ID); 133 return FolderProperties.getInstance(context).getDisplayName(type, mailboxId, 134 cursor.getString(COLUMN_MAILBOX_NAME)); 135 } 136 137 /** Loader for the "move to mailbox" dialog. */ 138 private static class MailboxMoveToLoader extends ThrottlingCursorLoader { 139 private final long mAccountId; 140 public MailboxMoveToLoader(Context context, long accountId, long mailboxId) { 141 super(context, Mailbox.CONTENT_URI, 142 null, MOVE_TO_SELECTION, 143 new String[] { Long.toString(accountId), Long.toString(mailboxId) }, null); 144 mAccountId = accountId; 145 } 146 147 @Override 148 public Cursor loadInBackground() { 149 // TODO Create a common way to store the fully qualified path name for all account types 150 final String protocol = Account.getProtocol(getContext(), mAccountId); 151 if (HostAuth.SCHEME_EAS.equals(protocol)) { 152 // For EAS accounts; use the display name 153 setProjection(MOVE_TO_PROJECTION_DISPLAY_NAME); 154 setSortOrder(MOVE_TO_ORDER_BY_DISPLAY_NAME); 155 } else { 156 // For all other accounts; use the server id 157 setProjection(MOVE_TO_PROJECTION_SERVER_ID); 158 setSortOrder(MOVE_TO_ORDER_BY_SERVER_ID); 159 } 160 final Cursor mailboxesCursor = super.loadInBackground(); 161 return Utility.CloseTraceCursorWrapper.get(mailboxesCursor); 162 } 163 } 164 } 165