X-Git-Url: https://gitweb.stoutner.com/?p=PrivacyBrowserAndroid.git;a=blobdiff_plain;f=app%2Fsrc%2Fmain%2Fjava%2Fcom%2Fstoutner%2Fprivacybrowser%2FBookmarksActivity.java;h=75a340211711d4f9fcb8f70d765fefacd3ac552d;hp=556bd60cafb215618bef6f40fc6ee6a04d4c1d54;hb=81931a2a88e383f1071ab5134afe5bd70b31895d;hpb=c6907b02eb70e1a4bde274e66101f9f54f77a660 diff --git a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java index 556bd60c..75a34021 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java @@ -25,6 +25,8 @@ import android.content.Context; import android.database.Cursor; import android.graphics.Bitmap; import android.graphics.BitmapFactory; +import android.graphics.drawable.BitmapDrawable; +import android.graphics.drawable.Drawable; import android.os.Bundle; import android.support.design.widget.FloatingActionButton; import android.support.design.widget.Snackbar; @@ -33,6 +35,7 @@ import android.support.v4.widget.CursorAdapter; import android.support.v7.app.ActionBar; import android.support.v7.app.AppCompatActivity; import android.support.v7.widget.Toolbar; +import android.util.SparseBooleanArray; import android.view.ActionMode; import android.view.Menu; import android.view.MenuItem; @@ -40,6 +43,7 @@ import android.view.View; import android.view.ViewGroup; import android.widget.AbsListView; import android.widget.AdapterView; +import android.widget.CheckBox; import android.widget.EditText; import android.widget.ImageView; import android.widget.ListView; @@ -47,12 +51,20 @@ import android.widget.TextView; import java.io.ByteArrayOutputStream; -public class BookmarksActivity extends AppCompatActivity implements CreateBookmark.CreateBookmarkListener { - private BookmarksDatabaseHandler bookmarksDatabaseHandler; - private ListView bookmarksListView; +public class BookmarksActivity extends AppCompatActivity implements CreateBookmark.CreateBookmarkListener, EditBookmark.EditBookmarkListener { + // `bookmarksDatabaseHandler` is public static so it can be accessed from EditBookmark. It is also used in `onCreate()`, + // `onCreateBookmarkCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. + public static BookmarksDatabaseHandler bookmarksDatabaseHandler; - // deleteBookmarkMenuItem is used in onCreate() and onPrepareOptionsMenu(). - private MenuItem deleteBookmarkMenuItem; + // `bookmarksListView` is public static so it can be accessed from EditBookmark. + // It is also used in `onCreate()`, `updateBookmarksListView()`, and `updateBookmarksListViewExcept()`. + public static ListView bookmarksListView; + + // `contextualActionMode` is used in `onCreate()` and `onEditBookmarkSave()`. + private ActionMode contextualActionMode; + + // `selectedBookmarkPosition` is used in `onCreate()` and `onEditBookarkSave()`. + private int selectedBookmarkPosition; @Override protected void onCreate(Bundle savedInstanceState) { @@ -69,13 +81,16 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma appBar.setDisplayHomeAsUpEnabled(true); // Initialize the database handler and the ListView. + // `this` specifies the context. The two `null`s do not specify the database name or a `CursorFactory`. + // The `0` is to specify a database version, but that is set instead using a constant in BookmarksDatabaseHandler. bookmarksDatabaseHandler = new BookmarksDatabaseHandler(this, null, null, 0); bookmarksListView = (ListView) findViewById(R.id.bookmarks_listview); // Display the bookmarks in the ListView. updateBookmarksListView(); - // Set a listener so that tapping a list item loads the URL. We need to store the activity in a variable so that we can return to the parent activity after loading the URL. + // Set a listener so that tapping a list item loads the URL. We need to store the activity + // in a variable so that we can return to the parent activity after loading the URL. final Activity bookmarksActivity = this; bookmarksListView.setOnItemClickListener(new AdapterView.OnItemClickListener() { @Override @@ -92,26 +107,32 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } }); - // registerForContextMenu(bookmarksListView); - + // `MultiChoiceModeListener` handles long clicks. bookmarksListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { - @Override - public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { - String numberSelectedString; - long[] selectedItemsLongArray = bookmarksListView.getCheckedItemIds(); + // `moveBookmarkUpMenuItem` is used in `onCreateActionMode()` and `onItemCheckedStateChanged`. + MenuItem moveBookmarkUpMenuItem; - numberSelectedString = selectedItemsLongArray.length + " " + getString(R.string.selected); + // `moveBookmarkDownMenuItem` is used in `onCreateActionMode()` and `onItemCheckedStateChanged`. + MenuItem moveBookmarkDownMenuItem; - mode.setSubtitle(numberSelectedString); - } + // `editBookmarkMenuItem` is used in `onCreateActionMode()` and `onItemCheckedStateChanged`. + MenuItem editBookmarkMenuItem; + + // `selectAllBookmarks` is used in `onCreateActionMode()` and `onItemCheckedStateChanges`. + MenuItem selectAllBookmarksMenuItem; @Override public boolean onCreateActionMode(ActionMode mode, Menu menu) { - // Inflate the menu for the contextual app bar. + // Inflate the menu for the contextual app bar and set the title. getMenuInflater().inflate(R.menu.bookmarks_context_menu, menu); - mode.setTitle(R.string.bookmarks); + // Get a handle for MenuItems we need to selectively disable. + moveBookmarkUpMenuItem = menu.findItem(R.id.move_bookmark_up); + moveBookmarkDownMenuItem = menu.findItem(R.id.move_bookmark_down); + editBookmarkMenuItem = menu.findItem(R.id.edit_bookmark); + selectAllBookmarksMenuItem = menu.findItem(R.id.context_menu_select_all_bookmarks); + return true; } @@ -120,25 +141,175 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma return false; } + @Override + public void onItemCheckedStateChanged(ActionMode mode, int position, long id, boolean checked) { + // Get an array of the selected bookmarks. + long[] selectedBookmarksLongArray = bookmarksListView.getCheckedItemIds(); + + // Calculate the number of selected bookmarks. + int numberOfSelectedBookmarks = selectedBookmarksLongArray.length; + + // List the number of selected bookmarks in the subtitle. + mode.setSubtitle(numberOfSelectedBookmarks + " " + getString(R.string.selected)); + + if (numberOfSelectedBookmarks == 1) { + // Show the `Move Up`, `Move Down`, and `Edit` option only if 1 bookmark is selected. + moveBookmarkUpMenuItem.setVisible(true); + moveBookmarkDownMenuItem.setVisible(true); + editBookmarkMenuItem.setVisible(true); + + // Get the database IDs for the bookmarks. + int selectedBookmarkDatabaseId = (int) selectedBookmarksLongArray[0]; + int firstBookmarkDatabaseId = (int) bookmarksListView.getItemIdAtPosition(0); + // bookmarksListView is 0 indexed. + int lastBookmarkDatabaseId = (int) bookmarksListView.getItemIdAtPosition(bookmarksListView.getCount() - 1); + + // Disable `moveBookmarkUpMenuItem` if the selected bookmark is at the top of the ListView. + if (selectedBookmarkDatabaseId == firstBookmarkDatabaseId) { + moveBookmarkUpMenuItem.setEnabled(false); + moveBookmarkUpMenuItem.setIcon(R.drawable.move_bookmark_up_disabled); + } else { // Otherwise enable `moveBookmarkUpMenuItem`. + moveBookmarkUpMenuItem.setEnabled(true); + moveBookmarkUpMenuItem.setIcon(R.drawable.move_bookmark_up_enabled); + } + + // Disable `moveBookmarkDownMenuItem` if the selected bookmark is at the bottom of the ListView. + if (selectedBookmarkDatabaseId == lastBookmarkDatabaseId) { + moveBookmarkDownMenuItem.setEnabled(false); + moveBookmarkDownMenuItem.setIcon(R.drawable.move_bookmark_down_disabled); + } else { // Otherwise enable `moveBookmarkDownMenuItem`. + moveBookmarkDownMenuItem.setEnabled(true); + moveBookmarkDownMenuItem.setIcon(R.drawable.move_bookmark_down_enabled); + } + } else { // Hide the MenuItems because more than one bookmark is selected. + moveBookmarkUpMenuItem.setVisible(false); + moveBookmarkDownMenuItem.setVisible(false); + editBookmarkMenuItem.setVisible(false); + } + + // Do not show `Select All` if all the bookmarks are already checked. + if (bookmarksListView.getCheckedItemIds().length == bookmarksListView.getCount()) { + selectAllBookmarksMenuItem.setVisible(false); + } else { + selectAllBookmarksMenuItem.setVisible(true); + } + } + @Override public boolean onActionItemClicked(ActionMode mode, MenuItem item) { int menuItemId = item.getItemId(); + // `numberOfBookmarks` is used in `R.id.move_bookmark_up_enabled`, `R.id.move_bookmark_down_enabled`, and `R.id.context_menu_select_all_bookmarks`. + int numberOfBookmarks; + + // `selectedBookmarkLongArray` is used in `R.id.move_bookmark_up` and `R.id.move_bookmark_down`. + long[]selectedBookmarkLongArray; + // `selectedBookmarkDatabaseId` is used in `R.id.move_bookmark_up` and `R.id.move_bookmark_down`. + int selectedBookmarkDatabaseId; + // `selectedBookmarkNewPosition` is used in `R.id.move_bookmark_up` and `R.id.move_bookmark_down`. + int selectedBookmarkNewPosition; + switch (menuItemId) { + case R.id.move_bookmark_up: + // Get the selected bookmark database ID. + selectedBookmarkLongArray = bookmarksListView.getCheckedItemIds(); + selectedBookmarkDatabaseId = (int) selectedBookmarkLongArray[0]; + + // Initialize `selectedBookmarkNewPosition`. + selectedBookmarkNewPosition = 0; + + for (int i = 0; i < bookmarksListView.getCount(); i++) { + int databaseId = (int) bookmarksListView.getItemIdAtPosition(i); + int nextBookmarkDatabaseId = (int) bookmarksListView.getItemIdAtPosition(i + 1); + + if (databaseId == selectedBookmarkDatabaseId || nextBookmarkDatabaseId == selectedBookmarkDatabaseId) { + if (databaseId == selectedBookmarkDatabaseId) { + // Move the selected bookmark up one and store the new bookmark position. + bookmarksDatabaseHandler.updateBookmarkDisplayOrder(databaseId, i - 1); + selectedBookmarkNewPosition = i - 1; + } else { // Move the bookmark above the selected bookmark down one. + bookmarksDatabaseHandler.updateBookmarkDisplayOrder(databaseId, i + 1); + } + } else { + // Reset the rest of the bookmarks' DISPLAY_ORDER to match the position in the ListView. + // This isn't necessary, but it clears out any stray values that might have crept into the database. + bookmarksDatabaseHandler.updateBookmarkDisplayOrder(databaseId, i); + } + } + + // Refresh the ListView. + updateBookmarksListView(); + + // Select the previously selected bookmark in the new location. + bookmarksListView.setItemChecked(selectedBookmarkNewPosition, true); + + bookmarksListView.setSelection(selectedBookmarkNewPosition - 5); + + break; + + case R.id.move_bookmark_down: + // Get the selected bookmark database ID. + selectedBookmarkLongArray = bookmarksListView.getCheckedItemIds(); + selectedBookmarkDatabaseId = (int) selectedBookmarkLongArray[0]; + + // Initialize `selectedBookmarkNewPosition`. + selectedBookmarkNewPosition = 0; + + for (int i = 0; i