Commit 6c747aa
Changed files (12)
lib
components
model
screens
test
model
export_import
lib/components/export_item_order.dart
@@ -3,7 +3,7 @@ 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/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/export_options.dart';
import 'package:blood_pressure_app/model/storage/storage.dart';
import 'package:blood_pressure_app/screens/subsettings/export_column_data.dart';
lib/model/export_import/column.dart
@@ -1,127 +1,49 @@
import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/export_import/reocord_formatter.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
-abstract interface class ExportColumnI {
+/// Class for storing export behavior of columns.
+class ExportColumn implements Formatter {
+ /// Create a object that handles export behavior for data in a column.
+ ///
+ /// [formatter] will be created according to [formatString].
+ ExportColumn(this.internalIdentifier, this.csvTitle, String formatString) {
+ formatter = ScriptedFormatter(formatString);
+ }
+
/// Unique internal identifier that is used to identify a column in the app.
///
/// A identifier can be any string, but is usually structured with a prefix and
/// a name. For example `buildin.sys`, `user.fancyvalue` or `convert.myheartsys`.
/// These examples are not guaranteed to be the prefixes used in the rest of the
/// app.
- ///
+ ///
/// It should not be used instead of [csvTitle].
- String get internalIdentifier;
+ final String internalIdentifier;
/// Column title in a csv file.
///
/// May not contain characters intended for CSV column separation (e.g. `,`).
- String get csvTitle;
+ final String csvTitle;
/// Column title in user facing places that don't require strict rules.
- ///
- /// It will be displayed on the exported PDF file or in the column selection.
- String userTitle(AppLocalizations localizations);
-
- /// Converter associated with this column.
- Formatter get formatter;
-}
-
-/// Convert [BloodPressureRecord]s from and to strings and provide metadata about the conversion.
-class ExportColumn { // TODO: change this class so it implements the interface.
- /// Create object that turns data into strings.
- ///
- /// Example: ExportColumn(internalColumnName: 'pulsePressure', columnTitle: 'Pulse pressure', formatPattern: '{{$SYS-$DIA}}')
- ExportColumn({required this.internalName, required this.columnTitle, required String formatPattern, this.editable = true, this.hidden = false}) {
- this.formatPattern = formatPattern.replaceAll('{{}}', '');
- _formatter = ScriptedFormatter(formatPattern);
- }
-
- late final Formatter _formatter;
-
- /// pure name as in the title of the csv file and for internal purposes. Should not contain special characters and spaces.
- late final String internalName;
-
- /// Display title of the column. Possibly localized
- late final String columnTitle;
-
- /// Pattern to create the field contents from:
- /// It supports inserting values for $TIMESTAMP, $SYS $DIA $PUL, $COLOR and $NOTE. Where $TIMESTAMP is the time since unix epoch in milliseconds.
- /// To format a timestamp in the same format as the $TIMESTAMP variable, $FORMAT(<timestamp>, <formatString>).
- /// It is supported to use basic mathematics inside of double brackets ("{{}}"). In case one of them is not present in the record, -1 is provided.
- /// The following math is supported:
- /// Operations: [+, -, *, /, %, ^]
- /// One-parameter functions [ abs, acos, asin, atan, ceil, cos, cosh, cot, coth, csc, csch, exp, floor, ln, log, round sec, sech, sin, sinh, sqrt, tan, tanh ]
- /// Two-parameter functions [ log, nrt, pow ]
- /// Constants [ e, pi, ln2, ln10, log2e, log10e, sqrt1_2, sqrt2 ]
- /// The full math interpreter specification can be found here: https://pub.dev/documentation/function_tree/latest#interpreter
///
- /// The String is processed in the following order:
- /// 1. variable replacement
- /// 2. Math
- /// 3. Date format
- late final String formatPattern;
-
- @Deprecated('will be replaced by the data structure the column is stored in')
- final bool editable; // TODO: remove
-
- /// doesn't show up as unused / hidden field in list
- final bool hidden;
-
- factory ExportColumn.fromJson(Map<String, dynamic> json, [editable = true, hidden = false]) =>
- ExportColumn(
- internalName: json['internalColumnName'],
- columnTitle: json['columnTitle'],
- formatPattern: json['formatPattern'],
- editable: editable,
- hidden: hidden
- );
-
- Map<String, dynamic> toJson() => {
- 'internalColumnName': internalName,
- 'columnTitle': columnTitle,
- 'formatPattern': formatPattern
- };
-
- /// Turns a [BloodPressureRecord] into a string as defined in the [formatPattern].
- String formatRecord(BloodPressureRecord record) => _formatter.encode(record);
-
- /// Parses records if [isReversible] is true else returns an empty list
- List<(RowDataFieldType, dynamic)> parseRecord(String formattedRecord) => [
- if (_formatter.decode(formattedRecord) != null)
- _formatter.decode(formattedRecord)!
- ];
+ /// It will be displayed on the exported PDF file or in the column selection.
+ String userTitle(AppLocalizations localizations) => csvTitle;
- /// Checks if the pattern can be used to parse records. This is the case when the pattern contains variables without
- /// containing curly brackets or commas.
- bool get isReversible => _formatter.restoreAbleType != null;
+ /// Converter associated with this column.
+ late final Formatter formatter;
- RowDataFieldType? get parsableFormat => _formatter.restoreAbleType;
+ @override
+ (RowDataFieldType, dynamic)? decode(String pattern) => formatter.decode(pattern);
@override
- String toString() {
- return 'ExportColumn{internalColumnName: $internalName, columnTitle: $columnTitle, formatPattern: $formatPattern}';
- }
-}
+ String encode(BloodPressureRecord record) => formatter.encode(record);
-/// Type a [ExportColumn] can be parsed as.
-enum RowDataFieldType {
- timestamp, sys, dia, pul, notes, color;
+ @override
+ String? get formatPattern => formatter.formatPattern;
- String localize(AppLocalizations localizations) {
- switch(this) {
- case RowDataFieldType.timestamp:
- return localizations.timestamp;
- case RowDataFieldType.sys:
- return localizations.sysLong;
- case RowDataFieldType.dia:
- return localizations.diaLong;
- case pul:
- return localizations.pulLong;
- case RowDataFieldType.notes:
- return localizations.notes;
- case RowDataFieldType.color:
- return localizations.color;
- }
- }
+ @override
+ RowDataFieldType? get restoreAbleType => formatter.restoreAbleType;
}
\ No newline at end of file
lib/model/export_import/legacy_column.dart
@@ -0,0 +1,103 @@
+import 'package:blood_pressure_app/model/blood_pressure.dart';
+import 'package:blood_pressure_app/model/export_import/reocord_formatter.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+
+/// Convert [BloodPressureRecord]s from and to strings and provide metadata about the conversion.
+@Deprecated("repaced by class in column.dart")
+class ExportColumn { // TODO: change this class so it implements the interface.
+ /// Create object that turns data into strings.
+ ///
+ /// Example: ExportColumn(internalColumnName: 'pulsePressure', columnTitle: 'Pulse pressure', formatPattern: '{{$SYS-$DIA}}')
+ ExportColumn({required this.internalName, required this.columnTitle, required String formatPattern, this.editable = true, this.hidden = false}) {
+ this.formatPattern = formatPattern.replaceAll('{{}}', '');
+ _formatter = ScriptedFormatter(formatPattern);
+ }
+
+ late final Formatter _formatter;
+
+ /// pure name as in the title of the csv file and for internal purposes. Should not contain special characters and spaces.
+ late final String internalName;
+
+ /// Display title of the column. Possibly localized
+ late final String columnTitle;
+
+ /// Pattern to create the field contents from:
+ /// It supports inserting values for $TIMESTAMP, $SYS $DIA $PUL, $COLOR and $NOTE. Where $TIMESTAMP is the time since unix epoch in milliseconds.
+ /// To format a timestamp in the same format as the $TIMESTAMP variable, $FORMAT(<timestamp>, <formatString>).
+ /// It is supported to use basic mathematics inside of double brackets ("{{}}"). In case one of them is not present in the record, -1 is provided.
+ /// The following math is supported:
+ /// Operations: [+, -, *, /, %, ^]
+ /// One-parameter functions [ abs, acos, asin, atan, ceil, cos, cosh, cot, coth, csc, csch, exp, floor, ln, log, round sec, sech, sin, sinh, sqrt, tan, tanh ]
+ /// Two-parameter functions [ log, nrt, pow ]
+ /// Constants [ e, pi, ln2, ln10, log2e, log10e, sqrt1_2, sqrt2 ]
+ /// The full math interpreter specification can be found here: https://pub.dev/documentation/function_tree/latest#interpreter
+ ///
+ /// The String is processed in the following order:
+ /// 1. variable replacement
+ /// 2. Math
+ /// 3. Date format
+ late final String formatPattern;
+
+ @Deprecated('will be replaced by the data structure the column is stored in')
+ final bool editable; // TODO: remove
+
+ /// doesn't show up as unused / hidden field in list
+ final bool hidden;
+
+ factory ExportColumn.fromJson(Map<String, dynamic> json, [editable = true, hidden = false]) =>
+ ExportColumn(
+ internalName: json['internalColumnName'],
+ columnTitle: json['columnTitle'],
+ formatPattern: json['formatPattern'],
+ editable: editable,
+ hidden: hidden
+ );
+
+ Map<String, dynamic> toJson() => {
+ 'internalColumnName': internalName,
+ 'columnTitle': columnTitle,
+ 'formatPattern': formatPattern
+ };
+
+ /// Turns a [BloodPressureRecord] into a string as defined in the [formatPattern].
+ String formatRecord(BloodPressureRecord record) => _formatter.encode(record);
+
+ /// Parses records if [isReversible] is true else returns an empty list
+ List<(RowDataFieldType, dynamic)> parseRecord(String formattedRecord) => [
+ if (_formatter.decode(formattedRecord) != null)
+ _formatter.decode(formattedRecord)!
+ ];
+
+ /// Checks if the pattern can be used to parse records. This is the case when the pattern contains variables without
+ /// containing curly brackets or commas.
+ bool get isReversible => _formatter.restoreAbleType != null;
+
+ RowDataFieldType? get parsableFormat => _formatter.restoreAbleType;
+
+ @override
+ String toString() {
+ return 'ExportColumn{internalColumnName: $internalName, columnTitle: $columnTitle, formatPattern: $formatPattern}';
+ }
+}
+
+/// Type a [ExportColumn] can be parsed as.
+enum RowDataFieldType {
+ timestamp, sys, dia, pul, notes, color;
+
+ String localize(AppLocalizations localizations) {
+ switch(this) {
+ case RowDataFieldType.timestamp:
+ return localizations.timestamp;
+ case RowDataFieldType.sys:
+ return localizations.sysLong;
+ case RowDataFieldType.dia:
+ return localizations.diaLong;
+ case pul:
+ return localizations.pulLong;
+ case RowDataFieldType.notes:
+ return localizations.notes;
+ case RowDataFieldType.color:
+ return localizations.color;
+ }
+ }
+}
\ No newline at end of file
lib/model/export_import/reocord_formatter.dart
@@ -1,5 +1,5 @@
import 'package:blood_pressure_app/model/blood_pressure.dart';
-import 'package:blood_pressure_app/model/export_import/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:flutter/material.dart';
import 'package:function_tree/function_tree.dart';
import 'package:intl/intl.dart';
lib/model/storage/db/config_dao.dart
@@ -1,4 +1,4 @@
-import 'package:blood_pressure_app/model/export_import/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/storage/db/config_db.dart';
import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
lib/model/export_import.dart
@@ -5,7 +5,7 @@ import 'dart:typed_data';
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/export_import/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/export_options.dart';
import 'package:blood_pressure_app/model/storage/export_csv_settings_store.dart';
import 'package:blood_pressure_app/model/storage/export_pdf_settings_store.dart';
lib/model/export_options.dart
@@ -2,7 +2,7 @@ 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/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/storage/common_settings_interfaces.dart';
import 'package:blood_pressure_app/model/storage/db/config_dao.dart';
import 'package:blood_pressure_app/model/storage/export_settings_store.dart';
lib/screens/subsettings/export_column_data.dart
@@ -1,6 +1,6 @@
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/export_import/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/export_options.dart';
import 'package:blood_pressure_app/screens/subsettings/export_field_format_documentation.dart';
import 'package:flutter/material.dart';
lib/screens/subsettings/export_import_screen.dart
@@ -5,7 +5,7 @@ import 'package:blood_pressure_app/components/export_item_order.dart';
import 'package:blood_pressure_app/components/settings/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_import/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:blood_pressure_app/model/export_options.dart';
import 'package:blood_pressure_app/model/storage/storage.dart';
import 'package:flutter/material.dart';
test/model/export_import/column_test.dart
@@ -1,6 +1,6 @@
import 'package:blood_pressure_app/model/blood_pressure.dart';
-import 'package:blood_pressure_app/model/export_import/column.dart';
+import 'package:blood_pressure_app/model/export_import/legacy_column.dart';
import 'package:flutter/material.dart';
import 'package:flutter_test/flutter_test.dart';
import 'package:intl/intl.dart';
pubspec.lock
@@ -125,10 +125,10 @@ packages:
dependency: "direct main"
description:
name: collection
- sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
+ sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
- version: "1.17.2"
+ version: "1.18.0"
convert:
dependency: transitive
description:
@@ -325,6 +325,22 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.3.0"
+ leak_tracker:
+ dependency: transitive
+ description:
+ name: leak_tracker
+ sha256: "04be76c4a4bb50f14904e64749237e541e7c7bcf7ec0b196907322ab5d2fc739"
+ url: "https://pub.dev"
+ source: hosted
+ version: "9.0.16"
+ leak_tracker_testing:
+ dependency: transitive
+ description:
+ name: leak_tracker_testing
+ sha256: b06739349ec2477e943055aea30172c5c7000225f79dad4702e2ec0eda79a6ff
+ url: "https://pub.dev"
+ source: hosted
+ version: "1.0.5"
lints:
dependency: transitive
description:
@@ -361,18 +377,18 @@ packages:
dependency: transitive
description:
name: material_color_utilities
- sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
+ sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a"
url: "https://pub.dev"
source: hosted
- version: "0.5.0"
+ version: "0.8.0"
meta:
dependency: transitive
description:
name: meta
- sha256: "3c74dbf8763d36539f114c799d8a2d87343b5067e9d796ca22b5eb8437090ee3"
+ sha256: d584fa6707a52763a52446f02cc621b077888fb63b93bbcb1143a7be5a0c0c04
url: "https://pub.dev"
source: hosted
- version: "1.9.1"
+ version: "1.11.0"
mockito:
dependency: "direct dev"
description:
@@ -638,18 +654,18 @@ packages:
dependency: transitive
description:
name: stack_trace
- sha256: c3c7d8edb15bee7f0f74debd4b9c5f3c2ea86766fe4178eb2a18eb30a0bdaed5
+ sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
- version: "1.11.0"
+ version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
- sha256: "83615bee9045c1d322bbbd1ba209b7a749c2cbcdcb3fdd1df8eb488b3279c1c8"
+ sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
- version: "2.1.1"
+ version: "2.1.2"
string_scanner:
dependency: transitive
description:
@@ -678,10 +694,10 @@ packages:
dependency: transitive
description:
name: test_api
- sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
+ sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b"
url: "https://pub.dev"
source: hosted
- version: "0.6.0"
+ version: "0.6.1"
typed_data:
dependency: transitive
description:
@@ -762,6 +778,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "2.1.4"
+ vm_service:
+ dependency: transitive
+ description:
+ name: vm_service
+ sha256: b3d56ff4341b8f182b96aceb2fa20e3dcb336b9f867bc0eafc0de10f1048e957
+ url: "https://pub.dev"
+ source: hosted
+ version: "13.0.0"
watcher:
dependency: transitive
description:
@@ -774,10 +798,10 @@ packages:
dependency: transitive
description:
name: web
- sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
+ sha256: edc8a9573dd8c5a83a183dae1af2b6fd4131377404706ca4e5420474784906fa
url: "https://pub.dev"
source: hosted
- version: "0.1.4-beta"
+ version: "0.4.0"
win32:
dependency: transitive
description:
@@ -811,5 +835,5 @@ packages:
source: hosted
version: "3.1.2"
sdks:
- dart: ">=3.1.0 <4.0.0"
+ dart: ">=3.2.0-194.0.dev <4.0.0"
flutter: ">=3.13.0"