Home | History | Annotate | Download | only in map
      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.BluetoothMapAccountItem;
     49 import com.android.bluetooth.map.BluetoothMapAccountLoader;
     50 public class BluetoothMapSettingsAdapter extends BaseExpandableListAdapter {
     51     private static final boolean D = BluetoothMapService.DEBUG;
     52     private static final boolean V = BluetoothMapService.VERBOSE;
     53     private static final String TAG = "BluetoothMapSettingsAdapter";
     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<BluetoothMapAccountItem,
     60                             ArrayList<BluetoothMapAccountItem>> mProupList;
     61     private ArrayList<BluetoothMapAccountItem> mMainGroup;
     62     private int[] mGroupStatus;
     63     /* number of accounts possible to share */
     64     private int mSlotsLeft = 10;
     65 
     66 
     67     public BluetoothMapSettingsAdapter(Activity act,
     68                                             ExpandableListView listView,
     69                                             LinkedHashMap<BluetoothMapAccountItem,
     70                                               ArrayList<BluetoothMapAccountItem>> 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                 BluetoothMapAccountItem group = mMainGroup.get(groupPosition);
     82                 if (mProupList.get(group).size() > 0)
     83                     mGroupStatus[groupPosition] = 1;
     84 
     85             }
     86         });
     87         mMainGroup = new ArrayList<BluetoothMapAccountItem>();
     88         for (Map.Entry<BluetoothMapAccountItem,
     89                 ArrayList<BluetoothMapAccountItem>> mapEntry : mProupList.entrySet()) {
     90             mMainGroup.add(mapEntry.getKey());
     91         }
     92     }
     93 
     94     @Override
     95     public BluetoothMapAccountItem getChild(int groupPosition, int childPosition) {
     96         BluetoothMapAccountItem item = mMainGroup.get(groupPosition);
     97         return mProupList.get(item).get(childPosition);
     98     }
     99     private ArrayList<BluetoothMapAccountItem> getChild(BluetoothMapAccountItem group) {
    100         return mProupList.get(group);
    101     }
    102 
    103     @Override
    104     public long getChildId(int groupPosition, int childPosition) {
    105         return 0;
    106     }
    107 
    108     @Override
    109     public View getChildView(final int groupPosition, final int childPosition,
    110             boolean isLastChild, View convertView, ViewGroup parent) {
    111 
    112 
    113         final ChildHolder holder;
    114         if (convertView == null) {
    115             convertView = mInflater.inflate(R.layout.bluetooth_map_settings_account_item, null);
    116             holder = new ChildHolder();
    117             holder.cb = (CheckBox) convertView.findViewById(R.id.bluetooth_map_settings_item_check);
    118             holder.title =
    119                 (TextView) convertView.findViewById(R.id.bluetooth_map_settings_item_text_view);
    120             convertView.setTag(holder);
    121         } else {
    122             holder = (ChildHolder) convertView.getTag();
    123         }
    124             final BluetoothMapAccountItem child =  getChild(groupPosition, childPosition);
    125             holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    126 
    127                 public void onCheckedChanged(CompoundButton buttonView,
    128                         boolean isChecked) {
    129                     BluetoothMapAccountItem parentGroup =
    130                           (BluetoothMapAccountItem)getGroup(groupPosition);
    131                     boolean oldIsChecked = child.mIsChecked; // needed to prevent updates on UI redraw
    132                     child.mIsChecked = isChecked;
    133                     if (isChecked) {
    134                         ArrayList<BluetoothMapAccountItem> childList = getChild(parentGroup);
    135                         int childIndex = childList.indexOf(child);
    136                         boolean isAllChildClicked = true;
    137                         if(mSlotsLeft-childList.size() >=0){
    138 
    139                             for (int i = 0; i < childList.size(); i++) {
    140                                 if (i != childIndex) {
    141                                     BluetoothMapAccountItem siblings = childList.get(i);
    142                                     if (!siblings.mIsChecked) {
    143                                         isAllChildClicked = false;
    144                                             BluetoothMapSettingsDataHolder.mCheckedChilds.put(
    145                                                 child.getName(), parentGroup.getName());
    146                                         break;
    147 
    148                                     }
    149                                 }
    150                             }
    151                         }else {
    152                             showWarning(mActivity.getString(
    153                                 R.string.bluetooth_map_settings_no_account_slots_left));
    154                             isAllChildClicked = false;
    155                             child.mIsChecked = false;
    156                         }
    157                         if (isAllChildClicked) {
    158                             parentGroup.mIsChecked = true;
    159                             if(!(BluetoothMapSettingsDataHolder.mCheckedChilds.containsKey(
    160                                 child.getName())==true)){
    161                                 BluetoothMapSettingsDataHolder.mCheckedChilds.put(child.getName(),
    162                                         parentGroup.getName());
    163                             }
    164                             mCheckAll = false;
    165                         }
    166 
    167 
    168                     } else {
    169                         if (parentGroup.mIsChecked) {
    170                             parentGroup.mIsChecked = false;
    171                             mCheckAll = false;
    172                             BluetoothMapSettingsDataHolder.mCheckedChilds.remove(child.getName());
    173                         } else {
    174                             mCheckAll = true;
    175                             BluetoothMapSettingsDataHolder.mCheckedChilds.remove(child.getName());
    176                         }
    177                         // child.isChecked =false;
    178                     }
    179                     notifyDataSetChanged();
    180                     if(child.mIsChecked != oldIsChecked){
    181                         updateAccount(child);
    182                     }
    183 
    184                 }
    185 
    186             });
    187 
    188             holder.cb.setChecked(child.mIsChecked);
    189             holder.title.setText(child.getName());
    190             if(D)Log.i("childs are", BluetoothMapSettingsDataHolder.mCheckedChilds.toString());
    191             return convertView;
    192 
    193     }
    194 
    195 
    196 
    197     @Override
    198     public int getChildrenCount(int groupPosition) {
    199         BluetoothMapAccountItem item = mMainGroup.get(groupPosition);
    200         return mProupList.get(item).size();
    201     }
    202 
    203     @Override
    204     public BluetoothMapAccountItem getGroup(int groupPosition) {
    205         return mMainGroup.get(groupPosition);
    206     }
    207 
    208     @Override
    209     public int getGroupCount() {
    210         return mMainGroup.size();
    211     }
    212 
    213     @Override
    214     public void onGroupCollapsed(int groupPosition) {
    215         super.onGroupCollapsed(groupPosition);
    216     }
    217 
    218     @Override
    219     public void onGroupExpanded(int groupPosition) {
    220         super.onGroupExpanded(groupPosition);
    221     }
    222 
    223     @Override
    224     public long getGroupId(int groupPosition) {
    225         return 0;
    226     }
    227 
    228     @Override
    229     public View getGroupView(int groupPosition, boolean isExpanded,
    230             View convertView, ViewGroup parent) {
    231 
    232         final GroupHolder holder;
    233 
    234         if (convertView == null) {
    235             convertView = mInflater.inflate(R.layout.bluetooth_map_settings_account_group, null);
    236             holder = new GroupHolder();
    237             holder.cb =
    238                 (CheckBox) convertView.findViewById(R.id.bluetooth_map_settings_group_checkbox);
    239             holder.imageView = (ImageView) convertView
    240                     .findViewById(R.id.bluetooth_map_settings_group_icon);
    241             holder.title =
    242                 (TextView) convertView.findViewById(R.id.bluetooth_map_settings_group_text_view);
    243             convertView.setTag(holder);
    244         } else {
    245             holder = (GroupHolder) convertView.getTag();
    246         }
    247 
    248         final BluetoothMapAccountItem groupItem = getGroup(groupPosition);
    249         holder.imageView.setImageDrawable(groupItem.getIcon());
    250 
    251 
    252         holder.title.setText(groupItem.getName());
    253 
    254         holder.cb.setOnCheckedChangeListener(new OnCheckedChangeListener() {
    255 
    256             public void onCheckedChanged(CompoundButton buttonView,
    257                     boolean isChecked) {
    258                 if (mCheckAll) {
    259                     ArrayList<BluetoothMapAccountItem> childItem = getChild(groupItem);
    260                     for (BluetoothMapAccountItem children : childItem)
    261                     {
    262                         boolean oldIsChecked = children.mIsChecked;
    263                         if(mSlotsLeft >0){
    264                             children.mIsChecked = isChecked;
    265                             if(oldIsChecked != children.mIsChecked){
    266                                 updateAccount(children);
    267                             }
    268                         }else {
    269                             showWarning(mActivity.getString(
    270                                     R.string.bluetooth_map_settings_no_account_slots_left));
    271                             isChecked = false;
    272                         }
    273                     }
    274                 }
    275                 groupItem.mIsChecked = isChecked;
    276                 notifyDataSetChanged();
    277                 new Handler().postDelayed(new Runnable() {
    278 
    279                     public void run() {
    280                         if (!mCheckAll)
    281                             mCheckAll = true;
    282                     }
    283                 }, 50);
    284 
    285             }
    286 
    287         });
    288         holder.cb.setChecked(groupItem.mIsChecked);
    289         return convertView;
    290 
    291     }
    292 
    293     @Override
    294     public boolean hasStableIds() {
    295         return true;
    296     }
    297 
    298     @Override
    299     public boolean isChildSelectable(int groupPosition, int childPosition) {
    300         return true;
    301     }
    302 
    303     private class GroupHolder {
    304         public ImageView imageView;
    305         public CheckBox cb;
    306         public TextView title;
    307 
    308     }
    309 
    310     private class ChildHolder {
    311         public TextView title;
    312         public CheckBox cb;
    313     }
    314     public void updateAccount(BluetoothMapAccountItem account) {
    315         updateSlotCounter(account.mIsChecked);
    316         if(D)Log.d(TAG,"Updating account settings for "
    317                 +account.getName() +". Value is:"+account.mIsChecked);
    318         ContentResolver mResolver = mActivity.getContentResolver();
    319         Uri uri = Uri.parse(account.mBase_uri_no_account+"/"+BluetoothMapContract.TABLE_ACCOUNT);
    320         ContentValues values = new ContentValues();
    321         values.put(BluetoothMapContract.AccountColumns.FLAG_EXPOSE, ((account.mIsChecked)?1:0));
    322         values.put(BluetoothMapContract.AccountColumns._ID, account.getId()); // get title
    323         mResolver.update(uri, values, null ,null);
    324 
    325     }
    326     private void updateSlotCounter(boolean isChecked){
    327         if(isChecked)
    328         {
    329             mSlotsLeft--;
    330         }else {
    331             mSlotsLeft++;
    332         }
    333         CharSequence text;
    334 
    335         if (mSlotsLeft <=0)
    336         {
    337             text = mActivity.getString(R.string.bluetooth_map_settings_no_account_slots_left);
    338         }else {
    339             text= mActivity.getString(R.string.bluetooth_map_settings_count)
    340                 + " "+ String.valueOf(mSlotsLeft);
    341         }
    342 
    343         int duration = Toast.LENGTH_SHORT;
    344 
    345         Toast toast = Toast.makeText(mActivity, text, duration);
    346         toast.show();
    347     }
    348     private void showWarning(String text){
    349         int duration = Toast.LENGTH_SHORT;
    350 
    351         Toast toast = Toast.makeText(mActivity, text, duration);
    352         toast.show();
    353 
    354     }
    355 
    356 
    357 }
    358