2241f6f6c9f2192754a08049e40f6971cd0aaae8
[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.R;
44 import eu.alefzero.owncloud.authenticator.AccountAuthenticator;
45 import eu.alefzero.owncloud.datamodel.OCFile;
46 import eu.alefzero.owncloud.files.services.FileDownloader;
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 i.putExtra(FileDownloader.EXTRA_FILE_SIZE, mFile.getFileLength());
146 getActivity().startService(i);
147 }
148
149 /**
150 * Can be used to get the file that is currently being displayed.
151 * @return The file on the screen.
152 */
153 public OCFile getDisplayedFile(){
154 return mFile;
155 }
156
157 /**
158 * Use this method to signal this Activity that it shall update its view.
159 *
160 * @param intent The {@link Intent} that contains extra information about
161 * this file The intent needs to have these extras:
162 * <p>
163 *
164 * {@link FileDetailFragment#EXTRA_FILE}: An {@link OCFile}
165 * {@link FileDownloader#EXTRA_ACCOUNT}: The Account that file
166 * belongs to (required for downloading)
167 */
168 public void updateFileDetails(Intent intent) {
169 mIntent = intent;
170 updateFileDetails();
171 }
172
173 /**
174 * Updates the view with all relevant details about that file.
175 */
176 private void updateFileDetails() {
177 mFile = mIntent.getParcelableExtra(EXTRA_FILE);
178 Button downloadButton = (Button) getView().findViewById(R.id.fdDownloadBtn);
179
180 if (mFile != null) {
181 // set file details
182 setFilename(mFile.getFileName());
183 setFiletype(DisplayUtils.convertMIMEtoPrettyPrint(mFile
184 .getMimetype()));
185 setFilesize(mFile.getFileLength());
186 if(ocVersionSupportsTimeCreated()){
187 setTimeCreated(mFile.getCreationTimestamp());
188 }
189
190 setTimeModified(mFile.getModificationTimestamp());
191
192 // Update preview
193 if (mFile.getStoragePath() != null) {
194 try {
195 if (mFile.getMimetype().startsWith("image/")) {
196 ImageView preview = (ImageView) getView().findViewById(
197 R.id.fdPreview);
198 Bitmap bmp = BitmapFactory.decodeFile(mFile.getStoragePath());
199 preview.setImageBitmap(bmp);
200 }
201 } catch (OutOfMemoryError e) {
202 Log.e(TAG, "Out of memory occured for file with size " + mFile.getFileLength());
203 }
204 downloadButton.setText(R.string.filedetails_open);
205 downloadButton.setOnClickListener(new OnClickListener() {
206 @Override
207 public void onClick(View v) {
208 Intent i = new Intent(Intent.ACTION_VIEW);
209 i.setDataAndType(Uri.parse("file://"+mFile.getStoragePath()), mFile.getMimetype());
210 startActivity(i);
211 }
212 });
213 } else {
214 // Make download button effective
215 downloadButton.setOnClickListener(this);
216 }
217 }
218 }
219
220 /**
221 * Updates the filename in view
222 * @param filename to set
223 */
224 private void setFilename(String filename) {
225 TextView tv = (TextView) getView().findViewById(R.id.fdFilename);
226 if (tv != null)
227 tv.setText(filename);
228 }
229
230 /**
231 * Updates the MIME type in view
232 * @param mimetype to set
233 */
234 private void setFiletype(String mimetype) {
235 TextView tv = (TextView) getView().findViewById(R.id.fdType);
236 if (tv != null)
237 tv.setText(mimetype);
238 }
239
240 /**
241 * Updates the file size in view
242 * @param filesize in bytes to set
243 */
244 private void setFilesize(long filesize) {
245 TextView tv = (TextView) getView().findViewById(R.id.fdSize);
246 if (tv != null)
247 tv.setText(DisplayUtils.bytesToHumanReadable(filesize));
248 }
249
250 /**
251 * Updates the time that the file was created in view
252 * @param milliseconds Unix time to set
253 */
254 private void setTimeCreated(long milliseconds){
255 TextView tv = (TextView) getView().findViewById(R.id.fdCreated);
256 TextView tvLabel = (TextView) getView().findViewById(R.id.fdCreatedLabel);
257 if(tv != null){
258 tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
259 tv.setVisibility(View.VISIBLE);
260 tvLabel.setVisibility(View.VISIBLE);
261 }
262 }
263
264 /**
265 * Updates the time that the file was last modified
266 * @param milliseconds Unix time to set
267 */
268 private void setTimeModified(long milliseconds){
269 TextView tv = (TextView) getView().findViewById(R.id.fdModified);
270 if(tv != null){
271 tv.setText(DisplayUtils.unixTimeToHumanReadable(milliseconds));
272 }
273 }
274
275 /**
276 * In ownCloud 3.0.3 and 4.0.0 there is a bug that SabreDAV does not return
277 * the time that the file was created. There is a chance that this will
278 * be fixed in future versions. Use this method to check if this version of
279 * ownCloud has this fix.
280 * @return True, if ownCloud the ownCloud version is > 3.0.4 and 4.0.1
281 */
282 private boolean ocVersionSupportsTimeCreated(){
283 if(mIntent != null){
284 Account ocAccount = mIntent.getParcelableExtra(FileDownloader.EXTRA_ACCOUNT);
285 if(ocAccount != null){
286 AccountManager accManager = (AccountManager) getActivity().getSystemService(Context.ACCOUNT_SERVICE);
287 OwnCloudVersion ocVersion = new OwnCloudVersion(accManager
288 .getUserData(ocAccount, AccountAuthenticator.KEY_OC_VERSION));
289 if(ocVersion.compareTo(new OwnCloudVersion(0x030004)) >= 0 || ocVersion.compareTo(new OwnCloudVersion(0x040001)) >= 0){
290 return true;
291 }
292 }
293 }
294 return false;
295 }
296
297 /**
298 * Once the file download has finished -> update view
299 * @author Bartek Przybylski
300 */
301 private class DownloadFinishReceiver extends BroadcastReceiver {
302 @Override
303 public void onReceive(Context context, Intent intent) {
304 updateFileDetails();
305 }
306
307 }
308
309 }