@@ -27,6 +27,7 @@ import kotlinx.coroutines.sync.withLock
2727import kotlinx.coroutines.withContext
2828import org.equeim.tremotesf.R
2929import org.equeim.tremotesf.TremotesfApplication
30+ import org.equeim.tremotesf.torrentfile.rpc.requests.torrentproperties.TorrentLimits
3031import org.equeim.tremotesf.ui.Settings.Property
3132import org.equeim.tremotesf.ui.torrentslistfragment.TorrentsListFragmentViewModel
3233import timber.log.Timber
@@ -106,31 +107,58 @@ object Settings {
106107 putString(colorTheme.key, newValue)
107108 }
108109 }
110+ context.getString(R .string.deprecated_prefs_remember_download_directory_key)
111+ .let { deprecatedRememberDownloadDirectoryKey ->
112+ if (preferences.contains(deprecatedRememberDownloadDirectoryKey)) {
113+ preferences.edit {
114+ putBoolean(
115+ rememberAddTorrentParameters.key,
116+ preferences.getBoolean(deprecatedRememberDownloadDirectoryKey, false )
117+ )
118+ remove(deprecatedRememberDownloadDirectoryKey)
119+ }
120+ }
121+ }
109122 migrated = true
110123 }
111124 }
112125 }
113126
127+ private class EnumPrefsMapper <T : Enum <T >>(
128+ private val enumClass : Class <T >,
129+ @StringRes private val keyResId : Int ,
130+ @StringRes private val defaultValueResId : Int ,
131+ val enumToPrefsValue : (T ) -> String ,
132+ ) {
133+ private val enumValues = requireNotNull(enumClass.enumConstants)
134+
135+ fun prefsValueToEnum (prefsValue : String ): T {
136+ enumValues.find { enumToPrefsValue(it) == prefsValue }?.let { return it }
137+ val key = context.getString(keyResId)
138+ Timber .e(" Unknown prefs value $prefsValue for key $key and enum $enumClass " )
139+ val defaultPrefsValue = context.getString(defaultValueResId)
140+ return enumValues.find { enumToPrefsValue(it) == defaultPrefsValue }
141+ ? : throw IllegalStateException (" Did not find value of enum $enumClass for default prefs value $defaultPrefsValue and key $key " )
142+ }
143+ }
144+
145+ private inline fun <reified T : Enum <T >> EnumPrefsMapper (
146+ @StringRes keyResId : Int ,
147+ @StringRes defaultValueResId : Int ,
148+ noinline enumToPrefsValue : (T ) -> String ,
149+ ): EnumPrefsMapper <T > =
150+ EnumPrefsMapper (T ::class .java, keyResId, defaultValueResId, enumToPrefsValue)
151+
114152 private interface MappedPrefsEnum {
115153 val prefsValue: String
116-
117- companion object {
118- inline fun <reified T > fromPrefsValueProvider (
119- @StringRes keyResId : Int ,
120- @StringRes defaultValueResId : Int ,
121- ): (String ) -> T where T : MappedPrefsEnum , T : Enum<T> {
122- val values = enumValues<T >()
123- return { prefsValue ->
124- values.find { it.prefsValue == prefsValue } ? : run {
125- Timber .e(" Unknown value $prefsValue for key ${context.getString(keyResId)} " )
126- val defaultPrefsValue = context.getString(defaultValueResId)
127- values.single { it.prefsValue == defaultPrefsValue }
128- }
129- }
130- }
131- }
132154 }
133155
156+ private inline fun <reified T > EnumPrefsMapper (
157+ @StringRes keyResId : Int ,
158+ @StringRes defaultValueResId : Int ,
159+ ): EnumPrefsMapper <T > where T : MappedPrefsEnum , T : Enum<T> =
160+ EnumPrefsMapper (T ::class .java, keyResId, defaultValueResId, MappedPrefsEnum ::prefsValue)
161+
134162 enum class ColorTheme (
135163 @StringRes prefsValueResId : Int ,
136164 @StyleRes val activityThemeResId : Int = 0 ,
@@ -140,20 +168,15 @@ object Settings {
140168 Teal (R .string.prefs_color_theme_value_teal, R .style.AppTheme_Teal );
141169
142170 override val prefsValue = context.getString(prefsValueResId)
143-
144- companion object {
145- val fromPrefsValue = MappedPrefsEnum .fromPrefsValueProvider<ColorTheme >(
146- R .string.prefs_color_theme_key,
147- R .string.prefs_color_theme_default_value
148- )
149- }
150171 }
151172
173+ private val colorThemeMapper =
174+ EnumPrefsMapper <ColorTheme >(R .string.prefs_color_theme_key, R .string.prefs_color_theme_default_value)
152175 val colorTheme: MutableProperty <ColorTheme > = mutableProperty<String >(
153176 R .string.prefs_color_theme_key,
154177 R .string.prefs_color_theme_default_value
155178 ).map(
156- transformGetter = ColorTheme .fromPrefsValue ,
179+ transformGetter = colorThemeMapper::prefsValueToEnum ,
157180 transformSetter = { it.prefsValue }
158181 )
159182
@@ -171,20 +194,17 @@ object Settings {
171194 Off (R .string.prefs_dark_theme_mode_value_off, AppCompatDelegate .MODE_NIGHT_NO );
172195
173196 override val prefsValue = context.getString(prefsValueResId)
174-
175- companion object {
176- val fromPrefsValue = MappedPrefsEnum .fromPrefsValueProvider<DarkThemeMode >(
177- R .string.prefs_dark_theme_mode_key,
178- R .string.prefs_dark_theme_mode_default_value
179- )
180- }
181197 }
182198
199+ private val darkThemeModeMapper = EnumPrefsMapper <DarkThemeMode >(
200+ R .string.prefs_dark_theme_mode_key,
201+ R .string.prefs_dark_theme_mode_default_value
202+ )
183203 val darkThemeMode: Property <DarkThemeMode > =
184204 property<String >(
185205 R .string.prefs_dark_theme_mode_key,
186206 R .string.prefs_dark_theme_mode_default_value
187- ).map(DarkThemeMode .fromPrefsValue )
207+ ).map(darkThemeModeMapper::prefsValueToEnum )
188208
189209 val torrentCompactView: Property <Boolean > = property(
190210 R .string.prefs_torrent_compact_view_key,
@@ -247,8 +267,47 @@ object Settings {
247267 val fillTorrentLinkFromKeyboard: Property <Boolean > =
248268 property(R .string.prefs_link_from_clipboard_key, R .bool.prefs_link_from_clipboard_default_value)
249269
250- val rememberDownloadDirectory: Property <Boolean > =
251- property(R .string.prefs_remember_download_directory_key, R .bool.prefs_remember_download_directory_default_value)
270+ val rememberAddTorrentParameters: Property <Boolean > =
271+ property(
272+ R .string.prefs_remember_add_torrent_parameters_key,
273+ R .bool.prefs_remember_add_torrent_parameters_default_value
274+ )
275+
276+ enum class StartTorrentAfterAdding (override val prefsValue : String ) : MappedPrefsEnum {
277+ Start (" start" ),
278+ DontStart (" dont_start" ),
279+ Unknown (" unknown" )
280+ }
281+
282+ private val startTorrentAfterAddingMapper = EnumPrefsMapper <StartTorrentAfterAdding >(
283+ R .string.prefs_last_add_torrent_start_after_adding_key,
284+ R .string.prefs_last_add_torrent_start_after_adding_default_value
285+ )
286+ val lastAddTorrentStartAfterAdding: MutableProperty <StartTorrentAfterAdding > = mutableProperty<String >(
287+ R .string.prefs_last_add_torrent_start_after_adding_key,
288+ R .string.prefs_last_add_torrent_start_after_adding_default_value
289+ ).map(
290+ transformGetter = startTorrentAfterAddingMapper::prefsValueToEnum,
291+ transformSetter = startTorrentAfterAddingMapper.enumToPrefsValue
292+ )
293+
294+ private val bandwidthPriorityMapper = EnumPrefsMapper <TorrentLimits .BandwidthPriority >(
295+ R .string.prefs_last_add_torrent_priority_key,
296+ R .string.prefs_last_add_torrent_priority_default_value
297+ ) {
298+ when (it) {
299+ TorrentLimits .BandwidthPriority .Low -> " low"
300+ TorrentLimits .BandwidthPriority .Normal -> " normal"
301+ TorrentLimits .BandwidthPriority .High -> " high"
302+ }
303+ }
304+ val lastAddTorrentPriority: MutableProperty <TorrentLimits .BandwidthPriority > = mutableProperty<String >(
305+ R .string.prefs_last_add_torrent_priority_key,
306+ R .string.prefs_last_add_torrent_priority_default_value
307+ ).map(
308+ transformGetter = bandwidthPriorityMapper::prefsValueToEnum,
309+ transformSetter = bandwidthPriorityMapper.enumToPrefsValue
310+ )
252311
253312 val torrentsSortMode: MutableProperty <TorrentsListFragmentViewModel .SortMode > =
254313 mutableProperty<Int >(
0 commit comments