]> Pileus Git - ~andy/freeotp/blob - src/org/fedorahosted/freeotp/adapters/DeleteActionBarBaseAdapter.java
Tablet UI rewrite
[~andy/freeotp] / src / org / fedorahosted / freeotp / adapters / DeleteActionBarBaseAdapter.java
1 /*
2  * FreeOTP
3  *
4  * Authors: Nathaniel McCallum <npmccallum@redhat.com>
5  *
6  * Copyright (C) 2013  Nathaniel McCallum, Red Hat
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  *     http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20
21 package org.fedorahosted.freeotp.adapters;
22
23 import java.util.ArrayList;
24 import java.util.Collections;
25 import java.util.Comparator;
26 import java.util.HashSet;
27 import java.util.List;
28 import java.util.Map;
29 import java.util.Set;
30 import java.util.WeakHashMap;
31
32 import org.fedorahosted.freeotp.R;
33
34 import android.content.Context;
35 import android.content.res.Resources;
36 import android.view.ActionMode;
37 import android.view.Menu;
38 import android.view.MenuItem;
39 import android.view.View;
40 import android.widget.CompoundButton;
41
42 public abstract class DeleteActionBarBaseAdapter extends ReorderableBaseAdapter {
43         private final Map<View, CompoundButton> mButtons = new WeakHashMap<View, CompoundButton>();
44         private final Set<Integer> mChecked = new HashSet<Integer>();
45         private ActionMode mActionMode;
46
47         @Override
48         public void notifyDataSetChanged() {
49                 if (mActionMode != null)
50                         mActionMode.finish();
51                 mChecked.clear();
52                 super.notifyDataSetChanged();
53         }
54
55         @Override
56         public void notifyDataSetInvalidated() {
57                 if (mActionMode != null)
58                         mActionMode.finish();
59                 mChecked.clear();
60                 super.notifyDataSetInvalidated();
61         }
62
63         @Override
64         protected void bindView(View view, int position) {
65                 super.bindView(view, position);
66                 mButtons.get(view).setChecked(mChecked.contains(position));
67         }
68
69         @Override
70         protected void processView(View view, int type) {
71                 super.processView(view, type);
72
73                 CompoundButton cb = getCompoundButton(view);
74                 mButtons.put(view, cb);
75                 cb.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() {
76                         @Override
77                         public void onCheckedChanged(CompoundButton buttonView, boolean isChecked) {
78                                 int position = getPositionFromView(buttonView);
79
80                                 if (!isChecked) {
81                                         mChecked.remove(position);
82                                         if (mChecked.size() == 0 && mActionMode != null)
83                                                 mActionMode.finish();
84
85                                         setTitle(buttonView.getContext());
86                                         return;
87                                 }
88
89                                 if (mChecked.size() == 0) {
90                                         mActionMode = buttonView.startActionMode(new ActionMode.Callback() {
91                                                 @Override
92                                                 public boolean onPrepareActionMode(ActionMode mode, Menu menu) {
93                                                         return false;
94                                                 }
95
96                                                 @Override
97                                                 public void onDestroyActionMode(ActionMode mode) {
98                                                         mActionMode = null;
99                                                         for (final CompoundButton cb : mButtons.values()) {
100                                                                 cb.post(new Runnable() {
101                                                                         @Override
102                                                                         public void run() {
103                                                                                 cb.setChecked(false);
104                                                                         }
105                                                                 });
106                                                         }
107                                                 }
108
109                                                 @Override
110                                                 public boolean onCreateActionMode(ActionMode mode, Menu menu) {
111                                                         menu.add(R.string.delete).setIcon(android.R.drawable.ic_menu_delete);
112                                                         return true;
113                                                 }
114
115                                                 @Override
116                                                 public boolean onActionItemClicked(ActionMode mode, MenuItem item) {
117                                                         // Get the list of all the checked positions
118                                                         // and reverse sort the list.
119                                                         List<Integer> list = new ArrayList<Integer>(mChecked);
120                                                         Collections.sort(list, new Comparator<Integer>() {
121                                                                 @Override
122                                                                 public int compare(Integer lhs, Integer rhs) {
123                                                                         return rhs.intValue() - lhs.intValue();
124                                                                 }
125                                                         });
126
127                                                         // Delete all the selected tokens (in reverse order!)
128                                                         for (Integer i : list)
129                                                                 delete(i);
130
131                                                         mode.finish();
132                                                         return true;
133                                                 }
134                                         });
135                                 }
136
137                                 mChecked.add(position);
138                                 setTitle(buttonView.getContext());
139                         }
140                 });
141         }
142
143         private void setTitle(Context ctx) {
144                 if (mActionMode == null || mChecked.size() == 0)
145                         return;
146
147                 Resources res = ctx.getResources();
148                 mActionMode.setTitle(res.getQuantityString(R.plurals.tokens_selected,
149                                                    mChecked.size(),
150                                                    mChecked.size()));
151         }
152
153         protected abstract CompoundButton getCompoundButton(View view);
154         public abstract void delete(int position);
155 }