View Javadoc
1   /*
2    * Copyright (C) 2003-2014 eXo Platform SAS.
3    *
4    * This is free software; you can redistribute it and/or modify it
5    * under the terms of the GNU Lesser General Public License as
6    * published by the Free Software Foundation; either version 3 of
7    * the License, or (at your option) any later version.
8    *
9    * This software 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 GNU
12   * Lesser General Public License for more details.
13   *
14   * You should have received a copy of the GNU Lesser General Public
15   * License along with this software; if not, write to the Free
16   * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
17   * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
18   */
19  package org.exoplatform.ui;
20  
21  import java.util.ArrayList;
22  import java.util.List;
23  
24  import org.exoplatform.R;
25  import org.exoplatform.controller.document.DocumentAdapter;
26  import org.exoplatform.controller.document.DocumentLoadTask;
27  import org.exoplatform.model.ExoFile;
28  import org.exoplatform.singleton.AccountSetting;
29  import org.exoplatform.singleton.DocumentHelper;
30  import org.exoplatform.ui.social.SelectedImageActivity;
31  import org.exoplatform.utils.CompatibleFileOpen;
32  import org.exoplatform.utils.CrashUtils;
33  import org.exoplatform.utils.ExoConnectionUtils;
34  import org.exoplatform.utils.ExoConstants;
35  import org.exoplatform.utils.ExoDocumentUtils;
36  import org.exoplatform.utils.PhotoUtils;
37  import org.exoplatform.utils.SettingUtils;
38  import org.exoplatform.widget.ConnectionErrorDialog;
39  
40  import android.annotation.SuppressLint;
41  import android.app.Activity;
42  import android.content.Intent;
43  import android.content.pm.PackageManager;
44  import android.content.res.Resources;
45  import android.os.Bundle;
46  import android.support.v4.app.ActivityCompat.OnRequestPermissionsResultCallback;
47  import android.util.Log;
48  import android.view.Menu;
49  import android.view.MenuItem;
50  import android.view.View;
51  import android.view.ViewStub;
52  import android.view.animation.AnimationUtils;
53  import android.widget.ImageView;
54  import android.widget.ListView;
55  import android.widget.TextView;
56  import android.widget.Toast;
57  
58  public class DocumentActivity extends Activity implements OnRequestPermissionsResultCallback {
59    // add photo
60    public static final int        ACTION_ADD_PHOTO = 0;
61  
62    // copy file
63    public static final int        ACTION_COPY      = 1;
64  
65    // move file
66    public static final int        ACTION_MOVE      = 2;
67  
68    // paste file
69    public static final int        ACTION_PASTE     = 3;
70  
71    // delete file or folder
72    public static final int        ACTION_DELETE    = 4;
73  
74    // rename folder
75    public static final int        ACTION_RENAME    = 5;
76  
77    // create new folder
78    public static final int        ACTION_CREATE    = 6;
79  
80    // open in
81    public static final int        ACTION_OPEN_IN   = 7;
82  
83    // default
84    public static final int        ACTION_DEFAULT   = 8;
85  
86    private MenuItem               mDocAction;
87  
88    private static final String    DOCUMENT_HELPER  = "document_helper";
89  
90    private static final String    ACCOUNT_SETTING  = "account_setting";
91  
92    private static final String    CURRENT_FILE     = "current_file";
93  
94    public static DocumentActivity _documentActivityInstance;
95  
96    public ListView                _listViewDocument;
97  
98    private TextView               _textViewEmptyPage;
99  
100   private String                 emptyFolderString;
101 
102   public String                  _sdcard_temp_dir;
103 
104   public DocumentAdapter         _documentAdapter;
105 
106   private DocumentLoadTask       mLoadTask;
107   
108   public CompatibleFileOpen      mFileOpenController;
109 
110   private View                   empty_stub;
111 
112   public ExoFile                 _fileForCurrentActionBar;
113 
114   private static final String    TAG              = "eXo____DocumentActivity____";
115 
116   @Override
117   public void onCreate(Bundle bundle) {
118     super.onCreate(bundle);
119 
120     setContentView(R.layout.exofilesview);
121     setTitle(R.string.Documents);
122     _documentActivityInstance = this;
123     init();
124 
125     /*
126      * Restore the current state of activity
127      */
128     if (bundle != null) {
129       DocumentHelper helper = bundle.getParcelable(DOCUMENT_HELPER);
130       DocumentHelper.getInstance().setInstance(helper);
131       AccountSetting accountSetting = bundle.getParcelable(ACCOUNT_SETTING);
132       AccountSetting.getInstance().setInstance(accountSetting);
133       ExoConnectionUtils.setCookieStore(ExoConnectionUtils.cookiesStore, AccountSetting.getInstance().cookiesList);
134       _fileForCurrentActionBar = bundle.getParcelable(CURRENT_FILE);
135     } else {
136       /*
137        * Initialize 2 dictionaries for mapping each time document starting
138        */
139       DocumentHelper.getInstance().folderToChildrenMap = new Bundle();
140       DocumentHelper.getInstance().folderToParentMap = new Bundle();
141       _fileForCurrentActionBar = new ExoFile();
142       setTitle(R.string.Documents);
143     }
144     onLoad(_fileForCurrentActionBar, null, ACTION_DEFAULT);
145 
146   }
147 
148   /*
149    * (non-Javadoc)
150    * @see android.app.Activity#onSaveInstanceState(android.os.Bundle)
151    */
152   @Override
153   protected void onSaveInstanceState(Bundle outState) {
154     super.onSaveInstanceState(outState);
155     outState.putParcelable(DOCUMENT_HELPER, DocumentHelper.getInstance());
156     outState.putParcelable(ACCOUNT_SETTING, AccountSetting.getInstance());
157     outState.putParcelable(CURRENT_FILE, _fileForCurrentActionBar);
158   }
159 
160   @Override
161   public boolean onCreateOptionsMenu(Menu menu) {
162     getMenuInflater().inflate(R.menu.document, menu);
163     mDocAction = menu.findItem(R.id.menu_doc_action);
164     addOrRemoveFileActionButton();
165     return true;
166   }
167 
168   @Override
169   public boolean onOptionsItemSelected(MenuItem item) {
170     switch (item.getItemId()) {
171 
172     case android.R.id.home:
173       _documentActivityInstance = null;
174       finish();
175       break;
176     case R.id.menu_doc_action:
177 
178       _documentAdapter._documentActionDialog = new DocumentActionDialog(this, _fileForCurrentActionBar, true);
179       _documentAdapter._documentActionDialog._documentActionAdapter.setSelectedFile(_fileForCurrentActionBar);
180       _documentAdapter._documentActionDialog._documentActionAdapter.notifyDataSetChanged();
181       _documentAdapter._documentActionDialog.setTileForDialog(_fileForCurrentActionBar.name);
182       _documentAdapter._documentActionDialog.myFile = _fileForCurrentActionBar;
183       _documentAdapter._documentActionDialog.show();
184 
185       break;
186     default:
187 
188       break;
189 
190     }
191     return true;
192   }
193 
194   public void addOrRemoveFileActionButton() {
195     /*
196      * If at the document level or driver level, make the action bar button
197      * invisible
198      */
199     if (mDocAction == null)
200       return;
201 
202     if (_fileForCurrentActionBar == null) {
203       mDocAction.setVisible(false);
204     } else {
205       if (_fileForCurrentActionBar.name == null) {
206         mDocAction.setVisible(false);
207       } else if ("".equals(_fileForCurrentActionBar.name)) {
208         mDocAction.setVisible(false);
209       } else {
210         mDocAction.setVisible(true);
211       }
212     }
213   }
214 
215   @Override
216   public void onBackPressed() {
217     onCancelLoad();
218     if (_documentAdapter == null) {
219       _documentActivityInstance = null;
220       finish();
221     } else {
222       /*
223        * Each time press on back button, return to parent folder and get parents
224        * list file which is retrieved from 2 mapping dictionaries {@link
225        * currentFileMap} and {@link childFileMap}
226        * @param: parent The parent folder
227        * @param: documentList The parents list file
228        */
229       if ("".equals(_fileForCurrentActionBar.name)) {
230         _documentActivityInstance = null;
231         finish();
232       } else {
233         /*
234          * Set animation for listview when press back button
235          */
236         _listViewDocument.setAnimation(AnimationUtils.loadAnimation(this, R.anim.anim_left_to_right));
237 
238         /*
239          * Reset ListView
240          */
241         updateContent(getParentFolderAndChildren());
242       }
243     }
244   }
245 
246   private ExoFile getParentFolderAndChildren() {
247     ArrayList<ExoFile> documentList = null;
248 
249     if ("".equals(_fileForCurrentActionBar.currentFolder)) {
250       // "" as currentFolder means we're at the root of the drive
251       // so we go back to the list of drives
252       _fileForCurrentActionBar = new ExoFile();
253       documentList = DocumentHelper.getInstance().folderToChildrenMap.getParcelableArrayList(ExoConstants.DOCUMENT_JCR_PATH);
254     } else {
255       String currPath = _fileForCurrentActionBar.path;
256       // replace the current folder by its parent
257       _fileForCurrentActionBar = DocumentHelper.getInstance().folderToParentMap.getParcelable(currPath);
258       // remove the former current folder from memory
259       DocumentHelper.getInstance().folderToParentMap.remove(currPath);
260       // get the list of children of the new current folder
261       if ("".equals(_fileForCurrentActionBar.name)) {
262         documentList = DocumentHelper.getInstance().folderToChildrenMap.getParcelableArrayList("");
263       } else {
264         documentList = DocumentHelper.getInstance().folderToChildrenMap.getParcelableArrayList(_fileForCurrentActionBar.path);
265       }
266     }
267     // link the current folder with the list of its children
268     _fileForCurrentActionBar.children = documentList;
269     return _fileForCurrentActionBar;
270   }
271 
272   public void loadFolderContent(ExoFile parent) {
273     onLoad(parent, null, DocumentActivity.ACTION_DEFAULT);
274   }
275 
276   public void deleteFile(ExoFile fileToDelete) {
277     onLoad(fileToDelete, fileToDelete.path, DocumentActivity.ACTION_DELETE);
278   }
279 
280   public void pasteFile(ExoFile fileToPaste, String destination, int action) {
281     onLoad(fileToPaste, destination, action);
282   }
283 
284   public void uploadFile() {
285     onLoad(_documentAdapter._documentActionDialog.myFile, null, ACTION_ADD_PHOTO);
286   }
287 
288   public void createFile(ExoFile fileToCreate, String destination) {
289     onLoad(fileToCreate, destination, DocumentActivity.ACTION_CREATE);
290   }
291 
292   public void renameFile(ExoFile fileToRename, String destination) {
293     onLoad(fileToRename, destination, DocumentActivity.ACTION_RENAME);
294   }
295 
296   private void onLoad(ExoFile source, String destination, int action) {
297     if (ExoConnectionUtils.isNetworkAvailableExt(this)) {
298       if (mLoadTask == null || mLoadTask.getStatus() == DocumentLoadTask.Status.FINISHED) {
299         Log.i(TAG, "Starting Document Load Task");
300         mLoadTask = (DocumentLoadTask) new DocumentLoadTask(this, source, destination, action).execute();
301       }
302     } else {
303       new ConnectionErrorDialog(this).show();
304     }
305   }
306 
307   public void onCancelLoad() {
308     if (mLoadTask != null && mLoadTask.getStatus() == DocumentLoadTask.Status.RUNNING) {
309       Log.i(TAG, "Canceling Document Load Task");
310       mLoadTask.cancel(true);
311       mLoadTask = null;
312     }
313     if (mFileOpenController != null) {
314       mFileOpenController.onCancelLoad();
315     }
316   }
317   
318   @Override
319   protected void onPause() {
320     onCancelLoad();
321     super.onPause();
322   }
323   
324   @Override
325   protected void onDestroy() {
326     _documentActivityInstance = null;
327     super.onDestroy();
328   }
329 
330   private void init() {
331     _listViewDocument = (ListView) findViewById(R.id.ListView_Files);
332     _listViewDocument.setDivider(null);
333     _textViewEmptyPage = (TextView) findViewById(R.id.TextView_EmptyPage);
334     _textViewEmptyPage.setVisibility(View.INVISIBLE);
335 
336     changeLanguage();
337 
338   }
339 
340   public void updateContent(ExoFile newFolder) {
341     _fileForCurrentActionBar = newFolder;
342     if ("".equals(_fileForCurrentActionBar.name)) {
343       setTitle(getResources().getString(R.string.Documents));
344     } else {
345       setTitle(_fileForCurrentActionBar.getName());
346     }
347     List<ExoFile> documentList = newFolder.children;
348     if (documentList == null) {
349       CrashUtils.loge(TAG, String.format("Null list of children for folder '%s'", newFolder.path));
350       documentList = new ArrayList<ExoFile>(0);
351     }
352     if (documentList.size() == 0) {
353       setEmptyView(View.VISIBLE);
354     } else
355       setEmptyView(View.GONE);
356 
357     _documentAdapter = new DocumentAdapter(this, documentList);
358     _listViewDocument.setAdapter(_documentAdapter);
359     addOrRemoveFileActionButton();
360   }
361 
362   /**
363    * Take a photo and store it into /sdcard/eXo/DocumentCache
364    **/
365   public void takePicture() {
366     _sdcard_temp_dir = PhotoUtils.startImageCapture(this);
367   }
368   
369   @SuppressLint("Override")
370   @Override
371   public void onRequestPermissionsResult(int reqCode, String[] permissions, int[] results) {
372     if (results.length > 0
373         && results[0] == PackageManager.PERMISSION_GRANTED) {  
374         // permission granted
375         switch (reqCode) {
376         case ExoConstants.REQUEST_PICK_IMAGE_FROM_GALLERY:
377           PhotoUtils.pickPhotoForActivity(this);
378           break;
379         case ExoConstants.REQUEST_TAKE_PICTURE_WITH_CAMERA:
380           takePicture();
381           break;
382         default:
383           break;
384         }
385     } else {
386         // permission denied
387       if (ExoDocumentUtils.shouldDisplayExplanation(this, ExoConstants.REQUEST_PICK_IMAGE_FROM_GALLERY) ||
388           ExoDocumentUtils.shouldDisplayExplanation(this, ExoConstants.REQUEST_TAKE_PICTURE_WITH_CAMERA) ) {
389         PhotoUtils.alertNeedStoragePermission(this);
390       } else {
391         Toast.makeText(this, R.string.PermissionStorageDeniedToast, Toast.LENGTH_LONG).show();
392       }
393     }
394     return;
395   }
396 
397   public void onActivityResult(int requestCode, int resultCode, Intent intent) {
398     super.onActivityResult(requestCode, resultCode, intent);
399     if (resultCode == RESULT_OK) {
400       switch (requestCode) {
401       case ExoConstants.REQUEST_TAKE_PICTURE_WITH_CAMERA:
402         Intent intent1 = new Intent(_documentActivityInstance, SelectedImageActivity.class);
403         intent1.putExtra(ExoConstants.SELECTED_IMAGE_EXTRA, _sdcard_temp_dir);
404         startActivity(intent1);
405         break;
406 
407       case ExoConstants.REQUEST_PICK_IMAGE_FROM_GALLERY:
408         Intent intent2 = new Intent(this, SelectedImageActivity.class);
409         intent.putExtra(ExoConstants.SELECTED_IMAGE_MODE, 2);
410         intent2.setData(intent.getData());
411         if (intent.getExtras() != null) {
412           intent2.putExtras(intent.getExtras());
413         }
414         startActivity(intent2);
415         break;
416       }
417     }
418     /*
419      * Set default language to our application setting language
420      */
421     SettingUtils.setDefaultLanguage(this);
422   }
423 
424   private void setEmptyView(int status) {
425     if (empty_stub == null) {
426       initStubView();
427     }
428     empty_stub.setVisibility(status);
429   }
430 
431   private void initStubView() {
432     empty_stub = ((ViewStub) findViewById(R.id.file_empty_stub)).inflate();
433     ImageView emptyImage = (ImageView) empty_stub.findViewById(R.id.empty_image);
434     emptyImage.setBackgroundResource(R.drawable.icon_for_empty_folder);
435     TextView emptyStatus = (TextView) empty_stub.findViewById(R.id.empty_status);
436     emptyStatus.setText(emptyFolderString);
437   }
438 
439   // Set language
440   private void changeLanguage() {
441     Resources resource = getResources();
442     emptyFolderString = resource.getString(R.string.EmptyFolder);
443     _textViewEmptyPage.setText(emptyFolderString);
444   }
445 
446 }