Merge commit 'refs/pr/707' into text_file_preview_pr_707_with
[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.owncloud.android.R;
15 import com.owncloud.android.datamodel.OCFile;
16 import com.owncloud.android.files.FileMenuFilter;
17 import com.owncloud.android.lib.common.utils.Log_OC;
18 import com.owncloud.android.ui.activity.FileDisplayActivity;
19 import com.owncloud.android.ui.dialog.ConfirmationDialogFragment;
20 import com.owncloud.android.ui.dialog.LoadingDialog;
21 import com.owncloud.android.ui.dialog.RemoveFileDialogFragment;
22 import com.owncloud.android.ui.fragment.FileFragment;
23
24 import java.io.BufferedWriter;
25 import java.io.FileInputStream;
26 import java.io.IOException;
27 import java.io.StringWriter;
28 import java.lang.ref.WeakReference;
29 import java.util.Scanner;
30
31 public class PreviewTextFragment extends FileFragment {
32 private static final String EXTRA_FILE = "FILE";
33 private static final String EXTRA_ACCOUNT = "ACCOUNT";
34 private static final String TAG = PreviewTextFragment.class.getSimpleName();
35
36 private Account mAccount;
37 private TextView mTextPreview;
38 private TextLoadAsyncTask mTextLoadTask;
39
40 /**
41 * Creates an empty fragment for previews.
42 * <p/>
43 * MUST BE KEPT: the system uses it when tries to reinstantiate a fragment automatically
44 * (for instance, when the device is turned a aside).
45 * <p/>
46 * DO NOT CALL IT: an {@link OCFile} and {@link Account} must be provided for a successful
47 * construction
48 */
49 public PreviewTextFragment() {
50 super();
51 mAccount = null;
52 }
53
54 /**
55 * {@inheritDoc}
56 */
57 @Override
58 public View onCreateView(LayoutInflater inflater, ViewGroup container,
59 Bundle savedInstanceState) {
60 super.onCreateView(inflater, container, savedInstanceState);
61 Log_OC.e(TAG, "onCreateView");
62
63
64 View ret = inflater.inflate(R.layout.text_file_preview, container, false);
65
66 mTextPreview = (TextView) ret.findViewById(R.id.text_preview);
67
68 return ret;
69 }
70
71 /**
72 * {@inheritDoc}
73 */
74 @Override
75 public void onCreate(Bundle savedInstanceState) {
76 super.onCreate(savedInstanceState);
77
78 OCFile file = getFile();
79
80 Bundle args = getArguments();
81
82 if (file == null) {
83 file = args.getParcelable(FileDisplayActivity.EXTRA_FILE);
84 }
85
86 if (mAccount == null) {
87 mAccount = args.getParcelable(FileDisplayActivity.EXTRA_ACCOUNT);
88 }
89
90 if (savedInstanceState == null) {
91 if (file == null) {
92 throw new IllegalStateException("Instanced with a NULL OCFile");
93 }
94 if (mAccount == null) {
95 throw new IllegalStateException("Instanced with a NULL ownCloud Account");
96 }
97 } else {
98 file = savedInstanceState.getParcelable(EXTRA_FILE);
99 mAccount = savedInstanceState.getParcelable(EXTRA_ACCOUNT);
100 }
101 setFile(file);
102 setHasOptionsMenu(true);
103 }
104
105 /**
106 * {@inheritDoc}
107 */
108 @Override
109 public void onSaveInstanceState(Bundle outState) {
110 super.onSaveInstanceState(outState);
111 outState.putParcelable(PreviewImageFragment.EXTRA_FILE, getFile());
112 outState.putParcelable(PreviewImageFragment.EXTRA_ACCOUNT, mAccount);
113 }
114
115 @Override
116 public void onStart() {
117 super.onStart();
118 Log_OC.e(TAG, "onStart");
119
120 loadAndShowTextPreview();
121 }
122
123 private void loadAndShowTextPreview() {
124 mTextLoadTask = new TextLoadAsyncTask(new WeakReference<TextView>(mTextPreview));
125 mTextLoadTask.execute(getFile().getStoragePath());
126 }
127
128
129 /**
130 * Reads the file to preview and shows its contents. Too critical to be anonymous.
131 */
132 private class TextLoadAsyncTask extends AsyncTask<Object, Void, StringWriter> {
133 private final String DIALOG_WAIT_TAG = "DIALOG_WAIT";
134 private final WeakReference<TextView> mTextViewReference;
135
136 private TextLoadAsyncTask(WeakReference<TextView> textView) {
137 mTextViewReference = textView;
138 }
139
140
141 @Override
142 protected void onPreExecute() {
143 showLoadingDialog();
144 }
145
146 @Override
147 protected StringWriter doInBackground(java.lang.Object... params) {
148 if (params.length != 1) {
149 throw new IllegalArgumentException("The parameter to " + TextLoadAsyncTask.class.getName() + " must be (1) the file location");
150 }
151 final String location = (String) params[0];
152
153 FileInputStream inputStream = null;
154 Scanner sc = null;
155 StringWriter source = new StringWriter();
156 BufferedWriter bufferedWriter = new BufferedWriter(source);
157 try {
158 inputStream = new FileInputStream(location);
159 sc = new Scanner(inputStream);
160 while (sc.hasNextLine()) {
161 bufferedWriter.append(sc.nextLine());
162 if (sc.hasNextLine()) bufferedWriter.append("\n");
163 }
164 bufferedWriter.close();
165 IOException exc = sc.ioException();
166 if (exc != null) throw exc;
167 } catch (IOException e) {
168 Log_OC.e(TAG, e.getMessage(), e);
169 finish();
170 } finally {
171 if (inputStream != null) {
172 try {
173 inputStream.close();
174 } catch (IOException e) {
175 Log_OC.e(TAG, e.getMessage(), e);
176 finish();
177 }
178 }
179 if (sc != null) {
180 sc.close();
181 }
182 }
183 return source;
184 }
185
186 @Override
187 protected void onPostExecute(final StringWriter stringWriter) {
188 final TextView textView = mTextViewReference.get();
189
190 if (textView != null) {
191 textView.setText(new String(stringWriter.getBuffer()));
192 textView.setVisibility(View.VISIBLE);
193 }
194
195 dismissLoadingDialog();
196 }
197
198 /**
199 * Show loading dialog
200 */
201 public void showLoadingDialog() {
202 // Construct dialog
203 LoadingDialog loading = new LoadingDialog(getResources().getString(R.string.wait_a_moment));
204 FragmentManager fm = getActivity().getSupportFragmentManager();
205 FragmentTransaction ft = fm.beginTransaction();
206 loading.show(ft, DIALOG_WAIT_TAG);
207 }
208
209 /**
210 * Dismiss loading dialog
211 */
212 public void dismissLoadingDialog() {
213 final Fragment frag = getActivity().getSupportFragmentManager().findFragmentByTag(DIALOG_WAIT_TAG);
214 if (frag != null) {
215 LoadingDialog loading = (LoadingDialog) frag;
216 loading.dismiss();
217 }
218 }
219 }
220
221 /**
222 * {@inheritDoc}
223 */
224 @Override
225 public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
226 super.onCreateOptionsMenu(menu, inflater);
227 inflater.inflate(R.menu.file_actions_menu, menu);
228 }
229
230 /**
231 * {@inheritDoc}
232 */
233 @Override
234 public void onPrepareOptionsMenu(Menu menu) {
235 super.onPrepareOptionsMenu(menu);
236
237 if (mContainerActivity.getStorageManager() != null) {
238 FileMenuFilter mf = new FileMenuFilter(
239 getFile(),
240 mContainerActivity.getStorageManager().getAccount(),
241 mContainerActivity,
242 getSherlockActivity()
243 );
244 mf.filter(menu);
245 }
246
247 // additional restriction for this fragment
248 MenuItem item = menu.findItem(R.id.action_rename_file);
249 if (item != null) {
250 item.setVisible(false);
251 item.setEnabled(false);
252 }
253
254 // additional restriction for this fragment
255 item = menu.findItem(R.id.action_move);
256 if (item != null) {
257 item.setVisible(false);
258 item.setEnabled(false);
259 }
260
261 // this one doesn't make sense since the file has to be down in order to be previewed
262 item = menu.findItem(R.id.action_download_file);
263 if (item != null) {
264 item.setVisible(false);
265 item.setEnabled(false);
266 }
267
268 item = menu.findItem(R.id.action_settings);
269 if (item != null) {
270 item.setVisible(false);
271 item.setEnabled(false);
272 }
273
274 item = menu.findItem(R.id.action_logger);
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 getSherlockActivity().onBackPressed();
403 }
404 });
405 }
406 }