diff --git a/CHANGELOG.md b/CHANGELOG.md index fbc4a8614..2eaa36851 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ## [Unreleased] +## [1.7.0] - 2626-07-18 +### Added +- Added alarm groups (see [PR #473](https://github.com/FossifyOrg/Clock/pull/473) for more details) + ## [1.6.0] - 2026-01-30 ### Added - Added support for custom fonts diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml index 81bf146d1..05fc11214 100644 --- a/app/src/main/AndroidManifest.xml +++ b/app/src/main/AndroidManifest.xml @@ -33,6 +33,14 @@ android:roundIcon="@mipmap/ic_launcher" android:theme="@style/AppTheme"> + + + if (menuItem.itemId == R.id.delete_group) { + ConfirmationDialog(this, messageId = R.string.delete_group_confirmation) { + dbHelper.deleteGroup(groupRef) + EventBus.getDefault().post(AlarmEvent.Refresh) + finish() + } + true + } else { + false + } + } + + binding.groupFab.setOnClickListener { + val newAlarm = createNewAlarm(DEFAULT_ALARM_MINUTES, 0) + newAlarm.isEnabled = true + newAlarm.days = getTomorrowBit() + newAlarm.groupRef = groupRef + openEditAlarm(newAlarm) + } + } + + override fun onResume() { + super.onResume() + setupTopAppBar(binding.groupAppbar, NavigationIcon.Arrow, topBarColor = getProperBackgroundColor()) + updateTextColors(binding.groupHolder) + if (!setupGroupTitle()) { + return + } + refreshAlarms() + } + + override fun onDestroy() { + super.onDestroy() + EventBus.getDefault().unregister(this) + } + + override fun onActivityResult(requestCode: Int, resultCode: Int, resultData: Intent?) { + super.onActivityResult(requestCode, resultCode, resultData) + if (requestCode == PICK_AUDIO_FILE_INTENT_ID && resultCode == RESULT_OK && resultData != null) { + currentEditAlarmDialog?.updateSelectedAlarmSound(storeNewYourAlarmSound(resultData)) + } + } + + private fun setupGroupTitle(): Boolean { + val group = dbHelper.getGroups().firstOrNull { it.ref == groupRef } + if (group == null) { + finish() + return false + } + + binding.groupToolbarTitle.text = group.title + binding.groupToolbarTitle.setTextColor(getProperTextColor()) + binding.groupToolbarTitle.setOnClickListener { + RenameGroupDialog(this, group) { + setupGroupTitle() + } + } + return true + } + + private fun refreshAlarms() { + ensureBackgroundThread { + val alarms = dbHelper.getAlarms() + .filter { it.groupRef == groupRef } + .sortedBy { it.timeInMinutes } + + runOnUiThread { + val items = ArrayList(alarms.map { AlarmListItem.AlarmRow(it) }) + var currAdapter = binding.groupList.adapter as? AlarmsAdapter + if (currAdapter == null) { + currAdapter = AlarmsAdapter( + activity = this, + items = items, + toggleAlarmInterface = this, + recyclerView = binding.groupList + ) { + if (it is Alarm) { + openEditAlarm(it) + } + }.apply { + binding.groupList.adapter = this + } + } else { + currAdapter.apply { + updatePrimaryColor() + updateBackgroundColor(getProperBackgroundColor()) + updateTextColor(getProperTextColor()) + updateItems(items) + } + } + binding.groupPlaceholder.beVisibleIf(items.isEmpty()) + } + } + } + + private fun openEditAlarm(alarm: Alarm) { + currentEditAlarmDialog = EditAlarmDialog(this, alarm) { + alarm.id = it + currentEditAlarmDialog = null + refreshAlarms() + checkAlarmState(alarm) + } + } + + private fun checkAlarmState(alarm: Alarm) { + if (alarm.isEnabled) { + alarmController.scheduleNextOccurrence(alarm = alarm, showToasts = true) + } else { + cancelAlarmClock(alarm) + } + } + + override fun alarmToggled(id: Int, isEnabled: Boolean) { + handleFullScreenNotificationsPermission { granted -> + if (granted) { + if (dbHelper.updateAlarmEnabledState(id, isEnabled)) { + dbHelper.getAlarmWithId(id)?.let { alarm -> + alarm.isEnabled = isEnabled + checkAlarmState(alarm) + if (!alarm.isEnabled && alarm.oneShot) { + dbHelper.deleteAlarms(arrayListOf(alarm)) + } + } + refreshAlarms() + } else { + toast(org.fossify.commons.R.string.unknown_error_occurred) + } + updateWidgets() + } else { + refreshAlarms() + } + } + } + + @Subscribe(threadMode = ThreadMode.MAIN) + fun onMessageEvent(@Suppress("unused") event: AlarmEvent.Refresh) { + refreshAlarms() + } +} diff --git a/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt b/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt index 66a10e184..a573bd043 100644 --- a/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt +++ b/app/src/main/kotlin/org/fossify/clock/activities/SettingsActivity.kt @@ -307,12 +307,13 @@ class SettingsActivity : SimpleActivity() { private fun exportData(outputUri: Uri) { val alarms = dbHelper.getAlarms() + val groups = dbHelper.getGroups() val timers = timerDb.getTimers() if (alarms.isEmpty() && timers.isEmpty()) { toast(org.fossify.commons.R.string.no_entries_for_exporting) } else { ExportHelper(this).exportData( - backup = AlarmTimerBackup(alarms, timers), + backup = AlarmTimerBackup(alarms, groups, timers), outputUri = outputUri, ) { toast( diff --git a/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt b/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt index c29d72fe6..0f5b1a304 100644 --- a/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt +++ b/app/src/main/kotlin/org/fossify/clock/adapters/AlarmsAdapter.kt @@ -8,21 +8,28 @@ import android.view.ViewGroup import androidx.recyclerview.widget.ItemTouchHelper import androidx.recyclerview.widget.RecyclerView import org.fossify.clock.R +import org.fossify.clock.activities.GroupActivity import org.fossify.clock.activities.SimpleActivity import org.fossify.clock.databinding.ItemAlarmBinding +import org.fossify.clock.databinding.ItemAlarmGroupBinding +import org.fossify.clock.dialogs.AddToGroupDialog import org.fossify.clock.extensions.config import org.fossify.clock.extensions.dbHelper import org.fossify.clock.extensions.getFormattedTime +import org.fossify.clock.extensions.handleFullScreenNotificationsPermission import org.fossify.clock.helpers.updateNonRecurringAlarmDay import org.fossify.clock.interfaces.ToggleAlarmInterface import org.fossify.clock.models.Alarm import org.fossify.clock.models.AlarmEvent +import org.fossify.clock.models.AlarmListItem +import org.fossify.clock.models.Group import org.fossify.commons.adapters.MyRecyclerViewAdapter import org.fossify.commons.dialogs.ConfirmationDialog import org.fossify.commons.extensions.applyColorFilter import org.fossify.commons.extensions.beVisibleIf import org.fossify.commons.extensions.getSelectedDaysString import org.fossify.commons.extensions.move +import org.fossify.commons.extensions.moveLastItemToFront import org.fossify.commons.helpers.EVERY_DAY_BIT import org.fossify.commons.helpers.SORT_BY_CUSTOM import org.fossify.commons.interfaces.ItemMoveCallback @@ -33,12 +40,17 @@ import org.greenrobot.eventbus.EventBus class AlarmsAdapter( activity: SimpleActivity, - private var alarms: ArrayList, + private var items: ArrayList, private val toggleAlarmInterface: ToggleAlarmInterface, recyclerView: MyRecyclerView, itemClick: (Any) -> Unit, ) : MyRecyclerViewAdapter(activity, recyclerView, itemClick), ItemTouchHelperContract { + companion object { + private const val VIEW_TYPE_ALARM = 0 + private const val VIEW_TYPE_GROUP = 1 + } + private var startReorderDragListener: StartReorderDragListener init { @@ -63,17 +75,21 @@ class AlarmsAdapter( } when (id) { + R.id.cab_add_to_group -> addSelectedToGroup() R.id.cab_delete -> deleteItems() } } - override fun getSelectableItemCount() = alarms.size + override fun getSelectableItemCount() = items.count { it is AlarmListItem.AlarmRow } - override fun getIsItemSelectable(position: Int) = true + override fun getIsItemSelectable(position: Int) = items.getOrNull(position) is AlarmListItem.AlarmRow - override fun getItemSelectionKey(position: Int) = alarms.getOrNull(position)?.id + override fun getItemSelectionKey(position: Int) = + (items.getOrNull(position) as? AlarmListItem.AlarmRow)?.alarm?.id - override fun getItemKeyPosition(key: Int) = alarms.indexOfFirst { it.id == key } + override fun getItemKeyPosition(key: Int): Int { + return items.indexOfFirst { it is AlarmListItem.AlarmRow && it.alarm.id == key } + } @SuppressLint("NotifyDataSetChanged") override fun onActionModeCreated() { @@ -89,46 +105,78 @@ class AlarmsAdapter( override fun onRowSelected(myViewHolder: ViewHolder?) {} + override fun getItemViewType(position: Int): Int { + return when (items[position]) { + is AlarmListItem.GroupRow -> VIEW_TYPE_GROUP + is AlarmListItem.AlarmRow -> VIEW_TYPE_ALARM + } + } + override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): ViewHolder { - return createViewHolder(ItemAlarmBinding.inflate(layoutInflater, parent, false).root) + return if (viewType == VIEW_TYPE_GROUP) { + createViewHolder(ItemAlarmGroupBinding.inflate(layoutInflater, parent, false).root) + } else { + createViewHolder(ItemAlarmBinding.inflate(layoutInflater, parent, false).root) + } } override fun onBindViewHolder(holder: ViewHolder, position: Int) { - val alarm = alarms[position] - holder.bindView( - any = alarm, - allowSingleClick = true, - allowLongClick = true - ) { itemView, _ -> - setupView(itemView, alarm, holder) + when (val item = items[position]) { + is AlarmListItem.GroupRow -> { + holder.bindView( + any = item.group, + allowSingleClick = true, + allowLongClick = false + ) { itemView, _ -> + setupGroupView(itemView, item) + } + } + + is AlarmListItem.AlarmRow -> { + holder.bindView( + any = item.alarm, + allowSingleClick = true, + allowLongClick = true + ) { itemView, _ -> + setupView(itemView, item.alarm, holder) + } + } } bindViewHolder(holder) } - override fun getItemCount() = alarms.size + override fun getItemCount() = items.size @SuppressLint("NotifyDataSetChanged") - fun updateItems(newItems: ArrayList) { - alarms = newItems + fun updateItems(newItems: ArrayList) { + items = newItems notifyDataSetChanged() finishActMode() } - private fun deleteItems() { - val alarmsToRemove = ArrayList() - val positions = getSelectedItemPositions() - getSelectedItems().forEach { - alarmsToRemove.add(it) + private fun addSelectedToGroup() { + val selectedIds = getSelectedAlarms().map { it.id } + AddToGroupDialog(activity as SimpleActivity) { groupId -> + activity.dbHelper.assignAlarmsToGroup(selectedIds, groupId) + finishActMode() + EventBus.getDefault().post(AlarmEvent.Refresh) } + } - alarms.removeAll(alarmsToRemove) + private fun deleteItems() { + val positions = getSelectedItemPositions() + val alarmsToRemove = getSelectedAlarms() + items.removeAll { it is AlarmListItem.AlarmRow && alarmsToRemove.contains(it.alarm) } removeSelectedItems(positions) activity.dbHelper.deleteAlarms(alarmsToRemove) EventBus.getDefault().post(AlarmEvent.Refresh) } - private fun getSelectedItems(): ArrayList { - return alarms.filter { selectedKeys.contains(it.id) } as ArrayList + private fun getSelectedAlarms(): ArrayList { + return items.filterIsInstance() + .map { it.alarm } + .filter { selectedKeys.contains(it.id) } + .toCollection(ArrayList()) } @SuppressLint("ClickableViewAccessibility") @@ -166,6 +214,38 @@ class AlarmsAdapter( } } + private fun setupGroupView(view: View, groupRow: AlarmListItem.GroupRow) { + ItemAlarmGroupBinding.bind(view).apply { + val group = groupRow.group + val alarms = groupRow.alarms + + groupIcon.applyColorFilter(textColor) + groupTitle.text = group.title + groupTitle.setTextColor(textColor) + + groupSubtitle.text = resources.getQuantityString( + R.plurals.group_alarm_count, alarms.size, alarms.size + ) + groupSubtitle.setTextColor(textColor) + + val anyEnabled = alarms.isNotEmpty() && alarms.any { it.isEnabled } + groupSwitch.setColors(textColor, properPrimaryColor, backgroundColor) + groupSwitch.isChecked = anyEnabled + groupSwitch.setOnClickListener { + toggleGroup(group.ref, groupSwitch.isChecked) + } + } + } + + private fun toggleGroup(groupId: Int, isEnabled: Boolean) { + (activity as SimpleActivity).handleFullScreenNotificationsPermission { granted -> + if (granted) { + val updatedAlarms = activity.dbHelper.updateGroupEnabledState(groupId, isEnabled) + updatedAlarms.forEach { toggleAlarmInterface.alarmToggled(it.id, isEnabled) } + } + } + } + private fun toggleAlarm(binding: ItemAlarmBinding, alarm: Alarm) { when { alarm.isRecurring() -> { @@ -202,7 +282,6 @@ class AlarmsAdapter( return if (alarm.days == EVERY_DAY_BIT) { activity.getString(org.fossify.commons.R.string.every_day) } else { - // TODO: This does not respect config.firstDayOfWeek activity.getSelectedDaysString(alarm.days) } } @@ -215,17 +294,16 @@ class AlarmsAdapter( } override fun onRowMoved(fromPosition: Int, toPosition: Int) { - alarms.move(fromPosition, toPosition) + items.move(fromPosition, toPosition) notifyItemMoved(fromPosition, toPosition) - saveAlarmsCustomOrder(alarms) + saveAlarmsCustomOrder() if (activity.config.alarmSort != SORT_BY_CUSTOM) { activity.config.alarmSort = SORT_BY_CUSTOM } } - private fun saveAlarmsCustomOrder(alarms: ArrayList) { - val alarmsCustomSortingIds = alarms.map { it.id } - - activity.config.alarmsCustomSorting = alarmsCustomSortingIds.joinToString { it.toString() } + private fun saveAlarmsCustomOrder() { + val ids = items.filterIsInstance().map { it.alarm.id } + activity.config.alarmsCustomSorting = ids.joinToString { it.toString() } } } diff --git a/app/src/main/kotlin/org/fossify/clock/dialogs/AddToGroupDialog.kt b/app/src/main/kotlin/org/fossify/clock/dialogs/AddToGroupDialog.kt new file mode 100644 index 000000000..f11421031 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/dialogs/AddToGroupDialog.kt @@ -0,0 +1,63 @@ +package org.fossify.clock.dialogs + +import android.widget.Toast +import org.fossify.clock.activities.SimpleActivity +import org.fossify.clock.databinding.DialogAddToGroupBinding +import org.fossify.clock.extensions.dbHelper +import org.fossify.clock.models.Group +import org.fossify.commons.extensions.getAlertDialogBuilder +import org.fossify.commons.extensions.setupDialogStuff +import org.fossify.commons.extensions.value +import org.fossify.commons.views.MyCompatRadioButton + +class AddToGroupDialog( + val activity: SimpleActivity, + val callback: (groupId: Int) -> Unit, +) { + private val binding = DialogAddToGroupBinding.inflate(activity.layoutInflater) + private val groups = activity.dbHelper.getGroups() + private val radioIdToGroupId = HashMap() + + init { + val mutableGroups = groups.toMutableList() + + if (groups.any()){ + val noneText = activity.resources.getString(org.fossify.commons.R.string.none) + mutableGroups.add(0, Group(0, 0, noneText)) + } + + mutableGroups.forEach { group -> + val radioButton = MyCompatRadioButton(activity).apply { + id = android.view.View.generateViewId() + text = group.title + } + radioIdToGroupId[radioButton.id] = group.ref + binding.addToGroupRadioGroup.addView(radioButton) + } + + activity.getAlertDialogBuilder() + .setPositiveButton(org.fossify.commons.R.string.ok) { _, _ -> dialogConfirmed() } + .setNegativeButton(org.fossify.commons.R.string.cancel, null) + .apply { + activity.setupDialogStuff(binding.root, this, org.fossify.clock.R.string.add_to_group) + } + } + + private fun dialogConfirmed() { + val newGroupName = binding.addToGroupNewName.value.trim() + val groupNameExists = activity.dbHelper.getGroups().any { it.title == newGroupName } + + val groupId = if (newGroupName.isNotEmpty() && !groupNameExists) { + activity.dbHelper.insertGroup(newGroupName) + } else if (groupNameExists) { + val text = activity.resources.getString(org.fossify.clock.R.string.group_name_exists) + Toast.makeText(activity.baseContext, text, Toast.LENGTH_SHORT).show() + return + } else { + val checkedRadioId = binding.addToGroupRadioGroup.checkedRadioButtonId + radioIdToGroupId[checkedRadioId] ?: return + } + + callback(groupId) + } +} diff --git a/app/src/main/kotlin/org/fossify/clock/dialogs/EditAlarmDialog.kt b/app/src/main/kotlin/org/fossify/clock/dialogs/EditAlarmDialog.kt index 06a992637..b9d63fc30 100644 --- a/app/src/main/kotlin/org/fossify/clock/dialogs/EditAlarmDialog.kt +++ b/app/src/main/kotlin/org/fossify/clock/dialogs/EditAlarmDialog.kt @@ -122,7 +122,6 @@ class EditAlarmDialog( val dayLetters = activity.resources.getStringArray(org.fossify.commons.R.array.week_day_letters) - .toList() as ArrayList val dayIndexes = activity.rotateWeekdays(arrayListOf(0, 1, 2, 3, 4, 5, 6)) dayIndexes.forEach { diff --git a/app/src/main/kotlin/org/fossify/clock/dialogs/RenameGroupDialog.kt b/app/src/main/kotlin/org/fossify/clock/dialogs/RenameGroupDialog.kt new file mode 100644 index 000000000..8c236dbf3 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/dialogs/RenameGroupDialog.kt @@ -0,0 +1,45 @@ +package org.fossify.clock.dialogs + +import androidx.appcompat.app.AlertDialog +import org.fossify.clock.R +import org.fossify.clock.activities.SimpleActivity +import org.fossify.clock.databinding.DialogRenameGroupBinding +import org.fossify.clock.extensions.dbHelper +import org.fossify.clock.models.Group +import org.fossify.commons.extensions.getAlertDialogBuilder +import org.fossify.commons.extensions.setupDialogStuff +import org.fossify.commons.extensions.showKeyboard +import org.fossify.commons.extensions.toast +import org.fossify.commons.extensions.value + +class RenameGroupDialog( + val activity: SimpleActivity, + val group: Group, + val callback: () -> Unit, +) { + private val binding = DialogRenameGroupBinding.inflate(activity.layoutInflater).apply { + renameGroupTitle.setText(group.title) + } + + init { + activity.getAlertDialogBuilder() + .setPositiveButton(org.fossify.commons.R.string.ok, null) + .setNegativeButton(org.fossify.commons.R.string.cancel, null) + .apply { + activity.setupDialogStuff(binding.root, this, R.string.rename_group) { alertDialog -> + alertDialog.showKeyboard(binding.renameGroupTitle) + alertDialog.getButton(AlertDialog.BUTTON_POSITIVE).setOnClickListener { + val newTitle = binding.renameGroupTitle.value.trim() + if (newTitle.isEmpty()) { + activity.toast(org.fossify.commons.R.string.empty_name) + return@setOnClickListener + } + + activity.dbHelper.updateGroup(Group(group.id, group.ref, newTitle)) + callback() + alertDialog.dismiss() + } + } + } + } +} diff --git a/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt b/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt index 7eb52fc9e..d9c29fc6b 100644 --- a/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt +++ b/app/src/main/kotlin/org/fossify/clock/fragments/AlarmFragment.kt @@ -5,6 +5,7 @@ import android.view.LayoutInflater import android.view.View import android.view.ViewGroup import androidx.fragment.app.Fragment +import org.fossify.clock.activities.GroupActivity import org.fossify.clock.activities.MainActivity import org.fossify.clock.activities.SimpleActivity import org.fossify.clock.adapters.AlarmsAdapter @@ -26,6 +27,8 @@ import org.fossify.clock.helpers.getTomorrowBit import org.fossify.clock.interfaces.ToggleAlarmInterface import org.fossify.clock.models.Alarm import org.fossify.clock.models.AlarmEvent +import org.fossify.clock.models.AlarmListItem +import org.fossify.clock.models.Group import org.fossify.commons.extensions.beVisibleIf import org.fossify.commons.extensions.getProperBackgroundColor import org.fossify.commons.extensions.getProperTextColor @@ -40,7 +43,7 @@ import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.ThreadMode class AlarmFragment : Fragment(), ToggleAlarmInterface { - private var alarms = ArrayList() + private var alarmItems = ArrayList() private var currentEditAlarmDialog: EditAlarmDialog? = null private lateinit var binding: FragmentAlarmBinding @@ -89,21 +92,23 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { setupAlarms() } - private fun getSortedAlarms(callback: (alarms: ArrayList) -> Unit) { + private fun getSortedItems(callback: (items: ArrayList) -> Unit) { val safeContext = context ?: return ensureBackgroundThread { - var newAlarms = context?.dbHelper?.getAlarms() - if (newAlarms == null) { - activity?.runOnUiThread { - callback(arrayListOf()) - } + val allAlarms = context?.dbHelper?.getAlarms() + if (allAlarms == null) { + activity?.runOnUiThread { callback(arrayListOf()) } return@ensureBackgroundThread } + val groups = safeContext.dbHelper.getGroups() + val groupedAlarms = allAlarms.filter { it.groupRef != 0 }.groupBy { it.groupRef } + var ungroupedAlarms = allAlarms.filter { it.groupRef == 0 } as ArrayList + when (safeContext.config.alarmSort) { - SORT_BY_ALARM_TIME -> newAlarms.sortBy { it.timeInMinutes } - SORT_BY_DATE_CREATED -> newAlarms.sortBy { it.id } - SORT_BY_DATE_AND_TIME -> newAlarms.sortWith(compareBy { + SORT_BY_ALARM_TIME -> ungroupedAlarms.sortBy { it.timeInMinutes } + SORT_BY_DATE_CREATED -> ungroupedAlarms.sortBy { it.id } + SORT_BY_DATE_AND_TIME -> ungroupedAlarms.sortWith(compareBy { safeContext.firstDayOrder(it.days) }.thenBy { it.timeInMinutes @@ -111,12 +116,12 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { SORT_BY_CUSTOM -> { val customAlarmsSortOrderString = activity?.config?.alarmsCustomSorting - if (customAlarmsSortOrderString == "") { - newAlarms.sortBy { it.id } + if (customAlarmsSortOrderString.isNullOrEmpty()) { + ungroupedAlarms.sortBy { it.id } } else { val customAlarmsSortOrder: List = - customAlarmsSortOrderString?.split(", ")?.map { it.toInt() }!! - val alarmsIdValueMap = newAlarms.associateBy { it.id } + customAlarmsSortOrderString.split(", ").map { it.toInt() } + val alarmsIdValueMap = ungroupedAlarms.associateBy { it.id } val sortedAlarms: ArrayList = ArrayList() customAlarmsSortOrder.map { id -> @@ -125,31 +130,47 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { } } - newAlarms = - (sortedAlarms + newAlarms.filter { it !in sortedAlarms }) as ArrayList + ungroupedAlarms = + (sortedAlarms + ungroupedAlarms.filter { it !in sortedAlarms }) as ArrayList } } } + val groupItems = groups + .sortedBy { it.title.lowercase() } + .map { group -> + AlarmListItem.GroupRow( + group = group, + alarms = groupedAlarms[group.ref].orEmpty().sortedBy { it.timeInMinutes } + ) + } + + val combined = ArrayList() + combined.addAll(groupItems) + combined.addAll(ungroupedAlarms.map { AlarmListItem.AlarmRow(it) }) + activity?.runOnUiThread { - callback(newAlarms) + callback(combined) } } } private fun setupAlarms() { - getSortedAlarms { sortedAlarms -> - alarms = sortedAlarms - val safeActivity = activity as? SimpleActivity ?: return@getSortedAlarms + getSortedItems { items -> + alarmItems = items + val safeActivity = activity as? SimpleActivity ?: return@getSortedItems var currAdapter = binding.alarmsList.adapter as? AlarmsAdapter if (currAdapter == null) { currAdapter = AlarmsAdapter( activity = safeActivity, - alarms = alarms, + items = items, toggleAlarmInterface = this, recyclerView = binding.alarmsList ) { - openEditAlarm(it as Alarm) + when (it) { + is Alarm -> openEditAlarm(it) + is Group -> GroupActivity.start(safeActivity, it.ref) + } }.apply { binding.alarmsList.adapter = this } @@ -158,10 +179,10 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { updatePrimaryColor() updateBackgroundColor(safeActivity.getProperBackgroundColor()) updateTextColor(safeActivity.getProperTextColor()) - updateItems(alarms) + updateItems(items) } } - binding.alarmsPlaceholder.beVisibleIf(alarms.isEmpty()) + binding.alarmsPlaceholder.beVisibleIf(items.isEmpty()) } } @@ -178,8 +199,7 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { (activity as SimpleActivity).handleFullScreenNotificationsPermission { granted -> if (granted) { if (requireContext().dbHelper.updateAlarmEnabledState(id, isEnabled)) { - val alarm = alarms.firstOrNull { it.id == id } - ?: return@handleFullScreenNotificationsPermission + val alarm = findAlarmById(id) ?: return@handleFullScreenNotificationsPermission alarm.isEnabled = isEnabled checkAlarmState(alarm) if (!alarm.isEnabled && alarm.oneShot) { @@ -196,6 +216,16 @@ class AlarmFragment : Fragment(), ToggleAlarmInterface { } } + private fun findAlarmById(id: Int): Alarm? { + alarmItems.forEach { item -> + when (item) { + is AlarmListItem.AlarmRow -> if (item.alarm.id == id) return item.alarm + is AlarmListItem.GroupRow -> item.alarms.firstOrNull { it.id == id }?.let { return it } + } + } + return null + } + private fun checkAlarmState(alarm: Alarm) { val activity = activity as? MainActivity ?: return if (alarm.isEnabled) { diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/DBHelper.kt b/app/src/main/kotlin/org/fossify/clock/helpers/DBHelper.kt index b40975992..bab3cd681 100644 --- a/app/src/main/kotlin/org/fossify/clock/helpers/DBHelper.kt +++ b/app/src/main/kotlin/org/fossify/clock/helpers/DBHelper.kt @@ -10,6 +10,7 @@ import android.text.TextUtils import org.fossify.clock.extensions.cancelAlarmClock import org.fossify.clock.extensions.createNewAlarm import org.fossify.clock.models.Alarm +import org.fossify.clock.models.Group import org.fossify.commons.extensions.getIntValue import org.fossify.commons.extensions.getStringValue import org.fossify.commons.helpers.FRIDAY_BIT @@ -34,11 +35,16 @@ class DBHelper private constructor( private val COL_SOUND_URI = "sound_uri" private val COL_LABEL = "label" private val COL_ONE_SHOT = "one_shot" + private val GROUPS_TABLE_NAME = "alarm_groups" + private val COL_GROUP_ID = "group_id" + private val COL_GROUP_REF = "group_ref" + private val COL_GROUP_TITLE = "title" + private val mDb = writableDatabase companion object { - private const val DB_VERSION = 2 + private const val DB_VERSION = 3 const val DB_NAME = "alarms.db" @SuppressLint("StaticFieldLeak") @@ -55,16 +61,30 @@ class DBHelper private constructor( override fun onCreate(db: SQLiteDatabase) { db.execSQL( - "CREATE TABLE IF NOT EXISTS $ALARMS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_TIME_IN_MINUTES INTEGER, $COL_DAYS INTEGER, " + - "$COL_IS_ENABLED INTEGER, $COL_VIBRATE INTEGER, $COL_SOUND_TITLE TEXT, $COL_SOUND_URI TEXT, $COL_LABEL TEXT, $COL_ONE_SHOT INTEGER)" + "CREATE TABLE IF NOT EXISTS $ALARMS_TABLE_NAME (" + + "$COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, $COL_TIME_IN_MINUTES INTEGER, $COL_DAYS INTEGER, " + + "$COL_IS_ENABLED INTEGER, $COL_VIBRATE INTEGER, $COL_SOUND_TITLE TEXT, $COL_SOUND_URI TEXT, " + + "$COL_LABEL TEXT, $COL_ONE_SHOT INTEGER, $COL_GROUP_ID INTEGER)" ) + createGroupsTable(db) insertInitialAlarms(db) } + private fun createGroupsTable(db: SQLiteDatabase) { + db.execSQL( + "CREATE TABLE IF NOT EXISTS $GROUPS_TABLE_NAME ($COL_ID INTEGER PRIMARY KEY AUTOINCREMENT, " + + "$COL_GROUP_REF INTEGER, $COL_GROUP_TITLE TEXT)" + ) + } + override fun onUpgrade(db: SQLiteDatabase, oldVersion: Int, newVersion: Int) { if (oldVersion == 1 && newVersion > oldVersion) { db.execSQL("ALTER TABLE $ALARMS_TABLE_NAME ADD COLUMN $COL_ONE_SHOT INTEGER NOT NULL DEFAULT 0") } + if (oldVersion < 3) { + db.execSQL("ALTER TABLE $GROUPS_TABLE_NAME ADD COLUMN $COL_GROUP_REF INTEGER DEFAULT 0") + createGroupsTable(db) + } } private fun insertInitialAlarms(db: SQLiteDatabase) { @@ -107,6 +127,71 @@ class DBHelper private constructor( mDb.delete(ALARMS_TABLE_NAME, selection, null) } + fun insertGroup(title: String, ref: Int = 0): Int { + val values = ContentValues().apply { + put(COL_GROUP_TITLE, title) + } + val res = mDb.insert(GROUPS_TABLE_NAME, null, values).toInt() + if (res == -1) { + return -1 + } + + val finalRef = if (ref == 0) res else ref + if (ref == 0) { + updateGroup(Group(res, res, title)) + } else { + updateGroup(Group(res, ref, title)) + } + + return finalRef + } + + fun updateGroup(group: Group) { + val values = ContentValues().apply { + put(COL_GROUP_TITLE, group.title) + put(COL_GROUP_REF, group.ref) } + mDb.update(GROUPS_TABLE_NAME, values, "$COL_ID = ?", arrayOf(group.id.toString())) + } + + fun deleteGroup(groupRef: Int) { + val values = ContentValues().apply { putNull(COL_GROUP_ID) } + mDb.update(ALARMS_TABLE_NAME, values, "$COL_GROUP_ID = ?", arrayOf(groupRef.toString())) + mDb.delete(GROUPS_TABLE_NAME, "$COL_GROUP_REF = ?", arrayOf(groupRef.toString())) + } + fun getGroups(): ArrayList { + val groups = ArrayList() + val cursor = mDb.query(GROUPS_TABLE_NAME, arrayOf(COL_ID, COL_GROUP_REF, COL_GROUP_TITLE), + null, null, null, null, null) + cursor.use { + if (it.moveToFirst()){ + do { + groups.add(Group(id = it.getIntValue(COL_ID), ref = it.getIntValue(COL_GROUP_REF), + title = it.getStringValue(COL_GROUP_TITLE))) + } while (it.moveToNext()) + } + } + + return groups + } + + fun assignAlarmsToGroup(alarmIds: List, groupRef: Int) { + val values = ContentValues().apply { + if (groupRef == 0) { + putNull(COL_GROUP_ID) + } else { + put(COL_GROUP_ID, groupRef) + } + } + val args = TextUtils.join(", ", alarmIds) + mDb.update(ALARMS_TABLE_NAME, values, "$COL_ID IN ($args)", null) + } + + fun updateGroupEnabledState(groupRef: Int, isEnabled: Boolean): List { + val values = ContentValues().apply { put(COL_IS_ENABLED, isEnabled) } + mDb.update(ALARMS_TABLE_NAME, values, "$COL_GROUP_ID = ?", arrayOf(groupRef.toString())) + return getAlarms().filter { it.groupRef == groupRef } + } + fun getAlarmWithId(id: Int) = getAlarms().firstOrNull { it.id == id } fun getAlarmsWithUri(uri: String) = getAlarms().filter { it.soundUri == uri } @@ -121,6 +206,7 @@ class DBHelper private constructor( put(COL_SOUND_URI, alarm.soundUri) put(COL_LABEL, alarm.label) put(COL_ONE_SHOT, alarm.oneShot) + put(COL_GROUP_ID, alarm.groupRef) } } @@ -137,7 +223,8 @@ class DBHelper private constructor( COL_SOUND_TITLE, COL_SOUND_URI, COL_LABEL, - COL_ONE_SHOT + COL_ONE_SHOT, + COL_GROUP_ID ) var cursor: Cursor? = null try { @@ -154,6 +241,7 @@ class DBHelper private constructor( val soundUri = cursor.getStringValue(COL_SOUND_URI) val label = cursor.getStringValue(COL_LABEL) val oneShot = cursor.getIntValue(COL_ONE_SHOT) == 1 + val groupId = cursor.getIntValue(COL_GROUP_ID) val alarm = Alarm( id = id, @@ -164,7 +252,8 @@ class DBHelper private constructor( soundTitle = soundTitle, soundUri = soundUri, label = label, - oneShot = oneShot + oneShot = oneShot, + groupRef = groupId ) alarms.add(alarm) } catch (e: Exception) { diff --git a/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt b/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt index bcb524d76..e8bd2919f 100644 --- a/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt +++ b/app/src/main/kotlin/org/fossify/clock/helpers/ImportHelper.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.ExperimentalSerializationApi import kotlinx.serialization.json.Json import kotlinx.serialization.json.decodeFromStream import org.fossify.clock.models.Alarm +import org.fossify.clock.models.Group import org.fossify.clock.models.AlarmTimerBackup import org.fossify.clock.models.Timer import org.fossify.commons.extensions.showErrorToast @@ -27,11 +28,13 @@ class ImportHelper( return try { context.contentResolver.openInputStream(uri)?.use { inputStream -> val backup = Json.decodeFromStream(inputStream) - val importedAlarms = insertAlarms(backup.alarms) + val importedGroups = insertGroups(backup.groups) + val updatedAlarms = updateAlarmGroupIds(backup.alarms, backup.groups) + val importedAlarms = insertAlarms(updatedAlarms) val importedTimers = insertTimers(backup.timers) when { - importedAlarms > 0 || importedTimers > 0 -> ImportResult.IMPORT_OK - importedAlarms == 0 && importedTimers == 0 -> ImportResult.IMPORT_INCOMPLETE + importedGroups > 0 || importedAlarms > 0 || importedTimers > 0 -> ImportResult.IMPORT_OK + importedGroups == 0 && importedAlarms == 0 && importedTimers == 0 -> ImportResult.IMPORT_INCOMPLETE else -> ImportResult.IMPORT_FAIL } } ?: ImportResult.IMPORT_FAIL @@ -45,7 +48,9 @@ class ImportHelper( val existingAlarms = dbHelper.getAlarms() var insertedCount = 0 alarms.forEach { alarm -> - if (!isAlarmAlreadyInserted(alarm, existingAlarms)) { + if (isAlarmAlreadyInserted(alarm, existingAlarms)) { + dbHelper.updateAlarm(alarm) + } else { if (dbHelper.insertAlarm(alarm) != -1) { insertedCount++ } @@ -54,6 +59,37 @@ class ImportHelper( return insertedCount } + private fun updateAlarmGroupIds(alarms: List, backupGroups: List): List { + val localGroups = dbHelper.getGroups() + alarms.forEach { alarm -> + if (alarm.groupRef != 0) { + val backupGroup = backupGroups.find { it.ref == alarm.groupRef } + if (backupGroup != null) { + val localGroup = localGroups.find { it.title == backupGroup.title } + if (localGroup != null) { + alarm.groupRef = localGroup.ref + } + } + } + } + + return alarms + } + + private fun insertGroups(groups: List): Int { + val existingGroups = dbHelper.getGroups() + var insertedCount = 0 + groups.forEach { group -> + if (!isGroupInserted(group, existingGroups)){ + val newId = dbHelper.insertGroup(group.title, group.ref) + if (newId != -1){ + insertedCount++ + } + } + } + return insertedCount + } + private fun insertTimers(timers: List): Int { var insertedCount = 0 timers.forEach { timer -> @@ -85,6 +121,16 @@ class ImportHelper( alarm.label == existingAlarm.label && alarm.oneShot == existingAlarm.oneShot ) { + alarm.id = existingAlarm.id + return true + } + } + return false + } + + private fun isGroupInserted(group: Group, existingGroups: List): Boolean{ + for (existingGroup in existingGroups) { + if (group.title == existingGroup.title) { return true } } diff --git a/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt b/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt index 263ca1fac..b2d658a25 100644 --- a/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt +++ b/app/src/main/kotlin/org/fossify/clock/models/Alarm.kt @@ -16,6 +16,7 @@ data class Alarm( var soundUri: String, var label: String, var oneShot: Boolean = false, + var groupRef: Int = 0, ) { fun isRecurring() = days > 0 diff --git a/app/src/main/kotlin/org/fossify/clock/models/AlarmListItem.kt b/app/src/main/kotlin/org/fossify/clock/models/AlarmListItem.kt new file mode 100644 index 000000000..7b64ce223 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/models/AlarmListItem.kt @@ -0,0 +1,6 @@ +package org.fossify.clock.models + +sealed class AlarmListItem { + data class AlarmRow(val alarm: Alarm) : AlarmListItem() + data class GroupRow(val group: Group, val alarms: List) : AlarmListItem() +} diff --git a/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt b/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt index c7deac165..0a0486f28 100644 --- a/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt +++ b/app/src/main/kotlin/org/fossify/clock/models/AlarmTimerBackup.kt @@ -6,5 +6,6 @@ import androidx.annotation.Keep @kotlinx.serialization.Serializable data class AlarmTimerBackup( val alarms: List, + val groups: List, val timers: List, ) diff --git a/app/src/main/kotlin/org/fossify/clock/models/Group.kt b/app/src/main/kotlin/org/fossify/clock/models/Group.kt new file mode 100644 index 000000000..f68e40385 --- /dev/null +++ b/app/src/main/kotlin/org/fossify/clock/models/Group.kt @@ -0,0 +1,13 @@ +package org.fossify.clock.models + +import androidx.annotation.Keep +import kotlinx.serialization.KSerializer + +@Keep +@kotlinx.serialization.Serializable +data class Group ( + var id: Int, + var ref: Int, + var title: String, +) { +} diff --git a/app/src/main/res/layout/activity_group.xml b/app/src/main/res/layout/activity_group.xml new file mode 100644 index 000000000..851b44a57 --- /dev/null +++ b/app/src/main/res/layout/activity_group.xml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_add_to_group.xml b/app/src/main/res/layout/dialog_add_to_group.xml new file mode 100644 index 000000000..6a39a9966 --- /dev/null +++ b/app/src/main/res/layout/dialog_add_to_group.xml @@ -0,0 +1,25 @@ + + + + + + + + + + diff --git a/app/src/main/res/layout/dialog_rename_group.xml b/app/src/main/res/layout/dialog_rename_group.xml new file mode 100644 index 000000000..5c6a899d3 --- /dev/null +++ b/app/src/main/res/layout/dialog_rename_group.xml @@ -0,0 +1,25 @@ + + + + + + + + + diff --git a/app/src/main/res/layout/item_alarm_group.xml b/app/src/main/res/layout/item_alarm_group.xml new file mode 100644 index 000000000..a23358549 --- /dev/null +++ b/app/src/main/res/layout/item_alarm_group.xml @@ -0,0 +1,65 @@ + + + + + + + + + + + + diff --git a/app/src/main/res/menu/cab_alarms.xml b/app/src/main/res/menu/cab_alarms.xml index 9e2f21475..0e1597640 100644 --- a/app/src/main/res/menu/cab_alarms.xml +++ b/app/src/main/res/menu/cab_alarms.xml @@ -1,6 +1,11 @@ + + + + diff --git a/app/src/main/res/values-ar/strings.xml b/app/src/main/res/values-ar/strings.xml index ad6258aa5..2d835cadc 100644 --- a/app/src/main/res/values-ar/strings.xml +++ b/app/src/main/res/values-ar/strings.xml @@ -57,4 +57,15 @@ تنبيه فائت تم استبداله بمنبه آخر مدة المؤقِّت + أضف إلى المجموعة + مجموعة جديدة + اسم المجموعة + حذف المجموعة + إعادة تسمية المجموعة + هل تريد حذف هذه المجموعة؟ سيتم إعادة تنبيهاتها إلى القائمة الرئيسية. + + منبه %d + %d منبهاتs + + هناك مجموعة تحمل هذا الاسم بالفعل diff --git a/app/src/main/res/values-az/strings.xml b/app/src/main/res/values-az/strings.xml index decd87f9a..d097399e6 100644 --- a/app/src/main/res/values-az/strings.xml +++ b/app/src/main/res/values-az/strings.xml @@ -19,4 +19,15 @@ Sayğaç bölməsi Saniyələri göstər Səsi aramla yüksəlt + Qrupa əlavə et + Yeni qrup + Qrup adı + Qrupu sil + Qrupun adını dəyişdir + Bu qrupu silin? Onun siqnalları əsas siyahıya qaytarılacaq. + + %d alarm + %d alarms + + Bu adla artıq bir qrup mövcuddur diff --git a/app/src/main/res/values-be/strings.xml b/app/src/main/res/values-be/strings.xml index ea5d663d9..fd1a6dc3d 100644 --- a/app/src/main/res/values-be/strings.xml +++ b/app/src/main/res/values-be/strings.xml @@ -55,4 +55,15 @@ Час дзеяння будзільніка сышоў Імпартаваць будзільнікі і таймеры Экспартаваць будзільнікі і таймеры + Дадаць у групу + Новая група + Назва групы + Выдаліць групу + Перайменаваць групу + Выдаліць гэту групу? Яе абвесткі будуць вернуты ў асноўны спіс. + + %d ы трывожны сігнал + %d трывог + + Ужо існуе група з такой назвай. diff --git a/app/src/main/res/values-bg/strings.xml b/app/src/main/res/values-bg/strings.xml index 2557dc8e3..2a4dcc8c3 100644 --- a/app/src/main/res/values-bg/strings.xml +++ b/app/src/main/res/values-bg/strings.xml @@ -53,4 +53,15 @@ Времето за звънене на будилника е изтекло Пропуснат будилник Заменен от друг будилник + Добави към групата + Нова група + Име на групата + Изтриване на група + Преименуване на група + Да изтриете тази група ли? Нейните аларми ще бъдат преместени обратно в основния списък. + + %d аларма + %d аларми + + Вече съществува група с това име diff --git a/app/src/main/res/values-br/strings.xml b/app/src/main/res/values-br/strings.xml index e533ae130..3e3b6fb00 100644 --- a/app/src/main/res/values-br/strings.xml +++ b/app/src/main/res/values-br/strings.xml @@ -52,4 +52,15 @@ Penaos e c\'hallan cheñch urzh rummañ an troioù en ivinell padventer? Klikit war unan eus ar bannoù evit rummañ an troioù hervez ar bann-mañ. Gant klikoù ouzhpenn e c\'hallit trec\'haoliñ etre urzh rummañ war-gresk ha war-zigresk. Padelezh ar munuter + Ouzhpennañ d\'ar strollad + Strollad nevez + Anv ar strollad + Dilemel ar strollad + Adanvañ ar strollad + Dilemel ar strollad-mañ ? Adkaset e vo e evezhiadennoù d\'al listenn bennañ. + + %d diwall + %d diwalls + + Ur strollad gant an anv-se a zo dija. diff --git a/app/src/main/res/values-ca/strings.xml b/app/src/main/res/values-ca/strings.xml index 85b049697..257091ee6 100644 --- a/app/src/main/res/values-ca/strings.xml +++ b/app/src/main/res/values-ca/strings.xml @@ -54,4 +54,15 @@ Alarma desatesa Substituïda per una altra alarma L\'alarma ha excedit el temps d\'espera + Afegeix al grup + Grup nou + Nom del grup + Suprimeix grup + Canvia el nom del grup + Eliminar aquest grup? Les seves alarmes es tornaran a traslladar a la llista principal. + + Alerta %d + %d alarmes + + Ja existeix un grup amb aquest nom. diff --git a/app/src/main/res/values-cs/strings.xml b/app/src/main/res/values-cs/strings.xml index 460207100..3f4df52f6 100644 --- a/app/src/main/res/values-cs/strings.xml +++ b/app/src/main/res/values-cs/strings.xml @@ -54,4 +54,15 @@ Zmeškaný budík Nahrazen jiným budíkem Budík vypršel + Přidat do skupiny + Nová skupina + Název skupiny + Odstranit skupinu + Přejmenovat skupinu + Chcete tuto skupinu smazat? Její upozornění budou přesunuta zpět do hlavního seznamu. + + %d budík + %d budíků + + Skupina s tímto názvem již existuje diff --git a/app/src/main/res/values-cy/strings.xml b/app/src/main/res/values-cy/strings.xml index 7fb552cae..6f046ecb2 100644 --- a/app/src/main/res/values-cy/strings.xml +++ b/app/src/main/res/values-cy/strings.xml @@ -28,4 +28,14 @@ Cynyddu uchder sain yn raddol Sut gallaf newid trefn lapiau yn y tab stopwats? Clifia ar unrhyw un o\'r colofnau. Mi fydd hynny\'n ail-drefnu\'r lapiau yn ôl y golofn honno. Gyda chliciau ychwanegol, bydd y drefn yn toglo rhwng esgynnol a disgynnol. + Grŵp newydd + Enw\'r grŵp + Dileu grŵp + Ail-enwi grŵp + Dileu\'r grŵp hwn? Bydd ei larwmau\'n cael eu symud yn ôl i\'r prif restr. + + %d alarm + %d larwm + + Mae grŵp o\'r enw hwnnw eisoes yn bodoli. diff --git a/app/src/main/res/values-da/strings.xml b/app/src/main/res/values-da/strings.xml index d3c4bf63b..53117e7fa 100644 --- a/app/src/main/res/values-da/strings.xml +++ b/app/src/main/res/values-da/strings.xml @@ -53,4 +53,15 @@ %d timer kører %d timere kører + Tilføj til gruppe + Ny gruppe + Gruppe navn + Slet gruppe + Omdøb gruppe + Skal denne gruppe slettes? Dens alarmer flyttes tilbage til hovedlisten. + + %d alarm + %d alarmer + + Der findes allerede en gruppe med det navn diff --git a/app/src/main/res/values-de/strings.xml b/app/src/main/res/values-de/strings.xml index 95a686372..2cd2bf46b 100644 --- a/app/src/main/res/values-de/strings.xml +++ b/app/src/main/res/values-de/strings.xml @@ -53,4 +53,15 @@ Verpasster Alarm Ersetzt durch einen anderen Alarm Alarm ist abgelaufen + Zur Gruppe hinzufügen + Neue Gruppe + Gruppenname + Gruppe löschen + Gruppe umbenennen + Diese Gruppe löschen? Die darin enthaltenen Alarme werden zurück in die Hauptliste verschoben. + + %d Alarm + %d Alarme + + Eine Gruppe mit diesem Namen existiert bereits diff --git a/app/src/main/res/values-el/strings.xml b/app/src/main/res/values-el/strings.xml index 6ece999dd..a6931a889 100644 --- a/app/src/main/res/values-el/strings.xml +++ b/app/src/main/res/values-el/strings.xml @@ -52,4 +52,15 @@ Εξαγωγή ξυπνητηριών και χρονομέτρων Διάρκεια χρονομέτρου Η αφύπνιση παραλήφθηκε + Προσθήκη στην ομάδα + Νέα ομάδα + Όνομα ομάδας + Διαγραφή ομάδας + Μετονομασία ομάδας + Να διαγραφεί αυτή η ομάδα; Οι ειδοποιήσεις της θα μεταφερθούν ξανά στην κύρια λίστα. + + %d ξυπνητήρι + %d ειδοποιήσεις + + Υπάρχει ήδη μια ομάδα με αυτό το όνομα diff --git a/app/src/main/res/values-en-rGB/strings.xml b/app/src/main/res/values-en-rGB/strings.xml index abfdf865c..9b39d75c4 100644 --- a/app/src/main/res/values-en-rGB/strings.xml +++ b/app/src/main/res/values-en-rGB/strings.xml @@ -53,4 +53,15 @@ Export alarms and timers How can I change lap sorting at the stopwatch tab? Just click on any of the columns, that will make the laps be sorted by the given column. With additional clicks you can toggle between ascending and descending sorting. + Add to group + New group + Group name + Delete group + Rename group + Delete this group? Its alarms will be moved back to the main list. + + %d alarm + %d alarms + + A group with that name already exists diff --git a/app/src/main/res/values-eo/strings.xml b/app/src/main/res/values-eo/strings.xml index cbccb4ccf..944b13d90 100644 --- a/app/src/main/res/values-eo/strings.xml +++ b/app/src/main/res/values-eo/strings.xml @@ -53,4 +53,15 @@ Alarmo elĉerpiĝis Ne planita Anstataŭigita de alia alarmo + Aldoni al grupo + Nova grupo + Grupnomo + Forigi grupon + Renomigi grupon + Forigi ĉi tiun grupon? Ĝiaj alarmoj estos movitaj reen al la ĉefa listo. + + %d alarmo + %d alarmoj + + Jam ekzistas grupo kun tiu nomo. diff --git a/app/src/main/res/values-es/strings.xml b/app/src/main/res/values-es/strings.xml index d7e47d090..bb3434be0 100644 --- a/app/src/main/res/values-es/strings.xml +++ b/app/src/main/res/values-es/strings.xml @@ -54,4 +54,15 @@ Sustituida por otra alarma No programado Alarma caducada + Añadir al grupo + Nuevo grupo + Nombre del grupo + Eliminar grupo + Cambiar el nombre del grupo + ¿Quieres eliminar este grupo? Sus alarmas se volverán a mover a la lista principal. + + Alarma %d + %d alarmas + + Ya existe un grupo con ese nombre diff --git a/app/src/main/res/values-et/strings.xml b/app/src/main/res/values-et/strings.xml index 7f3dec1dd..27e78dfee 100644 --- a/app/src/main/res/values-et/strings.xml +++ b/app/src/main/res/values-et/strings.xml @@ -53,4 +53,15 @@ Pole ajastatud Märkamata äratus Seda asendas teine äratus + Lisa rühma + Uus rühm + Rühma nimi + Rühma kustutamine + Rühma ümbernimetamine + Kas soovid selle grupi kustutada? Selle äratused viiakse tagasi põhinimekirja. + + %d äratus + %d äratust + + Sellise nimega rühm on juba olemas diff --git a/app/src/main/res/values-eu/strings.xml b/app/src/main/res/values-eu/strings.xml index fddf3fd84..ab3a21516 100644 --- a/app/src/main/res/values-eu/strings.xml +++ b/app/src/main/res/values-eu/strings.xml @@ -53,4 +53,15 @@ Galdutako alarma Beste alarma batek ordeztu du Alarma iraungita + Taldeari gehitu + Talde berria + Taldearen izena + Taldea ezabatu + Taldearen izena aldatu + Talde hau ezabatu? Bere alerta guztiak berriro zerrenda nagusira eramango dira. + + %d alarma + %d alarma + + Izena horrekin talde bat dagoeneko badago. diff --git a/app/src/main/res/values-fa/strings.xml b/app/src/main/res/values-fa/strings.xml index 18de5af0d..74b19cb1b 100644 --- a/app/src/main/res/values-fa/strings.xml +++ b/app/src/main/res/values-fa/strings.xml @@ -1,4 +1,15 @@ ساعت زنگی + افزودن به گروه + گروه جدید + نام گروه + حذف گروه + نام گروه را تغییر دهید + حذف این گروه؟ هشدارهای آن به فهرست اصلی بازگردانده خواهند شد. + + هشدار %d + %d هشدار + + گروهی با آن نام از قبل وجود دارد diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml index 7a9d170e2..a0ecdf1aa 100644 --- a/app/src/main/res/values-fi/strings.xml +++ b/app/src/main/res/values-fi/strings.xml @@ -53,4 +53,15 @@ Ei aikataulutettu Toinen hälytys korvannut Hukattu hälytys + Lisää ryhmään + Uusi ryhmä + Ryhmän nimi + Poista ryhmä + Nimeä ryhmä uudelleen + Haluatko poistaa tämän ryhmän? Sen hälytykset siirretään takaisin pääluetteloon. + + %d hälytys + %d hälytystä + + Tällainen ryhmä on jo olemassa diff --git a/app/src/main/res/values-fr/strings.xml b/app/src/main/res/values-fr/strings.xml index b7bf54b15..0f2b76fdc 100644 --- a/app/src/main/res/values-fr/strings.xml +++ b/app/src/main/res/values-fr/strings.xml @@ -54,4 +54,15 @@ Remplacée par une autre alarme Alarme manquée Alarme expirée + Ajouter au groupe + Nouveau groupe + Nom du groupe + Supprimer le groupe + Renommer un groupe + Supprimer ce groupe ? Ses alarmes seront replacées dans la liste principale. + + Alarme %d + %d alarmes + + Un groupe portant ce nom existe déjà diff --git a/app/src/main/res/values-ga/strings.xml b/app/src/main/res/values-ga/strings.xml index 4aeb17f7b..cbac39177 100644 --- a/app/src/main/res/values-ga/strings.xml +++ b/app/src/main/res/values-ga/strings.xml @@ -38,7 +38,7 @@ Clog analógach Clog digiteach Aláram atá le teacht - Amadóirí ag rith + Amadóirí ag rithr Tá an t- amadóir do %s ag rith Amadóir Nua Cluaisín clog @@ -56,4 +56,15 @@ Gan sceidealú Aláram caillte Cuireadh aláram eile ina áit + Cuir leis an ngrúpa + Grúpa nua + Ainm an ghrúpa + Scrios an grúpa + Athainm an ghrúpa + An grúpa seo a scriosadh? Aistrófar a chuid aláraim ar ais go dtí an príomhliosta. + + Alaram %d + %d aláraim + + Tá grúpa leis an ainm sin ann cheana féin. diff --git a/app/src/main/res/values-gl/strings.xml b/app/src/main/res/values-gl/strings.xml index eb1772ec0..a65ddc833 100644 --- a/app/src/main/res/values-gl/strings.xml +++ b/app/src/main/res/values-gl/strings.xml @@ -53,4 +53,15 @@ Alarma caduca Importar alarmas e temporizadores Exportar alarmas e temporizadores + Engadir ao grupo + Novo grupo + Nome do grupo + Eliminar grupo + Renombrar grupo + Eliminar este grupo? As súas alarmas volverán á lista principal. + + Alarma %d + %d alarmas + + Xa existe un grupo con ese nome. diff --git a/app/src/main/res/values-hi/strings.xml b/app/src/main/res/values-hi/strings.xml index 19037ded0..6a23aae35 100644 --- a/app/src/main/res/values-hi/strings.xml +++ b/app/src/main/res/values-hi/strings.xml @@ -53,4 +53,15 @@ अनुसूचित नहीं अलार्म छूट गया दूसरे अलार्म द्वारा प्रतिस्थापित + समूह में जोड़ें + नया समूह + समूह का नाम + समूह हटाएँ + समूह का नाम बदलें + इस समूह को हटाएँ? इसके अलार्म मुख्य सूची में वापस स्थानांतरित कर दिए जाएँगे। + + %d अलार्म + %d अलार्म + + उस नाम का एक समूह पहले से ही मौजूद है। diff --git a/app/src/main/res/values-hr/strings.xml b/app/src/main/res/values-hr/strings.xml index 59a76de8a..8ff2e4418 100644 --- a/app/src/main/res/values-hr/strings.xml +++ b/app/src/main/res/values-hr/strings.xml @@ -54,4 +54,15 @@ Vrijeme alarma je isteklo Uvezi alarme i timere Izvezi alarme i timere + Dodaj u grupu + Nova grupa + Naziv grupe + Izbriši grupu + Preimenuj grupu + Izbrisati ovu grupu? Njezine će se alarme vratiti na glavnu listu. + + %d alarm + %d alarma + + Grupa s tim imenom već postoji diff --git a/app/src/main/res/values-hu/strings.xml b/app/src/main/res/values-hu/strings.xml index 67f78b6cb..3bf251a85 100644 --- a/app/src/main/res/values-hu/strings.xml +++ b/app/src/main/res/values-hu/strings.xml @@ -53,4 +53,15 @@ Nincs ütemezve Kihagyott ébresztés Másik ébresztés helyettesíti + Csoporthoz hozzáadása + Új csoport + Csoport neve + Csoport törlése + Csoport átnevezése + Törölje ezt a csoportot? A hozzá tartozó riasztások visszakerülnek a fő listára. + + %d riasztás + %d riasztás + + Már létezik egy ilyen nevű csoport diff --git a/app/src/main/res/values-ia/strings.xml b/app/src/main/res/values-ia/strings.xml index 8971d392f..2b835e729 100644 --- a/app/src/main/res/values-ia/strings.xml +++ b/app/src/main/res/values-ia/strings.xml @@ -26,4 +26,4 @@ Initiar chronometro Horologio analogic Le temporisator esseva stoppate - \ No newline at end of file + diff --git a/app/src/main/res/values-in/strings.xml b/app/src/main/res/values-in/strings.xml index c5c06bc31..ff57f31bf 100644 --- a/app/src/main/res/values-in/strings.xml +++ b/app/src/main/res/values-in/strings.xml @@ -52,4 +52,15 @@ Belum dijadwalkan Alarm terlewat Digantikan oleh alarm lain + Tambahkan ke grup + Grup baru + Nama grup + Hapus grup + Endurnefna hóp + Hapus grup ini? Notifikasi dari grup ini akan dipindahkan kembali ke daftar utama. + + Alarm %d + %d alarm + + Sudah ada grup dengan nama itu diff --git a/app/src/main/res/values-is/strings.xml b/app/src/main/res/values-is/strings.xml index 9b9e4f503..9c7d5d3db 100644 --- a/app/src/main/res/values-is/strings.xml +++ b/app/src/main/res/values-is/strings.xml @@ -31,4 +31,15 @@ Hækka hljóðstyrk jafnt og þétt Hvernig get ég breytt röðun hrigja í skeiðklukkuflipanum? Smellið á hvaða dálk sem er, það mun raða hringjunum eftir þeim dálki. Með því að smella oftar er hægt að breyta milli þess að hafa minnsta eða hæsta gildi eftst. + Bæta við hóp + Ný hópur + Nafn hópsins + Eyða hópi + Csoport átnevezése + Eyða þessum hópi? Viðvaranir hans verða færðar aftur í aðallista. + + %d viðvörun + %d viðvaranir + + Hópur með það nafn er þegar til. diff --git a/app/src/main/res/values-it/strings.xml b/app/src/main/res/values-it/strings.xml index 41ae36a56..8e5fc73bf 100644 --- a/app/src/main/res/values-it/strings.xml +++ b/app/src/main/res/values-it/strings.xml @@ -54,4 +54,15 @@ Sveglia mancata Sostituita da un\'altra sveglia Sveglia scaduta + Aggiungi al gruppo + Nuovo gruppo + Nome del gruppo + Elimina gruppo + Rinomina gruppo + Elimina questo gruppo? I suoi allarmi verranno riportati nell\'elenco principale. + + %d allarme + %d allarmi + + Esiste già un gruppo con quel nome diff --git a/app/src/main/res/values-iw/strings.xml b/app/src/main/res/values-iw/strings.xml index 8bcabae9c..377bba6a6 100644 --- a/app/src/main/res/values-iw/strings.xml +++ b/app/src/main/res/values-iw/strings.xml @@ -54,4 +54,15 @@ לא מתוכנן התראה שלא נענתה הוחלף על ידי התראה אחרת + הוסף לקבוצה + קבוצה חדשה + שם הקבוצה + מחק קבוצה + שינוי שם הקבוצה + האם למחוק את הקבוצה הזו? ההתראות שלה יועברו בחזרה לרשימה הראשית. + + %d אזעקה + %d אזעקות + + כבר קיימת קבוצה בשם זה diff --git a/app/src/main/res/values-ja/strings.xml b/app/src/main/res/values-ja/strings.xml index db309b2a8..17050eb7b 100644 --- a/app/src/main/res/values-ja/strings.xml +++ b/app/src/main/res/values-ja/strings.xml @@ -52,4 +52,15 @@ タイムアウトしたアラーム アラームとタイマーをインポートする アラームとタイマーをエクスポートする + グループに追加 + 新しいグループ + グループ名 + グループを削除 + グループの名前を変更する + このグループを削除しますか?このグループのアラームはメインリストに戻されます。 + + %d アラーム + %d 件のアラーム + + その名前のグループはすでに存在します diff --git a/app/src/main/res/values-ko/strings.xml b/app/src/main/res/values-ko/strings.xml index 2add7b783..f2ca765d8 100644 --- a/app/src/main/res/values-ko/strings.xml +++ b/app/src/main/res/values-ko/strings.xml @@ -48,4 +48,15 @@ 타이머 길이 예약되지 않음 놓친 알람 + 그룹에 추가 + 새로운 그룹 + 그룹 이름 + 그룹 삭제 + 그룹 이름 변경 + 이 그룹을 삭제하시겠습니까? 이 그룹의 알림은 메인 목록으로 다시 이동됩니다. + + %d 알람 + %d 개의 알람 + + 그런 이름의 그룹이 이미 존재합니다 diff --git a/app/src/main/res/values-lt/strings.xml b/app/src/main/res/values-lt/strings.xml index 208c134ce..0fec13b5b 100644 --- a/app/src/main/res/values-lt/strings.xml +++ b/app/src/main/res/values-lt/strings.xml @@ -24,4 +24,15 @@ Rodyti sekundes Kaip aš galiu pakeisti etapų rikiavimą chronometro auselėje? Spustelėkite ant bet kurio stulpelio, tai surikiuos etapus pagal tą stulpelį. Su papildomais paspaudimais Jūs galite pasirinkti tarp rikiavimo mažėjančia arba didėjančia tvarka. + Pridėti prie grupės + Nauja grupė + Grupės pavadinimas + Ištrinti grupę + Pervardyti grupę + Ar norite ištrinti šią grupę? Jos žadintuvai bus perkelti atgal į pagrindinį sąrašą. + + %d budilka + %d budilkas + + Grupė su tokiu pavadinimu jau egzistuoja diff --git a/app/src/main/res/values-lv/strings.xml b/app/src/main/res/values-lv/strings.xml index 5e1b07ddd..11122e210 100644 --- a/app/src/main/res/values-lv/strings.xml +++ b/app/src/main/res/values-lv/strings.xml @@ -3,4 +3,15 @@ Pulkstenis Laika josla Trīcēt + Pievienot grupai + Jauna grupa + Grupas nosaukums + Dzēst grupu + Pārdēvēt grupu + Hunc gregem delere? Monitus eius ad indicem principalem redigentur. + + %d modinātājs + %d modinātāji + + Grupa ar šādu nosaukumu jau pastāv diff --git a/app/src/main/res/values-mk/strings.xml b/app/src/main/res/values-mk/strings.xml index b1ef6a5c9..ac13a562b 100644 --- a/app/src/main/res/values-mk/strings.xml +++ b/app/src/main/res/values-mk/strings.xml @@ -1,4 +1,15 @@ Часовник + Додај во група + Нова група + Име на групата + Избриши група + Преименувај група + Да се избрише оваа група? Нејзините аларми ќе бидат вратени во главната листа. + + %d аларм + %d аларми + + Веќе постои група со тоа име. diff --git a/app/src/main/res/values-ml/strings.xml b/app/src/main/res/values-ml/strings.xml index 5e3d193b5..89cad6689 100644 --- a/app/src/main/res/values-ml/strings.xml +++ b/app/src/main/res/values-ml/strings.xml @@ -41,4 +41,15 @@ വോളിയം ക്രമേണ വർദ്ധിപ്പിക്കുക സ്റ്റോപ്പ് വാച്ച് ടാബിൽ ലാപ് സോർട്ടിംഗ് എങ്ങനെ മാറ്റാം? ഏതെങ്കിലും കോളങ്ങളിൽ ക്ലിക്കുചെയ്യുക, അത് നൽകിയ കോളം ഉപയോഗിച്ച് ലാപ്പുകൾ ക്രമീകരിക്കാൻ ഇടയാക്കും. അധിക ക്ലിക്കുകൾ ഉപയോഗിച്ച് നിങ്ങൾക്ക് അസെന്റിങ് ആയും ഡിസെൻഡിങ് ആയും ടോഗിൾ ചെയ്യാൻ സഹായിക്കും. + ഗ്രൂപ്പിൽ ചേർക്കുക + പുതിയ ഗ്രൂപ്പ് + സംഘത്തിൻ്റെ പേര് + ഗ്രൂപ്പ് ഇല്ലാതാക്കുക + ഗ്രൂപ്പ് പുനർനാമകരണം ചെയ്യുക + ഈ ഗ്രൂപ്പ് ഇല്ലാതാക്കണോ? ഇതിന്റെ അലാറങ്ങൾ പ്രധാന ലിസ്റ്റിലേക്ക് തിരികെ മാറ്റും. + + %d അലാറം + %d അലാറങ്ങൾ + + അങ്ങനെയൊരു ഗ്രൂപ്പ് ഇതിനകം നിലവിലുണ്ട് diff --git a/app/src/main/res/values-my/strings.xml b/app/src/main/res/values-my/strings.xml index 8de6f424f..14590b6a1 100644 --- a/app/src/main/res/values-my/strings.xml +++ b/app/src/main/res/values-my/strings.xml @@ -45,4 +45,11 @@ မြည်သံအားတစ်ဆင့်ချင်းမြှင့်ပါ ငါဘယ်လိုစံချိန်ယူနာရီမှာပြန်​ကျော့ထားတယ့်စာရင်းအစီအစဥ်ကိုချိန်းနိုင်မလဲ? ကော်လံတစ်ခု​ပေါ်မှာနှိပ်ပါ သင်နှိပ်လိုက်သည့်​ကော်လံကိုတစ်ခါထပ်နှိပ်ခြင်းဖြင့် ကြီးစဥ်ငယ်လိုက် နဲ့ငယ်စဥ်ကြီးလိုက်စီနိုင်ပါတယ်။ + အုပ်စုထဲထည့်ပါ + အသစ်အဖွဲ့ + အဖွဲ့အမည် + အုပ်စု ဖျက်ရန် + အဖွဲ့အမည်ပြောင်းပါ + Да изтриете тази група ли? Нейните аларми ще бъдат преместени обратно в основния списък. + အဲဒီနာမည်နဲ့အဖွဲ့တစ်ဖွဲ့က ရှိပြီးသားပါ။ diff --git a/app/src/main/res/values-nb-rNO/strings.xml b/app/src/main/res/values-nb-rNO/strings.xml index e59e91662..8217c06b4 100644 --- a/app/src/main/res/values-nb-rNO/strings.xml +++ b/app/src/main/res/values-nb-rNO/strings.xml @@ -46,4 +46,15 @@ Eksporter alarmer og timere Ikke planlagt Alarmen gikk ut + Legg til i gruppe + Ny gruppe + Gruppenavn + Slett gruppe + Gi gruppen nytt navn + Skal denne gruppen slettes? Alarmene i den vil da bli flyttet tilbake til hovedlisten. + + %d alarm + %d alarmer + + Det finnes allerede en gruppe med det navnet diff --git a/app/src/main/res/values-nl/strings.xml b/app/src/main/res/values-nl/strings.xml index 14e07b339..81597204d 100644 --- a/app/src/main/res/values-nl/strings.xml +++ b/app/src/main/res/values-nl/strings.xml @@ -53,4 +53,15 @@ Wekker gemist Vervangen door andere wekker Wekker afgelopen + Aan groep toevoegen + Nieuwe groep + Groepsnaam + Groep verwijderen + Groep hernoemen + Deze groep verwijderen? De meldingen ervan worden dan teruggezet naar de hoofdlijst. + + %d alarm + %d alarmen + + Er bestaat al een groep met die naam diff --git a/app/src/main/res/values-oc/strings.xml b/app/src/main/res/values-oc/strings.xml index 31b44cd80..b36ec36c8 100644 --- a/app/src/main/res/values-oc/strings.xml +++ b/app/src/main/res/values-oc/strings.xml @@ -53,4 +53,14 @@ Exportar las alarmas e los minutadors Cossí cambi los torns dins l’onglet cronomètre ? Clicatz sus una de las colomnas, aquò farà que los torns seràn ordenats per la colomna donada. Amb de clics suplementaris podètz alternar entre l\'òrdre creissent e descreissent. + Nòu grop + Nom del grop + Suprimir lo grop + Renomenar lo grop + Suprimir aqueste grop? Sas alarmas seràn tornadas a la lista principala. + + Alarma %d + %d alarmas + + Un grop amb aquel nom ja existís. diff --git a/app/src/main/res/values-pa-rPK/strings.xml b/app/src/main/res/values-pa-rPK/strings.xml index 0601ed83e..e2f532b1c 100644 --- a/app/src/main/res/values-pa-rPK/strings.xml +++ b/app/src/main/res/values-pa-rPK/strings.xml @@ -30,4 +30,14 @@ سماں والے دی ٹیب سکنٹ ویکھو ہولی ہولی آواز ودھاؤ + ਨਵਾਂ ਸਮੂਹ + ਸਮੂਹ ਦਾ ਨਾਮ + ਸਮੂਹ ਮਿਟਾਓ + ਸਮੂਹ ਦਾ ਨਾਮ ਬਦਲੋ + ਇਸ ਗਰੁੱਪ ਨੂੰ ਮਿਟਾਓ? ਇਸ ਦੀਆਂ ਅਲਾਰਮਾਂ ਮੁੱਖ ਸੂਚੀ ਵਿੱਚ ਵਾਪਸ ਭੇਜ ਦਿੱਤੀਆਂ ਜਾਣਗੀਆਂ। + + %d ਚੇਤਾਵਨੀ + %d ਚੇਤਾਵਨੀਆਂ + + ਉਸੇ ਨਾਮ ਦਾ ਇੱਕ ਗਰੁੱਪ ਪਹਿਲਾਂ ਹੀ ਮੌਜੂਦ ਹੈ। diff --git a/app/src/main/res/values-pl/strings.xml b/app/src/main/res/values-pl/strings.xml index 884eaf7b0..3f827eb2b 100644 --- a/app/src/main/res/values-pl/strings.xml +++ b/app/src/main/res/values-pl/strings.xml @@ -55,4 +55,15 @@ Pominięty alarm Zastąpiony innym alarmem Alarm wygasł + Dodaj do grupy + Nowa grupa + Nazwa grupy + Usuń grupę + Zmień nazwę grupy + Czy chcesz usunąć tę grupę? Jej alarmy zostaną przeniesione z powrotem na listę główną. + + %d alarm + %d alarmów + + Grupa o tej nazwie już istnieje diff --git a/app/src/main/res/values-pt-rBR/strings.xml b/app/src/main/res/values-pt-rBR/strings.xml index 4462089d4..dea6b58d1 100644 --- a/app/src/main/res/values-pt-rBR/strings.xml +++ b/app/src/main/res/values-pt-rBR/strings.xml @@ -54,4 +54,15 @@ Não agendado Alarme perdido Substituído por outro alarme + Adicionar ao grupo + Novo grupo + Nome do grupo + Excluir grupo + Renomear grupo + ਇਸ ਗਰੁੱਪ ਨੂੰ ਮਿਟਾਓ? ਇਸ ਦੀਆਂ ਅਲਾਰਮਾਂ ਮੁੱਖ ਸੂਚੀ ਵਿੱਚ ਵਾਪਸ ਭੇਜ ਦਿੱਤੀਆਂ ਜਾਣਗੀਆਂ। + + Alarme %d + %d alarmes + + Já existe um grupo com esse nome diff --git a/app/src/main/res/values-pt-rPT/strings.xml b/app/src/main/res/values-pt-rPT/strings.xml index 02104103f..330a22f6d 100644 --- a/app/src/main/res/values-pt-rPT/strings.xml +++ b/app/src/main/res/values-pt-rPT/strings.xml @@ -54,4 +54,15 @@ Alarme perdido Substituído por outro alarme Alarme expirou + Adicionar ao grupo + Novo grupo + Nome do grupo + Eliminar grupo + Renomear grupo + Deseja eliminar este grupo? Os seus alarmes serão transferidos de volta para a lista principal. + + Alarme %d + %d alarmes + + Já existe um grupo com esse nome diff --git a/app/src/main/res/values-pt/strings.xml b/app/src/main/res/values-pt/strings.xml index bd7692326..710d0fd53 100644 --- a/app/src/main/res/values-pt/strings.xml +++ b/app/src/main/res/values-pt/strings.xml @@ -36,7 +36,7 @@ Novo temporizador %d temporizador em curso - %d temporizadores em curso + %d temporizadores em cursoala %d temporizadores em curso Relógio @@ -54,4 +54,15 @@ Não agendado Alarme perdido Substituído por outro alarme + Adicionar ao grupo + Novo grupo + Nome do grupo + Eliminar grupo + Renomear grupo + Deseja eliminar este grupo? Os seus alarmes serão transferidos de volta para a lista principal. + + Alarme %d + %d alarmes + + Já existe um grupo com esse nome diff --git a/app/src/main/res/values-ro/strings.xml b/app/src/main/res/values-ro/strings.xml index de793e7a1..87d9ee458 100644 --- a/app/src/main/res/values-ro/strings.xml +++ b/app/src/main/res/values-ro/strings.xml @@ -54,4 +54,15 @@ Nu este programat Alarmă ratată Înlocuită cu o altă alarmă + Adaugă la grup + Grup nou + Numele grupului + Șterge grupul + Redenumire grup + Vrei să ștergi acest grup? Alarmele sale vor fi mutate înapoi în lista principală. + + Alarmă %d + %d alarme + + Există deja un grup cu acest nume diff --git a/app/src/main/res/values-ru/strings.xml b/app/src/main/res/values-ru/strings.xml index aa2ee140c..231986b67 100644 --- a/app/src/main/res/values-ru/strings.xml +++ b/app/src/main/res/values-ru/strings.xml @@ -55,4 +55,15 @@ Пропущенный будильник Заменён другим будильником Время действия будильника истекло + Добавить в группу + Новая группа + Название группы + Удалить группу + Переименовать группу + Удалить эту группу? Ее оповещения будут перенесены обратно в основной список. + + %d будильник + %d сигналов тревоги + + Группа с таким названием уже существует diff --git a/app/src/main/res/values-sk/strings.xml b/app/src/main/res/values-sk/strings.xml index 4c69052d0..3c540fc12 100644 --- a/app/src/main/res/values-sk/strings.xml +++ b/app/src/main/res/values-sk/strings.xml @@ -54,4 +54,15 @@ Importovať budíky a časovače Exportovať budíky a časovače Dĺžky trvania časovača + Pridať do skupiny + Nová skupina + Názov skupiny + Odstrániť skupinu + Pomenovať skupinu + Chcete túto skupinu odstrániť? Jej upozornenia sa presunú späť do hlavného zoznamu. + + %d budík + %d budíkov + + Skupina s týmto názvom už existuje diff --git a/app/src/main/res/values-sl/strings.xml b/app/src/main/res/values-sl/strings.xml index 3cddd9784..d069181eb 100644 --- a/app/src/main/res/values-sl/strings.xml +++ b/app/src/main/res/values-sl/strings.xml @@ -43,4 +43,15 @@ Povečajte postopno glasnost Kako spremenim razvrščanje krogov v zavihku štoparica\? Kliknite na izbrani stolpec, da se krogi razvrstijo stolpcu. Z dodatnimi kliki preklapljate med naraščajočim in padajočim razvrščanjem. + Dodaj v skupino + Nova skupina + Ime skupine + Izbriši skupino + Preimenuj skupino + Ali želite izbrisati to skupino? Njeni alarmi bodo vrnjeni na glavni seznam. + + %d alarm + %d alarmov + + Skupina s tem imenom že obstaja diff --git a/app/src/main/res/values-sr/strings.xml b/app/src/main/res/values-sr/strings.xml index cbe9c9f25..3b1cc9f68 100644 --- a/app/src/main/res/values-sr/strings.xml +++ b/app/src/main/res/values-sr/strings.xml @@ -43,4 +43,15 @@ Како могу да променим сортирање кругова на картици штоперице\? Само кликните на било коју колону, тако да ће кругови бити сортирани према датој колони. Додатним кликовима можете се пребацивати између растућег и опадајућег сортирања. Покрени штоперицу + Додај у групу + Нова група + Назив групе + Избриши групу + Преименујте групу + Избришите ову групу? Њене аларме ће бити враћене у главну листу. + + %d аларм + %d аларма + + Већ постоји група са тим именом. diff --git a/app/src/main/res/values-sv/strings.xml b/app/src/main/res/values-sv/strings.xml index bdfb70434..47b87285e 100644 --- a/app/src/main/res/values-sv/strings.xml +++ b/app/src/main/res/values-sv/strings.xml @@ -53,4 +53,15 @@ Missat alarm Ersatt av ett annat alarm Alarm gick ut + Lägg till i gruppen + Ny grupp + Gruppnamn + Ta bort grupp + Byt namn på gruppen + ¿Quieres eliminar este grupo? Sus alarmas se volverán a mover a la lista principal. + + %d larm + %d larm + + Det finns redan en grupp med det namnet diff --git a/app/src/main/res/values-tr/strings.xml b/app/src/main/res/values-tr/strings.xml index c4c26c8c6..79ce705d8 100644 --- a/app/src/main/res/values-tr/strings.xml +++ b/app/src/main/res/values-tr/strings.xml @@ -53,4 +53,15 @@ Planlanmadı Kaçırılmış alarm Yerine başka bir alarm konuldu + Gruba ekle + Yeni grup + Grup adı + Grubu sil + Grubun adını değiştir + ¿Quieres eliminar este grupo? Sus alarmas se volverán a mover a la lista principal. + + %d alarmı + %d alarm + + Bu isimde bir grup zaten mevcut diff --git a/app/src/main/res/values-uk/strings.xml b/app/src/main/res/values-uk/strings.xml index 6a72bb4a2..f4a23320b 100644 --- a/app/src/main/res/values-uk/strings.xml +++ b/app/src/main/res/values-uk/strings.xml @@ -55,4 +55,15 @@ Не заплановано Пропущений будильник Замінено на інший будильник + Додати до групи + Нова група + Назва групи + Видалити групу + Перейменувати групу + ¿Quieres eliminar este grupo? Sus alarmas se volverán a mover a la lista principal. + + %d будильник + %d сигналів тривоги + + Група з такою назвою вже існує diff --git a/app/src/main/res/values-vi/strings.xml b/app/src/main/res/values-vi/strings.xml index 50fa60dd3..6e7b9f9d3 100644 --- a/app/src/main/res/values-vi/strings.xml +++ b/app/src/main/res/values-vi/strings.xml @@ -31,7 +31,7 @@ Thêm báo thức Không tìm thấy bộ hẹn giờ nào Thêm bộ hẹn giờ - Báo thức sắp tới + Báo thức sắp tớir Đồng hồ hẹn giờ đang chạy Bộ hẹn giờ cho %s đang chạy Hẹn giờ mới @@ -45,4 +45,15 @@ Hiển thị giây Tăng âm lượng dần dần Làm cách nào tôi có thể thay đổi cách sắp xếp vòng ở danh mục đồng hồ bấm giờ? - \ No newline at end of file + Thêm vào nhóm + Nhóm mới + Tên nhóm + Xóa nhóm + Đổi tên nhóm + Xóa nhóm này? Các cảnh báo của nhóm này sẽ được chuyển trở lại danh sách chính. + + Báo thức %d + %d báo thức + + Đã có một nhóm mang tên đó rồi + diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml index b129f5c3c..f87c437de 100644 --- a/app/src/main/res/values/strings.xml +++ b/app/src/main/res/values/strings.xml @@ -60,6 +60,17 @@ How can I change lap sorting at the stopwatch tab? Just click on any of the columns, that will make the laps be sorted by the given column. With additional clicks you can toggle between ascending and descending sorting. + Add to group + New group + Group name + Delete group + + %d alarm + %d alarms + + Rename group + Delete this group? Its alarms will be moved back to the main list. + A group with that name already exists