From 8951c7351854bbfc9f2815e74b81cc2a4d606bf0 Mon Sep 17 00:00:00 2001 From: Soren Stoutner Date: Thu, 7 Jul 2016 15:21:02 -0700 Subject: [PATCH] Add the ability to edit bookmarks. --- .idea/dictionaries/soren.xml | 3 + ...about_license.html => about_licenses.html} | 2 + app/src/main/assets/images/ic_edit.png | Bin 0 -> 826 bytes .../privacybrowser/AboutActivity.java | 2 +- .../privacybrowser/AboutTabFragment.java | 2 +- .../privacybrowser/BookmarksActivity.java | 173 +++++++++++------- .../BookmarksDatabaseHandler.java | 84 +++++++-- .../privacybrowser/CreateBookmark.java | 57 +++--- .../CreateHomeScreenShortcut.java | 3 - .../stoutner/privacybrowser/EditBookmark.java | 166 +++++++++++++++++ .../privacybrowser/MainWebViewActivity.java | 4 +- app/src/main/res/drawable/back.xml | 1 + app/src/main/res/drawable/edit.xml | 15 ++ app/src/main/res/drawable/exit.xml | 1 + app/src/main/res/drawable/forward.xml | 1 + .../res/layout/create_bookmark_dialog.xml | 66 ++++--- .../create_home_screen_shortcut_dialog.xml | 17 +- .../main/res/layout/edit_bookmark_dialog.xml | 96 ++++++++++ .../res/layout/main_coordinatorlayout.xml | 3 +- app/src/main/res/layout/url_bar.xml | 24 ++- .../main/res/menu/bookmarks_context_menu.xml | 9 +- app/src/main/res/values/colors.xml | 3 +- app/src/main/res/values/strings.xml | 8 +- 23 files changed, 567 insertions(+), 173 deletions(-) rename app/src/main/assets/{about_license.html => about_licenses.html} (99%) create mode 100644 app/src/main/assets/images/ic_edit.png create mode 100644 app/src/main/java/com/stoutner/privacybrowser/EditBookmark.java create mode 100644 app/src/main/res/drawable/edit.xml create mode 100644 app/src/main/res/layout/edit_bookmark_dialog.xml diff --git a/.idea/dictionaries/soren.xml b/.idea/dictionaries/soren.xml index f0434fc3..2d91de18 100644 --- a/.idea/dictionaries/soren.xml +++ b/.idea/dictionaries/soren.xml @@ -11,6 +11,7 @@ bookmarkurl buildapi buildversion + checkedtextview chromeversion commitdiff coordinatorlayout @@ -28,6 +29,7 @@ linearlayout listview logins + lossless mozilla nojs orbot @@ -36,6 +38,7 @@ redmine referer relativelayout + requery robinlinus samsung securitypatch diff --git a/app/src/main/assets/about_license.html b/app/src/main/assets/about_licenses.html similarity index 99% rename from app/src/main/assets/about_license.html rename to app/src/main/assets/about_licenses.html index b495595d..6ff69285 100644 --- a/app/src/main/assets/about_license.html +++ b/app/src/main/assets/about_licenses.html @@ -77,6 +77,8 @@

ic_add.

+

ic_edit.

+

ic_download.


diff --git a/app/src/main/assets/images/ic_edit.png b/app/src/main/assets/images/ic_edit.png new file mode 100644 index 0000000000000000000000000000000000000000..f4612f085475745a4f5ddb0e2490453caf129747 GIT binary patch literal 826 zcmeAS@N?(olHy`uVBq!ia0vp^4Is?H1|$#LC7uRSEX7WqAsj$Z!;#Vf4nJ zsJsMW#sHP)KY)UgC9V-A!TD(=<%vb94CUqJdYO6I#mR{Use1WE>9gP2NHH)lZTEC> z45^s&_NHT&NFamj#ct#91(B_K4h7*ttRHhvHl9A=B5F+N6xh1SBo|E9nfOy?XI#f{{f?d0x6X%bwv2Wg&vDeK-_USZn78TP`eyAv`j6DsS~iJm&-HYV z%4T_g-D*Of{j0rJk6vGwIJmvi{nEli?`Q8@Dp)hKR7+OnPwnIFMors``Icoqyl=kW zwn_fLX36x+Ee5g+Et^h*SOpaw*WGLGFO?J9JG0Qtm*Y5lWHHMzd5t^vXQY%3{y8N6 zi~f8ac}wDk1br-SG<;{UI| zo}u2>pFYP|_|UJ9??3x3V06;or>w#K_eb9Xl`o5}n!9h zyWaZG|HuEhXt`%6x&IzGrq4M9i7a-rx=8CyA5Y&}*c*SXFZa);vVzCcw=S06zee`n zkJMxLEg!$1^RfKg59{. + * + * This file is part of Privacy Browser . + * + * Privacy Browser is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * Privacy Browser is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with Privacy Browser. If not, see . + */ + +package com.stoutner.privacybrowser; + +import android.app.Activity; +import android.app.Dialog; +import android.app.DialogFragment; +import android.content.DialogInterface; +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; +// If we don't use `android.support.v7.app.AlertDialog` instead of `android.app.AlertDialog` then the dialog will be covered by the keyboard. +import android.support.v7.app.AlertDialog; +import android.view.KeyEvent; +import android.view.View; +import android.view.WindowManager; +import android.widget.EditText; +import android.widget.ImageView; + +public class EditBookmark extends DialogFragment { + // The public interface is used to send information back to the parent activity. + public interface EditBookmarkListener { + void onEditBookmarkCancel(DialogFragment editBookmarkDialogFragment); + + void onEditBookmarkSave(DialogFragment editBookmarkDialogFragment); + } + + // `editBookmarkListener` is used in `onAttach()` and `onCreateDialog()` + private EditBookmarkListener editBookmarkListener; + + public void onAttach(Activity parentActivity) { + super.onAttach(parentActivity); + + // Get a handle for `EditBookmarkListener` from the `parentActivity`. + try { + editBookmarkListener = (EditBookmarkListener) parentActivity; + } catch(ClassCastException exception) { + throw new ClassCastException(parentActivity.toString() + " must implement EditBookmarkListener."); + } + } + + @Override + public Dialog onCreateDialog(Bundle savedInstanceState) { + // Get a long array with the the databaseId of the selected bookmark and convert it to an `int`. + long[] selectedBookmarksLongArray = BookmarksActivity.bookmarksListView.getCheckedItemIds(); + int selectedBookmarkDatabaseId = (int) selectedBookmarksLongArray[0]; + + // Get a `Cursor` with the specified bookmark and move it to the first position. + Cursor bookmarkCursor = BookmarksActivity.bookmarksDatabaseHandler.getBookmarkCursor(selectedBookmarkDatabaseId); + bookmarkCursor.moveToFirst(); + + // Get the favorite icon byte array from the `Cursor`. + byte[] favoriteIconByteArray = bookmarkCursor.getBlob(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.FAVORITE_ICON)); + // Convert the byte array to a `Bitmap` beginning at the first byte and ending at the last. + Bitmap favoriteIconBitmap = BitmapFactory.decodeByteArray(favoriteIconByteArray, 0, favoriteIconByteArray.length); + // Convert the `Bitmap` to a `Drawable`. + Drawable favoriteIconDrawable = new BitmapDrawable(getResources(), favoriteIconBitmap); + + // Use `AlertDialog.Builder` to create the `AlertDialog`. The style formats the color of the button text. + AlertDialog.Builder editBookmarkDialogBuilder = new AlertDialog.Builder(getActivity(), R.style.PrivacyBrowser_AlertDialog); + editBookmarkDialogBuilder.setTitle(R.string.edit_bookmark); + editBookmarkDialogBuilder.setIcon(favoriteIconDrawable); + // The parent view is `null` because it will be assigned by `AlertDialog`. + editBookmarkDialogBuilder.setView(getActivity().getLayoutInflater().inflate(R.layout.edit_bookmark_dialog, null)); + + // Set an `onClick()` listener for the negative button. + editBookmarkDialogBuilder.setNegativeButton(R.string.cancel, new Dialog.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Return the `DialogFragment` to the parent activity on cancel. + editBookmarkListener.onEditBookmarkCancel(EditBookmark.this); + } + }); + + // Set the `onClick()` listener fo the positive button. + editBookmarkDialogBuilder.setPositiveButton(R.string.save, new Dialog.OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + // Return the `DialogFragment` to the parent activity on save. + editBookmarkListener.onEditBookmarkSave(EditBookmark.this); + } + }); + + + // Create an `AlertDialog` from the `AlertDialog.Builder`. + final AlertDialog editBookmarkDialog = editBookmarkDialogBuilder.create(); + + // Show the keyboard when the `Dialog` is displayed on the screen. + editBookmarkDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE); + + // We need to show the `AlertDialog` before we can call `setOnKeyListener()` below. + editBookmarkDialog.show(); + + // Get a `Drawable` of the favorite icon from `mainWebView` and display it in `edit_bookmark_new_favorite_icon`. + ImageView newFavoriteIcon = (ImageView) editBookmarkDialog.findViewById(R.id.edit_bookmark_new_favorite_icon); + assert newFavoriteIcon != null; // Remove the warning below that `newFavoriteIcon` might be null. + newFavoriteIcon.setImageBitmap(MainWebViewActivity.favoriteIcon); + + // Load the text for `edit_bookmark_name_edittext`. + EditText bookmarkNameEditText = (EditText) editBookmarkDialog.findViewById(R.id.edit_bookmark_name_edittext); + assert bookmarkNameEditText != null; // Remove the warning below that `bookmarkNameEditText` might be null. + bookmarkNameEditText.setText(bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_NAME))); + + // Allow the `enter` key on the keyboard to save the bookmark from `edit_bookmark_name_edittext`. + bookmarkNameEditText.setOnKeyListener(new View.OnKeyListener() { + public boolean onKey(View v, int keyCode, KeyEvent event) { + // If the event is a key-down on the "enter" button, select the PositiveButton `Save`. + if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { + // Trigger `editBookmarkListener` and return the DialogFragment to the parent activity. + editBookmarkListener.onEditBookmarkSave(EditBookmark.this); + // Manually dismiss the `AlertDialog`. + editBookmarkDialog.dismiss(); + // Consume the event. + return true; + } else { // If any other key was pressed, do not consume the event. + return false; + } + } + }); + + // Load the text for `create_bookmark_url_edittext`. + EditText bookmarkUrlEditText = (EditText) editBookmarkDialog.findViewById(R.id.edit_bookmark_url_edittext); + assert bookmarkUrlEditText != null;// Remove the warning below that `bookmarkUrlEditText` might be null. + bookmarkUrlEditText.setText(bookmarkCursor.getString(bookmarkCursor.getColumnIndex(BookmarksDatabaseHandler.BOOKMARK_URL))); + + // Allow the "enter" key on the keyboard to save the bookmark from `edit_bookmark_url_edittext`. + bookmarkUrlEditText.setOnKeyListener(new View.OnKeyListener() { + public boolean onKey(View v, int keyCode, KeyEvent event) { + // If the event is a key-down on the `enter` button, select the PositiveButton `Save`. + if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER)) { + // Trigger `editBookmarkListener` and return the DialogFragment to the parent activity. + editBookmarkListener.onEditBookmarkSave(EditBookmark.this); + // Manually dismiss the `AlertDialog`. + editBookmarkDialog.dismiss(); + // Consume the event. + return true; + } else { // If any other key was pressed, do not consume the event. + return false; + } + } + }); + + // `onCreateDialog` requires the return of an `AlertDialog`. + return editBookmarkDialog; + } +} \ No newline at end of file diff --git a/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java b/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java index 5f549b25..e59168fe 100644 --- a/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java +++ b/app/src/main/java/com/stoutner/privacybrowser/MainWebViewActivity.java @@ -65,8 +65,8 @@ import java.net.URLEncoder; // We need to use AppCompatActivity from android.support.v7.app.AppCompatActivity to have access to the SupportActionBar until the minimum API is >= 21. public class MainWebViewActivity extends AppCompatActivity implements NavigationView.OnNavigationItemSelectedListener, CreateHomeScreenShortcut.CreateHomeScreenSchortcutListener { - // favoriteIcon is public static so it can be accessed from CreateHomeScreenShortcut and BookmarksActivity. - // It is also used in onCreate() and onCreateHomeScreenShortcutCreate(). + // `favoriteIcon` is public static so it can be accessed from `CreateHomeScreenShortcut`, `BookmarksActivity`, and `EditBookmark`. + // It is also used in `onCreate()` and `onCreateHomeScreenShortcutCreate()`. public static Bitmap favoriteIcon; // mainWebView is public static so it can be accessed from SettingsFragment. diff --git a/app/src/main/res/drawable/back.xml b/app/src/main/res/drawable/back.xml index 28da543b..e69b5ad5 100644 --- a/app/src/main/res/drawable/back.xml +++ b/app/src/main/res/drawable/back.xml @@ -3,6 +3,7 @@ . --> + + + + + diff --git a/app/src/main/res/drawable/exit.xml b/app/src/main/res/drawable/exit.xml index f50586d2..89d4faff 100644 --- a/app/src/main/res/drawable/exit.xml +++ b/app/src/main/res/drawable/exit.xml @@ -3,6 +3,7 @@ . --> - - - + + + - - + + + + + + + + android:layout_marginTop="6dp" + android:layout_marginBottom="12dp" + android:layout_marginStart="4dp" + android:layout_marginEnd="4dp" > + + + \ No newline at end of file diff --git a/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml b/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml index 32d2eb4d..5e924111 100644 --- a/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml +++ b/app/src/main/res/layout/create_home_screen_shortcut_dialog.xml @@ -21,23 +21,22 @@ + android:layout_height="wrap_content" + android:layout_width="match_parent" > - + - \ No newline at end of file diff --git a/app/src/main/res/layout/edit_bookmark_dialog.xml b/app/src/main/res/layout/edit_bookmark_dialog.xml new file mode 100644 index 00000000..1768ca08 --- /dev/null +++ b/app/src/main/res/layout/edit_bookmark_dialog.xml @@ -0,0 +1,96 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/app/src/main/res/layout/main_coordinatorlayout.xml b/app/src/main/res/layout/main_coordinatorlayout.xml index b59aeb45..520f450e 100644 --- a/app/src/main/res/layout/main_coordinatorlayout.xml +++ b/app/src/main/res/layout/main_coordinatorlayout.xml @@ -71,7 +71,8 @@ android:layout_height="match_parent" android:layout_gravity="start" app:headerLayout="@layout/navigation_header" - app:menu="@menu/webview_navigation_menu"/> + app:menu="@menu/webview_navigation_menu" + app:itemIconTint="@color/blue_gray" /> . --> - + - - + - - - - + - - + - \ No newline at end of file diff --git a/app/src/main/res/menu/bookmarks_context_menu.xml b/app/src/main/res/menu/bookmarks_context_menu.xml index 0d64adc0..6b2fc748 100644 --- a/app/src/main/res/menu/bookmarks_context_menu.xml +++ b/app/src/main/res/menu/bookmarks_context_menu.xml @@ -22,10 +22,17 @@ xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"> + + \ No newline at end of file diff --git a/app/src/main/res/values/colors.xml b/app/src/main/res/values/colors.xml index dad5ef3f..02fa590f 100644 --- a/app/src/main/res/values/colors.xml +++ b/app/src/main/res/values/colors.xml @@ -22,7 +22,8 @@ #FF000000 #FF1976D2 - #FF0D4781 + #FF0D47A1 + #FF607d8b #FF64DD17 #FFBBDEFB #FFD50000 diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index 6c87a126..5b5ad90d 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -35,6 +35,7 @@ Favorite Icon + URL or Search Terms Navigation Drawer @@ -70,11 +71,16 @@ Create bookmark + Edit bookmark + Save Bookmark name Bookmark URL + New favorite icon + Use new icon Selected + Edit Delete 1 Bookmark Deleted Bookmarks Deleted @@ -191,7 +197,7 @@ Permissions Privacy Policy Changelog - License + Licenses Contributors Links -- 2.45.2