Commit 59371e2

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-10-05 18:15:38
use new settings system everywhere in app
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent f47aa77
lib/components/measurement_list/measurement_list.dart
@@ -1,6 +1,8 @@
 import 'package:blood_pressure_app/components/blood_pressure_builder.dart';
+import 'package:blood_pressure_app/components/consistent_future_builder.dart';
 import 'package:blood_pressure_app/components/measurement_list/measurement_list_entry.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
lib/components/measurement_list/measurement_list_entry.dart
@@ -1,4 +1,5 @@
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/add_measurement.dart';
 import 'package:flutter/material.dart';
lib/components/display_interval_picker.dart
@@ -1,3 +1,4 @@
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
lib/components/export_item_order.dart
@@ -3,7 +3,9 @@ import 'dart:async';
 
 import 'package:badges/badges.dart' as badges;
 import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/model/export_import.dart';
 import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
lib/components/input_dialoge.dart
@@ -1,6 +1,8 @@
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter/services.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:provider/provider.dart';
 
 // TODO: redo dialoges in flutter style
 class InputDialoge extends StatefulWidget {
lib/components/legacy_measurement_list.dart
@@ -1,7 +1,9 @@
 import 'dart:collection';
 
 import 'package:blood_pressure_app/components/blood_pressure_builder.dart';
+import 'package:blood_pressure_app/components/consistent_future_builder.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/add_measurement.dart';
lib/components/measurement_graph.dart
@@ -1,9 +1,11 @@
 import 'dart:math';
 
 import 'package:blood_pressure_app/components/blood_pressure_builder.dart';
+import 'package:blood_pressure_app/components/consistent_future_builder.dart';
 import 'package:blood_pressure_app/components/display_interval_picker.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/horizontal_graph_line.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:collection/collection.dart';
lib/model/export_import.dart
@@ -8,6 +8,7 @@ import 'package:blood_pressure_app/model/export_options.dart';
 import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
+import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:csv/csv.dart';
 import 'package:file_picker/file_picker.dart';
lib/model/export_options.dart
@@ -2,9 +2,12 @@ import 'dart:collection';
 
 import 'package:blood_pressure_app/main.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/export_import.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/common_settings_intervaces.dart';
 import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
+import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:function_tree/function_tree.dart';
lib/model/settings_store.dart
@@ -1,8 +1,640 @@
+import 'dart:convert';
+
+import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/export_import.dart';
+import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/horizontal_graph_line.dart';
+import 'package:file_saver/file_saver.dart' show MimeType;
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:package_info_plus/package_info_plus.dart';
+import 'package:shared_preferences/shared_preferences.dart';
 
 // TODO: remove file
 
+class _Settings extends ChangeNotifier {
+
+  late final SharedPreferences _prefs;
+  final PackageInfo _packageInfo;
+
+  DateTime? _displayDataStart;
+  DateTime? _displayDataEnd;
+
+  _Settings._create(this._packageInfo);
+  // factory method, to allow for async constructor
+  static Future<_Settings> create([PackageInfo? packageInfo]) async {
+    final component = _Settings._create(packageInfo ?? (await PackageInfo.fromPlatform()));
+    component._prefs = await SharedPreferences.getInstance();
+    await component._update();
+    return component;
+  }
+
+  Future<void> _update() async {
+    final keys = _prefs.getKeys();
+    List<Future> toAwait = [];
+
+    // delete old keys
+    if (keys.contains('age')) {
+      final lastAge = _prefs.getInt('age') ?? 30;
+      sysWarn = BloodPressureWarnValues.getUpperSysWarnValue(lastAge);
+      diaWarn = BloodPressureWarnValues.getUpperDiaWarnValue(lastAge);
+      toAwait.add(_prefs.remove('age'));
+    }
+    if (keys.contains('overrideWarnValues')) {
+      toAwait.add(_prefs.remove('overrideWarnValues'));
+    }
+    if (keys.contains('exportLimitDataRange')) {
+      toAwait.add(_prefs.remove('exportLimitDataRange'));
+    }
+    if (keys.contains('exportDataRangeStartEpochMs')) {
+      toAwait.add(_prefs.remove('exportDataRangeStartEpochMs'));
+    }
+    if (keys.contains('exportDataRangeEndEpochMs')) {
+      toAwait.add(_prefs.remove('exportDataRangeEndEpochMs'));
+    }
+    if (keys.contains('exportAddableItems')) {
+      toAwait.add(_prefs.remove('exportAddableItems'));
+    }
+    if (keys.contains('exportCustomEntries')) {
+      await _prefs.setBool('exportCustomEntriesCsv', _prefs.getBool('exportCustomEntries') ?? false);
+      toAwait.add(_prefs.remove('exportCustomEntries'));
+    }
+    if (keys.contains('exportItems')) {
+      await _prefs.setStringList('exportItemsCsv', _prefs.getStringList('exportItems') ?? ExportFields.defaultCsv);
+      toAwait.add(_prefs.remove('exportItems'));
+    }
+    if (keys.contains('iconSize')) {
+      toAwait.add(_prefs.remove('iconSize'));
+    }
+    if (keys.contains('titlesCount')) {
+      toAwait.add(_prefs.remove('titlesCount'));
+    }
+
+    // reset variables for new version. Necessary for reusing variable names in new version and avoid having unexpected
+    // breaking values in the preferences
+    switch (_prefs.getInt('lastAppVersion')) {
+      case null:
+        toAwait.add(_prefs.remove('exportCsvHeadline'));
+        toAwait.add(_prefs.remove('exportCustomEntries'));
+        toAwait.add(_prefs.remove('exportItems'));
+        toAwait.add(_prefs.remove('exportMimeType'));
+    }
+
+    for (var e in toAwait) {
+      await e;
+    }
+    await _prefs.setInt('lastAppVersion', int.parse(_packageInfo.buildNumber));
+    return;
+  }
+
+  _TimeStep get graphStepSize {
+    int stepInt = _prefs.getInt('graphStepSize') ?? 0;
+    switch (stepInt) {
+      case 0:
+        return _TimeStep.day;
+      case 1:
+        return _TimeStep.month;
+      case 2:
+        return _TimeStep.year;
+      case 3:
+        return _TimeStep.lifetime;
+      case 4:
+        return _TimeStep.week;
+      case 5:
+        return _TimeStep.last7Days;
+      case 6:
+        return _TimeStep.last30Days;
+      case 7:
+        return _TimeStep.custom;
+    }
+    assert(false);
+    return _TimeStep.day;
+  }
+
+  set graphStepSize(_TimeStep newStepSize) {
+    _prefs.setInt('graphStepSize', ((){
+      switch (newStepSize) {
+        case _TimeStep.day:
+          return 0;
+        case _TimeStep.month:
+          return 1;
+        case _TimeStep.year:
+          return 2;
+        case _TimeStep.lifetime:
+          return 3;
+        case _TimeStep.week:
+          return 4;
+        case _TimeStep.last7Days:
+          return 5;
+        case _TimeStep.last30Days:
+          return 6;
+        case _TimeStep.custom:
+          return 7;
+      }
+    })());
+
+
+    notifyListeners();
+  }
+
+  void changeStepSize(_TimeStep value) {
+    graphStepSize = value;
+    final newInterval = getMostRecentDisplayIntervall();
+    displayDataStart = newInterval[0];
+    displayDataEnd = newInterval[1];
+  }
+
+  void setToMostRecentIntervall() {
+    changeStepSize(graphStepSize);
+  }
+
+  void moveDisplayDataByStep(int directionalStep) {
+    final oldStart = displayDataStart;
+    final oldEnd = displayDataEnd;
+    switch (graphStepSize) {
+      case _TimeStep.day:
+        displayDataStart = oldStart.copyWith(day: oldStart.day + directionalStep);
+        displayDataEnd = oldEnd.copyWith(day: oldEnd.day + directionalStep);
+        break;
+      case _TimeStep.week:
+      case _TimeStep.last7Days:
+        displayDataStart = oldStart.copyWith(day: oldStart.day + directionalStep * 7);
+        displayDataEnd = oldEnd.copyWith(day: oldEnd.day + directionalStep * 7);
+        break;
+      case _TimeStep.month:
+        displayDataStart = oldStart.copyWith(month: oldStart.month + directionalStep);
+        displayDataEnd = oldEnd.copyWith(month: oldEnd.month + directionalStep);
+        break;
+      case _TimeStep.year:
+        displayDataStart = oldStart.copyWith(year: oldStart.year + directionalStep);
+        displayDataEnd = oldEnd.copyWith(year: oldEnd.year + directionalStep);
+        break;
+      case _TimeStep.lifetime:
+        displayDataStart = DateTime.fromMillisecondsSinceEpoch(1);
+        displayDataEnd = DateTime.now().copyWith(hour: 23, minute: 59, second: 59);
+        break;
+      case _TimeStep.last30Days:
+        displayDataStart = oldStart.copyWith(day: oldStart.day + directionalStep * 30);
+        displayDataEnd = oldEnd.copyWith(day: oldEnd.day + directionalStep * 30);
+        break;
+      case _TimeStep.custom:
+        final step = oldEnd.difference(oldStart) * directionalStep;
+        displayDataStart = oldStart.add(step);
+        displayDataEnd = oldEnd.add(step);
+        break;
+    }
+  }
+
+  List<DateTime> getMostRecentDisplayIntervall() {
+    final now = DateTime.now();
+    switch (graphStepSize) {
+      case _TimeStep.day:
+        final start = DateTime(now.year, now.month, now.day);
+        return [start, start.copyWith(day: now.day + 1)];
+      case _TimeStep.week:
+        final start = DateTime(now.year, now.month, now.day - (now.weekday - 1)); // monday
+        return [start, start.copyWith(day: start.day + DateTime.sunday)]; // end of sunday
+      case _TimeStep.month:
+        final start = DateTime(now.year, now.month);
+        return [start, start.copyWith(month: now.month + 1)];
+      case _TimeStep.year:
+        final start = DateTime(now.year);
+        return [start, start.copyWith(year: now.year + 1)];
+      case _TimeStep.lifetime:
+        final start = DateTime.fromMillisecondsSinceEpoch(1);
+        final endOfToday = now.copyWith(hour: 23, minute: 59, second: 59);
+        return [start, endOfToday];
+      case _TimeStep.last7Days:
+        final start = now.copyWith(day: now.day - 7);
+        final endOfToday = now.copyWith(hour: 23, minute: 59, second: 59);
+        return [start, endOfToday];
+      case _TimeStep.last30Days:
+        final start = now.copyWith(day: now.day - 30);
+        final endOfToday = now.copyWith(hour: 23, minute: 59, second: 59);
+        return [start, endOfToday];
+      case _TimeStep.custom:
+        // fallback, _TimeStep will be reset by getter
+        return [DateTime.fromMillisecondsSinceEpoch(-1), DateTime.fromMillisecondsSinceEpoch(-1)];
+    }
+  }
+
+  DateTime get displayDataStart {
+    final s = _displayDataStart ?? getMostRecentDisplayIntervall()[0];
+    if(s.millisecondsSinceEpoch < 1) {
+      changeStepSize(_TimeStep.last7Days);
+    }
+    return s;
+  }
+
+  set displayDataStart(DateTime newGraphStart) {
+    _displayDataStart = newGraphStart;
+    notifyListeners();
+  }
+
+  DateTime get displayDataEnd {
+    final s = _displayDataEnd ?? getMostRecentDisplayIntervall()[1];
+    if(s.millisecondsSinceEpoch < 1) {
+      changeStepSize(_TimeStep.last7Days);
+    }
+    return s;
+  }
+
+  set displayDataEnd(DateTime newGraphEnd) {
+    _displayDataEnd = newGraphEnd;
+    notifyListeners();
+  }
+
+  bool get followSystemDarkMode {
+    return _prefs.getBool('followSystemDarkMode') ?? true;
+  }
+
+  set followSystemDarkMode(bool newSetting) {
+    _prefs.setBool('followSystemDarkMode', newSetting);
+    notifyListeners();
+  }
+
+  bool get darkMode {
+    return _prefs.getBool('darkMode') ?? true;
+  }
+
+  set darkMode(bool newSetting) {
+    _prefs.setBool('darkMode', newSetting);
+    notifyListeners();
+  }
+
+  MaterialColor get accentColor {
+    return createMaterialColor(_prefs.getInt('accentColor') ?? 0xFF009688);
+  }
+
+  set accentColor(MaterialColor newColor) {
+    _prefs.setInt('accentColor', newColor.value);
+    notifyListeners();
+  }
+
+  MaterialColor get diaColor {
+    return createMaterialColor(_prefs.getInt('diaColor') ?? 0xFF4CAF50);
+  }
+
+  set diaColor(MaterialColor newColor) {
+    _prefs.setInt('diaColor', newColor.value);
+    notifyListeners();
+  }
+
+  MaterialColor get sysColor {
+    return createMaterialColor(_prefs.getInt('sysColor') ?? 0xFF009688);
+  }
+
+  set sysColor(MaterialColor newColor) {
+    _prefs.setInt('sysColor', newColor.value);
+    notifyListeners();
+  }
+
+  MaterialColor get pulColor {
+    return createMaterialColor(_prefs.getInt('pulColor') ?? 0xFFF44336);
+  }
+
+  set pulColor(MaterialColor newColor) {
+    _prefs.setInt('pulColor', newColor.value);
+    notifyListeners();
+  }
+
+  bool get allowManualTimeInput {
+    return _prefs.getBool('allowManualTimeInput') ?? true;
+  }
+
+  set allowManualTimeInput(bool newSetting) {
+    _prefs.setBool('allowManualTimeInput', newSetting);
+    notifyListeners();
+  }
+
+  String get dateFormatString {
+    return _prefs.getString('dateFormatString') ?? 'yyyy-MM-dd  HH:mm';
+  }
+
+  set dateFormatString(String newFormatString) {
+    _prefs.setString('dateFormatString', newFormatString);
+    notifyListeners();
+  }
+
+  int get sysWarn {
+    return _prefs.getInt('sysWarn') ?? 120;
+  }
+
+  set sysWarn(int newWarn) {
+    _prefs.setInt('sysWarn', newWarn);
+    notifyListeners();
+  }
+
+  int get diaWarn {
+    return _prefs.getInt('diaWarn') ?? 80;
+  }
+
+  set diaWarn(int newWarn) {
+    _prefs.setInt('diaWarn', newWarn);
+    notifyListeners();
+  }
+
+  bool get validateInputs {
+    return _prefs.getBool('validateInputs') ?? true;
+  }
+
+  set validateInputs(bool validateInputs) {
+    _prefs.setBool('validateInputs', validateInputs);
+    notifyListeners();
+  }
+
+  bool get allowMissingValues {
+    return _prefs.getBool('allowMissingValues') ?? false;
+  }
+
+  set allowMissingValues(bool allowMissingValues) {
+    _prefs.setBool('allowMissingValues', allowMissingValues);
+    notifyListeners();
+  }
+
+  double get graphLineThickness {
+    return _prefs.getDouble('graphLineThickness') ?? 3;
+  }
+
+  set graphLineThickness(double newThickness) {
+    _prefs.setDouble('graphLineThickness', newThickness);
+    notifyListeners();
+  }
+
+  int get animationSpeed {
+    return _prefs.getInt('animationSpeed') ?? 150;
+  }
+
+  set animationSpeed(int newSpeed) {
+    _prefs.setInt('animationSpeed', newSpeed);
+    notifyListeners();
+  }
+
+  bool get confirmDeletion {
+    return _prefs.getBool('confirmDeletion') ?? true;
+  }
+
+  set confirmDeletion(bool confirmDeletion) {
+    _prefs.setBool('confirmDeletion', confirmDeletion);
+    notifyListeners();
+  }
+
+  ExportFormat get exportFormat {
+    switch (_prefs.getInt('exportFormat') ?? 0) {
+      case 0:
+        return ExportFormat.csv;
+      case 1:
+        return ExportFormat.pdf;
+      case 2:
+        return ExportFormat.db;
+      default:
+        assert(false);
+        return ExportFormat.csv;
+    }
+  }
+
+  set exportFormat(ExportFormat format) {
+    switch (format) {
+      case ExportFormat.csv:
+        _prefs.setInt('exportFormat', 0);
+        break;
+      case ExportFormat.pdf:
+        _prefs.setInt('exportFormat', 1);
+        break;
+      case ExportFormat.db:
+        _prefs.setInt('exportFormat', 2);
+        break;
+      default:
+        assert(false);
+    }
+    notifyListeners();
+  }
+
+  String get csvFieldDelimiter {
+    return _prefs.getString('csvFieldDelimiter') ?? ',';
+  }
+
+  set csvFieldDelimiter(String value) {
+    _prefs.setString('csvFieldDelimiter', value);
+    notifyListeners();
+  }
+
+  String get csvTextDelimiter {
+    return _prefs.getString('csvTextDelimiter') ?? '"';
+  }
+
+  set csvTextDelimiter(String value) {
+    _prefs.setString('csvTextDelimiter', value);
+    notifyListeners();
+  }
+
+  MimeType get exportMimeType {
+    switch (_prefs.getInt('exportMimeType') ?? 0) {
+      case 0:
+        return MimeType.csv;
+      case 1:
+        return MimeType.text;
+      case 2:
+        return MimeType.pdf;
+      case 3:
+        return MimeType.other;
+      default:
+        throw UnimplementedError();
+    }
+  }
+  set exportMimeType(MimeType value) {
+    switch (value) {
+      case MimeType.csv:
+        _prefs.setInt('exportMimeType', 0);
+        break;
+      case MimeType.text:
+        _prefs.setInt('exportMimeType', 1);
+        break;
+      case MimeType.pdf:
+        _prefs.setInt('exportMimeType', 2);
+        break;
+      case MimeType.other:
+        _prefs.setInt('exportMimeType', 3);
+        break;
+      default:
+        throw UnimplementedError();
+    }
+    notifyListeners();
+  }
+
+  bool get exportCustomEntriesCsv {
+    return _prefs.getBool('exportCustomEntriesCsv') ?? false;
+  }
+
+  set exportCustomEntriesCsv(bool value) {
+    _prefs.setBool('exportCustomEntriesCsv', value);
+    notifyListeners();
+  }
+
+  List<String> get exportItemsCsv {
+    return _prefs.getStringList('exportItemsCsv') ?? ExportFields.defaultCsv;
+  }
+
+  set exportItemsCsv(List<String> value) {
+    _prefs.setStringList('exportItemsCsv', value);
+    notifyListeners();
+  }
+
+  bool get exportCsvHeadline {
+    return _prefs.getBool('exportCsvHeadline') ?? true;
+  }
+
+  set exportCsvHeadline(bool value) {
+    _prefs.setBool('exportCsvHeadline', value);
+    notifyListeners();
+  }
+
+  String get defaultExportDir {
+    return _prefs.getString('defaultExportDir') ?? '';
+  }
+  set defaultExportDir (String value) {
+    _prefs.setString('defaultExportDir', value);
+    notifyListeners();
+  }
+
+  bool get exportAfterEveryEntry {
+    return _prefs.getBool('exportAfterEveryEntry') ?? false;
+  }
+
+  set exportAfterEveryEntry(bool value) {
+    _prefs.setBool('exportAfterEveryEntry', value);
+    notifyListeners();
+  }
+
+  Locale? get language {
+    final value = _prefs.getString('language');
+    if (value?.isEmpty ?? true) return null;
+    return Locale(value ?? 'en');
+  }
+
+  set language (Locale? value) {
+    _prefs.setString('language', value?.languageCode ?? '');
+    notifyListeners();
+  }
+
+  bool get drawRegressionLines {
+    return _prefs.getBool('drawRegressionLines') ?? false;
+  }
+
+  set drawRegressionLines(bool value) {
+    _prefs.setBool('drawRegressionLines', value);
+    notifyListeners();
+  }
+
+  double get exportPdfHeaderHeight {
+    return _prefs.getDouble('exportPdfHeaderHeight') ?? 20;
+  }
+
+  set exportPdfHeaderHeight(double value) {
+    _prefs.setDouble('exportPdfHeaderHeight', value);
+    notifyListeners();
+  }
+  double get exportPdfCellHeight {
+    return _prefs.getDouble('exportPdfCellHeight') ?? 15;
+  }
+
+  set exportPdfCellHeight(double value) {
+    _prefs.setDouble('exportPdfCellHeight', value);
+    notifyListeners();
+  }
+
+  double get exportPdfHeaderFontSize {
+    return _prefs.getDouble('exportPdfHeaderFontSize') ?? 10;
+  }
+
+  set exportPdfHeaderFontSize(double value) {
+    _prefs.setDouble('exportPdfHeaderFontSize', value);
+    notifyListeners();
+  }
+
+  double get exportPdfCellFontSize {
+    return _prefs.getDouble('exportPdfCellFontSize') ?? 8;
+  }
+
+  set exportPdfCellFontSize(double value) {
+    _prefs.setDouble('exportPdfCellFontSize', value);
+    notifyListeners();
+  }
+
+  bool get exportPdfExportTitle {
+    return _prefs.getBool('exportPdfExportTitle') ?? true;
+  }
+
+  set exportPdfExportTitle(bool value) {
+    _prefs.setBool('exportPdfExportTitle', value);
+    notifyListeners();
+  }
+
+  bool get exportPdfExportStatistics {
+    return _prefs.getBool('exportPdfExportStatistics') ?? false;
+  }
+
+  set exportPdfExportStatistics(bool value) {
+    _prefs.setBool('exportPdfExportStatistics', value);
+    notifyListeners();
+  }
+
+  /// whether to add a section with all entries to pdf export
+  bool get exportPdfExportData {
+    return _prefs.getBool('exportPdfExportData') ?? true;
+  }
+
+  set exportPdfExportData(bool value) {
+    _prefs.setBool('exportPdfExportData', value);
+    notifyListeners();
+  }
+
+  bool get startWithAddMeasurementPage {
+    return _prefs.getBool('startWithAddMeasurementPage') ?? false;
+  }
+
+  set startWithAddMeasurementPage(bool value) {
+    _prefs.setBool('startWithAddMeasurementPage', value);
+    notifyListeners();
+  }
+
+  bool get exportCustomEntriesPdf {
+    return _prefs.getBool('exportCustomEntriesPdf') ?? false;
+  }
+
+  set exportCustomEntriesPdf(bool value) {
+    _prefs.setBool('exportCustomEntriesPdf', value);
+    notifyListeners();
+  }
+
+  List<String> get exportItemsPdf {
+    return _prefs.getStringList('exportItemsPdf') ?? ExportFields.defaultPdf;
+  }
+
+  set exportItemsPdf(List<String> value) {
+    _prefs.setStringList('exportItemsPdf', value);
+    notifyListeners();
+  }
+
+  Iterable<HorizontalGraphLine> get horizontalGraphLines {
+    final linesStr = _prefs.getStringList('horizontalGraphLines') ?? [];
+    return linesStr.map((e) => HorizontalGraphLine.fromJson(jsonDecode(e)));
+  }
+
+  set horizontalGraphLines(Iterable<HorizontalGraphLine> value) {
+    _prefs.setStringList('horizontalGraphLines', value.map((e) => jsonEncode(e)).toList());
+    notifyListeners();
+  }
+
+  bool get useLegacyList {
+    return _prefs.getBool('useLegacyList') ?? false;
+  }
+
+  set useLegacyList(bool value) {
+    _prefs.setBool('useLegacyList', value);
+    notifyListeners();
+  }
+}
 
 enum _TimeStep {
   day,
lib/screens/subsettings/enter_timeformat.dart
@@ -1,3 +1,4 @@
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/subsettings/time_formats_explainer.dart';
 import 'package:flutter/material.dart';
lib/screens/subsettings/export_column_data.dart
@@ -1,8 +1,11 @@
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
+import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/subsettings/export_field_format_documentation.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:provider/provider.dart';
 
 class  EditExportColumnPage extends StatefulWidget {
   final String? initialInternalName;
lib/screens/subsettings/export_import_screen.dart
@@ -5,6 +5,7 @@ import 'package:blood_pressure_app/components/settings_widgets.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/export_import.dart';
 import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/common_settings_intervaces.dart';
 import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
lib/screens/subsettings/graph_markings.dart
@@ -1,5 +1,6 @@
 import 'package:blood_pressure_app/components/input_dialoge.dart';
 import 'package:blood_pressure_app/model/horizontal_graph_line.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
lib/screens/add_measurement.dart
@@ -2,6 +2,7 @@ import 'package:blood_pressure_app/components/date_time_picker.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/export_import.dart';
 import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:flutter/material.dart';
lib/screens/home.dart
@@ -1,5 +1,6 @@
 import 'package:blood_pressure_app/components/legacy_measurement_list.dart';
 import 'package:blood_pressure_app/components/measurement_graph.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/add_measurement.dart';
 import 'package:blood_pressure_app/screens/settings.dart';
lib/screens/statistics.dart
@@ -1,6 +1,10 @@
+import 'dart:collection';
+
 import 'package:blood_pressure_app/components/blood_pressure_builder.dart';
 import 'package:blood_pressure_app/components/display_interval_picker.dart';
+import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/blood_pressure_analyzer.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
 import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:fl_chart/fl_chart.dart';
@@ -8,6 +12,8 @@ import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:provider/provider.dart';
 
+import '../components/blood_pressure_builder.dart';
+
 class StatisticsPage extends StatelessWidget {
   const StatisticsPage({super.key});
 
lib/main.dart
@@ -1,4 +1,5 @@
 import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
 import 'package:blood_pressure_app/model/storage/db/config_db.dart';
 import 'package:blood_pressure_app/model/storage/intervall_store.dart';
test/ui/add_measurement_test.dart
@@ -1,5 +1,6 @@
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/ram_only_implementations.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
test/ui/navigation_test.dart
@@ -1,6 +1,7 @@
 import 'package:blood_pressure_app/main.dart';
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/ram_only_implementations.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
test/ui/statistics_test.dart
@@ -1,5 +1,6 @@
 import 'package:blood_pressure_app/model/blood_pressure.dart';
 import 'package:blood_pressure_app/model/ram_only_implementations.dart';
+import 'package:blood_pressure_app/model/settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
 import 'package:blood_pressure_app/model/storage/export_settings_store.dart';