d2f5d1067df1a766aab9f49d87c68b86114c5529
[pub/Android/ownCloud.git] / src / eu / alefzero / owncloud / ui / fragment / FileDetailFragment.java
1 /* ownCloud Android client application
2 * Copyright (C) 2011 Bartek Przybylski
3 *
4 * This program is free software: you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation, either version 3 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 */
18 package eu.alefzero.owncloud.ui.fragment;
19
20 import android.accounts.Account;
21 import android.accounts.AccountManager;
22 import android.content.BroadcastReceiver;
23 import android.content.Context;
24 import android.content.Intent;
25 import android.content.IntentFilter;
26 import android.graphics.Bitmap;
27 import android.graphics.BitmapFactory;
28 import android.net.Uri;
29 import android.os.Bundle;
30 import android.util.Log;
31 import android.view.LayoutInflater;
32 import android.view.View;
33 import android.view.View.OnClickListener;
34 import android.view.ViewGroup;
35 import android.widget.Button;
36 import android.widget.ImageView;
37 import android.widget.TextView;
38 import android.widget.Toast;
39
40 import com.actionbarsherlock.app.SherlockFragment;
41
42 import eu.alefzero.owncloud.DisplayUtils;
43 import eu.alefzero.owncloud.FileDownloader;
44 import eu.alefzero.owncloud.R;
45 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
46 import eu.alefzero.owncloud.datamodel.OCFile;
47 import eu.alefzero.owncloud.utils.OwnCloudVersion;
48
49 /**
50 * This Fragment is used to display the details about a file.
51 *
52 * @author Bartek Przybylski
53 *
54 */
55 public class FileDetailFragment extends SherlockFragment implements
56 OnClickListener {
57
58 public static final String EXTRA_FILE = "FILE";
59
60 private DownloadFinishReceiver mDownloadFinishReceiver;
61 private Intent mIntent;
62 private int mLayout;
63 private View mView;
64 private OCFile mFile;
65 private static final String TAG = "FileDetailFragment";
66
67 /**
68 * Default constructor - contains real layout
69 */
70 public FileDetailFragment(){
71 mLayout = R.layout.file_details_fragment;
72 }
73
74 /**
75 * Creates a dummy layout. For use if the user never has
76 * tapped on a file before
77 *
78 * @param useEmptyView If true, use empty layout
79 */
80 public FileDetailFragment(boolean useEmptyView){
81 if(useEmptyView){
82 mLayout = R.layout.file_details_empty;
83 } else {
84 mLayout = R.layout.file_details_fragment;
85 }
86 }
87
88 /**
89 * Use this when creating the fragment and display
90 * a file at the same time
91 *
92 * @param showDetailsIntent The Intent with the required parameters
93 * @see FileDetailFragment#updateFileDetails(Intent)
94 */
95 public FileDetailFragment(Intent showDetailsIntent) {
96 mIntent = showDetailsIntent;
97 mLayout = R.layout.file_details_fragment;
98 }
99
100 @Override
101 public void onResume() {
102 super.onResume();
103 mDownloadFinishReceiver = new DownloadFinishReceiver();
104 IntentFilter filter = new IntentFilter(
105 FileDownloader.DOWNLOAD_FINISH_MESSAGE);
106 getActivity().registerReceiver(mDownloadFinishReceiver, filter);
107 }
108
109 @Override
110 public void onPause() {
111 super.onPause();
112 getActivity().unregisterReceiver(mDownloadFinishReceiver);
113 mDownloadFinishReceiver = null;
114 }
115
116 @Override
117 public View onCreateView(LayoutInflater inflater, ViewGroup container,
118 Bundle savedInstanceState) {
119 View view = null;
120 view = inflater.inflate(mLayout, container, false);
121 mView = view;
122 if(mLayout == R.layout.file_details_fragment){
123 // Phones will launch an activity with this intent
124 if(mIntent == null){
125 mIntent = getActivity().getIntent();
126 }
127 updateFileDetails();
128 }
129
130 return view;
131 }
132
133 @Override
134 public View getView() {
135 return super.getView() == null ? mView : super.getView();
136 }
137
138 @Override
139 public void onClick(View v) {
140 Toast.makeText(getActivity(), "Downloading", Toast.LENGTH_LONG).show();
141 Intent i = new Intent(getActivity(), FileDownloader.class);
142 i.putExtra(FileDownloader.EXTRA_ACCOUNT,
143 mIntent.getParcelableExtra(FileDownloader.EXTRA_ACCOUNT));
144 i.putExtra(FileDownloader.EXTRA_FILE_PATH, mFile.getRemotePath());
145 getActivity().startService(i);
146 }
147
148 /**
149 * Can be used to get the file that is currently being displayed.
150 * @return The file on the screen.
151 */
152 public OCFile getDisplayedFile(){
153 return mFile;
154 }
155
156 /**
157 * Use this method to signal this Activity that it shall update its view.
158 *
159 * @param intent The {@link Intent} that contains extra information about
160 * this file The intent needs to have these extras:
161 * <p>
162 *
163 * {@link FileDetailFragment#EXTRA_FILE}: An {@link OCFile}
164 * {@link FileDownloader#EXTRA_ACCOUNT}: The Account that file
165 * belongs to (required for downloading)
166 */
167 public void updateFileDetails(Intent intent) {
168 mIntent = intent;
169 updateFileDetails();
170 }
171
172 /**
173 * Updates the view with all relevant details about that file.
174 */
175 private void updateFileDetails() {
176 mFile = mIntent.getParcelableExtra(EXTRA_FILE);
177 Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
178
179 if (mFile != null) {
180 // set file details
181 setFilename(mFile.getFileName());
182 setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile
183 .getMimetype()));
184 setFilesize(mFile.getFileLength());
185 if(ocVersionSupportsTimeCreated()){
186 setTimeCreated(mFile.getCreationTimestamp());
187 }
188
189 setTimeModified(mFile.getModificationTimestamp());
190
191 // Update preview
192 if (mFile.getStoragePath() != null) {
193 try {
194 if (mFile.getMimetype().startsWith("image/")) {
195 ImageView preview = (ImageView) getView().findViewById(
196 R.id.fdPreview);
197 Bitmap bmp = BitmapFactory.decodeFile(mFile.getStoragePath());
198 preview.setImageBitmap(bmp);
199 }
200 } catch (OutOfMemoryError e) {
201 Log.e(TAG, "Out of memory occured for file with size " + mFile.getFileLength());
202 }
203 downloadButton.setText(R.string.filedetails_open);
204 downloadButton.setOnClickListener(new OnClickListener() {
205 @Override
206 public void onClick(View v) {
207 Intent i = new Intent(Intent.ACTION_VIEW);
208 i.setDataAndType(Uri.parse("file://"+mFile.getStoragePath()), mFile.getMimetype());
209 startActivity(i);
210 }
211 });
212 } else {
213 // Make download button effective
214 downloadButton.setOnClickListener(this);
215 }
216 }
217 }
218
219 /**
220 * Updates the filename in view
221 * @param filename to set
222 */
223 private void setFilename(String filename) {
224 TextView tv = (TextView) getView().findViewById(R.id.fdFilename);
225 if (tv != null)
226 tv.setText(filename);
227 }
228
229 /**
230 * Updates the MIME type in view
231 * @param mimetype to set
232 */
233 private void setFiletype(String mimetype) {
234 TextView tv = (TextView) getView().findViewById(R.id.fdType);
235 if (tv != null)
236 tv.setText(mimetype);
237 }
238
239 /**
240 * Updates the file size in view
241 * @param filesize in bytes to set
242 */
243 private void setFilesize(long filesize) {
244 TextView tv = (TextView) getView().findViewById(R.id.fdSize);
245 if (tv != null)
246 tv.setText(DisplayUtils.bytesToHumanReadable(filesize));
247 }
248
249 /**
250 * Updates the time that the file was created in view
251 * @param milliseconds Unix time to set
252 */
253 private void setTimeCreated(long milliseconds){
254 TextView tv = (TextView) getView().findViewById(R.id.fdCreated);
255 TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);
256 if(tv != null){
257 tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
258 tv.setVisibility(View.VISIBLE);
259 tvLabel.setVisibility(View.VISIBLE);
260 }
261 }
262
263 /**
264 * Updates the time that the file was last modified
265 * @param milliseconds Unix time to set
266 */
267 private void setTimeModified(long milliseconds){
268 TextView tv = (TextView) getView().findViewById(R.id.fdModified);
269 if(tv != null){
270 tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
271 }
272 }
273
274 /**
275 * In ownCloud 3.0.3 and 4.0.0 there is a bug that SabreDAV does not return
276 * the time that the file was created. There is a chance that this will
277 * be fixed in future versions. Use this method to check if this version of
278 * ownCloud has this fix.
279 * @return True, if ownCloud the ownCloud version is > 3.0.4 and 4.0.1
280 */
281 private boolean ocVersionSupportsTimeCreated(){
282 if(mIntent != null){
283 Account ocAccount = mIntent.getParcelableExtra(FileDownloader.EXTRA_ACCOUNT);
284 if(ocAccount != null){
285 AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);
286 OwnCloudVersion ocVersion = new OwnCloudVersion(accManager
287 .getUserData(ocAccount, AccountAuthenticator.KEY_OC_VERSION));
288 if(ocVersion.compareTo(new OwnCloudVersion(0x030004)) >= 0 || ocVersion.compareTo(new OwnCloudVersion(0x040001)) >= 0){
289 return true;
290 }
291 }
292 }
293 return false;
294 }
295
296 /**
297 * Once the file download has finished -> update view
298 * @author Bartek Przybylski
299 */
300 private class DownloadFinishReceiver extends BroadcastReceiver {
301 @Override
302 public void onReceive(Context context, Intent intent) {
303 updateFileDetails();
304 }
305
306 }
307
308 }