Implementation of the requested changes to the asynctask that loads the text
[pub/Android/ownCloud.git] / src / com / owncloud / android / ui / preview / PreviewTextFragment.java
1 package com.owncloud.android.ui.preview;
2
3 import android.accounts.Account;
4 import android.os.AsyncTask;
5 import android.os.Bundle;
6 import android.support.v4.app.Fragment;
7 import android.support.v4.app.FragmentManager;
8 import android.support.v4.app.FragmentTransaction;
9 import android.view.LayoutInflater;
10 import android.view.View;
11 import android.view.ViewGroup;
12 import android.widget.TextView;
13
14 import com.actionbarsherlock.view.Menu;
15 import com.actionbarsherlock.view.MenuInflater;
16 import com.actionbarsherlock.view.MenuItem;
17 import com.owncloud.android.R;
18 import com.owncloud.android.datamodel.OCFile;
19 import com.owncloud.android.files.FileMenuFilter;
20 import com.owncloud.android.lib.common.utils.Log_OC;
21 import com.owncloud.android.ui.activity.FileDisplayActivity;
22 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
23 import com.owncloud.android.ui.dialog.LoadingDialog;
24 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
25 import com.owncloud.android.ui.fragment.FileFragment;
26
27 import java.io.BufferedWriter;
28 import java.io.FileInputStream;
29 import java.io.IOException;
30 import java.io.StringWriter;
31 import java.lang.ref.WeakReference;
32 import java.util.Scanner;
33
34 public class PreviewTextFragment extends FileFragment {
35 private static final String EXTRA_FILE = "FILE";
36 private static final String EXTRA_ACCOUNT = "ACCOUNT";
37 private static final String TAG = PreviewTextFragment.class.getSimpleName();
38
39 private Account mAccount;
40 private TextView mTextPreview;
41 private TextLoadAsyncTask mTextLoadTask;
42
43 /**
44 * Creates an empty fragment for previews.
45 * <p/>
46 * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
47 * (for instance, when the device is turned a aside).
48 * <p/>
49 * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
50 * construction
51 */
52 public PreviewTextFragment() {
53 super();
54 mAccount = null;
55 }
56
57 /**
58 * {@inheritDoc}
59 */
60 @Override
61 public View onCreateView(LayoutInflater inflater, ViewGroup container,
62 Bundle savedInstanceState) {
63 super.onCreateView(inflater, container, savedInstanceState);
64 Log_OC.e(TAG, "onCreateView");
65
66
67 View ret = inflater.inflate(R.layout.text_file_preview, container, false);
68
69 mTextPreview = (TextView) ret.findViewById(R.id.text_preview);
70
71 return ret;
72 }
73
74 /**
75 * {@inheritDoc}
76 */
77 @Override
78 public void onCreate(Bundle savedInstanceState) {
79 super.onCreate(savedInstanceState);
80
81 OCFile file = getFile();
82
83 Bundle args = getArguments();
84
85 if (file == null) {
86 file = args.getParcelable(FileDisplayActivity.EXTRA_FILE);
87 }
88
89 if (mAccount == null) {
90 mAccount = args.getParcelable(FileDisplayActivity.EXTRA_ACCOUNT);
91 }
92
93 if (savedInstanceState == null) {
94 if (file == null) {
95 throw new IllegalStateException("Instanced with a NULL OCFile");
96 }
97 if (mAccount == null) {
98 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
99 }
100 } else {
101 file = savedInstanceState.getParcelable(EXTRA_FILE);
102 mAccount = savedInstanceState.getParcelable(EXTRA_ACCOUNT);
103 }
104 setFile(file);
105 setHasOptionsMenu(true);
106 }
107
108 /**
109 * {@inheritDoc}
110 */
111 @Override
112 public void onSaveInstanceState(Bundle outState) {
113 super.onSaveInstanceState(outState);
114 outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile());
115 outState.putParcelable(PreviewImageFragment.EXTRA_ACCOUNT, mAccount);
116 }
117
118 @Override
119 public void onStart() {
120 super.onStart();
121 Log_OC.e(TAG, "onStart");
122 }
123
124 private void loadAndShowTextPreview() {
125 mTextLoadTask = new TextLoadAsyncTask(new WeakReference<TextView>(mTextPreview));
126 mTextLoadTask.execute(getFile().getStoragePath());
127 }
128
129
130 /**
131 * Reads the file to preview and shows its contents. Too critical to be anonymous.
132 */
133 private class TextLoadAsyncTask extends AsyncTask<Object, Void, StringWriter> {
134 private final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
135 private final WeakReference<TextView> mTextViewReference;
136
137 private TextLoadAsyncTask(WeakReference<TextView> textView) {
138 mTextViewReference = textView;
139 }
140
141
142 @Override
143 protected void onPreExecute() {
144 showLoadingDialog();
145 }
146
147 @Override
148 protected StringWriter doInBackground(java.lang.Object... params) {
149 if (params.length != 1) {
150 throw new IllegalArgumentException("The parameter to " + TextLoadAsyncTask.class.getName() + " must be (1) the file location");
151 }
152 final String location = (String) params[0];
153
154 FileInputStream inputStream = null;
155 Scanner sc = null;
156 StringWriter source = new StringWriter();
157 BufferedWriter bufferedWriter = new BufferedWriter(source);
158 try {
159 inputStream = new FileInputStream(location);
160 sc = new Scanner(inputStream);
161 while (sc.hasNextLine()) {
162 bufferedWriter.append(sc.nextLine());
163 if (sc.hasNextLine()) bufferedWriter.append("\n");
164 }
165 bufferedWriter.close();
166 IOException exc = sc.ioException();
167 if (exc != null) throw exc;
168 } catch (IOException e) {
169 Log_OC.e(TAG, e.getMessage(), e);
170 finish();
171 } finally {
172 if (inputStream != null) {
173 try {
174 inputStream.close();
175 } catch (IOException e) {
176 Log_OC.e(TAG, e.getMessage(), e);
177 finish();
178 }
179 }
180 if (sc != null) {
181 sc.close();
182 }
183 }
184 return source;
185 }
186
187 @Override
188 protected void onPostExecute(final StringWriter stringWriter) {
189 final TextView textView = mTextViewReference.get();
190
191 if (textView != null) {
192 textView.setText(new String(stringWriter.getBuffer()));
193 textView.setVisibility(View.VISIBLE);
194 }
195
196 dismissLoadingDialog();
197 }
198
199 /**
200 * Show loading dialog
201 */
202 public void showLoadingDialog() {
203 // Construct dialog
204 LoadingDialog loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
205 FragmentManager fm = getActivity().getSupportFragmentManager();
206 FragmentTransaction ft = fm.beginTransaction();
207 loading.show(ft, DIALOG_WAIT_TAG);
208 }
209
210 /**
211 * Dismiss loading dialog
212 */
213 public void dismissLoadingDialog() {
214 final Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
215 if (frag != null) {
216 LoadingDialog loading = (LoadingDialog) frag;
217 loading.dismiss();
218 }
219 }
220 }
221
222 /**
223 * {@inheritDoc}
224 */
225 @Override
226 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
227 super.onCreateOptionsMenu(menu, inflater);
228 inflater.inflate(R.menu.file_actions_menu, menu);
229 }
230
231 /**
232 * {@inheritDoc}
233 */
234 @Override
235 public void onPrepareOptionsMenu(Menu menu) {
236 super.onPrepareOptionsMenu(menu);
237
238 if (mContainerActivity.getStorageManager() != null) {
239 FileMenuFilter mf = new FileMenuFilter(
240 getFile(),
241 mContainerActivity.getStorageManager().getAccount(),
242 mContainerActivity,
243 getSherlockActivity()
244 );
245 mf.filter(menu);
246 }
247
248 // additional restriction for this fragment
249 MenuItem item = menu.findItem(R.id.action_rename_file);
250 if (item != null) {
251 item.setVisible(false);
252 item.setEnabled(false);
253 }
254
255 // additional restriction for this fragment
256 item = menu.findItem(R.id.action_move);
257 if (item != null) {
258 item.setVisible(false);
259 item.setEnabled(false);
260 }
261
262 // this one doesn't make sense since the file has to be down in order to be previewed
263 item = menu.findItem(R.id.action_download_file);
264 if (item != null) {
265 item.setVisible(false);
266 item.setEnabled(false);
267 }
268
269 item = menu.findItem(R.id.action_settings);
270 if (item != null) {
271 item.setVisible(false);
272 item.setEnabled(false);
273 }
274
275 item = menu.findItem(R.id.action_logger);
276 if (item != null) {
277 item.setVisible(false);
278 item.setEnabled(false);
279 }
280
281 item = menu.findItem(R.id.action_sync_file);
282 if (item != null) {
283 item.setVisible(false);
284 item.setEnabled(false);
285 }
286
287 item = menu.findItem(R.id.action_sync_account);
288 if (item != null) {
289 item.setVisible(false);
290 item.setEnabled(false);
291 }
292 }
293
294 /**
295 * {@inheritDoc}
296 */
297 @Override
298 public boolean onOptionsItemSelected(MenuItem item) {
299 switch (item.getItemId()) {
300 case R.id.action_share_file: {
301 mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
302 return true;
303 }
304 case R.id.action_unshare_file: {
305 mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
306 return true;
307 }
308 case R.id.action_open_file_with: {
309 openFile();
310 return true;
311 }
312 case R.id.action_remove_file: {
313 RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(getFile());
314 dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
315 return true;
316 }
317 case R.id.action_see_details: {
318 seeDetails();
319 return true;
320 }
321 case R.id.action_send_file: {
322 sendFile();
323 return true;
324 }
325 case R.id.action_sync_file: {
326 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
327 return true;
328 }
329
330 default:
331 return false;
332 }
333 }
334
335 /**
336 * Update the file of the fragment with file value
337 *
338 * @param file The new file to set
339 */
340 public void updateFile(OCFile file) {
341 setFile(file);
342 }
343
344 private void sendFile() {
345 mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
346 }
347
348 private void seeDetails() {
349 mContainerActivity.showDetails(getFile());
350 }
351
352 @Override
353 public void onPause() {
354 Log_OC.e(TAG, "onPause");
355 super.onPause();
356 }
357
358 @Override
359 public void onResume() {
360 super.onResume();
361 Log_OC.e(TAG, "onResume");
362
363 loadAndShowTextPreview();
364 }
365
366 @Override
367 public void onDestroy() {
368 Log_OC.e(TAG, "onDestroy");
369 super.onDestroy();
370 }
371
372 @Override
373 public void onStop() {
374 super.onStop();
375 Log_OC.e(TAG, "onStop");
376 if (mTextLoadTask != null)
377 mTextLoadTask.cancel(Boolean.TRUE);
378 }
379
380 /**
381 * Opens the previewed file with an external application.
382 */
383 private void openFile() {
384 mContainerActivity.getFileOperationsHelper().openFile(getFile());
385 finish();
386 }
387
388 /**
389 * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewTextFragment} to be previewed.
390 *
391 * @param file File to test if can be previewed.
392 * @return 'True' if the file can be handled by the fragment.
393 */
394 public static boolean canBePreviewed(OCFile file) {
395 return (file != null && file.isDown() && file.isText());
396 }
397
398 /**
399 * Finishes the preview
400 */
401 private void finish() {
402 getActivity().runOnUiThread(new Runnable() {
403 @Override
404 public void run() {
405 getSherlockActivity().onBackPressed();
406 }
407 });
408 }
409 }