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