]> gitweb.stoutner.com Git - PrivacyBrowserAndroid.git/blob - app/src/main/java/com/stoutner/privacybrowser/dialogs/OpenDialog.kt
Convert a number of files to Kotlin. https://redmine.stoutner.com/issues/641
[PrivacyBrowserAndroid.git] / app / src / main / java / com / stoutner / privacybrowser / dialogs / OpenDialog.kt
1 /*
2  * Copyright © 2019-2021 Soren Stoutner <soren@stoutner.com>.
3  *
4  * This file is part of Privacy Browser <https://www.stoutner.com/privacy-browser>.
5  *
6  * Privacy Browser is free software: you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation, either version 3 of the License, or
9  * (at your option) any later version.
10  *
11  * Privacy Browser is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14  * GNU General Public License for more details.
15  *
16  * You should have received a copy of the GNU General Public License
17  * along with Privacy Browser.  If not, see <http://www.gnu.org/licenses/>.
18  */
19
20 package com.stoutner.privacybrowser.dialogs
21
22 import android.Manifest
23 import android.annotation.SuppressLint
24 import android.app.Dialog
25 import android.content.Context
26 import android.content.DialogInterface
27 import android.content.Intent
28 import android.content.pm.PackageManager
29 import android.content.res.Configuration
30 import android.os.Bundle
31 import android.text.Editable
32 import android.text.TextWatcher
33 import android.view.View
34 import android.view.WindowManager
35 import android.widget.Button
36 import android.widget.EditText
37 import android.widget.TextView
38
39 import androidx.appcompat.app.AlertDialog
40 import androidx.core.content.ContextCompat
41 import androidx.fragment.app.DialogFragment
42 import androidx.preference.PreferenceManager
43
44 import com.stoutner.privacybrowser.R
45 import com.stoutner.privacybrowser.activities.MainWebViewActivity
46 import com.stoutner.privacybrowser.helpers.DownloadLocationHelper
47
48 import java.io.File
49
50 class OpenDialog : DialogFragment() {
51     // Define the open listener.
52     private lateinit var openListener: OpenListener
53
54     // The public interface is used to send information back to the parent activity.
55     interface OpenListener {
56         fun onOpen(dialogFragment: DialogFragment)
57     }
58
59     override fun onAttach(context: Context) {
60         // Run the default commands.
61         super.onAttach(context)
62
63         // Get a handle for the open listener from the launching context.
64         openListener = context as OpenListener
65     }
66
67     // `@SuppressLint("InflateParams")` removes the warning about using null as the parent view group when inflating the alert dialog.
68     @SuppressLint("InflateParams")
69     override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
70         // Use an alert dialog builder to create the alert dialog.
71         val dialogBuilder = AlertDialog.Builder(requireContext(), R.style.PrivacyBrowserAlertDialog)
72
73         // Get the current theme status.
74         val currentThemeStatus = resources.configuration.uiMode and Configuration.UI_MODE_NIGHT_MASK
75
76         // Set the icon according to the theme.
77         if (currentThemeStatus == Configuration.UI_MODE_NIGHT_NO) {
78             dialogBuilder.setIcon(R.drawable.proxy_enabled_day)
79         } else {
80             dialogBuilder.setIcon(R.drawable.proxy_enabled_night)
81         }
82
83         // Set the title.
84         dialogBuilder.setTitle(R.string.open)
85
86         // Set the view.  The parent view is null because it will be assigned by the alert dialog.
87         dialogBuilder.setView(requireActivity().layoutInflater.inflate(R.layout.open_dialog, null))
88
89         // Set the cancel button listener.  Using `null` as the listener closes the dialog without doing anything else.
90         dialogBuilder.setNegativeButton(R.string.cancel, null)
91
92         // Set the open button listener.
93         dialogBuilder.setPositiveButton(R.string.open) { _: DialogInterface?, _: Int ->
94             // Return the dialog fragment to the parent activity.
95             openListener.onOpen(this)
96         }
97
98         // Create an alert dialog from the builder.
99         val alertDialog = dialogBuilder.create()
100
101         // Get a handle for the shared preferences.
102         val sharedPreferences = PreferenceManager.getDefaultSharedPreferences(context)
103
104         // Get the screenshot preference.
105         val allowScreenshots = sharedPreferences.getBoolean(getString(R.string.allow_screenshots_key), false)
106
107         // Disable screenshots if not allowed.
108         if (!allowScreenshots) {
109             alertDialog.window!!.addFlags(WindowManager.LayoutParams.FLAG_SECURE)
110         }
111
112         // The alert dialog must be shown before items in the layout can be modified.
113         alertDialog.show()
114
115         // Get handles for the layout items.
116         val fileNameEditText = alertDialog.findViewById<EditText>(R.id.file_name_edittext)!!
117         val browseButton = alertDialog.findViewById<Button>(R.id.browse_button)!!
118         val fileDoesNotExistTextView = alertDialog.findViewById<TextView>(R.id.file_does_not_exist_textview)!!
119         val storagePermissionTextView = alertDialog.findViewById<TextView>(R.id.storage_permission_textview)!!
120         val openButton = alertDialog.getButton(AlertDialog.BUTTON_POSITIVE)
121
122         // Update the status of the open button when the file name changes.
123         fileNameEditText.addTextChangedListener(object : TextWatcher {
124             override fun beforeTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
125                 // Do nothing.
126             }
127
128             override fun onTextChanged(charSequence: CharSequence, i: Int, i1: Int, i2: Int) {
129                 // Do nothing.
130             }
131
132             override fun afterTextChanged(editable: Editable) {
133                 // Get the current file name.
134                 val fileNameString = fileNameEditText.text.toString()
135
136                 // Convert the file name string to a file.
137                 val file = File(fileNameString)
138
139                 // Check to see if the file exists.
140                 if (file.exists()) {  // The file exists.
141                     // Hide the notification that the file does not exist.
142                     fileDoesNotExistTextView.visibility = View.GONE
143
144                     // Enable the open button.
145                     openButton.isEnabled = true
146                 } else {  // The file does not exist.
147                     // Show the notification that the file does not exist.
148                     fileDoesNotExistTextView.visibility = View.VISIBLE
149
150                     // Disable the open button.
151                     openButton.isEnabled = false
152                 }
153             }
154         })
155
156         // Instantiate the download location helper.
157         val downloadLocationHelper = DownloadLocationHelper()
158
159         // Get the default file path.
160         val defaultFilePath = downloadLocationHelper.getDownloadLocation(context) + "/"
161
162         // Display the default file path.
163         fileNameEditText.setText(defaultFilePath)
164
165         // Move the cursor to the end of the default file path.
166         fileNameEditText.setSelection(defaultFilePath.length)
167
168         // Hide the storage permission text view if the permission has already been granted.
169         if (ContextCompat.checkSelfPermission(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE) == PackageManager.PERMISSION_GRANTED) {
170             storagePermissionTextView.visibility = View.GONE
171         }
172
173         // Handle clicks on the browse button.
174         browseButton.setOnClickListener {
175             // Create the file picker intent.
176             val browseIntent = Intent(Intent.ACTION_OPEN_DOCUMENT)
177
178             // Set the intent MIME type to include all files so that everything is visible.
179             browseIntent.type = "*/*"
180
181             // Start the file picker.  This must be started under `activity` to that the request code is returned correctly.
182             requireActivity().startActivityForResult(browseIntent, MainWebViewActivity.BROWSE_OPEN_REQUEST_CODE)
183         }
184
185         // Return the alert dialog.
186         return alertDialog
187     }
188 }