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=6d0819913cbb7bf009b597d7e7f6ed028b3130d3;hb=81931a2a88e383f1071ab5134afe5bd70b31895d;hpb=9c582d802e641b2b6d27271310fc16898020b470 diff --git a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java index 6d081991..75a34021 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/BookmarksActivity.java @@ -21,27 +21,50 @@ package com.stoutner.privacybrowser; import android.app.Activity; import android.app.DialogFragment; +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; import android.support.v4.app.NavUtils; +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; 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; -import android.widget.SimpleCursorAdapter; +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; + + // `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) { @@ -49,7 +72,7 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma setContentView(R.layout.bookmarks_coordinatorlayout); // We need to use the SupportActionBar from android.support.v7.app.ActionBar until the minimum API is >= 21. - Toolbar bookmarksAppBar = (Toolbar) findViewById(R.id.bookmarks_toolbar); + final Toolbar bookmarksAppBar = (Toolbar) findViewById(R.id.bookmarks_toolbar); setSupportActionBar(bookmarksAppBar); // Display the home arrow on supportAppBar. @@ -58,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 @@ -81,77 +107,460 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma } }); + // `MultiChoiceModeListener` handles long clicks. + bookmarksListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() { + // `moveBookmarkUpMenuItem` is used in `onCreateActionMode()` and `onItemCheckedStateChanged`. + MenuItem moveBookmarkUpMenuItem; + + // `moveBookmarkDownMenuItem` is used in `onCreateActionMode()` and `onItemCheckedStateChanged`. + MenuItem moveBookmarkDownMenuItem; + + // `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 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; + } + + @Override + public boolean onPrepareActionMode(ActionMode mode, Menu menu) { + 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