blob: 49422c67172950709449fe608b57d1e26365189b [file] [log] [blame]
The Android Open Source Projectc8f00b62008-10-21 07:00:00 -07001/*
2 * Copyright (C) 2008 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
17package com.android.launcher;
18
19import android.content.ComponentName;
20import android.content.Context;
21import android.content.Intent;
22import android.content.pm.ActivityInfo;
23import android.content.pm.PackageManager;
24import android.content.pm.ResolveInfo;
25import android.view.LayoutInflater;
26import android.view.View;
27import android.view.ViewGroup;
28import android.widget.TextView;
29import android.widget.BaseExpandableListAdapter;
30import android.graphics.drawable.Drawable;
31
32import java.util.ArrayList;
33import java.util.Collections;
34import java.util.List;
35
36/**
37 * Shows a list of all the items that can be added to the workspace.
38 */
39public final class AddAdapter extends BaseExpandableListAdapter {
40 private static final int GROUP_APPLICATIONS = 0;
41 private static final int GROUP_SHORTCUTS = 1;
42 private static final int GROUP_WIDGETS = 2;
43 private static final int GROUP_WALLPAPERS = 3;
44
45 private final Intent mCreateShortcutIntent;
46 private Intent mSetWallpaperIntent;
47 private final LayoutInflater mInflater;
48 private Launcher mLauncher;
49 private Group[] mGroups;
50
51 /**
52 * Abstract class representing one thing that can be added
53 */
54 public abstract class AddAction implements Runnable {
55 private final Context mContext;
56
57 AddAction(Context context) {
58 mContext = context;
59 }
60
61 Drawable getIcon(int resource) {
62 return mContext.getResources().getDrawable(resource);
63 }
64
65 public abstract void bindView(View v);
66 }
67
68 /**
69 * Class representing an action that will create set the wallpaper.
70 */
71 public class SetWallpaperAction extends CreateShortcutAction {
72 SetWallpaperAction(Context context, ResolveInfo info) {
73 super(context, info);
74 }
75
76 public void run() {
77 Intent intent = new Intent(mSetWallpaperIntent);
78 ActivityInfo activityInfo = mInfo.activityInfo;
79 intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
80 activityInfo.name));
81 mLauncher.startActivity(intent);
82 }
83 }
84
85 /**
86 * Class representing an action that will create a specific type
87 * of shortcut
88 */
89 public class CreateShortcutAction extends AddAction {
90
91 ResolveInfo mInfo;
92 private CharSequence mLabel;
93 private Drawable mIcon;
94
95 CreateShortcutAction(Context context, ResolveInfo info) {
96 super(context);
97 mInfo = info;
98 }
99
100 @Override
101 public void bindView(View view) {
102 ResolveInfo info = mInfo;
103 TextView text = (TextView) view;
104
105 PackageManager pm = mLauncher.getPackageManager();
106
107 if (mLabel == null) {
108 mLabel = info.loadLabel(pm);
109 if (mLabel == null) {
110 mLabel = info.activityInfo.name;
111 }
112 }
113 if (mIcon == null) {
114 mIcon = info.loadIcon(pm);
115 }
116
117 text.setText(mLabel);
118 text.setCompoundDrawablesWithIntrinsicBounds(mIcon, null, null, null);
119 }
120
121 public void run() {
122 Intent intent = new Intent(mCreateShortcutIntent);
123 ActivityInfo activityInfo = mInfo.activityInfo;
124 intent.setComponent(new ComponentName(activityInfo.applicationInfo.packageName,
125 activityInfo.name));
126 mLauncher.addShortcut(intent);
127 }
128 }
129
130 /**
131 * Class representing an action that will add a folder
132 */
133 public class CreateFolderAction extends AddAction {
134
135 CreateFolderAction(Context context) {
136 super(context);
137 }
138
139 @Override
140 public void bindView(View view) {
141 TextView text = (TextView) view;
142 text.setText(R.string.add_folder);
143 text.setCompoundDrawablesWithIntrinsicBounds(getIcon(R.drawable.ic_launcher_folder),
144 null, null, null);
145 }
146
147 public void run() {
148 mLauncher.addFolder();
149 }
150 }
151
152 /**
153 * Class representing an action that will add a folder
154 */
155 public class CreateClockAction extends AddAction {
156
157 CreateClockAction(Context context) {
158 super(context);
159 }
160
161 @Override
162 public void bindView(View view) {
163 TextView text = (TextView) view;
164 text.setText(R.string.add_clock);
165 Drawable icon = getIcon(R.drawable.ic_launcher_alarmclock);
166 text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
167 }
168
169 public void run() {
170 mLauncher.addClock();
171 }
172 }
173
174 /**
175 * Class representing an action that will add a PhotoFrame
176 */
177 public class CreatePhotoFrameAction extends AddAction {
178 CreatePhotoFrameAction(Context context) {
179 super(context);
180 }
181
182 @Override
183 public void bindView(View view) {
184 TextView text = (TextView) view;
185 text.setText(R.string.add_photo_frame);
186 Drawable icon = getIcon(R.drawable.ic_launcher_gallery);
187 text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
188 }
189
190 public void run() {
191 mLauncher.getPhotoForPhotoFrame();
192 }
193 }
194
195
196 /**
197 * Class representing an action that will add a Search widget
198 */
199 public class CreateSearchAction extends AddAction {
200 CreateSearchAction(Context context) {
201 super(context);
202 }
203
204 @Override
205 public void bindView(View view) {
206 TextView text = (TextView) view;
207 text.setText(R.string.add_search);
208 Drawable icon = getIcon(R.drawable.ic_search_gadget);
209 text.setCompoundDrawablesWithIntrinsicBounds(icon, null, null, null);
210 }
211
212 public void run() {
213 mLauncher.addSearch();
214 }
215 }
216
217 private class Group {
218 private String mName;
219 private ArrayList<AddAction> mList;
220
221 Group(String name) {
222 mName = name;
223 mList = new ArrayList<AddAction>();
224 }
225
226 void add(AddAction action) {
227 mList.add(action);
228 }
229
230 int size() {
231 return mList.size();
232 }
233
234 String getName() {
235 return mName;
236 }
237
238 void run(int position) {
239 mList.get(position).run();
240 }
241
242 void bindView(int childPosition, View view) {
243 mList.get(childPosition).bindView(view);
244 }
245
246 public Object get(int childPosition) {
247 return mList.get(childPosition);
248 }
249 }
250
251 private class ApplicationsGroup extends Group {
252 private final Launcher mLauncher;
253 private final ArrayList<ApplicationInfo> mApplications;
254
255 ApplicationsGroup(Launcher launcher, String name) {
256 super(name);
257 mLauncher = launcher;
258 mApplications = Launcher.getModel().getApplications();
259 }
260
261 @Override
262 int size() {
263 return mApplications == null ? 0 : mApplications.size();
264 }
265
266 @Override
267 void add(AddAction action) {
268 }
269
270 @Override
271 void run(int position) {
272 final ApplicationInfo info = mApplications.get(position);
273 mLauncher.addApplicationShortcut(info);
274 }
275
276 @Override
277 void bindView(int childPosition, View view) {
278 TextView text = (TextView) view.findViewById(R.id.title);
279
280 final ApplicationInfo info = mApplications.get(childPosition);
281 text.setText(info.title);
282 if (!info.filtered) {
283 info.icon = Utilities.createIconThumbnail(info.icon, mLauncher);
284 info.filtered = true;
285 }
286 text.setCompoundDrawablesWithIntrinsicBounds(info.icon, null, null, null);
287 }
288
289 @Override
290 public Object get(int childPosition) {
291 return mApplications.get(childPosition);
292 }
293 }
294
295 public AddAdapter(Launcher launcher, boolean forFolder) {
296 mCreateShortcutIntent = new Intent(Intent.ACTION_CREATE_SHORTCUT);
297 mCreateShortcutIntent.setComponent(null);
298
299 mSetWallpaperIntent = new Intent(Intent.ACTION_SET_WALLPAPER);
300 mSetWallpaperIntent.setComponent(null);
301
302 mLauncher = launcher;
303 mInflater = (LayoutInflater) launcher.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
304
305 mGroups = new Group[forFolder ? 2 : 4];
306 final Group[] groups = mGroups;
307 groups[GROUP_APPLICATIONS] = new ApplicationsGroup(mLauncher,
308 mLauncher.getString(R.string.group_applications));
309 groups[GROUP_SHORTCUTS] = new Group(mLauncher.getString(R.string.group_shortcuts));
310
311 if (!forFolder) {
312 groups[GROUP_WALLPAPERS] = new Group(mLauncher.getString(R.string.group_wallpapers));
313 groups[GROUP_SHORTCUTS].add(new CreateFolderAction(launcher));
314 groups[GROUP_WIDGETS] = new Group(mLauncher.getString(R.string.group_widgets));
315 final Group widgets = groups[GROUP_WIDGETS];
316 widgets.add(new CreateClockAction(launcher));
317 widgets.add(new CreatePhotoFrameAction(launcher));
318 widgets.add(new CreateSearchAction(launcher));
319 }
320
321 PackageManager packageManager = launcher.getPackageManager();
322
323 List<ResolveInfo> list = findTargetsForIntent(mCreateShortcutIntent, packageManager);
324 if (list != null && list.size() > 0) {
325 int count = list.size();
326 final Group shortcuts = groups[GROUP_SHORTCUTS];
327 for (int i = 0; i < count; i++) {
328 ResolveInfo resolveInfo = list.get(i);
329 shortcuts.add(new CreateShortcutAction(launcher, resolveInfo));
330 }
331 }
332
333 list = findTargetsForIntent(mSetWallpaperIntent, packageManager);
334 if (list != null && list.size() > 0) {
335 int count = list.size();
336 final Group shortcuts = groups[GROUP_WALLPAPERS];
337 for (int i = 0; i < count; i++) {
338 ResolveInfo resolveInfo = list.get(i);
339 shortcuts.add(new SetWallpaperAction(launcher, resolveInfo));
340 }
341 }
342 }
343
344 private List<ResolveInfo> findTargetsForIntent(Intent intent, PackageManager packageManager) {
345 List<ResolveInfo> list = packageManager.queryIntentActivities(intent,
346 PackageManager.MATCH_DEFAULT_ONLY);
347 if (list != null) {
348 int count = list.size();
349 if (count > 1) {
350 // Only display the first matches that are either of equal
351 // priority or have asked to be default options.
352 ResolveInfo firstInfo = list.get(0);
353 for (int i=1; i<count; i++) {
354 ResolveInfo resolveInfo = list.get(i);
355 if (firstInfo.priority != resolveInfo.priority ||
356 firstInfo.isDefault != resolveInfo.isDefault) {
357 while (i < count) {
358 list.remove(i);
359 count--;
360 }
361 }
362 }
363 Collections.sort(list, new ResolveInfo.DisplayNameComparator(packageManager));
364 }
365 }
366 return list;
367 }
368
369 public int getGroupCount() {
370 return mGroups.length;
371 }
372
373 public int getChildrenCount(int groupPosition) {
374 return mGroups[groupPosition].size();
375 }
376
377 public Object getGroup(int groupPosition) {
378 return mGroups[groupPosition].getName();
379 }
380
381 public Object getChild(int groupPosition, int childPosition) {
382 return mGroups[groupPosition].get(childPosition);
383 }
384
385 public long getGroupId(int groupPosition) {
386 return groupPosition;
387 }
388
389 public long getChildId(int groupPosition, int childPosition) {
390 return (groupPosition << 16) | childPosition;
391 }
392
393 public boolean hasStableIds() {
394 return true;
395 }
396
397 public View getGroupView(int groupPosition, boolean isExpanded,
398 View convertView, ViewGroup parent) {
399 View view;
400 if (convertView == null) {
401 view = mInflater.inflate(R.layout.create_shortcut_group_item, parent, false);
402 } else {
403 view = convertView;
404 }
405 ((TextView) view).setText(mGroups[groupPosition].getName());
406 return view;
407 }
408
409 public View getChildView(int groupPosition, int childPosition, boolean isLastChild,
410 View convertView, ViewGroup parent) {
411 View view;
412 if (convertView == null) {
413 view = mInflater.inflate(R.layout.create_shortcut_list_item, parent, false);
414 } else {
415 view = convertView;
416 }
417 mGroups[groupPosition].bindView(childPosition, view);
418 return view;
419 }
420
421 public boolean isChildSelectable(int groupPosition, int childPosition) {
422 return true;
423 }
424
425 void performAction(int groupPosition, int childPosition) {
426 mGroups[groupPosition].run(childPosition);
427 }
428}