1 /* 2 * Copyright (C) 2007 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 17 package com.example.android.notepad; 18 19 import com.example.android.notepad.NotePad.Notes; 20 21 import android.app.ListActivity; 22 import android.content.ComponentName; 23 import android.content.ContentUris; 24 import android.content.Intent; 25 import android.database.Cursor; 26 import android.net.Uri; 27 import android.os.Bundle; 28 import android.util.Log; 29 import android.view.ContextMenu; 30 import android.view.Menu; 31 import android.view.MenuItem; 32 import android.view.View; 33 import android.view.ContextMenu.ContextMenuInfo; 34 import android.widget.AdapterView; 35 import android.widget.ListView; 36 import android.widget.SimpleCursorAdapter; 37 38 /** 39 * Displays a list of notes. Will display notes from the {@link Uri} 40 * provided in the intent if there is one, otherwise defaults to displaying the 41 * contents of the {@link NotePadProvider} 42 */ 43 public class NotesList extends ListActivity { 44 private static final String TAG = "NotesList"; 45 46 // Menu item ids 47 public static final int MENU_ITEM_DELETE = Menu.FIRST; 48 public static final int MENU_ITEM_INSERT = Menu.FIRST + 1; 49 50 /** 51 * The columns we are interested in from the database 52 */ 53 private static final String[] PROJECTION = new String[] { 54 Notes._ID, // 0 55 Notes.TITLE, // 1 56 }; 57 58 /** The index of the title column */ 59 private static final int COLUMN_INDEX_TITLE = 1; 60 61 @Override 62 protected void onCreate(Bundle savedInstanceState) { 63 super.onCreate(savedInstanceState); 64 65 setDefaultKeyMode(DEFAULT_KEYS_SHORTCUT); 66 67 // If no data was given in the intent (because we were started 68 // as a MAIN activity), then use our default content provider. 69 Intent intent = getIntent(); 70 if (intent.getData() == null) { 71 intent.setData(Notes.CONTENT_URI); 72 } 73 74 // Inform the list we provide context menus for items 75 getListView().setOnCreateContextMenuListener(this); 76 77 // Perform a managed query. The Activity will handle closing and requerying the cursor 78 // when needed. 79 Cursor cursor = managedQuery(getIntent().getData(), PROJECTION, null, null, 80 Notes.DEFAULT_SORT_ORDER); 81 82 // Used to map notes entries from the database to views 83 SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.noteslist_item, cursor, 84 new String[] { Notes.TITLE }, new int[] { android.R.id.text1 }); 85 setListAdapter(adapter); 86 } 87 88 @Override 89 public boolean onCreateOptionsMenu(Menu menu) { 90 super.onCreateOptionsMenu(menu); 91 92 // This is our one standard application action -- inserting a 93 // new note into the list. 94 menu.add(0, MENU_ITEM_INSERT, 0, R.string.menu_insert) 95 .setShortcut('3', 'a') 96 .setIcon(android.R.drawable.ic_menu_add); 97 98 // Generate any additional actions that can be performed on the 99 // overall list. In a normal install, there are no additional 100 // actions found here, but this allows other applications to extend 101 // our menu with their own actions. 102 Intent intent = new Intent(null, getIntent().getData()); 103 intent.addCategory(Intent.CATEGORY_ALTERNATIVE); 104 menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, 105 new ComponentName(this, NotesList.class), null, intent, 0, null); 106 107 return true; 108 } 109 110 @Override 111 public boolean onPrepareOptionsMenu(Menu menu) { 112 super.onPrepareOptionsMenu(menu); 113 final boolean haveItems = getListAdapter().getCount() > 0; 114 115 // If there are any notes in the list (which implies that one of 116 // them is selected), then we need to generate the actions that 117 // can be performed on the current selection. This will be a combination 118 // of our own specific actions along with any extensions that can be 119 // found. 120 if (haveItems) { 121 // This is the selected item. 122 Uri uri = ContentUris.withAppendedId(getIntent().getData(), getSelectedItemId()); 123 124 // Build menu... always starts with the EDIT action... 125 Intent[] specifics = new Intent[1]; 126 specifics[0] = new Intent(Intent.ACTION_EDIT, uri); 127 MenuItem[] items = new MenuItem[1]; 128 129 // ... is followed by whatever other actions are available... 130 Intent intent = new Intent(null, uri); 131 intent.addCategory(Intent.CATEGORY_ALTERNATIVE); 132 menu.addIntentOptions(Menu.CATEGORY_ALTERNATIVE, 0, 0, null, specifics, intent, 0, 133 items); 134 135 // Give a shortcut to the edit action. 136 if (items[0] != null) { 137 items[0].setShortcut('1', 'e'); 138 } 139 } else { 140 menu.removeGroup(Menu.CATEGORY_ALTERNATIVE); 141 } 142 143 return true; 144 } 145 146 @Override 147 public boolean onOptionsItemSelected(MenuItem item) { 148 switch (item.getItemId()) { 149 case MENU_ITEM_INSERT: 150 // Launch activity to insert a new item 151 startActivity(new Intent(Intent.ACTION_INSERT, getIntent().getData())); 152 return true; 153 } 154 return super.onOptionsItemSelected(item); 155 } 156 157 @Override 158 public void onCreateContextMenu(ContextMenu menu, View view, ContextMenuInfo menuInfo) { 159 AdapterView.AdapterContextMenuInfo info; 160 try { 161 info = (AdapterView.AdapterContextMenuInfo) menuInfo; 162 } catch (ClassCastException e) { 163 Log.e(TAG, "bad menuInfo", e); 164 return; 165 } 166 167 Cursor cursor = (Cursor) getListAdapter().getItem(info.position); 168 if (cursor == null) { 169 // For some reason the requested item isn't available, do nothing 170 return; 171 } 172 173 // Setup the menu header 174 menu.setHeaderTitle(cursor.getString(COLUMN_INDEX_TITLE)); 175 176 // Add a menu item to delete the note 177 menu.add(0, MENU_ITEM_DELETE, 0, R.string.menu_delete); 178 } 179 180 @Override 181 public boolean onContextItemSelected(MenuItem item) { 182 AdapterView.AdapterContextMenuInfo info; 183 try { 184 info = (AdapterView.AdapterContextMenuInfo) item.getMenuInfo(); 185 } catch (ClassCastException e) { 186 Log.e(TAG, "bad menuInfo", e); 187 return false; 188 } 189 190 switch (item.getItemId()) { 191 case MENU_ITEM_DELETE: { 192 // Delete the note that the context menu is for 193 Uri noteUri = ContentUris.withAppendedId(getIntent().getData(), info.id); 194 getContentResolver().delete(noteUri, null, null); 195 return true; 196 } 197 } 198 return false; 199 } 200 201 @Override 202 protected void onListItemClick(ListView l, View v, int position, long id) { 203 Uri uri = ContentUris.withAppendedId(getIntent().getData(), id); 204 205 String action = getIntent().getAction(); 206 if (Intent.ACTION_PICK.equals(action) || Intent.ACTION_GET_CONTENT.equals(action)) { 207 // The caller is waiting for us to return a note selected by 208 // the user. The have clicked on one, so return it now. 209 setResult(RESULT_OK, new Intent().setData(uri)); 210 } else { 211 // Launch activity to view/edit the currently selected item 212 startActivity(new Intent(Intent.ACTION_EDIT, uri)); 213 } 214 } 215 } 216