2 * Copyright (C) 2012 The CyanogenMod Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.cyanogenmod.filemanager.activities;
19 import android.app.ActionBar;
20 import android.app.Activity;
21 import android.content.BroadcastReceiver;
22 import android.content.Context;
23 import android.content.Intent;
24 import android.content.IntentFilter;
25 import android.content.res.Configuration;
26 import android.content.res.XmlResourceParser;
27 import android.database.Cursor;
28 import android.os.AsyncTask;
29 import android.os.Bundle;
30 import android.os.storage.StorageVolume;
31 import android.util.Log;
32 import android.view.KeyEvent;
33 import android.view.MenuItem;
34 import android.view.View;
35 import android.view.View.OnClickListener;
36 import android.widget.AdapterView;
37 import android.widget.AdapterView.OnItemClickListener;
38 import android.widget.ListView;
39 import android.widget.TextView;
40 import android.widget.Toast;
42 import com.android.internal.util.XmlUtils;
43 import com.cyanogenmod.filemanager.FileManagerApplication;
44 import com.cyanogenmod.filemanager.R;
45 import com.cyanogenmod.filemanager.adapters.BookmarksAdapter;
46 import com.cyanogenmod.filemanager.console.NoSuchFileOrDirectory;
47 import com.cyanogenmod.filemanager.model.Bookmark;
48 import com.cyanogenmod.filemanager.model.Bookmark.BOOKMARK_TYPE;
49 import com.cyanogenmod.filemanager.model.FileSystemObject;
50 import com.cyanogenmod.filemanager.preferences.AccessMode;
51 import com.cyanogenmod.filemanager.preferences.Bookmarks;
52 import com.cyanogenmod.filemanager.preferences.FileManagerSettings;
53 import com.cyanogenmod.filemanager.preferences.Preferences;
54 import com.cyanogenmod.filemanager.ui.ThemeManager;
55 import com.cyanogenmod.filemanager.ui.ThemeManager.Theme;
56 import com.cyanogenmod.filemanager.ui.dialogs.InitialDirectoryDialog;
57 import com.cyanogenmod.filemanager.ui.widgets.FlingerListView;
58 import com.cyanogenmod.filemanager.ui.widgets.FlingerListView.OnItemFlingerListener;
59 import com.cyanogenmod.filemanager.ui.widgets.FlingerListView.OnItemFlingerResponder;
60 import com.cyanogenmod.filemanager.util.CommandHelper;
61 import com.cyanogenmod.filemanager.util.DialogHelper;
62 import com.cyanogenmod.filemanager.util.ExceptionUtil;
63 import com.cyanogenmod.filemanager.util.StorageHelper;
65 import java.io.FileNotFoundException;
66 import java.util.ArrayList;
67 import java.util.List;
70 * An activity for show bookmarks and links.
72 public class BookmarksActivity extends Activity implements OnItemClickListener, OnClickListener {
74 private static final String TAG = "BookmarksActivity"; //$NON-NLS-1$
76 private static boolean DEBUG = false;
79 * A listener for flinging events from {@link FlingerListView}
81 private final OnItemFlingerListener mOnItemFlingerListener = new OnItemFlingerListener() {
84 public boolean onItemFlingerStart(
85 AdapterView<?> parent, View view, int position, long id) {
87 // Response if the item can be removed
88 BookmarksAdapter adapter = (BookmarksAdapter)parent.getAdapter();
89 Bookmark bookmark = adapter.getItem(position);
90 if (bookmark != null &&
91 bookmark.mType.compareTo(BOOKMARK_TYPE.USER_DEFINED) == 0) {
94 } catch (Exception e) {
95 ExceptionUtil.translateException(BookmarksActivity.this, e, true, false);
101 public void onItemFlingerEnd(OnItemFlingerResponder responder,
102 AdapterView<?> parent, View view, int position, long id) {
105 // Response if the item can be removed
106 BookmarksAdapter adapter = (BookmarksAdapter)parent.getAdapter();
107 Bookmark bookmark = adapter.getItem(position);
108 if (bookmark != null &&
109 bookmark.mType.compareTo(BOOKMARK_TYPE.USER_DEFINED) == 0) {
110 boolean result = Bookmarks.removeBookmark(BookmarksActivity.this, bookmark);
113 DialogHelper.showToast(BookmarksActivity.this,
114 R.string.msgs_operation_failure, Toast.LENGTH_SHORT);
119 adapter.remove(bookmark);
123 // Cancels the flinger operation
126 } catch (Exception e) {
127 ExceptionUtil.translateException(BookmarksActivity.this, e, true, false);
133 private final BroadcastReceiver mNotificationReceiver = new BroadcastReceiver() {
135 public void onReceive(Context context, Intent intent) {
136 if (intent != null) {
137 if (intent.getAction().compareTo(FileManagerSettings.INTENT_THEME_CHANGED) == 0) {
144 // Bookmark list XML tags
145 private static final String TAG_BOOKMARKS = "Bookmarks"; //$NON-NLS-1$
146 private static final String TAG_BOOKMARK = "bookmark"; //$NON-NLS-1$
151 ListView mBookmarksListView;
153 private boolean mChRooted;
159 protected void onCreate(Bundle state) {
161 Log.d(TAG, "BookmarksActivity.onCreate"); //$NON-NLS-1$
164 // Register the broadcast receiver
165 IntentFilter filter = new IntentFilter();
166 filter.addAction(FileManagerSettings.INTENT_THEME_CHANGED);
167 registerReceiver(this.mNotificationReceiver, filter);
170 this.mChRooted = FileManagerApplication.getAccessMode().compareTo(AccessMode.SAFE) == 0;
173 overridePendingTransition(R.anim.translate_to_right_in, R.anim.hold_out);
175 //Set the main layout of the activity
176 setContentView(R.layout.bookmarks);
178 //Initialize action bars and data
179 initTitleActionBar();
186 super.onCreate(state);
193 protected void onDestroy() {
195 Log.d(TAG, "BookmarksActivity.onDestroy"); //$NON-NLS-1$
198 // Unregister the receiver
200 unregisterReceiver(this.mNotificationReceiver);
201 } catch (Throwable ex) {
205 //All destroy. Continue
213 protected void onPause() {
215 overridePendingTransition(R.anim.hold_in, R.anim.translate_to_left_out);
223 public void onConfigurationChanged(Configuration newConfig) {
224 super.onConfigurationChanged(newConfig);
228 * Method that initializes the titlebar of the activity.
230 private void initTitleActionBar() {
231 //Configure the action bar options
232 getActionBar().setBackgroundDrawable(
233 getResources().getDrawable(R.drawable.bg_holo_titlebar));
234 getActionBar().setDisplayOptions(
235 ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_SHOW_HOME);
236 getActionBar().setDisplayHomeAsUpEnabled(true);
237 View customTitle = getLayoutInflater().inflate(R.layout.simple_customtitle, null, false);
238 TextView title = (TextView)customTitle.findViewById(R.id.customtitle_title);
239 title.setText(R.string.bookmarks);
240 title.setContentDescription(getString(R.string.bookmarks));
241 getActionBar().setCustomView(customTitle);
245 * Method that initializes the titlebar of the activity.
247 private void initBookmarks() {
248 this.mBookmarksListView = (ListView)findViewById(R.id.bookmarks_listview);
249 List<Bookmark> bookmarks = new ArrayList<Bookmark>();
250 BookmarksAdapter adapter = new BookmarksAdapter(this, bookmarks, this);
251 this.mBookmarksListView.setAdapter(adapter);
252 this.mBookmarksListView.setOnItemClickListener(this);
254 // If we should set the listview to response to flinger gesture detection
256 Preferences.getSharedPreferences().getBoolean(
257 FileManagerSettings.SETTINGS_USE_FLINGER.getId(),
258 ((Boolean)FileManagerSettings.
259 SETTINGS_USE_FLINGER.
260 getDefaultValue()).booleanValue());
262 ((FlingerListView)this.mBookmarksListView).
263 setOnItemFlingerListener(this.mOnItemFlingerListener);
271 * Method that makes the refresh of the data.
274 // Retrieve the loading view
275 final View waiting = findViewById(R.id.bookmarks_waiting);
276 final BookmarksAdapter adapter = (BookmarksAdapter)this.mBookmarksListView.getAdapter();
278 // Load the history in background
279 AsyncTask<Void, Void, Boolean> task = new AsyncTask<Void, Void, Boolean>() {
281 List<Bookmark> mBookmarks;
284 protected Boolean doInBackground(Void... params) {
286 this.mBookmarks = loadBookmarks();
289 } catch (Exception e) {
291 return Boolean.FALSE;
296 protected void onPreExecute() {
297 waiting.setVisibility(View.VISIBLE);
302 protected void onPostExecute(Boolean result) {
303 waiting.setVisibility(View.GONE);
304 if (result.booleanValue()) {
305 adapter.addAll(this.mBookmarks);
306 BookmarksActivity.this.mBookmarksListView.setSelection(0);
309 if (this.mCause != null) {
310 ExceptionUtil.translateException(BookmarksActivity.this, this.mCause);
316 protected void onCancelled() {
317 waiting.setVisibility(View.GONE);
327 public boolean onKeyUp(int keyCode, KeyEvent event) {
329 case KeyEvent.KEYCODE_BACK:
333 return super.onKeyUp(keyCode, event);
341 public boolean onOptionsItemSelected(MenuItem item) {
342 switch (item.getItemId()) {
343 case android.R.id.home:
347 return super.onOptionsItemSelected(item);
355 public void onItemClick(AdapterView<?> parent, View view, int position, long id) {
356 Bookmark bookmark = ((BookmarksAdapter)parent.getAdapter()).getItem(position);
357 back(false, bookmark.mPath);
364 public void onClick(View v) {
365 //Retrieve the position
366 final int position = ((Integer)v.getTag()).intValue();
367 final BookmarksAdapter adapter = (BookmarksAdapter)this.mBookmarksListView.getAdapter();
368 final Bookmark bookmark = adapter.getItem(position);
371 if (bookmark.mType.compareTo(BOOKMARK_TYPE.HOME) == 0) {
372 //Show a dialog for configure initial directory
373 InitialDirectoryDialog dialog = new InitialDirectoryDialog(this);
374 dialog.setOnValueChangedListener(new InitialDirectoryDialog.OnValueChangedListener() {
376 public void onValueChanged(String newInitialDir) {
377 adapter.getItem(position).mPath = newInitialDir;
378 adapter.notifyDataSetChanged();
386 if (bookmark.mType.compareTo(BOOKMARK_TYPE.USER_DEFINED) == 0) {
387 boolean result = Bookmarks.removeBookmark(this, bookmark);
390 DialogHelper.showToast(this, R.string.msgs_operation_failure, Toast.LENGTH_SHORT);
393 adapter.remove(bookmark);
399 * Method that returns to previous activity and.
401 * @param cancelled Indicates if the activity was cancelled
402 * @param path The path of the selected bookmark
404 private void back(final boolean cancelled, final String path) {
405 Intent intent = new Intent();
407 setResult(RESULT_CANCELED, intent);
409 // Check that the bookmark exists
411 FileSystemObject fso = CommandHelper.getFileInfo(this, path, null);
413 intent.putExtra(NavigationActivity.EXTRA_BOOKMARK_SELECTION, fso);
414 setResult(RESULT_OK, intent);
416 // The bookmark not exists, delete the user-defined bookmark
418 Bookmark b = Bookmarks.getBookmark(getContentResolver(), path);
419 Bookmarks.removeBookmark(this, b);
421 } catch (Exception ex) {/**NON BLOCK**/}
423 } catch (Exception e) {
424 // Capture the exception
425 ExceptionUtil.translateException(this, e);
426 if (e instanceof NoSuchFileOrDirectory || e instanceof FileNotFoundException) {
427 // The bookmark not exists, delete the user-defined bookmark
429 Bookmark b = Bookmarks.getBookmark(getContentResolver(), path);
430 Bookmarks.removeBookmark(this, b);
432 } catch (Exception ex) {/**NON BLOCK**/}
441 * Method that loads all kind of bookmarks and join in
442 * an array to be used in the listview adapter.
444 * @return List<Bookmark>
447 List<Bookmark> loadBookmarks() {
448 // Bookmarks = HOME + FILESYSTEM + SD STORAGES + USER DEFINED
449 // In ChRooted mode = SD STORAGES + USER DEFINED (from SD STORAGES)
450 List<Bookmark> bookmarks = new ArrayList<Bookmark>();
451 if (!this.mChRooted) {
452 bookmarks.add(loadHomeBookmarks());
453 bookmarks.addAll(loadFilesystemBookmarks());
455 bookmarks.addAll(loadSdStorageBookmarks());
456 bookmarks.addAll(loadUserBookmarks());
461 * Method that loads the home bookmark from the user preference.
463 * @return Bookmark The bookmark loaded
465 private Bookmark loadHomeBookmarks() {
466 String initialDir = Preferences.getSharedPreferences().getString(
467 FileManagerSettings.SETTINGS_INITIAL_DIR.getId(),
468 (String)FileManagerSettings.SETTINGS_INITIAL_DIR.getDefaultValue());
469 return new Bookmark(BOOKMARK_TYPE.HOME, getString(R.string.bookmarks_home), initialDir);
473 * Method that loads the filesystem bookmarks from the internal xml file.
474 * (defined by this application)
476 * @return List<Bookmark> The bookmarks loaded
478 private List<Bookmark> loadFilesystemBookmarks() {
480 //Initialize the bookmarks
481 List<Bookmark> bookmarks = new ArrayList<Bookmark>();
483 //Read the command list xml file
484 XmlResourceParser parser = getResources().getXml(R.xml.filesystem_bookmarks);
487 //Find the root element
488 XmlUtils.beginDocument(parser, TAG_BOOKMARKS);
490 XmlUtils.nextElement(parser);
491 String element = parser.getName();
492 if (element == null) {
496 if (TAG_BOOKMARK.equals(element)) {
497 CharSequence name = null;
498 CharSequence directory = null;
502 getString(parser.getAttributeResourceValue(
503 R.styleable.Bookmark_name, 0));
504 } catch (Exception e) {/**NON BLOCK**/}
507 getString(parser.getAttributeResourceValue(
508 R.styleable.Bookmark_directory, 0));
509 } catch (Exception e) {/**NON BLOCK**/}
510 if (directory == null) {
512 parser.getAttributeValue(R.styleable.Bookmark_directory);
514 if (name != null && directory != null) {
517 BOOKMARK_TYPE.FILESYSTEM,
519 directory.toString()));
524 //Return the bookmarks
530 } catch (Throwable ex) {
531 Log.e(TAG, "Load filesystem bookmarks failed", ex); //$NON-NLS-1$
535 return new ArrayList<Bookmark>();
539 * Method that loads the secure digital card storage bookmarks from the system.
541 * @return List<Bookmark> The bookmarks loaded
543 private List<Bookmark> loadSdStorageBookmarks() {
544 //Initialize the bookmarks
545 List<Bookmark> bookmarks = new ArrayList<Bookmark>();
548 //Recovery sdcards from storage manager
549 StorageVolume[] volumes = StorageHelper.getStorageVolumes(getApplication());
550 int cc = volumes.length;
551 for (int i = 0; i < cc ; i++) {
552 if (volumes[i].getPath().toLowerCase().indexOf("usb") != -1) { //$NON-NLS-1$
556 StorageHelper.getStorageVolumeDescription(
557 getApplication(), volumes[i]),
558 volumes[i].getPath()));
562 BOOKMARK_TYPE.SDCARD,
563 StorageHelper.getStorageVolumeDescription(
564 getApplication(), volumes[i]),
565 volumes[i].getPath()));
569 //Return the bookmarks
571 } catch (Throwable ex) {
572 Log.e(TAG, "Load filesystem bookmarks failed", ex); //$NON-NLS-1$
576 return new ArrayList<Bookmark>();
580 * Method that loads the user bookmarks (added by the user).
582 * @return List<Bookmark> The bookmarks loaded
584 private List<Bookmark> loadUserBookmarks() {
585 List<Bookmark> bookmarks = new ArrayList<Bookmark>();
586 Cursor cursor = Bookmarks.getAllBookmarks(this.getContentResolver());
588 if (cursor != null && cursor.moveToFirst()) {
590 Bookmark bm = new Bookmark(cursor);
591 if (this.mChRooted && !StorageHelper.isPathInStorageVolume(bm.mPath)) {
595 } while (cursor.moveToNext());
599 if (cursor != null) {
602 } catch (Exception e) {/**NON BLOCK**/}
608 * Method that applies the current theme to the activity
612 Theme theme = ThemeManager.getCurrentTheme(this);
613 theme.setBaseTheme(this, false);
616 theme.setTitlebarDrawable(this, getActionBar(), "titlebar_drawable"); //$NON-NLS-1$
617 View v = getActionBar().getCustomView().findViewById(R.id.customtitle_title);
618 theme.setTextColor(this, (TextView)v, "text_color"); //$NON-NLS-1$
620 theme.setBackgroundDrawable(
621 this, this.mBookmarksListView, "background_drawable"); //$NON-NLS-1$
622 if (((BookmarksAdapter)this.mBookmarksListView.getAdapter()) != null) {
623 ((BookmarksAdapter)this.mBookmarksListView.getAdapter()).notifyThemeChanged();
624 ((BookmarksAdapter)this.mBookmarksListView.getAdapter()).notifyDataSetChanged();
626 this.mBookmarksListView.setDivider(
627 theme.getDrawable(this, "horizontal_divider_drawable")); //$NON-NLS-1$
628 this.mBookmarksListView.invalidate();