DialogDetailsView.java revision 7817979db0c52ffeacb951625b1e821eba303285
1/* 2 * Copyright (C) 2011 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.gallery3d.ui; 18 19import android.app.Activity; 20import android.app.AlertDialog; 21import android.app.Dialog; 22import android.content.Context; 23import android.content.DialogInterface; 24import android.content.DialogInterface.OnDismissListener; 25import android.text.format.Formatter; 26import android.view.LayoutInflater; 27import android.view.View; 28import android.view.ViewGroup; 29import android.widget.BaseAdapter; 30import android.widget.ListView; 31import android.widget.TextView; 32 33import com.android.gallery3d.R; 34import com.android.gallery3d.app.GalleryActivity; 35import com.android.gallery3d.common.Utils; 36import com.android.gallery3d.data.MediaDetails; 37import com.android.gallery3d.ui.DetailsAddressResolver.AddressResolvingListener; 38import com.android.gallery3d.ui.DetailsHelper.CloseListener; 39import com.android.gallery3d.ui.DetailsHelper.DetailsSource; 40import com.android.gallery3d.ui.DetailsHelper.DetailsViewContainer; 41 42import java.util.ArrayList; 43import java.util.Map.Entry; 44 45public class DialogDetailsView implements DetailsViewContainer { 46 @SuppressWarnings("unused") 47 private static final String TAG = "DialogDetailsView"; 48 49 private final GalleryActivity mContext; 50 private DetailsAdapter mAdapter; 51 private MediaDetails mDetails; 52 private final DetailsSource mSource; 53 private int mIndex; 54 private Dialog mDialog; 55 private CloseListener mListener; 56 57 public DialogDetailsView(GalleryActivity activity, DetailsSource source) { 58 mContext = activity; 59 mSource = source; 60 } 61 62 @Override 63 public void show() { 64 reloadDetails(); 65 mDialog.show(); 66 } 67 68 @Override 69 public void hide() { 70 mDialog.hide(); 71 } 72 73 @Override 74 public void reloadDetails() { 75 int index = mSource.setIndex(); 76 if (index == -1) return; 77 MediaDetails details = mSource.getDetails(); 78 if (details != null) { 79 if (mIndex == index && mDetails == details) return; 80 mIndex = index; 81 mDetails = details; 82 setDetails(details); 83 } 84 } 85 86 private void setDetails(MediaDetails details) { 87 mAdapter = new DetailsAdapter(details); 88 String title = String.format( 89 mContext.getAndroidContext().getString(R.string.details_title), 90 mIndex + 1, mSource.size()); 91 ListView detailsList = (ListView) LayoutInflater.from(mContext.getAndroidContext()).inflate( 92 R.layout.details_list, null, false); 93 detailsList.setAdapter(mAdapter); 94 mDialog = new AlertDialog.Builder((Activity) mContext) 95 .setView(detailsList) 96 .setTitle(title) 97 .setPositiveButton(R.string.close, new DialogInterface.OnClickListener() { 98 @Override 99 public void onClick(DialogInterface dialog, int whichButton) { 100 mDialog.dismiss(); 101 } 102 }) 103 .create(); 104 105 mDialog.setOnDismissListener(new OnDismissListener() { 106 @Override 107 public void onDismiss(DialogInterface dialog) { 108 if (mListener != null) { 109 mListener.onClose(); 110 } 111 } 112 }); 113 } 114 115 private class DetailsAdapter extends BaseAdapter implements AddressResolvingListener { 116 private final ArrayList<String> mItems; 117 private int mLocationIndex; 118 119 public DetailsAdapter(MediaDetails details) { 120 Context context = mContext.getAndroidContext(); 121 mItems = new ArrayList<String>(details.size()); 122 mLocationIndex = -1; 123 setDetails(context, details); 124 } 125 126 private void setDetails(Context context, MediaDetails details) { 127 for (Entry<Integer, Object> detail : details) { 128 String value; 129 switch (detail.getKey()) { 130 case MediaDetails.INDEX_LOCATION: { 131 double[] latlng = (double[]) detail.getValue(); 132 mLocationIndex = mItems.size(); 133 value = DetailsHelper.resolveAddress(mContext, latlng, this); 134 break; 135 } 136 case MediaDetails.INDEX_SIZE: { 137 value = Formatter.formatFileSize( 138 context, (Long) detail.getValue()); 139 break; 140 } 141 case MediaDetails.INDEX_WHITE_BALANCE: { 142 value = "1".equals(detail.getValue()) 143 ? context.getString(R.string.manual) 144 : context.getString(R.string.auto); 145 break; 146 } 147 case MediaDetails.INDEX_FLASH: { 148 MediaDetails.FlashState flash = 149 (MediaDetails.FlashState) detail.getValue(); 150 // TODO: camera doesn't fill in the complete values, show more information 151 // when it is fixed. 152 if (flash.isFlashFired()) { 153 value = context.getString(R.string.flash_on); 154 } else { 155 value = context.getString(R.string.flash_off); 156 } 157 break; 158 } 159 case MediaDetails.INDEX_EXPOSURE_TIME: { 160 value = (String) detail.getValue(); 161 double time = Double.valueOf(value); 162 if (time < 1.0f) { 163 value = String.format("1/%d", (int) (0.5f + 1 / time)); 164 } else { 165 int integer = (int) time; 166 time -= integer; 167 value = String.valueOf(integer) + "''"; 168 if (time > 0.0001) { 169 value += String.format(" 1/%d", (int) (0.5f + 1 / time)); 170 } 171 } 172 break; 173 } 174 default: { 175 Object valueObj = detail.getValue(); 176 // This shouldn't happen, log its key to help us diagnose the problem. 177 if (valueObj == null) { 178 Utils.fail("%s's value is Null", 179 DetailsHelper.getDetailsName(context, detail.getKey())); 180 } 181 value = valueObj.toString(); 182 } 183 } 184 int key = detail.getKey(); 185 if (details.hasUnit(key)) { 186 value = String.format("%s : %s %s", DetailsHelper.getDetailsName( 187 context, key), value, context.getString(details.getUnit(key))); 188 } else { 189 value = String.format("%s : %s", DetailsHelper.getDetailsName( 190 context, key), value); 191 } 192 mItems.add(value); 193 } 194 } 195 196 @Override 197 public boolean areAllItemsEnabled() { 198 return false; 199 } 200 201 @Override 202 public boolean isEnabled(int position) { 203 return false; 204 } 205 206 @Override 207 public int getCount() { 208 return mItems.size(); 209 } 210 211 @Override 212 public Object getItem(int position) { 213 return mDetails.getDetail(position); 214 } 215 216 @Override 217 public long getItemId(int position) { 218 return position; 219 } 220 221 @Override 222 public View getView(int position, View convertView, ViewGroup parent) { 223 TextView tv; 224 if (convertView == null) { 225 tv = (TextView) LayoutInflater.from(mContext.getAndroidContext()).inflate( 226 R.layout.details, parent, false); 227 } else { 228 tv = (TextView) convertView; 229 } 230 tv.setText(mItems.get(position)); 231 return tv; 232 } 233 234 @Override 235 public void onAddressAvailable(String address) { 236 mItems.set(mLocationIndex, address); 237 notifyDataSetChanged(); 238 } 239 } 240 241 @Override 242 public void setCloseListener(CloseListener listener) { 243 mListener = listener; 244 } 245} 246