From a06e727f6094541b763e2dc18a300edb3e17fd26 Mon Sep 17 00:00:00 2001 From: Mike Hardy Date: Sun, 19 Feb 2023 12:15:26 -0500 Subject: [PATCH] Dependency Updates 20220219 (#13305) * Bump org.jlleitschuh.gradle:ktlint-gradle from 11.1.0 to 11.2.0 (#13265) * Bump org.jlleitschuh.gradle:ktlint-gradle from 11.1.0 to 11.2.0 Bumps org.jlleitschuh.gradle:ktlint-gradle from 11.1.0 to 11.2.0. --- updated-dependencies: - dependency-name: org.jlleitschuh.gradle:ktlint-gradle dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] * build(deps): move ktlint rules to .editorconfig With new syntax ---- An individual property can be enabled or disabled with a rule property. The name of the rule property consists of the ktlint_ prefix followed by the rule set id followed by a _ and the rule id. > https://pinterest.github.io/ktlint/faq/#why-is-editorconfig-property-disabled_rules-deprecated-and-how-do-i-resolve-this ---- disabled_rules is deprecated: https://pinterest.github.io/ktlint/faq/#why-is-editorconfig-property-disabled_rules-deprecated-and-how-do-i-resolve-this ktlint-gradle v11.2.0 resolves a few issues around this > Fixed disabled_rules set only in editorconfig in ktlint 0.46+ > Fixed disabled_rules warning when using new editorconfig syntax in ktlint 0.48+ https://github.com/JLLeitschuh/ktlint-gradle/releases/tag/v11.2.0 * lint: fix new ktlint errors Caused when we remove the version specifier in ktlint-gradle * Argument should be on a separate line (unless all arguments can fit a single line) * File annotations should be separated from file contents with a blank line * Declarations and declarations with comments should have an empty space between. * Multiple annotations should not be placed on the same line as the annotated construct Removed unused `KotlinCleanup` class rather than fixing lint errors * build(deps): depend on ktlint-gradle's ktlint Some lint indentation was reduced due to this. Fixed it manually as I didn't like the change --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com> * autoformat squash --------- Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: David Allison <62114487+david-allison@users.noreply.github.com> --- .editorconfig | 3 + .../java/com/ichi2/anki/tests/ACRATest.kt | 2 - .../ichi2/anki/tests/ContentProviderTest.kt | 31 ++- .../ichi2/anki/tests/LayoutValidationTest.kt | 1 + .../anki/tests/NotificationChannelTest.kt | 2 + .../com/ichi2/anki/tests/libanki/HttpTest.kt | 1 - .../ichi2/anki/tests/libanki/ImportTest.kt | 2 +- .../ichi2/anki/testutil/GrantPermissions.kt | 12 +- .../main/java/com/ichi2/anim/ViewAnimation.kt | 30 ++- .../com/ichi2/anki/AbstractFlashcardViewer.kt | 206 +++++++++--------- .../main/java/com/ichi2/anki/AnkiDroidApp.kt | 5 +- .../java/com/ichi2/anki/BackendBackups.kt | 2 +- .../java/com/ichi2/anki/BackendImporting.kt | 8 +- .../main/java/com/ichi2/anki/BackendUndo.kt | 1 - .../main/java/com/ichi2/anki/BackupManager.kt | 4 +- .../main/java/com/ichi2/anki/CardBrowser.kt | 71 +++--- .../src/main/java/com/ichi2/anki/CardInfo.kt | 4 +- .../CardTemplateBrowserAppearanceEditor.kt | 17 +- .../java/com/ichi2/anki/CardTemplateEditor.kt | 9 +- .../com/ichi2/anki/CardTemplatePreviewer.kt | 4 +- .../java/com/ichi2/anki/CollectionHelper.kt | 19 +- .../java/com/ichi2/anki/CollectionManager.kt | 14 +- .../java/com/ichi2/anki/CoroutineHelpers.kt | 6 +- .../java/com/ichi2/anki/CrashReportService.kt | 12 +- .../main/java/com/ichi2/anki/DatabaseCheck.kt | 2 +- .../com/ichi2/anki/DeckOptionsActivity.kt | 17 +- .../main/java/com/ichi2/anki/DeckPicker.kt | 53 +++-- .../com/ichi2/anki/DeckSpinnerSelection.kt | 7 +- .../main/java/com/ichi2/anki/FieldEditText.kt | 8 +- .../ichi2/anki/FilterSheetBottomFragment.kt | 6 +- .../src/main/java/com/ichi2/anki/Info.kt | 2 +- .../java/com/ichi2/anki/InitialActivity.kt | 1 - .../com/ichi2/anki/LeakCanaryConfiguration.kt | 2 +- .../src/main/java/com/ichi2/anki/MetaDB.kt | 24 +- .../src/main/java/com/ichi2/anki/MyAccount.kt | 13 +- .../ichi2/anki/NavigationDrawerActivity.kt | 5 +- .../main/java/com/ichi2/anki/NoteEditor.kt | 29 ++- .../main/java/com/ichi2/anki/Onboarding.kt | 2 +- .../java/com/ichi2/anki/OnboardingUtils.kt | 1 + .../src/main/java/com/ichi2/anki/Reviewer.kt | 41 ++-- .../com/ichi2/anki/SharedDecksActivity.kt | 2 +- .../ichi2/anki/SharedDecksDownloadFragment.kt | 3 +- .../main/java/com/ichi2/anki/Statistics.kt | 11 +- .../com/ichi2/anki/StudyOptionsFragment.kt | 3 +- .../src/main/java/com/ichi2/anki/Sync.kt | 11 +- .../main/java/com/ichi2/anki/Whiteboard.kt | 7 +- .../analytics/AnkiDroidCrashReportDialog.kt | 4 +- .../ichi2/anki/analytics/UsageAnalytics.kt | 13 +- .../ichi2/anki/cardviewer/CardAppearance.kt | 1 + .../com/ichi2/anki/cardviewer/CardHtml.kt | 2 +- .../com/ichi2/anki/cardviewer/CardTemplate.kt | 1 + .../java/com/ichi2/anki/cardviewer/Gesture.kt | 3 +- .../ichi2/anki/cardviewer/GestureProcessor.kt | 3 +- .../com/ichi2/anki/cardviewer/TypeAnswer.kt | 2 + .../ichi2/anki/cardviewer/ViewerCommand.kt | 12 +- .../ichi2/anki/dialogs/CreateDeckDialog.kt | 3 - .../ichi2/anki/dialogs/DatabaseErrorDialog.kt | 12 +- .../anki/dialogs/DeckPickerContextMenu.kt | 4 +- .../ichi2/anki/dialogs/DeckSelectionDialog.kt | 8 +- .../anki/dialogs/ExportCompleteDialog.kt | 2 +- .../java/com/ichi2/anki/dialogs/HelpDialog.kt | 27 ++- .../dialogs/ImportFileSelectionFragment.kt | 2 +- .../anki/dialogs/KeySelectionDialogUtils.kt | 2 +- .../ichi2/anki/dialogs/MediaCheckDialog.kt | 4 +- .../anki/dialogs/ModelBrowserContextMenu.kt | 2 +- .../ichi2/anki/dialogs/RescheduleDialog.kt | 16 +- .../dialogs/ScopedStorageMigrationDialog.kt | 3 +- .../ichi2/anki/dialogs/SimpleMessageDialog.kt | 2 + .../com/ichi2/anki/dialogs/SyncErrorDialog.kt | 16 +- .../dialogs/customstudy/CustomStudyDialog.kt | 35 ++- .../customstudy/CustomStudyDialogFactory.kt | 4 +- .../anki/dialogs/tags/TagsArrayAdapter.kt | 1 + .../com/ichi2/anki/dialogs/tags/TagsDialog.kt | 6 +- .../anki/dialogs/tags/TagsDialogFactory.kt | 4 +- .../anki/dialogs/tags/TagsDialogListener.kt | 3 +- .../com/ichi2/anki/dialogs/tags/TagsList.kt | 1 + .../anki/export/ActivityExportingDelegate.kt | 8 +- .../ichi2/anki/export/ExportDialogsFactory.kt | 4 +- .../introduction/SetupCollectionFragment.kt | 1 + .../ichi2/anki/jsaddons/TgzPackageExtract.kt | 2 - .../java/com/ichi2/anki/model/Directory.kt | 2 + .../java/com/ichi2/anki/model/DiskFile.kt | 1 + .../ichi2/anki/multimediacard/AudioView.kt | 3 +- .../ichi2/anki/multimediacard/MediaPlayer.kt | 24 +- .../activity/LoadPronunciationActivity.kt | 3 +- .../activity/MultimediaEditFieldActivity.kt | 6 +- .../activity/PickStringDialogFragment.kt | 3 +- .../fields/BasicImageFieldController.kt | 1 + .../fields/BasicMediaClipFieldController.kt | 12 +- .../anki/multimediacard/fields/ImageField.kt | 1 + .../impl/MultimediaEditableNote.kt | 4 +- .../language/LanguageListerBase.kt | 4 +- .../java/com/ichi2/anki/noteeditor/Toolbar.kt | 1 + .../ichi2/anki/notetype/ManageNotetypes.kt | 6 +- .../ichi2/anki/notetype/NotetypeAdapter.kt | 6 +- .../ichi2/anki/notetype/NotetypeUiModel.kt | 2 +- .../com/ichi2/anki/pages/PagesActivity.kt | 1 + .../CustomSyncServerSettingsFragment.kt | 2 +- .../NotificationsSettingsFragment.kt | 6 +- .../com/ichi2/anki/preferences/Preferences.kt | 3 +- .../anki/provider/CardContentProvider.kt | 14 +- .../com/ichi2/anki/reviewer/AnswerButtons.kt | 1 + .../com/ichi2/anki/reviewer/FullScreenMode.kt | 2 + .../com/ichi2/anki/reviewer/GestureMapper.kt | 12 +- .../ichi2/anki/reviewer/MappableBinding.kt | 8 +- .../ichi2/anki/reviewer/PeripheralKeymap.kt | 4 +- .../ichi2/anki/servicelayer/NoteService.kt | 4 +- .../servicelayer/PreferenceUpgradeService.kt | 2 +- .../anki/servicelayer/SchedulerService.kt | 14 +- .../anki/servicelayer/ScopedStorageService.kt | 4 +- .../ichi2/anki/servicelayer/SearchService.kt | 1 + .../scopedstorage/MoveConflictedFile.kt | 3 +- .../migrateuserdata/MigrateUserData.kt | 3 +- .../UserDataMigrationPreferences.kt | 1 + .../ichi2/anki/services/MigrationService.kt | 5 +- .../anki/services/NotificationService.kt | 4 +- .../ichi2/anki/services/ReminderService.kt | 1 - .../snackbar/SnackbarPackageWorkaround.kt | 1 + .../ichi2/anki/stats/AnkiStatsTaskHandler.kt | 9 +- .../java/com/ichi2/anki/stats/ChartBuilder.kt | 1 - .../java/com/ichi2/anki/stats/ChartView.kt | 1 + .../ichi2/anki/stats/OverviewStatsBuilder.kt | 11 +- .../com/ichi2/anki/ui/NoteTypeSpinnerUtils.kt | 2 +- .../anki/ui/dialogs/tools/AsyncDialogs.kt | 5 +- .../screens/BackupLimitsPresenter.kt | 2 +- .../anki/ui/windows/managespace/FileUtils.kt | 3 +- .../managespace/ManageSpaceFragment.kt | 3 +- .../ichi2/anki/web/PreferenceBackedHostNum.kt | 12 +- .../com/ichi2/anki/widgets/DeckAdapter.kt | 2 +- .../AppLoadedFromBackupWorkaround.kt | 1 - .../java/com/ichi2/annotations/NeedsTest.kt | 9 +- .../com/ichi2/async/CollectionOperations.kt | 14 +- .../main/java/com/ichi2/compat/CompatV21.kt | 3 +- .../com/ichi2/compat/ResolveInfoCompat.kt | 3 +- .../com/ichi2/libanki/AnkiPackageExporter.kt | 1 + .../com/ichi2/libanki/BackendImportExport.kt | 6 +- .../src/main/java/com/ichi2/libanki/Card.kt | 8 +- .../main/java/com/ichi2/libanki/Collection.kt | 73 +++++-- .../java/com/ichi2/libanki/CollectionV16.kt | 8 +- .../java/com/ichi2/libanki/ConfigManager.kt | 7 + .../src/main/java/com/ichi2/libanki/Consts.kt | 11 + .../src/main/java/com/ichi2/libanki/DB.kt | 4 +- .../java/com/ichi2/libanki/DeckManager.kt | 19 +- .../src/main/java/com/ichi2/libanki/Decks.kt | 6 +- .../main/java/com/ichi2/libanki/DecksV16.kt | 5 +- .../src/main/java/com/ichi2/libanki/Finder.kt | 26 ++- .../src/main/java/com/ichi2/libanki/Media.kt | 17 +- .../src/main/java/com/ichi2/libanki/Model.kt | 1 + .../java/com/ichi2/libanki/ModelManager.kt | 10 + .../src/main/java/com/ichi2/libanki/Models.kt | 58 +++-- .../main/java/com/ichi2/libanki/ModelsV16.kt | 4 +- .../src/main/java/com/ichi2/libanki/Note.kt | 23 +- .../main/java/com/ichi2/libanki/SortOrder.kt | 3 + .../src/main/java/com/ichi2/libanki/Sound.kt | 11 +- .../main/java/com/ichi2/libanki/StdModels.kt | 3 +- .../main/java/com/ichi2/libanki/TagManager.kt | 9 + .../src/main/java/com/ichi2/libanki/Tags.kt | 3 +- .../main/java/com/ichi2/libanki/TagsV16.kt | 6 +- .../java/com/ichi2/libanki/TemplateManager.kt | 14 +- .../main/java/com/ichi2/libanki/UndoAction.kt | 25 ++- .../src/main/java/com/ichi2/libanki/Utils.kt | 27 ++- .../backend/exception/DeckRenameException.kt | 4 +- .../ichi2/libanki/importer/Anki2Importer.kt | 5 +- .../com/ichi2/libanki/importer/Importer.kt | 2 + .../libanki/sched/AbstractDeckTreeNode.kt | 6 +- .../java/com/ichi2/libanki/sched/BaseSched.kt | 7 +- .../ichi2/libanki/sched/DeckDueTreeNode.kt | 18 +- .../java/com/ichi2/libanki/sched/LrnCard.kt | 3 +- .../java/com/ichi2/libanki/sched/Sched.kt | 108 ++++++--- .../java/com/ichi2/libanki/sched/SchedV2.kt | 194 ++++++++++++----- .../ichi2/libanki/sched/SimpleCardQueue.kt | 3 +- .../ichi2/libanki/stats/AdvancedStatistics.kt | 90 +++++--- .../java/com/ichi2/libanki/stats/Stats.kt | 20 +- .../java/com/ichi2/libanki/sync/HttpSyncer.kt | 5 +- .../com/ichi2/libanki/sync/MediaSyncer.kt | 10 +- .../com/ichi2/libanki/template/ParsedNode.kt | 10 +- .../ichi2/libanki/template/TemplateFilters.kt | 3 +- .../com/ichi2/libanki/template/Tokenizer.kt | 57 ++--- .../ichi2/preferences/ControlPreference.kt | 15 +- .../ichi2/preferences/HtmlHelpPreference.kt | 2 +- .../preferences/NumberRangePreference.kt | 1 + .../preferences/SeekBarPreferenceCompat.kt | 3 +- .../com/ichi2/preferences/StepsPreference.kt | 3 +- .../preferences/VersatileTextPreference.kt | 3 +- .../main/java/com/ichi2/themes/HtmlColors.kt | 16 +- .../main/java/com/ichi2/ui/AnimationUtil.kt | 12 +- .../ichi2/ui/AppCompatPreferenceActivity.kt | 4 +- .../ichi2/ui/AutoSizeCheckBoxPreference.kt | 15 +- .../java/com/ichi2/ui/CheckBoxTriStates.kt | 6 +- .../java/com/ichi2/ui/SeekBarPreference.kt | 3 +- .../java/com/ichi2/ui/TvNavigationElement.kt | 1 + .../main/java/com/ichi2/utils/BundleUtils.kt | 4 +- .../com/ichi2/utils/ContentResolverUtil.kt | 4 +- .../main/java/com/ichi2/utils/DiffEngine.kt | 3 +- .../java/com/ichi2/utils/ExceptionUtil.kt | 4 +- .../src/main/java/com/ichi2/utils/FileUtil.kt | 5 +- .../main/java/com/ichi2/utils/ImportUtils.kt | 2 - .../java/com/ichi2/utils/KotlinCleanup.kt | 10 +- .../main/java/com/ichi2/utils/LanguageUtil.kt | 6 +- .../com/ichi2/utils/NoteFieldDecorator.kt | 13 +- .../main/java/com/ichi2/utils/SyncStatus.kt | 1 + .../main/java/com/ichi2/utils/TypedFilter.kt | 2 +- .../java/com/ichi2/utils/WebViewDebugging.kt | 1 + .../com/ichi2/widget/AnkiDroidWidgetSmall.kt | 4 +- .../java/com/wildplot/android/parsing/Atom.kt | 35 ++- .../parsing/AtomTypes/MathFunctionAtom.kt | 29 +-- .../wildplot/android/rendering/PieChart.kt | 6 +- .../wildplot/android/rendering/PlotSheet.kt | 9 +- .../com/wildplot/android/rendering/XAxis.kt | 9 +- .../com/wildplot/android/rendering/XGrid.kt | 12 +- .../com/wildplot/android/rendering/YAxis.kt | 15 +- .../com/wildplot/android/rendering/YGrid.kt | 12 +- .../anim/ActivityTransitionAnimationTest.kt | 2 +- .../anki/ActivityStartupUnderBackupTest.kt | 1 + .../test/java/com/ichi2/anki/AnalyticsTest.kt | 1 + .../java/com/ichi2/anki/AnkiActivityTest.kt | 3 +- .../java/com/ichi2/anki/CardBrowserTest.kt | 6 +- .../java/com/ichi2/anki/CardInfoModelTest.kt | 1 + .../com/ichi2/anki/CardTemplateEditorTest.kt | 1 - .../ichi2/anki/CardTemplatePreviewerTest.kt | 2 - .../com/ichi2/anki/DeckAdapterFilterTest.kt | 2 +- .../anki/DeckPickerFloatingActionMenuTest.kt | 13 ++ .../java/com/ichi2/anki/DeckPickerTest.kt | 54 +++-- .../com/ichi2/anki/ModelFieldEditorTest.kt | 5 +- .../anki/ProductionCrashReportingTreeTest.kt | 4 +- .../test/java/com/ichi2/anki/ReviewerTest.kt | 2 +- .../java/com/ichi2/anki/RobolectricTest.kt | 1 - .../anki/RobolectricTestAnnotationTest.kt | 5 +- .../java/com/ichi2/anki/TemporaryModelTest.kt | 2 - .../WhiteboardDefaultForegroundColorTest.kt | 1 + .../anki/analytics/AnalyticsConstantsTest.kt | 9 +- .../ichi2/anki/cardviewer/TypeAnswerTest.kt | 6 + .../anki/cardviewer/ViewerCommandTest.kt | 1 - .../anki/dialogs/CreateDeckDialogTest.kt | 3 +- .../ichi2/anki/dialogs/tags/TagsDialogTest.kt | 33 ++- .../ichi2/anki/dialogs/tags/TagsListTest.kt | 79 ++++--- .../anki/jsaddons/TgzPackageExtractTest.kt | 1 - .../AudioRecorderAndroidTest.kt | 1 + .../anki/multimediacard/AudioRecorderTest.kt | 1 + .../fields/BasicImageFieldControllerTest.kt | 3 +- .../anki/preferences/PreferencesSimpleTest.kt | 2 +- .../anki/preferences/SettingsSearchBarTest.kt | 3 +- .../ichi2/anki/reviewer/AnswerTimerTest.kt | 2 +- .../ichi2/anki/reviewer/GestureMapperTest.kt | 1 + .../KeyboardShortcutIntegrationTest.kt | 1 + .../servicelayer/ScopedStorageAndroidTest.kt | 2 +- .../scopedstorage/ExecutorTest.kt | 8 +- .../MigrateEssentialFilesIntegrationTest.kt | 1 - .../scopedstorage/MockMigrationContext.kt | 1 + .../scopedstorage/OperationTest.kt | 2 + .../ScopedStorageMigrationIntegrationTest.kt | 15 +- .../UpgradeGesturesToControlsTest.kt | 2 +- .../ichi2/anki/services/NoteServiceTest.kt | 1 + .../anki/stats/AnkiStatsTaskHandlerTest.kt | 3 +- .../com/ichi2/async/ForegroundTaskManager.kt | 4 +- .../test/java/com/ichi2/compat/Test21And26.kt | 2 +- .../test/java/com/ichi2/libanki/FinderTest.kt | 7 +- .../com/ichi2/libanki/MathJaxClozeTest.kt | 1 - .../test/java/com/ichi2/libanki/ModelTest.kt | 1 - .../com/ichi2/libanki/StorageLockingTest.kt | 1 + .../java/com/ichi2/libanki/StorageTest.kt | 4 +- .../com/ichi2/libanki/TextNoteExporterTest.kt | 1 + .../test/java/com/ichi2/libanki/UndoTest.kt | 2 +- .../test/java/com/ichi2/libanki/UtilsTest.kt | 6 +- .../ichi2/libanki/sched/AbstractSchedTest.kt | 1 + .../ichi2/libanki/sched/SchedUpgradeTest.kt | 6 +- .../com/ichi2/libanki/sched/SchedV2Test.kt | 39 +++- .../ichi2/libanki/template/TemplateTest.kt | 3 +- .../ichi2/preferences/TimePreferenceTest.kt | 4 +- .../java/com/ichi2/testutils/ActivityList.kt | 3 +- .../ichi2/testutils/CollectionDBCorruption.kt | 2 +- .../test/java/com/ichi2/testutils/MockTime.kt | 3 +- .../com/ichi2/ui/BindingPreferenceTest.kt | 1 - .../test/java/com/ichi2/utils/FileUtilTest.kt | 1 + .../java/com/ichi2/utils/JSONObjectTest.kt | 2 + .../java/com/ichi2/utils/LanguageUtilsTest.kt | 3 +- .../java/com/ichi2/utils/SequenceUtilTest.kt | 1 - .../test/java/com/ichi2/utils/TagsUtilTest.kt | 5 +- .../com/ichi2/utils/UniqueArrayListTest.kt | 15 +- .../rendering/PieChartParameterizedTest.kt | 5 +- .../android/rendering/PieChartTest.kt | 38 +++- .../java/com/ichi2/anki/FlashCardsContract.kt | 9 + .../java/com/ichi2/anki/api/AddContentApi.kt | 54 +++-- .../java/com/ichi2/anki/api/Basic2Model.kt | 3 + .../java/com/ichi2/anki/api/BasicModel.kt | 3 + build.gradle | 10 +- .../java/com/ichi2/anki/lint/IssueRegistry.kt | 1 + .../lint/rules/DirectSnackbarMakeUsage.kt | 1 + .../DirectSystemCurrentTimeMillisUsage.kt | 1 + .../rules/DirectSystemTimeInstantiation.kt | 4 +- .../lint/rules/DirectToastMakeTextUsage.kt | 1 + .../lint/rules/DuplicateCrowdInStrings.kt | 1 + .../rules/DuplicateTextInPreferencesXml.kt | 2 + .../lint/rules/FixedPreferencesTitleLength.kt | 2 + .../anki/lint/rules/HardcodedPreferenceKey.kt | 1 + .../lint/rules/InvalidStringFormatDetector.kt | 4 +- .../lint/rules/JUnitNullAssertionDetector.kt | 1 + .../lint/rules/KotlinMigrationBrokenEmails.kt | 1 + .../rules/KotlinMigrationFixLineBreaks.kt | 1 + .../rules/NonPositionalFormatSubstitutions.kt | 2 +- .../anki/lint/rules/PrintStackTraceUsage.kt | 1 + .../anki/lint/rules/VariableNamingDetector.kt | 1 + .../com/ichi2/anki/lint/utils/Aapt2Util.kt | 3 +- .../com/ichi2/anki/lint/utils/Constants.kt | 1 + .../lint/utils/ImportStatementDetector.kt | 1 + .../ichi2/anki/lint/utils/KotlinCleanup.kt | 28 --- lint.gradle | 2 + 307 files changed, 1986 insertions(+), 989 deletions(-) create mode 100644 .editorconfig delete mode 100644 lint-rules/src/main/java/com/ichi2/anki/lint/utils/KotlinCleanup.kt diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000000..1f2d56b0b1 --- /dev/null +++ b/.editorconfig @@ -0,0 +1,3 @@ +[*.{kt,kts}] +ktlint_disabled_rules = no-wildcard-imports +# ktlint_standard_no-wildcard-imports = disabled \ No newline at end of file diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt index 5501df0d4e..586863627b 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ACRATest.kt @@ -63,7 +63,6 @@ class ACRATest : InstrumentedTest() { @Test @Throws(Exception::class) fun testDebugConfiguration() { - // Debug mode overrides all saved state so no setup needed CrashReportService.setDebugACRAConfig(sharedPrefs) assertArrayEquals( @@ -91,7 +90,6 @@ class ACRATest : InstrumentedTest() { @Test @Throws(Exception::class) fun testProductionConfigurationUserDisabled() { - // set up as if the user had prefs saved to disable completely setReportConfig(CrashReportService.FEEDBACK_REPORT_NEVER) diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt index eb8d7318fe..e6f3525631 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/ContentProviderTest.kt @@ -71,6 +71,7 @@ class ContentProviderTest : InstrumentedTest() { // Whether tear down should be executed. I.e. if set up was not cancelled. private var mTearDown = false + @KotlinCleanup("lateinit") private var mNumDecksBeforeTest = 0 @@ -290,7 +291,8 @@ class ContentProviderTest : InstrumentedTest() { col = reopenCol() // test that the changes are physically saved to the DB assertNotNull("Check template uri", templateUri) assertEquals( - "Check template uri ord", expectedOrd.toLong(), + "Check template uri ord", + expectedOrd.toLong(), ContentUris.parseId( templateUri!! ) @@ -606,7 +608,8 @@ class ContentProviderTest : InstrumentedTest() { i.toString() ) assertThat( - "Update rows", cr.update(tmplUri, cv, null, null), + "Update rows", + cr.update(tmplUri, cv, null, null), `is`( greaterThan(0) ) @@ -649,7 +652,8 @@ class ContentProviderTest : InstrumentedTest() { assertNotNull(allModels) allModels.use { assertThat( - "Check that there is at least one result", allModels.count, + "Check that there is at least one result", + allModels.count, `is`(greaterThan(0)) ) while (allModels.moveToNext()) { @@ -689,7 +693,8 @@ class ContentProviderTest : InstrumentedTest() { val numCards = allModels.getInt(allModels.getColumnIndex(FlashCardsContract.Model.NUM_CARDS)) assertThat( - "Check that valid number of cards", numCards, + "Check that valid number of cards", + numCards, `is`( greaterThanOrEqualTo(1) ) @@ -958,7 +963,11 @@ class ContentProviderTest : InstrumentedTest() { val col = col val sched = col.sched val reviewInfoCursor = contentResolver.query( - FlashCardsContract.ReviewInfo.CONTENT_URI, null, null, null, null + FlashCardsContract.ReviewInfo.CONTENT_URI, + null, + null, + null, + null ) assertNotNull(reviewInfoCursor) assertEquals("Check that we actually received one card", 1, reviewInfoCursor.count) @@ -1002,7 +1011,11 @@ class ContentProviderTest : InstrumentedTest() { val selectedDeckBeforeTest = col.decks.selected() col.decks.select(1) // select Default deck val reviewInfoCursor = contentResolver.query( - FlashCardsContract.ReviewInfo.CONTENT_URI, null, deckSelector, deckArguments, null + FlashCardsContract.ReviewInfo.CONTENT_URI, + null, + deckSelector, + deckArguments, + null ) assertNotNull(reviewInfoCursor) assertEquals("Check that we actually received one card", 1, reviewInfoCursor.count) @@ -1168,7 +1181,6 @@ class ContentProviderTest : InstrumentedTest() { */ @Test fun testSuspendCard() { - // get the first card due // ---------------------- val col = col @@ -1190,6 +1202,7 @@ class ContentProviderTest : InstrumentedTest() { val reviewInfoUri = FlashCardsContract.ReviewInfo.CONTENT_URI val noteId = card.note().id val cardOrd = card.ord + @KotlinCleanup("rename, while valid suspend is a kotlin soft keyword") val values = ContentValues().apply { val suspend = 1 @@ -1304,6 +1317,7 @@ class ContentProviderTest : InstrumentedTest() { private val TEST_MODEL_AFMT = arrayOf("{{BACK}}", "{{FRONTS}}") private val TEST_NOTE_FIELDS = arrayOf("dis is za Fr0nt", "Te\$t") private const val TEST_MODEL_CSS = "styleeeee" + @Suppress("SameParameterValue") private fun setupNewNote( col: com.ichi2.libanki.Collection, @@ -1318,7 +1332,8 @@ class ContentProviderTest : InstrumentedTest() { } newNote.addTag(tag) assertThat( - "At least one card added for note", col.addNote(newNote), + "At least one card added for note", + col.addNote(newNote), `is`( greaterThanOrEqualTo(1) ) diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/LayoutValidationTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/LayoutValidationTest.kt index 9aad8d265d..c693be5aad 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/LayoutValidationTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/LayoutValidationTest.kt @@ -38,6 +38,7 @@ class LayoutValidationTest : InstrumentedTest() { @JvmField // required for Parameter @Parameterized.Parameter(1) var name: String? = null + @Test @Throws(Exception::class) fun ensureLayout() { diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/NotificationChannelTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/NotificationChannelTest.kt index e9a2bd9c00..ae6b3fcab2 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/NotificationChannelTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/NotificationChannelTest.kt @@ -44,8 +44,10 @@ class NotificationChannelTest : InstrumentedTest() { var runtimePermissionRule = GrantStoragePermission.instance private var mCurrentAPI = -1 private var mTargetAPI = -1 + @KotlinCleanup("lateinit") private var mManager: NotificationManager? = null + @Before @UiThreadTest fun setUp() { diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/HttpTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/HttpTest.kt index 211e5caa26..70273bea0f 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/HttpTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/HttpTest.kt @@ -44,7 +44,6 @@ class HttpTest { @Suppress("DEPRECATION") @Test fun testLogin() { - val username = "AnkiDroidInstrumentedTestUser" val password = "AnkiDroidInstrumentedTestInvalidPass" val invalidPayload = Connection.Payload(arrayOf(username, password, HostNum(null))) diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/ImportTest.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/ImportTest.kt index cb44bf53db..bc14c20a2e 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/ImportTest.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/tests/libanki/ImportTest.kt @@ -59,6 +59,7 @@ class ImportTest : InstrumentedTest() { // Allowing it to re-run now, 3 times, in case it flakes again. @get:Rule var retry = RetryRule(10) + @Before @Throws(IOException::class) fun setUp() { @@ -75,7 +76,6 @@ class ImportTest : InstrumentedTest() { @Test @Throws(IOException::class, JSONException::class, ImportExportException::class) fun testAnki2Mediadupes() { - // add a note that references a sound var n = testCol.newNote() n.setField(0, "[sound:foo.mp3]") diff --git a/AnkiDroid/src/androidTest/java/com/ichi2/anki/testutil/GrantPermissions.kt b/AnkiDroid/src/androidTest/java/com/ichi2/anki/testutil/GrantPermissions.kt index 31e4de7770..868be5172b 100644 --- a/AnkiDroid/src/androidTest/java/com/ichi2/anki/testutil/GrantPermissions.kt +++ b/AnkiDroid/src/androidTest/java/com/ichi2/anki/testutil/GrantPermissions.kt @@ -26,10 +26,11 @@ object GrantStoragePermission { val storagePermission = if ( targetSdkVersion >= Build.VERSION_CODES.R && Build.VERSION.SDK_INT >= Build.VERSION_CODES.R - ) + ) { null - else + } else { android.Manifest.permission.WRITE_EXTERNAL_STORAGE + } /** * Storage is longer necessary for API 30+ @@ -38,8 +39,11 @@ object GrantStoragePermission { val instance: TestRule = grantPermissions(storagePermission) } -val notificationPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) - android.Manifest.permission.POST_NOTIFICATIONS else null +val notificationPermission = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + android.Manifest.permission.POST_NOTIFICATIONS +} else { + null +} /** Grants permissions, given some may be invalid */ fun grantPermissions(vararg permissions: String?): TestRule { diff --git a/AnkiDroid/src/main/java/com/ichi2/anim/ViewAnimation.kt b/AnkiDroid/src/main/java/com/ichi2/anim/ViewAnimation.kt index e3b3ed2c25..1a4e0055da 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anim/ViewAnimation.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anim/ViewAnimation.kt @@ -30,32 +30,50 @@ object ViewAnimation { when (type) { SLIDE_IN_FROM_RIGHT -> { animation = translateAnimation( - +1.0f, 0.0f, 0.0f, 0.0f + +1.0f, + 0.0f, + 0.0f, + 0.0f ) } SLIDE_OUT_TO_RIGHT -> { animation = translateAnimation( - 0.0f, +1.0f, 0.0f, 0.0f + 0.0f, + +1.0f, + 0.0f, + 0.0f ) } SLIDE_IN_FROM_LEFT -> { animation = translateAnimation( - -1.0f, 0.0f, 0.0f, 0.0f + -1.0f, + 0.0f, + 0.0f, + 0.0f ) } SLIDE_OUT_TO_LEFT -> { animation = translateAnimation( - 0.0f, -1.0f, 0.0f, 0.0f + 0.0f, + -1.0f, + 0.0f, + 0.0f ) } SLIDE_IN_FROM_BOTTOM -> { animation = translateAnimation( - 0.0f, 0.0f, +1.0f, 0.0f + 0.0f, + 0.0f, + +1.0f, + 0.0f ) } SLIDE_IN_FROM_TOP -> { animation = translateAnimation( - 0.0f, 0.0f, -1.0f, 0.0f + 0.0f, + 0.0f, + -1.0f, + 0.0f ) } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt index 7feac109d6..cd4b020fb4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AbstractFlashcardViewer.kt @@ -177,12 +177,16 @@ abstract class AbstractFlashcardViewer : protected var answerField: FixedEditText? = null protected var flipCardLayout: LinearLayout? = null private var easeButtonsLayout: LinearLayout? = null + @KotlinCleanup("internal for AnkiDroidJsApi") internal var easeButton1: EaseButton? = null + @KotlinCleanup("internal for AnkiDroidJsApi") internal var easeButton2: EaseButton? = null + @KotlinCleanup("internal for AnkiDroidJsApi") internal var easeButton3: EaseButton? = null + @KotlinCleanup("internal for AnkiDroidJsApi") internal var easeButton4: EaseButton? = null protected var topBarLayout: RelativeLayout? = null @@ -223,6 +227,7 @@ abstract class AbstractFlashcardViewer : private var mViewerUrl: String? = null private var mAssetLoader: WebViewAssetLoader? = null private val mFadeDuration = 300 + @KotlinCleanup("made internal for tests") @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) internal var sched: AbstractSched? = null @@ -651,7 +656,9 @@ abstract class AbstractFlashcardViewer : override fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { return if (processCardFunction { cardWebView: WebView? -> processHardwareButtonScroll(keyCode, cardWebView) }) { true - } else super.onKeyDown(keyCode, event) + } else { + super.onKeyDown(keyCode, event) + } } public override val currentCardId: CardId? get() = currentCard?.id @@ -824,7 +831,6 @@ abstract class AbstractFlashcardViewer : legacyUndo() } else { return launchCatchingTask { - if (!backendUndoAndShowPopup(findViewById(R.id.flip_card))) { legacyUndo() } @@ -1246,7 +1252,6 @@ abstract class AbstractFlashcardViewer : } protected open fun restoreCollectionPreferences(col: Collection) { - // These are preferences we pull out of the collection instead of SharedPreferences try { mShowNextReviewTime = col.get_config_boolean("estTimes") @@ -1652,104 +1657,106 @@ abstract class AbstractFlashcardViewer : override fun executeCommand(which: ViewerCommand, fromGesture: Gesture?): Boolean { return if (isControlBlocked && which !== ViewerCommand.EXIT) { false - } else when (which) { - ViewerCommand.SHOW_ANSWER -> { - if (displayAnswer) { - return false + } else { + when (which) { + ViewerCommand.SHOW_ANSWER -> { + if (displayAnswer) { + return false + } + displayCardAnswer() + true } - displayCardAnswer() - true - } - ViewerCommand.FLIP_OR_ANSWER_EASE1 -> { - flipOrAnswerCard(EASE_1) - true - } - ViewerCommand.FLIP_OR_ANSWER_EASE2 -> { - flipOrAnswerCard(EASE_2) - true - } - ViewerCommand.FLIP_OR_ANSWER_EASE3 -> { - flipOrAnswerCard(EASE_3) - true - } - ViewerCommand.FLIP_OR_ANSWER_EASE4 -> { - flipOrAnswerCard(EASE_4) - true - } - ViewerCommand.FLIP_OR_ANSWER_RECOMMENDED -> { - flipOrAnswerCard(getRecommendedEase(false)) - true - } - ViewerCommand.FLIP_OR_ANSWER_BETTER_THAN_RECOMMENDED -> { - flipOrAnswerCard(getRecommendedEase(true)) - true - } - ViewerCommand.EXIT -> { - closeReviewer(RESULT_DEFAULT, false) - true - } - ViewerCommand.UNDO -> { - if (!isUndoAvailable) { - return false + ViewerCommand.FLIP_OR_ANSWER_EASE1 -> { + flipOrAnswerCard(EASE_1) + true + } + ViewerCommand.FLIP_OR_ANSWER_EASE2 -> { + flipOrAnswerCard(EASE_2) + true + } + ViewerCommand.FLIP_OR_ANSWER_EASE3 -> { + flipOrAnswerCard(EASE_3) + true + } + ViewerCommand.FLIP_OR_ANSWER_EASE4 -> { + flipOrAnswerCard(EASE_4) + true + } + ViewerCommand.FLIP_OR_ANSWER_RECOMMENDED -> { + flipOrAnswerCard(getRecommendedEase(false)) + true + } + ViewerCommand.FLIP_OR_ANSWER_BETTER_THAN_RECOMMENDED -> { + flipOrAnswerCard(getRecommendedEase(true)) + true + } + ViewerCommand.EXIT -> { + closeReviewer(RESULT_DEFAULT, false) + true + } + ViewerCommand.UNDO -> { + if (!isUndoAvailable) { + return false + } + undo() + true + } + ViewerCommand.EDIT -> { + editCard(fromGesture) + true + } + ViewerCommand.TAG -> { + showTagsDialog() + true + } + ViewerCommand.BURY_CARD -> buryCard() + ViewerCommand.BURY_NOTE -> buryNote() + ViewerCommand.SUSPEND_CARD -> suspendCard() + ViewerCommand.SUSPEND_NOTE -> suspendNote() + ViewerCommand.DELETE -> { + showDeleteNoteDialog() + true + } + ViewerCommand.PLAY_MEDIA -> { + playSounds(true) + true + } + ViewerCommand.PAGE_UP -> { + onPageUp() + true + } + ViewerCommand.PAGE_DOWN -> { + onPageDown() + true + } + ViewerCommand.ABORT_AND_SYNC -> { + abortAndSync() + true + } + ViewerCommand.RECORD_VOICE -> { + recordVoice() + true + } + ViewerCommand.REPLAY_VOICE -> { + replayVoice() + true + } + ViewerCommand.TOGGLE_WHITEBOARD -> { + toggleWhiteboard() + true + } + ViewerCommand.SHOW_HINT -> { + loadUrlInViewer("javascript: showHint();") + true + } + ViewerCommand.SHOW_ALL_HINTS -> { + loadUrlInViewer("javascript: showAllHints();") + true + } + else -> { + Timber.w("Unknown command requested: %s", which) + false } - undo() - true - } - ViewerCommand.EDIT -> { - editCard(fromGesture) - true - } - ViewerCommand.TAG -> { - showTagsDialog() - true - } - ViewerCommand.BURY_CARD -> buryCard() - ViewerCommand.BURY_NOTE -> buryNote() - ViewerCommand.SUSPEND_CARD -> suspendCard() - ViewerCommand.SUSPEND_NOTE -> suspendNote() - ViewerCommand.DELETE -> { - showDeleteNoteDialog() - true - } - ViewerCommand.PLAY_MEDIA -> { - playSounds(true) - true - } - ViewerCommand.PAGE_UP -> { - onPageUp() - true - } - ViewerCommand.PAGE_DOWN -> { - onPageDown() - true - } - ViewerCommand.ABORT_AND_SYNC -> { - abortAndSync() - true - } - ViewerCommand.RECORD_VOICE -> { - recordVoice() - true - } - ViewerCommand.REPLAY_VOICE -> { - replayVoice() - true - } - ViewerCommand.TOGGLE_WHITEBOARD -> { - toggleWhiteboard() - true - } - ViewerCommand.SHOW_HINT -> { - loadUrlInViewer("javascript: showHint();") - true - } - ViewerCommand.SHOW_ALL_HINTS -> { - loadUrlInViewer("javascript: showAllHints();") - true - } - else -> { - Timber.w("Unknown command requested: %s", which) - false } } } @@ -2602,6 +2609,7 @@ abstract class AbstractFlashcardViewer : * Should be protected, using non-JVM static members protected in the superclass companion is unsupported yet */ const val INITIAL_HIDE_DELAY = 200 + // I don't see why we don't do this by intent. /** to be sent to and from the card editor */ @set:VisibleForTesting(otherwise = VisibleForTesting.NONE) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt index acf452a795..58285acab6 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/AnkiDroidApp.kt @@ -64,6 +64,7 @@ open class AnkiDroidApp : Application() { /** An exception if the WebView subsystem fails to load */ private var mWebViewError: Throwable? = null private val mNotifications = MutableLiveData() + @KotlinCleanup("can move analytics here now") override fun attachBaseContext(base: Context) { // update base context with preferred app language before attach @@ -260,7 +261,9 @@ open class AnkiDroidApp : Application() { // throw new IllegalStateException( // "Synthetic stacktrace didn't have enough elements: are you using proguard?"); // --- end of alteration from upstream Timber.DebugTree.getTag --- - } else createStackElementTag(stackTrace[CALL_STACK_INDEX]) + } else { + createStackElementTag(stackTrace[CALL_STACK_INDEX]) + } } // ---- END copied from Timber.DebugTree because DebugTree.getTag() is package private ---- diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/BackendBackups.kt b/AnkiDroid/src/main/java/com/ichi2/anki/BackendBackups.kt index 08df32ebf3..199bd4fccf 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/BackendBackups.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/BackendBackups.kt @@ -39,7 +39,7 @@ fun DeckPicker.importColpkg(colpkgPath: String) { if (progress.hasImporting()) { text = progress.importing } - }, + } ) { CollectionManager.importColpkg(colpkgPath) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/BackendImporting.kt b/AnkiDroid/src/main/java/com/ichi2/anki/BackendImporting.kt index d205c7c661..085c00f1dc 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/BackendImporting.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/BackendImporting.kt @@ -41,7 +41,7 @@ fun DeckPicker.importApkgs(apkgPaths: List) { if (progress.hasImporting()) { text = progress.importing } - }, + } ) { undoableOp { importAnkiPackage(apkgPath) @@ -105,7 +105,7 @@ suspend fun AnkiActivity.exportApkg( if (progress.hasExporting()) { text = progress.exporting } - }, + } ) { withCol { newBackend.exportAnkiPackage(apkgPath, withScheduling, withMedia, limit) @@ -115,14 +115,14 @@ suspend fun AnkiActivity.exportApkg( suspend fun AnkiActivity.exportColpkg( colpkgPath: String, - withMedia: Boolean, + withMedia: Boolean ) { withProgress( extractProgress = { if (progress.hasExporting()) { text = progress.exporting } - }, + } ) { withCol { newBackend.exportCollectionPackage(colpkgPath, withMedia, true) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt b/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt index 66cb1753f5..fb9bf3aaaa 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/BackendUndo.kt @@ -35,7 +35,6 @@ suspend fun FragmentActivity.backendUndoAndShowPopup(anchorView: View? = null): } showSnackbar(TR.undoActionUndone(changes.operation)) { - // A snackbar may obscure vital elements (e.g: the answer buttons on the Reviewer) // `anchorView` stops this anchorView?.let { setAnchorView(anchorView) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/BackupManager.kt b/AnkiDroid/src/main/java/com/ichi2/anki/BackupManager.kt index 30c0c829dd..5cbc105ce7 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/BackupManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/BackupManager.kt @@ -113,7 +113,9 @@ open class BackupManager { // If have no backups, then a backup is necessary return if (len <= 0) { false - } else colBackups[len - 1].lastModified() == colFile.lastModified() + } else { + colBackups[len - 1].lastModified() == colFile.lastModified() + } // no collection changes means we don't need a backup } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt index 249d0debae..9690d37793 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardBrowser.kt @@ -239,6 +239,7 @@ open class CardBrowser : @get:VisibleForTesting(otherwise = VisibleForTesting.NONE) var isInMultiSelectMode = false private set + @get:VisibleForTesting(otherwise = VisibleForTesting.NONE) var isTruncated = false private val mCheckedCards = Collections.synchronizedSet(LinkedHashSet()) @@ -399,7 +400,8 @@ open class CardBrowser : if (searchName.isNullOrEmpty()) { showThemedToast( this@CardBrowser, - getString(R.string.card_browser_list_my_searches_new_search_error_empty_name), true + getString(R.string.card_browser_list_my_searches_new_search_error_empty_name), + true ) return } @@ -413,7 +415,8 @@ open class CardBrowser : } else { showThemedToast( this@CardBrowser, - getString(R.string.card_browser_list_my_searches_new_search_error_dup), true + getString(R.string.card_browser_list_my_searches_new_search_error_dup), + true ) } } @@ -443,8 +446,8 @@ open class CardBrowser : * Change Deck * @param did Id of the deck */ - @VisibleForTesting // TODO: This function can be simplified a lot + @VisibleForTesting fun moveSelectedCardsToDeck(did: DeckId) { val selectedDeck = col.decks.get(did) // TODO: Currently try-catch is at every level which isn't required, simplify that @@ -577,7 +580,8 @@ open class CardBrowser : val cardsColumn1Spinner = findViewById(R.id.browser_column1_spinner) val column1Adapter = ArrayAdapter.createFromResource( this, - R.array.browser_column1_headings, android.R.layout.simple_spinner_item + R.array.browser_column1_headings, + android.R.layout.simple_spinner_item ) column1Adapter.setDropDownViewResource(R.layout.spinner_custom_layout) cardsColumn1Spinner.adapter = column1Adapter @@ -606,7 +610,8 @@ open class CardBrowser : val cardsColumn2Spinner = findViewById(R.id.browser_column2_spinner) val column2Adapter = ArrayAdapter.createFromResource( this, - R.array.browser_column2_headings, android.R.layout.simple_spinner_item + R.array.browser_column2_headings, + android.R.layout.simple_spinner_item ) // The custom layout for the adapter is used to prevent the overlapping of various interactive components on the screen column2Adapter.setDropDownViewResource(R.layout.spinner_custom_layout) @@ -638,7 +643,8 @@ open class CardBrowser : cardsAdapter = MultiColumnListAdapter( this, R.layout.card_item_browser, - columnsContent, intArrayOf(R.id.card_sfld, R.id.card_column2), + columnsContent, + intArrayOf(R.id.card_sfld, R.id.card_column2), sflRelativeFontSize, sflCustomFont ) @@ -666,12 +672,7 @@ open class CardBrowser : cardsListView!!.setOnItemLongClickListener { _: AdapterView<*>?, view: View?, position: Int, _: Long -> if (isInMultiSelectMode) { var hasChanged = false - for ( - i in min(mLastSelectedPosition, position)..max( - mLastSelectedPosition, - position - ) - ) { + for (i in min(mLastSelectedPosition, position)..max(mLastSelectedPosition, position)) { val card = cardsListView!!.getItemAtPosition(i) as CardCache // Add to the set of checked cards @@ -697,8 +698,12 @@ open class CardBrowser : window.setSoftInputMode(WindowManager.LayoutParams.SOFT_INPUT_STATE_ALWAYS_HIDDEN) val deckId = col.decks.selected() deckSpinnerSelection = DeckSpinnerSelection( - this, col, findViewById(R.id.toolbar_spinner), - showAllDecks = true, alwaysShowDefault = false, showFilteredDecks = true + this, + col, + findViewById(R.id.toolbar_spinner), + showAllDecks = true, + alwaysShowDefault = false, + showFilteredDecks = true ) inCardsMode = AnkiDroidApp.getSharedPrefs(this).getBoolean("inCardsMode", true) isTruncated = AnkiDroidApp.getSharedPrefs(this).getBoolean("isTruncated", false) @@ -738,7 +743,6 @@ open class CardBrowser : } } KeyEvent.KEYCODE_E -> { - // Ctrl+Shift+E: Export (TODO) if (event.isCtrlPressed) { Timber.i("Ctrl+E: Add Note") @@ -1127,8 +1131,10 @@ open class CardBrowser : val searchTerms = mSearchView!!.query.toString() showDialogFragment( newInstance( - null, mMySearchesDialogListener, - searchTerms, CardBrowserMySearchesDialog.CARD_BROWSER_MY_SEARCHES_TYPE_SAVE + null, + mMySearchesDialogListener, + searchTerms, + CardBrowserMySearchesDialog.CARD_BROWSER_MY_SEARCHES_TYPE_SAVE ) ) return true @@ -1142,8 +1148,10 @@ open class CardBrowser : ) showDialogFragment( newInstance( - savedFilters, mMySearchesDialogListener, - "", CardBrowserMySearchesDialog.CARD_BROWSER_MY_SEARCHES_TYPE_LIST + savedFilters, + mMySearchesDialogListener, + "", + CardBrowserMySearchesDialog.CARD_BROWSER_MY_SEARCHES_TYPE_LIST ) ) return true @@ -1566,7 +1574,9 @@ open class CardBrowser : mTagsDialogListenerAction = TagsDialogListenerAction.EDIT_TAGS val dialog = mTagsDialogFactory!!.newTagsDialog().withArguments( TagsDialog.DialogType.EDIT_TAGS, - checkedTags, uncheckedTags, allTags + checkedTags, + uncheckedTags, + allTags ) showDialogFragment(dialog) } @@ -1574,7 +1584,9 @@ open class CardBrowser : private fun showFilterByTagsDialog() { mTagsDialogListenerAction = TagsDialogListenerAction.FILTER val dialog = mTagsDialogFactory!!.newTagsDialog().withArguments( - TagsDialog.DialogType.FILTER_BY_TAG, ArrayList(0), col.tags.all() + TagsDialog.DialogType.FILTER_BY_TAG, + ArrayList(0), + col.tags.all() ) showDialogFragment(dialog) } @@ -1708,10 +1720,12 @@ open class CardBrowser : override val subtitleText: String get() { val count = cardCount - @androidx.annotation.StringRes val subtitleId = if (inCardsMode) + + @androidx.annotation.StringRes val subtitleId = if (inCardsMode) { R.plurals.card_browser_subtitle - else + } else { R.plurals.card_browser_subtitle_notes_mode + } return resources.getQuantityString(subtitleId, count, count) } @@ -2035,8 +2049,11 @@ open class CardBrowser : protected suspend fun renderBrowserQAParams(firstVisibleItem: Int, visibleItemCount: Int, cards: CardCollection) { Timber.d("Starting Q&A background rendering") val result = renderBrowserQA( - cards, firstVisibleItem, visibleItemCount, - mColumn1Index, mColumn2Index + cards, + firstVisibleItem, + visibleItemCount, + mColumn1Index, + mColumn2Index ) { // Note: This is called every time a card is rendered. // It blocks the long-click callback while the task is running, so usage of the task should be minimized @@ -2466,7 +2483,9 @@ open class CardBrowser : } return if (javaClass != other.javaClass) { false - } else id == (other as CardCache).id + } else { + id == (other as CardCache).id + } } override fun hashCode(): Int { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardInfo.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardInfo.kt index 2b15f107e2..9b0cd5708e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardInfo.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardInfo.kt @@ -267,7 +267,9 @@ class CardInfo : AnkiActivity() { fun intervalAsTimeSeconds(): Long { return if (ivl < 0) { -ivl - } else ivl * Stats.SECONDS_PER_DAY + } else { + ivl * Stats.SECONDS_PER_DAY + } } // saves space if we just use seconds rather than a "s" suffix diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateBrowserAppearanceEditor.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateBrowserAppearanceEditor.kt index 4b3a7b97f8..a93493ecf7 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateBrowserAppearanceEditor.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateBrowserAppearanceEditor.kt @@ -187,13 +187,15 @@ class CardTemplateBrowserAppearanceEditor : AnkiActivity() { fun fromIntent(intent: Intent?): Result? { return if (intent == null) { null - } else try { - val question = intent.getStringExtra(INTENT_QUESTION_FORMAT) - val answer = intent.getStringExtra(INTENT_ANSWER_FORMAT) - Result(question, answer) - } catch (e: Exception) { - Timber.w(e, "Could not read result from intent") - null + } else { + try { + val question = intent.getStringExtra(INTENT_QUESTION_FORMAT) + val answer = intent.getStringExtra(INTENT_ANSWER_FORMAT) + Result(question, answer) + } catch (e: Exception) { + Timber.w(e, "Could not read result from intent") + null + } } } } @@ -205,6 +207,7 @@ class CardTemplateBrowserAppearanceEditor : AnkiActivity() { /** Specified the card browser should use the default template formatter */ const val VALUE_USE_DEFAULT = "" + @CheckResult fun getIntentFromTemplate(context: Context, template: JSONObject): Intent { val browserQuestionTemplate = template.getString("bqfmt") diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt index 5f7b75371a..bc71431804 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplateEditor.kt @@ -584,7 +584,8 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { return false } }, - viewLifecycleOwner, Lifecycle.State.RESUMED + viewLifecycleOwner, + Lifecycle.State.RESUMED ) } @@ -688,7 +689,6 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { val currentDeletes = tempModel.getDeleteDbOrds(position) // TODO - this is a SQL query on GUI thread - should see a DeckTask conversion ideally if (col.models.getCardIdsForModel(tempModel.modelId, currentDeletes) == null) { - // It is possible but unlikely that a user has an in-memory template addition that would // generate cards making the deletion safe, but we don't handle that. All users who do // not already have cards generated making it safe will see this error message: @@ -748,7 +748,8 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { R.plurals.card_template_editor_confirm_delete, numAffectedCards ), - numAffectedCards, tmpl.optString("name") + numAffectedCards, + tmpl.optString("name") ) d.setArgs(msg) @@ -918,8 +919,10 @@ open class CardTemplateEditor : AnkiActivity(), DeckSelectionListener { private const val EDITOR_NOTE_ID = "noteId" private const val EDITOR_START_ORD_ID = "ordId" private const val CARD_INDEX = "card_ord" + @Suppress("unused") private const val REQUEST_PREVIEWER = 0 + @Suppress("unused") private const val REQUEST_CARD_BROWSER_APPEARANCE = 1 } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplatePreviewer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplatePreviewer.kt index 541218775a..589de1c9ab 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplatePreviewer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CardTemplatePreviewer.kt @@ -385,7 +385,9 @@ open class CardTemplatePreviewer : AbstractFlashcardViewer() { override val isEmpty: Boolean get() = if (mNote != null) { false - } else super.isEmpty + } else { + super.isEmpty + } /** Override the method that fetches the model so we can render unsaved models */ override fun model(): Model { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CollectionHelper.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CollectionHelper.kt index 16c0afd20a..d15f850277 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CollectionHelper.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CollectionHelper.kt @@ -75,7 +75,8 @@ open class CollectionHelper { Timber.i("Begin openCollection: %s", path) val backend = BackendFactory.getBackend(context) val collection = Storage.collection( - context, path, + context, + path, server = false, log = true, backend = backend @@ -223,13 +224,15 @@ open class CollectionHelper { } val required = Formatter.formatShortFileSize(context, mRequiredSpace) val insufficientSpace = context.resources.getString( - R.string.integrity_check_insufficient_space, required + R.string.integrity_check_insufficient_space, + required ) // Also concat in the extra content showing the current free space. val currentFree = Formatter.formatShortFileSize(context, mFreeSpace) val insufficientSpaceCurrentFree = context.resources.getString( - R.string.integrity_check_insufficient_space_extra_content, currentFree + R.string.integrity_check_insufficient_space_extra_content, + currentFree ) return insufficientSpace + insufficientSpaceCurrentFree } @@ -539,10 +542,12 @@ open class CollectionHelper { getDefaultAnkiDroidDirectory(context), "androidTest" ).absolutePath - } else PreferenceExtensions.getOrSetString( - preferences, - PREF_COLLECTION_PATH - ) { getDefaultAnkiDroidDirectory(context) } + } else { + PreferenceExtensions.getOrSetString( + preferences, + PREF_COLLECTION_PATH + ) { getDefaultAnkiDroidDirectory(context) } + } } /** Fetches additional collection data not required for diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt index ca1e44d0c1..e9af16e973 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CollectionManager.kt @@ -296,12 +296,14 @@ object CollectionManager { // out our own code, and standard dalvik/java.lang stack frames val caller = stackTraceElements.filter { val klass = it.className - for ( - text in listOf( - "CollectionManager", "dalvik", "java.lang", - "CollectionHelper", "AnkiActivity" - ) - ) { + val toCheck = listOf( + "CollectionManager", + "dalvik", + "java.lang", + "CollectionHelper", + "AnkiActivity" + ) + for (text in toCheck) { if (text in klass) { return@filter false } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt index 5a8467f4c0..20f7a01c6d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CoroutineHelpers.kt @@ -180,7 +180,7 @@ private fun showError(context: Context, msg: String, exception: Throwable) { suspend fun Backend.withProgress( extractProgress: ProgressContext.() -> Unit, updateUi: ProgressContext.() -> Unit, - block: suspend CoroutineScope.() -> T, + block: suspend CoroutineScope.() -> T ): T { return coroutineScope { val monitor = launch { @@ -292,7 +292,7 @@ private suspend fun withProgressDialog( private suspend fun monitorProgress( backend: Backend, extractProgress: ProgressContext.() -> Unit, - updateUi: ProgressContext.() -> Unit, + updateUi: ProgressContext.() -> Unit ) { val state = ProgressContext(Progress.getDefaultInstance()) while (true) { @@ -313,7 +313,7 @@ data class ProgressContext( var progress: Progress, var text: String = "", /** If set, shows progress bar with a of b complete. */ - var amount: Pair? = null, + var amount: Pair? = null ) @Suppress("Deprecation") // ProgressDialog deprecation diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/CrashReportService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/CrashReportService.kt index 854f1b9d6f..ef494e9498 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/CrashReportService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/CrashReportService.kt @@ -48,12 +48,22 @@ object CrashReportService { /** Our ACRA configurations, initialized during Application.onCreate() */ @JvmStatic private var logcatArgs = arrayOf( - "-t", "100", "-v", "time", "ActivityManager:I", "SQLiteLog:W", AnkiDroidApp.TAG + ":D", "*:S" + "-t", + "100", + "-v", + "time", + "ActivityManager:I", + "SQLiteLog:W", + AnkiDroidApp.TAG + ":D", + "*:S" ) + @JvmStatic private var dialogEnabled = true + @JvmStatic private lateinit var toastText: String + @JvmStatic lateinit var acraCoreConfigBuilder: CoreConfigurationBuilder private set diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DatabaseCheck.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DatabaseCheck.kt index 640ceb7435..35669748cd 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/DatabaseCheck.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/DatabaseCheck.kt @@ -34,7 +34,7 @@ fun DeckPicker.handleDatabaseCheck() { } } }, - onCancel = null, + onCancel = null ) { withCol { newBackend.fixIntegrity() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DeckOptionsActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DeckOptionsActivity.kt index 72412d7571..9f30355559 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/DeckOptionsActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/DeckOptionsActivity.kt @@ -136,7 +136,9 @@ class DeckOptionsActivity : mValues["reminderEnabled"] = reminder.getBoolean("enabled").toString() mValues["reminderTime"] = String.format( - "%1$02d:%2$02d", reminderTime.getLong(0), reminderTime.getLong(1) + "%1$02d:%2$02d", + reminderTime.getLong(0), + reminderTime.getLong(1) ) } else { mValues["reminderEnabled"] = "false" @@ -171,8 +173,10 @@ class DeckOptionsActivity : fun preConfChange() { val res = deckOptionsActivity.resources progressDialog = StyledProgressDialog.show( - deckOptionsActivity as Context, null, - res?.getString(R.string.reordering_cards), false + deckOptionsActivity as Context, + null, + res?.getString(R.string.reordering_cards), + false ) } @@ -282,7 +286,8 @@ class DeckOptionsActivity : // Don't remove the options group if it's the default group UIUtils.showThemedToast( this@DeckOptionsActivity, - resources.getString(R.string.default_conf_delete_error), false + resources.getString(R.string.default_conf_delete_error), + false ) } else { // Remove options group, handling the case where the user needs to confirm full sync @@ -346,7 +351,8 @@ class DeckOptionsActivity : applicationContext, mOptions.getLong("id").toInt(), Intent(applicationContext, ReminderService::class.java).putExtra( - ReminderService.EXTRA_DECK_OPTION_ID, mOptions.getLong("id") + ReminderService.EXTRA_DECK_OPTION_ID, + mOptions.getLong("id") ), 0 ) @@ -698,7 +704,6 @@ class DeckOptionsActivity : companion object { fun reminderToCalendar(time: Time, reminder: JSONObject): Calendar { - val calendar = time.calendar() calendar[Calendar.HOUR_OF_DAY] = reminder.getJSONArray("time").getInt(0) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt index b7f98f83d0..40d188471e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/DeckPicker.kt @@ -22,6 +22,7 @@ // usage of 'this' in constructors when class is non-final - weak warning // should be OK as this is only non-final for tests @file:Suppress("LeakingThis") + package com.ichi2.anki import android.Manifest @@ -137,6 +138,7 @@ import kotlin.system.measureTimeMillis const val MIGRATION_WAS_LAST_POSTPONED_AT_SECONDS = "secondWhenMigrationWasPostponedLast" const val POSTPONE_MIGRATION_INTERVAL_DAYS = 5L + /** * The current entry point for AnkiDroid. Displays decks, allowing users to study. Many other functions. * @@ -179,6 +181,7 @@ open class DeckPicker : private var mShortAnimDuration = 0 private var mBackButtonPressedToExit = false private lateinit var mDeckPickerContent: RelativeLayout + @Suppress("Deprecation") // TODO: Encapsulate ProgressDialog within a class to limit the use of deprecated functionality private var mProgressDialog: android.app.ProgressDialog? = null private var mStudyoptionsFrame: View? = null // not lateInit - can be null @@ -191,6 +194,7 @@ open class DeckPicker : private lateinit var mNoDecksPlaceholder: LinearLayout private lateinit var mPullToSyncWrapper: SwipeRefreshLayout private lateinit var mReviewSummaryTextView: TextView + @KotlinCleanup("make lateinit, but needs more changes") private var mUnmountReceiver: BroadcastReceiver? = null private lateinit var mFloatingActionMenu: DeckPickerFloatingActionMenu @@ -343,7 +347,9 @@ open class DeckPicker : if (context.mProgressDialog == null || !context.mProgressDialog!!.isShowing) { context.mProgressDialog = StyledProgressDialog.show( context, - context.resources.getString(R.string.import_title), null, false + context.resources.getString(R.string.import_title), + null, + false ) } } @@ -377,7 +383,8 @@ open class DeckPicker : context.mProgressDialog = StyledProgressDialog.show( context, context.resources.getString(R.string.import_title), - context.resources.getString(R.string.import_replacing), false + context.resources.getString(R.string.import_replacing), + false ) } } @@ -390,6 +397,7 @@ open class DeckPicker : context.mProgressDialog!!.setMessage(value) } } + // ---------------------------------------------------------------------------- // ANDROID ACTIVITY METHODS // ---------------------------------------------------------------------------- @@ -1176,7 +1184,6 @@ open class DeckPicker : } private fun showStartupScreensAndDialogs(preferences: SharedPreferences, skip: Int) { - // For Android 8/8.1 we want to use software rendering by default or the Reviewer UI is broken #7369 if (sdkVersion == Build.VERSION_CODES.O || sdkVersion == Build.VERSION_CODES.O_MR1 @@ -1693,7 +1700,8 @@ open class DeckPicker : if (mProgressDialog == null || !mProgressDialog!!.isShowing) { try { mProgressDialog = StyledProgressDialog.show( - this@DeckPicker, resources.getString(R.string.sync_title), + this@DeckPicker, + resources.getString(R.string.sync_title), """ ${resources.getString(R.string.sync_title)} ${resources.getString(R.string.sync_up_down_size, mCountUp, mCountDown)} @@ -1818,7 +1826,8 @@ open class DeckPicker : diff >= 86100 -> { // The difference if more than a day minus 5 minutes acceptable by ankiweb error res.getString( - R.string.sync_log_clocks_unsynchronized, diff, + R.string.sync_log_clocks_unsynchronized, + diff, res.getString(R.string.sync_log_clocks_unsynchronized_date) ) } @@ -1826,7 +1835,8 @@ open class DeckPicker : // The difference would be within limit if we adjusted the time by few hours // It doesn't work for all timezones, but it covers most and it's a guess anyway res.getString( - R.string.sync_log_clocks_unsynchronized, diff, + R.string.sync_log_clocks_unsynchronized, + diff, res.getString(R.string.sync_log_clocks_unsynchronized_tz) ) } @@ -1922,7 +1932,8 @@ open class DeckPicker : if (dialogMessage == null) { dialogMessage = res.getString( R.string.sync_log_error_specific, - code.toString(), result[1] + code.toString(), + result[1] ) } } else { @@ -2041,7 +2052,9 @@ open class DeckPicker : val frag = supportFragmentManager.findFragmentById(R.id.studyoptions_fragment) return if (frag is StudyOptionsFragment) { frag - } else null + } else { + null + } } /** @@ -2161,7 +2174,8 @@ open class DeckPicker : setAction(R.string.study_more) { val d = mCustomStudyDialogFactory.newCustomStudyDialog().withArguments( CustomStudyDialog.ContextMenuConfiguration.LIMITS, - col.decks.selected(), true + col.decks.selected(), + true ) showDialogFragment(d) } @@ -2200,7 +2214,8 @@ open class DeckPicker : setAction(R.string.custom_study) { val d = mCustomStudyDialogFactory.newCustomStudyDialog().withArguments( CustomStudyDialog.ContextMenuConfiguration.EMPTY_SCHEDULE, - col.decks.selected(), true + col.decks.selected(), + true ) showDialogFragment(d) } @@ -2306,7 +2321,8 @@ open class DeckPicker : mNoDecksPlaceholder.visibility = if (isEmpty) View.VISIBLE else View.GONE } else { val translation = TypedValue.applyDimension( - TypedValue.COMPLEX_UNIT_DIP, 8f, + TypedValue.COMPLEX_UNIT_DIP, + 8f, resources.displayMetrics ) val decksListShown = mDeckPickerContent.visibility == View.VISIBLE @@ -2691,8 +2707,10 @@ open class DeckPicker : internal inner class CheckDatabaseListener : TaskListener?>() { override fun onPreExecute() { mProgressDialog = StyledProgressDialog.show( - this@DeckPicker, AnkiDroidApp.appResources.getString(R.string.app_name), - resources.getString(R.string.check_db_message), false + this@DeckPicker, + AnkiDroidApp.appResources.getString(R.string.app_name), + resources.getString(R.string.check_db_message), + false ) } @@ -2930,6 +2948,7 @@ open class DeckPicker : get() = getSharedPrefs(baseContext).getLong(MIGRATION_WAS_LAST_POSTPONED_AT_SECONDS, 0L) set(timeInSecond) = getSharedPrefs(baseContext) .edit { putLong(MIGRATION_WAS_LAST_POSTPONED_AT_SECONDS, timeInSecond) } + /** * Show a dialog offering to migrate, postpone or learn more. */ @@ -2945,7 +2964,8 @@ open class DeckPicker : else -> R.string.migration_update_request_dialog_download_warning } - @Language("HTML") val message = """${getString(R.string.migration_update_request)} + @Language("HTML") + val message = """${getString(R.string.migration_update_request)}

${getString(ifYouUninstallMessageId)}""" @@ -2993,7 +3013,7 @@ data class OptionsMenuState( /** If undo is available, a string describing the action. */ val undoIcon: String?, val syncIcon: SyncIconState, - val offerToMigrate: Boolean, + val offerToMigrate: Boolean ) enum class SyncIconState { @@ -3001,10 +3021,11 @@ enum class SyncIconState { PendingChanges, FullSync, NotLoggedIn, + /** * The icon should appear as disabled. Currently only occurs during scoped storage migration. */ - Disabled, + Disabled } /** diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/DeckSpinnerSelection.kt b/AnkiDroid/src/main/java/com/ichi2/anki/DeckSpinnerSelection.kt index 39e0ecfd38..faf90f9d12 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/DeckSpinnerSelection.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/DeckSpinnerSelection.kt @@ -57,7 +57,7 @@ class DeckSpinnerSelection( private val spinner: Spinner, private val showAllDecks: Boolean, private val alwaysShowDefault: Boolean, - private val showFilteredDecks: Boolean, + private val showFilteredDecks: Boolean ) { /** * All of the decks shown to the user. @@ -112,7 +112,6 @@ class DeckSpinnerSelection( } val noteDeckAdapter: ArrayAdapter = object : ArrayAdapter(context, R.layout.multiline_spinner_item, deckNames as List) { override fun getDropDownView(position: Int, convertView: View?, parent: ViewGroup): View { - // Cast the drop down items (popup items) as text view val tv = super.getDropDownView(position, convertView, parent) as TextView @@ -189,7 +188,9 @@ class DeckSpinnerSelection( fun selectDeckById(deckId: DeckId, setAsCurrentDeck: Boolean): Boolean { return if (deckId == ALL_DECKS_ID) { selectAllDecks() - } else selectDeck(deckId, setAsCurrentDeck) + } else { + selectDeck(deckId, setAsCurrentDeck) + } } /** diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/FieldEditText.kt b/AnkiDroid/src/main/java/com/ichi2/anki/FieldEditText.kt index 2aec10a9ef..50ba5c2fbd 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/FieldEditText.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/FieldEditText.kt @@ -55,6 +55,7 @@ class FieldEditText : FixedEditText, NoteService.NoteField { private var mOrigBackground: Drawable? = null private var mSelectionChangeListener: TextSelectionListener? = null private var mImageListener: ImagePasteListener? = null + @VisibleForTesting(otherwise = VisibleForTesting.PRIVATE) var clipboard: ClipboardManager? = null @@ -103,7 +104,8 @@ class FieldEditText : FixedEditText, NoteService.NoteField { val inputConnection = super.onCreateInputConnection(editorInfo) ?: return null EditorInfoCompat.setContentMimeTypes(editorInfo, IMAGE_MIME_TYPES) ViewCompat.setOnReceiveContentListener( - this, IMAGE_MIME_TYPES, + this, + IMAGE_MIME_TYPES, object : OnReceiveContentListener { override fun onReceiveContent(view: View, payload: ContentInfoCompat): ContentInfoCompat? { val pair = payload.partition { item -> item.uri != null } @@ -219,7 +221,9 @@ class FieldEditText : FixedEditText, NoteService.NoteField { private fun onImagePaste(imageUri: Uri?): Boolean { return if (imageUri == null) { false - } else mImageListener!!.onImagePaste(this, imageUri) + } else { + mImageListener!!.onImagePaste(this, imageUri) + } } override fun onRestoreInstanceState(state: Parcelable) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/FilterSheetBottomFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/FilterSheetBottomFragment.kt index fd56e81075..6d1b9e60fb 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/FilterSheetBottomFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/FilterSheetBottomFragment.kt @@ -54,8 +54,10 @@ class FilterSheetBottomFragment : private lateinit var flagListAdapter: FlagsAdapter private lateinit var flagToggleIcon: ImageView + /** Heading of the Flags filter section */ private lateinit var filterHeaderFlags: TextView + /** Icon of the Flags filter section */ private lateinit var filterIconFlags: ImageView @@ -145,9 +147,7 @@ class FilterSheetBottomFragment : } flagsHeaderLayout.setOnClickListener { - if (SystemClock.elapsedRealtime() - lastClickTime > DELAY_TIME) { - lastClickTime = SystemClock.elapsedRealtime().toInt() if (flagsRecyclerViewLayout.isVisible) { @@ -164,7 +164,6 @@ class FilterSheetBottomFragment : private fun createQuery( flagList: Set ): String { - if (flagList.isEmpty()) { return "" } @@ -207,6 +206,7 @@ class FilterSheetBottomFragment : inner class ViewHolder(view: View) : RecyclerView.ViewHolder(view) { private val itemTextView: TextView = view.findViewById(R.id.filter_list_item) val icon: ImageView = view.findViewById(R.id.filter_list_icon) + /** Checks whether flagSearchItems was empty before adding new element to it */ private fun onFlagItemClicked(item: Flags) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/Info.kt b/AnkiDroid/src/main/java/com/ichi2/anki/Info.kt index 19d6f2df2a..0c168e8edc 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/Info.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/Info.kt @@ -47,6 +47,7 @@ private const val GITHUB_COMMITS = "https://github.com/ankidroid/Anki-Android/co */ class Info : AnkiActivity() { private var mWebView: WebView? = null + @SuppressLint("SetJavaScriptEnabled") override fun onCreate(savedInstanceState: Bundle?) { if (showedActivityFailedScreen(savedInstanceState)) { @@ -110,7 +111,6 @@ class Info : AnkiActivity() { mWebView!!.settings.javaScriptEnabled = true mWebView!!.webViewClient = object : WebViewClient() { override fun onPageFinished(view: WebView, url: String) { - /* The order of below javascript code must not change (this order works both in debug and release mode) * or else it will break in any one mode. */ diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/InitialActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/InitialActivity.kt index 0f12ec41f3..c31d7afe65 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/InitialActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/InitialActivity.kt @@ -30,7 +30,6 @@ object InitialActivity { /** Returns null on success */ @CheckResult fun getStartupFailureType(context: Context): StartupFailure? { - // A WebView failure means that we skip `AnkiDroidApp`, and therefore haven't loaded the collection if (AnkiDroidApp.webViewFailedToLoad()) { return StartupFailure.WEBVIEW_FAILED diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/LeakCanaryConfiguration.kt b/AnkiDroid/src/main/java/com/ichi2/anki/LeakCanaryConfiguration.kt index 47e264c4a1..3293de5501 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/LeakCanaryConfiguration.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/LeakCanaryConfiguration.kt @@ -33,7 +33,7 @@ object LeakCanaryConfiguration { retainedVisibleThreshold = 0, referenceMatchers = AndroidReferenceMatchers.appDefaults, computeRetainedHeapSize = false, - maxStoredHeapDumps = 0, + maxStoredHeapDumps = 0 ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/MetaDB.kt b/AnkiDroid/src/main/java/com/ichi2/anki/MetaDB.kt index 793305ffd2..adbd3a56ce 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/MetaDB.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/MetaDB.kt @@ -63,10 +63,11 @@ object MetaDB { private fun openDB(context: Context) { try { mMetaDb = context.openOrCreateDatabase(DATABASE_NAME, 0, null).let { - if (it.needUpgrade(DATABASE_VERSION)) + if (it.needUpgrade(DATABASE_VERSION)) { upgradeDB(it, DATABASE_VERSION) - else + } else { it + } } Timber.v("Opening MetaDB") } catch (e: Exception) { @@ -225,7 +226,10 @@ object MetaDB { mMetaDb!!.execSQL( "INSERT INTO languages (did, ord, qa, language) " + " VALUES (?, ?, ?, ?);", arrayOf( - did, ord, qa.int, language + did, + ord, + qa.int, + language ) ) Timber.v("Store language for deck %d", did) @@ -233,7 +237,10 @@ object MetaDB { mMetaDb!!.execSQL( "UPDATE languages SET language = ? WHERE did = ? AND ord = ? AND qa = ?;", arrayOf( - language, did, ord, qa.int + language, + did, + ord, + qa.int ) ) Timber.v("Update language for deck %d", did) @@ -460,8 +467,13 @@ object MetaDB { var cursor: Cursor? = null try { cursor = mMetaDb!!.query( - "smallWidgetStatus", arrayOf("due", "eta"), - null, null, null, null, null + "smallWidgetStatus", + arrayOf("due", "eta"), + null, + null, + null, + null, + null ) if (cursor.moveToNext()) { return intArrayOf(cursor.getInt(0), cursor.getInt(1)) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/MyAccount.kt b/AnkiDroid/src/main/java/com/ichi2/anki/MyAccount.kt index 1de981395c..bc14a7b1eb 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/MyAccount.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/MyAccount.kt @@ -50,6 +50,7 @@ open class MyAccount : AnkiActivity() { private lateinit var mUsername: EditText private lateinit var mPassword: TextInputEditField private lateinit var mUsernameLoggedIn: TextView + @Suppress("Deprecation") private var mProgressDialog: android.app.ProgressDialog? = null var toolbar: Toolbar? = null @@ -116,7 +117,8 @@ open class MyAccount : AnkiActivity() { mLoginListener, Connection.Payload( arrayOf( - username, password, + username, + password, getInstance(this) ) ) @@ -155,7 +157,8 @@ open class MyAccount : AnkiActivity() { mLoginListener, Connection.Payload( arrayOf( - username, password, + username, + password, getInstance(this) ) ) @@ -258,8 +261,10 @@ open class MyAccount : AnkiActivity() { Timber.d("loginListener.onPreExecute()") if (mProgressDialog == null || !mProgressDialog!!.isShowing) { mProgressDialog = StyledProgressDialog.show( - this@MyAccount, null, - resources.getString(R.string.alert_logging_message), false + this@MyAccount, + null, + resources.getString(R.string.alert_logging_message), + false ) } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/NavigationDrawerActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/NavigationDrawerActivity.kt index b83132d5f9..24756caff5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/NavigationDrawerActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/NavigationDrawerActivity.kt @@ -61,6 +61,7 @@ abstract class NavigationDrawerActivity : */ protected var fragmented = false private var mNavButtonGoesBack = false + // Navigation drawer list item entries private lateinit var mDrawerLayout: DrawerLayout private lateinit var mNavigationView: NavigationView @@ -77,7 +78,9 @@ abstract class NavigationDrawerActivity : // Using ClosableDrawerLayout as a parent view. val closableDrawerLayout = LayoutInflater.from(this).inflate( - navigationDrawerLayout, null, false + navigationDrawerLayout, + null, + false ) as ClosableDrawerLayout // Get CoordinatorLayout using resource ID val coordinatorLayout = LayoutInflater.from(this) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt b/AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt index e8115f5f20..61e64c871f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/NoteEditor.kt @@ -134,6 +134,7 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags // non-null after onCollectionLoaded private var mEditorNote: Note? = null + /* Null if adding a new card. Presently NonNull if editing an existing note - but this is subject to change */ private var mCurrentEditedCard: Card? = null private var mSelectedTags: ArrayList? = null @@ -142,6 +143,7 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags var deckId: DeckId = 0 private set private var mAllModelIds: List? = null + @KotlinCleanup("this ideally should be Int, Int?") private var mModelChangeFieldMap: MutableMap? = null private var mModelChangeCardMap: HashMap? = null @@ -201,7 +203,9 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags } return if (allFieldsHaveContent()) { R.string.note_editor_no_cards_created_all_fields - } else R.string.note_editor_no_cards_created + } else { + R.string.note_editor_no_cards_created + } // Otherwise, display "no cards created". } @@ -360,7 +364,9 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags } mDeckSpinnerSelection = DeckSpinnerSelection( - this, col, findViewById(R.id.note_deck_spinner), + this, + col, + findViewById(R.id.note_deck_spinner), showAllDecks = false, alwaysShowDefault = true, showFilteredDecks = false @@ -429,7 +435,6 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags } private fun modifyCurrentSelection(formatter: Toolbar.TextFormatter, textBox: FieldEditText) { - // get the current text and selection locations val selectionStart = textBox.selectionStart val selectionEnd = textBox.selectionEnd @@ -623,7 +628,9 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags // changed fields? return if (isFieldEdited) { true - } else isTagsEdited + } else { + isTagsEdited + } // changed tags? } @@ -805,7 +812,6 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags val dialog = ConfirmationDialog() dialog.setArgs(res.getString(R.string.full_sync_confirmation)) val confirm = Runnable { - // Bypass the check once the user confirms col.modSchemaNoCheck() try { @@ -1182,7 +1188,6 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags } } REQUEST_TEMPLATE_EDIT -> { - // Model can change regardless of exit type - update ourselves and CardBrowser mReloadRequired = true mEditorNote!!.reloadModel() @@ -1416,8 +1421,9 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags @NeedsTest("If a field is sticky after synchronization, the toggleStickyButton should be activated.") private fun setToggleStickyButtonListener(toggleStickyButton: ImageButton?, index: Int) { - if (currentFields.getJSONObject(index).getBoolean("sticky")) + if (currentFields.getJSONObject(index).getBoolean("sticky")) { mToggleStickyText.getOrPut(index) { "" } + } if (mToggleStickyText[index] == null) { toggleStickyButton!!.background.alpha = 64 } else { @@ -1684,8 +1690,12 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags private fun updateToolbar() { val editorLayout = findViewById(R.id.note_editor_layout) val bottomMargin = - if (shouldHideToolbar()) 0 else resources.getDimension(R.dimen.note_editor_toolbar_height) - .toInt() + if (shouldHideToolbar()) { + 0 + } else { + resources.getDimension(R.dimen.note_editor_toolbar_height) + .toInt() + } val params = editorLayout.layoutParams as MarginLayoutParams params.bottomMargin = bottomMargin editorLayout.layoutParams = params @@ -1718,7 +1728,6 @@ class NoteEditor : AnkiActivity(), DeckSelectionListener, SubtitleListener, Tags } val buttons = toolbarButtons for (b in buttons) { - // 0th button shows as '1' and is Ctrl + 1 val visualIndex = b.index + 1 var text = visualIndex.toString() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/Onboarding.kt b/AnkiDroid/src/main/java/com/ichi2/anki/Onboarding.kt index ca651ac560..623bf00347 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/Onboarding.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/Onboarding.kt @@ -80,7 +80,7 @@ abstract class Onboarding( DECK_PICKER_ONBOARDING, REVIEWER_ONBOARDING, NOTE_EDITOR_ONBOARDING, - CARD_BROWSER_ONBOARDING, + CARD_BROWSER_ONBOARDING ) ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/OnboardingUtils.kt b/AnkiDroid/src/main/java/com/ichi2/anki/OnboardingUtils.kt index d2ec79c105..4f22aea6ae 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/OnboardingUtils.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/OnboardingUtils.kt @@ -32,6 +32,7 @@ class OnboardingUtils { * Preference can be toggled by visiting 'Advanced' settings in the app. */ const val SHOW_ONBOARDING = "showOnboarding" + @VisibleForTesting val featureConstants: MutableSet = HashSet() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/Reviewer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/Reviewer.kt index 83ab242dc3..b6490549e0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/Reviewer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/Reviewer.kt @@ -121,6 +121,7 @@ open class Reviewer : @get:VisibleForTesting(otherwise = VisibleForTesting.NONE) var whiteboard: Whiteboard? = null protected set + // Record Audio /** File of the temporary mic record */ @get:VisibleForTesting(otherwise = VisibleForTesting.NONE) @@ -150,7 +151,8 @@ open class Reviewer : val cardCount: Int = result!!.value.result.size showThemedToast( this, - resources.getQuantityString(toastResourceId, cardCount, cardCount), true + resources.getQuantityString(toastResourceId, cardCount, cardCount), + true ) } } @@ -201,7 +203,9 @@ open class Reviewer : val shownAsToolbarButton = mActionButtons.findMenuItem(ActionButtons.RES_FLAG)?.isActionButton == true return if (shownAsToolbarButton && !mPrefFullscreenReview) { CardMarker.FLAG_NONE - } else actualValue + } else { + actualValue + } } override fun createWebView(): WebView { @@ -600,7 +604,8 @@ open class Reviewer : private fun openOrToggleMicToolbar() { if (!canRecordAudio(this)) { ActivityCompat.requestPermissions( - this, arrayOf(Manifest.permission.RECORD_AUDIO), + this, + arrayOf(Manifest.permission.RECORD_AUDIO), REQUEST_AUDIO_PERMISSION ) } else { @@ -632,7 +637,8 @@ open class Reviewer : return } val lp2 = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT ) audioView!!.layoutParams = lp2 val micToolBarLayer = findViewById(R.id.mic_tool_bar_layer) @@ -924,7 +930,9 @@ open class Reviewer : override fun onKeyUp(keyCode: Int, event: KeyEvent): Boolean { return if (mProcessor.onKeyUp(keyCode, event)) { true - } else super.onKeyUp(keyCode, event) + } else { + super.onKeyUp(keyCode, event) + } } private fun setupSubMenu(menu: Menu, @IdRes parentMenu: Int, subMenuProvider: T) where T : ActionProvider?, T : SubMenuProvider? { @@ -1419,20 +1427,27 @@ open class Reviewer : private fun suspendNoteAvailable(): Boolean { return if (currentCard == null || isControlBlocked) { false - } else col.db.queryScalar( - "select 1 from cards where nid = ? and id != ? and queue != " + Consts.QUEUE_TYPE_SUSPENDED + " limit 1", - currentCard!!.nid, currentCard!!.id - ) == 1 + } else { + col.db.queryScalar( + "select 1 from cards where nid = ? and id != ? and queue != " + Consts.QUEUE_TYPE_SUSPENDED + " limit 1", + currentCard!!.nid, + currentCard!!.id + ) == 1 + } // whether there exists a sibling not buried. } + @KotlinCleanup("mCurrentCard handling") private fun buryNoteAvailable(): Boolean { return if (currentCard == null || isControlBlocked) { false - } else col.db.queryScalar( - "select 1 from cards where nid = ? and id != ? and queue >= " + Consts.QUEUE_TYPE_NEW + " limit 1", - currentCard!!.nid, currentCard!!.id - ) == 1 + } else { + col.db.queryScalar( + "select 1 from cards where nid = ? and id != ? and queue >= " + Consts.QUEUE_TYPE_NEW + " limit 1", + currentCard!!.nid, + currentCard!!.id + ) == 1 + } // Whether there exists a sibling which is neither suspended nor buried } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksActivity.kt index 1fdfed3b86..356a55891a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksActivity.kt @@ -186,5 +186,5 @@ data class DownloadFile( val url: String, val userAgent: String, val contentDisposition: String, - val mimeType: String, + val mimeType: String ) : Serializable diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksDownloadFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksDownloadFragment.kt index f49aa5cb2f..571c44093f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksDownloadFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/SharedDecksDownloadFragment.kt @@ -140,7 +140,8 @@ class SharedDecksDownloadFragment : Fragment() { activity?.registerReceiver(mOnComplete, IntentFilter(DownloadManager.ACTION_DOWNLOAD_COMPLETE)) val currentFileName = URLUtil.guessFileName( - fileToBeDownloaded.url, fileToBeDownloaded.contentDisposition, + fileToBeDownloaded.url, + fileToBeDownloaded.contentDisposition, fileToBeDownloaded.mimeType ) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/Statistics.kt b/AnkiDroid/src/main/java/com/ichi2/anki/Statistics.kt index 57b99a4002..697b88310b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/Statistics.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/Statistics.kt @@ -115,8 +115,12 @@ class Statistics : NavigationDrawerActivity(), DeckSelectionListener, SubtitleLi else -> Timber.w("Unknown defaultDeck: %s", defaultDeck) } mDeckSpinnerSelection = DeckSpinnerSelection( - this, col, - findViewById(R.id.toolbar_spinner), showAllDecks = true, alwaysShowDefault = true, showFilteredDecks = true + this, + col, + findViewById(R.id.toolbar_spinner), + showAllDecks = true, + alwaysShowDefault = true, + showFilteredDecks = true ) mDeckSpinnerSelection.initializeActionBarDeckSpinner(this.supportActionBar!!) mDeckSpinnerSelection.selectDeckById(mStatsDeckId, false) @@ -285,7 +289,8 @@ class Statistics : NavigationDrawerActivity(), DeckSelectionListener, SubtitleLi mTabLayoutMediator.detach() } mTabLayoutMediator = TabLayoutMediator( - slidingTabLayout, mActivityPager + slidingTabLayout, + mActivityPager ) { tab: TabLayout.Tab, position: Int -> tab.text = getTabTitle(position) } mTabLayoutMediator.attach() } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt index f4e9701536..7f8967d60a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/StudyOptionsFragment.kt @@ -583,7 +583,6 @@ class StudyOptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener { private fun rebuildUi(result: DeckStudyData?, refreshDecklist: Boolean) { dismissProgressDialog() if (result != null) { - // Don't do anything if the fragment is no longer attached to it's Activity or col has been closed if (activity == null) { Timber.e("StudyOptionsFragment.mRefreshFragmentListener :: can't refresh") @@ -718,8 +717,10 @@ class StudyOptionsFragment : Fragment(), Toolbar.OnMenuItemClickListener { */ @Suppress("unused") private const val BROWSE_CARDS = 3 + @Suppress("unused") private const val STATISTICS = 4 + @Suppress("unused") private const val DECK_OPTIONS = 5 diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/Sync.kt b/AnkiDroid/src/main/java/com/ichi2/anki/Sync.kt index f21f083abe..b7e3c789aa 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/Sync.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/Sync.kt @@ -47,6 +47,7 @@ object SyncPreferences { const val CURRENT_SYNC_URI = "currentSyncUri" const val CUSTOM_SYNC_URI = "syncBaseUrl" const val CUSTOM_SYNC_ENABLED = CUSTOM_SYNC_URI + VersatileTextWithASwitchPreference.SWITCH_SUFFIX + // Used in the legacy schema path const val HOSTNUM = "hostNum" } @@ -106,7 +107,7 @@ fun isLoggedIn() = AnkiDroidApp.getSharedPrefs(AnkiDroidApp.instance).getString( fun DeckPicker.handleNewSync( conflict: Connection.ConflictResolution?, - syncMedia: Boolean, + syncMedia: Boolean ) { val auth = this.syncAuth() ?: return val deckPicker = this @@ -177,7 +178,7 @@ private fun cancelSync(backend: Backend) { private suspend fun handleNormalSync( deckPicker: DeckPicker, auth: SyncAuth, - syncMedia: Boolean, + syncMedia: Boolean ) { val output = deckPicker.withProgress( extractProgress = { @@ -242,7 +243,7 @@ private fun fullDownloadProgress(title: String): ProgressContext.() -> Unit { private suspend fun handleDownload( deckPicker: DeckPicker, auth: SyncAuth, - syncMedia: Boolean, + syncMedia: Boolean ) { deckPicker.withProgress( extractProgress = fullDownloadProgress(TR.syncDownloadingFromAnkiweb()), @@ -272,7 +273,7 @@ private suspend fun handleDownload( private suspend fun handleUpload( deckPicker: DeckPicker, auth: SyncAuth, - syncMedia: Boolean, + syncMedia: Boolean ) { deckPicker.withProgress( extractProgress = fullDownloadProgress(TR.syncUploadingToAnkiweb()), @@ -325,7 +326,7 @@ private suspend fun handleMediaSync( }, updateUi = { dialog.setMessage(text) - }, + } ) { withContext(Dispatchers.IO) { backend.syncMedia(auth) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/Whiteboard.kt b/AnkiDroid/src/main/java/com/ichi2/anki/Whiteboard.kt index d2da56b567..6fd2438665 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/Whiteboard.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/Whiteboard.kt @@ -172,7 +172,9 @@ class Whiteboard(activity: AnkiActivity, handleMultiTouch: Boolean, inverted: Bo MotionEvent.ACTION_POINTER_UP -> trySecondFingerClick(event) else -> false } - } else false + } else { + false + } } /** @@ -521,7 +523,8 @@ class Whiteboard(activity: AnkiActivity, handleMultiTouch: Boolean, inverted: Bo val whiteboard = Whiteboard(context, handleMultiTouch, currentTheme.isNightMode) mWhiteboardMultiTouchMethods = whiteboardMultiTouchMethods val lp2 = FrameLayout.LayoutParams( - ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT + ViewGroup.LayoutParams.MATCH_PARENT, + ViewGroup.LayoutParams.MATCH_PARENT ) whiteboard.layoutParams = lp2 val fl = context.findViewById(R.id.whiteboard) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/analytics/AnkiDroidCrashReportDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/analytics/AnkiDroidCrashReportDialog.kt index 16fbe69fff..8e15181fa7 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/analytics/AnkiDroidCrashReportDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/analytics/AnkiDroidCrashReportDialog.kt @@ -66,7 +66,9 @@ class AnkiDroidCrashReportDialog : CrashReportDialog(), DialogInterface.OnClickL override fun buildCustomView(savedInstanceState: Bundle?): View { val preferences = AnkiDroidApp.getSharedPrefs(this) val inflater = layoutInflater - @SuppressLint("InflateParams") val rootView = // when you inflate into an alert dialog, you have no parent view + + @SuppressLint("InflateParams") + val rootView = // when you inflate into an alert dialog, you have no parent view inflater.inflate(R.layout.feedback, null) mAlwaysReportCheckBox = rootView.findViewById(R.id.alwaysReportCheckbox) mAlwaysReportCheckBox?.isChecked = preferences.getBoolean("autoreportCheckboxValue", true) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/analytics/UsageAnalytics.kt b/AnkiDroid/src/main/java/com/ichi2/anki/analytics/UsageAnalytics.kt index 862bc14c2e..6b966a7c89 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/analytics/UsageAnalytics.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/analytics/UsageAnalytics.kt @@ -39,6 +39,7 @@ import timber.log.Timber @KotlinCleanup("see if we can make variables lazy, or properties without the `s` prefix") object UsageAnalytics { const val ANALYTICS_OPTIN_KEY = "analyticsOptIn" + @KotlinCleanup("lateinit") private var sAnalytics: GoogleAnalytics? = null private var sOriginalUncaughtExceptionHandler: Thread.UncaughtExceptionHandler? = null @@ -136,13 +137,9 @@ object UsageAnalytics { Thread.setDefaultUncaughtExceptionHandler(sOriginalUncaughtExceptionHandler) sOriginalUncaughtExceptionHandler = null } - /** - * Determine whether we are disabled or not - */ + /** * Allow users to enable or disable analytics - * - * @param optIn true allows collection of analytics information */ @set:Synchronized private var optIn: Boolean @@ -174,7 +171,6 @@ object UsageAnalytics { */ @Synchronized fun reInitialize() { - // send any pending async hits, re-chain default exception handlers and re-init Timber.i("reInitialize()") sAnalytics!!.flush() @@ -283,7 +279,9 @@ object UsageAnalytics { // if we're not under the ACRA process then we're fine to initialize a WebView return if (!ACRA.isACRASenderServiceProcess()) { true - } else hasSetDataDirectory() + } else { + hasSetDataDirectory() + } // If we have a custom data directory, then the crash will not occur. } @@ -313,7 +311,6 @@ object UsageAnalytics { */ private class AndroidDefaultRequest : DefaultRequest() { fun setAndroidRequestParameters(context: Context): DefaultRequest { - // Are we running on really large screens or small screens? Send raw screen size try { val size = DisplayUtils.getDisplayDimensions(context) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardAppearance.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardAppearance.kt index 2c963dcba9..0269ed0ff6 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardAppearance.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardAppearance.kt @@ -87,6 +87,7 @@ class CardAppearance(private val customFonts: ReviewerCustomFonts, private val c // font-weight to 700 return content.replace("font-weight:600;", "font-weight:700;") } + /** * hasUserDefinedNightMode finds out if the user has included class .night_mode in card's stylesheet */ diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardHtml.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardHtml.kt index c560b7d6e1..cd1e8f4d65 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardHtml.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardHtml.kt @@ -43,7 +43,7 @@ class CardHtml( private val getAnswerContentWithoutFrontSide_slow: (() -> String), @RustCleanup("too many variables, combine once we move away from backend") private var questionSound: List? = null, - private var answerSound: List? = null, + private var answerSound: List? = null ) { fun getSoundTags(sideFor: Side): List { if (sideFor == this.side) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardTemplate.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardTemplate.kt index 497cf4accb..ff4f3718f6 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardTemplate.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/CardTemplate.kt @@ -24,6 +24,7 @@ class CardTemplate(template: String) { private var mPreClass: String? = null private var mPreContent: String? = null private var mPostContent: String? = null + @CheckResult fun render(content: String, style: String, script: String, cardClass: String): String { return mPreStyle + style + mPreScript + script + mPreClass + cardClass + mPreContent + content + mPostContent diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/Gesture.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/Gesture.kt index aff17561a1..8c0817f0d0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/Gesture.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/Gesture.kt @@ -36,7 +36,7 @@ fun interface GestureListener { } enum class Gesture( - @get:JvmName("getResourceId") val resourceId: Int, + @get:JvmName("getResourceId") val resourceId: Int ) { SWIPE_UP(R.string.gestures_swipe_up), SWIPE_DOWN(R.string.gestures_swipe_down), @@ -75,6 +75,7 @@ enum class TapGestureMode { * are ambiguous in a nine-point system and thus not interchangeable */ FOUR_POINT, + /** * Divide the screen into 9 equally sized squares for touch targets. * Better for tablets diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/GestureProcessor.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/GestureProcessor.kt index 66e556b6d5..d70a2d172b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/GestureProcessor.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/GestureProcessor.kt @@ -54,8 +54,9 @@ class GestureProcessor(private val processor: ViewerCommand.CommandProcessor?) { val associatedCommands = HashMap() for (command in ViewerCommand.values()) { for (mappableBinding in MappableBinding.fromPreference(preferences, command)) { - if (mappableBinding.binding.isGesture) + if (mappableBinding.binding.isGesture) { associatedCommands[mappableBinding.binding.gesture!!] = command + } } } gestureDoubleTap = associatedCommands[Gesture.DOUBLE_TAP] diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/TypeAnswer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/TypeAnswer.kt index 9ab05b3e49..f7713f49fa 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/TypeAnswer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/TypeAnswer.kt @@ -46,9 +46,11 @@ class TypeAnswer( /** What the learner actually typed (externally mutable) */ var input = "" + /** Font face of the 'compare to' field */ var font = "" private set + /** The font size of the 'compare to' field */ var size = 0 private set diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/ViewerCommand.kt b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/ViewerCommand.kt index c4d828f585..7abc152fa7 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/ViewerCommand.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/cardviewer/ViewerCommand.kt @@ -124,19 +124,23 @@ enum class ViewerCommand(val resourceId: Int) { when (this) { FLIP_OR_ANSWER_EASE1 -> from( keyCode(KeyEvent.KEYCODE_BUTTON_Y, CardSide.BOTH), - keyCode(KeyEvent.KEYCODE_1, CardSide.ANSWER), keyCode(KeyEvent.KEYCODE_NUMPAD_1, CardSide.ANSWER) + keyCode(KeyEvent.KEYCODE_1, CardSide.ANSWER), + keyCode(KeyEvent.KEYCODE_NUMPAD_1, CardSide.ANSWER) ) FLIP_OR_ANSWER_EASE2 -> from( keyCode(KeyEvent.KEYCODE_BUTTON_X, CardSide.BOTH), - keyCode(KeyEvent.KEYCODE_2, CardSide.ANSWER), keyCode(KeyEvent.KEYCODE_NUMPAD_2, CardSide.ANSWER) + keyCode(KeyEvent.KEYCODE_2, CardSide.ANSWER), + keyCode(KeyEvent.KEYCODE_NUMPAD_2, CardSide.ANSWER) ) FLIP_OR_ANSWER_EASE3 -> from( keyCode(KeyEvent.KEYCODE_BUTTON_B, CardSide.BOTH), - keyCode(KeyEvent.KEYCODE_3, CardSide.ANSWER), keyCode(KeyEvent.KEYCODE_NUMPAD_3, CardSide.ANSWER) + keyCode(KeyEvent.KEYCODE_3, CardSide.ANSWER), + keyCode(KeyEvent.KEYCODE_NUMPAD_3, CardSide.ANSWER) ) FLIP_OR_ANSWER_EASE4 -> from( keyCode(KeyEvent.KEYCODE_BUTTON_A, CardSide.BOTH), - keyCode(KeyEvent.KEYCODE_4, CardSide.ANSWER), keyCode(KeyEvent.KEYCODE_NUMPAD_4, CardSide.ANSWER) + keyCode(KeyEvent.KEYCODE_4, CardSide.ANSWER), + keyCode(KeyEvent.KEYCODE_NUMPAD_4, CardSide.ANSWER) ) FLIP_OR_ANSWER_RECOMMENDED -> from( keyCode(KeyEvent.KEYCODE_DPAD_CENTER, CardSide.BOTH), diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CreateDeckDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CreateDeckDialog.kt index e8b459c1ff..c3ad4e33da 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CreateDeckDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/CreateDeckDialog.kt @@ -172,7 +172,6 @@ class CreateDeckDialog(private val context: Context, private val title: Int, pri if (deckName.isNotEmpty()) { when (deckDialogType) { DeckDialogType.DECK -> { - // create deck createDeck(deckName) } @@ -180,12 +179,10 @@ class CreateDeckDialog(private val context: Context, private val title: Int, pri renameDeck(deckName) } DeckDialogType.SUB_DECK -> { - // create sub deck createSubDeck(parentId!!, deckName) } DeckDialogType.FILTERED_DECK -> { - // create filtered deck createFilteredDeck(deckName) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DatabaseErrorDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DatabaseErrorDialog.kt index 171ca8569d..d91b572fdc 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DatabaseErrorDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DatabaseErrorDialog.kt @@ -64,7 +64,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } return when (type) { DIALOG_LOAD_FAILED -> { - // Collection failed to load; give user the option of either choosing from repair options, or closing // the activity dialog.show { @@ -81,7 +80,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_DB_ERROR -> { - // Database Check failed to execute successfully; give user the option of either choosing from repair // options, submitting an error report, or closing the activity dialog.show { @@ -103,7 +101,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_ERROR_HANDLING -> { - // The user has asked to see repair options; allow them to choose one of the repair options or go back // to the previous dialog val options = ArrayList(6) @@ -176,7 +173,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_REPAIR_COLLECTION -> { - // Allow user to run BackupManager.repairCollection() dialog.show { contentNullable(message) @@ -189,7 +185,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_RESTORE_BACKUP -> { - // Allow user to restore one of the backups val path = CollectionHelper.getCollectionPath(requireContext()) mBackups = BackupManager.getBackups(File(path)) @@ -244,7 +239,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { dialog } DIALOG_NEW_COLLECTION -> { - // Allow user to create a new empty collection dialog.show { contentNullable(message) @@ -263,7 +257,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_CONFIRM_DATABASE_CHECK -> { - // Confirmation dialog for database check dialog.show { contentNullable(message) @@ -275,7 +268,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_CONFIRM_RESTORE_BACKUP -> { - // Confirmation dialog for backup restore dialog.show { contentNullable(message) @@ -287,7 +279,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_FULL_SYNC_FROM_SERVER -> { - // Allow user to do a full-sync from the server dialog.show { contentNullable(message) @@ -299,7 +290,6 @@ class DatabaseErrorDialog : AsyncDialogFragment() { } } DIALOG_DB_LOCKED -> { - // If the database is locked, all we can do is ask the user to exit. dialog.show { contentNullable(message) @@ -444,8 +434,10 @@ class DatabaseErrorDialog : AsyncDialogFragment() { /** If the database is at a version higher than what we can currently handle */ const val INCOMPATIBLE_DB_VERSION = 10 + /** If the disk space is full **/ const val DIALOG_DISK_FULL = 11 + // public flag which lets us distinguish between inaccessible and corrupt database var databaseCorruptFlag = false diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckPickerContextMenu.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckPickerContextMenu.kt index d37e22b4c8..26b1a5d3ea 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckPickerContextMenu.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckPickerContextMenu.kt @@ -180,7 +180,9 @@ class DeckPickerContextMenu(private val collection: Collection) : AnalyticsDialo val cls = loadFragmentClass(classLoader, className) return if (cls == DeckPickerContextMenu::class.java) { newDeckPickerContextMenu() - } else super.instantiate(classLoader, className) + } else { + super.instantiate(classLoader, className) + } } private fun newDeckPickerContextMenu(): DeckPickerContextMenu = diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckSelectionDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckSelectionDialog.kt index 991c2c900f..5696bbef5a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckSelectionDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/DeckSelectionDialog.kt @@ -344,11 +344,15 @@ open class DeckSelectionDialog : AnalyticsDialogFragment() { if (deckId == Stats.ALL_DECKS_ID) { return if (other.deckId == Stats.ALL_DECKS_ID) { 0 - } else -1 + } else { + -1 + } } return if (other.deckId == Stats.ALL_DECKS_ID) { 1 - } else DeckNameComparator.INSTANCE.compare(name, other.name) + } else { + DeckNameComparator.INSTANCE.compare(name, other.name) + } } companion object { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ExportCompleteDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ExportCompleteDialog.kt index 6c2ead7718..5f7c9fe317 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ExportCompleteDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ExportCompleteDialog.kt @@ -42,7 +42,7 @@ class ExportCompleteDialog(private val listener: ExportCompleteDialogListener) : super.onCreate(savedInstanceState) val options = listOf( getString(R.string.export_select_save_app), - getString(R.string.export_select_share_app), + getString(R.string.export_select_share_app) ) return MaterialDialog(requireActivity()).show { title(text = notificationTitle) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/HelpDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/HelpDialog.kt index 0584b89ac8..1db0e0c6f4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/HelpDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/HelpDialog.kt @@ -52,18 +52,26 @@ object HelpDialog { UsageAnalytics.sendAnalyticsEvent(UsageAnalytics.Category.LINK_CLICKED, UsageAnalytics.Actions.OPENED_HELPDIALOG) val allItems = arrayOf( ItemHeader( - R.string.help_title_using_ankidroid, R.drawable.ic_manual_black_24dp, UsageAnalytics.Actions.OPENED_USING_ANKIDROID, + R.string.help_title_using_ankidroid, + R.drawable.ic_manual_black_24dp, + UsageAnalytics.Actions.OPENED_USING_ANKIDROID, FunctionItem( - R.string.help_item_ankidroid_manual, R.drawable.ic_manual_black_24dp, UsageAnalytics.Actions.OPENED_ANKIDROID_MANUAL + R.string.help_item_ankidroid_manual, + R.drawable.ic_manual_black_24dp, + UsageAnalytics.Actions.OPENED_ANKIDROID_MANUAL ) { activity -> openManual(activity) }, LinkItem(R.string.help_item_anki_manual, R.drawable.ic_manual_black_24dp, UsageAnalytics.Actions.OPENED_ANKI_MANUAL, R.string.link_anki_manual), LinkItem(R.string.help_item_ankidroid_faq, R.drawable.ic_help_black_24dp, UsageAnalytics.Actions.OPENED_ANKIDROID_FAQ, R.string.link_ankidroid_faq) ), ItemHeader( - R.string.help_title_get_help, R.drawable.ic_help_black_24dp, UsageAnalytics.Actions.OPENED_GET_HELP, + R.string.help_title_get_help, + R.drawable.ic_help_black_24dp, + UsageAnalytics.Actions.OPENED_GET_HELP, LinkItem(R.string.help_item_mailing_list, R.drawable.ic_email_black_24dp, UsageAnalytics.Actions.OPENED_MAILING_LIST, R.string.link_forum), FunctionItem( - R.string.help_item_report_bug, R.drawable.ic_bug_report_black_24dp, UsageAnalytics.Actions.OPENED_REPORT_BUG + R.string.help_item_report_bug, + R.drawable.ic_bug_report_black_24dp, + UsageAnalytics.Actions.OPENED_REPORT_BUG ) { activity -> openFeedback(activity) }, exceptionReportItem ), @@ -77,7 +85,9 @@ object HelpDialog { LinkItem(R.string.help_item_twitter, R.drawable.twitter, UsageAnalytics.Actions.OPENED_TWITTER, R.string.link_twitter) ), ItemHeader( - R.string.help_title_privacy, R.drawable.ic_baseline_privacy_tip_24, UsageAnalytics.Actions.OPENED_PRIVACY, + R.string.help_title_privacy, + R.drawable.ic_baseline_privacy_tip_24, + UsageAnalytics.Actions.OPENED_PRIVACY, LinkItem(R.string.help_item_ankidroid_privacy_policy, R.drawable.ic_baseline_policy_24, UsageAnalytics.Actions.OPENED_ANKIDROID_PRIVACY_POLICY, R.string.link_ankidroid_privacy_policy), LinkItem(R.string.help_item_ankiweb_privacy_policy, R.drawable.ic_baseline_policy_24, UsageAnalytics.Actions.OPENED_ANKIWEB_PRIVACY_POLICY, R.string.link_ankiweb_privacy_policy), LinkItem(R.string.help_item_ankiweb_terms_and_conditions, R.drawable.ic_baseline_description_24, UsageAnalytics.Actions.OPENED_ANKIWEB_TERMS_AND_CONDITIONS, R.string.link_ankiweb_terms_and_conditions) @@ -96,7 +106,9 @@ object HelpDialog { rateAppItem, LinkItem(R.string.help_item_support_other_ankidroid, R.drawable.ic_help_black_24dp, UsageAnalytics.Actions.OPENED_OTHER, R.string.link_contribution), FunctionItem( - R.string.send_feedback, R.drawable.ic_email_black_24dp, UsageAnalytics.Actions.OPENED_SEND_FEEDBACK + R.string.send_feedback, + R.drawable.ic_email_black_24dp, + UsageAnalytics.Actions.OPENED_SEND_FEEDBACK ) { activity -> openFeedback(activity) } ) val itemList = ArrayList(listOf(*allItems)) @@ -234,7 +246,8 @@ object HelpDialog { val wasReportSent = CrashReportService.sendReport(activity) if (!wasReportSent) { showThemedToast( - activity, activity.getString(R.string.help_dialog_exception_report_debounce), + activity, + activity.getString(R.string.help_dialog_exception_report_debounce), true ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ImportFileSelectionFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ImportFileSelectionFragment.kt index b9fa4f8b8e..bec38ca1e3 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ImportFileSelectionFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ImportFileSelectionFragment.kt @@ -60,7 +60,7 @@ class ImportFileSelectionFragment { R.drawable.ic_manual_black_24dp, UsageAnalytics.Actions.IMPORT_COLPKG_FILE, OpenFilePicker(DeckPicker.PICK_APKG_FILE) - ), + ) ) if (!BackendFactory.defaultLegacySchema) { val mimes = arrayOf("text/plain", "text/comma-separated-values", "text/csv", "text/tab-separated-values") diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/KeySelectionDialogUtils.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/KeySelectionDialogUtils.kt index 5ac5bd36ee..e736f28716 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/KeySelectionDialogUtils.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/KeySelectionDialogUtils.kt @@ -31,7 +31,7 @@ object KeySelectionDialogUtils { KeyEvent.KEYCODE_ALT_RIGHT, KeyEvent.KEYCODE_META_LEFT, KeyEvent.KEYCODE_META_RIGHT, - KeyEvent.KEYCODE_FUNCTION, + KeyEvent.KEYCODE_FUNCTION ) return { !modifierKeyCodes.contains(it) } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/MediaCheckDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/MediaCheckDialog.kt index 528bcf6f4c..5b5d81ff75 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/MediaCheckDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/MediaCheckDialog.kt @@ -124,7 +124,9 @@ class MediaCheckDialog : AsyncDialogFragment() { get() { return if (requireArguments().getInt("dialogType") == DIALOG_CONFIRM_MEDIA_CHECK) { resources.getString(R.string.check_media_title) - } else resources.getString(R.string.app_name) + } else { + resources.getString(R.string.app_name) + } } override val dialogHandlerMessage: Message diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ModelBrowserContextMenu.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ModelBrowserContextMenu.kt index 6c278d9e1b..7189a054e6 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ModelBrowserContextMenu.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ModelBrowserContextMenu.kt @@ -40,5 +40,5 @@ class ModelBrowserContextMenu : AnalyticsDialogFragment() { enum class ModelBrowserContextMenuAction(val order: Int, @StringRes val actionTextResId: Int) { Template(0, R.string.model_browser_template), Rename(1, R.string.model_browser_rename), - Delete(2, R.string.model_browser_delete), + Delete(2, R.string.model_browser_delete) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/RescheduleDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/RescheduleDialog.kt index 913abb629b..9d2bb3fcb3 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/RescheduleDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/RescheduleDialog.kt @@ -88,17 +88,19 @@ class RescheduleDialog : IntegerDialog() { ) return if (currentCard.isInDynamicDeck) { message - } else """ + } else { + """ $message ${ - resources.getQuantityString( - R.plurals.reschedule_card_dialog_interval, - currentCard.ivl, - currentCard.ivl - ) + resources.getQuantityString( + R.plurals.reschedule_card_dialog_interval, + currentCard.ivl, + currentCard.ivl + ) + } + """.trimIndent() } - """.trimIndent() } } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ScopedStorageMigrationDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ScopedStorageMigrationDialog.kt index 453118225e..00328c7253 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ScopedStorageMigrationDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/ScopedStorageMigrationDialog.kt @@ -168,7 +168,8 @@ fun openUrl(activity: AnkiActivity): OpenUri = activity::openUrl * @return the dialog */ fun AlertDialog.Builder.addScopedStorageLearnMoreLinkAndShow(@Language("HTML") message: String): AlertDialog { - @Language("HTML") val messageWithLink = """$message + @Language("HTML") + val messageWithLink = """$message

${context.getString(R.string.scoped_storage_learn_more)} """.trimIndent().parseAsHtml() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SimpleMessageDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SimpleMessageDialog.kt index 19529921c3..53a555f817 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SimpleMessageDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SimpleMessageDialog.kt @@ -61,8 +61,10 @@ class SimpleMessageDialog : AsyncDialogFragment() { companion object { /** The title of the notification/dialog */ private const val ARGS_TITLE = "title" + /** The content of the notification/dialog */ private const val ARGS_MESSAGE = "message" + /** * If the calling activity should be reloaded when 'OK' is pressed. * @see SimpleMessageDialogListener.dismissSimpleMessageDialog diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SyncErrorDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SyncErrorDialog.kt index 3ae83618cf..26cc159d04 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SyncErrorDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/SyncErrorDialog.kt @@ -48,7 +48,6 @@ class SyncErrorDialog : AsyncDialogFragment() { .cancelable(true) return when (requireArguments().getInt("dialogType")) { DIALOG_USER_NOT_LOGGED_IN_SYNC -> { - // User not logged in; take them to login screen dialog.show { iconAttr(R.attr.dialogSyncErrorIcon) @@ -59,7 +58,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_CONNECTION_ERROR -> { - // Connection error; allow user to retry or cancel dialog.show { iconAttr(R.attr.dialogSyncErrorIcon) @@ -73,7 +71,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_SYNC_CONFLICT_RESOLUTION -> { - // Sync conflict; allow user to cancel, or choose between local and remote versions dialog.show { iconAttr(R.attr.dialogSyncErrorIcon) @@ -91,7 +88,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_SYNC_CONFLICT_CONFIRM_KEEP_LOCAL -> { - // Confirmation before pushing local collection to server after sync conflict dialog.show { iconAttr(R.attr.dialogSyncErrorIcon) @@ -104,7 +100,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_SYNC_CONFLICT_CONFIRM_KEEP_REMOTE -> { - // Confirmation before overwriting local collection with server collection after sync conflict dialog.show { iconAttr(R.attr.dialogSyncErrorIcon) @@ -117,7 +112,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_SYNC_SANITY_ERROR -> { - // Sync sanity check error; allow user to cancel, or choose between local and remote versions dialog.show { positiveButton(R.string.sync_sanity_local) { @@ -132,7 +126,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_SYNC_SANITY_ERROR_CONFIRM_KEEP_LOCAL -> { - // Confirmation before pushing local collection to server after sanity check error dialog.show { positiveButton(R.string.dialog_positive_replace) { @@ -143,7 +136,6 @@ class SyncErrorDialog : AsyncDialogFragment() { } } DIALOG_SYNC_SANITY_ERROR_CONFIRM_KEEP_REMOTE -> { - // Confirmation before overwriting local collection with server collection after sanity check error dialog.show { positiveButton(R.string.dialog_positive_replace) { @@ -201,7 +193,9 @@ class SyncErrorDialog : AsyncDialogFragment() { get() { return if (requireArguments().getInt("dialogType") == DIALOG_USER_NOT_LOGGED_IN_SYNC) { resources.getString(R.string.sync_error) - } else title + } else { + title + } } private val message: String? @@ -229,7 +223,9 @@ class SyncErrorDialog : AsyncDialogFragment() { get() { return if (requireArguments().getInt("dialogType") == DIALOG_USER_NOT_LOGGED_IN_SYNC) { resources.getString(R.string.not_logged_in_title) - } else message + } else { + message + } } override val dialogHandlerMessage: Message diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialog.kt index af7983fbfe..848c823ed8 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialog.kt @@ -130,7 +130,6 @@ class CustomStudyDialog(private val collection: Collection, private val customSt customStudyListener?.showDialogFragment(d) } STUDY_TAGS -> { - /* * This is a special Dialog for CUSTOM STUDY, where instead of only collecting a * number, it is necessary to collect a list of tags. This case handles the creation @@ -139,13 +138,13 @@ class CustomStudyDialog(private val collection: Collection, private val customSt val currentDeck = requireArguments().getLong("did") val dialogFragment = TagsDialog().withArguments( - TagsDialog.DialogType.CUSTOM_STUDY_TAGS, ArrayList(), + TagsDialog.DialogType.CUSTOM_STUDY_TAGS, + ArrayList(), ArrayList(collection.tags.byDeck(currentDeck, true)) ) customStudyListener?.showDialogFragment(dialogFragment) } else -> { - // User asked for a standard custom study option val d = CustomStudyDialog(collection, customStudyListener) .withArguments( @@ -179,7 +178,8 @@ class CustomStudyDialog(private val collection: Collection, private val customSt */ // Input dialogs // Show input dialog for an individual custom study dialog - @SuppressLint("InflateParams") val v = requireActivity().layoutInflater.inflate(R.layout.styled_custom_study_details_dialog, null) + @SuppressLint("InflateParams") + val v = requireActivity().layoutInflater.inflate(R.layout.styled_custom_study_details_dialog, null) val textView1 = v.findViewById(R.id.custom_study_details_text1) val textView2 = v.findViewById(R.id.custom_study_details_text2) val editText = v.findViewById(R.id.custom_study_details_edittext2) @@ -234,9 +234,11 @@ class CustomStudyDialog(private val collection: Collection, private val customSt arrayOf( String.format( Locale.US, - "rated:%d:1", n + "rated:%d:1", + n ), - Consts.DYN_MAX_SIZE, Consts.DYN_RANDOM + Consts.DYN_MAX_SIZE, + Consts.DYN_RANDOM ), false ) @@ -247,9 +249,11 @@ class CustomStudyDialog(private val collection: Collection, private val customSt arrayOf( String.format( Locale.US, - "prop:due<=%d", n + "prop:due<=%d", + n ), - Consts.DYN_MAX_SIZE, Consts.DYN_DUE + Consts.DYN_MAX_SIZE, + Consts.DYN_DUE ), true ) @@ -263,7 +267,8 @@ class CustomStudyDialog(private val collection: Collection, private val customSt arrayOf( "is:new added:" + n, - Consts.DYN_MAX_SIZE, Consts.DYN_OLDEST + Consts.DYN_MAX_SIZE, + Consts.DYN_OLDEST ), false ) @@ -333,7 +338,8 @@ class CustomStudyDialog(private val collection: Collection, private val customSt JSONArray(), arrayOf( sb.toString(), - Consts.DYN_MAX_SIZE, Consts.DYN_RANDOM + Consts.DYN_MAX_SIZE, + Consts.DYN_RANDOM ), true ) @@ -375,8 +381,12 @@ class CustomStudyDialog(private val collection: Collection, private val customSt } EMPTY_SCHEDULE -> // Special custom study options to show when extending the daily study limits is not applicable return listOf( - STUDY_FORGOT, STUDY_AHEAD, STUDY_RANDOM, - STUDY_PREVIEW, STUDY_TAGS, DECK_OPTIONS + STUDY_FORGOT, + STUDY_AHEAD, + STUDY_RANDOM, + STUDY_PREVIEW, + STUDY_TAGS, + DECK_OPTIONS ) } } @@ -501,6 +511,7 @@ class CustomStudyDialog(private val collection: Collection, private val customSt */ interface ContextMenuAttribute where T : Enum<*> { val value: Int + @get:StringRes val stringResource: Int? } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialogFactory.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialogFactory.kt index b6a232d180..019490a925 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialogFactory.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/customstudy/CustomStudyDialogFactory.kt @@ -26,7 +26,9 @@ class CustomStudyDialogFactory(val collectionSupplier: Supplier, pri val cls = loadFragmentClass(classLoader, className) return if (cls == CustomStudyDialog::class.java) { newCustomStudyDialog() - } else super.instantiate(classLoader, className) + } else { + super.instantiate(classLoader, className) + } } fun newCustomStudyDialog(): CustomStudyDialog { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsArrayAdapter.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsArrayAdapter.kt index 028d11ba8f..67ec075704 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsArrayAdapter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsArrayAdapter.kt @@ -38,6 +38,7 @@ class TagsArrayAdapter(private val tags: TagsList, private val resources: Resour internal lateinit var node: TagTreeNode internal val mExpandButton: ImageButton = itemView.findViewById(R.id.id_expand_button) internal val mCheckBoxView: CheckBoxTriStates = itemView.findViewById(R.id.tags_dialog_tag_item_checkbox) + // TextView contains the displayed tag (only the last part), while the full tag is stored in TagTreeNode internal val mTextView: TextView = itemView.findViewById(R.id.tags_dialog_tag_item_text) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialog.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialog.kt index 031f4d8594..b8c089a11d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialog.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialog.kt @@ -136,7 +136,8 @@ class TagsDialog : AnalyticsDialogFragment { "filled as prefix properly. In other dialog types, long-clicking a tag behaves like a short click." ) override fun onCreateDialog(savedInstanceState: Bundle?): Dialog { - @SuppressLint("InflateParams") val tagsDialogView = LayoutInflater.from(activity).inflate(R.layout.tags_dialog, null, false) + @SuppressLint("InflateParams") + val tagsDialogView = LayoutInflater.from(activity).inflate(R.layout.tags_dialog, null, false) mTagsListRecyclerView = tagsDialogView.findViewById(R.id.tags_dialog_tags_list) val tagsListRecyclerView: RecyclerView? = mTagsListRecyclerView tagsListRecyclerView?.requestFocus() @@ -174,7 +175,8 @@ class TagsDialog : AnalyticsDialogFragment { .positiveButton(text = mPositiveText!!) { tagsDialogListener.onSelectedTags( mTags!!.copyOfCheckedTagList(), - mTags!!.copyOfIndeterminateTagList(), mSelectedOption + mTags!!.copyOfIndeterminateTagList(), + mSelectedOption ) } .negativeButton(R.string.dialog_cancel) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogFactory.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogFactory.kt index 4727e2396a..e2887ecee4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogFactory.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogFactory.kt @@ -23,7 +23,9 @@ class TagsDialogFactory(val listener: TagsDialogListener) : ExtendedFragmentFact val cls = loadFragmentClass(classLoader, className) return if (cls == TagsDialog::class.java) { newTagsDialog() - } else super.instantiate(classLoader, className) + } else { + super.instantiate(classLoader, className) + } } fun newTagsDialog(): TagsDialog { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogListener.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogListener.kt index 82aecb80a5..04017b0c69 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogListener.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsDialogListener.kt @@ -37,7 +37,8 @@ interface TagsDialogListener { fun onSelectedTags(selectedTags: List, indeterminateTags: List, option: Int) fun F.registerFragmentResultReceiver() where F : Fragment, F : TagsDialogListener { parentFragmentManager.setFragmentResultListener( - ON_SELECTED_TAGS_KEY, this, + ON_SELECTED_TAGS_KEY, + this, FragmentResultListener { _: String?, bundle: Bundle -> val selectedTags: List = bundle.getStringArrayList(ON_SELECTED_TAGS__SELECTED_TAGS)!! val indeterminateTags: List = bundle.getStringArrayList(ON_SELECTED_TAGS__INDETERMINATE_TAGS)!! diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsList.kt b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsList.kt index efc4d1deec..03bd69f097 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsList.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/dialogs/tags/TagsList.kt @@ -129,6 +129,7 @@ class TagsList constructor( addAncestors(tag) return true } + /** * Mark a tag as checked tag. * Optionally mark ancestors as indeterminate diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/export/ActivityExportingDelegate.kt b/AnkiDroid/src/main/java/com/ichi2/anki/export/ActivityExportingDelegate.kt index 27ba9396ce..e7a0f0dad4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/export/ActivityExportingDelegate.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/export/ActivityExportingDelegate.kt @@ -202,7 +202,7 @@ class ActivityExportingDelegate(private val activity: AnkiActivity, private val activity.getString( R.string.export_email_text, activity.getString(R.string.link_manual), - activity.getString(R.string.link_distributions), + activity.getString(R.string.link_distributions) ) ) .intent.apply { @@ -311,13 +311,15 @@ class ActivityExportingDelegate(private val activity: AnkiActivity, private val if (::mExportFileName.isInitialized && !mExportFileName.endsWith(".colpkg")) return AnkiDroidApp.getSharedPrefs(activity).edit { putLong( - LAST_SUCCESSFUL_EXPORT_AT_SECOND_KEY, TimeManager.time.intTime() + LAST_SUCCESSFUL_EXPORT_AT_SECOND_KEY, + TimeManager.time.intTime() ) } val col = collectionSupplier.get() AnkiDroidApp.getSharedPrefs(activity).edit { putLong( - LAST_SUCCESSFUL_EXPORT_AT_MOD_KEY, col.mod + LAST_SUCCESSFUL_EXPORT_AT_MOD_KEY, + col.mod ) } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/export/ExportDialogsFactory.kt b/AnkiDroid/src/main/java/com/ichi2/anki/export/ExportDialogsFactory.kt index 7e2cd83e08..5ee1831324 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/export/ExportDialogsFactory.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/export/ExportDialogsFactory.kt @@ -34,7 +34,9 @@ internal class ExportDialogsFactory( } return if (cls == ExportCompleteDialog::class.java) { newExportCompleteDialog() - } else super.instantiate(classLoader, className) + } else { + super.instantiate(classLoader, className) + } } fun newExportDialog(): ExportDialog { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/introduction/SetupCollectionFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/introduction/SetupCollectionFragment.kt index 4242ed6de0..7c8dc0f6a4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/introduction/SetupCollectionFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/introduction/SetupCollectionFragment.kt @@ -81,6 +81,7 @@ class SetupCollectionFragment : Fragment() { enum class CollectionSetupOption { /** Continues to the DeckPicker with a new collection */ DeckPickerWithNewCollection, + /** Syncs an existing profile from AnkiWeb */ SyncFromExistingAccount } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/TgzPackageExtract.kt b/AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/TgzPackageExtract.kt index 2a447e0b40..347a5eb4e4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/TgzPackageExtract.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/jsaddons/TgzPackageExtract.kt @@ -125,7 +125,6 @@ class TgzPackageExtract(private val context: Context) { */ @Throws(Exception::class) fun extractTarGzipToAddonFolder(tarballFile: File, addonsPackageDir: AddonsPackageDir) { - require(isGzip(tarballFile)) { context.getString(R.string.not_valid_js_addon, tarballFile.absolutePath) } try { @@ -285,7 +284,6 @@ class TgzPackageExtract(private val context: Context) { while (total + BUFFER <= TOO_BIG_SIZE && tarInputStream.read(data, 0, BUFFER).also { count = it } != -1 ) { - bufferOutput.write(data, 0, count) total += count diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/model/Directory.kt b/AnkiDroid/src/main/java/com/ichi2/anki/model/Directory.kt index 5359c38873..f578979a93 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/model/Directory.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/model/Directory.kt @@ -57,6 +57,7 @@ class Directory private constructor(val directory: File) { * Otherwise returns `null`. */ fun createInstance(path: String): Directory? = createInstance(File(path)) + /** * Returns a [Directory] from [file] if `Directory` precondition holds; i.e. [file] is an existing directory. * Otherwise returns `null`. @@ -67,6 +68,7 @@ class Directory private constructor(val directory: File) { } return Directory(file) } + /** Creates an instance. Only call it if [Directory] preconditions are known to be true */ fun createInstanceUnsafe(file: File) = Directory(file) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/model/DiskFile.kt b/AnkiDroid/src/main/java/com/ichi2/anki/model/DiskFile.kt index ab923255a8..2db3d299ef 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/model/DiskFile.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/model/DiskFile.kt @@ -30,6 +30,7 @@ import java.io.File class DiskFile private constructor(val file: File) { /** @see [File.renameTo] */ fun renameTo(destination: File): Boolean = file.renameTo(destination) + /** @see [FileUtils.contentEquals] */ fun contentEquals(f2: File): Boolean = FileUtils.contentEquals(file, f2) override fun toString(): String = file.canonicalPath diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/AudioView.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/AudioView.kt index 00894830cd..ab97a5ae0e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/AudioView.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/AudioView.kt @@ -352,7 +352,8 @@ class AudioView private constructor(context: Context, resPlay: Int, resPause: In CrashReportService.sendExceptionReport(e, "Unable to create recorder tool bar") showThemedToast( context, - context.getText(R.string.multimedia_editor_audio_view_create_failed).toString(), true + context.getText(R.string.multimedia_editor_audio_view_create_failed).toString(), + true ) null } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/MediaPlayer.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/MediaPlayer.kt index 97251266be..68d7b8066d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/MediaPlayer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/MediaPlayer.kt @@ -53,8 +53,9 @@ class MediaPlayer : override fun setDataSource(context: Context, uri: Uri) { super.setDataSource(context, uri) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource( @@ -64,44 +65,51 @@ class MediaPlayer : cookies: MutableList? ) { super.setDataSource(context, uri, headers, cookies) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource(context: Context, uri: Uri, headers: MutableMap?) { super.setDataSource(context, uri, headers) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource(path: String?) { super.setDataSource(path) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource(afd: AssetFileDescriptor) { super.setDataSource(afd) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource(fd: FileDescriptor?) { super.setDataSource(fd) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource(fd: FileDescriptor?, offset: Long, length: Long) { super.setDataSource(fd, offset, length) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun setDataSource(dataSource: MediaDataSource?) { super.setDataSource(dataSource) - if (state == IDLE) + if (state == IDLE) { state = INITIALIZED + } } override fun reset() { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/LoadPronunciationActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/LoadPronunciationActivity.kt index ee2def5a08..536d0ec971 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/LoadPronunciationActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/LoadPronunciationActivity.kt @@ -103,7 +103,8 @@ open class LoadPronunciationActivity : AnkiActivity(), DialogInterface.OnCancelL mLanguageLister = LanguageListerBeolingus() mSpinnerFrom = Spinner(this) val adapter = ArrayAdapter( - this, android.R.layout.simple_spinner_item, + this, + android.R.layout.simple_spinner_item, mLanguageLister.languages ) adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/MultimediaEditFieldActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/MultimediaEditFieldActivity.kt index 70dd3f2734..8b4b238b3d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/MultimediaEditFieldActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/MultimediaEditFieldActivity.kt @@ -102,7 +102,8 @@ class MultimediaEditFieldActivity : AnkiActivity(), OnRequestPermissionsResultCa if (field is AudioRecordingField && !Permissions.canRecordAudio(this)) { Timber.d("Requesting Audio Permissions") ActivityCompat.requestPermissions( - this, arrayOf(Manifest.permission.RECORD_AUDIO), + this, + arrayOf(Manifest.permission.RECORD_AUDIO), REQUEST_AUDIO_PERMISSION ) return true @@ -114,7 +115,8 @@ class MultimediaEditFieldActivity : AnkiActivity(), OnRequestPermissionsResultCa ) { Timber.d("Requesting Camera Permissions") ActivityCompat.requestPermissions( - this, arrayOf(Manifest.permission.CAMERA), + this, + arrayOf(Manifest.permission.CAMERA), REQUEST_CAMERA_PERMISSION ) return true diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/PickStringDialogFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/PickStringDialogFragment.kt index 84b0fbdb47..5e2dc63c11 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/PickStringDialogFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/activity/PickStringDialogFragment.kt @@ -44,7 +44,8 @@ class PickStringDialogFragment : DialogFragment() { builder.setTitle(mTitle) val adapter = ArrayAdapter( requireActivity(), - R.layout.simple_list_item_1, mPossibleChoices!! + R.layout.simple_list_item_1, + mPossibleChoices!! ) builder.setAdapter(adapter, mListener) return builder.create() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicImageFieldController.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicImageFieldController.kt index c4e4b33c64..c89029bca2 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicImageFieldController.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicImageFieldController.kt @@ -96,6 +96,7 @@ class BasicImageFieldController : FieldControllerBase(), IFieldController { return min(height * 0.4, width * 0.6).toInt() } private lateinit var cropImageRequest: ActivityResultLauncher + @VisibleForTesting lateinit var registryToUse: ActivityResultRegistry diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicMediaClipFieldController.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicMediaClipFieldController.kt index 9e51ec5a29..601e07629c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicMediaClipFieldController.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/BasicMediaClipFieldController.kt @@ -118,7 +118,8 @@ class BasicMediaClipFieldController : FieldControllerBase(), IFieldController { if (cursor == null) { showThemedToast( AnkiDroidApp.instance.applicationContext, - AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), true + AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), + true ) return } @@ -137,7 +138,8 @@ class BasicMediaClipFieldController : FieldControllerBase(), IFieldController { CrashReportService.sendExceptionReport(e, "Media Clip addition failed. Name " + mediaClipFullName + " / cursor mime type column type " + cursor.getType(2)) showThemedToast( AnkiDroidApp.instance.applicationContext, - AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), true + AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), + true ) return } @@ -154,7 +156,8 @@ class BasicMediaClipFieldController : FieldControllerBase(), IFieldController { CrashReportService.sendExceptionReport(e, "handleMediaSelection:tempFile") showThemedToast( AnkiDroidApp.instance.applicationContext, - AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), true + AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), + true ) return } @@ -175,7 +178,8 @@ class BasicMediaClipFieldController : FieldControllerBase(), IFieldController { CrashReportService.sendExceptionReport(e, "handleMediaSelection:copyFromProvider") showThemedToast( AnkiDroidApp.instance.applicationContext, - AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), true + AnkiDroidApp.instance.getString(R.string.multimedia_editor_something_wrong), + true ) } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/ImageField.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/ImageField.kt index a3c5adfbc7..729ceca589 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/ImageField.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/fields/ImageField.kt @@ -72,6 +72,7 @@ class ImageField : FieldBase(), IField { companion object { private const val serialVersionUID = 4431611060655809687L + @VisibleForTesting fun formatImageFileName(file: File): String { return if (file.exists()) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/impl/MultimediaEditableNote.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/impl/MultimediaEditableNote.kt index 0e8d5fc290..63e6a4b86e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/impl/MultimediaEditableNote.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/impl/MultimediaEditableNote.kt @@ -66,7 +66,9 @@ class MultimediaEditableNote : IMultimediaEditableNote { override fun getField(index: Int): IField? { return if (index in 0 until numberOfFields) { fieldsPrivate[index] - } else null + } else { + null + } } override fun setField(index: Int, field: IField?): Boolean { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/language/LanguageListerBase.kt b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/language/LanguageListerBase.kt index 1c955456e7..db55146224 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/language/LanguageListerBase.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/multimediacard/language/LanguageListerBase.kt @@ -41,7 +41,9 @@ open class LanguageListerBase { fun getCodeFor(Language: String): String? { return if (mLanguageMap.containsKey(Language)) { mLanguageMap[Language] - } else null + } else { + null + } } val languages: ArrayList diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/noteeditor/Toolbar.kt b/AnkiDroid/src/main/java/com/ichi2/anki/noteeditor/Toolbar.kt index c9ffbe3053..5ea073209c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/noteeditor/Toolbar.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/noteeditor/Toolbar.kt @@ -64,6 +64,7 @@ class Toolbar : FrameLayout { var formatListener: TextFormatListener? = null private val mToolbar: LinearLayout private val mToolbarLayout: LinearLayout + /** A list of buttons, typically user-defined which modify text + selection */ private val mCustomButtons: MutableList = ArrayList() private val mRows: MutableList = ArrayList() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/notetype/ManageNotetypes.kt b/AnkiDroid/src/main/java/com/ichi2/anki/notetype/ManageNotetypes.kt index 7342e46b3f..463afb8615 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/notetype/ManageNotetypes.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/notetype/ManageNotetypes.kt @@ -59,13 +59,13 @@ class ManageNotetypes : AnkiActivity() { launchForChanges( mapOf( "title" to it.name, - "noteTypeID" to it.id, + "noteTypeID" to it.id ) ) }, onEditCards = { launchForChanges(mapOf("modelId" to it.id)) }, onRename = ::renameNotetype, - onDelete = ::deleteNotetype, + onDelete = ::deleteNotetype ) } private val outsideChangesLauncher = @@ -227,7 +227,7 @@ class ManageNotetypes : AnkiActivity() { optionsToDisplay.map { String.format( if (it.isStandard) addPrefixStr else clonePrefixStr, - it.name, + it.name ) } ).apply { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeAdapter.kt b/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeAdapter.kt index a4cd75f8ec..871c631ee0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeAdapter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeAdapter.kt @@ -46,7 +46,7 @@ internal class NotetypesAdapter( private val onShowFields: (NoteTypeUiModel) -> Unit, private val onEditCards: (NoteTypeUiModel) -> Unit, private val onRename: (NoteTypeUiModel) -> Unit, - private val onDelete: (NoteTypeUiModel) -> Unit, + private val onDelete: (NoteTypeUiModel) -> Unit ) : ListAdapter(notetypeNamesAndCountDiff) { private val layoutInflater = LayoutInflater.from(context) @@ -56,7 +56,7 @@ internal class NotetypesAdapter( onDelete = onDelete, onRename = onRename, onEditCards = onEditCards, - onShowFields = onShowFields, + onShowFields = onShowFields ) } @@ -70,7 +70,7 @@ internal class NotetypeViewHolder( onShowFields: (NoteTypeUiModel) -> Unit, onEditCards: (NoteTypeUiModel) -> Unit, onRename: (NoteTypeUiModel) -> Unit, - onDelete: (NoteTypeUiModel) -> Unit, + onDelete: (NoteTypeUiModel) -> Unit ) : RecyclerView.ViewHolder(rowView) { val name: TextView = rowView.findViewById(R.id.note_name) val useCount: TextView = rowView.findViewById(R.id.note_use_count) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeUiModel.kt b/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeUiModel.kt index 9b18a03d3c..6303072c3c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeUiModel.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/notetype/NotetypeUiModel.kt @@ -25,7 +25,7 @@ import anki.notetypes.NotetypeNameIdUseCount internal data class NoteTypeUiModel( val id: Long, val name: String, - val useCount: Int, + val useCount: Int ) internal fun NotetypeNameIdUseCount.toUiModel(): NoteTypeUiModel = diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/pages/PagesActivity.kt b/AnkiDroid/src/main/java/com/ichi2/anki/pages/PagesActivity.kt index 04d93fdc38..95985f32ee 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/pages/PagesActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/pages/PagesActivity.kt @@ -84,6 +84,7 @@ class PagesActivity : AnkiActivity() { * as arguments of the [PageFragment] that will be opened */ const val EXTRA_PAGE_ARGS = "pageArgs" + /** * Extra key of [PagesActivity]'s intent that must be included and * hold the name of an [Anki HTML page](https://github.com/ankitects/anki/tree/main/ts) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/CustomSyncServerSettingsFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/CustomSyncServerSettingsFragment.kt index bebc3ee129..40cee911c8 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/CustomSyncServerSettingsFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/CustomSyncServerSettingsFragment.kt @@ -31,7 +31,7 @@ class CustomSyncServerSettingsFragment : SettingsFragment() { override fun initSubscreen() { listOf( - R.string.custom_sync_server_collection_url_key, + R.string.custom_sync_server_collection_url_key ).forEach { requirePreference(it).continuousValidator = VersatileTextPreference.Validator { value -> diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/NotificationsSettingsFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/NotificationsSettingsFragment.kt index 999a448317..191cb349d0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/NotificationsSettingsFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/NotificationsSettingsFragment.kt @@ -53,8 +53,10 @@ class NotificationsSettingsFragment : SettingsFragment() { scheduleNotification(TimeManager.time, requireContext()) } else { val intent = CompatHelper.compat.getImmutableBroadcastIntent( - requireContext(), 0, - Intent(requireContext(), NotificationService::class.java), 0 + requireContext(), + 0, + Intent(requireContext(), NotificationService::class.java), + 0 ) val alarmManager = requireActivity().getSystemService(ALARM_SERVICE) as AlarmManager alarmManager.cancel(intent) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/Preferences.kt b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/Preferences.kt index 62134e0b0b..c5ed162f5e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/preferences/Preferences.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/preferences/Preferences.kt @@ -123,7 +123,8 @@ class Preferences : pref: Preference ): Boolean { val fragment = supportFragmentManager.fragmentFactory.instantiate( - classLoader, pref.fragment!! + classLoader, + pref.fragment!! ) fragment.arguments = pref.extras supportFragmentManager.commit { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt b/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt index 12f0e3ea95..e9c00c00af 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/provider/CardContentProvider.kt @@ -206,7 +206,6 @@ class CardContentProvider : ContentProvider() { col.db.query(sql, *(selectionArgs ?: arrayOf())) } NOTES -> { - /* Search for notes using the libanki browser syntax */ val proj = sanitizeNoteProjection(projection) val query = selection ?: "" @@ -220,7 +219,6 @@ class CardContentProvider : ContentProvider() { } } NOTES_ID -> { - /* Direct access note with specific ID*/ val noteId = uri.pathSegments[1] val proj = sanitizeNoteProjection(projection) @@ -260,7 +258,6 @@ class CardContentProvider : ContentProvider() { rv } MODELS_ID_TEMPLATES -> { - /* Direct access model templates */ val models = col.models val currentModel = models.get(getModelIdFromUri(uri, col)) @@ -280,7 +277,6 @@ class CardContentProvider : ContentProvider() { rv } MODELS_ID_TEMPLATES_ID -> { - /* Direct access model template with specific ID */ val models = col.models val ord = uri.lastPathSegment!!.toInt() @@ -412,7 +408,6 @@ class CardContentProvider : ContentProvider() { when (match) { NOTES_V2, NOTES -> throw IllegalArgumentException("Not possible to update notes directly (only through data URI)") NOTES_ID -> { - /* Direct access note details */ val currentNote = getNoteFromUri(uri, col) @@ -781,7 +776,6 @@ class CardContentProvider : ContentProvider() { // Find out what data the user is requesting return when (sUriMatcher.match(uri)) { NOTES -> { - /* Insert new note with specified fields and tags */ val modelId = values!!.getAsLong(FlashCardsContract.Note.MID) @@ -1265,7 +1259,9 @@ class CardContentProvider : ContentProvider() { private fun hasReadWritePermission(): Boolean { return if (BuildConfig.DEBUG) { // Allow self-calling of the provider only in debug builds (e.g. for unit tests) context!!.checkCallingOrSelfPermission(FlashCardsContract.READ_WRITE_PERMISSION) == PackageManager.PERMISSION_GRANTED - } else context!!.checkCallingPermission(FlashCardsContract.READ_WRITE_PERMISSION) == PackageManager.PERMISSION_GRANTED + } else { + context!!.checkCallingPermission(FlashCardsContract.READ_WRITE_PERMISSION) == PackageManager.PERMISSION_GRANTED + } } /** Returns true if the calling package is known to be "rogue" and should be blocked. @@ -1276,7 +1272,9 @@ class CardContentProvider : ContentProvider() { val callingPi = pm.getPackageInfoCompat(callingPackage!!, PackageInfoFlagsCompat.of(PackageManager.GET_PERMISSIONS.toLong())) ?: return false if (callingPi.requestedPermissions == null) { false - } else !listOf(*callingPi.requestedPermissions).contains(FlashCardsContract.READ_WRITE_PERMISSION) + } else { + !listOf(*callingPi.requestedPermissions).contains(FlashCardsContract.READ_WRITE_PERMISSION) + } } catch (e: PackageManager.NameNotFoundException) { Timber.w(e) false diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/AnswerButtons.kt b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/AnswerButtons.kt index 2b60ca5527..58152be1cf 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/AnswerButtons.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/AnswerButtons.kt @@ -54,6 +54,7 @@ enum class AnswerButtons { * * * See: [Anki - Hard/good interval is longer than good/easy](https://faqs.ankiweb.net/hard-good-interval-longer-than-good-easy.html) */ HARD, + /** * In Step-Mode, Good moves to the next step, or performs a regular graduation * diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/FullScreenMode.kt b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/FullScreenMode.kt index c972b3c084..13922d2c1b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/FullScreenMode.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/FullScreenMode.kt @@ -24,8 +24,10 @@ enum class FullScreenMode(private val prefValue: String) { /** Display both navigation and buttons (default) */ BUTTONS_AND_MENU("0"), + /** Remove the menu bar, keeps answer button. */ BUTTONS_ONLY("1"), + /** Remove both menu bar and buttons. Can only be set if gesture is on. */ FULLSCREEN_ALL_GONE("2"); diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt index 03929ed5be..6cd4645223 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/GestureMapper.kt @@ -86,9 +86,11 @@ class GestureMapper { fun gesture(height: Int, width: Int, posX: Float, posY: Float): Gesture? { return if (width == 0 || height == 0) { null - } else when (tapGestureMode) { - TapGestureMode.FOUR_POINT -> fromTap(height, width, posX, posY) - TapGestureMode.NINE_POINT -> fromTapCorners(height, width, posX, posY) + } else { + when (tapGestureMode) { + TapGestureMode.FOUR_POINT -> fromTap(height, width, posX, posY) + TapGestureMode.NINE_POINT -> fromTapCorners(height, width, posX, posY) + } } } @@ -159,7 +161,9 @@ class GestureMapper { } return if (valueFloor < 1) { TriState.LOW - } else TriState.MID + } else { + TriState.MID + } } } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/MappableBinding.kt b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/MappableBinding.kt index a73e2c2b79..de85e01692 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/MappableBinding.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/MappableBinding.kt @@ -71,9 +71,11 @@ class MappableBinding(val binding: Binding, private val screen: Screen) { // one is null return if (keys == null || thisKeys == null) { false - } else (thisKeys.shiftMatches(true) == keys.shiftMatches(true) || thisKeys.shiftMatches(false) == keys.shiftMatches(false)) && - (thisKeys.ctrlMatches(true) == keys.ctrlMatches(true) || thisKeys.ctrlMatches(false) == keys.ctrlMatches(false)) && - (thisKeys.altMatches(true) == keys.altMatches(true) || thisKeys.altMatches(false) == keys.altMatches(false)) + } else { + (thisKeys.shiftMatches(true) == keys.shiftMatches(true) || thisKeys.shiftMatches(false) == keys.shiftMatches(false)) && + (thisKeys.ctrlMatches(true) == keys.ctrlMatches(true) || thisKeys.ctrlMatches(false) == keys.ctrlMatches(false)) && + (thisKeys.altMatches(true) == keys.altMatches(true) || thisKeys.altMatches(false) == keys.altMatches(false)) + } // Perf: Could get a slight improvement if we check that both instances are not subclasses diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/PeripheralKeymap.kt b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/PeripheralKeymap.kt index 1ed8593b43..ddd8fa6a78 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/PeripheralKeymap.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/reviewer/PeripheralKeymap.kt @@ -55,7 +55,9 @@ class PeripheralKeymap(reviewerUi: ReviewerUi, commandProcessor: ViewerCommand.C fun onKeyDown(keyCode: Int, event: KeyEvent): Boolean { return if (!mHasSetup || event.repeatCount > 0) { false - } else mKeyMap.onKeyUp(keyCode, event) + } else { + mKeyMap.onKeyUp(keyCode, event) + } } @Suppress("UNUSED_PARAMETER") diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt index fdcd054526..9898dd86ac 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/NoteService.kt @@ -176,7 +176,9 @@ object NoteService { fun convertToHtmlNewline(fieldData: String, replaceNewlines: Boolean): String { return if (!replaceNewlines) { fieldData - } else fieldData.replace(FieldEditText.NEW_LINE, "
") + } else { + fieldData.replace(FieldEditText.NEW_LINE, "
") + } } suspend fun toggleMark(note: Note) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/PreferenceUpgradeService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/PreferenceUpgradeService.kt index 6865504f2f..a6174a3eac 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/PreferenceUpgradeService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/PreferenceUpgradeService.kt @@ -265,7 +265,7 @@ object PreferenceUpgradeService { Pair(37, ViewerCommand.TOGGLE_WHITEBOARD), Pair(41, ViewerCommand.SHOW_HINT), Pair(42, ViewerCommand.SHOW_ALL_HINTS), - Pair(43, ViewerCommand.ADD_NOTE), + Pair(43, ViewerCommand.ADD_NOTE) ) override fun upgrade(preferences: SharedPreferences) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SchedulerService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SchedulerService.kt index 555f62e7e2..8dceae123b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SchedulerService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SchedulerService.kt @@ -44,6 +44,7 @@ class SchedulerService { */ class NextCard(private val card: Card?, val result: T) { fun hasNoMoreCards(): Boolean = card == null + /** Returns the next scheduled card * Only call if noMoreCards returns false */ fun nextScheduledCard(): Card = card!! @@ -188,7 +189,11 @@ class SchedulerService { } } - class UndoRepositionRescheduleResetCards(@StringRes @UndoNameId undoNameId: Int, private val cardsCopied: Array) : UndoAction(undoNameId) { + class UndoRepositionRescheduleResetCards( + @StringRes @UndoNameId + undoNameId: Int, + private val cardsCopied: Array + ) : UndoAction(undoNameId) { override fun undo(col: AnkiCollection): Card? { Timber.i("Undoing action of type %s on %d cards", javaClass, cardsCopied.size) for (card in cardsCopied) { @@ -221,7 +226,12 @@ class SchedulerService { } } - fun AnkiMethod<*>.rescheduleRepositionReset(cards: Array, @UndoNameId @StringRes undoNameId: Int, actualActualTask: () -> Unit): Computation> { + fun AnkiMethod<*>.rescheduleRepositionReset( + cards: Array, + @UndoNameId @StringRes + undoNameId: Int, + actualActualTask: () -> Unit + ): Computation> { val sched = col.sched // collect undo information, sensitive to memory pressure, same for all 3 cases try { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/ScopedStorageService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/ScopedStorageService.kt index fcffe2ce21..e7218fe222 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/ScopedStorageService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/ScopedStorageService.kt @@ -244,7 +244,9 @@ object ScopedStorageService { val internalScopedDir = File(internalScopedDirPath).canonicalFile Timber.i( "isLegacyStorage(): current dir: %s\nscoped external dirs: %s\nscoped internal dir: %s", - currentDirPath, externalScopedDirs.joinToString(", "), internalScopedDirPath + currentDirPath, + externalScopedDirs.joinToString(", "), + internalScopedDirPath ) // Loop to check if the current AnkiDroid directory or any of its parents are the same as the root directories diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SearchService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SearchService.kt index 77d5039f2f..2e1b52c438 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SearchService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/SearchService.kt @@ -30,6 +30,7 @@ class SearchService { @get:JvmName("hasResult") val hasResult = result != null + @get:JvmName("hasError") val hasError = error != null fun size() = result?.size ?: 0 diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/MoveConflictedFile.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/MoveConflictedFile.kt index 4effca3914..ec6fefb655 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/MoveConflictedFile.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/MoveConflictedFile.kt @@ -49,7 +49,6 @@ class MoveConflictedFile private constructor( ) : Operation() { override fun execute(context: MigrationContext): List { - // create the "conflict" folder if it didn't exist, and the relative path to the file // example: "AnkiDroid/conflict/collection.media/subfolder" createDirectory(proposedDestinationFile.parentFile!!) @@ -88,6 +87,7 @@ class MoveConflictedFile private constructor( companion object { const val CONFLICT_DIRECTORY = "conflict" + /** * @param sourceFile The file to move from * @param destinationTopLevel The top level directory to move to (non-relative path). "/storage/emulated/0/AnkiDroid/" @@ -99,7 +99,6 @@ class MoveConflictedFile private constructor( destinationTopLevel: Directory, sourceRelativePath: RelativeFilePath ): MoveConflictedFile { - // we add /conflict/ to the path inside this method. If this already occurred, something was wrong if (sourceRelativePath.path.firstOrNull() == CONFLICT_DIRECTORY) { throw IllegalStateException("can't move from a root path of 'conflict': $sourceRelativePath") diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/MigrateUserData.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/MigrateUserData.kt index 30341d77ca..e1fdba07a1 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/MigrateUserData.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/MigrateUserData.kt @@ -40,6 +40,7 @@ fun NumberOfBytes.toKB(): Int { fun NumberOfBytes.toMB(): Int { return this.toKB() / 1024 } + /** * Function that is executed when one file is migrated, with the number of bytes moved. * Called with 0 when the file is already present in destination (i.e. successful move with no byte copied) @@ -167,6 +168,7 @@ open class MigrateUserData protected constructor(val source: Directory, val dest * @param transferred The number of bytes of the transferred file */ abstract fun reportProgress(transferred: NumberOfBytes) + /** * Whether [File#renameTo] should be attempted for files. * @@ -489,7 +491,6 @@ open class MigrateUserData protected constructor(val source: Directory, val dest * @throws RuntimeException Various other failings if only a single exception was thrown */ fun migrateFiles(progressListener: MigrationProgressListener): Boolean { - val context = initializeContext(progressListener) // define the function here, so we can execute it on retry diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/UserDataMigrationPreferences.kt b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/UserDataMigrationPreferences.kt index ceea7e43a1..1fb5e86e13 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/UserDataMigrationPreferences.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/servicelayer/scopedstorage/migrateuserdata/UserDataMigrationPreferences.kt @@ -34,6 +34,7 @@ class UserDataMigrationPreferences private constructor(val source: String, val d val migrationInProgress = source.isNotEmpty() val sourceFile get() = File(source) val destinationFile get() = File(destination) + // Throws if migration can't occur as expected. fun check() { // ensure that both are set, or both are empty diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/services/MigrationService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/services/MigrationService.kt index 8dbad86dc4..66aa9a3e9f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/services/MigrationService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/services/MigrationService.kt @@ -144,7 +144,8 @@ class MigrationService : Service() { notificationBuilder.setContentText( context.resources.getString( R.string.migration_transferred_size, - currentProgress.toMB().toFloat(), sourceSize.toMB().toFloat() + currentProgress.toMB().toFloat(), + sourceSize.toMB().toFloat() ) ) manager.notify(id, notificationBuilder.build()) @@ -216,7 +217,7 @@ class MigrationService : Service() { } private fun getRemainingTransferSize( - task: MigrateUserData, + task: MigrateUserData ): NumberOfBytes? { return try { val ignoredFiles = MigrateEssentialFiles.iterateEssentialFiles(task.source) + diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/services/NotificationService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/services/NotificationService.kt index 67d9a9b60c..c065cdcfe4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/services/NotificationService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/services/NotificationService.kt @@ -69,7 +69,9 @@ class NotificationService : BroadcastReceiver() { val resultIntent = Intent(context, DeckPicker::class.java) resultIntent.flags = Intent.FLAG_ACTIVITY_NEW_TASK or Intent.FLAG_ACTIVITY_CLEAR_TASK val resultPendingIntent = CompatHelper.compat.getImmutableActivityIntent( - context, 0, resultIntent, + context, + 0, + resultIntent, PendingIntent.FLAG_UPDATE_CURRENT ) builder.setContentIntent(resultPendingIntent) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/services/ReminderService.kt b/AnkiDroid/src/main/java/com/ichi2/anki/services/ReminderService.kt index 60c22a8ec9..8dbbd06f88 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/services/ReminderService.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/services/ReminderService.kt @@ -134,7 +134,6 @@ class ReminderService : BroadcastReceiver() { // getDeckOptionDue information, will recur one time to workaround collection close if recur is true private fun getDeckOptionDue(col: Collection, dConfId: Long, recur: Boolean): List? { - // Avoid crashes if the deck option group is deleted while we // are working if (col.dbClosed || col.decks.getConf(dConfId) == null) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/snackbar/SnackbarPackageWorkaround.kt b/AnkiDroid/src/main/java/com/ichi2/anki/snackbar/SnackbarPackageWorkaround.kt index 39aa3979bc..5d27484b92 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/snackbar/SnackbarPackageWorkaround.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/snackbar/SnackbarPackageWorkaround.kt @@ -13,6 +13,7 @@ */ @file:Suppress("PackageDirectoryMismatch") + package com.google.android.material.snackbar /* diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/stats/AnkiStatsTaskHandler.kt b/AnkiDroid/src/main/java/com/ichi2/anki/stats/AnkiStatsTaskHandler.kt index 06c6c7339e..d07a9b6c65 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/stats/AnkiStatsTaskHandler.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/stats/AnkiStatsTaskHandler.kt @@ -52,7 +52,7 @@ class AnkiStatsTaskHandler private constructor( suspend fun createChart( chartType: ChartType, progressBar: ProgressBar, - chartView: ChartView, + chartView: ChartView ) = withContext(defaultDispatcher) { mutex.withLock { val plotSheet = if (!this.isActive) { @@ -61,8 +61,10 @@ class AnkiStatsTaskHandler private constructor( } else { Timber.d("Starting CreateChartTask, type: %s", chartType.name) val chartBuilder = ChartBuilder( - chartView, collectionData, - mDeckId, chartType + chartView, + collectionData, + mDeckId, + chartType ) chartBuilder.renderChart(statType) } @@ -114,6 +116,7 @@ class AnkiStatsTaskHandler private constructor( var instance: AnkiStatsTaskHandler? = null private set private val mutex = Mutex() + @Synchronized fun getInstance( collection: Collection, diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartBuilder.kt b/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartBuilder.kt index 4da61bad65..070547a8f4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartBuilder.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartBuilder.kt @@ -323,7 +323,6 @@ class ChartBuilder(private val chartView: ChartView, private val collectionData: } fun ticsCalc(pixelDistance: Int, field: RectangleWrap, deltaRange: Double): Double { - // Make approximation of number of ticks based on desired number of pixels per tick val numTicks = (field.height / pixelDistance).toDouble() diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartView.kt b/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartView.kt index 4541aefcbc..95fb51ea55 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartView.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/stats/ChartView.kt @@ -32,6 +32,7 @@ class ChartView : View { private var mFragment: ChartFragment? = null private var mPlotSheet: PlotSheet? = null private var mDataIsSet = false + @KotlinCleanup("is this really needed?") private val drawingBoundsRect = Rect() private val paint = Paint(Paint.LINEAR_TEXT_FLAG) diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/stats/OverviewStatsBuilder.kt b/AnkiDroid/src/main/java/com/ichi2/anki/stats/OverviewStatsBuilder.kt index 48ff6da444..94b4744fec 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/stats/OverviewStatsBuilder.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/stats/OverviewStatsBuilder.kt @@ -65,7 +65,9 @@ class OverviewStatsBuilder(private val webView: WebView, private val col: Collec val percentage: Double get() = if (correct == 0) { 0.0 - } else correct.toDouble() / total.toDouble() * 100.0 + } else { + correct.toDouble() / total.toDouble() * 100.0 + } } } @@ -98,7 +100,8 @@ class OverviewStatsBuilder(private val webView: WebView, private val col: Collec val daysStudied = res.getString( stats_overview_days_studied, (oStats.daysStudied.toFloat() / oStats.allDays.toFloat() * 100).toInt(), - oStats.daysStudied, oStats.allDays + oStats.daysStudied, + oStats.allDays ) // FORECAST @@ -192,7 +195,9 @@ class OverviewStatsBuilder(private val webView: WebView, private val col: Collec stringBuilder.append( res.getQuantityString( com.ichi2.anki.R.plurals.stats_today_cards, - todayStats[CARDS_INDEX], todayStats[CARDS_INDEX], span + todayStats[CARDS_INDEX], + todayStats[CARDS_INDEX], + span ) ) stringBuilder.append("
") diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/NoteTypeSpinnerUtils.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/NoteTypeSpinnerUtils.kt index c0685f0429..89d199930a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/NoteTypeSpinnerUtils.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/NoteTypeSpinnerUtils.kt @@ -30,7 +30,7 @@ fun setupNoteTypeSpinner(context: Context, noteTypeSpinner: Spinner, col: Collec noteTypeSpinner.adapter = ArrayAdapter( context, android.R.layout.simple_spinner_dropdown_item, - modelNames, + modelNames ).apply { // The resource passed to the constructor is normally used for both the spinner view // and the dropdown list. This keeps the former and overrides the latter. diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/dialogs/tools/AsyncDialogs.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/dialogs/tools/AsyncDialogs.kt index f8683cc518..b011d10857 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/dialogs/tools/AsyncDialogs.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/dialogs/tools/AsyncDialogs.kt @@ -55,7 +55,7 @@ open class AsyncDialogBuilder(private val alertDialogBuilder: AlertDialog.Builde fun setMultiChoiceItems( items: List, checkedItems: CheckedItems, - disablePositiveButtonIfNoItemsChosen: Boolean = true, + disablePositiveButtonIfNoItemsChosen: Boolean = true ) { this.checkedItems = when (checkedItems) { is CheckedItems.All -> BooleanArray(items.size) { true } @@ -92,10 +92,13 @@ open class AsyncDialogBuilder(private val alertDialogBuilder: AlertDialog.Builde class CompoundDialogBuilder(private val alertDialogBuilder: AlertDialog.Builder) : AsyncDialogBuilder(alertDialogBuilder) { /** @see AlertDialog.Builder.setTitle */ fun setTitle(@StringRes titleId: Int): AlertDialog.Builder = alertDialogBuilder.setTitle(titleId) + /** @see AlertDialog.Builder.setTitle */ fun setTitle(title: CharSequence): AlertDialog.Builder = alertDialogBuilder.setTitle(title) + /** @see AlertDialog.Builder.setMessage */ fun setMessage(@StringRes messageId: Int): AlertDialog.Builder = alertDialogBuilder.setMessage(messageId) + /** @see AlertDialog.Builder.setMessage */ fun setMessage(message: CharSequence): AlertDialog.Builder = alertDialogBuilder.setMessage(message) } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/preferences/screens/BackupLimitsPresenter.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/preferences/screens/BackupLimitsPresenter.kt index e5125d891c..3dd2e64d13 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/preferences/screens/BackupLimitsPresenter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/preferences/screens/BackupLimitsPresenter.kt @@ -128,7 +128,7 @@ class BackupLimitsPresenter(private val fragment: PreferenceFragmentCompat) : De minutesBetweenAutomaticBackupsPreference, dailyBackupsToKeepPreference, weeklyBackupsToKeepPreference, - monthlyBackupsToKeepPreference, + monthlyBackupsToKeepPreference ).forEach { preference -> preference.summaryProvider = Preference.SummaryProvider { when (viewModel.flowOfState.value) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/FileUtils.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/FileUtils.kt index 56926e51e5..dbe64339c9 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/FileUtils.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/FileUtils.kt @@ -182,8 +182,9 @@ class CanNotWriteToOrCreateFileException(val file: File) : Exception() { } suspend fun CollectionDirectoryProvider.ensureCanWriteToOrCreateCollectionDirectory() { - if (!withContext(Dispatchers.IO) { collectionDirectory.canWriteToOrCreate() }) + if (!withContext(Dispatchers.IO) { collectionDirectory.canWriteToOrCreate() }) { throw CanNotWriteToOrCreateFileException(collectionDirectory) + } } suspend fun CollectionDirectoryProvider.collectionDirectoryExists() = diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/ManageSpaceFragment.kt b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/ManageSpaceFragment.kt index b65483796a..bad4b43e87 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/ManageSpaceFragment.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/ui/windows/managespace/ManageSpaceFragment.kt @@ -209,7 +209,7 @@ class ManageSpaceFragment : SettingsFragment() { viewModel.flowOfDeleteUnusedMediaSize to deleteUnusedMediaPreference, viewModel.flowOfDeleteCollectionSize to deleteCollectionPreference, viewModel.flowOfDeleteEverythingSize to deleteEverythingPreference, - viewModel.flowOfDeleteBackupsSize to deleteBackupsPreference, + viewModel.flowOfDeleteBackupsSize to deleteBackupsPreference ).forEach { (flowOfSize, preference) -> lifecycleScope.launch { flowOfSize.collect { size -> preference.setWidgetTextBy(size) } } } @@ -317,6 +317,7 @@ class ManageSpaceFragment : SettingsFragment() { /************************************* Delete everything **************************************/ @StringRes private var deleteEverythingDialogTitle: Int = 0 + @StringRes private var deleteEverythingDialogMessage: Int = 0 private fun adjustDeleteEverythingStringsDependingOnCollectionLocation(preference: Preference) { diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/web/PreferenceBackedHostNum.kt b/AnkiDroid/src/main/java/com/ichi2/anki/web/PreferenceBackedHostNum.kt index 5572c09cb3..904aa4416f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/web/PreferenceBackedHostNum.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/web/PreferenceBackedHostNum.kt @@ -62,11 +62,13 @@ class PreferenceBackedHostNum(hostNum: Int?, private val preferences: SharedPref private fun convertFromPreferenceValue(hostNum: String?): Int? { return if (hostNum == null) { getDefaultHostNum() - } else try { - hostNum.toInt() - } catch (e: Exception) { - Timber.w(e) - getDefaultHostNum() + } else { + try { + hostNum.toInt() + } catch (e: Exception) { + Timber.w(e) + getDefaultHostNum() + } } } } diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/widgets/DeckAdapter.kt b/AnkiDroid/src/main/java/com/ichi2/anki/widgets/DeckAdapter.kt index 3f211a2739..ab8f57e003 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/widgets/DeckAdapter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/widgets/DeckAdapter.kt @@ -41,6 +41,7 @@ import java.util.* @KotlinCleanup("lots to do") class DeckAdapter(private val layoutInflater: LayoutInflater, context: Context) : RecyclerView.Adapter(), Filterable { private val mDeckList: MutableList> + /** A subset of mDeckList (currently displayed) */ private val mCurrentDeckList: MutableList> = ArrayList() private val mZeroCountColor: Int @@ -356,7 +357,6 @@ class DeckAdapter(private val layoutInflater: LayoutInflater, context: Context) } private fun filterDeckInternal(filterPattern: String, root: TreeNode): TreeNode? { - // If a deck contains the string, then all its children are valid if (containsFilterString(filterPattern, root.value)) { return root diff --git a/AnkiDroid/src/main/java/com/ichi2/anki/workarounds/AppLoadedFromBackupWorkaround.kt b/AnkiDroid/src/main/java/com/ichi2/anki/workarounds/AppLoadedFromBackupWorkaround.kt index 0904f253ef..c5de1ab15a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/anki/workarounds/AppLoadedFromBackupWorkaround.kt +++ b/AnkiDroid/src/main/java/com/ichi2/anki/workarounds/AppLoadedFromBackupWorkaround.kt @@ -66,7 +66,6 @@ object AppLoadedFromBackupWorkaround { // If we don't kill the process, the backup is not "done" and reopening the app show the same message. Thread { - // 3.5 seconds sleep, as the toast is killed on process death. // Same as the default value of LENGTH_LONG try { diff --git a/AnkiDroid/src/main/java/com/ichi2/annotations/NeedsTest.kt b/AnkiDroid/src/main/java/com/ichi2/annotations/NeedsTest.kt index 0bc2a39e51..af745d057d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/annotations/NeedsTest.kt +++ b/AnkiDroid/src/main/java/com/ichi2/annotations/NeedsTest.kt @@ -33,9 +33,12 @@ package com.ichi2.annotations * @param value the explanation for why the test is required. */ @Target( - AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, - AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION, - AnnotationTarget.FIELD, AnnotationTarget.PROPERTY + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.EXPRESSION, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY ) @Repeatable @Retention(AnnotationRetention.SOURCE) diff --git a/AnkiDroid/src/main/java/com/ichi2/async/CollectionOperations.kt b/AnkiDroid/src/main/java/com/ichi2/async/CollectionOperations.kt index a02fc0aaaa..3beda04ce5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/async/CollectionOperations.kt +++ b/AnkiDroid/src/main/java/com/ichi2/async/CollectionOperations.kt @@ -44,7 +44,7 @@ fun updateCard( col: Collection, editCard: Card, isFromReviewer: Boolean, - canAccessScheduler: Boolean, + canAccessScheduler: Boolean ): Card { Timber.d("doInBackgroundUpdateNote") // Save the note @@ -84,7 +84,7 @@ fun updateCard( */ fun updateMultipleNotes( col: Collection, - notesToUpdate: List, + notesToUpdate: List ): List { Timber.d("CollectionOperations: updateMultipleNotes") return col.db.executeInTransaction { @@ -133,8 +133,12 @@ fun updateValuesFromDeck( val totalNewCount = sched.totalNewForCurrentDeck() val totalCount = sched.cardCount() StudyOptionsFragment.DeckStudyData( - counts.new, counts.lrn, counts.rev, totalNewCount, - totalCount, sched.eta(counts) + counts.new, + counts.lrn, + counts.rev, + totalNewCount, + totalCount, + sched.eta(counts) ) } catch (e: RuntimeException) { Timber.e(e, "doInBackgroundUpdateValuesFromDeck - an error occurred") @@ -302,7 +306,7 @@ fun saveModel( */ fun deleteMultipleNotes( col: Collection, - cardIds: List, + cardIds: List ): Array { val cards = cardIds.map { col.getCard(it) }.toTypedArray() return col.db.executeInTransaction { diff --git a/AnkiDroid/src/main/java/com/ichi2/compat/CompatV21.kt b/AnkiDroid/src/main/java/com/ichi2/compat/CompatV21.kt index 40896cbd82..b094745949 100644 --- a/AnkiDroid/src/main/java/com/ichi2/compat/CompatV21.kt +++ b/AnkiDroid/src/main/java/com/ichi2/compat/CompatV21.kt @@ -212,7 +212,8 @@ open class CompatV21 : Compat { audioFocusRequest: AudioFocusRequest? ) { audioManager.requestAudioFocus( - audioFocusChangeListener, AudioManager.STREAM_MUSIC, + audioFocusChangeListener, + AudioManager.STREAM_MUSIC, AudioManager.AUDIOFOCUS_GAIN_TRANSIENT_MAY_DUCK ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/compat/ResolveInfoCompat.kt b/AnkiDroid/src/main/java/com/ichi2/compat/ResolveInfoCompat.kt index 26604c5e12..b4af6a8b09 100644 --- a/AnkiDroid/src/main/java/com/ichi2/compat/ResolveInfoCompat.kt +++ b/AnkiDroid/src/main/java/com/ichi2/compat/ResolveInfoCompat.kt @@ -40,6 +40,7 @@ class ResolveInfoFlagsCompat private constructor(@ResolveInfoFlagsBitsCompat val fun of(@ResolveInfoFlagsBitsCompat value: Long): ResolveInfoFlagsCompat { return ResolveInfoFlagsCompat(value) } + /** Helper property. Does not exist on Platform API */ val EMPTY get() = ResolveInfoFlagsCompat(0) @@ -161,7 +162,7 @@ const val MATCH_DIRECT_BOOT_UNAWARE = 0x00040000 MATCH_DIRECT_BOOT_AWARE.toLong(), MATCH_DIRECT_BOOT_UNAWARE.toLong(), MATCH_SYSTEM_ONLY.toLong(), - MATCH_UNINSTALLED_PACKAGES.toLong(), + MATCH_UNINSTALLED_PACKAGES.toLong() // PackageManager.MATCH_INSTANT, // @SystemApi // PackageManager.MATCH_DEBUG_TRIAGED_MISSING, // deprecated // PackageManager.GET_DISABLED_COMPONENTS, // deprecated diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/AnkiPackageExporter.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/AnkiPackageExporter.kt index dc7bcef865..1b209ab0c0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/AnkiPackageExporter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/AnkiPackageExporter.kt @@ -486,6 +486,7 @@ class AnkiPackageExporter : AnkiExporter { */ internal class ZipFile(path: String?) { private val mZos: ZipArchiveOutputStream + @Throws(IOException::class) fun write(path: String?, entry: String?) { val bis = BufferedInputStream(FileInputStream(path), BUFFER_SIZE) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/BackendImportExport.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/BackendImportExport.kt index 8c39ad9391..5519027163 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/BackendImportExport.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/BackendImportExport.kt @@ -62,13 +62,13 @@ fun CollectionV16.awaitBackupCompletion() { fun importCollectionPackage( backend: Backend, colPath: String, - colpkgPath: String, + colpkgPath: String ) { backend.importCollectionPackage( colPath = colPath, backupPath = colpkgPath, mediaFolder = colPath.replace(".anki2", ".media"), - mediaDb = colPath.replace(".anki2", ".media.db"), + mediaDb = colPath.replace(".anki2", ".media.db") ) } @@ -108,7 +108,7 @@ fun CollectionV16.exportAnkiPackage( withScheduling: Boolean, withMedia: Boolean, limit: ExportLimit, - legacy: Boolean = true, + legacy: Boolean = true ) { backend.exportAnkiPackage(outPath, withScheduling, withMedia, legacy, limit) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Card.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Card.kt index 055d700a4f..eb4461bb88 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Card.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Card.kt @@ -404,7 +404,9 @@ open class Card : Cloneable { override fun equals(other: Any?): Boolean { return if (other is Card) { this.id == other.id - } else super.equals(other) + } else { + super.equals(other) + } } override fun hashCode(): Int { @@ -552,7 +554,9 @@ open class Card : Cloneable { override fun equals(other: Any?): Boolean { return if (other !is Cache) { false - } else this.id == other.id + } else { + this.id == other.id + } } fun loadQA(reload: Boolean, browser: Boolean) { diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.kt index 34a5ceafaf..cf236088bf 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Collection.kt @@ -167,6 +167,7 @@ open class Collection( open var crt: Long = 0 open var mod: Long = 0 open var scm: Long = 0 + @RustCleanup("remove") var dirty: Boolean = false private var mUsn = 0 @@ -340,7 +341,8 @@ open class Collection( while (true) { db.query( "SELECT substr($columnName, ?, ?) FROM col", - pos.toString(), chunk.toString() + pos.toString(), + chunk.toString() ).use { cursor -> if (!cursor.moveToFirst()) { return buf.toString() @@ -790,6 +792,7 @@ open class Collection( val ord = cur.getInt(2) val did = cur.getLong(3) val due = cur.getLong(4) + @Consts.CARD_TYPE val type = cur.getInt(5) // existing cards @@ -1177,7 +1180,9 @@ open class Collection( val flag = flags and 0b111 return if (flag == 0) { "" - } else "flag$flag" + } else { + "flag$flag" + } } /* Finding cards ************************************************************ *********************************** @@ -1210,6 +1215,7 @@ open class Collection( fun buildSearchString(node: SearchNode): String { return backend.buildSearchString(node) } + /** Return a list of card ids */ @KotlinCleanup("set reasonable defaults") fun findCards(search: String): List { @@ -1313,7 +1319,9 @@ open class Collection( get_config_int("timeLim"), sched.reps - mStartReps ) - } else null + } else { + null + } } /* @@ -1335,7 +1343,9 @@ open class Collection( fun undoType(): UndoAction? { return if (!undo.isEmpty()) { undo.last - } else null + } else { + null + } } open fun undoName(res: Resources): String { @@ -1354,8 +1364,6 @@ open class Collection( return lastUndo.undo(this) } - @BlocksSchemaUpgrade("audit all UI actions that call this, and make sure they call a backend method") - @RustCleanup("this will be unnecessary after legacy schema dropped") /** * In the legacy schema, this adds the undo action to the undo list. * In the new schema, this action is not useful, as the backend stores its own @@ -1363,6 +1371,8 @@ open class Collection( * operation available. If you find an action is not undoable with the new backend, * you probably need to be calling the relevant backend method to perform it, * instead of trying to do it with raw SQL. */ + @BlocksSchemaUpgrade("audit all UI actions that call this, and make sure they call a backend method") + @RustCleanup("this will be unnecessary after legacy schema dropped") fun markUndo(undoAction: UndoAction) { Timber.d("markUndo() of type %s", undoAction.javaClass) undo.add(undoAction) @@ -1473,7 +1483,8 @@ open class Collection( val badOrd = db.queryScalar( "select 1 from cards where (ord < 0 or ord >= ?) and nid in ( " + "select id from notes where mid = ?) limit 1", - tmpls.length(), m.getLong("id") + tmpls.length(), + m.getLong("id") ) > 0 if (badOrd) { return false @@ -1768,7 +1779,9 @@ open class Collection( Utils.ids2str(dynDeckIds) + "and odid in " + Utils.ids2str(dynIdsAndZero), - nextDeckId, TimeManager.time.intTime(), usn() + nextDeckId, + TimeManager.time.intTime(), + usn() ) result.cardsWithFixedHomeDeckCount = cardIds.size val message = String.format(Locale.US, "Fixed %d cards with no home deck", cardIds.size) @@ -1840,7 +1853,9 @@ open class Collection( "UPDATE cards SET due = ?, ivl = 1, mod = ?, usn = ? WHERE id IN " + Utils.ids2str( ids ), - sched.today, TimeManager.time.intTime(), usn() + sched.today, + TimeManager.time.intTime(), + usn() ) } return problems @@ -2032,7 +2047,8 @@ open class Collection( ) if (firstException == null) { val details = String.format( - Locale.ROOT, "deleteNotesWithWrongFieldCounts row: %d col: %d", + Locale.ROOT, + "deleteNotesWithWrongFieldCounts row: %d col: %d", currentRow, cur.columnCount ) @@ -2205,7 +2221,10 @@ open class Collection( "update cards set flags = (flags & ~?) | ?, usn=?, mod=? where id in " + Utils.ids2str( cids ), - 7, flag, usn(), TimeManager.time.intTime() + 7, + flag, + usn(), + TimeManager.time.intTime() ) } @@ -2326,35 +2345,45 @@ open class Collection( fun get_config(key: String, defaultValue: Boolean?): Boolean? { return if (config!!.isNull(key)) { defaultValue - } else config!!.getBoolean(key) + } else { + config!!.getBoolean(key) + } } @Contract("_, !null -> !null") fun get_config(key: String, defaultValue: Long?): Long? { return if (config!!.isNull(key)) { defaultValue - } else config!!.getLong(key) + } else { + config!!.getLong(key) + } } @Contract("_, !null -> !null") fun get_config(key: String, defaultValue: Int?): Int? { return if (config!!.isNull(key)) { defaultValue - } else config!!.getInt(key) + } else { + config!!.getInt(key) + } } @Contract("_, !null -> !null") fun get_config(key: String, defaultValue: Double?): Double? { return if (config!!.isNull(key)) { defaultValue - } else config!!.getDouble(key) + } else { + config!!.getDouble(key) + } } @Contract("_, !null -> !null") fun get_config(key: String, defaultValue: String?): String? { return if (config!!.isNull(key)) { defaultValue - } else config!!.getString(key) + } else { + config!!.getString(key) + } } /** Edits to the config are not persisted to the preferences */ @@ -2362,7 +2391,9 @@ open class Collection( fun get_config(key: String, defaultValue: JSONObject?): JSONObject? { return if (config!!.isNull(key)) { if (defaultValue == null) null else defaultValue.deepClone() - } else config!!.getJSONObject(key).deepClone() + } else { + config!!.getJSONObject(key).deepClone() + } } /** Edits to the array are not persisted to the preferences */ @@ -2370,7 +2401,9 @@ open class Collection( fun get_config(key: String, defaultValue: JSONArray?): JSONArray? { return if (config!!.isNull(key)) { if (defaultValue == null) null else JSONArray(defaultValue) - } else JSONArray(config!!.getJSONArray(key)) + } else { + JSONArray(config!!.getJSONArray(key)) + } } fun set_config(key: String, value: Boolean) { @@ -2446,7 +2479,9 @@ open class Collection( open fun setDeck(cids: LongArray, did: Long) { db.execute( "update cards set did=?,usn=?,mod=? where id in " + Utils.ids2str(cids), - did, usn(), TimeManager.time.intTime() + did, + usn(), + TimeManager.time.intTime() ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/CollectionV16.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/CollectionV16.kt index d010085d74..2934ae64b5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/CollectionV16.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/CollectionV16.kt @@ -140,13 +140,13 @@ class CollectionV16( override fun findCards( search: String, - order: SortOrder, + order: SortOrder ): List { val adjustedOrder = if (order is SortOrder.UseCollectionOrdering) { @Suppress("DEPRECATION") SortOrder.BuiltinSortKind( get_config("sortType", null as String?) ?: "noteFld", - get_config("sortBackwards", false) ?: false, + get_config("sortBackwards", false) ?: false ) } else { order @@ -161,13 +161,13 @@ class CollectionV16( override fun findNotes( query: String, - order: SortOrder, + order: SortOrder ): List { val adjustedOrder = if (order is SortOrder.UseCollectionOrdering) { @Suppress("DEPRECATION") SortOrder.BuiltinSortKind( get_config("noteSortType", null as String?) ?: "noteFld", - get_config("browserNoteSortBackwards", false) ?: false, + get_config("browserNoteSortBackwards", false) ?: false ) } else { order diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/ConfigManager.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/ConfigManager.kt index 8b1e8d0060..6f91ce42d9 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/ConfigManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/ConfigManager.kt @@ -28,12 +28,19 @@ abstract class ConfigManager { * a mapping whose value is [JSONObject.NULL]. */ @CheckResult abstract fun isNull(key: String): Boolean + @CheckResult abstract fun getString(key: String): String + @CheckResult abstract fun getBoolean(key: String): Boolean + @CheckResult abstract fun getDouble(key: String): Double + @CheckResult abstract fun getInt(key: String): Int + @CheckResult abstract fun getLong(key: String): Long + @CheckResult abstract fun getJSONArray(key: String): JSONArray + @CheckResult abstract fun getJSONObject(key: String): JSONObject abstract fun put(key: String, value: Boolean) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Consts.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Consts.kt index e3efefdfd1..29f1d26bed 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Consts.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Consts.kt @@ -23,6 +23,7 @@ object Consts { const val NEW_CARDS_DISTRIBUTE = 0 const val NEW_CARDS_LAST = 1 const val NEW_CARDS_FIRST = 2 + @Retention(AnnotationRetention.SOURCE) @IntDef(NEW_CARDS_DISTRIBUTE, NEW_CARDS_LAST, NEW_CARDS_FIRST) annotation class NEW_CARD_ORDER @@ -30,6 +31,7 @@ object Consts { // new card insertion order const val NEW_CARDS_RANDOM = 0 const val NEW_CARDS_DUE = 1 + @Retention(AnnotationRetention.SOURCE) @IntDef(NEW_CARDS_RANDOM, NEW_CARDS_DUE) annotation class NEW_CARDS_INSERTION @@ -43,6 +45,7 @@ object Consts { const val QUEUE_TYPE_REV = 2 const val QUEUE_TYPE_DAY_LEARN_RELEARN = 3 const val QUEUE_TYPE_PREVIEW = 4 + @Retention(AnnotationRetention.SOURCE) @IntDef(QUEUE_TYPE_MANUALLY_BURIED, QUEUE_TYPE_SIBLING_BURIED, QUEUE_TYPE_SUSPENDED, QUEUE_TYPE_NEW, QUEUE_TYPE_LRN, QUEUE_TYPE_REV, QUEUE_TYPE_DAY_LEARN_RELEARN, QUEUE_TYPE_PREVIEW) annotation class CARD_QUEUE @@ -52,6 +55,7 @@ object Consts { const val CARD_TYPE_LRN = 1 const val CARD_TYPE_REV = 2 const val CARD_TYPE_RELEARNING = 3 + @Retention(AnnotationRetention.SOURCE) @IntDef(CARD_TYPE_NEW, CARD_TYPE_LRN, CARD_TYPE_REV, CARD_TYPE_RELEARNING) annotation class CARD_TYPE @@ -60,6 +64,7 @@ object Consts { const val REM_CARD = 0 const val REM_NOTE = 1 const val REM_DECK = 2 + @Retention(AnnotationRetention.SOURCE) @IntDef(REM_CARD, REM_NOTE, REM_DECK) annotation class REM_TYPE @@ -83,6 +88,7 @@ object Consts { const val DYN_REVADDED = 7 const val DYN_DUEPRIORITY = 8 const val DYN_MAX_SIZE = 99999 + @Retention(AnnotationRetention.SOURCE) @IntDef(DYN_OLDEST, DYN_RANDOM, DYN_SMALLINT, DYN_BIGINT, DYN_LAPSES, DYN_ADDED, DYN_DUE, DYN_REVADDED, DYN_DUEPRIORITY) annotation class DYN_PRIORITY @@ -90,6 +96,7 @@ object Consts { // model types const val MODEL_STD = 0 const val MODEL_CLOZE = 1 + @Retention(AnnotationRetention.SOURCE) @IntDef(MODEL_STD, MODEL_CLOZE) annotation class MODEL_TYPE @@ -97,6 +104,7 @@ object Consts { // deck types const val DECK_STD = 0 const val DECK_DYN = 1 + @Retention(AnnotationRetention.SOURCE) @IntDef(DECK_STD, DECK_DYN) annotation class DECK_TYPE @@ -105,6 +113,7 @@ object Consts { // deck schema & syncing vars const val LEGACY_SCHEMA_VERSION = 11 + /** Only used by the dialog shown to user */ const val BACKEND_SCHEMA_VERSION = 18 @@ -125,6 +134,7 @@ object Consts { const val BUTTON_TWO = 2 const val BUTTON_THREE = 3 const val BUTTON_FOUR = 4 + @Retention(AnnotationRetention.SOURCE) @IntDef(BUTTON_ONE, BUTTON_TWO, BUTTON_THREE, BUTTON_FOUR) annotation class BUTTON_TYPE @@ -136,6 +146,7 @@ object Consts { const val REVLOG_RELRN = 2 const val REVLOG_CRAM = 3 const val REVLOG_MANUAL = 4 + @Retention(AnnotationRetention.SOURCE) @IntDef(REVLOG_LRN, REVLOG_REV, REVLOG_RELRN, REVLOG_CRAM, REVLOG_MANUAL) annotation class REVLOG_TYPE diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/DB.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/DB.kt index 7f839e3a27..082147b4ec 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/DB.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/DB.kt @@ -203,11 +203,13 @@ class DB(db: SupportSQLiteDatabase) { @KotlinCleanup("""Use Kotlin string. Change split so that there is no empty string after last ";".""") fun executeScript(@Language("SQL") sql: String) { mod = true - @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") val queries = java.lang.String(sql).split(";") + @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") + val queries = java.lang.String(sql).split(";") for (query in queries) { database.execSQL(query) } } + /** update must always be called via DB in order to mark the db as changed */ fun update( table: String, diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/DeckManager.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/DeckManager.kt index 6acf659914..3b5294adb8 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/DeckManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/DeckManager.kt @@ -35,9 +35,11 @@ abstract class DeckManager { */ abstract fun load(@Language("JSON") decks: String, dconf: String) + @RustCleanup("Unused in V16") /** @throws DeckRenameException */ abstract fun save() + /** Can be called with either a deck or a deck configuration. * @throws DeckRenameException */ abstract fun save(g: Deck) @@ -50,24 +52,31 @@ abstract class DeckManager { */ abstract fun id_for_name(name: String): Long? + @Throws(DeckRenameException::class) abstract fun id(name: String): Long + /** Same as id, but rename ancestors if filtered to avoid failure */ fun id_safe(name: String) = id_safe(name, Decks.DEFAULT_DECK) + /** Same as id, but rename ancestors if filtered to avoid failure */ abstract fun id_safe(name: String, type: String): Long /** Remove the deck. delete any cards inside and child decks. */ fun rem(did: DeckId) = rem(did, true) + /** Remove the deck. Delete child decks. If cardsToo, delete any cards inside. */ fun rem(did: DeckId, cardsToo: Boolean = true) = rem(did, cardsToo, true) + /** Remove the deck. If cardsToo, delete any cards inside. */ abstract fun rem(did: DeckId, cardsToo: Boolean = true, childrenToo: Boolean = true) /** An unsorted list of all deck names. */ fun allNames() = allNames(true) + /** An unsorted list of all deck names. */ abstract fun allNames(dyn: Boolean = true): List + /** A list of all decks. */ abstract fun all(): List abstract fun allIds(): Set @@ -77,9 +86,11 @@ abstract class DeckManager { /** Return the number of decks. */ @RustCleanup("This is a long in V16 - shouldn't make a difference, but needs investigation") abstract fun count(): Int - @CheckResult + /** Obtains the deck from the DeckID, or default if the deck was not found */ + @CheckResult fun get(did: DeckId): Deck = get(did, true)!! + /** * Obtains the deck from the DeckID * @param did The deck to obtain @@ -114,8 +125,10 @@ abstract class DeckManager { abstract fun updateConf(g: DeckConfig) fun confId(name: String): Long = confId(name, Decks.DEFAULT_CONF) + /** Create a new configuration and return id */ abstract fun confId(name: String, cloneFrom: String): Long + /** * Remove a configuration and update all decks using it. * @throws ConfirmModSchemaException @@ -144,11 +157,14 @@ abstract class DeckManager { */ /** The currently active dids. Make sure to copy before modifying. */ abstract fun active(): LinkedList + /** The currently selected did. */ abstract fun selected(): Long abstract fun current(): Deck + /** Select a new branch. */ abstract fun select(did: DeckId) + /** * All children of did as nodes of (key:name, value:id) * @@ -158,6 +174,7 @@ abstract class DeckManager { abstract fun children(did: DeckId): TreeMap abstract fun childDids(did: DeckId, childMap: Decks.Node): List abstract fun childMap(): Decks.Node + /** All parents of did. */ abstract fun parents(did: DeckId): List diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Decks.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Decks.kt index fbd85e43e9..d7525a8955 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Decks.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Decks.kt @@ -626,8 +626,8 @@ class Decks(private val col: Collection) : DeckManager() { override fun confForDid(did: Long): DeckConfig { val deck = get(did, false)!! if (deck.has("conf")) { - @KotlinCleanup("Clarify comment. It doesn't make sense when using :?") // fall back on default + @KotlinCleanup("Clarify comment. It doesn't make sense when using :?") val conf = getConf(deck.getLong("conf")) ?: getConf(1L)!! return conf.apply { put("dyn", DECK_STD) @@ -959,6 +959,7 @@ class Decks(private val col: Collection) : DeckManager() { save() } } + /* Dynamic decks */ @@ -992,6 +993,7 @@ class Decks(private val col: Collection) : DeckManager() { // not in libAnki const val DECK_SEPARATOR = "::" + @KotlinCleanup("Maybe use triple quotes and @language? for these properties") const val DEFAULT_DECK = ( "" + @@ -1079,6 +1081,7 @@ class Decks(private val col: Collection) : DeckManager() { } private val spaceAroundSeparator = Pattern.compile("\\s*::\\s*") + @Suppress("NAME_SHADOWING") @VisibleForTesting fun strip(deckName: String): String { @@ -1097,6 +1100,7 @@ class Decks(private val col: Collection) : DeckManager() { * ************************************** */ private val normalized = HashMap() + @KotlinCleanup("nullability") fun normalizeName(name: String?): String? { if (!normalized.containsKey(name)) { diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/DecksV16.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/DecksV16.kt index 07bf65059d..439445f5c7 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/DecksV16.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/DecksV16.kt @@ -29,7 +29,7 @@ "MemberVisibilityCanBePrivate", "FunctionName", "ConvertToStringTemplate", - "LocalVariableName", + "LocalVariableName" ) package com.ichi2.libanki @@ -387,7 +387,8 @@ class DecksV16(private val col: CollectionV16) : @Deprecated("decks.allNames() is deprecated, use .all_names_and_ids()") fun allNames(dyn: bool = true, force_default: bool = true): MutableList { return this.all_names_and_ids( - skip_empty_default = !force_default, include_filtered = dyn + skip_empty_default = !force_default, + include_filtered = dyn ).map { x -> x.name }.toMutableList() diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Finder.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Finder.kt index 86590e5cf0..680625236a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Finder.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Finder.kt @@ -44,7 +44,7 @@ class Finder(private val col: Collection) { @CheckResult private fun _findCards( query: String, - _order: SortOrder, + _order: SortOrder ): List { val tokens = _tokenize(query) val res1 = _where(tokens) @@ -295,7 +295,9 @@ class Finder(private val col: Collection) { } return if (s.bad) { Pair(null, null) - } else Pair(s.q, args.toTypedArray()) + } else { + Pair(s.q, args.toTypedArray()) + } } /** @@ -517,19 +519,25 @@ class Finder(private val col: Collection) { private fun _findNids(`val`: String): String? { return if (fNidsPattern.matcher(`val`).find()) { null - } else "n.id in ($`val`)" + } else { + "n.id in ($`val`)" + } } private fun _findCids(`val`: String): String? { return if (fNidsPattern.matcher(`val`).find()) { null - } else "c.id in ($`val`)" + } else { + "c.id in ($`val`)" + } } private fun _findMid(`val`: String): String? { return if (fMidPattern.matcher(`val`).find()) { null - } else "n.mid = $`val`" + } else { + "n.mid = $`val`" + } } private fun _findModel(`val`: String): String { @@ -696,7 +704,9 @@ class Finder(private val col: Collection) { } return if (nids.isEmpty()) { "0" - } else "n.id in " + Utils.ids2str(nids) + } else { + "n.id in " + Utils.ids2str(nids) + } } private fun _findDupes(`val`: String): String? { @@ -713,7 +723,8 @@ class Finder(private val col: Collection) { val nids: MutableList = ArrayList() col.db.query( "select id, flds from notes where mid=? and csum=?", - mid, csum + mid, + csum ).use { cur -> val nid = cur.getLong(0) val flds = cur.getString(1) @@ -779,6 +790,7 @@ class Finder(private val col: Collection) { ): Int { @Suppress("NAME_SHADOWING") var src = src + @Suppress("NAME_SHADOWING") var dst = dst val mmap: MutableMap = HashMap() diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Media.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Media.kt index a6188340db..083925f9ca 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Media.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Media.kt @@ -227,6 +227,7 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);""" for (s in strings) { @Suppress("NAME_SHADOWING") var s = s + // handle latex @KotlinCleanup("change to .map { }") val svg = model.optBoolean("latexsvg", false) @@ -573,7 +574,9 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);""" val mtime = _mtime(dir()) return if (mod != 0L && mod == mtime) { null - } else mtime + } else { + mtime + } } @KotlinCleanup("destructure directly val (added, removed) = _changes()") @@ -875,7 +878,10 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);""" val path = File(dir(), fname).absolutePath db!!.execute( "insert or replace into media values (?,?,?,?)", - fname, _checksum(path), _mtime(path), 1 + fname, + _checksum(path), + _mtime(path), + 1 ) } @@ -890,7 +896,10 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);""" Timber.d("Marking media file removal in media db: %s", fname) db!!.execute( "insert or replace into media values (?,?,?,?)", - fname, null, 0, 1 + fname, + null, + 0, + 1 ) } @@ -1035,5 +1044,5 @@ create table meta (dirMod int, lastUsn int); insert into meta values (0, 0);""" data class MediaCheckResult( val missingFileNames: List, val unusedFileNames: List, - val invalidFileNames: List, + val invalidFileNames: List ) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Model.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Model.kt index bcf7ecf9c9..a69f15c5b1 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Model.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Model.kt @@ -50,6 +50,7 @@ class Model : JSONObject { constructor(json: JSONObject) : super() { json.deepClonedInto(this) } + /** * Creates a model object form json string */ diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/ModelManager.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/ModelManager.kt index b5ff8af9e6..2525c97c35 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/ModelManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/ModelManager.kt @@ -36,6 +36,7 @@ abstract class ModelManager(protected val col: Collection) { /** Mark M modified if provided, and schedule registry flush. */ fun save() = save(null) fun save(m: Model?) = save(m, false) + /** * Save a model * @param m model to save @@ -70,6 +71,7 @@ abstract class ModelManager(protected val col: Collection) { /** get model with ID, or null. */ abstract fun get(id: Long): Model? + /** get all models */ abstract fun all(): List @@ -91,6 +93,7 @@ abstract class ModelManager(protected val col: Collection) { abstract fun rem(m: Model) abstract fun add(m: Model) + /** Add or update an existing model. Used for syncing and merging. */ open fun update(m: Model) = update(m, true) @@ -120,6 +123,7 @@ abstract class ModelManager(protected val col: Collection) { */ @RustCleanup("use all_use_counts()") abstract fun useCount(m: Model): Int + /** * Number of notes using m * @param m The model to the count the notes of. @@ -142,15 +146,19 @@ abstract class ModelManager(protected val col: Collection) { abstract fun newField(name: String): JSONObject abstract fun sortIdx(m: Model): Int + @Throws(ConfirmModSchemaException::class) abstract fun setSortIdx(m: Model, idx: Int) @Throws(ConfirmModSchemaException::class) abstract fun addField(m: Model, field: JSONObject) + @Throws(ConfirmModSchemaException::class) abstract fun remField(m: Model, field: JSONObject) + @Throws(ConfirmModSchemaException::class) abstract fun moveField(m: Model, field: JSONObject, idx: Int) + @Throws(ConfirmModSchemaException::class) abstract fun renameField(m: Model, field: JSONObject, newName: String) @@ -160,6 +168,7 @@ abstract class ModelManager(protected val col: Collection) { @Throws(ConfirmModSchemaException::class) abstract fun addTemplate(m: Model, template: JSONObject) + /** * Removing a template * @@ -314,6 +323,7 @@ abstract class ModelManager(protected val col: Collection) { /** Add template without schema mod */ protected abstract fun _addTemplate(m: Model, template: JSONObject) + /** Add field without schema mod */ protected abstract fun _addField(m: Model, field: JSONObject) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Models.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Models.kt index b1de708644..e43d96c3bc 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Models.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Models.kt @@ -44,6 +44,7 @@ class Models(col: Collection) : ModelManager(col) { */ private var mChanged = false + @KotlinCleanup("lateinit") private var mModels: HashMap? = null @@ -58,6 +59,7 @@ class Models(col: Collection) : ModelManager(col) { mChanged = false mModels = HashMap() val modelarray = JSONObject(json) + @KotlinCleanup("simplify with ?.forEach{}") val ids = modelarray.names() if (ids != null) { @@ -116,6 +118,7 @@ class Models(col: Collection) : ModelManager(col) { false } } + /* Retrieving and creating models *********************************************************************************************** @@ -465,7 +468,9 @@ class Models(col: Collection) : ModelManager(col) { r.add( arrayOf( Utils.joinFields(fn.transform(Utils.splitFields(cur.getString(1)))), - time.intTime(), col.usn(), cur.getLong(0) + time.intTime(), + col.usn(), + cur.getLong(0) ) ) } @@ -524,7 +529,10 @@ class Models(col: Collection) : ModelManager(col) { col.db .execute( "update cards set ord = ord - 1, usn = ?, mod = ? where nid in (select id from notes where mid = ?) and ord > ?", - col.usn(), time.intTime(), m.getLong("id"), ord + col.usn(), + time.intTime(), + m.getLong("id"), + ord ) tmpls = m.getJSONArray("tmpls") val tmpls2 = JSONArray() @@ -576,7 +584,9 @@ class Models(col: Collection) : ModelManager(col) { col.db.execute( "update cards set ord = (case " + sb + " end),usn=?,mod=? where nid in (select id from notes where mid = ?)", - col.usn(), time.intTime(), m.getLong("id") + col.usn(), + time.intTime(), + m.getLong("id") ) } @@ -584,6 +594,7 @@ class Models(col: Collection) : ModelManager(col) { @Suppress("UNUSED_VARIABLE") // unused upstream as well val rem = col.genCards(nids(m), m)!! } + /* Model changing *********************************************************************************************** */ @@ -640,7 +651,8 @@ class Models(col: Collection) : ModelManager(col) { val nmType = newModel.getInt("type") val nflds = newModel.getJSONArray("tmpls").length() col.db.query( - "select id, ord from cards where nid = ?", nid + "select id, ord from cards where nid = ?", + nid ).use { cur -> while (cur.moveToNext()) { // if the src model is a cloze, we ignore the map, as the gui doesn't currently @@ -832,6 +844,7 @@ class Models(col: Collection) : ModelManager(col) { private val fClozePattern1 = Pattern.compile("\\{\\{[^}]*?cloze:(?:[^}]?:)*(.+?)\\}\\}") private val fClozePattern2 = Pattern.compile("<%cloze:(.+?)%>") private val fClozeOrdPattern = Pattern.compile("(?si)\\{\\{c(\\d+)::.*?\\}\\}") + @KotlinCleanup("Use triple quotes for this properties and maybe `@language('json'')`") const val DEFAULT_MODEL = ( "{\"sortf\": 0, " + @@ -922,9 +935,12 @@ class Models(col: Collection) : ModelManager(col) { // For cloze, getting the list of cloze numbes is linear in the size of the template // So computing the full list is almost as efficient as checking for a particular number !_availClozeOrds(m, sfld, false).contains(ord) - } else emptyStandardCard( - m.getJSONArray("tmpls").getJSONObject(ord), m.nonEmptyFields(sfld) - ) + } else { + emptyStandardCard( + m.getJSONArray("tmpls").getJSONObject(ord), + m.nonEmptyFields(sfld) + ) + } } /** @@ -955,12 +971,14 @@ class Models(col: Collection) : ModelManager(col) { sfld, allowEmpty == AllowEmpty.TRUE || allowEmpty == AllowEmpty.ONLY_CLOZE ) - } else _availStandardOrds( - m, - sfld, - nodes!!, - allowEmpty == AllowEmpty.TRUE - ) + } else { + _availStandardOrds( + m, + sfld, + nodes!!, + allowEmpty == AllowEmpty.TRUE + ) + } } fun availOrds( @@ -974,7 +992,9 @@ class Models(col: Collection) : ModelManager(col) { sfld, allowEmpty == AllowEmpty.TRUE || allowEmpty == AllowEmpty.ONLY_CLOZE ) - } else _availStandardOrds(m, sfld, allowEmpty == AllowEmpty.TRUE) + } else { + _availStandardOrds(m, sfld, allowEmpty == AllowEmpty.TRUE) + } } fun _availStandardOrds( @@ -1031,6 +1051,7 @@ class Models(col: Collection) : ModelManager(col) { } return namesOfFieldsContainingClozeCache[question]!! } + /** * @param m A note type with cloze * @param sflds The fields of a note of type m. (Assume the size of the array is the number of fields) @@ -1038,11 +1059,6 @@ class Models(col: Collection) : ModelManager(col) { * @return The indexes (in increasing order) of cards that should be generated according to req rules. * If empty is not allowed, it will contains ord 1. */ - /** - * @param m A note type with cloze - * @param sflds The fields of a note of type m. (Assume the size of the array is the number of fields) - * @return The indexes (in increasing order) of cards that should be generated according to req rules. - */ @KotlinCleanup("sflds: String? to string") @KotlinCleanup("return arrayListOf(0)") fun _availClozeOrds( @@ -1068,7 +1084,9 @@ class Models(col: Collection) : ModelManager(col) { return if (ords.isEmpty() && allowEmpty) { // empty clozes use first ord ArrayList(listOf(0)) - } else ArrayList(ords) + } else { + ArrayList(ords) + } } } // private long mCrt = mCol.getTime().intTime(); diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/ModelsV16.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/ModelsV16.kt index 3180d2eb7c..3bf2ba0275 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/ModelsV16.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/ModelsV16.kt @@ -50,6 +50,7 @@ class NoteTypeNameIDUseCount(val id: Long, val name: String, val useCount: UInt) class BackendNote(val fields: MutableList) private typealias int = Long + // # types private typealias Field = JSONObject // Dict private typealias Template = JSONObject // Dict> @@ -457,7 +458,6 @@ class ModelsV16(col: CollectionV16) : ModelManager(col) { /** Modifies schema. */ fun set_sort_index(nt: NoteType, idx: Int) { - assert(0 <= idx && idx < len(nt.flds)) nt.sortf = idx } @@ -604,7 +604,7 @@ class ModelsV16(col: CollectionV16) : ModelManager(col) { oldNotetypeId = m.id, newNotetypeId = newModel.id, currentSchema = col.scm, - oldNotetypeName = m.name, + oldNotetypeName = m.name ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Note.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Note.kt index 1bbab26057..77576428dd 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Note.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Note.kt @@ -121,14 +121,17 @@ class Note : Cloneable { usn = col.usn() } val csumAndStrippedFieldField = Utils.sfieldAndCsum( - fields, col.models.sortIdx(mModel) + fields, + col.models.sortIdx(mModel) ) val sfld = csumAndStrippedFieldField.first val tags = stringTags() val fields = joinedFields() if (mod == null && col.db.queryScalar( "select 1 from notes where id = ? and tags = ? and flds = ?", - this.id.toString(), tags, fields + this.id.toString(), + tags, + fields ) > 0 ) { return @@ -293,17 +296,19 @@ class Note : Cloneable { return DupeOrEmpty.EMPTY } val csumAndStrippedFieldField = Utils.sfieldAndCsum( - fields, 0 + fields, + 0 ) val csum = csumAndStrippedFieldField.second // find any matching csums and compare val strippedFirstField = csumAndStrippedFieldField.first - for ( - flds in col.db.queryStringList( - "SELECT flds FROM notes WHERE csum = ? AND id != ? AND mid = ?", - csum, this.id, mid - ) - ) { + val fields = col.db.queryStringList( + "SELECT flds FROM notes WHERE csum = ? AND id != ? AND mid = ?", + csum, + this.id, + mid + ) + for (flds in fields) { if (Utils.stripHTMLMedia( Utils.splitFields(flds)[0] ) == strippedFirstField diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/SortOrder.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/SortOrder.kt index 71fcbb61ee..f3b6e8a8a2 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/SortOrder.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/SortOrder.kt @@ -25,10 +25,13 @@ import net.ankiweb.rsdroid.RustCleanup */ abstract class SortOrder { class NoOrdering : SortOrder() + /** Based on config: sortType and sortBackwards */ class UseCollectionOrdering : SortOrder() + /** A custom SQL string placed after "order by" */ class AfterSqlOrderBy(val customOrdering: String) : SortOrder() + @Deprecated("Not yet usable - unhandled in Java backend") @RustCleanup("remove @Deprecated once Java backend is gone") class BuiltinSortKind(val value: String, val reverse: Boolean) : SortOrder() diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Sound.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Sound.kt index 64d176840a..b4f3dfd696 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Sound.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Sound.kt @@ -41,11 +41,11 @@ import java.lang.ref.WeakReference import java.util.* import java.util.regex.Pattern -@KotlinCleanup("IDE Lint") // NICE_TO_HAVE: Abstract, then add tests for #6111 /** * Class used to parse, load and play sound files on AnkiDroid. */ +@KotlinCleanup("IDE Lint") class Sound { /** * Media player used to play the sounds. It's Nullable and that it is set only if a sound is playing or paused, otherwise it is null. @@ -66,6 +66,7 @@ class Sound { * Weak reference to the activity which is attempting to play the sound */ private var mCallingActivity: WeakReference? = null + @VisibleForTesting fun getSounds(side: SoundSide): ArrayList? { if (side == SoundSide.QUESTION_AND_ANSWER) { @@ -367,7 +368,9 @@ class Sound { val currentAudioUri: String? get() = if (mCurrentAudioUri == null) { null - } else mCurrentAudioUri.toString() + } else { + mCurrentAudioUri.toString() + } fun notifyConfigurationChanged(videoView: VideoView) { if (mMediaPlayer != null) { @@ -584,7 +587,9 @@ class Sound { val trimmedSound = sound.trim { it <= ' ' } return if (hasURIScheme(trimmedSound)) { trimmedSound - } else soundDir + Uri.encode(trimRight(sound)) + } else { + soundDir + Uri.encode(trimRight(sound)) + } } /** diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/StdModels.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/StdModels.kt index 413de067e9..acbc91d6d5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/StdModels.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/StdModels.kt @@ -27,7 +27,8 @@ class StdModels( private val function: CreateStdModels, /** Essentially, the default name. As a resource, so that it can * be localized later. */ - @field:StringRes @param:StringRes private val defaultNameRes: Int + @field:StringRes @param:StringRes + private val defaultNameRes: Int ) { fun interface CreateStdModels { fun create(mm: ModelManager, name: String): Model diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/TagManager.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/TagManager.kt index 88c66cf971..b226884003 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/TagManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/TagManager.kt @@ -33,6 +33,7 @@ abstract class TagManager { */ @RustCleanup("Tags.java only") abstract fun load(json: String) + @RustCleanup("Tags.java only") abstract fun flush() @@ -43,15 +44,19 @@ abstract class TagManager { /** Given a list of tags, add any missing ones to tag registry. */ fun register(tags: Iterable) = register(tags, null) + /** Given a list of tags, add any missing ones to tag registry. */ fun register(tags: Iterable, usn: Int? = null) = register(tags, usn, false) + /** Given a list of tags, add any missing ones to tag registry. * @param clear_first Whether to clear the tags in the database before registering the provided tags * */ abstract fun register(tags: Iterable, usn: Int? = null, clear_first: Boolean = false) abstract fun all(): List + /** Add any missing tags from notes to the tags list. The old list is cleared first */ fun registerNotes() = registerNotes(null) + /** * Add any missing tags from notes to the tags list. * @param nids The old list is cleared first if this is null @@ -59,8 +64,10 @@ abstract class TagManager { abstract fun registerNotes(nids: kotlin.collections.Collection? = null) abstract fun allItems(): Iterable + @RustCleanup("Tags.java only") abstract fun save() + /** * byDeck returns the tags of the cards in the deck * @param did the deck id @@ -85,6 +92,7 @@ abstract class TagManager { /** Parse a string and return a list of tags. */ abstract fun split(tags: String): MutableList + /** Join tags into a single string, with leading and trailing spaces. */ abstract fun join(tags: kotlin.collections.Collection): String @@ -99,6 +107,7 @@ abstract class TagManager { /** Strip duplicates, adjust case to match existing tags, and sort. */ @RustCleanup("List, not Collection") abstract fun canonify(tagList: List): java.util.AbstractSet + /** @return True if TAG is in TAGS. Ignore case. */ abstract fun inList(tag: String, tags: Iterable): Boolean diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Tags.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Tags.kt index 7bf79c73a7..350ea25a9e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Tags.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Tags.kt @@ -109,7 +109,8 @@ class Tags override fun allItems(): Set { return mTags.entries.map { (key, value): Map.Entry -> TagUsnTuple( - key, value!! + key, + value!! ) }.toSet() } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/TagsV16.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/TagsV16.kt index c0b97ea0b3..0f02852132 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/TagsV16.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/TagsV16.kt @@ -99,10 +99,11 @@ class TagsV16(val col: CollectionV16) : TagManager() { /* Remove space-separated tags from provided notes. */ fun bulkRemove( noteIds: List, - tags: String, + tags: String ): OpChangesWithCount { return col.backend.removeNoteTags( - noteIds = noteIds, tags = tags + noteIds = noteIds, + tags = tags ) } @@ -138,7 +139,6 @@ class TagsV16(val col: CollectionV16) : TagManager() { /** Add tags if they don't exist, and canonify. */ fun addToStr(addtags: String, tags: String): String { - val currentTags = split(tags) for (tag in split(addtags)) { if (!inList(tag, currentTags)) { diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt index 99fcfa91d0..4043dbef3f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/TemplateManager.kt @@ -72,7 +72,7 @@ class TemplateManager { TemplateReplacement( field_name = node.replacement.fieldName, current_text = node.replacement.currentText, - filters = node.replacement.filtersList, + filters = node.replacement.filtersList ) ) ) @@ -92,7 +92,7 @@ class TemplateManager { lang = tag.tts.lang, voices = tag.tts.voicesList, otherArgs = tag.tts.otherArgsList, - speed = tag.tts.speed, + speed = tag.tts.speed ) } } @@ -145,7 +145,7 @@ class TemplateManager { card: Card, notetype: NoteType, template: JSONObject, - fill_empty: bool, + fill_empty: bool ): TemplateRenderContext { return TemplateRenderContext( note.col, @@ -153,7 +153,7 @@ class TemplateManager { note, notetype = notetype, template = template, - fill_empty = fill_empty, + fill_empty = fill_empty ) } } @@ -213,7 +213,7 @@ class TemplateManager { question_text = e.localizedMessage ?: e.toString(), answer_text = e.localizedMessage ?: e.toString(), question_av_tags = emptyList(), - answer_av_tags = emptyList(), + answer_av_tags = emptyList() ) } @@ -236,7 +236,7 @@ class TemplateManager { answer_text = aoutText, question_av_tags = av_tags_to_native(qout.avTagsList), answer_av_tags = av_tags_to_native(aout.avTagsList), - css = note_type().getString("css"), + css = note_type().getString("css") ) return output @@ -251,7 +251,7 @@ class TemplateManager { _note.toBackendNote(), _card.ord, BackendUtils.to_json_bytes(_template!!.deepClone()), - _fill_empty, + _fill_empty ) } else { // existing card (eg study mode) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/UndoAction.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/UndoAction.kt index c9a7c64fc9..9acf2ea53f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/UndoAction.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/UndoAction.kt @@ -27,8 +27,10 @@ import java.util.* abstract class UndoAction /** * For all descendants, we assume that a card/note/object passed as argument is never going to be changed again. - * It's the caller responsibility to clone the object if necessary. */ -(@field:UndoNameId @field:StringRes @param:StringRes @param:UndoNameId val undoNameId: Int) { + * It's the caller responsibility to clone the object if necessary. */( + @field:UndoNameId @field:StringRes @param:StringRes @param:UndoNameId + val undoNameId: Int +) { @Retention(AnnotationRetention.SOURCE) @IntDef(R.string.undo_action_change_deck_multi, R.string.menu_delete_note, R.string.card_browser_delete_card, R.string.card_browser_mark_card, R.string.card_browser_unmark_card, R.string.menu_suspend_card, R.string.card_browser_unsuspend_card, R.string.undo_action_review, R.string.menu_bury_note, R.string.menu_suspend_note, R.string.card_editor_reposition_card, R.string.card_editor_reschedule_card, R.string.menu_bury_card, R.string.card_editor_reset_card) annotation class UndoNameId @@ -54,7 +56,11 @@ abstract class UndoAction * @param card the card currently in the reviewer * @return An UndoAction which, if executed, put back the `card` in the state given here */ - fun revertNoteToProvidedState(@StringRes @UndoNameId undoNameId: Int, card: Card): UndoAction { + fun revertNoteToProvidedState( + @StringRes @UndoNameId + undoNameId: Int, + card: Card + ): UndoAction { return revertToProvidedState(undoNameId, card, card.note().cards()) } @@ -64,7 +70,11 @@ abstract class UndoAction * @param card the card currently in the reviewer * @return An UndoAction which, if executed, put back the `card` in the state given here */ - fun revertCardToProvidedState(@StringRes @UndoNameId undoNameId: Int, card: Card): UndoAction { + fun revertCardToProvidedState( + @StringRes @UndoNameId + undoNameId: Int, + card: Card + ): UndoAction { return revertToProvidedState(undoNameId, card, mutableListOf(card.clone())) } @@ -75,7 +85,12 @@ abstract class UndoAction * @param cards The cards that must be reverted * @return An UndoAction which, if executed, put back the `card` in the state given here */ - private fun revertToProvidedState(@StringRes @UndoNameId undoNameId: Int, card: Card, cards: Iterable): UndoAction { + private fun revertToProvidedState( + @StringRes @UndoNameId + undoNameId: Int, + card: Card, + cards: Iterable + ): UndoAction { return object : UndoAction(undoNameId) { override fun undo(col: Collection): Card { Timber.i("Undo: %d", undoNameId) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/Utils.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/Utils.kt index 5b148b5163..dabf55068f 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/Utils.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/Utils.kt @@ -186,7 +186,8 @@ object Utils { return if (time_s < TIME_HOUR_LONG) { // get time remaining, but never less than 1 time_x = max( - (time_s / TIME_MINUTE).roundToInt(), 1 + (time_s / TIME_MINUTE).roundToInt(), + 1 ) res.getQuantityString(R.plurals.reviewer_window_title, time_x, time_x) // It used to be minutes only. So the word "minutes" is not @@ -295,6 +296,7 @@ object Utils { ) } } + /* * Locale * *********************************************************************************************** @@ -373,6 +375,7 @@ object Utils { htmlEntities.appendTail(sb) return sb.toString() } + /* * IDs * *********************************************************************************************** @@ -533,6 +536,7 @@ object Utils { // -1 ensures that we don't drop empty fields at the ends return fields.split(FIELD_SEPARATOR).toTypedArray() } + /* * Checksums * *********************************************************************************************** @@ -804,10 +808,13 @@ object Utils { try { Timber.d("Creating new file... = %s", destination) f.createNewFile() - @SuppressLint("DirectSystemCurrentTimeMillisUsage") val startTimeMillis = + @SuppressLint("DirectSystemCurrentTimeMillisUsage") + val startTimeMillis = System.currentTimeMillis() val sizeBytes = compat.copyFile(source, destination) - @SuppressLint("DirectSystemCurrentTimeMillisUsage") val endTimeMillis = + + @SuppressLint("DirectSystemCurrentTimeMillisUsage") + val endTimeMillis = System.currentTimeMillis() Timber.d("Finished writeToFile!") val durationSeconds = (endTimeMillis - startTimeMillis) / 1000 @@ -838,6 +845,7 @@ object Utils { fun isIntentAvailable(context: Context, action: String?): Boolean { return isIntentAvailable(context, action, null) } + @KotlinCleanup("Use @JmOverloads, remove fun passing null for ComponentName") @KotlinCleanup("Simplify function body") @Suppress("deprecation") // queryIntentActivities @@ -1012,8 +1020,10 @@ object Utils { // AnkiWeb reads this string and uses , and : as delimiters, so we remove them. val model = Build.MODEL.replace(',', ' ').replace(':', ' ') return String.format( - Locale.US, "android:%s:%s", - Build.VERSION.RELEASE, model + Locale.US, + "android:%s:%s", + Build.VERSION.RELEASE, + model ) } @@ -1024,7 +1034,8 @@ object Utils { // AnkiWeb reads this string and uses , and : as delimiters, so we remove them. val model = Build.MODEL.replace(',', ' ').replace(':', ' ') return String.format( - Locale.US, "android:%s:%s:%s", + Locale.US, + "android:%s:%s:%s", BuildConfig.VERSION_NAME, Build.VERSION.RELEASE, model @@ -1041,7 +1052,9 @@ object Utils { fun nfcNormalized(txt: String): String { return if (!Normalizer.isNormalized(txt, Normalizer.Form.NFC)) { Normalizer.normalize(txt, Normalizer.Form.NFC) - } else txt + } else { + txt + } } /** diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/backend/exception/DeckRenameException.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/backend/exception/DeckRenameException.kt index c2fa4b3751..3b3733c0b1 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/backend/exception/DeckRenameException.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/backend/exception/DeckRenameException.kt @@ -14,7 +14,9 @@ class DeckRenameException override val message: String? get() = if (errorCode == FILTERED_NOSUBDECKS) { "Deck $mDeckName has filtered ancestor $mFilteredAncestorName" - } else super.message + } else { + super.message + } fun getLocalizedMessage(res: Resources): String { return when (errorCode) { diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Anki2Importer.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Anki2Importer.kt index 6c5bd13c18..fba19f34aa 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Anki2Importer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Anki2Importer.kt @@ -68,6 +68,7 @@ open class Anki2Importer(col: Collection?, file: String) : Importer(col!!, file) /** If importing SchedV1 into SchedV2 we need to reset the learning cards */ private var mMustResetLearning = false + @Throws(ImportExportException::class) override fun run() { publishProgress(0, 0, 0) @@ -404,6 +405,7 @@ open class Anki2Importer(col: Collection?, file: String) : Importer(col!!, file) mModelMap!![srcMid] = mid return mid } + /* * Decks * *********************************************************** @@ -529,7 +531,9 @@ open class Anki2Importer(col: Collection?, file: String) : Importer(col!!, file) val scid = cid // To keep track of card id in source var did = cur.getLong(2) val ord = cur.getInt(3) + @CARD_TYPE var type = cur.getInt(4) + @CARD_QUEUE var queue = cur.getInt(5) var due = cur.getLong(6) val ivl = cur.getLong(7) @@ -719,7 +723,6 @@ open class Anki2Importer(col: Collection?, file: String) : Importer(col!!, file) // Mark file addition to media db (see note in Media.java) dst.media.markFileAdd(fname) } catch (e: IOException) { - // the user likely used subdirectories Timber.e(e, "Error copying file %s.", fname) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Importer.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Importer.kt index 4f503bf4a5..a8f6f1c085 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Importer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/importer/Importer.kt @@ -35,6 +35,7 @@ abstract class Importer(col: Collection, protected var file: String) { var cardCount: Int protected set protected val mCol: Collection + @KotlinCleanup("rename") protected var _total: Int private var mTs: Long = 0 @@ -42,6 +43,7 @@ abstract class Importer(col: Collection, protected var file: String) { protected lateinit var src: Collection protected val context: Context protected var progress: TaskManager.ProgressCallback? = null + @Throws(ImportExportException::class) abstract fun run() diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/AbstractDeckTreeNode.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/AbstractDeckTreeNode.kt index 7325aa3540..3205afeaf9 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/AbstractDeckTreeNode.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/AbstractDeckTreeNode.kt @@ -66,8 +66,10 @@ abstract class AbstractDeckTreeNode( /** Line representing this string without its children. Used in timbers only. */ protected open fun toStringLine(): String? { return String.format( - Locale.US, "%s, %d", - fullDeckName, did + Locale.US, + "%s, %d", + fullDeckName, + did ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/BaseSched.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/BaseSched.kt index 1245e96a3f..15c87417d2 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/BaseSched.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/BaseSched.kt @@ -95,7 +95,7 @@ abstract class BaseSched(val col: Collection) { col.newBackend.backend.buryOrSuspendCards( cardIds = cids.toList(), noteIds = listOf(), - mode = mode, + mode = mode ) } @@ -254,7 +254,7 @@ abstract class BaseSched(val col: Collection) { col.newBackend.backend.extendLimits( deckId = col.decks.selected(), newDelta = newc, - reviewDelta = rev, + reviewDelta = rev ) } @@ -475,7 +475,8 @@ abstract class BaseSched(val col: Collection) { fun totalRevForCurrentDeck(): Int { return col.db.queryScalar( "SELECT count() FROM cards WHERE id IN (SELECT id FROM cards WHERE did IN " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ? LIMIT ?)", - today, REPORT_LIMIT + today, + REPORT_LIMIT ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/DeckDueTreeNode.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/DeckDueTreeNode.kt index 7d9f359389..73b3ff429e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/DeckDueTreeNode.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/DeckDueTreeNode.kt @@ -46,8 +46,13 @@ class DeckDueTreeNode( ) : AbstractDeckTreeNode(fullDeckName, did, collapsed, filtered) { override fun toString(): String { return String.format( - Locale.US, "%s, %d, %d, %d, %d", - fullDeckName, did, revCount, lrnCount, newCount + Locale.US, + "%s, %d, %d, %d, %d", + fullDeckName, + did, + revCount, + lrnCount, + newCount ) } @@ -101,8 +106,13 @@ class DeckDueTreeNode( /** Line representing this string without its children. Used in timbers only. */ override fun toStringLine(): String { return String.format( - Locale.US, "%s, %d, %d, %d, %d\n", - fullDeckName, did, revCount, lrnCount, newCount + Locale.US, + "%s, %d, %d, %d, %d\n", + fullDeckName, + did, + revCount, + lrnCount, + newCount ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/LrnCard.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/LrnCard.kt index 99f386cdb7..ab559437c0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/LrnCard.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/LrnCard.kt @@ -21,7 +21,8 @@ import com.ichi2.libanki.Collection class LrnCard(col: Collection, val due: Long, cid: Long) : Card.Cache( - col, cid + col, + cid ), Comparable { override fun compareTo(other: LrnCard): Int { diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Sched.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Sched.kt index 8e152e2def..90b1780f40 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Sched.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/Sched.kt @@ -129,7 +129,9 @@ class Sched(col: Collection) : SchedV2(col) { ).length() > 1 ) { 3 - } else 2 + } else { + 2 + } } else if (card.queue == Consts.QUEUE_TYPE_REV) { 4 } else { @@ -143,7 +145,8 @@ class Sched(col: Collection) : SchedV2(col) { col.log(col.db.queryLongList("select id from cards where " + queueIsBuriedSnippet() + " and did in " + sids)) col.db.execute( "update cards set mod=?,usn=?," + _restoreQueueSnippet() + " where " + queueIsBuriedSnippet() + " and did in " + sids, - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } /* @@ -156,6 +159,7 @@ class Sched(col: Collection) : SchedV2(col) { _checkDay() col.decks.checkIntegrity() val allDecksSorted = col.decks.allSorted() + @KotlinCleanup("input should be non-null") val lims = HashUtil.HashMapInit>(allDecksSorted.size) val deckNodes = ArrayList(allDecksSorted.size) @@ -266,7 +270,9 @@ class Sched(col: Collection) : SchedV2(col) { // collapse or finish return if (_preloadLrnCard(true)) { arrayOf(mLrnQueue) - } else arrayOf() + } else { + arrayOf() + } } /** @@ -281,14 +287,18 @@ class Sched(col: Collection) : SchedV2(col) { mLrnCount = col.db.queryScalar( "SELECT sum(left / 1000) FROM (SELECT left FROM cards WHERE did IN " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_LRN + " AND due < ? and id != ? LIMIT ?)", - dayCutoff, currentCardId(), mReportLimit + dayCutoff, + currentCardId(), + mReportLimit ) if (isCancelled(cancelListener)) return // day mLrnCount += col.db.queryScalar( "SELECT count() FROM cards WHERE did IN " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + " AND due <= ? " + "AND id != ? LIMIT ?", - mToday!!, currentCardId(), mReportLimit + mToday!!, + currentCardId(), + mReportLimit ) } @@ -317,7 +327,9 @@ class Sched(col: Collection) : SchedV2(col) { */mLrnQueue.setFilled() col.db.query( "SELECT due, id FROM cards WHERE did IN " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_LRN + " AND due < ? AND id != ? LIMIT ?", - dayCutoff, currentCardId(), mReportLimit + dayCutoff, + currentCardId(), + mReportLimit ).use { cur -> while (cur.moveToNext()) { mLrnQueue.add(cur.getLong(0), cur.getLong(1)) @@ -347,6 +359,7 @@ class Sched(col: Collection) : SchedV2(col) { */ override fun _answerLrnCard(card: Card, @BUTTON_TYPE ease: Int) { val conf = _lrnConf(card) + @REVLOG_TYPE val type: Int type = if (card.isInDynamicDeck && !card.wasNew) { Consts.REVLOG_CRAM @@ -518,7 +531,8 @@ class Sched(col: Collection) : SchedV2(col) { col.db.execute( "update cards set due = odue, queue = " + Consts.QUEUE_TYPE_REV + ", mod = ?" + ", usn = ?, odue = 0 where queue IN (" + Consts.QUEUE_TYPE_LRN + "," + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + ") and type = " + Consts.CARD_TYPE_REV + " " + extra, - time.intTime(), col.usn() + time.intTime(), + col.usn() ) // new cards in learning forgetCards(col.db.queryLongList("SELECT id FROM cards WHERE queue IN (" + Consts.QUEUE_TYPE_LRN + "," + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + ") " + extra)) @@ -530,13 +544,17 @@ class Sched(col: Collection) : SchedV2(col) { "SELECT sum(left / 1000) FROM (SELECT left FROM cards WHERE did = ?" + " AND queue = " + Consts.QUEUE_TYPE_LRN + " AND due < ?" + " LIMIT ?)", - did, time.intTime() + col.get_config_int("collapseTime"), mReportLimit + did, + time.intTime() + col.get_config_int("collapseTime"), + mReportLimit ) cnt + col.db.queryScalar( "SELECT count() FROM (SELECT 1 FROM cards WHERE did = ?" + " AND queue = " + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + " AND due <= ?" + " LIMIT ?)", - did, mToday!!, mReportLimit + did, + mToday!!, + mReportLimit ) } catch (e: SQLException) { throw RuntimeException(e) @@ -556,6 +574,7 @@ class Sched(col: Collection) : SchedV2(col) { considerCurrentCard ) } + /** * Maximal number of rev card still to see today in deck d. It's computed as: * the number of rev card to see by day according @@ -590,7 +609,9 @@ class Sched(col: Collection) : SchedV2(col) { lim = Math.min(lim, mReportLimit) return col.db.queryScalar( "SELECT count() FROM (SELECT 1 FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ? LIMIT ?)", - did, mToday!!, lim + did, + mToday!!, + lim ) } @@ -613,7 +634,10 @@ class Sched(col: Collection) : SchedV2(col) { return col.db.queryScalar( "SELECT count() FROM (SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " and due <= ? " + " AND id != ? LIMIT ?)", - did, mToday!!, currentCardId(), lim + did, + mToday!!, + currentCardId(), + lim ) } @@ -638,11 +662,14 @@ class Sched(col: Collection) : SchedV2(col) { val idName = if (allowSibling) "id" else "nid" val id = if (allowSibling) currentCardId() else currentCardNid() for ( - cid in col.db.queryLongList( - "SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ?" + - " AND " + idName + " != ? LIMIT ?", - did, mToday!!, id, lim - ) + cid in col.db.queryLongList( + "SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ?" + + " AND " + idName + " != ? LIMIT ?", + did, + mToday!!, + id, + lim + ) ) { /* Difference with upstream: we take current card into account. * @@ -957,6 +984,7 @@ class Sched(col: Collection) : SchedV2(col) { } // dynamic deck; override some attributes, use original deck for others val oconf = col.decks.confForDid(card.oDid) + @KotlinCleanup("use ?:") var delays = conf.optJSONArray("delays") if (delays == null) { @@ -1006,7 +1034,9 @@ class Sched(col: Collection) : SchedV2(col) { val conf = _cardConf(card) return if (conf.getInt("dyn") == DECK_STD) { true - } else conf.getBoolean("resched") + } else { + conf.getBoolean("resched") + } } /** @@ -1068,10 +1098,12 @@ class Sched(col: Collection) : SchedV2(col) { val conf = _lapseConf(card) if (conf.getJSONArray("delays").length() > 0) { (conf.getJSONArray("delays").getDouble(0) * 60.0).toLong() - } else _nextLapseIvl( - card, - conf - ) * SECONDS_PER_DAY + } else { + _nextLapseIvl( + card, + conf + ) * SECONDS_PER_DAY + } } else { // review _nextRevIvl(card, ease) * SECONDS_PER_DAY @@ -1091,24 +1123,28 @@ class Sched(col: Collection) : SchedV2(col) { // early removal if (!_resched(card)) { 0 - } else _graduatingIvl( - card, - conf, - true, - false - ) * SECONDS_PER_DAY + } else { + _graduatingIvl( + card, + conf, + true, + false + ) * SECONDS_PER_DAY + } } else { val left = card.left % 1000 - 1 if (left <= 0) { // graduate if (!_resched(card)) { 0 - } else _graduatingIvl( - card, - conf, - false, - false - ) * SECONDS_PER_DAY + } else { + _graduatingIvl( + card, + conf, + false, + false + ) * SECONDS_PER_DAY + } } else { _delayForGrade(conf, left).toLong() } @@ -1127,7 +1163,8 @@ class Sched(col: Collection) : SchedV2(col) { col.db.execute( "UPDATE cards SET queue = " + Consts.QUEUE_TYPE_SUSPENDED + ", mod = ?, usn = ? WHERE id IN " + Utils.ids2str(ids), - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } @@ -1151,7 +1188,8 @@ class Sched(col: Collection) : SchedV2(col) { "update cards set " + queueIsBuriedSnippet() + ",mod=?,usn=? where id in " + Utils.ids2str( cids ), - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SchedV2.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SchedV2.kt index 9e75fa492c..2e6818b34c 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SchedV2.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SchedV2.kt @@ -65,10 +65,12 @@ open class SchedV2(col: Collection) : AbstractSched(col) { protected var haveQueues = false protected var mHaveCounts = false protected var mToday: Int? = null + @KotlinCleanup("replace Sched.getDayCutoff() with dayCutoff") final override var dayCutoff: Long = 0 private var mLrnCutoff: Long = 0 protected var mNewCount = 0 + @VisibleForTesting(otherwise = VisibleForTesting.PROTECTED) internal var mLrnCount = 0 protected var mRevCount = 0 @@ -334,7 +336,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { val conf = _cardConf(card) return if (card.isInDynamicDeck && !conf.getBoolean("resched")) { 2 - } else 4 + } else { + 4 + } } /** @@ -425,6 +429,7 @@ open class SchedV2(col: Collection) : AbstractSched(col) { } return tot } + /* Deck list **************************************************************** ******************************* */ @@ -694,7 +699,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { // collapse or finish return if (_preloadLrnCard(true)) { arrayOf(mLrnQueue) - } else arrayOf() + } else { + arrayOf() + } } /** pre load the potential next card. It may loads many card because, depending on the time taken, the next card may @@ -727,7 +734,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { protected fun _cntFnNew(did: Long, lim: Int): Int { return col.db.queryScalar( "SELECT count() FROM (SELECT 1 FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_NEW + " AND id != ? LIMIT ?)", - did, currentCardId(), lim + did, + currentCardId(), + lim ) } @@ -754,7 +763,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { will have a nid distinct from 0. As it is used in sql statement, it is not possible to just use a function areSiblings()*/ 0 - } else currentCard!!.nid + } else { + currentCard!!.nid + } } /** @@ -767,7 +778,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { will have a nid distinct from 0. As it is used in sql statement, it is not possible to just use a function areSiblings()*/ 0 - } else mCurrentCard!!.id + } else { + mCurrentCard!!.id + } } protected fun _fillNew(): Boolean { @@ -799,12 +812,12 @@ open class SchedV2(col: Collection) : AbstractSched(col) { */ // fill the queue with the current did for ( - cid in col.db.queryLongList( - "SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_NEW + " AND " + idName + "!= ? ORDER BY due, ord LIMIT ?", - did, - id, - lim - ) + cid in col.db.queryLongList( + "SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_NEW + " AND " + idName + "!= ? ORDER BY due, ord LIMIT ?", + did, + id, + lim + ) ) { mNewQueue.add(cid) } @@ -832,7 +845,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { return if (_fillNew()) { // mNewCount -= 1; see decrementCounts() mNewQueue.removeFirstCard() - } else null + } else { + null + } } private fun _updateNewCardRatio() { @@ -883,7 +898,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { * @param considerCurrentCard Whether current card should be counted if it is in this deck */ protected fun _deckNewLimit(did: Long, fn: LimitMethod?, considerCurrentCard: Boolean): Int { - @Suppress("NAME_SHADOWING") var fn = fn + @Suppress("NAME_SHADOWING") + var fn = fn if (fn == null) { fn = LimitMethod { g: Deck -> _deckNewLimitSingle(g, considerCurrentCard) } } @@ -905,14 +921,16 @@ open class SchedV2(col: Collection) : AbstractSched(col) { /** New count for a single deck. */ fun _newForDeck(did: Long, lim: Int): Int { - @Suppress("NAME_SHADOWING") var lim = lim + @Suppress("NAME_SHADOWING") + var lim = lim if (lim == 0) { return 0 } lim = Math.min(lim, mReportLimit) return col.db.queryScalar( "SELECT count() FROM (SELECT 1 FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_NEW + " LIMIT ?)", - did, lim + did, + lim ) } @@ -979,7 +997,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { // day mLrnCount += col.db.queryScalar( "SELECT count() FROM cards WHERE did IN " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + " AND due <= ? AND id != ?", - mToday!!, currentCardId() + mToday!!, + currentCardId() ) if (isCancelled(cancelListener)) return // previews @@ -1017,7 +1036,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { .query( "SELECT due, id FROM cards WHERE did IN " + _deckLimit() + " AND queue IN (" + Consts.QUEUE_TYPE_LRN + ", " + Consts.QUEUE_TYPE_PREVIEW + ") AND due < ?" + " AND id != ? LIMIT ?", - cutoff, currentCardId(), mReportLimit + cutoff, + currentCardId(), + mReportLimit ).use { cur -> mLrnQueue.setFilled() while (cur.moveToNext()) { @@ -1080,10 +1101,13 @@ open class SchedV2(col: Collection) : AbstractSched(col) { * simulate _getLrnDayCard which did remove the card * from the queue. */for ( - cid in col.db.queryLongList( - "SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + " AND due <= ? and id != ? LIMIT ?", - did, mToday!!, currentCardId(), mQueueLimit - ) + cid in col.db.queryLongList( + "SELECT id FROM cards WHERE did = ? AND queue = " + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + " AND due <= ? and id != ? LIMIT ?", + did, + mToday!!, + currentCardId(), + mQueueLimit + ) ) { mLrnDayQueue.add(cid) } @@ -1109,12 +1133,15 @@ open class SchedV2(col: Collection) : AbstractSched(col) { return if (_fillLrnDay()) { // mLrnCount -= 1; see decrementCounts() mLrnDayQueue.removeFirstCard() - } else null + } else { + null + } } // Overridden protected open fun _answerLrnCard(card: Card, @BUTTON_TYPE ease: Int) { val conf = _lrnConf(card) + @REVLOG_TYPE val type: Int type = if (card.type == Consts.CARD_TYPE_REV || card.type == Consts.CARD_TYPE_RELEARNING) { @@ -1178,7 +1205,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { private fun _rescheduleLrnCard(card: Card, conf: JSONObject, delay: Int? = null): Int { // normal delay for the current step? - @Suppress("NAME_SHADOWING") var delay = delay + @Suppress("NAME_SHADOWING") + var delay = delay if (delay == null) { delay = _delayForGrade(conf, card.left) } @@ -1212,7 +1240,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { } protected fun _delayForGrade(conf: JSONObject, left: Int): Int { - @Suppress("NAME_SHADOWING") var left = left + @Suppress("NAME_SHADOWING") + var left = left left = left % 1000 return try { val delay: Double @@ -1300,7 +1329,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { } private fun _leftToday(delays: JSONArray, left: Int, now: Long): Int { - @Suppress("NAME_SHADOWING") var now = now + @Suppress("NAME_SHADOWING") + var now = now if (now == 0L) { now = time.intTime() } @@ -1398,13 +1428,17 @@ open class SchedV2(col: Collection) : AbstractSched(col) { "SELECT count() FROM (SELECT null FROM cards WHERE did = ?" + " AND queue = " + Consts.QUEUE_TYPE_LRN + " AND due < ?" + " LIMIT ?)", - did, time.intTime() + col.get_config_int("collapseTime"), mReportLimit + did, + time.intTime() + col.get_config_int("collapseTime"), + mReportLimit ) cnt + col.db.queryScalar( "SELECT count() FROM (SELECT null FROM cards WHERE did = ?" + " AND queue = " + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + " AND due <= ?" + " LIMIT ?)", - did, mToday!!, mReportLimit + did, + mToday!!, + mReportLimit ) } catch (e: SQLException) { throw RuntimeException(e) @@ -1479,13 +1513,15 @@ open class SchedV2(col: Collection) : AbstractSched(col) { } protected fun _revForDeck(did: Long, lim: Int, childMap: Decks.Node): Int { - @Suppress("NAME_SHADOWING") var lim = lim + @Suppress("NAME_SHADOWING") + var lim = lim val dids = col.decks.childDids(did, childMap).toMutableList() dids.add(0, did) lim = Math.min(lim, mReportLimit) return col.db.queryScalar( "SELECT count() FROM (SELECT 1 FROM cards WHERE did in " + Utils.ids2str(dids) + " AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ? LIMIT ?)", - mToday!!, lim + mToday!!, + lim ) } @@ -1500,7 +1536,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { if (isCancelled(cancelListener)) return mRevCount = col.db.queryScalar( "SELECT count() FROM (SELECT id FROM cards WHERE did in " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ? AND id != ? LIMIT ?)", - mToday!!, currentCardId(), lim + mToday!!, + currentCardId(), + lim ) } @@ -1535,7 +1573,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { col.db.query( "SELECT id FROM cards WHERE did in " + _deckLimit() + " AND queue = " + Consts.QUEUE_TYPE_REV + " AND due <= ? AND " + idName + " != ?" + " ORDER BY due, random() LIMIT ?", - mToday!!, id, lim + mToday!!, + id, + lim ).use { cur -> while (cur.moveToNext()) { mRevQueue.add(cur.getLong(0)) @@ -1634,8 +1674,14 @@ open class SchedV2(col: Collection) : AbstractSched(col) { protected fun _logRev(card: Card, @BUTTON_TYPE ease: Int, delay: Int, type: Int) { log( - card.id, col.usn(), ease, if (delay != 0) -delay else card.ivl, card.lastIvl, - card.factor, card.timeTaken(), type + card.id, + col.usn(), + ease, + if (delay != 0) -delay else card.ivl, + card.lastIvl, + card.factor, + card.timeTaken(), + type ) } /* @@ -1663,12 +1709,14 @@ open class SchedV2(col: Collection) : AbstractSched(col) { val ivl3 = _constrainedIvl((card.ivl + delay / 2) * fct, conf, ivl2.toDouble(), fuzz) return if (ease == Consts.BUTTON_THREE) { ivl3 - } else _constrainedIvl( - (card.ivl + delay) * fct * conf.getDouble("ease4"), - conf, - ivl3.toDouble(), - fuzz - ) + } else { + _constrainedIvl( + (card.ivl + delay) * fct * conf.getDouble("ease4"), + conf, + ivl3.toDouble(), + fuzz + ) + } } fun _fuzzedIvl(ivl: Int): Int { @@ -1821,7 +1869,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { Consts.DYN_DUEPRIORITY -> String.format( Locale.US, "(case when queue=" + Consts.QUEUE_TYPE_REV + " and due <= %d then (ivl / cast(%d-due+0.001 as real)) else 100000+due end)", - mToday, mToday + mToday, + mToday ) Consts.DYN_DUE -> // if we don't understand the term, default to due order "c.due" @@ -1838,7 +1887,10 @@ open class SchedV2(col: Collection) : AbstractSched(col) { for (id in ids) { data.add( arrayOf( - did, due, u, id + did, + due, + u, + id ) ) due += 1 @@ -1958,7 +2010,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { val conf = _cardConf(card) return if (!card.isInDynamicDeck) { conf.getJSONObject("rev") - } else col.decks.confForDid(card.oDid).getJSONObject("rev") + } else { + col.decks.confForDid(card.oDid).getJSONObject("rev") + } } private fun _previewingCard(card: Card): Boolean { @@ -1989,7 +2043,8 @@ open class SchedV2(col: Collection) : AbstractSched(col) { update(deck) } // unbury if the day has rolled over - val unburied: Int = @Suppress("USELESS_CAST") col.get_config("lastUnburied", 0 as Int)!! + val unburied: Int = @Suppress("USELESS_CAST") + col.get_config("lastUnburied", 0 as Int)!! if (unburied < mToday!!) { SyncStatus.ignoreDatabaseModification { unburyCards() } col.set_config("lastUnburied", mToday) @@ -2024,10 +2079,12 @@ open class SchedV2(col: Collection) : AbstractSched(col) { override fun hasCardsTodayAfterStudyAheadLimit(): Boolean { return if (!BackendFactory.defaultLegacySchema) { super.hasCardsTodayAfterStudyAheadLimit() - } else col.db.queryScalar( - "SELECT 1 FROM cards WHERE did IN " + _deckLimit() + - " AND queue = " + Consts.QUEUE_TYPE_LRN + " LIMIT 1" - ) != 0 + } else { + col.db.queryScalar( + "SELECT 1 FROM cards WHERE did IN " + _deckLimit() + + " AND queue = " + Consts.QUEUE_TYPE_LRN + " LIMIT 1" + ) != 0 + } } fun haveBuriedSiblings(): Boolean { @@ -2059,7 +2116,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { override fun haveBuried(): Boolean { return if (!BackendFactory.defaultLegacySchema) { super.haveBuried() - } else haveManuallyBuried() || haveBuriedSiblings() + } else { + haveManuallyBuried() || haveBuriedSiblings() + } } /* Next time reports ******************************************************** @@ -2074,7 +2133,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { if (_previewingCard(card)) { return if (ease == Consts.BUTTON_ONE) { _previewDelay(card).toLong() - } else 0 + } else { + 0 + } } // (re)learning? return if (card.queue == Consts.QUEUE_TYPE_NEW || card.queue == Consts.QUEUE_TYPE_LRN || card.queue == Consts.QUEUE_TYPE_DAY_LEARN_RELEARN) { @@ -2084,7 +2145,9 @@ open class SchedV2(col: Collection) : AbstractSched(col) { val conf = _lapseConf(card) if (conf.getJSONArray("delays").length() > 0) { (conf.getJSONArray("delays").getDouble(0) * 60.0).toLong() - } else _lapseIvl(card, conf) * Stats.SECONDS_PER_DAY + } else { + _lapseIvl(card, conf) * Stats.SECONDS_PER_DAY + } } else { // review val early = card.isInDynamicDeck && card.oDue > mToday!! @@ -2167,7 +2230,8 @@ end) """ col.db.execute( "UPDATE cards SET queue = " + Consts.QUEUE_TYPE_SUSPENDED + ", mod = ?, usn = ? WHERE id IN " + Utils.ids2str(ids), - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } @@ -2183,7 +2247,8 @@ end) """ col.db.execute( "UPDATE cards SET " + _restoreQueueSnippet() + ", mod = ?, usn = ?" + " WHERE queue = " + Consts.QUEUE_TYPE_SUSPENDED + " AND id IN " + Utils.ids2str(ids), - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } @@ -2202,7 +2267,9 @@ end) """ col.log(*cids.toTypedArray()) col.db.execute( "update cards set queue=?,mod=?,usn=? where id in " + Utils.ids2str(cids), - queue, time.intTime(), col.usn() + queue, + time.intTime(), + col.usn() ) } @@ -2241,7 +2308,8 @@ end) """ col.log(col.db.queryLongList("select id from cards where $queue $deckConstraint")) col.db.execute( "update cards set mod=?,usn=?, " + _restoreQueueSnippet() + " where " + queue + deckConstraint, - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } @@ -2259,7 +2327,8 @@ end) """ return } val cids = col.db.queryLongList( - "SELECT id FROM cards WHERE nid = ? AND queue >= " + Consts.CARD_TYPE_NEW, nid + "SELECT id FROM cards WHERE nid = ? AND queue >= " + Consts.CARD_TYPE_NEW, + nid ).toLongArray() buryCards(cids) } @@ -2411,7 +2480,10 @@ end) """ col.db.execute( "UPDATE cards SET mod = ?, usn = ?, due = due + ?" + " WHERE id NOT IN " + scids + " AND due >= ? AND type = " + Consts.CARD_TYPE_NEW, - now, col.usn(), shiftBy, low + now, + col.usn(), + shiftBy, + low ) } } @@ -2465,12 +2537,15 @@ end) """ if (schedVer == 1) { col.db.execute( "update cards set due = odue, queue = " + Consts.QUEUE_TYPE_REV + ", type = " + Consts.CARD_TYPE_REV + ", mod = ?, usn = ?, odue = 0 where queue in (" + Consts.QUEUE_TYPE_LRN + "," + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + ") and type in (" + Consts.CARD_TYPE_REV + "," + Consts.CARD_TYPE_RELEARNING + ")", - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } else { col.db.execute( "update cards set due = ?+ivl, queue = " + Consts.QUEUE_TYPE_REV + ", type = " + Consts.CARD_TYPE_REV + ", mod = ?, usn = ?, odue = 0 where queue in (" + Consts.QUEUE_TYPE_LRN + "," + Consts.QUEUE_TYPE_DAY_LEARN_RELEARN + ") and type in (" + Consts.CARD_TYPE_REV + "," + Consts.CARD_TYPE_RELEARNING + ")", - mToday, time.intTime(), col.usn() + mToday, + time.intTime(), + col.usn() ) } @@ -2482,7 +2557,8 @@ end) """ private fun _resetSuspendedLearning() { col.db.execute( "update cards set type = (case when type = " + Consts.CARD_TYPE_LRN + " then " + Consts.CARD_TYPE_NEW + " when type in (" + Consts.CARD_TYPE_REV + ", " + Consts.CARD_TYPE_RELEARNING + ") then " + Consts.CARD_TYPE_REV + " else type end), due = (case when odue then odue else due end), odue = 0, mod = ?, usn = ? where queue < 0", - time.intTime(), col.usn() + time.intTime(), + col.usn() ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SimpleCardQueue.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SimpleCardQueue.kt index 12b8eaabb1..4f488706e5 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SimpleCardQueue.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sched/SimpleCardQueue.kt @@ -19,7 +19,8 @@ package com.ichi2.libanki.sched import com.ichi2.libanki.Card import com.ichi2.utils.KotlinCleanup -@KotlinCleanup("Make sched non-null ") class SimpleCardQueue(sched: AbstractSched?) : CardQueue(sched) { +@KotlinCleanup("Make sched non-null ") +class SimpleCardQueue(sched: AbstractSched?) : CardQueue(sched) { fun add(id: Long) { add(col?.let { Card.Cache(it, id) }) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/stats/AdvancedStatistics.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/stats/AdvancedStatistics.kt index 9de017cdbc..b1b637aa0b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/stats/AdvancedStatistics.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/stats/AdvancedStatistics.kt @@ -174,8 +174,10 @@ class AdvancedStatistics { ).toDouble() // Y-Axis: # Young seriesList[REVIEW_TYPE_RELEARN_PLUS_1][t] = data[REVIEW_TYPE_LEARN_PLUS_1] .toDouble() // Y-Axis: # Learn - if (data[TIME] > lastElement) lastElement = data[TIME] - .toDouble() // X-Axis: Max. value (only for TYPE_LIFE) + if (data[TIME] > lastElement) { + lastElement = data[TIME] + .toDouble() // X-Axis: Max. value (only for TYPE_LIFE) + } if (data[TIME] == 0) { zeroIndex = t // Because we retrieve dues in the past and we should not cumulate them } @@ -314,9 +316,17 @@ class AdvancedStatistics { nInState[i][CARD_TYPE_NEW].toDouble() ) } else { - if (i == 0) nInStateCum[i] = doubleArrayOf( - i.toDouble(), 0.0, 0.0, 0.0, 0.0 - ) else nInStateCum[i] = nInStateCum[i - 1] + if (i == 0) { + nInStateCum[i] = doubleArrayOf( + i.toDouble(), + 0.0, + 0.0, + 0.0, + 0.0 + ) + } else { + nInStateCum[i] = nInStateCum[i - 1] + } } } @@ -478,10 +488,12 @@ class AdvancedStatistics { mProbabilities[CARD_TYPE_NEW] = calculateProbabilitiesForNewEaseForCurrentEase(queryNew, mPriorNew) mProbabilities[CARD_TYPE_YOUNG] = calculateProbabilitiesForNewEaseForCurrentEase( - queryYoung, mPriorYoung + queryYoung, + mPriorYoung ) mProbabilities[CARD_TYPE_MATURE] = calculateProbabilitiesForNewEaseForCurrentEase( - queryMature, mPriorMature + queryMature, + mPriorMature ) mProbabilitiesCumulative[CARD_TYPE_NEW] = cumsum( mProbabilities[CARD_TYPE_NEW] @@ -736,15 +748,19 @@ class AdvancedStatistics { // Since it's the average, it can be a non-integer // Adding a review to a non-integer can make it exceed the maximum # reviews per day, but not by 1 or more // So if we take the floor when displaying it, we will display the maximum # reviews - simulationResult = if (mSettings!!.computeNDays > 0) SimulationResult( - nTimeBins, - timeBinLength, - DOUBLE_TO_INT_MODE_FLOOR - ) else SimulationResult( - nTimeBins, - timeBinLength, - DOUBLE_TO_INT_MODE_ROUND - ) + simulationResult = if (mSettings!!.computeNDays > 0) { + SimulationResult( + nTimeBins, + timeBinLength, + DOUBLE_TO_INT_MODE_FLOOR + ) + } else { + SimulationResult( + nTimeBins, + timeBinLength, + DOUBLE_TO_INT_MODE_ROUND + ) + } // nSmooth=1 @@ -880,10 +896,14 @@ class AdvancedStatistics { for (i in 0 until m) { intMatrix[i] = IntArray(n) for (j in 0 until n) { - if (doubleToIntMode == DOUBLE_TO_INT_MODE_ROUND) intMatrix[i]!![j] = - Math.round( - doubleMatrix[i][j] - ).toInt() else intMatrix[i]!![j] = doubleMatrix[i][j].toInt() + if (doubleToIntMode == DOUBLE_TO_INT_MODE_ROUND) { + intMatrix[i]!![j] = + Math.round( + doubleMatrix[i][j] + ).toInt() + } else { + intMatrix[i]!![j] = doubleMatrix[i][j].toInt() + } } } return intMatrix.requireNoNulls() @@ -1307,8 +1327,12 @@ class AdvancedStatistics { mOutcome = 0 // # Rate-limit new cards by shifting starting time - if (card.type == CARD_TYPE_NEW) t = newCardSimulator.simulateNewCard(mDeck) else t = - card.due + if (card.type == CARD_TYPE_NEW) { + t = newCardSimulator.simulateNewCard(mDeck) + } else { + t = + card.due + } // Set state of card between start and first review // New reviews happen with probability 1 @@ -1347,9 +1371,13 @@ class AdvancedStatistics { mNewCard!!.setAll(mCard) val reviewOutcome: ReviewOutcome reviewOutcome = - if (t >= mSettings!!.computeNDays || mProb < mSettings!!.computeMaxError) mClassifier.simSingleReview( - mNewCard - ) else mClassifier.simSingleReview(mNewCard, mOutcome) + if (t >= mSettings!!.computeNDays || mProb < mSettings!!.computeMaxError) { + mClassifier.simSingleReview( + mNewCard + ) + } else { + mClassifier.simSingleReview(mNewCard, mOutcome) + } // Timber.d("Simulation at t=" + tElapsed + ": outcome " + outcomeIdx + ": " + reviewOutcome.toString() ); mNewCard = reviewOutcome.card @@ -1359,11 +1387,13 @@ class AdvancedStatistics { mNewCard!!.lastReview = t // If card failed, update "relearn" count - if (mNewCard!!.correct == 0) mSimulationResult.incrementNReviews( - 3, - t, - mProb * outcomeProb - ) + if (mNewCard!!.correct == 0) { + mSimulationResult.incrementNReviews( + 3, + t, + mProb * outcomeProb + ) + } // Set state of card between current and next review mSimulationResult.updateNInState( diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/stats/Stats.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/stats/Stats.kt index faf192e238..767b0ba53b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/stats/Stats.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/stats/Stats.kt @@ -194,6 +194,7 @@ class Stats(private val col: com.ichi2.libanki.Collection, did: Long) { } else { 3600.0 // hours } + @Suppress("UNUSED_VARIABLE") val cut = col.sched.dayCutoff val cardCount = col.db.queryScalar("select count(id) from cards $lim") @@ -465,7 +466,8 @@ from cards where did in ${_limit()} and queue = ${Consts.QUEUE_TYPE_REV}""" mHasColoredCumulative = false cumulative = createCumulative( arrayOf( - seriesList!![0], seriesList!![1] + seriesList!![0], + seriesList!![1] ), mZeroIndex ) @@ -520,7 +522,10 @@ from cards where did in ${_limit()} and queue = ${Consts.QUEUE_TYPE_REV}""" R.string.statistics_mature ) mColors = intArrayOf( - R.attr.stats_cram, R.attr.stats_learn, R.attr.stats_relearn, R.attr.stats_young, + R.attr.stats_cram, + R.attr.stats_learn, + R.attr.stats_relearn, + R.attr.stats_young, R.attr.stats_mature ) var num = 0 @@ -601,8 +606,12 @@ from cards where did in ${_limit()} and queue = ${Consts.QUEUE_TYPE_REV}""" while (cur.moveToNext()) { list.add( doubleArrayOf( - cur.getDouble(0), cur.getDouble(5), cur.getDouble(1), cur.getDouble(4), - cur.getDouble(2), cur.getDouble(3) + cur.getDouble(0), + cur.getDouble(5), + cur.getDouble(1), + cur.getDouble(4), + cur.getDouble(2), + cur.getDouble(3) ) ) } @@ -884,7 +893,8 @@ from cards where did in ${_limit()} and queue = ${Consts.QUEUE_TYPE_REV}""" } Collections.sort(list) { s1: DoubleArray, s2: DoubleArray -> java.lang.Double.compare( - s1[0], s2[0] + s1[0], + s2[0] ) } seriesList = Array(4) { DoubleArray(list.size) } diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sync/HttpSyncer.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sync/HttpSyncer.kt index 46f13117eb..260ac00d94 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sync/HttpSyncer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sync/HttpSyncer.kt @@ -88,11 +88,14 @@ open class HttpSyncer( @Volatile private var mHttpClient: OkHttpClient? = null private val mHostNum: HostNum + @KotlinCleanup("simplify with ?:") private val httpClient: OkHttpClient get() = if (mHttpClient != null) { mHttpClient!! - } else setupHttpClient() + } else { + setupHttpClient() + } // PERF: Thread safety isn't required for the current implementation @Synchronized diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/sync/MediaSyncer.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/sync/MediaSyncer.kt index c3f75bc37a..9abf3a6ab0 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/sync/MediaSyncer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/sync/MediaSyncer.kt @@ -178,7 +178,8 @@ class MediaSyncer( } con.publishProgress( String.format( - AnkiDroidApp.appResources.getString(R.string.sync_media_changes_count), toSend + AnkiDroidApp.appResources.getString(R.string.sync_media_changes_count), + toSend ) ) val changes = server.uploadChanges(zip) @@ -190,7 +191,9 @@ class MediaSyncer( String.format( Locale.US, "processed %d, serverUsn %d, clientUsn %d", - processedCnt, serverLastUsn, lastUsn + processedCnt, + serverLastUsn, + lastUsn ) ) if (serverLastUsn - processedCnt == lastUsn) { @@ -243,7 +246,8 @@ class MediaSyncer( } con.publishProgress( String.format( - AnkiDroidApp.appResources.getString(R.string.sync_media_downloaded_count), mDownloadCount + AnkiDroidApp.appResources.getString(R.string.sync_media_downloaded_count), + mDownloadCount ) ) } catch (e: IOException) { diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/template/ParsedNode.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/template/ParsedNode.kt index 9ed9a91f01..9123f8d07d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/template/ParsedNode.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/template/ParsedNode.kt @@ -56,9 +56,13 @@ abstract class ParsedNode { } catch (er: TemplateError) { Timber.w(er) val side = - if (question) context.getString(R.string.card_template_editor_front) else context.getString( - R.string.card_template_editor_back - ) + if (question) { + context.getString(R.string.card_template_editor_front) + } else { + context.getString( + R.string.card_template_editor_back + ) + } val explanation = context.getString(R.string.has_a_problem, side, er.message(context)) val more_explanation = "" + context.getString(R.string.more_information) + "" diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/template/TemplateFilters.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/template/TemplateFilters.kt index a02ac63fc3..0a2e999d87 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/template/TemplateFilters.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/template/TemplateFilters.kt @@ -203,7 +203,8 @@ object TemplateFilters { replacement, Matcher.quoteReplacement( m.group(0)!!.replace( - "{{c$ord::", "{{C$ord::" + "{{c$ord::", + "{{C$ord::" ) ) ) diff --git a/AnkiDroid/src/main/java/com/ichi2/libanki/template/Tokenizer.kt b/AnkiDroid/src/main/java/com/ichi2/libanki/template/Tokenizer.kt index 616102d7e3..e879efd9e4 100644 --- a/AnkiDroid/src/main/java/com/ichi2/libanki/template/Tokenizer.kt +++ b/AnkiDroid/src/main/java/com/ichi2/libanki/template/Tokenizer.kt @@ -172,6 +172,7 @@ class Tokenizer internal constructor(template: String) : Iterator") @@ -202,13 +203,15 @@ class Tokenizer internal constructor(template: String) : Iterator Token( - TokenKind.OPEN_CONDITIONAL, - start.substring(1).trim { it <= ' ' } - ) - '/' -> Token( - TokenKind.CLOSE_CONDITIONAL, - start.substring(1).trim { it <= ' ' } - ) - '^' -> Token( - TokenKind.OPEN_NEGATED, - start.substring(1).trim { it <= ' ' } - ) - else -> Token( - TokenKind.REPLACEMENT, - start - ) + } else { + when (start[0]) { + '#' -> Token( + TokenKind.OPEN_CONDITIONAL, + start.substring(1).trim { it <= ' ' } + ) + '/' -> Token( + TokenKind.CLOSE_CONDITIONAL, + start.substring(1).trim { it <= ' ' } + ) + '^' -> Token( + TokenKind.OPEN_NEGATED, + start.substring(1).trim { it <= ' ' } + ) + else -> Token( + TokenKind.REPLACEMENT, + start + ) + } } } @@ -259,7 +264,9 @@ class Tokenizer internal constructor(template: String) : Iterator = ArrayList() diff --git a/AnkiDroid/src/main/java/com/ichi2/preferences/HtmlHelpPreference.kt b/AnkiDroid/src/main/java/com/ichi2/preferences/HtmlHelpPreference.kt index 9009ab366d..56243c430e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/preferences/HtmlHelpPreference.kt +++ b/AnkiDroid/src/main/java/com/ichi2/preferences/HtmlHelpPreference.kt @@ -50,7 +50,7 @@ class HtmlHelpPreference(context: Context, attrs: AttributeSet?) : Preference(co arrayOf( getString(R.styleable.HtmlHelpPreference_substitution1), getString(R.styleable.HtmlHelpPreference_substitution2), - getString(R.styleable.HtmlHelpPreference_substitution3), + getString(R.styleable.HtmlHelpPreference_substitution3) ) } diff --git a/AnkiDroid/src/main/java/com/ichi2/preferences/NumberRangePreference.kt b/AnkiDroid/src/main/java/com/ichi2/preferences/NumberRangePreference.kt index 9341a7a668..67ce30c63b 100644 --- a/AnkiDroid/src/main/java/com/ichi2/preferences/NumberRangePreference.kt +++ b/AnkiDroid/src/main/java/com/ichi2/preferences/NumberRangePreference.kt @@ -157,6 +157,7 @@ open class NumberRangePreference : android.preference.EditTextPreference, AutoFo * @return the persisted value. */ get() = getPersistedInt(mMin) + /** * Set this preference's value. The value is validated and persisted as an Integer. * diff --git a/AnkiDroid/src/main/java/com/ichi2/preferences/SeekBarPreferenceCompat.kt b/AnkiDroid/src/main/java/com/ichi2/preferences/SeekBarPreferenceCompat.kt index 0909517b43..4ba12e5641 100644 --- a/AnkiDroid/src/main/java/com/ichi2/preferences/SeekBarPreferenceCompat.kt +++ b/AnkiDroid/src/main/java/com/ichi2/preferences/SeekBarPreferenceCompat.kt @@ -258,7 +258,8 @@ constructor( fun getLayoutParams(weight: Float): LinearLayout.LayoutParams { return LinearLayout.LayoutParams( LinearLayout.LayoutParams.WRAP_CONTENT, - LinearLayout.LayoutParams.WRAP_CONTENT, weight + LinearLayout.LayoutParams.WRAP_CONTENT, + weight ) } } diff --git a/AnkiDroid/src/main/java/com/ichi2/preferences/StepsPreference.kt b/AnkiDroid/src/main/java/com/ichi2/preferences/StepsPreference.kt index 8ec78ed1b8..e020b54e42 100644 --- a/AnkiDroid/src/main/java/com/ichi2/preferences/StepsPreference.kt +++ b/AnkiDroid/src/main/java/com/ichi2/preferences/StepsPreference.kt @@ -72,7 +72,8 @@ class StepsPreference : android.preference.EditTextPreference, AutoFocusable { showThemedToast(context, context.resources.getString(R.string.steps_error), false) } else if (validated.isEmpty() && !mAllowEmpty) { showThemedToast( - context, context.resources.getString(R.string.steps_min_error), + context, + context.resources.getString(R.string.steps_min_error), false ) } else { diff --git a/AnkiDroid/src/main/java/com/ichi2/preferences/VersatileTextPreference.kt b/AnkiDroid/src/main/java/com/ichi2/preferences/VersatileTextPreference.kt index d469815f7a..bb5dcbbfc1 100644 --- a/AnkiDroid/src/main/java/com/ichi2/preferences/VersatileTextPreference.kt +++ b/AnkiDroid/src/main/java/com/ichi2/preferences/VersatileTextPreference.kt @@ -41,7 +41,8 @@ open class VersatileTextPreference(context: Context, attrs: AttributeSet?) : EditTextPreference(context, attrs), DialogFragmentProvider { fun interface Validator { - @Throws(Exception::class) fun validate(value: String) + @Throws(Exception::class) + fun validate(value: String) } val referenceEditText = AppCompatEditText(context, attrs) diff --git a/AnkiDroid/src/main/java/com/ichi2/themes/HtmlColors.kt b/AnkiDroid/src/main/java/com/ichi2/themes/HtmlColors.kt index 89a7285328..5f1191d766 100644 --- a/AnkiDroid/src/main/java/com/ichi2/themes/HtmlColors.kt +++ b/AnkiDroid/src/main/java/com/ichi2/themes/HtmlColors.kt @@ -26,7 +26,8 @@ import java.util.regex.Pattern @KotlinCleanup("for better possibly-null handling") object HtmlColors { private val fHtmlColorPattern = Pattern.compile( - "((?:color|background)\\s*[=:]\\s*\"?)((?:[a-z]+|#[0-9a-f]+|rgb\\([0-9]+,\\s*[0-9],+\\s*[0-9]+\\)))([\";\\s])", Pattern.CASE_INSENSITIVE + "((?:color|background)\\s*[=:]\\s*\"?)((?:[a-z]+|#[0-9a-f]+|rgb\\([0-9]+,\\s*[0-9],+\\s*[0-9]+\\)))([\";\\s])", + Pattern.CASE_INSENSITIVE ) private val fShortHexColorPattern = Pattern.compile("^#([0-9a-f])([0-9a-f])([0-9a-f])$", Pattern.CASE_INSENSITIVE) private val fLongHexColorPattern = Pattern.compile("^#([0-9a-f]{2})([0-9a-f]{2})([0-9a-f]{2})$", Pattern.CASE_INSENSITIVE) @@ -46,7 +47,9 @@ object HtmlColors { val normalisedName = name.lowercase(Locale.US) return if (sColorsMap!!.containsKey(normalisedName)) { sColorsMap!![normalisedName] - } else name + } else { + name + } } /** @@ -67,7 +70,8 @@ object HtmlColors { m2 = fShortHexColorPattern.matcher(color) if (m2.find()) { color = String.format( - Locale.US, "#%x%x%x", + Locale.US, + "#%x%x%x", 0xf - m2.group(1)!!.toInt(16), 0xf - m2.group(2)!!.toInt(16), 0xf - m2.group(3)!!.toInt(16) @@ -77,7 +81,8 @@ object HtmlColors { m2 = fLongHexColorPattern.matcher(color) if (m2.find()) { color = String.format( - Locale.US, "#%02x%02x%02x", + Locale.US, + "#%02x%02x%02x", 0xff - m2.group(1)!!.toInt(16), 0xff - m2.group(2)!!.toInt(16), 0xff - m2.group(3)!!.toInt(16) @@ -87,7 +92,8 @@ object HtmlColors { m2 = fRgbColorPattern.matcher(color) if (m2.find()) { color = String.format( - Locale.US, "rgb(%d, %d, %d)", + Locale.US, + "rgb(%d, %d, %d)", 0xff - m2.group(1)!!.toInt(), 0xff - m2.group(2)!!.toInt(), 0xff - m2.group(3)!!.toInt() diff --git a/AnkiDroid/src/main/java/com/ichi2/ui/AnimationUtil.kt b/AnkiDroid/src/main/java/com/ichi2/ui/AnimationUtil.kt index b53584497b..df7521228a 100644 --- a/AnkiDroid/src/main/java/com/ichi2/ui/AnimationUtil.kt +++ b/AnkiDroid/src/main/java/com/ichi2/ui/AnimationUtil.kt @@ -35,8 +35,10 @@ object AnimationUtil { } val set = AnimationSet(true) val expandAnimation = ScaleAnimation( - 1f, 1f, - 1f, 0.5f + 1f, + 1f, + 1f, + 0.5f ) expandAnimation.duration = DURATION_MILLIS.toLong() expandAnimation.setAnimationListener(object : Animation.AnimationListener { @@ -67,8 +69,10 @@ object AnimationUtil { // Sadly this seems necessary - yScale didn't work. val set = AnimationSet(true) val resetEditTextScale = ScaleAnimation( - 1f, 1f, - 1f, 1f + 1f, + 1f, + 1f, + 1f ) resetEditTextScale.duration = DURATION_MILLIS.toLong() val alphaAnimation = AlphaAnimation(0.0f, 1.0f) diff --git a/AnkiDroid/src/main/java/com/ichi2/ui/AppCompatPreferenceActivity.kt b/AnkiDroid/src/main/java/com/ichi2/ui/AppCompatPreferenceActivity.kt index cd5fc44c8e..f767afcf3e 100644 --- a/AnkiDroid/src/main/java/com/ichi2/ui/AppCompatPreferenceActivity.kt +++ b/AnkiDroid/src/main/java/com/ichi2/ui/AppCompatPreferenceActivity.kt @@ -152,7 +152,9 @@ abstract class AppCompatPreferenceActivity): String? { - var apkgCount = 0 var colpkgCount = 0 @@ -368,7 +367,6 @@ object ImportUtils { * @param pathList list of path(s) to apkg file which will be imported */ private fun sendShowImportFileDialogMsg(pathList: ArrayList) { - // Get the filename from the path val f = File(pathList.first()) val filename = f.name diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/KotlinCleanup.kt b/AnkiDroid/src/main/java/com/ichi2/utils/KotlinCleanup.kt index 31ff0c8faf..846bcb2233 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/KotlinCleanup.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/KotlinCleanup.kt @@ -36,9 +36,13 @@ annotation class KotlinCleanup(val value: String) * by default. */ @Target( - AnnotationTarget.CLASS, AnnotationTarget.FUNCTION, - AnnotationTarget.VALUE_PARAMETER, AnnotationTarget.EXPRESSION, - AnnotationTarget.FIELD, AnnotationTarget.PROPERTY, AnnotationTarget.LOCAL_VARIABLE + AnnotationTarget.CLASS, + AnnotationTarget.FUNCTION, + AnnotationTarget.VALUE_PARAMETER, + AnnotationTarget.EXPRESSION, + AnnotationTarget.FIELD, + AnnotationTarget.PROPERTY, + AnnotationTarget.LOCAL_VARIABLE ) @Retention(AnnotationRetention.SOURCE) @Repeatable diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt b/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt index d383ae002c..757928014d 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/LanguageUtil.kt @@ -129,7 +129,8 @@ object LanguageUtil { "粵語" to "yue", // Cantonese "中文 (中国)" to "zh-CN", // Chinese (China) "中文 (台灣)" to "zh-TW", // Chinese (Taiwan) - "isiZulu" to "zu", // Zulu + "isiZulu" to "zu" // Zulu + ) /** Backend languages; may not include recently added ones. @@ -188,7 +189,7 @@ object LanguageUtil { "uk", // Yкраїнська мова "vi", // Tiếng Việt "zh-CN", // 简体中文 - "zh-TW", // 繁體中文 + "zh-TW" // 繁體中文 ) /** @@ -275,6 +276,7 @@ object LanguageUtil { * @return the language defined by the preferences, or the empty string. */ fun SharedPreferences.getLanguage() = getString(Preferences.LANGUAGE, "") + /** * @return the language defined by the preferences, or otherwise the default locale */ diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/NoteFieldDecorator.kt b/AnkiDroid/src/main/java/com/ichi2/utils/NoteFieldDecorator.kt index 44b6c14d9b..e173bbf6bf 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/NoteFieldDecorator.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/NoteFieldDecorator.kt @@ -59,7 +59,7 @@ object NoteFieldDecorator { "unacvatpuvarfr", "jro5atnl", "FuevquneTbry", - "Nxfunl0701", + "Nxfunl0701" ) fun aplicaHuevo(fieldText: String?): String? { @@ -84,10 +84,13 @@ object NoteFieldDecorator { val revuelto = StringBuilder() for (i in 0 until huevo.length) { var c = huevo[i] - if (c >= 'a' && c <= 'm') c += 13.toChar().code - else if (c >= 'A' && c <= 'M') c += 13.toChar().code - else if (c >= 'n' && c <= 'z') c -= 13.toChar().code - else if (c >= 'N' && c <= 'Z') c -= 13.toChar().code + if (c >= 'a' && c <= 'm') { + c += 13.toChar().code + } else if (c >= 'A' && c <= 'M') { + c += 13.toChar().code + } else if (c >= 'n' && c <= 'z') { + c -= 13.toChar().code + } else if (c >= 'N' && c <= 'Z') c -= 13.toChar().code revuelto.append(c) } return revuelto.toString() diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/SyncStatus.kt b/AnkiDroid/src/main/java/com/ichi2/utils/SyncStatus.kt index c6b798e57f..26907b7c76 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/SyncStatus.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/SyncStatus.kt @@ -28,6 +28,7 @@ import net.ankiweb.rsdroid.BackendFactory enum class SyncStatus { INCONCLUSIVE, NO_ACCOUNT, NO_CHANGES, HAS_CHANGES, FULL_SYNC, BADGE_DISABLED, + /** * Scope storage migration is ongoing. Sync should be disabled. */ diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/TypedFilter.kt b/AnkiDroid/src/main/java/com/ichi2/utils/TypedFilter.kt index ac5adf22d7..3b8b67deee 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/TypedFilter.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/TypedFilter.kt @@ -29,7 +29,6 @@ abstract class TypedFilter(private val getCurrentItems: (() -> List)) : Fi } override fun performFiltering(constraint: CharSequence?): FilterResults { - val itemsBeforeFiltering = getCurrentItems() if (constraint.isNullOrBlank()) { @@ -60,6 +59,7 @@ abstract class TypedFilter(private val getCurrentItems: (() -> List)) : Fi * @see Filter.performFiltering */ abstract fun filterResults(constraint: CharSequence, items: List): List + /** @see android.widget.Filter.publishResults */ abstract fun publishResults(constraint: CharSequence?, results: List) } diff --git a/AnkiDroid/src/main/java/com/ichi2/utils/WebViewDebugging.kt b/AnkiDroid/src/main/java/com/ichi2/utils/WebViewDebugging.kt index 9b44304282..af5eec8d48 100644 --- a/AnkiDroid/src/main/java/com/ichi2/utils/WebViewDebugging.kt +++ b/AnkiDroid/src/main/java/com/ichi2/utils/WebViewDebugging.kt @@ -24,6 +24,7 @@ import androidx.annotation.UiThread object WebViewDebugging { private var sHasSetDataDirectory = false + @UiThread fun initializeDebugging(sharedPrefs: SharedPreferences) { // DEFECT: We might be able to cache this value: check what happens on WebView Renderer crash diff --git a/AnkiDroid/src/main/java/com/ichi2/widget/AnkiDroidWidgetSmall.kt b/AnkiDroid/src/main/java/com/ichi2/widget/AnkiDroidWidgetSmall.kt index 2a6587e670..9c35ffcffd 100644 --- a/AnkiDroid/src/main/java/com/ichi2/widget/AnkiDroidWidgetSmall.kt +++ b/AnkiDroid/src/main/java/com/ichi2/widget/AnkiDroidWidgetSmall.kt @@ -152,7 +152,9 @@ class AnkiDroidWidgetSmall : AppWidgetProvider() { ankiDroidIntent.action = Intent.ACTION_MAIN ankiDroidIntent.addCategory(Intent.CATEGORY_LAUNCHER) val pendingAnkiDroidIntent = CompatHelper.compat.getImmutableActivityIntent( - context, 0, ankiDroidIntent, + context, + 0, + ankiDroidIntent, PendingIntent.FLAG_UPDATE_CURRENT ) updateViews.setOnClickPendingIntent(R.id.ankidroid_widget_small_button, pendingAnkiDroidIntent) diff --git a/AnkiDroid/src/main/java/com/wildplot/android/parsing/Atom.kt b/AnkiDroid/src/main/java/com/wildplot/android/parsing/Atom.kt index 433e69b21c..a91fc83f7f 100644 --- a/AnkiDroid/src/main/java/com/wildplot/android/parsing/Atom.kt +++ b/AnkiDroid/src/main/java/com/wildplot/android/parsing/Atom.kt @@ -53,9 +53,12 @@ class Atom(private val parser: TopLevelParser) : TreeElement { expression = expressionInBrackets atomType = EXP_IN_BRACKETS true - } else false - } else + } else { + false + } + } else { false + } } private fun initAsFunctionMath(atomString: String): Boolean { @@ -64,7 +67,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = FUNCTION_MATH atomObject = mathFunctionAtom true - } else false + } else { + false + } } private fun initAsFunctionX(atomString: String): Boolean { @@ -73,7 +78,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = FUNCTION_X atomObject = functionXAtom true - } else false + } else { + false + } } private fun initAsFunctionXY(atomString: String): Boolean { @@ -82,7 +89,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = FUNCTION_X_Y atomObject = functionXYAtom true - } else false + } else { + false + } } private fun initAsNumber(atomString: String): Boolean { @@ -91,7 +100,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = numberAtom.getAtomType() atomObject = numberAtom true - } else false + } else { + false + } } private fun initAsXVariable(atomString: String): Boolean { @@ -99,7 +110,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = VARIABLE atomObject = XVariableAtom(parser) true - } else false + } else { + false + } } private fun initAsYVariable(atomString: String): Boolean { @@ -107,7 +120,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = VARIABLE atomObject = YVariableAtom(parser) true - } else false + } else { + false + } } private fun initAsVariable(atomString: String): Boolean { @@ -116,7 +131,9 @@ class Atom(private val parser: TopLevelParser) : TreeElement { atomType = variableAtom.atomType atomObject = variableAtom true - } else false + } else { + false + } } @get:Throws(ExpressionFormatException::class) diff --git a/AnkiDroid/src/main/java/com/wildplot/android/parsing/AtomTypes/MathFunctionAtom.kt b/AnkiDroid/src/main/java/com/wildplot/android/parsing/AtomTypes/MathFunctionAtom.kt index 7738dce7e5..d7aafb4d24 100644 --- a/AnkiDroid/src/main/java/com/wildplot/android/parsing/AtomTypes/MathFunctionAtom.kt +++ b/AnkiDroid/src/main/java/com/wildplot/android/parsing/AtomTypes/MathFunctionAtom.kt @@ -14,6 +14,7 @@ * this program. If not, see . * ****************************************************************************************/ @file:Suppress("PackageName") // AtomTypes: copied from wildplot library + package com.wildplot.android.parsing.AtomTypes import com.wildplot.android.parsing.Expression @@ -71,19 +72,21 @@ class MathFunctionAtom(funcString: String, private val parser: TopLevelParser) : override val value: Double get() = if (hasSavedValue) { savedValue - } else when (mathType) { - MathType.SIN -> sin(expression!!.value) - MathType.COS -> cos(expression!!.value) - MathType.TAN -> tan(expression!!.value) - MathType.SQRT -> sqrt(expression!!.value) - MathType.ACOS -> acos(expression!!.value) - MathType.ASIN -> asin(expression!!.value) - MathType.ATAN -> atan(expression!!.value) - MathType.SINH -> sinh(expression!!.value) - MathType.COSH -> cosh(expression!!.value) - MathType.LOG -> log10(expression!!.value) - MathType.LN -> ln(expression!!.value) - MathType.INVALID -> throw ExpressionFormatException("Number is Invalid, cannot parse") + } else { + when (mathType) { + MathType.SIN -> sin(expression!!.value) + MathType.COS -> cos(expression!!.value) + MathType.TAN -> tan(expression!!.value) + MathType.SQRT -> sqrt(expression!!.value) + MathType.ACOS -> acos(expression!!.value) + MathType.ASIN -> asin(expression!!.value) + MathType.ATAN -> atan(expression!!.value) + MathType.SINH -> sinh(expression!!.value) + MathType.COSH -> cosh(expression!!.value) + MathType.LOG -> log10(expression!!.value) + MathType.LN -> ln(expression!!.value) + MathType.INVALID -> throw ExpressionFormatException("Number is Invalid, cannot parse") + } } @get:Throws(ExpressionFormatException::class) diff --git a/AnkiDroid/src/main/java/com/wildplot/android/rendering/PieChart.kt b/AnkiDroid/src/main/java/com/wildplot/android/rendering/PieChart.kt index d15711b22e..96b7fa3667 100644 --- a/AnkiDroid/src/main/java/com/wildplot/android/rendering/PieChart.kt +++ b/AnkiDroid/src/main/java/com/wildplot/android/rendering/PieChart.kt @@ -79,7 +79,11 @@ class PieChart(plotSheet: PlotSheet, values: DoubleArray, colors: Array 1e2) { @@ -156,7 +157,8 @@ class XAxis val arrowheadPos = floatArrayOf( plotSheet.xToGraphic( Math.min( - plotSheet.getxRange()[1], end + plotSheet.getxRange()[1], + end ), field ), @@ -186,7 +188,8 @@ class XAxis floatArrayOf(plotSheet.xToGraphic(0.0, field), plotSheet.yToGraphic(yOffset, field)) if (mHasName) { g.drawString( - name, field.width / 2 - width / 2, + name, + field.width / 2 - width / 2, Math.round( middlePosition[1] + fontHeight * 2.5f ).toFloat() diff --git a/AnkiDroid/src/main/java/com/wildplot/android/rendering/XGrid.kt b/AnkiDroid/src/main/java/com/wildplot/android/rendering/XGrid.kt index c23ae51925..f55cbccf17 100644 --- a/AnkiDroid/src/main/java/com/wildplot/android/rendering/XGrid.kt +++ b/AnkiDroid/src/main/java/com/wildplot/android/rendering/XGrid.kt @@ -93,12 +93,16 @@ class XGrid */ private fun drawGridLine(y: Double, g: GraphicsWrap, field: RectangleWrap) { g.drawLine( - plotSheet.xToGraphic(0.0, field), plotSheet.yToGraphic(y, field), - plotSheet.xToGraphic(-xLength, field), plotSheet.yToGraphic(y, field) + plotSheet.xToGraphic(0.0, field), + plotSheet.yToGraphic(y, field), + plotSheet.xToGraphic(-xLength, field), + plotSheet.yToGraphic(y, field) ) g.drawLine( - plotSheet.xToGraphic(0.0, field), plotSheet.yToGraphic(y, field), - plotSheet.xToGraphic(xLength, field), plotSheet.yToGraphic(y, field) + plotSheet.xToGraphic(0.0, field), + plotSheet.yToGraphic(y, field), + plotSheet.xToGraphic(xLength, field), + plotSheet.yToGraphic(y, field) ) } diff --git a/AnkiDroid/src/main/java/com/wildplot/android/rendering/YAxis.kt b/AnkiDroid/src/main/java/com/wildplot/android/rendering/YAxis.kt index 2f6a698a1a..fa7ff20d1c 100644 --- a/AnkiDroid/src/main/java/com/wildplot/android/rendering/YAxis.kt +++ b/AnkiDroid/src/main/java/com/wildplot/android/rendering/YAxis.kt @@ -138,7 +138,8 @@ class YAxis end, field ) + cleanSpace && plotSheet.yToGraphic(currentY, field) <= plotSheet.yToGraphic( - start, field + start, + field ) - cleanSpace && plotSheet.yToGraphic( currentY, field @@ -175,7 +176,8 @@ class YAxis plotSheet.xToGraphic(xOffset, field), plotSheet.yToGraphic( Math.min( - plotSheet.getyRange()[1], end + plotSheet.getyRange()[1], + end ), field ) @@ -259,7 +261,8 @@ class YAxis g.drawString(font, middlePosition[0] - width * 0.1f, middlePosition[1] + width / 2.0f) } else { g.drawString( - font, Math.round(coordStart[0] - width * 1.1f).toFloat(), + font, + Math.round(coordStart[0] - width * 1.1f).toFloat(), Math.round( coordStart[1] + fontHeight * 0.4f ).toFloat() @@ -303,7 +306,8 @@ class YAxis g.drawString(font, middlePosition[0] + width * 0.1f, middlePosition[1] - width / 2.0f) } else { g.drawString( - font, Math.round(coordStart[0] + width * 0.1f).toFloat(), + font, + Math.round(coordStart[0] + width * 0.1f).toFloat(), Math.round( coordStart[1] + fontHeight * 0.4f ).toFloat() @@ -393,7 +397,8 @@ class YAxis end, field ) + cleanSpace && plotSheet.yToGraphic(currentY, field) <= plotSheet.yToGraphic( - start, field + start, + field ) - cleanSpace && plotSheet.yToGraphic( currentY, field diff --git a/AnkiDroid/src/main/java/com/wildplot/android/rendering/YGrid.kt b/AnkiDroid/src/main/java/com/wildplot/android/rendering/YGrid.kt index d8496a5fce..c7eb2377be 100644 --- a/AnkiDroid/src/main/java/com/wildplot/android/rendering/YGrid.kt +++ b/AnkiDroid/src/main/java/com/wildplot/android/rendering/YGrid.kt @@ -109,12 +109,16 @@ class YGrid */ private fun drawGridLine(x: Double, g: GraphicsWrap, field: RectangleWrap) { g.drawLine( - plotSheet.xToGraphic(x, field), plotSheet.yToGraphic(0.0, field), - plotSheet.xToGraphic(x, field), plotSheet.yToGraphic(yLength, field) + plotSheet.xToGraphic(x, field), + plotSheet.yToGraphic(0.0, field), + plotSheet.xToGraphic(x, field), + plotSheet.yToGraphic(yLength, field) ) g.drawLine( - plotSheet.xToGraphic(x, field), plotSheet.yToGraphic(0.0, field), - plotSheet.xToGraphic(x, field), plotSheet.yToGraphic(-yLength, field) + plotSheet.xToGraphic(x, field), + plotSheet.yToGraphic(0.0, field), + plotSheet.xToGraphic(x, field), + plotSheet.yToGraphic(-yLength, field) ) } diff --git a/AnkiDroid/src/test/java/com/ichi2/anim/ActivityTransitionAnimationTest.kt b/AnkiDroid/src/test/java/com/ichi2/anim/ActivityTransitionAnimationTest.kt index 893581e3a5..d40234992a 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anim/ActivityTransitionAnimationTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anim/ActivityTransitionAnimationTest.kt @@ -50,7 +50,7 @@ class ActivityTransitionAnimationTest { return Stream.of( Arguments.of(Direction.START, Direction.END), Arguments.of(Direction.UP, Direction.DOWN), - Arguments.of(Direction.RIGHT, Direction.LEFT), + Arguments.of(Direction.RIGHT, Direction.LEFT) ) } } diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupUnderBackupTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupUnderBackupTest.kt index 3a7f0d4692..64b243beca 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupUnderBackupTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/ActivityStartupUnderBackupTest.kt @@ -47,6 +47,7 @@ class ActivityStartupUnderBackupTest : RobolectricTest() { @ParameterizedRobolectricTestRunner.Parameter(1) @JvmField // required for Parameter var mActivityName: String? = null + @Before fun before() { notYetHandled(CropImageActivity::class.java.simpleName, "cannot implemented - activity from canhub.cropper") diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/AnalyticsTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/AnalyticsTest.kt index 617a224933..bdb6f32f03 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/AnalyticsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/AnalyticsTest.kt @@ -44,6 +44,7 @@ class AnalyticsTest { @Mock private lateinit var mMockSharedPreferencesEditor: SharedPreferences.Editor + @Before fun setUp() { UsageAnalytics.resetForTests() diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/AnkiActivityTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/AnkiActivityTest.kt index 3a06bc59bd..f74546e301 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/AnkiActivityTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/AnkiActivityTest.kt @@ -32,7 +32,8 @@ class AnkiActivityTest : RobolectricTest() { fun themeChangeIsValid() { // #12404 - fail to respond to day/night mode change val activity = startActivityNormallyOpenCollectionWithIntent( - AnkiActivity::class.java, Intent() + AnkiActivity::class.java, + Intent() ) assertThat(Themes.currentTheme, equalTo(Theme.LIGHT)) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/CardBrowserTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/CardBrowserTest.kt index 20cfbf7a6a..1e9e33e348 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/CardBrowserTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/CardBrowserTest.kt @@ -657,8 +657,10 @@ class CardBrowserTest : RobolectricTest() { Timber.w("Can't use childAt on position $position for a single click as it is not visible") } listener.onItemLongClick( - null, childAt, - position, toSelect.getItemIdAtPosition(position) + null, + childAt, + position, + toSelect.getItemIdAtPosition(position) ) advanceRobolectricUiLooper() } diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/CardInfoModelTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/CardInfoModelTest.kt index 4ffa8b4230..d5a3ad74f7 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/CardInfoModelTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/CardInfoModelTest.kt @@ -25,6 +25,7 @@ import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class CardInfoModelTest : RobolectricTest() { private var mModel: CardInfo.CardInfoModel? = null + @Before fun setupModel() { // using a card from my collection diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt index 0045875938..ff3ba60e05 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplateEditorTest.kt @@ -169,7 +169,6 @@ class CardTemplateEditorTest : RobolectricTest() { @Test @Throws(Exception::class) fun testTemplateAdd() { - // Make sure we test previewing a new card template - not working for real yet val modelName = "Basic" val collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplatePreviewerTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplatePreviewerTest.kt index ccc58d83b8..a7609a89f7 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplatePreviewerTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/CardTemplatePreviewerTest.kt @@ -38,7 +38,6 @@ class CardTemplatePreviewerTest : RobolectricTest() { @Test fun testPreviewUnsavedTemplate() { - val modelName = "Basic" val collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName) val template = collectionBasicModelOriginal.getJSONArray("tmpls").getJSONObject(0) @@ -142,7 +141,6 @@ class CardTemplatePreviewerTest : RobolectricTest() { @Test fun testPreviewNormal() { - // Make sure we test previewing a new card template val modelName = "Basic (and reversed card)" val collectionBasicModelOriginal = getCurrentDatabaseModelCopy(modelName) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/DeckAdapterFilterTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/DeckAdapterFilterTest.kt index bf5843055b..6d9302bb64 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/DeckAdapterFilterTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/DeckAdapterFilterTest.kt @@ -71,7 +71,7 @@ class DeckAdapterFilterTest { TreeNode(DeckTreeNode("Chanson::Important", 6)), TreeNode(DeckTreeNode("Chanson::Important::Stuff", 7)), TreeNode(DeckTreeNode("Chanson::Important::Math", 8)), - TreeNode(DeckTreeNode("Chanson::Important::Stuff::Other Stuff", 9)), + TreeNode(DeckTreeNode("Chanson::Important::Stuff::Other Stuff", 9)) ) deckList.getByDid(0).children.addAll(deckList.getByDids(1, 4, 6)) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerFloatingActionMenuTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerFloatingActionMenuTest.kt index 029fba935a..56ebf295f5 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerFloatingActionMenuTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerFloatingActionMenuTest.kt @@ -46,20 +46,33 @@ import kotlin.test.assertTrue class DeckPickerFloatingActionMenuTest { @Mock private val deckPicker: DeckPicker = mock() + @Mock private lateinit var mFabMain: FloatingActionButton + @Mock private val mAddSharedLayout: LinearLayout = mock(defaultAnswer = Answers.RETURNS_MOCKS) + @Mock private val mAddDeckLayout: LinearLayout = mock(defaultAnswer = Answers.RETURNS_MOCKS) + @Mock private val mAddNoteLayout: LinearLayout = mock(defaultAnswer = Answers.RETURNS_MOCKS) + @Mock private val mFabBGLayout: View = mock() + @Mock private val mLinearLayout: LinearLayout = mock() + @Mock private val mStudyOptionsFrame: View = mock() + @Mock private lateinit var view: View @Mock private val addNoteButton: FloatingActionButton = mock() + @Mock private val addSharedButton: FloatingActionButton = mock() + @Mock private val addDeckButton: FloatingActionButton = mock() + @Mock private val addNoteLabel: TextView = mock() + @Mock private val addSharedLabel: TextView = mock() + @Mock private val addDeckLabel: TextView = mock() @InjectMocks diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerTest.kt index 360b45ba48..ba9930e090 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/DeckPickerTest.kt @@ -199,7 +199,8 @@ class DeckPickerTest : RobolectricTest() { sched.card ensureCollectionLoadIsSynchronous() val deckPicker = super.startActivityNormallyOpenCollectionWithIntent( - DeckPicker::class.java, Intent() + DeckPicker::class.java, + Intent() ) assertEquals(10, deckPicker.dueTree!![0].value.newCount.toLong()) } @@ -209,7 +210,8 @@ class DeckPickerTest : RobolectricTest() { val did = addDeck("Hello World") assertThat("Deck was added", col.decks.count(), equalTo(2)) val deckPicker = startActivityNormallyOpenCollectionWithIntent( - DeckPicker::class.java, Intent() + DeckPicker::class.java, + Intent() ) deckPicker.confirmDeckDeletion(did) advanceRobolectricLooperWithSleep() @@ -226,12 +228,14 @@ class DeckPickerTest : RobolectricTest() { // And they are more likely to be empty temporarily val did = addDynamicDeck("filtered") val deckPicker = startActivityNormallyOpenCollectionWithIntent( - DeckPicker::class.java, Intent() + DeckPicker::class.java, + Intent() ) deckPicker.confirmDeckDeletion(did) val fragment = deckPicker.getDialogFragment() assertThat( - "deck deletion confirmation window should be shown", fragment, + "deck deletion confirmation window should be shown", + fragment, instanceOf(DeckPickerConfirmDeleteDeckDialog::class.java) ) } @@ -254,7 +258,8 @@ class DeckPickerTest : RobolectricTest() { BackendEmulatingOpenConflict.enable() InitialActivityWithConflictTest.setupForDatabaseConflict() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) assertThat( "A specific dialog for a conflict should be shown", @@ -281,7 +286,8 @@ class DeckPickerTest : RobolectricTest() { InitialActivityWithConflictTest.setupForDefault() BackendEmulatingOpenConflict.enable() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) // grant permissions @@ -308,7 +314,8 @@ class DeckPickerTest : RobolectricTest() { AnkiDroidApp.getSharedPrefs(targetContext).edit().putString("lastVersion", "0.1") .apply() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) assertThat( "Analytics opt-in should be displayed", @@ -327,7 +334,8 @@ class DeckPickerTest : RobolectricTest() { try { enableNullCollection() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) d.updateMenuState() assertThat( @@ -345,7 +353,8 @@ class DeckPickerTest : RobolectricTest() { try { grantWritePermissions() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) d.updateMenuState() assertThat( @@ -365,7 +374,8 @@ class DeckPickerTest : RobolectricTest() { revokeWritePermissions() enableNullCollection() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) // Neither collection, not its models will be initialized without storage permission @@ -382,7 +392,8 @@ class DeckPickerTest : RobolectricTest() { try { grantWritePermissions() val d = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) assertThat( "Collection initialization ensured by CollectionTask.LoadCollectionComplete", @@ -390,7 +401,8 @@ class DeckPickerTest : RobolectricTest() { notNullValue() ) assertThat( - "Collection Models Loaded", d.col.models, + "Collection Models Loaded", + d.col.models, notNullValue() ) } finally { @@ -409,7 +421,8 @@ class DeckPickerTest : RobolectricTest() { setupColV16() InitialActivityWithConflictTest.setupForValid(targetContext) val deckPicker: DeckPicker = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) waitForAsyncTasksToComplete() assertThat( @@ -441,7 +454,8 @@ class DeckPickerTest : RobolectricTest() { DbUtils.performQuery(targetContext, "drop table decks") InitialActivityWithConflictTest.setupForValid(targetContext) val deckPicker = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) waitForAsyncTasksToComplete() assertThat( @@ -464,7 +478,8 @@ class DeckPickerTest : RobolectricTest() { setupColV250() InitialActivityWithConflictTest.setupForValid(targetContext) val deckPicker = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) waitForAsyncTasksToComplete() assertThat( @@ -491,7 +506,8 @@ class DeckPickerTest : RobolectricTest() { fun checkDisplayOfStudyOptionsOnTablet() { assumeTrue("We are running on a tablet", mQualifiers!!.contains("xlarge")) val deckPickerEx = super.startActivityNormallyOpenCollectionWithIntent( - DeckPickerEx::class.java, Intent() + DeckPickerEx::class.java, + Intent() ) val studyOptionsFragment = deckPickerEx.supportFragmentManager.findFragmentById(R.id.studyoptions_fragment) as StudyOptionsFragment? @@ -508,7 +524,8 @@ class DeckPickerTest : RobolectricTest() { // Reason for using 2 as the number of decks -> This deck + Default deck assertThat("Deck added", col.decks.count(), equalTo(2)) val deckPicker = startActivityNormallyOpenCollectionWithIntent( - DeckPicker::class.java, Intent() + DeckPicker::class.java, + Intent() ) assertThat( "Deck is being displayed", @@ -523,7 +540,8 @@ class DeckPickerTest : RobolectricTest() { // Default deck does not get displayed in the DeckPicker if the default deck is empty. assertThat("Contains only default deck", col.decks.count(), equalTo(1)) val deckPicker = startActivityNormallyOpenCollectionWithIntent( - DeckPicker::class.java, Intent() + DeckPicker::class.java, + Intent() ) assertThat( "No deck is being displayed", diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/ModelFieldEditorTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/ModelFieldEditorTest.kt index 9de11afb5c..7ded15202d 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/ModelFieldEditorTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/ModelFieldEditorTest.kt @@ -103,7 +103,9 @@ class ModelFieldEditorTest(private val forbiddenCharacter: String) : Robolectric intent.putExtra("title", modelName) intent.putExtra("noteTypeID", findModelIdByName(modelName)) val modelFieldEditor = startActivityNormallyOpenCollectionWithIntent( - this, ModelFieldEditor::class.java, intent + this, + ModelFieldEditor::class.java, + intent ) when (fieldOperationType) { FieldOperationType.ADD_FIELD -> modelFieldEditor.addField(fieldNameInput) @@ -130,6 +132,7 @@ class ModelFieldEditorTest(private val forbiddenCharacter: String) : Robolectric companion object { private val sForbiddenCharacters = arrayOf("#", "^", "/", " ", "\t") + @ParameterizedRobolectricTestRunner.Parameters(name = "\"{0}\"") @Suppress("unused") @JvmStatic // required: Parameters diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/ProductionCrashReportingTreeTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/ProductionCrashReportingTreeTest.kt index 3018c66d29..4bae9386b1 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/ProductionCrashReportingTreeTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/ProductionCrashReportingTreeTest.kt @@ -35,7 +35,6 @@ import java.lang.RuntimeException class ProductionCrashReportingTreeTest { @Before fun setUp() { - // setup - simply instrument the class and do same log init as production Timber.plant(AnkiDroidApp.ProductionCrashReportingTree()) } @@ -83,11 +82,10 @@ class ProductionCrashReportingTreeTest { */ @Test fun testProductionLogTag() { - var testWithProperClassNameCalled = false + // this is required to ensure 'NativeMethodAccessorImpl' isn't the class name fun testWithProperClassName(autoClosed: MockedStatic) { - // Now let's run through our API calls... Timber.i("info level message") Timber.w("warn level message") diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/ReviewerTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/ReviewerTest.kt index 6f274038af..54e53106e7 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/ReviewerTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/ReviewerTest.kt @@ -47,6 +47,7 @@ class ReviewerTest : RobolectricTest() { @JvmField // required for Parameter @ParameterizedRobolectricTestRunner.Parameter var schedVersion = 0 + @Before override fun setUp() { super.setUp() @@ -288,7 +289,6 @@ class ReviewerTest : RobolectricTest() { @Suppress("SameParameterValue") private fun assertCounts(r: Reviewer, newCount: Int, stepCount: Int, revCount: Int) { - val jsApi = r.javaScriptFunction() val countList = listOf( jsApi.ankiGetNewCardCount(), diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt index 5e2c882152..6ff7960252 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTest.kt @@ -138,7 +138,6 @@ open class RobolectricTest : CollectionGetter { @After @CallSuper open fun tearDown() { - // If you don't clean up your ActivityControllers you will get OOM errors for (controller in mControllersForCleanup) { Timber.d("Calling destroy on controller %s", controller.get().toString()) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTestAnnotationTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTestAnnotationTest.kt index 8015365244..0aea043ef7 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTestAnnotationTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/RobolectricTestAnnotationTest.kt @@ -24,7 +24,10 @@ import kotlin.test.assertFailsWith class RobolectricTestAnnotationTest : RobolectricTest() { @Test fun readableErrorIfNotAnnotated() { - val exception = assertFailsWith { @Suppress("UNUSED_VARIABLE") val unused = targetContext } + val exception = assertFailsWith { + @Suppress("UNUSED_VARIABLE") + val unused = this.targetContext + } assertThat(exception.message, containsString("RobolectricTestAnnotationTest")) assertThat(exception.message, containsString("@RunWith(AndroidJUnit4.class)")) } diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/TemporaryModelTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/TemporaryModelTest.kt index 6a146b7e8f..95bea3d620 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/TemporaryModelTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/TemporaryModelTest.kt @@ -34,7 +34,6 @@ class TemporaryModelTest : RobolectricTest() { @Test @Throws(Exception::class) fun testTempModelStorage() { - // Start off with clean state in the cache dir TemporaryModel.clearTempModelFiles() @@ -58,7 +57,6 @@ class TemporaryModelTest : RobolectricTest() { @Test fun testAddDeleteTracking() { - // Assume you start with a 2 template model (like "Basic (and reversed)") // Add a 3rd new template, remove the 2nd, remove the 1st, add a new now-2nd, remove 1st again // ...and it should reduce to just removing the original 1st/2nd and adding the final as first diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/WhiteboardDefaultForegroundColorTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/WhiteboardDefaultForegroundColorTest.kt index f7cb97b425..1ef63e2efe 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/WhiteboardDefaultForegroundColorTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/WhiteboardDefaultForegroundColorTest.kt @@ -32,6 +32,7 @@ class WhiteboardDefaultForegroundColorTest : RobolectricTest() { @ParameterizedRobolectricTestRunner.Parameter(1) @JvmField // required for Parameter var mExpectedResult = 0 + @Test fun testDefaultForegroundColor() { assertThat(foregroundColor, equalTo(mExpectedResult)) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt index 3224b5b725..315ce08f09 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/analytics/AnalyticsConstantsTest.kt @@ -88,7 +88,8 @@ object AnalyticsConstantsTest { fun checkAnalyticsString() { Assert.assertEquals( "Re-check if you renamed any string in the analytics string constants of Actions class or AnalyticsConstantsTest.listOfConstantFields. If so, revert them as those string constants must not change as they are compared in analytics.", - analyticsString, getStringFromReflection(analyticsString) + analyticsString, + getStringFromReflection(analyticsString) ) } @@ -118,12 +119,14 @@ object AnalyticsConstantsTest { if (fieldSize > listOfConstantFields.size) { Assert.assertEquals( "Add the newly added analytics constant to AnalyticsConstantsTest.listOfConstantFields. NOTE: Constants should not be renamed as we cannot compare these in analytics.", - listOfConstantFields.size, fieldSize + listOfConstantFields.size, + fieldSize ) } else if (fieldSize < listOfConstantFields.size) { Assert.assertEquals( "If a constant is removed, it should be removed from AnalyticsConstantsTest.listOfConstantFields. NOTE: Constants should not be renamed as we cannot compare these in analytics.", - listOfConstantFields.size, fieldSize + listOfConstantFields.size, + fieldSize ) } else { Assert.assertEquals(listOfConstantFields.size, fieldSize) diff --git a/AnkiDroid/src/test/java/com/ichi2/anki/cardviewer/TypeAnswerTest.kt b/AnkiDroid/src/test/java/com/ichi2/anki/cardviewer/TypeAnswerTest.kt index 0cfea110c6..8e8e467552 100644 --- a/AnkiDroid/src/test/java/com/ichi2/anki/cardviewer/TypeAnswerTest.kt +++ b/AnkiDroid/src/test/java/com/ichi2/anki/cardviewer/TypeAnswerTest.kt @@ -47,6 +47,7 @@ class TypeAnswerTest {
$!""" + @Language("HTML") val expectedOutput = """