1 /* 2 * Copyright (C) 2014 Samsung System LSI 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 package com.android.bluetooth.map; 17 18 import java.util.ArrayList; 19 import java.util.HashMap; 20 import java.util.LinkedHashMap; 21 import java.util.List; 22 import java.util.Map; 23 24 import com.android.bluetooth.R; 25 import android.app.Activity; 26 import android.content.ContentResolver; 27 import android.content.ContentValues; 28 import android.graphics.drawable.Drawable; 29 import android.net.Uri; 30 import android.os.Handler; 31 import com.android.bluetooth.mapapi.BluetoothMapContract; 32 import android.util.Log; 33 import android.util.SparseArray; 34 import android.view.LayoutInflater; 35 import android.view.View; 36 import android.view.View.OnClickListener; 37 import android.view.ViewGroup; 38 import android.widget.BaseExpandableListAdapter; 39 import android.widget.CheckBox; 40 import android.widget.CheckedTextView; 41 import android.widget.CompoundButton.OnCheckedChangeListener; 42 import android.widget.ExpandableListView; 43 import android.widget.ExpandableListView.OnGroupExpandListener; 44 import android.widget.ImageView; 45 import android.widget.TextView; 46 import android.widget.Toast; 47 import android.widget.CompoundButton; 48 import com.android.bluetooth.map.BluetoothMapEmailSettingsItem; 49 import com.android.bluetooth.map.BluetoothMapEmailSettingsLoader; 50 public class BluetoothMapEmailSettingsAdapter extends BaseExpandableListAdapter { 51 private static final boolean D = BluetoothMapService.DEBUG; 52 private static final boolean V = BluetoothMapService.VERBOSE; 53 private static final String TAG = "BluetoothMapEmailSettingsAdapter"; 54 private boolean mCheckAll = true; 55 public LayoutInflater mInflater; 56 public Activity mActivity; 57 /*needed to prevent random checkbox toggles due to item reuse */ 58 ArrayList<Boolean> mPositionArray; 59 private LinkedHashMap<BluetoothMapEmailSettingsItem, 60 ArrayList<BluetoothMapEmailSettingsItem>> mProupList; 61 private ArrayList<BluetoothMapEmailSettingsItem> mMainGroup; 62 private int[] mGroupStatus; 63 /* number of accounts possible to share */ 64 private int mSlotsLeft = 10; 65 66 67 public BluetoothMapEmailSettingsAdapter(Activity act, 68 ExpandableListView listView, 69 LinkedHashMap<BluetoothMapEmailSettingsItem, 70 ArrayList<BluetoothMapEmailSettingsItem>> groupsList, 71 int enabledAccountsCounts) { 72 mActivity = act; 73 this.mProupList = groupsList; 74 mInflater = act.getLayoutInflater(); 75 mGroupStatus = new int[groupsList.size()]; 76 mSlotsLeft = mSlotsLeft-enabledAccountsCounts; 77 78 listView.setOnGroupExpandListener(new OnGroupExpandListener() { 79 80 public void onGroupExpand(int groupPosition) { 81 BluetoothMapEmailSettingsItem group = mMainGroup.get(groupPosition); 82 if (mProupList.get(group).size() > 0) 83 mGroupStatus[groupPosition] = 1; 84 85 } 86 }); 87 mMainGroup = new ArrayList<BluetoothMapEmailSettingsItem>(); 88 for (Map.Entry<BluetoothMapEmailSettingsItem, ArrayList<BluetoothMapEmailSettingsItem>> mapEntry : mProupList.entrySet()) { 89 mMainGroup.add(mapEntry.getKey()); 90 } 91 } 92 93 @Override 94 public BluetoothMapEmailSettingsItem getChild(int groupPosition, int childPosition) { 95 BluetoothMapEmailSettingsItem item = mMainGroup.get(groupPosition); 96 return mProupList.get(item).get(childPosition); 97 } 98 private ArrayList<BluetoothMapEmailSettingsItem> getChild(BluetoothMapEmailSettingsItem group) { 99 return mProupList.get(group); 100 } 101 102 @Override 103 public long getChildId(int groupPosition, int childPosition) { 104 return 0; 105 } 106 107 @Override 108 public View getChildView(final int groupPosition, final int childPosition, 109 boolean isLastChild, View convertView, ViewGroup parent) { 110 111 112 final ChildHolder holder; 113 if (convertView == null) { 114 convertView = mInflater.inflate(R.layout.bluetooth_map_email_settings_account_item, null); 115 holder = new ChildHolder(); 116 holder.cb = (CheckBox) convertView.findViewById(R.id.bluetooth_map_email_settings_item_check); 117 holder.title = (TextView) convertView.findViewById(R.id.bluetooth_map_email_settings_item_text_view); 118 convertView.setTag(holder); 119 } else { 120 holder = (ChildHolder) convertView.getTag(); 121 } 122 final BluetoothMapEmailSettingsItem child = getChild(groupPosition, childPosition); 123 holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 124 125 public void onCheckedChanged(CompoundButton buttonView, 126 boolean isChecked) { 127 BluetoothMapEmailSettingsItem parentGroup = (BluetoothMapEmailSettingsItem)getGroup(groupPosition); 128 boolean oldIsChecked = child.mIsChecked; // needed to prevent updates on UI redraw 129 child.mIsChecked = isChecked; 130 if (isChecked) { 131 ArrayList<BluetoothMapEmailSettingsItem> childList = getChild(parentGroup); 132 int childIndex = childList.indexOf(child); 133 boolean isAllChildClicked = true; 134 if(mSlotsLeft-childList.size() >=0){ 135 136 for (int i = 0; i < childList.size(); i++) { 137 if (i != childIndex) { 138 BluetoothMapEmailSettingsItem siblings = childList.get(i); 139 if (!siblings.mIsChecked) { 140 isAllChildClicked = false; 141 BluetoothMapEmailSettingsDataHolder.mCheckedChilds.put(child.getName(), 142 parentGroup.getName()); 143 break; 144 145 } 146 } 147 } 148 }else { 149 showWarning(mActivity.getString(R.string.bluetooth_map_email_settings_no_account_slots_left)); 150 isAllChildClicked = false; 151 child.mIsChecked = false; 152 } 153 if (isAllChildClicked) { 154 parentGroup.mIsChecked = true; 155 if(!(BluetoothMapEmailSettingsDataHolder.mCheckedChilds.containsKey(child.getName())==true)){ 156 BluetoothMapEmailSettingsDataHolder.mCheckedChilds.put(child.getName(), 157 parentGroup.getName()); 158 } 159 mCheckAll = false; 160 } 161 162 163 } else { 164 if (parentGroup.mIsChecked) { 165 parentGroup.mIsChecked = false; 166 mCheckAll = false; 167 BluetoothMapEmailSettingsDataHolder.mCheckedChilds.remove(child.getName()); 168 } else { 169 mCheckAll = true; 170 BluetoothMapEmailSettingsDataHolder.mCheckedChilds.remove(child.getName()); 171 } 172 // child.isChecked =false; 173 } 174 notifyDataSetChanged(); 175 if(child.mIsChecked != oldIsChecked){ 176 updateAccount(child); 177 } 178 179 } 180 181 }); 182 183 holder.cb.setChecked(child.mIsChecked); 184 holder.title.setText(child.getName()); 185 if(D)Log.i("childs are", BluetoothMapEmailSettingsDataHolder.mCheckedChilds.toString()); 186 return convertView; 187 188 } 189 190 191 192 @Override 193 public int getChildrenCount(int groupPosition) { 194 BluetoothMapEmailSettingsItem item = mMainGroup.get(groupPosition); 195 return mProupList.get(item).size(); 196 } 197 198 @Override 199 public BluetoothMapEmailSettingsItem getGroup(int groupPosition) { 200 return mMainGroup.get(groupPosition); 201 } 202 203 @Override 204 public int getGroupCount() { 205 return mMainGroup.size(); 206 } 207 208 @Override 209 public void onGroupCollapsed(int groupPosition) { 210 super.onGroupCollapsed(groupPosition); 211 } 212 213 @Override 214 public void onGroupExpanded(int groupPosition) { 215 super.onGroupExpanded(groupPosition); 216 } 217 218 @Override 219 public long getGroupId(int groupPosition) { 220 return 0; 221 } 222 223 @Override 224 public View getGroupView(int groupPosition, boolean isExpanded, 225 View convertView, ViewGroup parent) { 226 227 final GroupHolder holder; 228 229 if (convertView == null) { 230 convertView = mInflater.inflate(R.layout.bluetooth_map_email_settings_account_group, null); 231 holder = new GroupHolder(); 232 holder.cb = (CheckBox) convertView.findViewById(R.id.bluetooth_map_email_settings_group_checkbox); 233 holder.imageView = (ImageView) convertView 234 .findViewById(R.id.bluetooth_map_email_settings_group_icon); 235 holder.title = (TextView) convertView.findViewById(R.id.bluetooth_map_email_settings_group_text_view); 236 convertView.setTag(holder); 237 } else { 238 holder = (GroupHolder) convertView.getTag(); 239 } 240 241 final BluetoothMapEmailSettingsItem groupItem = getGroup(groupPosition); 242 holder.imageView.setImageDrawable(groupItem.getIcon()); 243 244 245 holder.title.setText(groupItem.getName()); 246 247 holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() { 248 249 public void onCheckedChanged(CompoundButton buttonView, 250 boolean isChecked) { 251 if (mCheckAll) { 252 ArrayList<BluetoothMapEmailSettingsItem> childItem = getChild(groupItem); 253 for (BluetoothMapEmailSettingsItem children : childItem) 254 { 255 boolean oldIsChecked = children.mIsChecked; 256 if(mSlotsLeft >0){ 257 children.mIsChecked = isChecked; 258 if(oldIsChecked != children.mIsChecked){ 259 updateAccount(children); 260 } 261 }else { 262 showWarning(mActivity.getString(R.string.bluetooth_map_email_settings_no_account_slots_left)); 263 isChecked = false; 264 } 265 } 266 } 267 groupItem.mIsChecked = isChecked; 268 notifyDataSetChanged(); 269 new Handler().postDelayed(new Runnable() { 270 271 public void run() { 272 if (!mCheckAll) 273 mCheckAll = true; 274 } 275 }, 50); 276 277 } 278 279 }); 280 holder.cb.setChecked(groupItem.mIsChecked); 281 return convertView; 282 283 } 284 285 @Override 286 public boolean hasStableIds() { 287 return true; 288 } 289 290 @Override 291 public boolean isChildSelectable(int groupPosition, int childPosition) { 292 return true; 293 } 294 295 private class GroupHolder { 296 public ImageView imageView; 297 public CheckBox cb; 298 public TextView title; 299 300 } 301 302 private class ChildHolder { 303 public TextView title; 304 public CheckBox cb; 305 } 306 public void updateAccount(BluetoothMapEmailSettingsItem account) { 307 updateSlotCounter(account.mIsChecked); 308 if(D)Log.d(TAG,"Updating account settings for "+account.getName() +". Value is:"+account.mIsChecked); 309 ContentResolver mResolver = mActivity.getContentResolver(); 310 Uri uri = Uri.parse(account.mBase_uri_no_account+"/"+BluetoothMapContract.TABLE_ACCOUNT); 311 ContentValues values = new ContentValues(); 312 values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, ((account.mIsChecked)?1:0)); // get title 313 values.put(BluetoothMapContract.AccountColumns._ID, account.getId()); // get title 314 mResolver.update(uri, values, null ,null); 315 316 } 317 private void updateSlotCounter(boolean isChecked){ 318 if(isChecked) 319 { 320 mSlotsLeft--; 321 }else { 322 mSlotsLeft++; 323 } 324 CharSequence text; 325 326 if (mSlotsLeft <=0) 327 { 328 text = mActivity.getString(R.string.bluetooth_map_email_settings_no_account_slots_left); 329 }else { 330 text= mActivity.getString(R.string.bluetooth_map_email_settings_count) + " "+ String.valueOf(mSlotsLeft); 331 } 332 333 int duration = Toast.LENGTH_SHORT; 334 335 Toast toast = Toast.makeText(mActivity, text, duration); 336 toast.show(); 337 } 338 private void showWarning(String text){ 339 int duration = Toast.LENGTH_SHORT; 340 341 Toast toast = Toast.makeText(mActivity, text, duration); 342 toast.show(); 343 344 } 345 346 347 } 348