Display the folder icons in the spinners in the bookmarks database view activity...
authorSoren Stoutner <soren@stoutner.com>
Mon, 21 Jan 2019 22:23:15 +0000 (15:23 -0700)
committerSoren Stoutner <soren@stoutner.com>
Mon, 21 Jan 2019 22:23:15 +0000 (15:23 -0700)
30 files changed:
.idea/dictionaries/soren.xml
app/src/main/assets/de/about_licenses_dark.html
app/src/main/assets/de/about_licenses_light.html
app/src/main/assets/en/about_licenses_dark.html
app/src/main/assets/en/about_licenses_light.html
app/src/main/assets/es/about_licenses_dark.html
app/src/main/assets/es/about_licenses_light.html
app/src/main/assets/it/about_licenses_dark.html
app/src/main/assets/it/about_licenses_light.html
app/src/main/assets/ru/about_licenses_dark.html
app/src/main/assets/ru/about_licenses_light.html
app/src/main/assets/tr/about_licenses_dark.html
app/src/main/assets/tr/about_licenses_light.html
app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksActivity.java
app/src/main/java/com/stoutner/privacybrowser/activities/BookmarksDatabaseViewActivity.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/CreateBookmarkFolderDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkDatabaseViewDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/EditBookmarkFolderDatabaseViewDialog.java
app/src/main/java/com/stoutner/privacybrowser/dialogs/UrlHistoryDialog.java
app/src/main/java/com/stoutner/privacybrowser/helpers/BookmarksDatabaseHelper.java
app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java [new file with mode: 0644]
app/src/main/res/layout/appbar_spinner_dropdown_item.xml
app/src/main/res/layout/appbar_spinner_item.xml
app/src/main/res/layout/databaseview_spinner_dropdown_items.xml [new file with mode: 0644]
app/src/main/res/layout/databaseview_spinner_item.xml [new file with mode: 0644]
app/src/main/res/values-es/strings.xml
app/src/main/res/values-it/strings.xml
app/src/main/res/values-ru/strings.xml
app/src/main/res/values-tr/strings.xml
app/src/main/res/values/colors.xml

index 8814f0c..6bd3f77 100644 (file)
@@ -6,6 +6,7 @@
       <w>adsense</w>
       <w>adservers</w>
       <w>adview</w>
+      <w>affero</w>
       <w>amiunique</w>
       <w>amoled</w>
       <w>androidcentral</w>
@@ -88,6 +89,7 @@
       <w>konqueror</w>
       <w>kufc</w>
       <w>león</w>
+      <w>licensors</w>
       <w>linearlayout</w>
       <w>listview</w>
       <w>logins</w>
       <w>nightmode</w>
       <w>nist</w>
       <w>nojs</w>
+      <w>noncommercially</w>
       <w>oname</w>
       <w>openkeychain</w>
       <w>openpgp</w>
       <w>referer</w>
       <w>refreshlayout</w>
       <w>relativelayout</w>
+      <w>relicensing</w>
       <w>remarketing</w>
       <w>requery</w>
       <w>roadmap</w>
       <w>subdomain</w>
       <w>subdomains</w>
       <w>subfolders</w>
+      <w>sublicenses</w>
+      <w>sublicensing</w>
       <w>sublists</w>
       <w>sufficientlysecure</w>
       <w>swiperefreshlayout</w>
       <w>websocket</w>
       <w>webview</w>
       <w>whatismyip</w>
+      <w>wipo</w>
       <w>wouldn</w>
       <w>xmlhttprequest</w>
       <w>yoyo</w>
index d239bb7..18b24f3 100644 (file)
         <h3>Libraries</h3>
         <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icons</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index b224f44..74116fa 100644 (file)
         <h3>Libraries</h3>
         <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icons</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index 97bf1fb..99cb2c6 100644 (file)
         <h3>Libraries</h3>
         <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icons</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index ecb7d54..8fd7c67 100644 (file)
         <h3>Libraries</h3>
         <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icons</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index 5046b13..66318aa 100644 (file)
         <h3>Librerías</h3>
         <p>Navegador privado está construido con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">librería de soporte de android</a>,
             que se libera bajo la <a href="https://www.apache.org/licenses/LICENSE-2.0">Licencia Apache 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Iconos</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index a1607e6..5ff4c60 100644 (file)
         <h3>Librerías</h3>
         <p>Navegador privado está construido con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">librería de soporte de android</a>,
             que se libera bajo la <a href="https://www.apache.org/licenses/LICENSE-2.0">Licencia Apache 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Iconos</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index 878dc7f..b9244d9 100644 (file)
         <h3>Librerie</h3>
         <p>Privacy Browser è sviluppato con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             che è rilasciata con <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icone</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index a1bccd7..6759c41 100644 (file)
         <h3>Librerie</h3>
         <p>Privacy Browser è sviluppato con la <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             che è rilasciata con <a href="https://www.apache.org/licenses/LICENSE-2.0">Licenza Apache 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icone</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index cd6badf..2fdeef6 100644 (file)
         <h3>Библиотеки</h3>
         <p>Privacy Browser создан с использованием <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             которая выпущена под <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Иконки</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index bd01254..3aacc9a 100644 (file)
         <h3>Библиотеки</h3>
         <p>Privacy Browser создан с использованием <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             которая выпущена под <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Иконки</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index 97bf1fb..99cb2c6 100644 (file)
         <h3>Libraries</h3>
         <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icons</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index ecb7d54..8fd7c67 100644 (file)
         <h3>Libraries</h3>
         <p>Privacy Browser is built with the <a href="https://developer.android.com/topic/libraries/support-library/index.html">Android Support Library</a>,
             which is released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.</p>
+        <p>The free flavor of Privacy Browser is built with <a href="https://mvnrepository.com/artifact/com.google.firebase/firebase-ads">Firebase Ads</a>,
+            which is released under the <a href="https://developer.android.com/studio/terms">Android Software Development Kit License</a>.</p>
+
+        <h3>Classes</h3>
+        <p><code>com.stoutner.privacybrowser.views.CheckedLinearLayout</code> is a modified version of a class contained in the
+            <a href="https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java">Android Camera</a> source code.
+            The original file was released under the <a href="https://www.apache.org/licenses/LICENSE-2.0">Apache License 2.0</a>.
+            The modified file is released under the <a href="https://www.gnu.org/licenses/gpl-3.0.html">GPLv3+ license</a>.</p>
 
         <h3>Icons</h3>
         <p><img class="left" src="../shared_images/privacy_browser.png"> <img class="left" src="../shared_images/privacy_browser_free.png"> <img class="left" src="../shared_images/warning.png">
index 576e653..3858418 100644 (file)
@@ -203,9 +203,6 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
             bookmarkCursor.close();
         });
 
-        // Get a handle for the activity.
-        Activity activity = this;
-
         // Handle long presses on the list view.
         bookmarksListView.setMultiChoiceModeListener(new AbsListView.MultiChoiceModeListener() {
             // Instantiate the common variables.
@@ -680,10 +677,10 @@ public class BookmarksActivity extends AppCompatActivity implements CreateBookma
         // Get new folder name string.
         String folderNameString = createFolderNameEditText.getText().toString();
 
-        // Get the new folder icon `Bitmap`.
+        // Get the new folder icon bitmap.
         Bitmap folderIconBitmap;
         if (defaultFolderIconRadioButton.isChecked()) {  // Use the default folder icon.
-            // Get the default folder icon and convert it to a `Bitmap`.
+            // Get the default folder icon and convert it to a bitmap.
             Drawable folderIconDrawable = folderIconImageView.getDrawable();
             BitmapDrawable folderIconBitmapDrawable = (BitmapDrawable) folderIconDrawable;
             folderIconBitmap = folderIconBitmapDrawable.getBitmap();
index dd9c42c..70bd773 100644 (file)
@@ -60,6 +60,7 @@ import com.stoutner.privacybrowser.dialogs.EditBookmarkFolderDatabaseViewDialog;
 import com.stoutner.privacybrowser.helpers.BookmarksDatabaseHelper;
 
 import java.io.ByteArrayOutputStream;
+import java.util.Arrays;
 
 public class BookmarksDatabaseViewActivity extends AppCompatActivity implements EditBookmarkDatabaseViewDialog.EditBookmarkDatabaseViewListener,
         EditBookmarkFolderDatabaseViewDialog.EditBookmarkFolderDatabaseViewListener {
@@ -128,7 +129,7 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
         appBar.setCustomView(R.layout.spinner);
         appBar.setDisplayOptions(ActionBar.DISPLAY_SHOW_CUSTOM | ActionBar.DISPLAY_HOME_AS_UP);
 
-        // Initialize the database handler.  `this` specifies the context.  The `0` is to specify a database version, but that is set instead using a constant in `BookmarksDatabaseHelper`.
+        // Initialize the database handler.  The `0` is to specify a database version, but that is set instead using a constant in `BookmarksDatabaseHelper`.
         bookmarksDatabaseHelper = new BookmarksDatabaseHelper(this, null, null, 0);
 
         // Setup a matrix cursor for "All Folders" and "Home Folder".
@@ -143,13 +144,60 @@ public class BookmarksDatabaseViewActivity extends AppCompatActivity implements
         // Combine `matrixCursor` and `foldersCursor`.
         MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor});
 
+
+        // Get the default folder bitmap.  `ContextCompat` must be used until the minimum API >= 21.
+        Drawable defaultFolderDrawable = ContextCompat.getDrawable(getApplicationContext(), R.drawable.folder_blue_bitmap);
+
+        // Cast the default folder drawable to a `BitmapDrawable`.
+        BitmapDrawable defaultFolderBitmapDrawable = (BitmapDrawable) defaultFolderDrawable;
+
+        // Remove the incorrect lint warning that `.getBitmap()` might be null.
+        assert defaultFolderBitmapDrawable != null;
+
+        // Convert the default folder `BitmapDrawable` to a bitmap.
+        Bitmap defaultFolderBitmap = defaultFolderBitmapDrawable.getBitmap();
+
+
         // Create a resource cursor adapter for the spinner.
         ResourceCursorAdapter foldersCursorAdapter = new ResourceCursorAdapter(this, R.layout.appbar_spinner_item, foldersMergeCursor, 0) {
             @Override
             public void bindView(View view, Context context, Cursor cursor) {
-                // Get a handle for the spinner item text view.
+                // Get handles for the spinner views.
+                ImageView spinnerItemImageView = view.findViewById(R.id.spinner_item_imageview);
                 TextView spinnerItemTextView = view.findViewById(R.id.spinner_item_textview);
 
+                // Set the folder icon according to the type.
+                if (foldersMergeCursor.getPosition() > 1) {  // Set a user folder icon.
+                    // Initialize a default folder icon byte array output stream.
+                    ByteArrayOutputStream defaultFolderIconByteArrayOutputStream = new ByteArrayOutputStream();
+
+                    // Covert the default folder bitmap to a PNG and store it in the output stream.  `0` is for lossless compression (the only option for a PNG).
+                    defaultFolderBitmap.compress(Bitmap.CompressFormat.PNG, 0, defaultFolderIconByteArrayOutputStream);
+
+                    // Convert the default folder icon output stream to a byte array.
+                    byte[] defaultFolderIconByteArray = defaultFolderIconByteArrayOutputStream.toByteArray();
+
+
+                    // Get the folder icon byte array from the cursor.
+                    byte[] folderIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHelper.FAVORITE_ICON));
+
+                    // Convert the byte array to a bitmap beginning at the first byte and ending at the last.
+                    Bitmap folderIconBitmap = BitmapFactory.decodeByteArray(folderIconByteArray, 0, folderIconByteArray.length);
+
+
+                    // Set the icon according to the type.
+                    if (Arrays.equals(folderIconByteArray, defaultFolderIconByteArray)) {  // The default folder icon is used.
+                        // Set a smaller and darker folder icon, which works well with the spinner.
+                        spinnerItemImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.folder_dark_blue));
+                    } else {  // A custom folder icon is uses.
+                        // Set the folder image stored in the cursor.
+                        spinnerItemImageView.setImageBitmap(folderIconBitmap);
+                    }
+                } else {  // Set the `All Folders` or `Home Folder` icon.
+                    // Set the gray folder image.  `ContextCompat` must be used until the minimum API >= 21.
+                    spinnerItemImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.folder_gray));
+                }
+
                 // Set the text view to display the folder name.
                 spinnerItemTextView.setText(cursor.getString(cursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME)));
             }
index a7a9661..83aa93f 100644 (file)
@@ -94,7 +94,7 @@ public class CreateBookmarkFolderDialog extends AppCompatDialogFragment {
         });
 
 
-        // Create an `AlertDialog` from the `AlertDialog.Builder`.
+        // Create an alert dialog from the `AlertDialog.Builder`.
         final AlertDialog alertDialog = dialogBuilder.create();
 
         // Remove the warning below that `getWindow()` might be null.
@@ -108,7 +108,7 @@ public class CreateBookmarkFolderDialog extends AppCompatDialogFragment {
         // Show the keyboard when the `Dialog` is displayed on the screen.
         alertDialog.getWindow().setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_VISIBLE);
 
-        // The `AlertDialog` must be shown before items in the alert dialog can be modified.
+        // The alert dialog must be shown before items in the alert dialog can be modified.
         alertDialog.show();
 
         // Get handles for the views in the dialog.
@@ -147,7 +147,7 @@ public class CreateBookmarkFolderDialog extends AppCompatDialogFragment {
             }
         });
 
-        // Allow the `enter` key on the keyboard to create the folder from `create_folder_name_edittext`.
+        // Allow the enter key on the keyboard to create the folder from `create_folder_name_edittext`.
         folderNameEditText.setOnKeyListener((View v, int keyCode, KeyEvent event) -> {
             // If the event is a key-down on the `enter` key, select the `PositiveButton` `Create`.
             if ((event.getAction() == KeyEvent.ACTION_DOWN) && (keyCode == KeyEvent.KEYCODE_ENTER) && createButton.isEnabled()) {  // The enter key was pressed and the create button is enabled.
index 7328080..5abda5b 100644 (file)
@@ -32,6 +32,7 @@ import android.graphics.BitmapFactory;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
 // `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
+import android.support.v4.content.ContextCompat;
 import android.support.v4.widget.ResourceCursorAdapter;
 import android.support.v7.app.AppCompatDialogFragment;
 import android.text.Editable;
@@ -194,19 +195,19 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
         // Display `currentIconBitmap` in `edit_bookmark_current_icon`.
         currentIconImageView.setImageBitmap(currentIconBitmap);
 
-        // Get a `Bitmap` of the favorite icon from `MainWebViewActivity` and display it in `edit_bookmark_web_page_favorite_icon`.
+        // Get a bitmap of the favorite icon from `MainWebViewActivity` and display it in `edit_bookmark_web_page_favorite_icon`.
         newFavoriteIconImageView.setImageBitmap(MainWebViewActivity.favoriteIconBitmap);
 
         // Populate the bookmark name and URL `EditTexts`.
         nameEditText.setText(currentBookmarkName);
         urlEditText.setText(currentUrl);
 
-        // Setup a `MatrixCursor` "Home Folder".
+        // Setup a matrix cursor for "Home Folder".
         String[] matrixCursorColumnNames = {BookmarksDatabaseHelper._ID, BookmarksDatabaseHelper.BOOKMARK_NAME};
         MatrixCursor matrixCursor = new MatrixCursor(matrixCursorColumnNames);
         matrixCursor.addRow(new Object[]{HOME_FOLDER_DATABASE_ID, getString(R.string.home_folder)});
 
-        // Get a `Cursor` with the list of all the folders.
+        // Get a cursor with the list of all the folders.
         Cursor foldersCursor = bookmarksDatabaseHelper.getAllFolders();
 
         // Combine `matrixCursor` and `foldersCursor`.
@@ -215,20 +216,36 @@ public class EditBookmarkDatabaseViewDialog extends AppCompatDialogFragment {
         // Remove the incorrect lint warning below that `getContext()` might be null.
         assert getContext() != null;
 
-        // Create a `ResourceCursorAdapter` for the `Spinner`.  `0` specifies no flags.;
-        ResourceCursorAdapter foldersCursorAdapter = new ResourceCursorAdapter(getContext(), R.layout.spinner_item, foldersMergeCursor, 0) {
+        // Create a resource cursor adapter for the spinner.
+        ResourceCursorAdapter foldersCursorAdapter = new ResourceCursorAdapter(getContext(), R.layout.databaseview_spinner_item, foldersMergeCursor, 0) {
             @Override
             public void bindView(View view, Context context, Cursor cursor) {
-                // Get a handle for the `Spinner` item `TextView`.
+                // Get handles for the spinner views.
+                ImageView spinnerItemImageView = view.findViewById(R.id.spinner_item_imageview);
                 TextView spinnerItemTextView = view.findViewById(R.id.spinner_item_textview);
 
-                // Set the `TextView` to display the folder name.
+                // Set the folder icon according to the type.
+                if (foldersMergeCursor.getPosition() == 0) {  // Set the `Home Folder` icon.
+                    // Set the gray folder image.  `ContextCompat` must be used until the minimum API >= 21.
+                    spinnerItemImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.folder_gray));
+                } else {  // Set a user folder icon.
+                    // Get the folder icon byte array.
+                    byte[] folderIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHelper.FAVORITE_ICON));
+
+                    // Convert the byte array to a bitmap beginning at the first byte and ending at the last.
+                    Bitmap folderIconBitmap = BitmapFactory.decodeByteArray(folderIconByteArray, 0, folderIconByteArray.length);
+
+                    // Set the folder icon.
+                    spinnerItemImageView.setImageBitmap(folderIconBitmap);
+                }
+
+                // Set the text view to display the folder name.
                 spinnerItemTextView.setText(cursor.getString(cursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME)));
             }
         };
 
         // Set the `ResourceCursorAdapter` drop drown view resource.
-        foldersCursorAdapter.setDropDownViewResource(R.layout.spinner_dropdown_items);
+        foldersCursorAdapter.setDropDownViewResource(R.layout.databaseview_spinner_dropdown_items);
 
         // Set the adapter for the folder `Spinner`.
         folderSpinner.setAdapter(foldersCursorAdapter);
index 75e0d91..0f69143 100644 (file)
@@ -32,6 +32,7 @@ import android.graphics.Bitmap;
 import android.graphics.BitmapFactory;
 import android.os.Bundle;
 import android.support.annotation.NonNull;
+import android.support.v4.content.ContextCompat;
 import android.support.v4.widget.ResourceCursorAdapter;
 // `AppCompatDialogFragment` is required instead of `DialogFragment` or an error is produced on API <=22.
 import android.support.v7.app.AppCompatDialogFragment;
@@ -189,49 +190,65 @@ public class EditBookmarkFolderDatabaseViewDialog extends AppCompatDialogFragmen
         // Convert the byte array to a `Bitmap` beginning at the first byte and ending at the last.
         Bitmap currentIconBitmap = BitmapFactory.decodeByteArray(currentIconByteArray, 0, currentIconByteArray.length);
 
-        // Display `currentIconBitmap` in `edit_bookmark_current_icon`.
+        // Display the current icon bitmap in `edit_bookmark_current_icon`.
         currentIconImageView.setImageBitmap(currentIconBitmap);
 
-        // Get a `Bitmap` of the favorite icon from `MainWebViewActivity` and display it in `edit_bookmark_web_page_favorite_icon`.
+        // Get a bitmap of the favorite icon from `MainWebViewActivity` and display it in `edit_bookmark_web_page_favorite_icon`.
         newFavoriteIconImageView.setImageBitmap(MainWebViewActivity.favoriteIconBitmap);
 
-        // Populate the folder name `EditText`.
+        // Populate the folder name edit text.
         nameEditText.setText(currentFolderName);
 
-        // Setup a `MatrixCursor` "Home Folder".
+        // Setup a matrix cursor for "Home Folder".
         String[] matrixCursorColumnNames = {BookmarksDatabaseHelper._ID, BookmarksDatabaseHelper.BOOKMARK_NAME};
         MatrixCursor matrixCursor = new MatrixCursor(matrixCursorColumnNames);
         matrixCursor.addRow(new Object[]{HOME_FOLDER_DATABASE_ID, getString(R.string.home_folder)});
 
-        // Initialize a `StringBuilder` to track the folders not to display in the `Spinner` and populate it with the current folder.
+        // Initialize a string builder to track the folders not to display in the spinner and populate it with the current folder.
         exceptFolders = new StringBuilder(DatabaseUtils.sqlEscapeString(currentFolderName));
 
         // Add all subfolders of the current folder to the list of folders not to display.
         addSubfoldersToExceptFolders(currentFolderName);
 
-        // Get a `Cursor` with the list of all the folders.
+        // Get a cursor with the list of all the folders.
         Cursor foldersCursor = bookmarksDatabaseHelper.getFoldersExcept(exceptFolders.toString());
 
-        // Combine `matrixCursor` and `foldersCursor`.
+        // Combine the matrix cursor and the folders cursor.
         MergeCursor foldersMergeCursor = new MergeCursor(new Cursor[]{matrixCursor, foldersCursor});
 
         // Remove the incorrect lint warning that `getContext()` might be null.
         assert getContext() != null;
 
-        // Create a `ResourceCursorAdapter` for the `Spinner`.  `0` specifies no flags.;
-        ResourceCursorAdapter foldersCursorAdapter = new ResourceCursorAdapter(getContext(), R.layout.spinner_item, foldersMergeCursor, 0) {
+        // Create a resource cursor adapter for the spinner.
+        ResourceCursorAdapter foldersCursorAdapter = new ResourceCursorAdapter(getContext(), R.layout.databaseview_spinner_item, foldersMergeCursor, 0) {
             @Override
             public void bindView(View view, Context context, Cursor cursor) {
-                // Get a handle for the `Spinner` item `TextView`.
+                // Get handles for the spinner views.
+                ImageView spinnerItemImageView = view.findViewById(R.id.spinner_item_imageview);
                 TextView spinnerItemTextView = view.findViewById(R.id.spinner_item_textview);
 
-                // Set the `TextView` to display the folder name.
+                // Set the folder icon according to the type.
+                if (foldersMergeCursor.getPosition() == 0) {  // Set the `Home Folder` icon.
+                    // Set the gray folder image.  `ContextCompat` must be used until the minimum API >= 21.
+                    spinnerItemImageView.setImageDrawable(ContextCompat.getDrawable(context, R.drawable.folder_gray));
+                } else {  // Set a user folder icon.
+                    // Get the folder icon byte array.
+                    byte[] folderIconByteArray = cursor.getBlob(cursor.getColumnIndex(BookmarksDatabaseHelper.FAVORITE_ICON));
+
+                    // Convert the byte array to a bitmap beginning at the first byte and ending at the last.
+                    Bitmap folderIconBitmap = BitmapFactory.decodeByteArray(folderIconByteArray, 0, folderIconByteArray.length);
+
+                    // Set the folder icon.
+                    spinnerItemImageView.setImageBitmap(folderIconBitmap);
+                }
+
+                // Set the text view to display the folder name.
                 spinnerItemTextView.setText(cursor.getString(cursor.getColumnIndex(BookmarksDatabaseHelper.BOOKMARK_NAME)));
             }
         };
 
         // Set the `ResourceCursorAdapter` drop drown view resource.
-        foldersCursorAdapter.setDropDownViewResource(R.layout.spinner_dropdown_items);
+        foldersCursorAdapter.setDropDownViewResource(R.layout.databaseview_spinner_dropdown_items);
 
         // Set the adapter for the folder `Spinner`.
         folderSpinner.setAdapter(foldersCursorAdapter);
index 9b9d9f6..a593f5c 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright © 2016-2018 Soren Stoutner <soren@stoutner.com>.
+ * Copyright © 2016-2019 Soren Stoutner <soren@stoutner.com>.
  *
  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
  *
@@ -57,37 +57,37 @@ public class UrlHistoryDialog extends AppCompatDialogFragment{
     private int currentPageId;
 
     public static UrlHistoryDialog loadBackForwardList(Context context, WebBackForwardList webBackForwardList) {
-        // Create `argumentsBundle`.
+        // Create an arguments bundle.
         Bundle argumentsBundle = new Bundle();
 
-        // Store `currentPageIndex`.
+        // Store the current page index.
         int currentPageIndex = webBackForwardList.getCurrentIndex();
 
-        // Setup `urlArrayList` and `iconArrayList`.
+        // Setup the URL array list and the icon array list.
         ArrayList<String> urlArrayList = new ArrayList<>();
         ArrayList<String> iconBase64StringArrayList = new ArrayList<>();
 
-        // Get the default favorite icon `Drawable`.
+        // Get the default favorite icon drawable.  `ContextCompat` must be used until the minimum API >= 21.
         Drawable defaultFavoriteIconDrawable = ContextCompat.getDrawable(context, R.drawable.world);
 
-        // Convert `defaultFavoriteIconDrawable` to a `BitmapDrawable`.
+        // Convert the default favorite icon drawable to a `BitmapDrawable`.
         BitmapDrawable defaultFavoriteIconBitmapDrawable = (BitmapDrawable) defaultFavoriteIconDrawable;
 
         // Remove the incorrect lint error that `getBitmap()` might be null.
         assert defaultFavoriteIconBitmapDrawable != null;
 
-        // Extract a `Bitmap` from `defaultFavoriteIconBitmapDrawable`.
+        // Extract a `Bitmap` from the default favorite icon `BitmapDrawable`.
         Bitmap defaultFavoriteIcon = defaultFavoriteIconBitmapDrawable.getBitmap();
 
-        // Populate `urlArrayList` and `iconArrayList` from `webBackForwardList`.
+        // Populate the URL array list and the icon array list from `webBackForwardList`.
         for (int i=0; i < webBackForwardList.getSize(); i++) {
             // Store the URL.
             urlArrayList.add(webBackForwardList.getItemAtIndex(i).getUrl());
 
-            // Create a variable to store the icon `Bitmap`.
+            // Create a variable to store the icon bitmap.
             Bitmap iconBitmap;
 
-            // Store the icon `Bitmap`.
+            // Store the icon bitmap.
             if (webBackForwardList.getItemAtIndex(i).getFavicon() == null) {
                 // If `webBackForwardList` does not have a favorite icon, use Privacy Browser's default world icon.
                 iconBitmap = defaultFavoriteIcon;
@@ -119,7 +119,7 @@ public class UrlHistoryDialog extends AppCompatDialogFragment{
         argumentsBundle.putStringArrayList("URL_History", urlArrayList);
         argumentsBundle.putStringArrayList("Favorite_Icons", iconBase64StringArrayList);
 
-        // Add `argumentsBundle` to this instance of `UrlHistoryDialog`.
+        // Add the arguments bundle to this instance of `UrlHistoryDialog`.
         UrlHistoryDialog thisUrlHistoryDialog = new UrlHistoryDialog();
         thisUrlHistoryDialog.setArguments(argumentsBundle);
         return thisUrlHistoryDialog;
index 8508931..a2af645 100644 (file)
@@ -295,8 +295,7 @@ public class BookmarksDatabaseHelper extends SQLiteOpenHelper {
                 " WHERE " + IS_FOLDER + " = " + 1 +
                 " ORDER BY " + BOOKMARK_NAME + " ASC";
 
-        // Return the results as a `Cursor`.  The second argument is `null` because there are no `selectionArgs`.
-        // We can't close the `Cursor` because we need to use it in the parent activity.
+        // Return the results as a cursor.  The cursor cannot be closed because it is used in the parent activity.
         return bookmarksDatabase.rawQuery(GET_ALL_FOLDERS, null);
     }
 
diff --git a/app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java b/app/src/main/java/com/stoutner/privacybrowser/views/CheckedLinearLayout.java
new file mode 100644 (file)
index 0000000..e9bc804
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright © 2019 Soren Stoutner <soren@stoutner.com>.
+ *
+ * This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>.
+ *
+ *
+ *
+ * This file is a modified version of <https://android.googlesource.com/platform/packages/apps/Camera/+/master/src/com/android/camera/ui/CheckedLinearLayout.java>.
+ *
+ * The original licensing information is below.
+ *
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.stoutner.privacybrowser.views;
+
+import android.content.Context;
+import android.support.annotation.Nullable;
+import android.util.AttributeSet;
+import android.view.View;
+import android.widget.Checkable;
+import android.widget.LinearLayout;
+
+public class CheckedLinearLayout extends LinearLayout implements Checkable {
+    private boolean isCurrentlyChecked;
+    private static final int[] CHECKED_STATE_SET = {
+            android.R.attr.state_checked
+    };
+
+    public CheckedLinearLayout(Context context) {
+        // Run the default commands.
+        super(context);
+    }
+
+    public CheckedLinearLayout(Context context, @Nullable AttributeSet attributeSet) {
+        // Run the default commands.
+        super(context, attributeSet);
+    }
+
+    public CheckedLinearLayout(Context context, @Nullable AttributeSet attributeSet, int defaultStyleAttribute) {
+        // Run the default commands.
+        super(context, attributeSet, defaultStyleAttribute);
+    }
+
+    /*  This constructor can only be added once the minimum API >= 21.
+    public CheckedLinearLayout(Context context, @Nullable AttributeSet attributeSet, int defaultStyleAttribute, int defaultStyleResource) {
+        // Run the default commands.
+        super(context, attributeSet, defaultStyleAttribute, defaultStyleResource);
+    } */
+
+    @Override
+    public boolean isChecked() {
+        // Return the checked status.
+        return isCurrentlyChecked;
+    }
+
+    @Override
+    public void setChecked(boolean checked) {
+        // Only process the command if a change is requested.
+        if (isCurrentlyChecked != checked) {
+            // Update the is currently checked tracker.
+            isCurrentlyChecked = checked;
+
+            // Refresh the drawable state.
+            refreshDrawableState();
+
+            // Propagate the checked status to the child views.
+            for (int i = 0; i < getChildCount(); i++) {
+                // Get a handle for the child view.
+                View childView = getChildAt(i);
+
+                // Propagate the checked status if the child view is checkable.
+                if (childView instanceof Checkable) {
+                    // Cast the child view to `Checkable`.
+                    Checkable checkableChildView = (Checkable) childView;
+
+                    // Set the checked status.
+                    checkableChildView.setChecked(checked);
+                }
+            }
+        }
+    }
+
+    @Override
+    public void toggle() {
+        // Toggle the state.
+        setChecked(!isCurrentlyChecked);
+    }
+
+    @Override
+    public int[] onCreateDrawableState(int extraSpace) {
+        final int[] drawableState = super.onCreateDrawableState(extraSpace + 1);
+
+        if (isCurrentlyChecked) {
+            mergeDrawableStates(drawableState, CHECKED_STATE_SET);
+        }
+
+        return drawableState;
+    }
+}
index d71b180..a658675 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
   You should have received a copy of the GNU General Public License
   along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<!-- A checked text view allows the color of the text to be changed when it is selected (checked). -->
-<CheckedTextView
+<com.stoutner.privacybrowser.views.CheckedLinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/spinner_item_textview"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:maxLines="1"
-    android:ellipsize="end"
-    android:paddingStart="20dp"
-    android:paddingEnd="20dp"
-    android:paddingTop="8dp"
-    android:paddingBottom="8dp"
-    android:textSize="18sp"
-    android:textColor="?attr/appbarSpinnerTextColorSelector"
-    android:background="?attr/spinnerBackground" />
\ No newline at end of file
+    android:orientation="horizontal"
+    android:background="?attr/spinnerBackground" >
+
+    <ImageView
+        android:id="@+id/spinner_item_imageview"
+        android:layout_height="30dp"
+        android:layout_width="30dp"
+        android:layout_gravity="center_vertical"
+        android:layout_marginStart="10dp"
+        tools:ignore="contentDescription" />
+
+    <!-- A checked text view allows the color of the text to be changed when it is selected (checked). -->
+    <CheckedTextView
+        android:id="@+id/spinner_item_textview"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:paddingStart="20dp"
+        android:paddingEnd="20dp"
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp"
+        android:textSize="18sp"
+        android:textColor="?attr/appbarSpinnerTextColorSelector" />
+</com.stoutner.privacybrowser.views.CheckedLinearLayout>
\ No newline at end of file
index 3e7cc3c..5c61a20 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 
 <!--
-  Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+  Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
 
   This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
 
   You should have received a copy of the GNU General Public License
   along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>. -->
 
-<TextView
+<LinearLayout
     xmlns:android="http://schemas.android.com/apk/res/android"
-    android:id="@+id/spinner_item_textview"
+    xmlns:tools="http://schemas.android.com/tools"
     android:layout_height="wrap_content"
     android:layout_width="match_parent"
-    android:maxLines="1"
-    android:ellipsize="end"
-    android:paddingStart="10dp"
-    android:paddingEnd="10dp"
-    android:textSize="18sp"
-    android:textColor="?attr/spinnerHeaderTextColor" />
\ No newline at end of file
+    android:orientation="horizontal"
+    tools:ignore="UseCompoundDrawables" >
+
+    <ImageView
+        android:id="@+id/spinner_item_imageview"
+        android:layout_height="30dp"
+        android:layout_width="30dp"
+        android:layout_gravity="center_vertical"
+        android:layout_marginStart="10dp"
+        tools:ignore="contentDescription" />
+
+    <TextView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/spinner_item_textview"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:paddingStart="10dp"
+        android:paddingEnd="10dp"
+        android:textSize="18sp"
+        android:textColor="?attr/spinnerHeaderTextColor" />
+</LinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/databaseview_spinner_dropdown_items.xml b/app/src/main/res/layout/databaseview_spinner_dropdown_items.xml
new file mode 100644 (file)
index 0000000..5e3c1ff
--- /dev/null
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright © 2017-2018 Soren Stoutner <soren@stoutner.com>.
+
+  This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>. -->
+
+<com.stoutner.privacybrowser.views.CheckedLinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="horizontal" >
+
+    <ImageView
+        android:id="@+id/spinner_item_imageview"
+        android:layout_height="30dp"
+        android:layout_width="30dp"
+        android:layout_gravity="center_vertical"
+        android:layout_marginStart="10dp"
+        tools:ignore="contentDescription" />
+
+    <!-- A `CheckedTextView` allows the color of the text to be changed when it is selected (checked). -->
+    <CheckedTextView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/spinner_item_textview"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:paddingStart="20dp"
+        android:paddingEnd="20dp"
+        android:paddingTop="8dp"
+        android:paddingBottom="8dp"
+        android:textSize="18sp"
+        android:textColor="?attr/spinnerTextColorSelector" />
+</com.stoutner.privacybrowser.views.CheckedLinearLayout>
\ No newline at end of file
diff --git a/app/src/main/res/layout/databaseview_spinner_item.xml b/app/src/main/res/layout/databaseview_spinner_item.xml
new file mode 100644 (file)
index 0000000..e254b49
--- /dev/null
@@ -0,0 +1,48 @@
+<?xml version="1.0" encoding="utf-8"?>
+
+<!--
+  Copyright © 2017-2019 Soren Stoutner <soren@stoutner.com>.
+
+  This file is part of Privacy Browser <https://www.stoutner.com/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 <http://www.gnu.org/licenses/>. -->
+
+<LinearLayout
+    xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_height="wrap_content"
+    android:layout_width="match_parent"
+    android:orientation="horizontal"
+    tools:ignore="UseCompoundDrawables" >
+
+    <ImageView
+        android:id="@+id/spinner_item_imageview"
+        android:layout_height="30dp"
+        android:layout_width="30dp"
+        android:layout_gravity="center_vertical"
+        android:layout_marginStart="10dp"
+        tools:ignore="contentDescription" />
+
+    <TextView
+        xmlns:android="http://schemas.android.com/apk/res/android"
+        android:id="@+id/spinner_item_textview"
+        android:layout_height="wrap_content"
+        android:layout_width="match_parent"
+        android:maxLines="1"
+        android:ellipsize="end"
+        android:paddingStart="10dp"
+        android:paddingEnd="10dp"
+        android:textSize="18sp"
+        android:textColor="?android:textColorPrimary" />
+</LinearLayout>
\ No newline at end of file
index 6ab409a..789a3f6 100644 (file)
     <string name="folder">Carpeta:</string>
     <string name="parent_folder">Carpeta superior:</string>
     <string name="display_order">Mostrar orden:</string>
+    <string name="cannot_deselect_bookmark">No se puede deseleccionar un favorito mientras la carpeta superior está seleccionada.</string>
 
     <!-- Requests. -->
     <string name="requests">Peticiones</string>
index 79deaeb..3c3c149 100644 (file)
     <string name="folder">Cartella:</string>
     <string name="parent_folder">Cartella superiore:</string>
     <string name="display_order">Ordine di visualizzazione:</string>
+    <string name="cannot_deselect_bookmark">Non è possibile deselezionare un segnalibro mentre la cartella di appartenenza è selezionate.</string>
 
     <!-- Requests. -->
     <string name="requests">Richieste</string>
index 628cc79..3217b5d 100644 (file)
     <string name="folder">Папка:</string>
     <string name="parent_folder">Родительская папка:</string>
     <string name="display_order">Порядок отображения:</string>
+    <string name="cannot_deselect_bookmark">Невозможно отменить выбор закладки пока выбрана родительская папка.</string>
 
     <!-- Requests. -->
     <string name="requests">Запросы</string>
index 4092272..1f209cc 100644 (file)
     <string name="folder">Klasör:</string>
     <string name="parent_folder">Üst Klasör:</string>
     <string name="display_order">Görüntüleme düzeni:</string>
+    <string name="cannot_deselect_bookmark">Üst klasör seçiliyken bir yer iminin seçimi kaldırılamaz.</string>
 
     <!-- Requests. -->
     <string name="requests">İstekler</string>
index 2d4448e..0bcee21 100644 (file)
@@ -23,6 +23,9 @@
     <color name="semi_transparent_black">#66000000</color>
 
     <color name="black">#FF000000</color>
+    <color name="black_translucent_11">#11000000</color>
+    <color name="black_translucent_22">#22000000</color>
+    <color name="black_translucent_33">#33000000</color>
 
     <color name="blue_50">#FFE3F2FD</color>
     <color name="blue_100">#FFBBDEFB</color>