1 /* 2 * Copyright (C) 2009 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.cooliris.media; 18 19 import java.io.IOException; 20 import java.text.DateFormat; 21 import java.text.ParsePosition; 22 import java.text.SimpleDateFormat; 23 import java.util.ArrayList; 24 import java.util.Date; 25 26 import android.content.Context; 27 import android.content.res.Resources; 28 import android.media.ExifInterface; 29 30 import com.cooliris.app.App; 31 import com.cooliris.app.Res; 32 33 public final class DetailMode { 34 public static CharSequence[] populateDetailModeStrings(Context context, ArrayList<MediaBucket> buckets) { 35 int numBuckets = buckets.size(); 36 if (MediaBucketList.isSetSelection(buckets) && numBuckets == 1) { 37 // If just 1 set was selected, save the trouble of processing the 38 // items in the set again. 39 // We have already processed details for that set. 40 return populateSetViewDetailModeStrings(context, MediaBucketList.getFirstSetSelection(buckets), 1); 41 } else if (MediaBucketList.isSetSelection(buckets) || MediaBucketList.isMultipleItemSelection(buckets)) { 42 // Cycle through the items and add them to the selection items set. 43 MediaSet selectedItemsSet = new MediaSet(); 44 for (int i = 0; i < numBuckets; i++) { 45 MediaBucket bucket = buckets.get(i); 46 ArrayList<MediaItem> currItems = null; 47 int numCurrItems = 0; 48 if (MediaBucketList.isSetSelection(bucket)) { 49 MediaSet currSet = bucket.mediaSet; 50 if (currSet != null) { 51 currItems = currSet.getItems(); 52 numCurrItems = currSet.getNumItems(); 53 } 54 } else { 55 currItems = bucket.mediaItems; 56 numCurrItems = currItems.size(); 57 } 58 if (currItems != null) { 59 for (int j = 0; j < numCurrItems; j++) { 60 selectedItemsSet.addItem(currItems.get(j)); 61 } 62 } 63 } 64 return populateSetViewDetailModeStrings(context, selectedItemsSet, numBuckets); 65 } else { 66 return populateItemViewDetailModeStrings(context, MediaBucketList.getFirstItemSelection(buckets)); 67 } 68 } 69 70 private static CharSequence[] populateSetViewDetailModeStrings(Context context, MediaSet selectedItemsSet, int numOriginalSets) { 71 if (selectedItemsSet == null) { 72 return null; 73 } 74 Resources resources = context.getResources(); 75 ArrayList<CharSequence> strings = new ArrayList<CharSequence>(); 76 77 // Number of albums selected. 78 if (numOriginalSets == 1) { 79 strings.add("1 " + resources.getString(Res.string.album_selected)); 80 } else { 81 strings.add(Integer.toString(numOriginalSets) + " " + resources.getString(Res.string.albums_selected)); 82 } 83 84 // Number of items selected. 85 int numItems = selectedItemsSet.mNumItemsLoaded; 86 if (numItems == 1) { 87 strings.add("1 " + resources.getString(Res.string.item_selected)); 88 } else { 89 strings.add(Integer.toString(numItems) + " " + resources.getString(Res.string.items_selected)); 90 } 91 92 DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT); 93 94 // Start and end times of the selected items. 95 if (selectedItemsSet.areTimestampsAvailable()) { 96 long minTimestamp = selectedItemsSet.mMinTimestamp; 97 long maxTimestamp = selectedItemsSet.mMaxTimestamp; 98 if (selectedItemsSet.isPicassaSet()) { 99 minTimestamp -= App.CURRENT_TIME_ZONE.getOffset(minTimestamp); 100 maxTimestamp -= App.CURRENT_TIME_ZONE.getOffset(maxTimestamp); 101 } 102 strings.add(resources.getString(Res.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp))); 103 strings.add(resources.getString(Res.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp))); 104 } else if (selectedItemsSet.areAddedTimestampsAvailable()) { 105 long minTimestamp = selectedItemsSet.mMinAddedTimestamp; 106 long maxTimestamp = selectedItemsSet.mMaxAddedTimestamp; 107 if (selectedItemsSet.isPicassaSet()) { 108 minTimestamp -= App.CURRENT_TIME_ZONE.getOffset(minTimestamp); 109 maxTimestamp -= App.CURRENT_TIME_ZONE.getOffset(maxTimestamp); 110 } 111 strings.add(resources.getString(Res.string.start) + ": " + dateTimeFormat.format(new Date(minTimestamp))); 112 strings.add(resources.getString(Res.string.end) + ": " + dateTimeFormat.format(new Date(maxTimestamp))); 113 } else { 114 strings.add(resources.getString(Res.string.start) + ": " + resources.getString(Res.string.date_unknown)); 115 strings.add(resources.getString(Res.string.end) + ": " + resources.getString(Res.string.date_unknown)); 116 } 117 118 // The location of the selected items. 119 String locationString = null; 120 if (selectedItemsSet.mLatLongDetermined) { 121 locationString = selectedItemsSet.mReverseGeocodedLocation; 122 if (locationString == null) { 123 // Try computing the location if it does not exist. 124 ReverseGeocoder reverseGeocoder = App.get(context).getReverseGeocoder(); 125 locationString = reverseGeocoder.computeMostGranularCommonLocation(selectedItemsSet); 126 } 127 } 128 if (locationString != null && locationString.length() > 0) { 129 strings.add(resources.getString(Res.string.location) + ": " + locationString); 130 } 131 int numStrings = strings.size(); 132 CharSequence[] stringsArr = new CharSequence[numStrings]; 133 for (int i = 0; i < numStrings; ++i) { 134 stringsArr[i] = strings.get(i); 135 } 136 return stringsArr; 137 } 138 139 private static CharSequence[] populateItemViewDetailModeStrings(Context context, MediaItem item) { 140 if (item == null) { 141 return null; 142 } 143 Resources resources = context.getResources(); 144 CharSequence[] strings = new CharSequence[5]; 145 strings[0] = resources.getString(Res.string.title) + ": " + item.mCaption; 146 strings[1] = resources.getString(Res.string.type) + ": " + item.getDisplayMimeType(); 147 148 DateFormat dateTimeFormat = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.SHORT); 149 150 if (item.mLocaltime == null) { 151 SimpleDateFormat formatter = new SimpleDateFormat("yyyy:MM:dd HH:mm:ss"); 152 try { 153 ExifInterface exif = new ExifInterface(item.mFilePath); 154 String localtime = exif.getAttribute(ExifInterface.TAG_DATETIME); 155 if (localtime != null) { 156 item.mLocaltime = formatter.parse(localtime, new ParsePosition(0)); 157 } 158 } catch (IOException ex) { 159 // ignore it. 160 } 161 if (item.mLocaltime == null && item.mCaption != null) { 162 formatter = new SimpleDateFormat("yyyyMMdd'_'HHmmss"); 163 // skip initial IMG_ or VND_ 164 item.mLocaltime = formatter.parse(item.mCaption, new ParsePosition(4)); 165 } 166 } 167 168 if (item.mLocaltime != null) { 169 strings[2] = resources.getString(Res.string.taken_on) + ": " + dateTimeFormat.format(item.mLocaltime); 170 } else if (item.isDateTakenValid()) { 171 long dateTaken = item.mDateTakenInMs; 172 if (item.isPicassaItem()) { 173 dateTaken -= App.CURRENT_TIME_ZONE.getOffset(dateTaken); 174 } 175 strings[2] = resources.getString(Res.string.taken_on) + ": " + dateTimeFormat.format(new Date(dateTaken)); 176 } else if (item.isDateAddedValid()) { 177 long dateAdded = item.mDateAddedInSec * 1000; 178 if (item.isPicassaItem()) { 179 dateAdded -= App.CURRENT_TIME_ZONE.getOffset(dateAdded); 180 } 181 // TODO: Make this added_on as soon as translations are ready. 182 // strings[2] = resources.getString(Res.string.added_on) + ": " + 183 // DateFormat.format("h:mmaa MMM dd yyyy", dateAdded); 184 strings[2] = resources.getString(Res.string.taken_on) + ": " + dateTimeFormat.format(new Date(dateAdded)); 185 } else { 186 strings[2] = resources.getString(Res.string.taken_on) + ": " + resources.getString(Res.string.date_unknown); 187 } 188 MediaSet parentMediaSet = item.mParentMediaSet; 189 if (parentMediaSet == null) { 190 strings[3] = resources.getString(Res.string.album) + ":"; 191 } else { 192 strings[3] = resources.getString(Res.string.album) + ": " + parentMediaSet.mName; 193 } 194 ReverseGeocoder reverseGeocoder = App.get(context).getReverseGeocoder(); 195 String locationString = item.getReverseGeocodedLocation(reverseGeocoder); 196 if (locationString == null || locationString.length() == 0) { 197 locationString = context.getResources().getString(Res.string.location_unknown); 198 } 199 strings[4] = resources.getString(Res.string.location) + ": " + locationString; 200 return strings; 201 } 202 }