diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.java b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.java deleted file mode 100644 index 667cc9017c..0000000000 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.java +++ /dev/null @@ -1,157 +0,0 @@ -// SPDX-License-Identifier: GPL-2.0-or-later - -package org.dolphinemu.dolphinemu.features.input.ui; - -import android.content.Context; -import android.view.LayoutInflater; - -import androidx.annotation.NonNull; -import androidx.fragment.app.DialogFragment; - -import com.google.android.material.dialog.MaterialAlertDialogBuilder; -import com.google.android.material.textfield.TextInputEditText; - -import org.dolphinemu.dolphinemu.R; -import org.dolphinemu.dolphinemu.databinding.DialogInputStringBinding; -import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag; -import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView; -import org.dolphinemu.dolphinemu.utils.DirectoryInitialization; - -import java.io.File; -import java.text.Collator; -import java.util.Arrays; - -public final class ProfileDialogPresenter -{ - private static final String EXTENSION = ".ini"; - - private final Context mContext; - private final DialogFragment mDialog; - private final MenuTag mMenuTag; - - public ProfileDialogPresenter(MenuTag menuTag) - { - mContext = null; - mDialog = null; - mMenuTag = menuTag; - } - - public ProfileDialogPresenter(DialogFragment dialog, MenuTag menuTag) - { - mContext = dialog.getContext(); - mDialog = dialog; - mMenuTag = menuTag; - } - - public String[] getProfileNames(boolean stock) - { - File[] profiles = new File(getProfileDirectoryPath(stock)).listFiles( - file -> !file.isDirectory() && file.getName().endsWith(EXTENSION)); - - if (profiles == null) - return new String[0]; - - return Arrays.stream(profiles) - .map(file -> file.getName().substring(0, file.getName().length() - EXTENSION.length())) - .sorted(Collator.getInstance()) - .toArray(String[]::new); - } - - public void loadProfile(@NonNull String profileName, boolean stock) - { - new MaterialAlertDialogBuilder(mContext) - .setMessage(mContext.getString(R.string.input_profile_confirm_load, profileName)) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> - { - mMenuTag.getCorrespondingEmulatedController() - .loadProfile(getProfilePath(profileName, stock)); - ((SettingsActivityView) mDialog.requireActivity()).onControllerSettingsChanged(); - mDialog.dismiss(); - }) - .setNegativeButton(R.string.no, null) - .show(); - } - - public void saveProfile(@NonNull String profileName) - { - // If the user is saving over an existing profile, we should show an overwrite warning. - // If the user is creating a new profile, we normally shouldn't show a warning, - // but if they've entered the name of an existing profile, we should shown an overwrite warning. - - String profilePath = getProfilePath(profileName, false); - if (!new File(profilePath).exists()) - { - mMenuTag.getCorrespondingEmulatedController().saveProfile(profilePath); - mDialog.dismiss(); - } - else - { - new MaterialAlertDialogBuilder(mContext) - .setMessage(mContext.getString(R.string.input_profile_confirm_save, profileName)) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> - { - mMenuTag.getCorrespondingEmulatedController().saveProfile(profilePath); - mDialog.dismiss(); - }) - .setNegativeButton(R.string.no, null) - .show(); - } - } - - public void saveProfileAndPromptForName() - { - LayoutInflater inflater = LayoutInflater.from(mContext); - - DialogInputStringBinding binding = DialogInputStringBinding.inflate(inflater); - TextInputEditText input = binding.input; - - new MaterialAlertDialogBuilder(mContext) - .setView(binding.getRoot()) - .setPositiveButton(R.string.ok, (dialogInterface, i) -> - saveProfile(input.getText().toString())) - .setNegativeButton(R.string.cancel, null) - .show(); - } - - public void deleteProfile(@NonNull String profileName) - { - new MaterialAlertDialogBuilder(mContext) - .setMessage(mContext.getString(R.string.input_profile_confirm_delete, profileName)) - .setPositiveButton(R.string.yes, (dialogInterface, i) -> - { - new File(getProfilePath(profileName, false)).delete(); - mDialog.dismiss(); - }) - .setNegativeButton(R.string.no, null) - .show(); - } - - private String getProfileDirectoryName() - { - if (mMenuTag.isGCPadMenu()) - return "GCPad"; - else if (mMenuTag.isWiimoteMenu()) - return "Wiimote"; - else - throw new UnsupportedOperationException(); - } - - private String getProfileDirectoryPath(boolean stock) - { - if (stock) - { - return DirectoryInitialization.getSysDirectory() + "/Profiles/" + getProfileDirectoryName() + - '/'; - } - else - { - return DirectoryInitialization.getUserDirectory() + "/Config/Profiles/" + - getProfileDirectoryName() + '/'; - } - } - - private String getProfilePath(String profileName, boolean stock) - { - return getProfileDirectoryPath(stock) + profileName + EXTENSION; - } -} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt new file mode 100644 index 0000000000..624441aa73 --- /dev/null +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/input/ui/ProfileDialogPresenter.kt @@ -0,0 +1,119 @@ +// SPDX-License-Identifier: GPL-2.0-or-later + +package org.dolphinemu.dolphinemu.features.input.ui + +import android.content.Context +import android.content.DialogInterface +import android.view.LayoutInflater +import androidx.fragment.app.DialogFragment +import com.google.android.material.dialog.MaterialAlertDialogBuilder +import org.dolphinemu.dolphinemu.R +import org.dolphinemu.dolphinemu.databinding.DialogInputStringBinding +import org.dolphinemu.dolphinemu.features.settings.ui.MenuTag +import org.dolphinemu.dolphinemu.features.settings.ui.SettingsActivityView +import org.dolphinemu.dolphinemu.utils.DirectoryInitialization +import java.io.File +import java.util.Locale + +class ProfileDialogPresenter { + private val context: Context? + private val dialog: DialogFragment? + private val menuTag: MenuTag + + constructor(menuTag: MenuTag) { + context = null + dialog = null + this.menuTag = menuTag + } + + constructor(dialog: DialogFragment, menuTag: MenuTag) { + context = dialog.context + this.dialog = dialog + this.menuTag = menuTag + } + + fun getProfileNames(stock: Boolean): Array { + val profiles = File(getProfileDirectoryPath(stock)).listFiles { file: File -> + !file.isDirectory && file.name.endsWith(EXTENSION) + } ?: return emptyArray() + + return profiles.map { it.name.substring(0, it.name.length - EXTENSION.length) } + .sortedBy { it.lowercase(Locale.getDefault()) } + .toTypedArray() + } + + fun loadProfile(profileName: String, stock: Boolean) { + MaterialAlertDialogBuilder(context!!) + .setMessage(context.getString(R.string.input_profile_confirm_load, profileName)) + .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> + menuTag.correspondingEmulatedController + .loadProfile(getProfilePath(profileName, stock)) + (dialog!!.requireActivity() as SettingsActivityView).onControllerSettingsChanged() + dialog.dismiss() + } + .setNegativeButton(R.string.no, null) + .show() + } + + fun saveProfile(profileName: String) { + // If the user is saving over an existing profile, we should show an overwrite warning. + // If the user is creating a new profile, we normally shouldn't show a warning, + // but if they've entered the name of an existing profile, we should shown an overwrite warning. + val profilePath = getProfilePath(profileName, false) + if (!File(profilePath).exists()) { + menuTag.correspondingEmulatedController.saveProfile(profilePath) + dialog!!.dismiss() + } else { + MaterialAlertDialogBuilder(context!!) + .setMessage(context.getString(R.string.input_profile_confirm_save, profileName)) + .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> + menuTag.correspondingEmulatedController.saveProfile(profilePath) + dialog!!.dismiss() + } + .setNegativeButton(R.string.no, null) + .show() + } + } + + fun saveProfileAndPromptForName() { + val inflater = LayoutInflater.from(context) + val binding = DialogInputStringBinding.inflate(inflater) + val input = binding.input + + MaterialAlertDialogBuilder(context!!) + .setView(binding.root) + .setPositiveButton(android.R.string.ok) { _: DialogInterface?, _: Int -> + saveProfile(input.text.toString()) + } + .setNegativeButton(android.R.string.cancel, null) + .show() + } + + fun deleteProfile(profileName: String) { + MaterialAlertDialogBuilder(context!!) + .setMessage(context.getString(R.string.input_profile_confirm_delete, profileName)) + .setPositiveButton(R.string.yes) { _: DialogInterface?, _: Int -> + File(getProfilePath(profileName, false)).delete() + dialog!!.dismiss() + } + .setNegativeButton(R.string.no, null) + .show() + } + + private val profileDirectoryName: String + get() = if (menuTag.isGCPadMenu) "GCPad" else if (menuTag.isWiimoteMenu) "Wiimote" else throw UnsupportedOperationException() + + private fun getProfileDirectoryPath(stock: Boolean): String = + if (stock) { + "${DirectoryInitialization.getSysDirectory()}/Profiles/$profileDirectoryName/" + } else { + "${DirectoryInitialization.getUserDirectory()}/Config/Profiles/$profileDirectoryName/" + } + + private fun getProfilePath(profileName: String, stock: Boolean): String = + getProfileDirectoryPath(stock) + profileName + EXTENSION + + companion object { + private const val EXTENSION = ".ini" + } +} diff --git a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt index f339f7538c..0947e4f294 100644 --- a/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt +++ b/Source/Android/app/src/main/java/org/dolphinemu/dolphinemu/features/settings/ui/SettingsFragmentPresenter.kt @@ -41,7 +41,7 @@ class SettingsFragmentPresenter( private val fragmentView: SettingsFragmentView, private val context: Context ) { - private var menuTag: MenuTag? = null + private lateinit var menuTag: MenuTag private var gameId: String? = null private var settingsList: ArrayList? = null @@ -78,7 +78,7 @@ class SettingsFragmentPresenter( } } - fun onViewCreated(menuTag: MenuTag?, settings: Settings?) { + fun onViewCreated(menuTag: MenuTag, settings: Settings?) { this.menuTag = menuTag if (!TextUtils.isEmpty(gameId)) { @@ -2148,7 +2148,7 @@ class SettingsFragmentPresenter( profileString: String, controllerNumber: Int ) { - val profiles = ProfileDialogPresenter(menuTag!!).getProfileNames(false) + val profiles = ProfileDialogPresenter(menuTag).getProfileNames(false) val profileKey = profileString + "Profile" + (controllerNumber + 1) sl.add( StringSingleChoiceSetting( @@ -2227,7 +2227,7 @@ class SettingsFragmentPresenter( 0, 0, true - ) { fragmentView.showDialogFragment(ProfileDialog.create(menuTag!!)) }) + ) { fragmentView.showDialogFragment(ProfileDialog.create(menuTag)) }) updateOldControllerSettingsWarningVisibility(controller) } @@ -2313,7 +2313,7 @@ class SettingsFragmentPresenter( } fun updateOldControllerSettingsWarningVisibility() { - updateOldControllerSettingsWarningVisibility(menuTag!!.correspondingEmulatedController) + updateOldControllerSettingsWarningVisibility(menuTag.correspondingEmulatedController) } private fun updateOldControllerSettingsWarningVisibility(controller: EmulatedController) {