c1511aae07d606fe6c7a81ba8260dd227c10ec0b
[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.Menu;
11 import android.view.MenuInflater;
12 import android.view.MenuItem;
13 import android.view.View;
14 import android.view.ViewGroup;
15 import android.widget.TextView;
16
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(PreviewTextFragment.EXTRA_FILE, getFile());
115 outState.putParcelable(PreviewTextFragment.EXTRA_ACCOUNT, mAccount);
116 }
117
118 @Override
119 public void onStart() {
120 super.onStart();
121 Log_OC.e(TAG, "onStart");
122
123 loadAndShowTextPreview();
124 }
125
126 private void loadAndShowTextPreview() {
127 mTextLoadTask = new TextLoadAsyncTask(new WeakReference<TextView>(mTextPreview));
128 mTextLoadTask.execute(getFile().getStoragePath());
129 }
130
131
132 /**
133 * Reads the file to preview and shows its contents. Too critical to be anonymous.
134 */
135 private class TextLoadAsyncTask extends AsyncTask<Object, Void, StringWriter> {
136 private final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
137 private final WeakReference<TextView> mTextViewReference;
138
139 private TextLoadAsyncTask(WeakReference<TextView> textView) {
140 mTextViewReference = textView;
141 }
142
143
144 @Override
145 protected void onPreExecute() {
146 showLoadingDialog();
147 }
148
149 @Override
150 protected StringWriter doInBackground(java.lang.Object... params) {
151 if (params.length != 1) {
152 throw new IllegalArgumentException("The parameter to " + TextLoadAsyncTask.class.getName() + " must be (1) the file location");
153 }
154 final String location = (String) params[0];
155
156 FileInputStream inputStream = null;
157 Scanner sc = null;
158 StringWriter source = new StringWriter();
159 BufferedWriter bufferedWriter = new BufferedWriter(source);
160 try {
161 inputStream = new FileInputStream(location);
162 sc = new Scanner(inputStream);
163 while (sc.hasNextLine()) {
164 bufferedWriter.append(sc.nextLine());
165 if (sc.hasNextLine()) bufferedWriter.append("\n");
166 }
167 bufferedWriter.close();
168 IOException exc = sc.ioException();
169 if (exc != null) throw exc;
170 } catch (IOException e) {
171 Log_OC.e(TAG, e.getMessage(), e);
172 finish();
173 } finally {
174 if (inputStream != null) {
175 try {
176 inputStream.close();
177 } catch (IOException e) {
178 Log_OC.e(TAG, e.getMessage(), e);
179 finish();
180 }
181 }
182 if (sc != null) {
183 sc.close();
184 }
185 }
186 return source;
187 }
188
189 @Override
190 protected void onPostExecute(final StringWriter stringWriter) {
191 final TextView textView = mTextViewReference.get();
192
193 if (textView != null) {
194 textView.setText(new String(stringWriter.getBuffer()));
195 textView.setVisibility(View.VISIBLE);
196 }
197
198 dismissLoadingDialog();
199 }
200
201 /**
202 * Show loading dialog
203 */
204 public void showLoadingDialog() {
205 // only once
206 Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
207 LoadingDialog loading = null;
208 if (frag == null) {
209 // Construct dialog
210 loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
211 FragmentManager fm = getActivity().getSupportFragmentManager();
212 FragmentTransaction ft = fm.beginTransaction();
213 loading.show(ft, DIALOG_WAIT_TAG);
214 } else {
215 loading = (LoadingDialog) frag;
216 loading.setShowsDialog(true);
217 }
218
219 }
220
221 /**
222 * Dismiss loading dialog
223 */
224 public void dismissLoadingDialog() {
225 final Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
226 if (frag != null) {
227 LoadingDialog loading = (LoadingDialog) frag;
228 loading.dismiss();
229 }
230 }
231 }
232
233 /**
234 * {@inheritDoc}
235 */
236 @Override
237 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
238 super.onCreateOptionsMenu(menu, inflater);
239 inflater.inflate(R.menu.file_actions_menu, menu);
240 }
241
242 /**
243 * {@inheritDoc}
244 */
245 @Override
246 public void onPrepareOptionsMenu(Menu menu) {
247 super.onPrepareOptionsMenu(menu);
248
249 if (mContainerActivity.getStorageManager() != null) {
250 FileMenuFilter mf = new FileMenuFilter(
251 getFile(),
252 mContainerActivity.getStorageManager().getAccount(),
253 mContainerActivity,
254 getActivity()
255 );
256 mf.filter(menu);
257 }
258
259 // additional restriction for this fragment
260 MenuItem item = menu.findItem(R.id.action_rename_file);
261 if (item != null) {
262 item.setVisible(false);
263 item.setEnabled(false);
264 }
265
266 // additional restriction for this fragment
267 item = menu.findItem(R.id.action_move);
268 if (item != null) {
269 item.setVisible(false);
270 item.setEnabled(false);
271 }
272
273 // this one doesn't make sense since the file has to be down in order to be previewed
274 item = menu.findItem(R.id.action_download_file);
275 if (item != null) {
276 item.setVisible(false);
277 item.setEnabled(false);
278 }
279
280 item = menu.findItem(R.id.action_sync_file);
281 if (item != null) {
282 item.setVisible(false);
283 item.setEnabled(false);
284 }
285
286 item = menu.findItem(R.id.action_sync_account);
287 if (item != null) {
288 item.setVisible(false);
289 item.setEnabled(false);
290 }
291 }
292
293 /**
294 * {@inheritDoc}
295 */
296 @Override
297 public boolean onOptionsItemSelected(MenuItem item) {
298 switch (item.getItemId()) {
299 case R.id.action_share_file: {
300 mContainerActivity.getFileOperationsHelper().shareFileWithLink(getFile());
301 return true;
302 }
303 case R.id.action_unshare_file: {
304 mContainerActivity.getFileOperationsHelper().unshareFileWithLink(getFile());
305 return true;
306 }
307 case R.id.action_open_file_with: {
308 openFile();
309 return true;
310 }
311 case R.id.action_remove_file: {
312 RemoveFileDialogFragment dialog = RemoveFileDialogFragment.newInstance(getFile());
313 dialog.show(getFragmentManager(), ConfirmationDialogFragment.FTAG_CONFIRMATION);
314 return true;
315 }
316 case R.id.action_see_details: {
317 seeDetails();
318 return true;
319 }
320 case R.id.action_send_file: {
321 sendFile();
322 return true;
323 }
324 case R.id.action_sync_file: {
325 mContainerActivity.getFileOperationsHelper().syncFile(getFile());
326 return true;
327 }
328
329 default:
330 return false;
331 }
332 }
333
334 /**
335 * Update the file of the fragment with file value
336 *
337 * @param file The new file to set
338 */
339 public void updateFile(OCFile file) {
340 setFile(file);
341 }
342
343 private void sendFile() {
344 mContainerActivity.getFileOperationsHelper().sendDownloadedFile(getFile());
345 }
346
347 private void seeDetails() {
348 mContainerActivity.showDetails(getFile());
349 }
350
351 @Override
352 public void onPause() {
353 Log_OC.e(TAG, "onPause");
354 super.onPause();
355 }
356
357 @Override
358 public void onResume() {
359 super.onResume();
360 Log_OC.e(TAG, "onResume");
361 }
362
363 @Override
364 public void onDestroy() {
365 Log_OC.e(TAG, "onDestroy");
366 super.onDestroy();
367 }
368
369 @Override
370 public void onStop() {
371 super.onStop();
372 Log_OC.e(TAG, "onStop");
373 if (mTextLoadTask != null)
374 mTextLoadTask.cancel(Boolean.TRUE);
375 }
376
377 /**
378 * Opens the previewed file with an external application.
379 */
380 private void openFile() {
381 mContainerActivity.getFileOperationsHelper().openFile(getFile());
382 finish();
383 }
384
385 /**
386 * Helper method to test if an {@link OCFile} can be passed to a {@link PreviewTextFragment} to be previewed.
387 *
388 * @param file File to test if can be previewed.
389 * @return 'True' if the file can be handled by the fragment.
390 */
391 public static boolean canBePreviewed(OCFile file) {
392 return (file != null && file.isDown() && file.isText());
393 }
394
395 /**
396 * Finishes the preview
397 */
398 private void finish() {
399 getActivity().runOnUiThread(new Runnable() {
400 @Override
401 public void run() {
402 getActivity().onBackPressed();
403 }
404 });
405 }
406 }