michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.sync.setup.activities; michael@0: michael@0: import java.util.ArrayList; michael@0: import java.util.Collection; michael@0: import java.util.List; michael@0: michael@0: import org.mozilla.gecko.R; michael@0: import org.mozilla.gecko.sync.repositories.domain.ClientRecord; michael@0: michael@0: import android.content.Context; michael@0: import android.view.View; michael@0: import android.view.View.OnClickListener; michael@0: import android.view.ViewGroup; michael@0: import android.widget.ArrayAdapter; michael@0: import android.widget.CheckBox; michael@0: import android.widget.ImageView; michael@0: import android.widget.TextView; michael@0: michael@0: public class ClientRecordArrayAdapter extends ArrayAdapter { michael@0: public static final String LOG_TAG = "ClientRecArrayAdapter"; michael@0: michael@0: private boolean[] checkedItems; michael@0: private SendTabActivity sendTabActivity; michael@0: michael@0: public ClientRecordArrayAdapter(Context context, michael@0: int textViewResourceId) { michael@0: super(context, textViewResourceId, new ArrayList()); michael@0: this.checkedItems = new boolean[0]; michael@0: this.sendTabActivity = (SendTabActivity) context; michael@0: } michael@0: michael@0: public synchronized void setClientRecordList(final Collection clientRecordList) { michael@0: this.clear(); michael@0: this.checkedItems = new boolean[clientRecordList.size()]; michael@0: for (ClientRecord clientRecord : clientRecordList) { michael@0: this.add(clientRecord); michael@0: } michael@0: this.notifyDataSetChanged(); michael@0: } michael@0: michael@0: /** michael@0: * If we have only a single client record in the list, mark it as checked. michael@0: */ michael@0: public synchronized void checkItem(final int position, boolean checked) throws ArrayIndexOutOfBoundsException { michael@0: if (position < 0 || michael@0: position >= checkedItems.length) { michael@0: throw new ArrayIndexOutOfBoundsException(position); michael@0: } michael@0: michael@0: if (setRowChecked(position, true)) { michael@0: this.notifyDataSetChanged(); michael@0: } michael@0: } michael@0: michael@0: /** michael@0: * Set the specified row to the specified checked state. michael@0: * @param position an index. michael@0: * @param checked whether the checkbox should be checked. michael@0: * @return true if the state changed, false if the michael@0: * box was already in the requested state. michael@0: */ michael@0: protected synchronized boolean setRowChecked(int position, boolean checked) { michael@0: boolean current = checkedItems[position]; michael@0: if (current == checked) { michael@0: return false; michael@0: } michael@0: michael@0: checkedItems[position] = checked; michael@0: sendTabActivity.enableSend(getNumCheckedGUIDs() > 0); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: @Override michael@0: public View getView(final int position, View convertView, ViewGroup parent) { michael@0: final Context context = this.getContext(); michael@0: michael@0: // Reuse View objects if they exist. michael@0: View row = convertView; michael@0: if (row == null) { michael@0: row = View.inflate(context, R.layout.sync_list_item, null); michael@0: setSelectable(row, true); michael@0: row.setBackgroundResource(android.R.drawable.menuitem_background); michael@0: } michael@0: michael@0: final ClientRecord clientRecord = this.getItem(position); michael@0: ImageView clientType = (ImageView) row.findViewById(R.id.img); michael@0: TextView clientName = (TextView) row.findViewById(R.id.client_name); michael@0: michael@0: // Set up checkbox and restore stored state. michael@0: CheckBox checkbox = (CheckBox) row.findViewById(R.id.check); michael@0: checkbox.setChecked(checkedItems[position]); michael@0: setSelectable(checkbox, false); michael@0: michael@0: clientName.setText(clientRecord.name); michael@0: clientType.setImageResource(getImage(clientRecord)); michael@0: michael@0: row.setOnClickListener(new OnClickListener() { michael@0: @Override michael@0: public void onClick(View view) { michael@0: final CheckBox item = (CheckBox) view.findViewById(R.id.check); michael@0: michael@0: // Update the checked item, both in the UI and in our internal state. michael@0: final boolean checked = !item.isChecked(); // Because it hasn't happened yet. michael@0: item.setChecked(checked); michael@0: setRowChecked(position, checked); michael@0: } michael@0: }); michael@0: michael@0: return row; michael@0: } michael@0: michael@0: /** michael@0: * Get list of checked GUIDs. michael@0: * michael@0: * @return non-null list. michael@0: */ michael@0: public synchronized List getCheckedGUIDs() { michael@0: final List guids = new ArrayList(); michael@0: for (int i = 0; i < checkedItems.length; i++) { michael@0: if (checkedItems[i]) { michael@0: guids.add(this.getItem(i).guid); michael@0: } michael@0: } michael@0: return guids; michael@0: } michael@0: michael@0: /** michael@0: * Get number of checked GUIDs. michael@0: * michael@0: * @return non-negative integer. michael@0: */ michael@0: public synchronized int getNumCheckedGUIDs() { michael@0: int numCheckedGUIDs = 0; michael@0: for (int i = 0; i < checkedItems.length; i++) { michael@0: if (checkedItems[i]) { michael@0: numCheckedGUIDs += 1; michael@0: } michael@0: } michael@0: return numCheckedGUIDs; michael@0: } michael@0: michael@0: private int getImage(ClientRecord record) { michael@0: if ("mobile".equals(record.type)) { michael@0: return R.drawable.sync_mobile; michael@0: } michael@0: return R.drawable.sync_desktop; michael@0: } michael@0: michael@0: private void setSelectable(View view, boolean selectable) { michael@0: view.setClickable(selectable); michael@0: view.setFocusable(selectable); michael@0: } michael@0: }