Fixed ClassCastingException
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / activity / FileDetailActivity.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 com.owncloud.android.ui.activity;
19
20 import java.lang.ref.WeakReference;
21
22 import android.accounts.Account;
23 import android.app.Dialog;
24 import android.app.ProgressDialog;
25 import android.content.ComponentName;
26 import android.content.Context;
27 import android.content.Intent;
28 import android.content.ServiceConnection;
29 import android.content.res.Configuration;
30 import android.os.Bundle;
31 import android.os.IBinder;
32 import android.support.v4.app.Fragment;
33 import android.support.v4.app.FragmentTransaction;
34 import android.util.Log;
35 import android.widget.ProgressBar;
36
37 import com.actionbarsherlock.app.ActionBar;
38 import com.actionbarsherlock.app.SherlockFragmentActivity;
39 import com.actionbarsherlock.view.MenuItem;
40 import com.owncloud.android.datamodel.OCFile;
41 import com.owncloud.android.files.services.FileDownloader;
42 import com.owncloud.android.files.services.FileDownloader.FileDownloaderBinder;
43 import com.owncloud.android.files.services.FileUploader;
44 import com.owncloud.android.files.services.FileUploader.FileUploaderBinder;
45 import com.owncloud.android.ui.fragment.FileDetailFragment;
46 import com.owncloud.android.ui.fragment.FilePreviewFragment;
47
48 import com.owncloud.android.R;
49
50 import eu.alefzero.webdav.OnDatatransferProgressListener;
51
52 /**
53 * This activity displays the details of a file like its name, its size and so
54 * on.
55 *
56 * @author Bartek Przybylski
57 * @author David A. Velasco
58 */
59 public class FileDetailActivity extends SherlockFragmentActivity implements FileDetailFragment.ContainerActivity {
60
61 public static final int DIALOG_SHORT_WAIT = 0;
62
63 public static final String TAG = FileDetailActivity.class.getSimpleName();
64
65 public static final String EXTRA_MODE = "MODE";
66 public static final int MODE_DETAILS = 0;
67 public static final int MODE_PREVIEW = 1;
68
69 private static final String KEY_WAITING_TO_PREVIEW = "WAITING_TO_PREVIEW";
70
71 private boolean mConfigurationChangedToLandscape = false;
72 private FileDownloaderBinder mDownloaderBinder = null;
73 private ServiceConnection mDownloadConnection, mUploadConnection = null;
74 private FileUploaderBinder mUploaderBinder = null;
75 private boolean mWaitingToPreview;
76
77 public ProgressListener mProgressListener;
78
79
80 @Override
81 protected void onCreate(Bundle savedInstanceState) {
82 super.onCreate(savedInstanceState);
83
84 // check if configuration changed to large-land ; for a tablet being changed from portrait to landscape when in FileDetailActivity
85 Configuration conf = getResources().getConfiguration();
86 mConfigurationChangedToLandscape = (conf.orientation == Configuration.ORIENTATION_LANDSCAPE &&
87 (conf.screenLayout & Configuration.SCREENLAYOUT_SIZE_MASK) >= Configuration.SCREENLAYOUT_SIZE_LARGE
88 );
89
90 if (!mConfigurationChangedToLandscape) {
91 mDownloadConnection = new DetailsServiceConnection();
92 bindService(new Intent(this, FileDownloader.class), mDownloadConnection, Context.BIND_AUTO_CREATE);
93 mUploadConnection = new DetailsServiceConnection();
94 bindService(new Intent(this, FileUploader.class), mUploadConnection, Context.BIND_AUTO_CREATE);
95
96 setContentView(R.layout.file_activity_details);
97
98 ActionBar actionBar = getSupportActionBar();
99 actionBar.setDisplayHomeAsUpEnabled(true);
100
101 if (savedInstanceState == null) {
102 mWaitingToPreview = false;
103 createChildFragment();
104 } else {
105 mWaitingToPreview = savedInstanceState.getBoolean(KEY_WAITING_TO_PREVIEW);
106 }
107
108 } else {
109 backToDisplayActivity(); // the 'back' won't be effective until this.onStart() and this.onResume() are completed;
110 }
111
112
113 }
114
115 /**
116 * Creates the proper fragment depending upon the state of the handled {@link OCFile} and
117 * the requested {@link Intent}.
118 */
119 private void createChildFragment() {
120 OCFile file = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE);
121 Account account = getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT);
122 int mode = getIntent().getIntExtra(EXTRA_MODE, MODE_PREVIEW);
123
124 Fragment newFragment = null;
125 if (FilePreviewFragment.canBePreviewed(file) && mode == MODE_PREVIEW) {
126 if (file.isDown()) {
127 newFragment = new FilePreviewFragment(file, account);
128
129 } else {
130 newFragment = new FileDetailFragment(file, account);
131 mWaitingToPreview = true;
132 }
133
134 } else {
135 newFragment = new FileDetailFragment(file, account);
136 }
137 FragmentTransaction ft = getSupportFragmentManager().beginTransaction();
138 ft.replace(R.id.fragment, newFragment, FileDetailFragment.FTAG);
139 ft.commit();
140 }
141
142
143 @Override
144 protected void onSaveInstanceState(Bundle outState) {
145 outState.putBoolean(KEY_WAITING_TO_PREVIEW, mWaitingToPreview);
146 }
147
148
149 /** Defines callbacks for service binding, passed to bindService() */
150 private class DetailsServiceConnection implements ServiceConnection {
151
152 @Override
153 public void onServiceConnected(ComponentName component, IBinder service) {
154 Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
155 FileDetailFragment detailsFragment = (fragment instanceof FileDetailFragment) ? (FileDetailFragment) fragment : null;
156
157 if (component.equals(new ComponentName(FileDetailActivity.this, FileDownloader.class))) {
158 Log.d(TAG, "Download service connected");
159 mDownloaderBinder = (FileDownloaderBinder) service;
160 if (detailsFragment != null) {
161 mProgressListener = new ProgressListener(detailsFragment.getProgressBar());
162 mDownloaderBinder.addDatatransferProgressListener(
163 mProgressListener,
164 (Account) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT),
165 (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE)
166 );
167 }
168 } else if (component.equals(new ComponentName(FileDetailActivity.this, FileUploader.class))) {
169 Log.d(TAG, "Upload service connected");
170 mUploaderBinder = (FileUploaderBinder) service;
171 if (detailsFragment != null) {
172 mProgressListener = new ProgressListener(detailsFragment.getProgressBar());
173 mUploaderBinder.addDatatransferProgressListener(
174 mProgressListener,
175 (Account) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT),
176 (OCFile) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE)
177 );
178 }
179 } else {
180 return;
181 }
182
183 if (detailsFragment != null) {
184 detailsFragment.updateFileDetails(false); // let the fragment gets the mDownloadBinder through getDownloadBinder() (see FileDetailFragment#updateFileDetais())
185 }
186 }
187
188 @Override
189 public void onServiceDisconnected(ComponentName component) {
190 if (component.equals(new ComponentName(FileDetailActivity.this, FileDownloader.class))) {
191 Log.d(TAG, "Download service disconnected");
192 mDownloaderBinder = null;
193 } else if (component.equals(new ComponentName(FileDetailActivity.this, FileUploader.class))) {
194 Log.d(TAG, "Upload service disconnected");
195 mUploaderBinder = null;
196 }
197 }
198 };
199
200
201 /**
202 * Helper class responsible for updating the progress bar shown for file uploading or downloading
203 *
204 * @author David A. Velasco
205 */
206 private class ProgressListener implements OnDatatransferProgressListener {
207 int mLastPercent = 0;
208 WeakReference<ProgressBar> mProgressBar = null;
209
210 ProgressListener(ProgressBar progressBar) {
211 mProgressBar = new WeakReference<ProgressBar>(progressBar);
212 }
213
214 @Override
215 public void onTransferProgress(long progressRate) {
216 // old method, nothing here
217 };
218
219 @Override
220 public void onTransferProgress(long progressRate, long totalTransferredSoFar, long totalToTransfer, String filename) {
221 int percent = (int)(100.0*((double)totalTransferredSoFar)/((double)totalToTransfer));
222 if (percent != mLastPercent) {
223 ProgressBar pb = mProgressBar.get();
224 if (pb != null) {
225 pb.setProgress(percent);
226 }
227 }
228 mLastPercent = percent;
229 }
230
231 };
232
233
234 @Override
235 public void onDestroy() {
236 super.onDestroy();
237 if (mDownloadConnection != null) {
238 unbindService(mDownloadConnection);
239 mDownloadConnection = null;
240 }
241 if (mUploadConnection != null) {
242 unbindService(mUploadConnection);
243 mUploadConnection = null;
244 }
245 }
246
247
248 @Override
249 public boolean onOptionsItemSelected(MenuItem item) {
250 boolean returnValue = false;
251
252 switch(item.getItemId()){
253 case android.R.id.home:
254 backToDisplayActivity();
255 returnValue = true;
256 break;
257 default:
258 returnValue = super.onOptionsItemSelected(item);
259 }
260
261 return returnValue;
262 }
263
264
265
266 @Override
267 protected void onResume() {
268
269 super.onResume();
270 if (!mConfigurationChangedToLandscape) {
271 Fragment fragment = getSupportFragmentManager().findFragmentByTag(FileDetailFragment.FTAG);
272 if (fragment != null && fragment instanceof FileDetailFragment) {
273 ((FileDetailFragment) fragment).updateFileDetails(false);
274 }
275 }
276 }
277
278
279 private void backToDisplayActivity() {
280 Intent intent = new Intent(this, FileDisplayActivity.class);
281 intent.addFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP);
282 intent.putExtra(FileDetailFragment.EXTRA_FILE, getIntent().getParcelableExtra(FileDetailFragment.EXTRA_FILE));
283 intent.putExtra(FileDetailFragment.EXTRA_ACCOUNT, getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT));
284 startActivity(intent);
285 finish();
286 }
287
288
289 @Override
290 protected Dialog onCreateDialog(int id) {
291 Dialog dialog = null;
292 switch (id) {
293 case DIALOG_SHORT_WAIT: {
294 ProgressDialog working_dialog = new ProgressDialog(this);
295 working_dialog.setMessage(getResources().getString(
296 R.string.wait_a_moment));
297 working_dialog.setIndeterminate(true);
298 working_dialog.setCancelable(false);
299 dialog = working_dialog;
300 break;
301 }
302 default:
303 dialog = null;
304 }
305 return dialog;
306 }
307
308
309 /**
310 * {@inheritDoc}
311 */
312 @Override
313 public void onFileStateChanged() {
314 // nothing to do here!
315 }
316
317
318 /**
319 * {@inheritDoc}
320 */
321 @Override
322 public FileDownloaderBinder getFileDownloaderBinder() {
323 return mDownloaderBinder;
324 }
325
326
327 @Override
328 public FileUploaderBinder getFileUploaderBinder() {
329 return mUploaderBinder;
330 }
331
332
333 @Override
334 public void showFragmentWithDetails(OCFile file) {
335 FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
336 transaction.replace(R.id.fragment, new FileDetailFragment(file, (Account) getIntent().getParcelableExtra(FileDetailFragment.EXTRA_ACCOUNT)), FileDetailFragment.FTAG);
337 transaction.commit();
338 }
339
340 }