Commit f47aa77

derdilla <82763757+NobodyForNothing@users.noreply.github.com>
2023-10-05 18:13:24
use new settings system in app
Signed-off-by: derdilla <82763757+NobodyForNothing@users.noreply.github.com>
1 parent 54e5dcd
lib/components/measurement_list/measurement_list.dart
@@ -1,7 +1,8 @@
-import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/components/blood_pressure_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';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:provider/provider.dart';
@@ -11,29 +12,21 @@ class MeasurementList extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Consumer<Settings>(
-      builder: (context, settings, child) {
-        return Column(
-          mainAxisSize: MainAxisSize.min,
-          children: [
-            const MeasurementListHeader(),
-            Expanded(
-              child: Consumer<BloodPressureModel>(
-                builder: (context, model, child) {
-                  return ConsistentFutureBuilder(
-                    future: model.getInTimeRange(settings.displayDataStart, settings.displayDataEnd),
-                    onData: (context, data) {
-                      return MeasurementListEntries(
-                        entries: data
-                      );
-                    }
+    return Column(
+        mainAxisSize: MainAxisSize.min,
+        children: [
+          const MeasurementListHeader(),
+          Expanded(
+              child: BloodPressureBuilder(
+                rangeType: IntervallStoreManagerLocation.mainPage,
+                onData: (context, data) {
+                  return MeasurementListEntries(
+                      entries: data
                   );
                 },
               )
-            )
-          ]
-        );
-      },
+          )
+        ]
     );
   }
 }
lib/components/measurement_list/measurement_list_entry.dart
@@ -1,5 +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';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
lib/components/blood_pressure_builder.dart
@@ -0,0 +1,32 @@
+import 'dart:collection';
+
+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/storage/intervall_store.dart';
+import 'package:flutter/material.dart';
+import 'package:provider/provider.dart';
+
+/// Shorthand class for getting the blood pressure values
+class BloodPressureBuilder extends StatelessWidget {
+  const BloodPressureBuilder({required this.onData, required this.rangeType, super.key});
+
+  final Widget Function(BuildContext context, UnmodifiableListView<BloodPressureRecord> records) onData;
+  final IntervallStoreManagerLocation rangeType;
+  
+  @override
+  Widget build(BuildContext context) {
+    return Consumer<BloodPressureModel>(
+      builder: (context, model, child) =>
+        Consumer<IntervallStoreManager>(
+          builder: (context, intervallManager, child) {
+            final range = intervallManager.get(rangeType).currentRange;
+            return ConsistentFutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
+              future: model.getInTimeRange(range.start, range.end),
+              onData: onData,
+            );
+          }
+        )
+    );
+  }
+  
+}
lib/components/display_interval_picker.dart
@@ -1,30 +1,33 @@
-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';
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 
 class IntervalPicker extends StatelessWidget {
-  const IntervalPicker({super.key});
+  const IntervalPicker({super.key, required this.type});
 
+  final IntervallStoreManagerLocation type;
+  
   @override
   Widget build(BuildContext context) {
-    return Consumer<Settings>(builder: (context, settings, child) {
+    return Consumer<IntervallStoreManager>(builder: (context, intervallStoreManager, child) {
+      final intervall = intervallStoreManager.get(type);
       final String intervallDisplayText;
-      switch (settings.graphStepSize) {
+      switch (intervall.stepSize) {
         case TimeStep.day:
-          intervallDisplayText = DateFormat.yMMMd(AppLocalizations.of(context)!.localeName).format(settings.displayDataStart);
+          intervallDisplayText = DateFormat.yMMMd(AppLocalizations.of(context)!.localeName).format(intervall.currentRange.start);
           break;
         case TimeStep.week:
-          final dayOfYear = int.parse(DateFormat("D").format(settings.displayDataStart));
-          final weekOfYear = ((dayOfYear - settings.displayDataStart.weekday + 10) / 7).floor();
-          intervallDisplayText = AppLocalizations.of(context)!.weekOfYear(weekOfYear, settings.displayDataStart.year);
+          final dayOfYear = int.parse(DateFormat("D").format(intervall.currentRange.start));
+          final weekOfYear = ((dayOfYear - intervall.currentRange.start.weekday + 10) / 7).floor();
+          intervallDisplayText = AppLocalizations.of(context)!.weekOfYear(weekOfYear, intervall.currentRange.start.year);
           break;
         case TimeStep.month:
-          intervallDisplayText =  DateFormat.yMMM(AppLocalizations.of(context)!.localeName).format(settings.displayDataStart);
+          intervallDisplayText =  DateFormat.yMMM(AppLocalizations.of(context)!.localeName).format(intervall.currentRange.start);
           break;
         case TimeStep.year:
-          intervallDisplayText = DateFormat.y(AppLocalizations.of(context)!.localeName).format(settings.displayDataStart);
+          intervallDisplayText = DateFormat.y(AppLocalizations.of(context)!.localeName).format(intervall.currentRange.start);
           break;
         case TimeStep.lifetime:
           intervallDisplayText =  '-';
@@ -33,7 +36,7 @@ class IntervalPicker extends StatelessWidget {
         case TimeStep.last30Days:
         case TimeStep.custom:
           final f = DateFormat.yMMMd(AppLocalizations.of(context)!.localeName);
-          intervallDisplayText = '${f.format(settings.displayDataStart)} - ${f.format(settings.displayDataEnd)}';
+          intervallDisplayText = '${f.format(intervall.currentRange.start)} - ${f.format(intervall.currentRange.end)}';
           break;
       }
       return Column(
@@ -47,7 +50,7 @@ class IntervalPicker extends StatelessWidget {
               flex: 3,
               child: MaterialButton(
                 onPressed: () {
-                  settings.moveDisplayDataByStep(-1);
+                  intervall.moveDataRangeByStep(-1);
                 },
                 child: const Icon(
                   Icons.chevron_left,
@@ -58,7 +61,7 @@ class IntervalPicker extends StatelessWidget {
             Expanded(
               flex: 4,
               child: DropdownButton<TimeStep>(
-                value: settings.graphStepSize,
+                value: intervall.stepSize,
                 isExpanded: true,
                 onChanged: (TimeStep? value) async {
                   if (value == TimeStep.custom) {
@@ -67,12 +70,11 @@ class IntervalPicker extends StatelessWidget {
                         firstDate: DateTime.fromMillisecondsSinceEpoch(1),
                         lastDate: DateTime.now());
                     if (res != null) {
-                      settings.graphStepSize = value!;
-                      settings.displayDataStart = res.start;
-                      settings.displayDataEnd = res.end;
+                      intervall.changeStepSize(value!);
+                      intervall.currentRange = res;
                     }
                   } else if (value != null) {
-                    settings.changeStepSize(value);
+                    intervall.changeStepSize(value);
                   }
                 },
                 items: TimeStep.options.map<DropdownMenuItem<TimeStep>>((v) {
@@ -84,7 +86,7 @@ class IntervalPicker extends StatelessWidget {
               flex: 3,
               child: MaterialButton(
                 onPressed: () {
-                  settings.moveDisplayDataByStep(1);
+                  intervall.moveDataRangeByStep(1);
                 },
                 child: const Icon(
                   Icons.chevron_right,
lib/components/export_item_order.dart
@@ -3,9 +3,10 @@ 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';
 import 'package:blood_pressure_app/screens/subsettings/export_column_data.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -27,7 +28,7 @@ class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
   @override
   Widget build(BuildContext context) {
     return ConsistentFutureBuilder(
-      future: ExportConfigurationModel.get(Provider.of<Settings>(context, listen: false), AppLocalizations.of(context)!),
+      future: ExportConfigurationModel.get(AppLocalizations.of(context)!),
       onData: (BuildContext context, ExportConfigurationModel result) {
         return _buildAddItemBadge(context, result,
           child: _buildManagePresetsBadge(context, result,
@@ -117,12 +118,12 @@ class _ExportItemsCustomizerState extends State<ExportItemsCustomizer> {
           ];
         },
         onSelected: (value) {
-          final settings = Provider.of<Settings>(context, listen: false);
-          if (settings.exportFormat == ExportFormat.csv) {
-            settings.exportItemsCsv = exportConfigurations[value].$2;
+          final exportSettings = Provider.of<ExportSettings>(context, listen: false);
+          if (exportSettings.exportFormat == ExportFormat.csv) {
+            Provider.of<CsvExportSettings>(context, listen: false).customFields = exportConfigurations[value].$2;
           } else {
-            assert(settings.exportFormat == ExportFormat.pdf);
-            settings.exportItemsPdf = exportConfigurations[value].$2;
+            assert(exportSettings.exportFormat == ExportFormat.pdf);
+            Provider.of<PdfExportSettings>(context, listen: false).customFields = exportConfigurations[value].$2;
           }
         },
       ),
lib/components/input_dialoge.dart
@@ -1,8 +1,6 @@
-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 {
@@ -42,15 +40,12 @@ class _InputDialogeState extends State<InputDialoge> {
         decoration: InputDecoration(hintText: widget.hintText),
       ),
       actions: [
-        Consumer<Settings>(builder: (context, settings, child) {
-          return ElevatedButton(
-              onPressed: () {
-                widget.onSubmit(controller.text);
-              },
-              child: Text(AppLocalizations.of(context)!.btnConfirm)
-          );
-        }),
-
+        ElevatedButton(
+          onPressed: () {
+            widget.onSubmit(controller.text);
+          },
+          child: Text(AppLocalizations.of(context)!.btnConfirm)
+        )
       ],
     );
   }
lib/components/legacy_measurement_list.dart
@@ -1,8 +1,9 @@
 import 'dart:collection';
 
-import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+import 'package:blood_pressure_app/components/blood_pressure_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';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -25,181 +26,173 @@ class LegacyMeasurementsList extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    return Column(
+    return Consumer<Settings>(builder: (context, settings, child) =>
+      Column(
       children: [
-        Consumer<Settings>(builder: (context, settings, child) {
-          return Column(children: [
-            Row(
-              children: [
-                Expanded(
-                  flex: _sideFlex,
-                  child: const SizedBox(),
-                ),
-                Expanded(
-                    flex: _tableElementsSizes[0],
-                    child: Text(AppLocalizations.of(context)!.time, style: const TextStyle(fontWeight: FontWeight.bold))),
-                Expanded(
-                    flex: _tableElementsSizes[1],
-                    child: Text(AppLocalizations.of(context)!.sysShort, style: TextStyle(fontWeight: FontWeight.bold, color: settings.sysColor))),
-                Expanded(
-                    flex: _tableElementsSizes[2],
-                    child: Text(AppLocalizations.of(context)!.diaShort, style: TextStyle(fontWeight: FontWeight.bold, color: settings.diaColor))),
-                Expanded(
-                    flex: _tableElementsSizes[3],
-                    child: Text(AppLocalizations.of(context)!.pulShort, style: TextStyle(fontWeight: FontWeight.bold, color: settings.pulColor))),
-                Expanded(
-                    flex: _tableElementsSizes[4],
-                    child: Text(AppLocalizations.of(context)!.notes, style: const TextStyle(fontWeight: FontWeight.bold))),
-                Expanded(
-                  flex: _sideFlex,
-                  child: const SizedBox(),
-                ),
-              ],
+        Row(
+          children: [
+            Expanded(
+              flex: _sideFlex,
+              child: const SizedBox(),
             ),
-            const SizedBox(
-              height: 10,
+            Expanded(
+                flex: _tableElementsSizes[0],
+                child: Text(AppLocalizations.of(context)!.time, style: const TextStyle(fontWeight: FontWeight.bold))),
+            Expanded(
+                flex: _tableElementsSizes[1],
+                child: Text(AppLocalizations.of(context)!.sysShort, style: TextStyle(fontWeight: FontWeight.bold, color: settings.sysColor))),
+            Expanded(
+                flex: _tableElementsSizes[2],
+                child: Text(AppLocalizations.of(context)!.diaShort, style: TextStyle(fontWeight: FontWeight.bold, color: settings.diaColor))),
+            Expanded(
+                flex: _tableElementsSizes[3],
+                child: Text(AppLocalizations.of(context)!.pulShort, style: TextStyle(fontWeight: FontWeight.bold, color: settings.pulColor))),
+            Expanded(
+                flex: _tableElementsSizes[4],
+                child: Text(AppLocalizations.of(context)!.notes, style: const TextStyle(fontWeight: FontWeight.bold))),
+            Expanded(
+              flex: _sideFlex,
+              child: const SizedBox(),
             ),
-            Divider(
-              height: 0,
-              thickness: 2,
-              color: Theme.of(context).colorScheme.primaryContainer,
-            )
-          ]);
-        }),
+          ],
+        ),
+        const SizedBox(
+          height: 10,
+        ),
+        Divider(
+          height: 0,
+          thickness: 2,
+          color: Theme.of(context).colorScheme.primaryContainer,
+        ),
         Expanded(
-          child: Consumer<BloodPressureModel>(builder: (context, model, child) {
-            return Consumer<Settings>(builder: (context, settings, child) {
-              return ConsistentFutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
-                future: model.getInTimeRange(settings.displayDataStart, settings.displayDataEnd),
-                onData: (context, data) {
-                  if (data.isNotEmpty) {
-                    return ListView.builder(
-                        itemCount: data.length,
-                        shrinkWrap: true,
-                        padding: const EdgeInsets.all(2),
-                        itemBuilder: (context, index) {
-                          final formatter = DateFormat(settings.dateFormatString);
-                          return Column(
-                            children: [
-                              Dismissible(
-                                key: Key(data[index].creationTime.toIso8601String()),
-                                confirmDismiss: (direction) async {
-                                  final model = Provider.of<BloodPressureModel>(context, listen: false);
-                                  if (direction == DismissDirection.startToEnd) { // edit
-                                    Navigator.push(
-                                      context,
-                                      MaterialPageRoute(builder: (context) => AddMeasurementPage.edit(data[index])),
-                                    );
-                                    return false;
-                                  } else { // delete
-                                    bool dialogeDeletionConfirmed = false;
-                                    if (settings.confirmDeletion) {
-                                      await showDialog(
-                                          context: context,
-                                          builder: (context) {
-                                            return AlertDialog(
-                                              title: Text(AppLocalizations.of(context)!.confirmDelete),
-                                              content: Text(AppLocalizations.of(context)!.confirmDeleteDesc),
-                                              actions: [
-                                                ElevatedButton(
-                                                    onPressed: () => Navigator.of(context).pop(),
-                                                    child: Text(AppLocalizations.of(context)!.btnCancel)),
-                                                ElevatedButton(
-                                                    onPressed: () {
-                                                      model.delete(data[index].creationTime);
+          child: BloodPressureBuilder(
+            rangeType: IntervallStoreManagerLocation.mainPage,
+            onData: (BuildContext context, UnmodifiableListView<BloodPressureRecord> data) {
+              if (data.isNotEmpty) {
+                return ListView.builder(
+                    itemCount: data.length,
+                    shrinkWrap: true,
+                    padding: const EdgeInsets.all(2),
+                    itemBuilder: (context, index) {
+                      final formatter = DateFormat(settings.dateFormatString);
+                      return Column(
+                        children: [
+                          Dismissible(
+                            key: Key(data[index].creationTime.toIso8601String()),
+                            confirmDismiss: (direction) async {
+                              final model = Provider.of<BloodPressureModel>(context, listen: false);
+                              if (direction == DismissDirection.startToEnd) { // edit
+                                Navigator.push(
+                                  context,
+                                  MaterialPageRoute(builder: (context) => AddMeasurementPage.edit(data[index])),
+                                );
+                                return false;
+                              } else { // delete
+                                bool dialogeDeletionConfirmed = false;
+                                if (settings.confirmDeletion) {
+                                  await showDialog(
+                                      context: context,
+                                      builder: (context) {
+                                        return AlertDialog(
+                                          title: Text(AppLocalizations.of(context)!.confirmDelete),
+                                          content: Text(AppLocalizations.of(context)!.confirmDeleteDesc),
+                                          actions: [
+                                            ElevatedButton(
+                                                onPressed: () => Navigator.of(context).pop(),
+                                                child: Text(AppLocalizations.of(context)!.btnCancel)),
+                                            ElevatedButton(
+                                                onPressed: () {
+                                                  model.delete(data[index].creationTime);
 
-                                                      dialogeDeletionConfirmed = true;
-                                                      Navigator.of(context).pop();
-                                                    },
-                                                    child: Text(AppLocalizations.of(context)!.btnConfirm)),
-                                              ],
-                                            );
-                                          });
-                                    } else {
-                                      model.delete(data[index].creationTime);
-                                      dialogeDeletionConfirmed = true;
-                                    }
+                                                  dialogeDeletionConfirmed = true;
+                                                  Navigator.of(context).pop();
+                                                },
+                                                child: Text(AppLocalizations.of(context)!.btnConfirm)),
+                                          ],
+                                        );
+                                      });
+                                } else {
+                                  model.delete(data[index].creationTime);
+                                  dialogeDeletionConfirmed = true;
+                                }
 
-                                    if (dialogeDeletionConfirmed) {
-                                      if (!context.mounted) return true;
-                                      ScaffoldMessenger.of(context).removeCurrentSnackBar();
-                                      ScaffoldMessenger.of(context).showSnackBar(SnackBar(
-                                        duration: const Duration(seconds: 5),
-                                        content: Text(AppLocalizations.of(context)!.deletionConfirmed),
-                                        action: SnackBarAction(
-                                          label: AppLocalizations.of(context)!.btnUndo,
-                                          onPressed: () async {
-                                            model.add(BloodPressureRecord(
-                                                data[index].creationTime,
-                                                data[index].systolic,
-                                                data[index].diastolic,
-                                                data[index].pulse,
-                                                data[index].notes));
-                                          },
-                                        ),
-                                      ));
-                                    }
-                                    return dialogeDeletionConfirmed;
-                                  }
-                                },
-                                onDismissed: (direction) {},
-                                background: Container(
-                                  width: 10,
-                                  decoration:
-                                  BoxDecoration(color: Colors.blue, borderRadius: BorderRadius.circular(5)),
-                                  child: const Align(alignment: Alignment(-0.95, 0), child: Icon(Icons.edit)),
-                                ),
-                                secondaryBackground: Container(
-                                  width: 10,
-                                  decoration:
-                                  BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(5)),
-                                  child: const Align(alignment: Alignment(0.95, 0), child: Icon(Icons.delete)),
-                                ),
-                                child: Container(
-                                  constraints: const BoxConstraints(minHeight: 40),
-                                  child: Row(children: [
-                                    Expanded(
-                                      flex: _sideFlex,
-                                      child: const SizedBox(),
+                                if (dialogeDeletionConfirmed) {
+                                  if (!context.mounted) return true;
+                                  ScaffoldMessenger.of(context).removeCurrentSnackBar();
+                                  ScaffoldMessenger.of(context).showSnackBar(SnackBar(
+                                    duration: const Duration(seconds: 5),
+                                    content: Text(AppLocalizations.of(context)!.deletionConfirmed),
+                                    action: SnackBarAction(
+                                      label: AppLocalizations.of(context)!.btnUndo,
+                                      onPressed: () async {
+                                        model.add(BloodPressureRecord(
+                                            data[index].creationTime,
+                                            data[index].systolic,
+                                            data[index].diastolic,
+                                            data[index].pulse,
+                                            data[index].notes));
+                                      },
                                     ),
-                                    Expanded(
-                                        flex: _tableElementsSizes[0],
-                                        child: Text(formatter.format(data[index].creationTime))),
-                                    Expanded(
-                                        flex: _tableElementsSizes[1],
-                                        child: Text((data[index].systolic ?? '').toString())),
-                                    Expanded(
-                                        flex: _tableElementsSizes[2],
-                                        child: Text((data[index].diastolic ?? '').toString())),
-                                    Expanded(
-                                        flex: _tableElementsSizes[3],
-                                        child: Text((data[index].pulse ?? '').toString())),
-                                    Expanded(
-                                        flex: _tableElementsSizes[4],
-                                        child: Text(data[index].notes ?? '')),
-                                    Expanded(
-                                      flex: _sideFlex,
-                                      child: const SizedBox(),
-                                    ),
-                                  ]),
+                                  ));
+                                }
+                                return dialogeDeletionConfirmed;
+                              }
+                            },
+                            onDismissed: (direction) {},
+                            background: Container(
+                              width: 10,
+                              decoration:
+                              BoxDecoration(color: Colors.blue, borderRadius: BorderRadius.circular(5)),
+                              child: const Align(alignment: Alignment(-0.95, 0), child: Icon(Icons.edit)),
+                            ),
+                            secondaryBackground: Container(
+                              width: 10,
+                              decoration:
+                              BoxDecoration(color: Colors.red, borderRadius: BorderRadius.circular(5)),
+                              child: const Align(alignment: Alignment(0.95, 0), child: Icon(Icons.delete)),
+                            ),
+                            child: Container(
+                              constraints: const BoxConstraints(minHeight: 40),
+                              child: Row(children: [
+                                Expanded(
+                                  flex: _sideFlex,
+                                  child: const SizedBox(),
+                                ),
+                                Expanded(
+                                    flex: _tableElementsSizes[0],
+                                    child: Text(formatter.format(data[index].creationTime))),
+                                Expanded(
+                                    flex: _tableElementsSizes[1],
+                                    child: Text((data[index].systolic ?? '').toString())),
+                                Expanded(
+                                    flex: _tableElementsSizes[2],
+                                    child: Text((data[index].diastolic ?? '').toString())),
+                                Expanded(
+                                    flex: _tableElementsSizes[3],
+                                    child: Text((data[index].pulse ?? '').toString())),
+                                Expanded(
+                                    flex: _tableElementsSizes[4],
+                                    child: Text(data[index].notes ?? '')),
+                                Expanded(
+                                  flex: _sideFlex,
+                                  child: const SizedBox(),
                                 ),
-                              ),
-                              const Divider(
-                                thickness: 1,
-                                height: 1,
-                              )
-                            ],
-                          );
-                        });
-                  } else {
-                    return Text(AppLocalizations.of(context)!.errNoData);
-                  }
-                },
-              );
-            });
-          }),
+                              ]),
+                            ),
+                          ),
+                          const Divider(
+                            thickness: 1,
+                            height: 1,
+                          )
+                        ],
+                      );
+                    });
+              } else {
+                return Text(AppLocalizations.of(context)!.errNoData);
+              }
+            }),
         )
       ],
-    );
+    ));
   }
 }
lib/components/measurement_graph.dart
@@ -1,10 +1,11 @@
 import 'dart:math';
 
-import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+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/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';
 import 'package:fl_chart/fl_chart.dart';
 import 'package:flutter/material.dart';
@@ -28,69 +29,66 @@ class _LineChartState extends State<_LineChart> {
         height: widget.height,
         child: Consumer<Settings>(
           builder: (context, settings, child) {
-            return Consumer<BloodPressureModel>(builder: (context, model, child) {
-              var end = settings.displayDataEnd;
-              return ConsistentFutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
-                  future: model.getInTimeRange(settings.displayDataStart, end),
-                  onData: (context, fetchedData) {
-                    List<BloodPressureRecord> data = fetchedData.toList();
-                    data.sort((a, b) => a.creationTime.compareTo(b.creationTime));
-
-                    // calculate lines for graph
-                    List<FlSpot> pulSpots = [], diaSpots = [], sysSpots = [];
-                    int maxValue = 0;
-                    int minValue = (settings.validateInputs ? 30 : 0);
-                    double? graphBegin;
-                    double? graphEnd;
-                    for (var e in data) {
-                      final x = e.creationTime.millisecondsSinceEpoch.toDouble();
-                      if (e.diastolic != null) {
-                        diaSpots.add(FlSpot(x, e.diastolic!.toDouble()));
-                        maxValue = max(maxValue, e.diastolic!);
-                      }
-                      if (e.systolic != null) {
-                        sysSpots.add(FlSpot(x, e.systolic!.toDouble()));
-                        maxValue = max(maxValue, e.systolic!);
-                      }
-                      if (e.pulse != null) {
-                        pulSpots.add(FlSpot(x, e.pulse!.toDouble()));
-                        maxValue = max(maxValue, e.pulse!);
-                      }
-                      graphBegin ??= x;
-                      graphEnd ??= x;
-                      if (x < graphBegin) graphBegin = x;
-                      if (x > graphEnd) graphEnd = x;
-                    }
-
-                    if (diaSpots.length < 2 && sysSpots.length < 2 && pulSpots.length < 2 || graphBegin == null || graphEnd == null) {
-                      return Text(AppLocalizations.of(context)!.errNotEnoughDataToGraph);
-                    }
-
-
-                    return TweenAnimationBuilder<double>(
-                      duration: const Duration(milliseconds: 200), // interacts with LineChart duration property
-                      tween: Tween<double>(begin: 0, end: settings.graphLineThickness),
-                      builder: (context, animatedThickness, child) {
-                        return LineChart(
-                          duration: const Duration(milliseconds: 200),
-                          LineChartData(
-                              minY: minValue.toDouble(),
-                              maxY: maxValue + 5,
-                              clipData: const FlClipData.all(),
-                              titlesData: _buildFlTitlesData(settings,
-                                  DateTimeRange(start: data.first.creationTime, end: data.last.creationTime)),
-                              lineTouchData: const LineTouchData(
-                                  touchTooltipData: LineTouchTooltipData(tooltipMargin: -200, tooltipRoundedRadius: 20)
-                              ),
-                              lineBarsData: buildBars(animatedThickness, settings, sysSpots, diaSpots, pulSpots,
-                                  maxValue, minValue, graphBegin, graphEnd, fetchedData)
+            return BloodPressureBuilder(
+              rangeType: IntervallStoreManagerLocation.mainPage,
+              onData: (BuildContext context, UnmodifiableListView<BloodPressureRecord> records) {
+                List<BloodPressureRecord> data = records.toList();
+                data.sort((a, b) => a.creationTime.compareTo(b.creationTime));
+
+                // calculate lines for graph
+                List<FlSpot> pulSpots = [], diaSpots = [], sysSpots = [];
+                int maxValue = 0;
+                int minValue = (settings.validateInputs ? 30 : 0);
+                double? graphBegin;
+                double? graphEnd;
+                for (var e in data) {
+                  final x = e.creationTime.millisecondsSinceEpoch.toDouble();
+                  if (e.diastolic != null) {
+                    diaSpots.add(FlSpot(x, e.diastolic!.toDouble()));
+                    maxValue = max(maxValue, e.diastolic!);
+                  }
+                  if (e.systolic != null) {
+                    sysSpots.add(FlSpot(x, e.systolic!.toDouble()));
+                    maxValue = max(maxValue, e.systolic!);
+                  }
+                  if (e.pulse != null) {
+                    pulSpots.add(FlSpot(x, e.pulse!.toDouble()));
+                    maxValue = max(maxValue, e.pulse!);
+                  }
+                  graphBegin ??= x;
+                  graphEnd ??= x;
+                  if (x < graphBegin) graphBegin = x;
+                  if (x > graphEnd) graphEnd = x;
+                }
+
+                if (diaSpots.length < 2 && sysSpots.length < 2 && pulSpots.length < 2 || graphBegin == null || graphEnd == null) {
+                  return Text(AppLocalizations.of(context)!.errNotEnoughDataToGraph);
+                }
+
+
+                return TweenAnimationBuilder<double>(
+                  duration: const Duration(milliseconds: 200), // interacts with LineChart duration property
+                  tween: Tween<double>(begin: 0, end: settings.graphLineThickness),
+                  builder: (context, animatedThickness, child) {
+                    return LineChart(
+                      duration: const Duration(milliseconds: 200),
+                      LineChartData(
+                          minY: minValue.toDouble(),
+                          maxY: maxValue + 5,
+                          clipData: const FlClipData.all(),
+                          titlesData: _buildFlTitlesData(settings,
+                              DateTimeRange(start: data.first.creationTime, end: data.last.creationTime)),
+                          lineTouchData: const LineTouchData(
+                              touchTooltipData: LineTouchTooltipData(tooltipMargin: -200, tooltipRoundedRadius: 20)
                           ),
-                        );
-                      },
+                          lineBarsData: buildBars(animatedThickness, settings, sysSpots, diaSpots, pulSpots,
+                              maxValue, minValue, graphBegin, graphEnd, records)
+                      ),
                     );
-                  }
-              );
-            });
+                  },
+                );
+              },
+            );
           },
         )
     );
@@ -238,7 +236,7 @@ class MeasurementGraph extends StatelessWidget {
         child: Column(
           children: [
             _LineChart(height: height - 100),
-            const IntervalPicker()
+            const IntervalPicker(type: IntervallStoreManagerLocation.mainPage,)
           ],
         ),
       ),
lib/model/storage/common_settings_intervaces.dart
@@ -0,0 +1,9 @@
+/// This file hosts interfaces with attributes that different settings classes provide.
+
+
+abstract class CustomFieldsSettings {
+  bool get exportCustomFields;
+  set exportCustomFields(bool value);
+  List<String> get customFields;
+  set customFields(List<String> value);
+}
\ No newline at end of file
lib/model/storage/export_csv_settings_store.dart
@@ -1,10 +1,11 @@
 import 'dart:convert';
 
 import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/storage/common_settings_intervaces.dart';
 import 'package:blood_pressure_app/model/storage/convert_util.dart';
 import 'package:flutter/material.dart';
 
-class CsvExportSettings extends ChangeNotifier {
+class CsvExportSettings extends ChangeNotifier implements CustomFieldsSettings {
   CsvExportSettings({
     String? fieldDelimiter,
     String? textDelimiter,
lib/model/storage/export_pdf_settings_store.dart
@@ -1,10 +1,11 @@
 import 'dart:convert';
 
 import 'package:blood_pressure_app/model/export_options.dart';
+import 'package:blood_pressure_app/model/storage/common_settings_intervaces.dart';
 import 'package:blood_pressure_app/model/storage/convert_util.dart';
 import 'package:flutter/material.dart';
 
-class PdfExportSettings extends ChangeNotifier {
+class PdfExportSettings extends ChangeNotifier implements CustomFieldsSettings {
   PdfExportSettings({
     bool? exportTitle,
     bool? exportStatistics,
lib/model/storage/intervall_store.dart
@@ -1,6 +1,7 @@
 import 'dart:convert';
 
 import 'package:blood_pressure_app/model/storage/convert_util.dart';
+import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 
@@ -228,4 +229,42 @@ enum TimeStep {
         return TimeStep.last7Days;
     }
   }
+}
+
+/// Class that stores the interval objects that are needed in the app and provides named access to them. 
+class IntervallStoreManager extends ChangeNotifier {
+  IntervallStoreManager(this.mainPage, this.exportPage, this.statsPage) {
+    mainPage.addListener(notifyListeners);
+    exportPage.addListener(notifyListeners);
+    statsPage.addListener(notifyListeners);
+  }
+
+  static Future<IntervallStoreManager> load(ConfigDao configDao, int profileID) async =>
+      IntervallStoreManager(
+          await configDao.loadIntervallStorage(profileID, 0),
+          await configDao.loadIntervallStorage(profileID, 1),
+          await configDao.loadIntervallStorage(profileID, 2),
+      );
+
+  IntervallStorage get(IntervallStoreManagerLocation type) {
+    switch (type) {
+      case IntervallStoreManagerLocation.mainPage:
+        return mainPage;
+      case IntervallStoreManagerLocation.exportPage:
+        return exportPage;
+      case IntervallStoreManagerLocation.statsPage:
+        return statsPage;
+    }
+  }
+  
+  IntervallStorage mainPage;
+  IntervallStorage exportPage;
+  IntervallStorage statsPage;
+}
+
+/// enum of all locations supported by IntervallStoreManager
+enum IntervallStoreManagerLocation {
+  mainPage,
+  exportPage,
+  statsPage,
 }
\ No newline at end of file
lib/model/storage/settings_store.dart
@@ -1,5 +1,6 @@
 import 'dart:convert';
 
+import 'package:blood_pressure_app/model/horizontal_graph_line.dart';
 import 'package:blood_pressure_app/model/storage/convert_util.dart';
 import 'package:flutter/material.dart';
 
@@ -26,6 +27,7 @@ class Settings extends ChangeNotifier {
     MaterialColor? sysColor,
     MaterialColor? diaColor,
     MaterialColor? pulColor,
+    List<HorizontalGraphLine>? horizontalGraphLines,
     String? dateFormatString,
     double? graphLineThickness,
     int? animationSpeed,
@@ -59,6 +61,7 @@ class Settings extends ChangeNotifier {
     if (drawRegressionLines != null) _drawRegressionLines = drawRegressionLines;
     if (startWithAddMeasurementPage != null) _startWithAddMeasurementPage = startWithAddMeasurementPage;
     if (useLegacyList != null) _useLegacyList = useLegacyList;
+    if (horizontalGraphLines != null) _horizontalGraphLines = horizontalGraphLines;
     _language = language; // No check here, as null is the default as well. In general values should not be null
   }
 
@@ -81,7 +84,9 @@ class Settings extends ChangeNotifier {
     drawRegressionLines: ConvertUtil.parseBool(map['drawRegressionLines']),
     startWithAddMeasurementPage: ConvertUtil.parseBool(map['startWithAddMeasurementPage']),
     useLegacyList: ConvertUtil.parseBool(map['useLegacyList']),
-    language: ConvertUtil.parseLocale(map['language'])
+    language: ConvertUtil.parseLocale(map['language']),
+    horizontalGraphLines: ConvertUtil.parseList<String>(map['horizontalGraphLines'])?.map((e) =>
+        HorizontalGraphLine.fromJson(jsonDecode(e))).toList(),
   );
 
   factory Settings.fromJson(String json) {
@@ -112,6 +117,7 @@ class Settings extends ChangeNotifier {
       'startWithAddMeasurementPage': startWithAddMeasurementPage,
       'useLegacyList': useLegacyList,
       'language': ConvertUtil.serializeLocale(language),
+      'horizontalGraphLines': horizontalGraphLines.map((e) => jsonEncode(e)).toList()
     };
 
   String toJson() => jsonEncode(toMap());
@@ -152,6 +158,13 @@ class Settings extends ChangeNotifier {
     notifyListeners();
   }
 
+  List<HorizontalGraphLine> _horizontalGraphLines = [];
+  List<HorizontalGraphLine> get horizontalGraphLines => _horizontalGraphLines;
+  set horizontalGraphLines(List<HorizontalGraphLine> value) {
+    _horizontalGraphLines = value;
+    notifyListeners();
+  }
+
   String _dateFormatString = 'yyyy-MM-dd  HH:mm';
   String get dateFormatString => _dateFormatString;
   set dateFormatString(String value) {
lib/model/export_import.dart
@@ -5,7 +5,10 @@ import 'dart:typed_data';
 
 import 'package:blood_pressure_app/model/blood_pressure_analyzer.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';
+import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:csv/csv.dart';
 import 'package:file_picker/file_picker.dart';
 import 'package:file_saver/file_saver.dart';
@@ -16,6 +19,7 @@ import 'package:jsaver/jSaver.dart';
 import 'package:path/path.dart';
 import 'package:pdf/pdf.dart';
 import 'package:pdf/widgets.dart' as pw;
+import 'package:provider/provider.dart';
 import 'package:share_plus/share_plus.dart';
 import 'package:sqflite/sqflite.dart';
 
@@ -28,14 +32,18 @@ extension PdfCompatability on Color {
 // TODO: more testing
 class ExportFileCreator {
   final Settings settings;
+  final ExportSettings exportSettings;
+  final CsvExportSettings csvExportSettings;
+  final PdfExportSettings pdfExportSettings;
   final AppLocalizations localizations;
   final ThemeData theme;
   final ExportConfigurationModel exportColumnsConfig;
 
-  ExportFileCreator(this.settings, this.localizations, this.theme, this.exportColumnsConfig);
+  ExportFileCreator(this.settings, this.exportSettings, this.csvExportSettings, this.pdfExportSettings,
+      this.localizations, this.theme, this.exportColumnsConfig,);
 
-  Future<Uint8List> createFile(List<BloodPressureRecord> records) async {
-    switch (settings.exportFormat) {
+  Future<Uint8List> createFile(Iterable<BloodPressureRecord> records) async {
+    switch (exportSettings.exportFormat) {
       case ExportFormat.csv:
         return createCSVFile(records);
       case ExportFormat.pdf:
@@ -46,7 +54,7 @@ class ExportFileCreator {
   }
 
   Future<List<BloodPressureRecord>?> parseFile(String filePath, Uint8List data) async {
-    switch(settings.exportFormat) {
+    switch(exportSettings.exportFormat) {
       case ExportFormat.csv:
         try {
           return parseCSVFile(data);
@@ -60,9 +68,11 @@ class ExportFileCreator {
     }
   }
 
-  Uint8List createCSVFile(List<BloodPressureRecord> records) {
-    final items = exportColumnsConfig.createTable(records, ExportFormat.csv, createHeadline: settings.exportCsvHeadline);
-    final converter = ListToCsvConverter(fieldDelimiter: settings.csvFieldDelimiter, textDelimiter: settings.csvTextDelimiter);
+  Uint8List createCSVFile(Iterable<BloodPressureRecord> records) {
+    final columns = exportColumnsConfig.getActiveExportColumns(ExportFormat.csv, csvExportSettings);
+    final items = exportColumnsConfig.createTable(records, columns, createHeadline: csvExportSettings.exportHeadline);
+    final converter = ListToCsvConverter(fieldDelimiter: csvExportSettings.fieldDelimiter,
+        textDelimiter: csvExportSettings.textDelimiter);
     final csvData = converter.convert(items);
     return Uint8List.fromList(utf8.encode(csvData));
   }
@@ -71,10 +81,10 @@ class ExportFileCreator {
     List<BloodPressureRecord> records = [];
 
     String fileContents = utf8.decode(data.toList());
-    var converter = CsvToListConverter(fieldDelimiter: settings.csvFieldDelimiter, textDelimiter: settings.csvTextDelimiter);
+    var converter = CsvToListConverter(fieldDelimiter: csvExportSettings.fieldDelimiter, textDelimiter: csvExportSettings.textDelimiter);
     var csvLines = converter.convert(fileContents);
     if (csvLines.length <= 1) { // legacy files
-      converter = CsvToListConverter(fieldDelimiter: settings.csvFieldDelimiter, textDelimiter: settings.csvTextDelimiter, eol: '\n');
+      converter = CsvToListConverter(fieldDelimiter: csvExportSettings.fieldDelimiter, textDelimiter: csvExportSettings.textDelimiter, eol: '\n');
       csvLines = converter.convert(fileContents);
     }
 
@@ -136,7 +146,7 @@ class ExportFileCreator {
     return records;
   }
 
-  Future<Uint8List> createPdfFile(List<BloodPressureRecord> data) async {
+  Future<Uint8List> createPdfFile(Iterable<BloodPressureRecord> data) async {
     final analyzer = BloodPressureAnalyser(data.toList());
     final dateFormatter = DateFormat(settings.dateFormatString);
 
@@ -146,11 +156,11 @@ class ExportFileCreator {
         pageFormat: PdfPageFormat.a4,
         build: (pw.Context context) {
           return [
-            if (settings.exportPdfExportTitle)
+            if (pdfExportSettings.exportTitle)
               _buildPdfTitle(dateFormatter, analyzer),
-            if (settings.exportPdfExportStatistics)
+            if (pdfExportSettings.exportStatistics)
               _buildPdfStatistics(analyzer),
-            if (settings.exportPdfExportData)
+            if (pdfExportSettings.exportData)
               _buildPdfTable(data, dateFormatter),
           ];
         }));
@@ -182,8 +192,9 @@ class ExportFileCreator {
     );
   }
 
-  pw.Widget _buildPdfTable(List<BloodPressureRecord> data, DateFormat dateFormatter) {
-    final tableData = exportColumnsConfig.createTable(data, ExportFormat.pdf, createHeadline: true);
+  pw.Widget _buildPdfTable(Iterable<BloodPressureRecord> data, DateFormat dateFormatter) {
+    final columns = exportColumnsConfig.getActiveExportColumns(ExportFormat.pdf, pdfExportSettings);
+    final tableData = exportColumnsConfig.createTable(data, columns, createHeadline: true);
 
     return pw.TableHelper.fromTextArray(
         border: null,
@@ -191,16 +202,16 @@ class ExportFileCreator {
         headerDecoration: const pw.BoxDecoration(
           border: pw.Border(bottom: pw.BorderSide(color: PdfColors.black))
         ),
-        headerHeight: settings.exportPdfHeaderHeight,
-        cellHeight: settings.exportPdfCellHeight,
+        headerHeight: pdfExportSettings.headerHeight,
+        cellHeight: pdfExportSettings.cellHeight,
         cellAlignments: { for (var v in List.generate(tableData.first.length, (idx)=>idx)) v : pw.Alignment.centerLeft },
         headerStyle: pw.TextStyle(
           color: PdfColors.black,
-          fontSize: settings.exportPdfHeaderFontSize,
+          fontSize: pdfExportSettings.headerFontSize,
           fontWeight: pw.FontWeight.bold,
         ),
         cellStyle: pw.TextStyle(
-          fontSize: settings.exportPdfCellFontSize,
+          fontSize: pdfExportSettings.cellFontSize,
         ),
         headerCellDecoration: pw.BoxDecoration(
           border: pw.Border(
@@ -239,21 +250,39 @@ class ExportFileCreator {
 }
 
 class Exporter {
+  final Iterable<BloodPressureRecord> data;
   final Settings settings;
+  final ExportSettings exportSettings;
+  final CsvExportSettings csvExportSettings;
+  final PdfExportSettings pdfExportSettings;
   final BloodPressureModel model;
   final ScaffoldMessengerState messenger;
   final AppLocalizations localizations;
   final ThemeData theme;
   final ExportConfigurationModel exportColumnsConfig;
 
-  Exporter(this.settings, this.model, this.messenger, this.localizations, this.theme, this.exportColumnsConfig);
+  Exporter(this.data, this.model, this.messenger, this.localizations, this.theme, this.exportColumnsConfig,
+      this.settings, this.exportSettings, this.csvExportSettings, this.pdfExportSettings);
+  factory Exporter.load(BuildContext context, Iterable<BloodPressureRecord> data, ExportConfigurationModel exportColumnsConfig) {
+
+    final settings = Provider.of<Settings>(context);
+    final exportSettings = Provider.of<ExportSettings>(context);
+    final csvExportSettings = Provider.of<CsvExportSettings>(context);
+    final pdfExportSettings = Provider.of<PdfExportSettings>(context);
+    final model = Provider.of<BloodPressureModel>(context);
+    final localizations = AppLocalizations.of(context)!;
+    final theme = Theme.of(context);
+    final messenger = ScaffoldMessenger.of(context);
+    return Exporter(data, model, messenger, localizations, theme, exportColumnsConfig, settings, exportSettings,
+        csvExportSettings, pdfExportSettings);
+  }
 
   Future<void> export() async {
-    final entries = await model.getInTimeRange(settings.displayDataStart, settings.displayDataEnd);
-    var fileContents = await ExportFileCreator(settings, localizations, theme, exportColumnsConfig).createFile(entries);
+    var fileContents = await ExportFileCreator(settings, exportSettings, csvExportSettings, pdfExportSettings,
+        localizations, theme, exportColumnsConfig).createFile(data);
     String filename = 'blood_press_${DateTime.now().toIso8601String()}';
     String ext;
-    switch(settings.exportFormat) {
+    switch(exportSettings.exportFormat) {
       case ExportFormat.csv:
         ext = 'csv';
         break;
@@ -269,12 +298,12 @@ class Exporter {
     if (Platform.isLinux || Platform.isWindows || Platform.isMacOS) {
       messenger.showSnackBar(SnackBar(content: Text(localizations.success(path))));
     } else if (Platform.isAndroid || Platform.isIOS) {
-      if (settings.defaultExportDir.isNotEmpty) {
+      if (exportSettings.defaultExportDir.isNotEmpty) {
         JSaver.instance.save(
             fromPath: path,
             androidPathOptions: AndroidPathOptions(toDefaultDirectory: true)
         );
-        messenger.showSnackBar(SnackBar(content: Text(localizations.success(settings.defaultExportDir))));
+        messenger.showSnackBar(SnackBar(content: Text(localizations.success(exportSettings.defaultExportDir))));
       } else {
         Share.shareXFiles([
           XFile(
@@ -290,7 +319,7 @@ class Exporter {
 
 
   Future<void> import() async {
-    if (!([ExportFormat.csv, ExportFormat.db].contains(settings.exportFormat))) {
+    if (!([ExportFormat.csv, ExportFormat.db].contains(exportSettings.exportFormat))) {
       messenger.showSnackBar(SnackBar(content: Text(localizations.errWrongImportFormat)));
       return;
     }
@@ -311,7 +340,8 @@ class Exporter {
     var path = result.files.single.path;
     assert(path != null); // null state directly linked to binary content
 
-    final fileContentsFuture = ExportFileCreator(settings, localizations, theme, exportColumnsConfig).parseFile(path! ,binaryContent);
+    final fileContentsFuture = ExportFileCreator(settings, exportSettings, csvExportSettings, pdfExportSettings,
+        localizations, theme, exportColumnsConfig).parseFile(path! ,binaryContent);
     Object? fileContentsError;
     fileContentsFuture.onError((error, stackTrace) {
       fileContentsError = error;
@@ -330,10 +360,4 @@ class Exporter {
       model.add(e);
     }
   }
-}
-
-enum ExportFormat {
-  csv,
-  pdf,
-  db
 }
\ No newline at end of file
lib/model/export_options.dart
@@ -2,9 +2,9 @@ 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:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:function_tree/function_tree.dart';
@@ -20,7 +20,6 @@ class ExportConfigurationModel {
   // 2 sources.
   static ExportConfigurationModel? _instance;
 
-  final Settings settings;
   final AppLocalizations localizations;
   final ConfigDao _configDao; // TODO: remove after #181 is complete
   
@@ -34,30 +33,30 @@ class ExportConfigurationModel {
     ('"My Heart" export', ['DATUM', 'SYSTOLE', 'DIASTOLE', 'PULS', 'Beschreibung', 'Tags', 'Gewicht', 'Sauerstoffsättigung']),
   ];
 
-  ExportConfigurationModel._create(this.settings, this.localizations, this._configDao);
+  ExportConfigurationModel._create(this.localizations, this._configDao);
   Future<void> _asyncInit() async {
-
     _availableFormats.addAll(getDefaultFormates());
     _availableFormats.addAll(await _configDao.loadExportColumns());
   }
-  static Future<ExportConfigurationModel> get(Settings settings, AppLocalizations localizations, {String? dbPath, bool isFullPath = false}) async {
+  static Future<ExportConfigurationModel> get(AppLocalizations localizations) async {
     if (_instance == null) {
-      _instance = ExportConfigurationModel._create(settings, localizations, globalConfigDao);
+      _instance = ExportConfigurationModel._create(localizations, globalConfigDao);
       await _instance!._asyncInit();
     }
     return _instance!;
   }
 
-  List<ExportColumn> getActiveExportColumns(ExportFormat format) {
+  /// Determines which export columns should be used.
+  ///
+  /// The [fieldSettings] parameter describes the settings of the current export format and should be set accordingly.
+  List<ExportColumn> getActiveExportColumns(ExportFormat format, CustomFieldsSettings fieldsSettings) {
     switch (format) {
       case ExportFormat.csv:
-        return availableFormats.where((e) =>
-            ((settings.exportCustomEntriesCsv) ? settings.exportItemsCsv : ExportFields.defaultCsv)
-                .contains(e.internalName)).toList();
+        final fields = (fieldsSettings.exportCustomFields) ? fieldsSettings.customFields : ExportFields.defaultCsv;
+        return availableFormats.where((e) => fields.contains(e.internalName)).toList();
       case ExportFormat.pdf:
-        return availableFormats.where((e) => 
-          ((settings.exportCustomEntriesPdf) ? settings.exportItemsPdf : ExportFields.defaultPdf)
-        .contains(e.internalName)).toList();
+        final fields = (fieldsSettings.exportCustomFields) ? fieldsSettings.customFields : ExportFields.defaultPdf;
+        return availableFormats.where((e) => fields.contains(e.internalName)).toList();
       case ExportFormat.db:
         // Export formats don't work on this one
         return [];
@@ -66,7 +65,7 @@ class ExportConfigurationModel {
   
   List<ExportColumn> getDefaultFormates() => [
     ExportColumn(internalName: 'timestampUnixMs', columnTitle: localizations.unixTimestamp, formatPattern: r'$TIMESTAMP', editable: false),
-    ExportColumn(internalName: 'formattedTimestamp', columnTitle: localizations.time, formatPattern: '\$FORMAT{\$TIMESTAMP,${settings.dateFormatString}}', editable: false),
+    ExportColumn(internalName: 'formattedTimestamp', columnTitle: localizations.time, formatPattern: '\$FORMAT{\$TIMESTAMP,yyyy-MM-dd HH:mm:ss}', editable: false),
     ExportColumn(internalName: 'systolic', columnTitle: localizations.sysLong, formatPattern: r'$SYS', editable: false),
     ExportColumn(internalName: 'diastolic', columnTitle: localizations.diaLong, formatPattern: r'$DIA', editable: false),
     ExportColumn(internalName: 'pulse', columnTitle: localizations.pulLong, formatPattern: r'$PUL', editable: false),
@@ -100,14 +99,17 @@ class ExportConfigurationModel {
   UnmodifiableMapView<String, ExportColumn> get availableFormatsMap =>
       UnmodifiableMapView(Map.fromIterable(_availableFormats, key: (e) => e.internalName));
 
-  List<List<String>> createTable(List<BloodPressureRecord> data, ExportFormat format, {bool createHeadline = true,}) {
-    final exportItems = getActiveExportColumns(format);
+
+  List<List<String>> createTable(Iterable<BloodPressureRecord> data, List<ExportColumn> activeExportColumns,
+      {bool createHeadline = true,}) {
     List<List<String>> items = [];
     if (createHeadline) {
-      items.add(exportItems.map((e) => e.internalName).toList());
+      items.add(activeExportColumns.map((e) => e.internalName).toList());
     }
 
-    final dataRows = data.map((record) => exportItems.map((attribute) => attribute.formatRecord(record)).toList());
+    final dataRows = data.map((record) =>
+        activeExportColumns.map((attribute) =>
+            attribute.formatRecord(record)).toList());
     items.addAll(dataRows);
     return items;
   }
lib/model/settings_store.dart
@@ -1,639 +1,10 @@
-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';
-
-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();
-  }
+// TODO: remove file
 
-  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 {
+enum _TimeStep {
   day,
   month,
   year,
@@ -643,31 +14,31 @@ enum TimeStep {
   last30Days,
   custom;
 
-  static const options = [TimeStep.day, TimeStep.week, TimeStep.month, TimeStep.year, TimeStep.lifetime, TimeStep.last7Days, TimeStep.last30Days, TimeStep.custom];
+  static const options = [_TimeStep.day, _TimeStep.week, _TimeStep.month, _TimeStep.year, _TimeStep.lifetime, _TimeStep.last7Days, _TimeStep.last30Days, _TimeStep.custom];
 
-  static String getName(TimeStep opt, BuildContext context) {
+  static String getName(_TimeStep opt, BuildContext context) {
     switch (opt) {
-      case TimeStep.day:
+      case _TimeStep.day:
         return AppLocalizations.of(context)!.day;
-      case TimeStep.month:
+      case _TimeStep.month:
         return AppLocalizations.of(context)!.month;
-      case TimeStep.year:
+      case _TimeStep.year:
         return AppLocalizations.of(context)!.year;
-      case TimeStep.lifetime:
+      case _TimeStep.lifetime:
         return AppLocalizations.of(context)!.lifetime;
-      case TimeStep.week:
+      case _TimeStep.week:
         return AppLocalizations.of(context)!.week;
-      case TimeStep.last7Days:
+      case _TimeStep.last7Days:
         return AppLocalizations.of(context)!.last7Days;
-      case TimeStep.last30Days:
+      case _TimeStep.last30Days:
         return AppLocalizations.of(context)!.last30Days;
-      case TimeStep.custom:
+      case _TimeStep.custom:
         return AppLocalizations.of(context)!.custom;
     }
   }
 }
 
-MaterialColor createMaterialColor(int value) {
+MaterialColor createMaterialColor(int value) { // TODO: remove
   final color = Color(value);
   List strengths = <double>[.05];
   Map<int, Color> swatch = {};
lib/screens/subsettings/enter_timeformat.dart
@@ -1,4 +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';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
lib/screens/subsettings/export_column_data.dart
@@ -1,10 +1,8 @@
 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/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;
@@ -163,9 +161,8 @@ class _EditExportColumnPageState extends State<EditExportColumnPage> {
                         label: Text(localizations.btnSave),
                         onPressed: (widget.editable) ? (() async {
                           if (_formKey.currentState?.validate() ?? false) {
-                            final settings = Provider.of<Settings>(context, listen: false);
                             final navigator = Navigator.of(context);
-                            (await ExportConfigurationModel.get(settings, localizations)).addOrUpdate(ExportColumn(
+                            (await ExportConfigurationModel.get(localizations)).addOrUpdate(ExportColumn(
                                 internalName: _internalName!,
                                 columnTitle: _displayName!,
                                 formatPattern: _formatPattern!
lib/screens/subsettings/export_import_screen.dart
@@ -5,7 +5,12 @@ 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';
+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:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
 import 'package:jsaver/jSaver.dart';
@@ -22,7 +27,7 @@ class ExportImportScreen extends StatelessWidget {
         title: Text(localizations.exportImport),
         backgroundColor: Theme.of(context).primaryColor,
       ),
-      body: Consumer<Settings>(builder: (context, settings, child) {
+      body: Consumer<ExportSettings>(builder: (context, settings, child) {
         return SingleChildScrollView(
           child: Column(
             children: [
@@ -34,7 +39,7 @@ class ExportImportScreen extends StatelessWidget {
                 opacity: (settings.exportFormat == ExportFormat.db) ? 0.7 : 1,
                 child: IgnorePointer(
                     ignoring: (settings.exportFormat == ExportFormat.db),
-                    child: const IntervalPicker()),
+                    child: const IntervalPicker(type: IntervallStoreManagerLocation.exportPage,)),
               ),
               SettingsTile(
                   title: Text(localizations.exportDir),
@@ -69,106 +74,120 @@ class ExportImportScreen extends StatelessWidget {
                   }
                 },
               ),
-              InputSettingsTile(
-                title: Text(localizations.fieldDelimiter),
-                inputWidth: 40,
-                initialValue: settings.csvFieldDelimiter,
-                disabled: !(settings.exportFormat == ExportFormat.csv),
-                onEditingComplete: (value) {
-                  if (value != null) {
-                    settings.csvFieldDelimiter = value;
-                  }
-                },
-              ),
-              InputSettingsTile(
-                title: Text(localizations.textDelimiter),
-                inputWidth: 40,
-                initialValue: settings.csvTextDelimiter,
-                disabled: !(settings.exportFormat == ExportFormat.csv),
-                onEditingComplete: (value) {
-                  if (value != null) {
-                    settings.csvTextDelimiter = value;
-                  }
-                },
-              ),
-              SwitchSettingsTile(
-                  title: Text(localizations.exportCsvHeadline),
-                  description: Text(localizations.exportCsvHeadlineDesc),
-                  initialValue: settings.exportCsvHeadline,
-                  disabled: settings.exportFormat != ExportFormat.csv,
-                  onToggle: (value) {
-                    settings.exportCsvHeadline = value;
-                  }),
-              SwitchSettingsTile(
-                  title: Text(localizations.exportPdfExportTitle),
-                  initialValue: settings.exportPdfExportTitle,
-                  disabled: settings.exportFormat != ExportFormat.pdf,
-                  onToggle: (value) {
-                    settings.exportPdfExportTitle = value;
-                  }),
-              SwitchSettingsTile(
-                  title: Text(localizations.exportPdfExportStatistics),
-                  initialValue: settings.exportPdfExportStatistics,
-                  disabled: settings.exportFormat != ExportFormat.pdf,
-                  onToggle: (value) {
-                    settings.exportPdfExportStatistics = value;
-                  }),
-              SwitchSettingsTile(
-                  title: Text(localizations.exportPdfExportData),
-                  initialValue: settings.exportPdfExportData,
-                  disabled: settings.exportFormat != ExportFormat.pdf,
-                  onToggle: (value) {
-                    settings.exportPdfExportData = value;
-                  }),
-              InputSettingsTile(
-                initialValue: settings.exportPdfHeaderHeight.toString(),
-                title: Text(localizations.exportPdfHeaderHeight),
-                onEditingComplete: (value) {
-                  final pV = double.tryParse(value ?? '');
-                  if (pV != null) settings.exportPdfHeaderHeight = pV;
-                },
-                disabled: !(settings.exportFormat == ExportFormat.pdf &&
-                    settings.exportPdfExportData),
-                keyboardType: TextInputType.number,
-                inputWidth: 40,
-              ),
-              InputSettingsTile(
-                initialValue: settings.exportPdfCellHeight.toString(),
-                title: Text(localizations.exportPdfCellHeight),
-                onEditingComplete: (value) {
-                  final pV = double.tryParse(value ?? '');
-                  if (pV != null) settings.exportPdfCellHeight = pV;
-                },
-                disabled: !(settings.exportFormat == ExportFormat.pdf &&
-                    settings.exportPdfExportData),
-                keyboardType: TextInputType.number,
-                inputWidth: 40,
-              ),
-              InputSettingsTile(
-                initialValue: settings.exportPdfHeaderFontSize.toString(),
-                title: Text(localizations.exportPdfHeaderFontSize),
-                onEditingComplete: (value) {
-                  final pV = double.tryParse(value ?? '');
-                  if (pV != null) settings.exportPdfHeaderFontSize = pV;
-                },
-                disabled: !(settings.exportFormat == ExportFormat.pdf &&
-                    settings.exportPdfExportData),
-                keyboardType: TextInputType.number,
-                inputWidth: 40,
-              ),
-              InputSettingsTile(
-                initialValue: settings.exportPdfCellFontSize.toString(),
-                title: Text(localizations.exportPdfCellFontSize),
-                onEditingComplete: (value) {
-                  final pV = double.tryParse(value ?? '');
-                  if (pV != null) settings.exportPdfCellFontSize = pV;
-                },
-                disabled: !(settings.exportFormat == ExportFormat.pdf &&
-                    settings.exportPdfExportData),
-                keyboardType: TextInputType.number,
-                inputWidth: 40,
-              ),
-              const ExportFieldCustomisationSetting(),
+              if (settings.exportFormat == ExportFormat.csv)
+                Consumer<CsvExportSettings>(builder: (context, csvExportSettings, child) =>
+                  Column(
+                    children: [
+                      InputSettingsTile(
+                        title: Text(localizations.fieldDelimiter),
+                        inputWidth: 40,
+                        initialValue: csvExportSettings.fieldDelimiter,
+                        disabled: !(settings.exportFormat == ExportFormat.csv),
+                        onEditingComplete: (value) {
+                          if (value != null) {
+                            csvExportSettings.fieldDelimiter = value;
+                          }
+                        },
+                      ),
+                      InputSettingsTile(
+                        title: Text(localizations.textDelimiter),
+                        inputWidth: 40,
+                        initialValue: csvExportSettings.textDelimiter,
+                        disabled: !(settings.exportFormat == ExportFormat.csv),
+                        onEditingComplete: (value) {
+                          if (value != null) {
+                            csvExportSettings.textDelimiter = value;
+                          }
+                        },
+                      ),
+                      SwitchSettingsTile(
+                        title: Text(localizations.exportCsvHeadline),
+                        description: Text(localizations.exportCsvHeadlineDesc),
+                        initialValue: csvExportSettings.exportHeadline,
+                        disabled: settings.exportFormat != ExportFormat.csv,
+                        onToggle: (value) {
+                          csvExportSettings.exportHeadline = value;
+                        }
+                      ),
+                      ExportFieldCustomisationSetting(
+                        fieldsSettings: csvExportSettings,
+                      ),
+                    ],
+                  )
+                ),
+              if (settings.exportFormat == ExportFormat.pdf)
+                Consumer<PdfExportSettings>(builder: (context, pdfExportSettings, child) =>
+                  Column(
+                    children: [
+                      SwitchSettingsTile(
+                          title: Text(localizations.exportPdfExportTitle),
+                          initialValue: pdfExportSettings.exportTitle,
+                          onToggle: (value) {
+                            pdfExportSettings.exportTitle = value;
+                          }),
+                      SwitchSettingsTile(
+                          title: Text(localizations.exportPdfExportStatistics),
+                          initialValue: pdfExportSettings.exportStatistics,
+                          onToggle: (value) {
+                            pdfExportSettings.exportStatistics = value;
+                          }),
+                      SwitchSettingsTile(
+                          title: Text(localizations.exportPdfExportData),
+                          initialValue: pdfExportSettings.exportData,
+                          onToggle: (value) {
+                            pdfExportSettings.exportData = value;
+                          }),
+                      InputSettingsTile(
+                        initialValue: pdfExportSettings.headerHeight.toString(),
+                        title: Text(localizations.exportPdfHeaderHeight),
+                        onEditingComplete: (value) {
+                          final pV = double.tryParse(value ?? '');
+                          if (pV != null) pdfExportSettings.headerHeight = pV;
+                        },
+                        disabled: !(pdfExportSettings.exportData),
+                        keyboardType: TextInputType.number,
+                        inputWidth: 40,
+                      ),
+                      InputSettingsTile(
+                        initialValue: pdfExportSettings.cellHeight.toString(),
+                        title: Text(localizations.exportPdfCellHeight),
+                        onEditingComplete: (value) {
+                          final pV = double.tryParse(value ?? '');
+                          if (pV != null) pdfExportSettings.cellHeight = pV;
+                        },
+                        disabled: !pdfExportSettings.exportData,
+                        keyboardType: TextInputType.number,
+                        inputWidth: 40,
+                      ),
+                      InputSettingsTile(
+                        initialValue: pdfExportSettings.headerFontSize.toString(),
+                        title: Text(localizations.exportPdfHeaderFontSize),
+                        onEditingComplete: (value) {
+                          final pV = double.tryParse(value ?? '');
+                          if (pV != null) pdfExportSettings.headerFontSize = pV;
+                        },
+                        disabled: !pdfExportSettings.exportData,
+                        keyboardType: TextInputType.number,
+                        inputWidth: 40,
+                      ),
+                      InputSettingsTile(
+                        initialValue: pdfExportSettings.cellFontSize.toString(),
+                        title: Text(localizations.exportPdfCellFontSize),
+                        onEditingComplete: (value) {
+                          final pV = double.tryParse(value ?? '');
+                          if (pV != null) pdfExportSettings.cellFontSize = pV;
+                        },
+                        disabled: !pdfExportSettings.exportData,
+                        keyboardType: TextInputType.number,
+                        inputWidth: 40,
+                      ),
+                      if (pdfExportSettings.exportData)
+                        ExportFieldCustomisationSetting(
+                          fieldsSettings: pdfExportSettings,
+                        ),
+                    ]
+                  )
+                ),
             ],
           ),
         );
@@ -179,70 +198,48 @@ class ExportImportScreen extends StatelessWidget {
 }
 
 class ExportFieldCustomisationSetting extends StatelessWidget {
-  const ExportFieldCustomisationSetting({super.key});
+  const ExportFieldCustomisationSetting({super.key, required this.fieldsSettings});
+
+  final CustomFieldsSettings fieldsSettings;
 
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
     return ConsistentFutureBuilder(
-        future: ExportConfigurationModel.get(Provider.of<Settings>(context, listen: false), localizations),
-        onData: (context, configurationModel) {
-          return Consumer<Settings>(builder: (context, settings, child) {
-            /// whether or not the currently selected export format supports field customization
-            final isApplicable = (settings.exportFormat == ExportFormat.csv ||
-                settings.exportFormat == ExportFormat.pdf &&
-                    settings.exportPdfExportData);
-            final exportCustomEntries =
-                (settings.exportFormat == ExportFormat.csv)
-                    ? settings.exportCustomEntriesCsv
-                    : settings.exportCustomEntriesPdf;
-            final exportItems = (settings.exportFormat == ExportFormat.csv)
-                ? settings.exportItemsCsv
-                : settings.exportItemsPdf;
+      future: ExportConfigurationModel.get(localizations),
+      onData: (context, configurationModel) {
+        return Consumer<ExportSettings>(builder: (context, settings, child) {
+          final formats = configurationModel.availableFormats.toSet();
+          List<ExportColumn> activeFields = configurationModel
+              .getActiveExportColumns(settings.exportFormat, fieldsSettings);
+          List<ExportColumn> hiddenFields = [];
+          for (final internalName in fieldsSettings.customFields) {
+            formats.removeWhere((e) => e.internalName == internalName);
+          }
+          hiddenFields = formats.toList();
 
-            final formats = configurationModel.availableFormats.toSet();
-            List<ExportColumn> activeFields = configurationModel
-                .getActiveExportColumns(settings.exportFormat);
-            List<ExportColumn> hiddenFields = [];
-            for (final internalName in exportItems) {
-              formats.removeWhere((e) => e.internalName == internalName);
-            }
-            hiddenFields = formats.toList();
-
-            return Column(
-              children: [
-                SwitchSettingsTile(
-                    title: Text(localizations.exportCustomEntries),
-                    initialValue: exportCustomEntries,
-                    disabled: !isApplicable,
-                    onToggle: (value) {
-                      if (settings.exportFormat == ExportFormat.csv) {
-                        settings.exportCustomEntriesCsv = value;
-                      } else {
-                        assert(settings.exportFormat == ExportFormat.pdf);
-                        settings.exportCustomEntriesPdf = value;
-                      }
-                    }),
-                (exportCustomEntries && isApplicable)
-                    ? ExportItemsCustomizer(
-                        shownItems: activeFields,
-                        disabledItems: hiddenFields,
-                        onReorder: (exportItems, exportAddableItems) {
-                          if (settings.exportFormat == ExportFormat.csv) {
-                            settings.exportItemsCsv =
-                                exportItems.map((e) => e.internalName).toList();
-                          } else {
-                            assert(settings.exportFormat == ExportFormat.pdf);
-                            settings.exportItemsPdf =
-                                exportItems.map((e) => e.internalName).toList();
-                          }
-                        },
-                      )
-                    : const SizedBox.shrink()
-              ],
-            );
-          });
+          return Column(
+            children: [
+              SwitchSettingsTile(
+                title: Text(localizations.exportCustomEntries),
+                initialValue: fieldsSettings.exportCustomFields,
+                onToggle: (value) {
+                  fieldsSettings.exportCustomFields = value;
+                }
+              ),
+              if (fieldsSettings.exportCustomFields)
+                ExportItemsCustomizer(
+                  shownItems: activeFields,
+                  disabledItems: hiddenFields,
+                  onReorder: (exportItems, exportAddableItems) {
+                    fieldsSettings.customFields = exportItems.map((e) => e.internalName).toList();
+                  },
+                ),
+            ],
+          );
         });
+      }
+    );
   }
 }
 
@@ -251,11 +248,7 @@ class ExportImportButtons extends StatelessWidget {
 
   @override
   Widget build(BuildContext context) {
-    final settings = Provider.of<Settings>(context, listen: false);
-    final model = Provider.of<BloodPressureModel>(context, listen: false);
-    final messenger = ScaffoldMessenger.of(context);
     final localizations = AppLocalizations.of(context)!;
-    final theme = Theme.of(context);
 
     return Container(
       height: 60,
@@ -268,15 +261,15 @@ class ExportImportButtons extends StatelessWidget {
                 child: MaterialButton(
                   height: 60,
                   child: Text(localizations.export),
-                  onPressed: () async => Exporter(
-                          settings,
-                          model,
-                          messenger,
-                          localizations,
-                          theme,
-                          await ExportConfigurationModel.get(
-                              settings, localizations))
-                      .export(),
+                  onPressed: () async {
+                    final model = Provider.of<BloodPressureModel>(context, listen: false);
+                    final interval = Provider.of<IntervallStoreManager>(context, listen: false).exportPage.currentRange;
+
+                    Exporter.load(context,
+                        await model.getInTimeRange(interval.start, interval.end),
+                        await ExportConfigurationModel.get(localizations)
+                    ).export();
+                  }
                 )),
             const VerticalDivider(),
             Expanded(
@@ -284,14 +277,8 @@ class ExportImportButtons extends StatelessWidget {
                 child: MaterialButton(
                   height: 60,
                   child: Text(localizations.import),
-                  onPressed: () async => Exporter(
-                          settings,
-                          model,
-                          messenger,
-                          localizations,
-                          theme,
-                          await ExportConfigurationModel.get(settings, localizations))
-                      .import(),
+                  onPressed: () async => 
+                      Exporter.load(context, [], await ExportConfigurationModel.get(localizations)).import(),
                 )),
           ],
         ),
@@ -313,57 +300,63 @@ class _ExportWarnBannerState extends State<ExportWarnBanner> {
   @override
   Widget build(BuildContext context) {
     final localizations = AppLocalizations.of(context)!;
-    return Consumer<Settings>(builder: (context, settings, child) {
-      return ConsistentFutureBuilder(
-          future: ExportConfigurationModel.get(Provider.of<Settings>(context, listen: false), localizations),
-          onData: (context, configurationModel) {
-            String? message;
-            final exportCustomEntries =
-                (settings.exportFormat == ExportFormat.csv)
-                    ? settings.exportCustomEntriesCsv
-                    : settings.exportCustomEntriesPdf;
-            final exportFormats = configurationModel
-                .getActiveExportColumns(settings.exportFormat)
-                .map((e) => e.parsableFormat);
-            var missingAttributes = {
-              RowDataFieldType.timestamp,
-              RowDataFieldType.sys,
-              RowDataFieldType.dia,
-              RowDataFieldType.pul,
-              RowDataFieldType.notes,
-              RowDataFieldType.color
-            };
-            missingAttributes.removeWhere((e) => exportFormats.contains(e));
-            if (ExportFormat.db == settings.exportFormat) {
-              // When exporting as database no wrong configuration is possible
-            } else if (_showWarnBanner && ((ExportFormat.pdf == settings.exportFormat) ||
-                settings.exportCsvHeadline == false ||
-                exportCustomEntries &&
-                    missingAttributes.contains(RowDataFieldType.timestamp) ||
-                ![',', '|'].contains(settings.csvFieldDelimiter) ||
-                !['"', '\''].contains(settings.csvTextDelimiter))) {
-              message = localizations.exportWarnConfigNotImportable;
-            } else if (_showWarnBanner && exportCustomEntries && missingAttributes.isNotEmpty) {
-              message = localizations.exportWarnNotEveryFieldExported(
-                  missingAttributes.length, missingAttributes.join(', '));
-            }
+    return Consumer<Settings>(builder: (context, settings, child) =>
+      Consumer<ExportSettings>(builder: (context, exportSettings, child) =>
+        Consumer<CsvExportSettings>(builder: (context, csvExportSettings, child) =>
+          Consumer<PdfExportSettings>(builder: (context, pdfExportSettings, child) {
+            return ConsistentFutureBuilder(
+              future: ExportConfigurationModel.get(localizations),
+              onData: (context, configurationModel) {
+                String? message;
+                final exportCustomEntries = (exportSettings.exportFormat == ExportFormat.csv)
+                    ? csvExportSettings.exportCustomFields : pdfExportSettings.exportCustomFields;
+                final CustomFieldsSettings fieldSettings = (exportSettings.exportFormat == ExportFormat.csv
+                    ? csvExportSettings : pdfExportSettings) as CustomFieldsSettings;
+                final exportFormats = configurationModel
+                    .getActiveExportColumns(exportSettings.exportFormat, fieldSettings)
+                    .map((e) => e.parsableFormat);
+                var missingAttributes = {
+                  RowDataFieldType.timestamp,
+                  RowDataFieldType.sys,
+                  RowDataFieldType.dia,
+                  RowDataFieldType.pul,
+                  RowDataFieldType.notes,
+                  RowDataFieldType.color
+                };
+                missingAttributes.removeWhere((e) => exportFormats.contains(e));
+                if (ExportFormat.db == exportSettings.exportFormat) {
+                  // When exporting as database no wrong configuration is possible
+                } else if (_showWarnBanner && ((ExportFormat.pdf == exportSettings.exportFormat) ||
+                    csvExportSettings.exportHeadline == false ||
+                    exportCustomEntries &&
+                        missingAttributes.contains(RowDataFieldType.timestamp) ||
+                    ![',', '|'].contains(csvExportSettings.fieldDelimiter) ||
+                    !['"', '\''].contains(csvExportSettings.textDelimiter))) {
+                  message = localizations.exportWarnConfigNotImportable;
+                } else if (_showWarnBanner && exportCustomEntries && missingAttributes.isNotEmpty) {
+                  message = localizations.exportWarnNotEveryFieldExported(
+                      missingAttributes.length, missingAttributes.join(', '));
+                }
 
-            if (message != null) {
-              return MaterialBanner(
-                  padding: const EdgeInsets.all(20),
-                  content: Text(message),
-                  actions: [
-                    TextButton(
-                        onPressed: () {
-                          setState(() {
-                            _showWarnBanner = false;
-                          });
-                        },
-                        child: Text(localizations.btnConfirm))
-                  ]);
-            }
-            return const SizedBox.shrink();
-          });
-    });
+                if (message != null) {
+                  return MaterialBanner(
+                      padding: const EdgeInsets.all(20),
+                      content: Text(message),
+                      actions: [
+                        TextButton(
+                            onPressed: () {
+                              setState(() {
+                                _showWarnBanner = false;
+                              });
+                            },
+                            child: Text(localizations.btnConfirm))
+                      ]);
+                }
+                return const SizedBox.shrink();
+              });
+          })
+        )
+      )
+    );
   }
 }
lib/screens/subsettings/graph_markings.dart
@@ -1,6 +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';
 import 'package:flutter_material_color_picker/flutter_material_color_picker.dart';
lib/screens/add_measurement.dart
@@ -2,7 +2,8 @@ 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';
 import 'package:flutter/services.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -10,6 +11,8 @@ import 'package:flutter_material_color_picker/flutter_material_color_picker.dart
 import 'package:intl/intl.dart';
 import 'package:provider/provider.dart';
 
+import '../model/storage/intervall_store.dart';
+
 class AddMeasurementPage extends StatefulWidget {
   final DateTime? initTime;
   final int? initSys;
@@ -162,7 +165,8 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                               if ((_formKey.currentState?.validate() ?? false) ||
                                   (_systolic == null && _diastolic == null && _pulse == null &&
                                       (_note != null || _needlePin != null))){
-                                final settings = Provider.of<Settings>(context, listen: false);
+                                final settings = Provider.of<ExportSettings>(context, listen: false);
+                                final intervalls = Provider.of<IntervallStoreManager>(context, listen: false);
                                 final model = Provider.of<BloodPressureModel>(context, listen: false);
                                 final navigator = Navigator.of(context);
 
@@ -172,14 +176,12 @@ class _AddMeasurementPageState extends State<AddMeasurementPage> {
                                 await model.add(BloodPressureRecord(_time, _systolic, _diastolic, _pulse, _note ?? '',
                                 needlePin: _needlePin));
                                 if (settings.exportAfterEveryEntry && context.mounted) {
-                                  final exporter = Exporter(settings, model, ScaffoldMessenger.of(context),
-                                      localizations, Theme.of(context),
-                                      await ExportConfigurationModel.get(Provider.of<Settings>(context, listen: false), localizations));
+                                  final exporter = Exporter.load(context, await model.all, await ExportConfigurationModel.get(localizations));
                                   exporter.export();
                                 }
                                 // ensures the most recent entry is visible when submitting a new measurement
-                                if (settings.graphStepSize != TimeStep.custom) {
-                                  settings.setToMostRecentIntervall();
+                                if (intervalls.mainPage.stepSize != TimeStep.custom) {
+                                  intervalls.mainPage.setToMostRecentIntervall();
                                 }
                                 navigator.pop();
                               }
lib/screens/home.dart
@@ -1,6 +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';
 import 'package:blood_pressure_app/screens/statistics.dart';
lib/screens/settings.dart
@@ -4,6 +4,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/iso_lang_names.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/enter_timeformat.dart';
 import 'package:blood_pressure_app/screens/subsettings/export_import_screen.dart';
 import 'package:blood_pressure_app/screens/subsettings/graph_markings.dart';
lib/screens/statistics.dart
@@ -1,10 +1,8 @@
-import 'dart:collection';
-
-import 'package:blood_pressure_app/components/consistent_future_builder.dart';
+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';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -20,133 +18,131 @@ class StatisticsPage extends StatelessWidget {
         title: Text(AppLocalizations.of(context)!.statistics),
         backgroundColor: Theme.of(context).primaryColor,
       ),
-      body: SingleChildScrollView(child: Consumer<BloodPressureModel>(
-        builder: (context, model, child) {
-          return Consumer<Settings>(builder: (context, settings, child) {
-            return ConsistentFutureBuilder<UnmodifiableListView<BloodPressureRecord>>(
-                future: model.getInTimeRange(settings.displayDataStart, settings.displayDataEnd),
-                onData: (context, data) {
-                  final analyzer = BloodPressureAnalyser(data.toList());
-                  return Column(
-                    children: [
-                      Statistic(
-                          key: const Key('measurementCount'),
-                          caption: Text(AppLocalizations.of(context)!.measurementCount), child: displayInt(analyzer.count)),
-                      // special measurements
-                      StatisticsRow(
-                        caption1: Text(
-                          AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.sysLong),
-                          style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
-                        ),
-                        child1: displayInt(analyzer.avgSys),
-                        caption2: Text(
-                          AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.diaLong),
-                          style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
-                        ),
-                        child2: displayInt(analyzer.avgDia),
-                        caption3: Text(
-                          AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.pulLong),
-                          style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
-                        ),
-                        child3: displayInt(analyzer.avgPul),
-                      ),
-                      Statistic(
-                        caption: Text(AppLocalizations.of(context)!.measurementsPerDay),
-                        child: displayInt(analyzer.measurementsPerDay)),
-                      StatisticsRow(
-                        caption1: Text(
-                          AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.sysLong),
-                          style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
-                        ),
-                        child1: displayInt(analyzer.minSys),
-                        caption2: Text(
-                          AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.diaLong),
-                          style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
-                        ),
-                        child2: displayInt(analyzer.minDia),
-                        caption3: Text(
-                          AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.pulLong),
-                          style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
-                        ),
-                        child3: displayInt(analyzer.minPul),
-                      ),
-                      StatisticsRow(
-                        caption2: Text(
-                          AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.diaLong),
-                          style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
-                        ),
-                        child2: displayInt(analyzer.maxDia),
-                        caption1: Text(
-                          AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.sysLong),
-                          style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
-                        ),
-                        child1: displayInt(analyzer.maxSys),
-                        caption3: Text(
-                          AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.pulLong),
-                          style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+      body: SingleChildScrollView(
+        child: Consumer<Settings>(builder: (context, settings, child) {
+          return BloodPressureBuilder(
+            rangeType: IntervallStoreManagerLocation.statsPage,
+            onData: (context, data) {
+              final analyzer = BloodPressureAnalyser(data.toList());
+              return Column(
+                children: [
+                  Statistic(
+                      key: const Key('measurementCount'),
+                      caption: Text(AppLocalizations.of(context)!.measurementCount), child: displayInt(analyzer.count)),
+                  // special measurements
+                  StatisticsRow(
+                    caption1: Text(
+                      AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.sysLong),
+                      style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
+                    ),
+                    child1: displayInt(analyzer.avgSys),
+                    caption2: Text(
+                      AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.diaLong),
+                      style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
+                    ),
+                    child2: displayInt(analyzer.avgDia),
+                    caption3: Text(
+                      AppLocalizations.of(context)!.avgOf(AppLocalizations.of(context)!.pulLong),
+                      style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+                    ),
+                    child3: displayInt(analyzer.avgPul),
+                  ),
+                  Statistic(
+                      caption: Text(AppLocalizations.of(context)!.measurementsPerDay),
+                      child: displayInt(analyzer.measurementsPerDay)),
+                  StatisticsRow(
+                    caption1: Text(
+                      AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.sysLong),
+                      style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
+                    ),
+                    child1: displayInt(analyzer.minSys),
+                    caption2: Text(
+                      AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.diaLong),
+                      style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
+                    ),
+                    child2: displayInt(analyzer.minDia),
+                    caption3: Text(
+                      AppLocalizations.of(context)!.minOf(AppLocalizations.of(context)!.pulLong),
+                      style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+                    ),
+                    child3: displayInt(analyzer.minPul),
+                  ),
+                  StatisticsRow(
+                    caption2: Text(
+                      AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.diaLong),
+                      style: TextStyle(color: settings.diaColor, fontWeight: FontWeight.w700),
+                    ),
+                    child2: displayInt(analyzer.maxDia),
+                    caption1: Text(
+                      AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.sysLong),
+                      style: TextStyle(color: settings.sysColor, fontWeight: FontWeight.w700),
+                    ),
+                    child1: displayInt(analyzer.maxSys),
+                    caption3: Text(
+                      AppLocalizations.of(context)!.maxOf(AppLocalizations.of(context)!.pulLong),
+                      style: TextStyle(color: settings.pulColor, fontWeight: FontWeight.w700),
+                    ),
+                    child3: displayInt(analyzer.maxPul),
+                  ),
+                  // Time-Resolved Metrics
+                  Statistic(
+                    caption: Text(AppLocalizations.of(context)!.timeResolvedMetrics),
+                    child: (() {
+                      final data = analyzer.allAvgsRelativeToDaytime;
+                      const opacity = 0.5;
+                      return SizedBox(
+                        width: 500,
+                        height: 500,
+                        child: RadarChart(
+                          RadarChartData(
+                            radarShape: RadarShape.circle,
+                            radarBorderData: const BorderSide(color: Colors.transparent),
+                            gridBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
+                            tickBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
+                            ticksTextStyle: const TextStyle(color: Colors.transparent),
+                            tickCount: 5,
+                            titleTextStyle: const TextStyle(fontSize: 25),
+                            getTitle: (pos, value) {
+                              if (pos % 2 == 0) {
+                                return RadarChartTitle(text: '$pos', positionPercentageOffset: 0.05);
+                              }
+                              return const RadarChartTitle(text: '');
+                            },
+                            dataSets: [
+                              RadarDataSet(
+                                  dataEntries: intListToRadarEntry(data[0]),
+                                  borderColor: settings.diaColor,
+                                  fillColor: settings.diaColor.withOpacity(opacity),
+                                  entryRadius: 0,
+                                  borderWidth: settings.graphLineThickness),
+                              RadarDataSet(
+                                  dataEntries: intListToRadarEntry(data[1]),
+                                  borderColor: settings.sysColor,
+                                  fillColor: settings.sysColor.withOpacity(opacity),
+                                  entryRadius: 0,
+                                  borderWidth: settings.graphLineThickness),
+                              RadarDataSet(
+                                  dataEntries: intListToRadarEntry(data[2]),
+                                  borderColor: settings.pulColor,
+                                  fillColor: settings.pulColor.withOpacity(opacity),
+                                  entryRadius: 0,
+                                  borderWidth: settings.graphLineThickness),
+                            ],
+                          ),
                         ),
-                        child3: displayInt(analyzer.maxPul),
-                      ),
-                      // Time-Resolved Metrics
-                      Statistic(
-                        caption: Text(AppLocalizations.of(context)!.timeResolvedMetrics),
-                        child: (() {
-                          final data = analyzer.allAvgsRelativeToDaytime;
-                          const opacity = 0.5;
-                          return SizedBox(
-                            width: 500,
-                            height: 500,
-                            child: RadarChart(
-                              RadarChartData(
-                                radarShape: RadarShape.circle,
-                                radarBorderData: const BorderSide(color: Colors.transparent),
-                                gridBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
-                                tickBorderData: BorderSide(color: Theme.of(context).dividerColor, width: 2),
-                                ticksTextStyle: const TextStyle(color: Colors.transparent),
-                                tickCount: 5,
-                                titleTextStyle: const TextStyle(fontSize: 25),
-                                getTitle: (pos, value) {
-                                  if (pos % 2 == 0) {
-                                    return RadarChartTitle(text: '$pos', positionPercentageOffset: 0.05);
-                                  }
-                                  return const RadarChartTitle(text: '');
-                                },
-                                dataSets: [
-                                  RadarDataSet(
-                                      dataEntries: intListToRadarEntry(data[0]),
-                                      borderColor: settings.diaColor,
-                                      fillColor: settings.diaColor.withOpacity(opacity),
-                                      entryRadius: 0,
-                                      borderWidth: settings.graphLineThickness),
-                                  RadarDataSet(
-                                      dataEntries: intListToRadarEntry(data[1]),
-                                      borderColor: settings.sysColor,
-                                      fillColor: settings.sysColor.withOpacity(opacity),
-                                      entryRadius: 0,
-                                      borderWidth: settings.graphLineThickness),
-                                  RadarDataSet(
-                                      dataEntries: intListToRadarEntry(data[2]),
-                                      borderColor: settings.pulColor,
-                                      fillColor: settings.pulColor.withOpacity(opacity),
-                                      entryRadius: 0,
-                                      borderWidth: settings.graphLineThickness),
-                                ],
-                              ),
-                            ),
-                          );
-                        })(),
-                      ),
-                    ],
-                  );
-                }
-            );
-          });
-        },
+                      );
+                    })(),
+                  ),
+                ],
+              );
+            }
+          );
+        }
       )),
       bottomNavigationBar: Container(
         height: 70,
         margin: const EdgeInsets.only(top: 15, bottom: 5),
-        child: const IntervalPicker(),
+        child: const IntervalPicker(type: IntervallStoreManagerLocation.statsPage,),
       )
     );
   }
lib/main.dart
@@ -1,7 +1,8 @@
 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';
+import 'package:blood_pressure_app/model/storage/settings_store.dart';
 import 'package:blood_pressure_app/screens/home.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -17,17 +18,31 @@ void main() async {
   WidgetsFlutterBinding.ensureInitialized();
   // 2 different db files
   final dataModel = await BloodPressureModel.create();
-  final settingsModel = await Settings.create();
 
   // TODO:
-  globalConfigDao = ConfigDao(await ConfigDB.open());
+  final configDB = await ConfigDB.open();
+  final configDao = ConfigDao(configDB);
+
+  final settings = await configDao.loadSettings(0);
+  final exportSettings = await configDao.loadExportSettings(0);
+  final csvExportSettings = await configDao.loadCsvExportSettings(0);
+  final pdfExportSettings = await configDao.loadPdfExportSettings(0);
+  final intervalStorageManager = await IntervallStoreManager.load(configDao, 0);
+
+  // TODO: old settings migration
+
+  globalConfigDao = configDao;
 
   // Reset the step size intervall to current on startup
-  settingsModel.changeStepSize(settingsModel.graphStepSize);
+  intervalStorageManager.mainPage.setToMostRecentIntervall();
 
   runApp(MultiProvider(providers: [
     ChangeNotifierProvider(create: (context) => dataModel),
-    ChangeNotifierProvider(create: (context) => settingsModel),
+    ChangeNotifierProvider(create: (context) => settings),
+    ChangeNotifierProvider(create: (context) => exportSettings),
+    ChangeNotifierProvider(create: (context) => csvExportSettings),
+    ChangeNotifierProvider(create: (context) => pdfExportSettings),
+    ChangeNotifierProvider(create: (context) => intervalStorageManager),
   ], child: const AppRoot()));
 }
 
test/model/json_serialization_test.dart
@@ -1,4 +1,5 @@
 
+import 'package:blood_pressure_app/model/horizontal_graph_line.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';
@@ -87,6 +88,7 @@ void main() {
         drawRegressionLines: false,
         startWithAddMeasurementPage: false,
         useLegacyList: false,
+        horizontalGraphLines: [HorizontalGraphLine(Colors.blue, 1230)],
       );
       final fromJson = Settings.fromJson(initial.toJson());
 
@@ -109,6 +111,9 @@ void main() {
       expect(initial.drawRegressionLines, fromJson.drawRegressionLines);
       expect(initial.startWithAddMeasurementPage, fromJson.startWithAddMeasurementPage);
       expect(initial.useLegacyList, fromJson.useLegacyList);
+      expect(initial.horizontalGraphLines.length, fromJson.horizontalGraphLines.length);
+      expect(initial.horizontalGraphLines.first.color.value, fromJson.horizontalGraphLines.first.color.value);
+      expect(initial.horizontalGraphLines.first.height, fromJson.horizontalGraphLines.first.height);
 
       expect(initial.toJson(), fromJson.toJson());
     });
test/ui/add_measurement.dart → test/ui/add_measurement_test.dart
@@ -1,6 +1,10 @@
 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';
+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';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -126,13 +130,30 @@ void main() {
   });
 }
 
-Future<void> _initPage(WidgetTester widgetTester, Widget pageWidget, {Settings? settings, BloodPressureModel? model}) async {
+Future<void> _initPage(WidgetTester widgetTester, Widget pageWidget, {
+  Settings? settings,
+  ExportSettings? exportSettings,
+  CsvExportSettings? csvExportSettings,
+  PdfExportSettings? pdfExportSettings,
+  IntervallStoreManager? intervallStoreManager,
+  BloodPressureModel? model,
+}) async {
+  model ??= RamBloodPressureModel();
+  settings ??= Settings();
+  exportSettings ??= ExportSettings();
+  csvExportSettings ??= CsvExportSettings();
+  pdfExportSettings ??= PdfExportSettings();
+  intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
   await widgetTester.pumpWidget(
     MaterialApp(
       home: MultiProvider(
           providers: [
-            ChangeNotifierProvider<Settings>(create: (_) => settings ?? RamSettings()),
-            ChangeNotifierProvider<BloodPressureModel>(create: (_) => model ?? RamBloodPressureModel()),
+            ChangeNotifierProvider(create: (_) => settings),
+            ChangeNotifierProvider(create: (_) => exportSettings),
+            ChangeNotifierProvider(create: (_) => csvExportSettings),
+            ChangeNotifierProvider(create: (_) => pdfExportSettings),
+            ChangeNotifierProvider(create: (_) => intervallStoreManager),
+            ChangeNotifierProvider<BloodPressureModel>(create: (_) => model!),
           ],
           child: Localizations(
             delegates: AppLocalizations.localizationsDelegates,
test/ui/navigation_test.dart
@@ -1,7 +1,11 @@
 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';
+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';
 import 'package:blood_pressure_app/screens/settings.dart';
 import 'package:blood_pressure_app/screens/statistics.dart';
@@ -80,12 +84,26 @@ void main() {
   });
 }
 
-Future<void> _pumpAppRoot(WidgetTester widgetTester) async {
+Future<void> _pumpAppRoot(WidgetTester widgetTester, {
+  Settings? settings,
+  ExportSettings? exportSettings,
+  CsvExportSettings? csvExportSettings,
+  PdfExportSettings? pdfExportSettings,
+  IntervallStoreManager? intervallStoreManager,
+}) async {
   final model = RamBloodPressureModel();
-  final settings = RamSettings();
+  settings ??= Settings();
+  exportSettings ??= ExportSettings();
+  csvExportSettings ??= CsvExportSettings();
+  pdfExportSettings ??= PdfExportSettings();
+  intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
 
   await widgetTester.pumpWidget(MultiProvider(providers: [
-    ChangeNotifierProvider<Settings>(create: (_) => settings),
+    ChangeNotifierProvider(create: (_) => settings),
+    ChangeNotifierProvider(create: (_) => exportSettings),
+    ChangeNotifierProvider(create: (_) => csvExportSettings),
+    ChangeNotifierProvider(create: (_) => pdfExportSettings),
+    ChangeNotifierProvider(create: (_) => intervallStoreManager),
     ChangeNotifierProvider<BloodPressureModel>(create: (_) => model),
   ], child: const AppRoot()));
 }
test/ui/statistics_test.dart
@@ -1,6 +1,10 @@
 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';
+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/statistics.dart';
 import 'package:flutter/material.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -10,23 +14,38 @@ import 'package:provider/provider.dart';
 void main() {
   group("StatisticsPage", () {
     testWidgets('should load page', (widgetTester) async {
-      await _initStatsPage(widgetTester, RamSettings(), []);
+      await _initStatsPage(widgetTester, []);
       expect(find.text('Statistics'), findsOneWidget);
     });
     testWidgets("should report measurement count", (widgetTester) async {
-      await _initStatsPage(widgetTester, _allMeasurements(), [
+      await _initStatsPage(widgetTester, [
         for (int i = 1; i<51; i++) // can't safe entries at or before epoch
           BloodPressureRecord(DateTime.fromMillisecondsSinceEpoch(1582991592 + i), 40+i, 60+i, 30+i, 'Test comment $i'),
-      ]);
+      ],
+        intervallStoreManager: IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage(stepSize: TimeStep.lifetime))
+      );
       final measurementCountWidget = find.byKey(const Key('measurementCount'));
       expect(measurementCountWidget, findsOneWidget);
+      expect(find.descendant(of: measurementCountWidget, matching: find.text('49')), findsNothing);
+      expect(find.descendant(of: measurementCountWidget, matching: find.text('51')), findsNothing);
       expect(find.descendant(of: measurementCountWidget, matching: find.text('50')), findsOneWidget);
     });
   });
 }
 
-Future<void> _initStatsPage(WidgetTester widgetTester, Settings settings, List<BloodPressureRecord> records) async {
+Future<void> _initStatsPage(WidgetTester widgetTester, List<BloodPressureRecord> records, {
+  Settings? settings,
+  ExportSettings? exportSettings,
+  CsvExportSettings? csvExportSettings,
+  PdfExportSettings? pdfExportSettings,
+  IntervallStoreManager? intervallStoreManager,
+}) async {
   final model = RamBloodPressureModel();
+  settings ??= Settings();
+  exportSettings ??= ExportSettings();
+  csvExportSettings ??= CsvExportSettings();
+  pdfExportSettings ??= PdfExportSettings();
+  intervallStoreManager ??= IntervallStoreManager(IntervallStorage(), IntervallStorage(), IntervallStorage());
 
   for (var r in records) {
     model.add(r);
@@ -34,7 +53,11 @@ Future<void> _initStatsPage(WidgetTester widgetTester, Settings settings, List<B
 
   await widgetTester.pumpWidget(MultiProvider(
       providers: [
-        ChangeNotifierProvider<Settings>(create: (_) => settings),
+        ChangeNotifierProvider(create: (_) => settings),
+        ChangeNotifierProvider(create: (_) => exportSettings),
+        ChangeNotifierProvider(create: (_) => csvExportSettings),
+        ChangeNotifierProvider(create: (_) => pdfExportSettings),
+        ChangeNotifierProvider(create: (_) => intervallStoreManager),
         ChangeNotifierProvider<BloodPressureModel>(create: (_) => model),
       ],
       child: Localizations(
@@ -44,10 +67,4 @@ Future<void> _initStatsPage(WidgetTester widgetTester, Settings settings, List<B
       )
   ));
   await widgetTester.pumpAndSettle();
-}
-
-RamSettings _allMeasurements() {
-  final settings = RamSettings();
-  settings.changeStepSize(TimeStep.lifetime);
-  return settings;
 }
\ No newline at end of file