HeliBoard/app/src/main/java/helium314/keyboard/latin/settings/SettingsFragment.java
Helium314 f0689b00f6 remove "use system locales"
now behavior is as it was disabled
if no subtypes are explicitly enabled, it behaves the same as if the setting was enabled (same as before, actually)
2025-02-25 22:41:54 +01:00

153 lines
6 KiB
Java

/*
* Copyright (C) 2008 The Android Open Source Project
* modified
* SPDX-License-Identifier: Apache-2.0 AND GPL-3.0-only
*/
package helium314.keyboard.latin.settings;
import android.app.Activity;
import android.content.Intent;
import android.net.Uri;
import android.os.Bundle;
import android.view.inputmethod.InputMethodSubtype;
import androidx.activity.result.ActivityResultLauncher;
import androidx.activity.result.contract.ActivityResultContracts;
import androidx.annotation.Nullable;
import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AlertDialog;
import androidx.appcompat.app.AppCompatActivity;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import helium314.keyboard.latin.BuildConfig;
import helium314.keyboard.latin.R;
import helium314.keyboard.latin.common.FileUtils;
import helium314.keyboard.latin.define.DebugFlags;
import helium314.keyboard.latin.utils.DictionaryUtilsKt;
import helium314.keyboard.latin.utils.ExecutorUtils;
import helium314.keyboard.latin.utils.JniUtils;
import helium314.keyboard.latin.utils.KtxKt;
import helium314.keyboard.latin.utils.SubtypeSettings;
import helium314.keyboard.latin.utils.SubtypeUtilsKt;
import java.util.List;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;
public final class SettingsFragment extends PreferenceFragmentCompat {
private final ArrayList<File> crashReportFiles = new ArrayList<>();
@Override
public void onCreate(final Bundle icicle) {
super.onCreate(icicle);
setHasOptionsMenu(true);
}
@Override
public void onCreatePreferences(@Nullable Bundle bundle, @Nullable String s) {
addPreferencesFromResource(R.xml.prefs);
if (!JniUtils.sHaveGestureLib) {
final Preference gesturePreference = findPreference(Settings.SCREEN_GESTURE);
getPreferenceScreen().removePreference(gesturePreference);
}
ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD)
.execute(() -> DictionaryUtilsKt.cleanUnusedMainDicts(requireContext()));
}
@Override
public void onResume() {
super.onResume();
final Activity activity = getActivity();
if (activity instanceof AppCompatActivity) {
final ActionBar actionBar = ((AppCompatActivity) activity).getSupportActionBar();
final CharSequence screenTitle = getPreferenceScreen().getTitle();
if (actionBar != null && screenTitle != null) {
actionBar.setTitle(screenTitle);
}
}
findPreference("screen_languages").setSummary(getEnabledSubtypesLabel());
if (BuildConfig.DEBUG || DebugFlags.DEBUG_ENABLED)
askAboutCrashReports();
}
private String getEnabledSubtypesLabel() {
final List<InputMethodSubtype> subtypes = SubtypeSettings.INSTANCE.getEnabledSubtypes(true);
final StringBuilder sb = new StringBuilder();
for (final InputMethodSubtype subtype : subtypes) {
if (sb.length() > 0)
sb.append(", ");
sb.append(SubtypeUtilsKt.displayName(subtype, requireContext()));
}
return sb.toString();
}
private void askAboutCrashReports() {
// find crash report files
final File dir = requireContext().getExternalFilesDir(null);
if (dir == null) return;
final File[] allFiles = dir.listFiles();
if (allFiles == null) return;
crashReportFiles.clear();
for (File file : allFiles) {
if (file.getName().startsWith("crash_report"))
crashReportFiles.add(file);
}
if (crashReportFiles.isEmpty()) return;
new AlertDialog.Builder(requireContext())
.setMessage("Crash report files found")
.setPositiveButton("get", (dialogInterface, i) -> {
final Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT);
intent.addCategory(Intent.CATEGORY_OPENABLE);
intent.putExtra(Intent.EXTRA_TITLE, "crash_reports.zip");
intent.setType("application/zip");
crashReportFilePicker.launch(intent);
})
.setNeutralButton("delete", (dialogInterface, i) -> {
for (File file : crashReportFiles) {
file.delete(); // don't care whether it fails, though user will complain
}
})
.setNegativeButton("ignore", null)
.show();
}
final ActivityResultLauncher<Intent> crashReportFilePicker = registerForActivityResult(new ActivityResultContracts.StartActivityForResult(), (intent) -> {
if (intent.getResultCode() != Activity.RESULT_OK || intent.getData() == null) return;
final Uri uri = intent.getData().getData();
if (uri != null)
ExecutorUtils.getBackgroundExecutor(ExecutorUtils.KEYBOARD).execute(() -> saveCrashReport(uri));
});
private void saveCrashReport(final Uri uri) {
if (uri == null || crashReportFiles.isEmpty()) return;
final OutputStream os;
try {
os = requireContext().getContentResolver().openOutputStream(uri);
if (os == null) return;
final BufferedOutputStream bos = new BufferedOutputStream(os);
final ZipOutputStream z = new ZipOutputStream(bos);
for (File file : crashReportFiles) {
FileInputStream f = new FileInputStream(file);
z.putNextEntry(new ZipEntry(file.getName()));
FileUtils.copyStreamToOtherStream(f, z);
f.close();
z.closeEntry();
}
z.close();
bos.close();
os.close();
for (File file : crashReportFiles) {
file.delete();
}
} catch (IOException ignored) { }
}
}