86 Commits

Author SHA1 Message Date
3267bd9d5a Merge branch 'release-2.2.5' 2016-10-03 17:16:45 +02:00
5a9e7fe444 Bump version number, update versioninfo.txt. 2016-10-03 17:14:28 +02:00
f199b2f1bf Improve logging. 2016-10-03 17:12:47 +02:00
eae8cb718b Update homepage URLs in installer and About view. 2016-10-03 17:09:30 +02:00
ae012d42fb Merge branch 'refactor' into develop
- Repariert: Word bleibt nicht mehr hängen, wenn man versucht, ein Dokument zu speichern.
- Verbessert: Multiple Verbesserungen im Programmcode.
2016-10-03 16:29:27 +02:00
aea6d037c3 Update homepage URLs. 2016-10-03 16:29:09 +02:00
26c0d9e456 Update VstoAddinInstaller to v1.4.0. 2016-10-03 16:09:52 +02:00
e190e85b89 Fix additional tests. 2016-10-03 16:09:43 +02:00
ba07293385 Fix window handle provider. 2016-10-03 16:09:03 +02:00
46b4af54c5 Update Bovender framework to v0.14.5. 2016-09-03 23:44:30 +02:00
63012281db Refactor, using latest bovender framework. 2016-09-03 23:18:43 +02:00
812042d4bf Update notification action property names. 2016-09-03 11:14:25 +02:00
ad34141909 Update bovender framework to v0.14.1. 2016-09-03 11:13:49 +02:00
523e6ac438 Update versioninfo.txt for 2.2.4. 2016-04-05 14:14:04 +02:00
e20b967b44 Merge branch 'release-2.2.4' into develop 2016-04-05 14:12:59 +02:00
753219c1eb Merge branch 'release-2.2.4' 2016-04-05 14:11:34 +02:00
19ffff86ff Write history. 2016-04-05 14:11:03 +02:00
5b8cea34de Bump version number.
- VERBESSERT: Kleine Optimierungen beim Installationsprogramm.
2016-04-05 14:10:07 +02:00
999f2def41 Update VstoInstaller to 1.1.0. 2016-04-03 15:35:11 +02:00
1ba74bbc29 Use VstoAddinInstaller from Github repository. 2016-03-30 17:18:50 +02:00
474a292991 Remove local VstoAddinInstaller submodule. 2016-03-30 17:14:42 +02:00
eaaed3b659 Update publication year. 2016-03-30 15:51:43 +02:00
1be66fbd71 Merge branch 'release-2.2.3' into develop 2016-03-30 14:12:30 +02:00
b1cd1f1a05 Merge branch 'release-2.2.3' 2016-03-30 14:11:57 +02:00
003da0f1b2 Update copyright year on home page. 2016-03-30 14:11:49 +02:00
9a5cc4d9df Update version info file. 2016-03-30 14:11:03 +02:00
15ada1cefd Update VstoAddinInstaller and fix make-installer script. 2016-03-30 14:08:15 +02:00
94efa435f2 Bump version number, write history. 2016-03-30 14:02:33 +02:00
89df2f5e13 Fix host declaration in installer script.
- REPARIERT: Installationsskript hat Add-in nicht aktiviert.
2016-03-30 13:59:43 +02:00
e3e86891b8 Merge branch 'release-2.2.2' into develop 2016-03-29 21:49:54 +02:00
20c0b8a76e Merge branch 'release-2.2.2' 2016-03-29 21:49:22 +02:00
d807472016 Update VstoAddinInstaller. 2016-03-29 21:49:16 +02:00
33c8f48282 Write history. 2016-03-29 21:06:51 +02:00
9bbab2607d Merge branch 'vstoaddininstaller' into develop
- VERBESSERT: Installationsprogramm erkennt jetzt, wenn Word bereits läuft, und bietet an, es zu schließen
2016-03-29 12:21:46 +02:00
15df44a93b Use VstoAddinInstaller to produce version 2.2.2. 2016-03-29 12:21:40 +02:00
67219d0ae5 Add VstoAddinInstaller as submodule. 2016-03-29 10:16:54 +02:00
3f6383b076 Merge branch 'hotfix-2.2.1' into develop 2015-12-03 16:17:22 +01:00
c104568e5b Merge branch 'hotfix-2.2.1' 2015-12-03 16:16:48 +01:00
687ce567e3 Prepare release 2.2.1. 2015-12-03 16:16:42 +01:00
573cd743d1 Fix parsing of single-prescription lines.
- VERBESSERT: 'Alternative' Verordnungen wurden nicht erkannt, wenn in der selben Zeile nicht auch eine 'kanonische' Verordnung stand.
2015-12-03 16:13:53 +01:00
0d4b60096a Fix typo in demo document. 2015-12-03 16:13:34 +01:00
4c147a9764 Fix XmlException (report ID 6a36e38b).
- VERBESSERT: Fehlermeldung "Ein Name darf nicht mit dem Zeichen ' ' beginnen" wurde abgestellt (Fehlernr. 6a36e38b).
2015-12-03 16:12:04 +01:00
d1fa0b797d Merge branch 'release-2.2.0' into develop 2015-12-03 06:12:25 +01:00
2a3ff8c63e Merge branch 'release-2.2.0' 2015-12-03 06:10:35 +01:00
7e79256ffd Prepare release 2.2.0. 2015-12-03 06:10:27 +01:00
1314cb0e4b Merge branch 'medication' into develop
- NEU: Funktion zum Formatieren der Medikationsliste.
2015-12-03 06:08:03 +01:00
d28d51e875 Improve detection of two prescription columns. 2015-12-03 06:03:35 +01:00
86c8a9a1b4 Improve prescription block autodetection. 2015-12-02 21:45:55 +01:00
c3fde7fc28 Add reference levels to immunology in clinic style.
- VERBESSERT: Referenzbereiche zu Immunologie-Vorlage im Ambulanzstil hinzugefügt.
2015-12-02 21:10:47 +01:00
e71e69d4c4 Implement automatic MMF warning. 2015-12-02 17:08:25 +01:00
865e5bff1e Split prescriptions regexes. 2015-12-02 14:20:42 +01:00
2296fcfe41 Fix parsing of prescriptions without regular dosing. 2015-12-02 12:25:30 +01:00
92153f6d6c Import prescriptions by columns. 2015-12-01 21:10:42 +01:00
def5fce235 Fill prescription block by columns, not rows. 2015-12-01 20:51:24 +01:00
6ec282ee68 Improve formatting of prescriptions. 2015-12-01 17:38:44 +01:00
4479efc196 Fix parsing again. 2015-12-01 17:02:31 +01:00
84e298e9ad Fix parsing of drugs with comments. 2015-12-01 14:52:22 +01:00
61f494f10f Fix ribbon command. 2015-11-27 09:52:46 +01:00
21e7d44187 First working version of drugs formatting. 2015-11-26 21:33:10 +01:00
bcbed5bca3 Add prescriptions importer. 2015-11-26 20:02:07 +01:00
c35c73f56a Add multiple prescriptions parsing. 2015-11-26 19:44:33 +01:00
a255349672 Initial Prescription model with factory. 2015-11-26 19:11:25 +01:00
5198fa7358 Add carbohydrate-deficient transferrin.
- VERBESSERT: Kohlehydratdefizientes Transferrin hinzugefügt (als 'CDT') und Ambulanzstil angepaßt.
2015-11-25 20:52:20 +01:00
bed957a5cb Merge branch 'release-2.1.13' into develop 2015-11-12 21:25:16 +01:00
d01bdabf35 Merge branch 'release-2.1.13' 2015-11-12 21:24:56 +01:00
346112b069 Prepare release 2.1.13. 2015-11-12 21:24:38 +01:00
5d1ee1f96e Add pregnancy test and ARQ parameters.
- VERBESSERT: Parameter für Aldosteron, Renin und Schwangerschaftstest einprogrammiert.
2015-11-12 21:22:45 +01:00
3043a07632 Merge branch 'release-2.1.12' into develop 2015-11-04 20:52:49 +01:00
da90e8e528 Merge branch 'release-2.1.12' 2015-11-04 20:51:57 +01:00
1f744c8c42 Prepare release 2.1.12. 2015-11-04 20:51:52 +01:00
5868dc0cd4 Add Lipoprotein (a) to known parameters.
- VERBESSERT: Lp(a) zu den bekannten Parametern hinzugefügt.
2015-11-04 20:50:00 +01:00
fe1da47f84 Merge branch 'release-2.1.11' into develop 2015-10-28 15:37:49 +01:00
c8492c6266 Merge branch 'release-2.1.11' 2015-10-28 15:35:10 +01:00
bbd7bd1d7b Prepare release 2.1.11. 2015-10-28 15:35:05 +01:00
cb044015d2 Fix CK-MB in clinic style.
- VERBESSERT: Ambulanzstil überarbeitet, CK-MB wird jetzt mit ausgegeben.
2015-10-28 15:32:35 +01:00
08640363a2 Upgrade settings only once.
- VERBESSERT: Benutzereinstellungen werden nicht mehr jedes Mal zurückgesetzt.
2015-10-28 08:17:44 +01:00
578c126a20 Edit versioninfo.txt for 2.1.10. 2015-10-24 10:43:04 +02:00
180cb351a6 Merge branch 'release-2.1.10' into develop 2015-10-24 10:42:23 +02:00
d5bb0cd5fb Merge branch 'release-2.1.10' 2015-10-24 10:39:49 +02:00
65c6f9335f Prepare release 2.1.10. 2015-10-24 10:39:40 +02:00
80c8177a58 Fix definition of PSA.
- VERBESSERT: PSA wird jetzt richtig erkannt.
2015-10-24 10:37:21 +02:00
684a11a81a Merge branch 'release-2.1.9' into develop 2015-10-18 21:19:49 +02:00
b62204109f Merge branch 'release-2.1.9' 2015-10-18 21:19:19 +02:00
f2443d6e93 Prepare release 2.1.9. 2015-10-18 21:19:14 +02:00
0b4763bf99 Update bovender framework to 0.5.0.
- VERBESSERT: Integritätsprüfung für Updates wurde für besseren Algorithmus (SHA-256) vorbereitet.
2015-10-18 06:59:14 +02:00
45430302ae Merge branch 'release-2.1.8' into develop 2015-10-11 07:22:11 +02:00
64 changed files with 2075 additions and 1190 deletions

1
.gitignore vendored
View File

@ -16,6 +16,7 @@ publish/release/
x64/
win32/
[Rr]elease/
[Rr]eleases/
[Dd]debug/
Dist/
build/

3
.gitmodules vendored
View File

@ -1,3 +1,6 @@
[submodule "www/PHPMailer"]
path = www/PHPMailer
url = git@github.com:PHPMailer/PHPMailer.git
[submodule "deploy/VstoAddinInstaller"]
path = deploy/VstoAddinInstaller
url = git@github.com:bovender/VstoAddinInstaller.git

View File

@ -1,5 +1,89 @@
Version 2.1.8 (2015-10-09)
========================================================================
Version 2.2.4 (2016-04-05)
------------------------------------------------------------------------
- VERBESSERT: Kleine Optimierungen beim Installationsprogramm.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.2.3 (2016-03-30)
------------------------------------------------------------------------
- REPARIERT: Installationsskript hat Add-in nicht aktiviert.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.2.2 (2016-03-29)
------------------------------------------------------------------------
- VERBESSERT: Installationsprogramm erkennt jetzt, wenn Word bereits läuft, und bietet an, es zu schließen
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.2.1 (2015-12-03)
------------------------------------------------------------------------
- VERBESSERT: 'Alternative' Verordnungen wurden nicht erkannt, wenn in der selben Zeile nicht auch eine 'kanonische' Verordnung stand.
- VERBESSERT: Fehlermeldung "Ein Name darf nicht mit dem Zeichen ' ' beginnen" wurde abgestellt (Fehlernr. 6a36e38b).
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.2.0 (2015-12-03)
------------------------------------------------------------------------
- NEU: Funktion zum Formatieren der Medikationsliste.
- VERBESSERT: Kohlehydratdefizientes Transferrin hinzugefügt (als 'CDT') und Ambulanzstil angepaßt.
- VERBESSERT: Referenzbereiche zu Immunologie-Vorlage im Ambulanzstil hinzugefügt.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.1.13 (2015-11-12)
------------------------------------------------------------------------
- VERBESSERT: Parameter für Aldosteron, Renin und Schwangerschaftstest einprogrammiert.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.1.12 (2015-11-04)
------------------------------------------------------------------------
- VERBESSERT: Lp(a) zu den bekannten Parametern hinzugefügt.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.1.11 (2015-10-28)
------------------------------------------------------------------------
- VERBESSERT: Ambulanzstil überarbeitet, CK-MB wird jetzt mit ausgegeben.
- VERBESSERT: Benutzereinstellungen werden nicht mehr jedes Mal zurückgesetzt.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.1.10 (2015-10-24)
------------------------------------------------------------------------
- VERBESSERT: PSA wird jetzt richtig erkannt.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.1.9 (2015-10-18)
------------------------------------------------------------------------
- VERBESSERT: Integritätsprüfung für Updates wurde für besseren Algorithmus (SHA-256) vorbereitet.
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
Version 2.1.8 (2015-10-11)
------------------------------------------------------------------------
- VERBESSERT: Alpha-Fetoprotein (AFP) zu den bekannten Parametern hinzugefügt.
- VERBESSERT: Einstellungen werden nach Office-Update nicht vergessen.
@ -8,7 +92,7 @@ Version 2.1.8 (2015-10-09)
Version 2.1.7 (2015-10-02)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: Statt Sekretariatsmodus stand zweimal Ärztemodus im Begrüßungsbildschirm.
@ -16,7 +100,7 @@ Version 2.1.7 (2015-10-02)
Version 2.1.6. (2015-09-27)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: Eingebaute Stile überarbeitet.
- VERBESSERT: Troponin T wurde nicht richtig verarbeitet.
@ -25,7 +109,7 @@ Version 2.1.6. (2015-09-27)
Version 2.1.5. (2015-09-24)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: NT-proBNP wird jetzt korrekt ausgegeben.
@ -33,7 +117,7 @@ Version 2.1.5. (2015-09-24)
Version 2.1.4 (2015-09-23)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: Unkonventionell ausgegebene Laborwerte (v.a. Cyclosporin-A vor Gabe) wurden nicht richtig erkannt.
@ -41,7 +125,7 @@ Version 2.1.4 (2015-09-23)
Version 2.1.3. (2015-09-18)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: CsA-Talspiegel tauchte nicht in der Ausgabe auf.
- VERBESSERT: Extreme Werte (mit "<" oder ">") wurden nicht sehr schön formatiert.
@ -50,7 +134,7 @@ Version 2.1.3. (2015-09-18)
Version 2.1.2 (2015-09-11)
========================================================================
------------------------------------------------------------------------
- GEÄNDERT: Sammelurin-Proteinurie als Prot abgekürzt.
- VERBESSERT: Ambulanzstil überarbeitet.
@ -60,7 +144,7 @@ Version 2.1.2 (2015-09-11)
Version 2.1.1 (2015-09-07)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: Fehler bei der Kommentaraufforderung wurden behoben.
@ -68,7 +152,7 @@ Version 2.1.1 (2015-09-07)
Version 2.1.0 (2015-09-06)
========================================================================
------------------------------------------------------------------------
- NEU: Optionale Kommentare zu Laborwerten.
- NEU: Sekretariatsmodus (siehe 'Einstellungen'), um die Nachfrage nach Zusatz-Kommentaren zu unterdrücken.
@ -80,7 +164,7 @@ Version 2.1.0 (2015-09-06)
Version 2.0.1 (2015-09-02)
========================================================================
------------------------------------------------------------------------
- FEHLERBEHEBUNG: Kein Absturz mehr, wenn zwei Spalten formatiert werden.
- VERBESSERT: Kein Absturz mehr, wenn das Demo-Dokument innerhalb der ZAA geöffnet wird (Exception ID 65a5c34e).
@ -91,7 +175,7 @@ Version 2.0.1 (2015-09-02)
Version 2.0.0-beta.5 (2015-08-25)
========================================================================
------------------------------------------------------------------------
- NEU: Auszeichnung pathologischer Werte kann eingestellt werden.
- NEU: Für bestimmte Laborwerte ist die bevorzugte Nachkommastellenzahl hinterlegt (z.B. Kreatinin mit nur einer Nachkommastelle).
@ -102,7 +186,7 @@ Version 2.0.0-beta.5 (2015-08-25)
Version 2.0.0-beta.4. (2015-08-23)
========================================================================
------------------------------------------------------------------------
- VERBESSERUNG: Aliasse für fT3 und fT4.
- VERBESSERUNG: Ambulanz-Stil überarbeitet.
@ -111,7 +195,7 @@ Version 2.0.0-beta.4. (2015-08-23)
Version 2.0.0-beta.3. (2015-08-20)
========================================================================
------------------------------------------------------------------------
- VERBESSERT: Bei Updates werden neue eingebaute Stile jetzt immer berücksichtigt.
- VERBESSERT: Formatierung erscheint nur noch als 1 Undo-Schritt.
@ -123,7 +207,7 @@ Version 2.0.0-beta.3. (2015-08-20)
Version 2.0.0-beta.2 (2015-08-16)
========================================================================
------------------------------------------------------------------------
- FIX: Kleinere Bugfixes.
- GEÄNDERT: Diff.-BB-Werte im Stations-Stil in Hämatologie-Zeile integriert.
@ -139,7 +223,7 @@ Version 2.0.0-beta.2 (2015-08-16)
Version 2.0.0-beta.1 (2015-08-13)
========================================================================
------------------------------------------------------------------------
- FIX: Datenimport funktioniert jetzt auch mit Word-Text und nicht nur in den Tests.
- FIX: Mehrere Thesaurus-Fehler behoben.
@ -156,7 +240,7 @@ Version 2.0.0-beta.1 (2015-08-13)
Version 2.0.0-alpha.5. (2015-08-04)
========================================================================
------------------------------------------------------------------------
- FIX: Daniels Spezial löscht nicht mehr die Unterschriften.
- NEU: Eingebautes Demo-Dokument zum Ausprobieren.
@ -166,7 +250,7 @@ Version 2.0.0-alpha.5. (2015-08-04)
Version 2.0.0-alpha.3 (2015-07-31)
========================================================================
------------------------------------------------------------------------
- FIX: Beim Start wird jetzt nach Updates gesucht.
@ -174,7 +258,7 @@ Version 2.0.0-alpha.3 (2015-07-31)
Version 2.0.0-alpha.2 (2015-07-28)
========================================================================
------------------------------------------------------------------------
- NEU: Fehlerbehandlung und Fehlerberichte.
@ -182,7 +266,7 @@ Version 2.0.0-alpha.2 (2015-07-28)
Version 2.0.0-alpha.1 (2015-07-27)
========================================================================
------------------------------------------------------------------------
- NEW: First release of version 2 series.
@ -190,7 +274,7 @@ Version 2.0.0-alpha.1 (2015-07-27)
Version 2.0.0 (2015-08-30)
========================================================================
------------------------------------------------------------------------
- FEHLERBEHEBUNG: Kein Absturz mehr, wenn zwei Spalten formatiert werden.
- VERBESSERT: Kein Crash mehr, falls sich ein Komma in den Lauris-Block einschleicht.

View File

@ -44,6 +44,7 @@ namespace Tests.Controller.Elements
public void TearDown()
{
((_Document)_document).Close(WdSaveOptions.wdDoNotSaveChanges);
Bovender.ComHelpers.ReleaseComObject(_document);
}
[Test]

View File

@ -32,14 +32,14 @@ namespace Tests.Controller
[SetUp]
public void SetUp()
{
_savedSettings = zaaReloaded2.Properties.Settings.Default.SettingsRepository;
_savedSettings = zaaReloaded2.UserSettings.Default.SettingsRepository;
}
[TearDown]
public void TearDown()
{
zaaReloaded2.Properties.Settings.Default.SettingsRepository = _savedSettings;
zaaReloaded2.Properties.Settings.Default.Save();
zaaReloaded2.UserSettings.Default.SettingsRepository = _savedSettings;
zaaReloaded2.UserSettings.Default.Save();
}
[Test]

View File

@ -153,7 +153,7 @@ namespace Tests.Importer.ZaaImporter
[TestCase("Albumin (SU)/die: 149.9 [<= 30] mg/d; ", Material.SU)]
[TestCase("Gesamt-Eiweiss/Creatinin (PU): 281 [<= 70] mg/g Crea;", Material.U)]
[TestCase("Cystatin C (N Latex): 2.37 [0.57 - 0.96] mg/l; ", Material.B)]
[TestCase("Cystatin C (N Latex): 2.37 [0.57 - 0.96] mg/l; ", Material.S)]
public void ParseLaurisMaterial(string laurisString, Material expectedMaterial)
{
LaurisItem i = new LaurisItem(laurisString);

View File

@ -0,0 +1,45 @@
/* ImporterTest.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
namespace Tests.Medication
{
[TestFixture]
class ImporterTest
{
[Test]
public void ImportDrugsTwoColumns()
{
string s =
"Aktuelle Medikation:\r" +
"Advagraf 1 mg 2-0-0 CellCept 500 mg 1-0-1\r" +
"CellCept 250 mg 1-0-1 Decortin 10 mg 1-0-0\r" +
"Beloc-Zok mite 1-0-1 Ramipril 5 mg 0-0-1 (neu)\r" +
"Pantozol 40 mg 0-0-1 Decostriol 0,5 µg 2-0-0\r" +
"Euthyrox 200 µg 1-1-1 (gesteigert) Ossofortin forte 1-0-1\r" +
"Vfend 200 mg 2-0-2 CPS-Pulver 0-1-0\r" +
"Cyklokapron 500 mg 1-1-1 Tamsulosin 0,4 mg 1-0-0 ";
zaaReloaded2.Medication.Importer i = new zaaReloaded2.Medication.Importer(s);
Assert.AreEqual(14, i.Prescriptions.Count);
}
}
}

View File

@ -0,0 +1,128 @@
/* PrescriptionTest.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NUnit.Framework;
using zaaReloaded2.Medication;
namespace Tests.Medication
{
[TestFixture]
class PrescriptionTest
{
[Test]
[TestCase("Ramipril 5 mg 1-2-3", "Ramipril 5 mg", "1", "2", "3")]
[TestCase("Ramipril 5 mg 1 -2 - 3", "Ramipril 5 mg", "1", "2", "3")]
[TestCase("Ramipril 5 mg 1 - 2 - 3", "Ramipril 5 mg", "1", "2", "3")]
[TestCase("Ramipril 5 mg 1 - 2 - 3", "Ramipril 5 mg", "1", "2", "3")]
[TestCase("Ramipril 5 mg 1 1/2-2-3", "Ramipril 5 mg", "1 1/2", "2", "3")]
[TestCase("Ramipril 5 mg 1 1/2 - 2 - 3", "Ramipril 5 mg", "1 1/2", "2", "3")]
[TestCase("Ramipril 5 mg ½-⅓-¼", "Ramipril 5 mg", "½", "⅓", "¼")]
public void ParseLine(string line, string drug, string morning,
string noon, string evening)
{
Prescription p = Prescription.FromLine(line);
Assert.AreEqual(drug, p.Drug, "Drug should be " + drug);
Assert.AreEqual(morning, p.Morning, "Morning should be " + morning);
Assert.AreEqual(noon, p.Noon, "Noon should be " + noon);
Assert.AreEqual(evening, p.Evening, "Evening should be " + evening);
}
[Test]
public void MultiplePrescriptions()
{
IEnumerable<Prescription> list = Prescription.ManyFromLine(
"Ramipril 5 mg 1-0-0 \t Prograf 1 mg 1-0-1");
Assert.AreEqual(2, list.Count());
Assert.AreEqual("Ramipril 5 mg\t1-0-0", list.First().ToString());
Assert.AreEqual("Prograf 1 mg\t1-0-1", list.Last().ToString());
}
[Test]
[TestCase("Ramipril 5 mg", "1", "0", "0", "0", "Ramipril 5 mg\t1-0-0-0")]
[TestCase("Ramipril 5 mg", "1", "0", "0", "", "Ramipril 5 mg\t1-0-0")]
[TestCase("Ramipril 5 mg", "1", "0", "", "", "Ramipril 5 mg\t1-0")]
[TestCase("Ramipril 5 mg", "1", "", "", "", "Ramipril 5 mg\t1")]
[TestCase("Ramipril 5 mg", "1", "", "0", "0", "Ramipril 5 mg\t1-0-0-0")]
[TestCase("Ramipril 5 mg", "1", "0", "", "0", "Ramipril 5 mg\t1-0-0-0")]
[TestCase("Ramipril 5 mg", "1", "", "", "0", "Ramipril 5 mg\t1-0-0-0")]
[TestCase("Ramipril 5 mg", "", "", "", "", "Ramipril 5 mg\t")]
public void PrescriptionToString(string drug, string morning, string noon,
string evening, string night, string formatted)
{
Prescription p = new Prescription(drug, morning, noon, evening, night);
Assert.AreEqual(formatted, p.ToString());
}
[Test]
public void PrescriptionWithComment()
{
Prescription p = Prescription.FromLine("Ramipril 5 mg 1-0-2 (gesteigert)");
Assert.AreEqual("Ramipril 5 mg", p.Drug);
Assert.AreEqual("1", p.Morning);
Assert.AreEqual("0", p.Noon);
Assert.AreEqual("2", p.Evening);
Assert.AreEqual("(gesteigert)", p.Comment);
Assert.AreEqual("Ramipril 5 mg\t1-0-2 (gesteigert)", p.ToString());
}
[Test]
public void PrescriptionsLineWithComment()
{
IList<Prescription> list = Prescription.ManyFromLine(
"Ramipril 5 mg 1-0-2 (gesteigert) \t Concor 2,5 mg 3-2-1-0 neu");
Assert.AreEqual(2, list.Count);
Assert.AreEqual("Ramipril 5 mg", list[0].Drug);
Assert.AreEqual("1", list[0].Morning);
Assert.AreEqual("0", list[0].Noon);
Assert.AreEqual("2", list[0].Evening);
Assert.AreEqual("", list[0].Night);
Assert.AreEqual("(gesteigert)", list[0].Comment);
Assert.AreEqual("Concor 2,5 mg", list[1].Drug);
Assert.AreEqual("3", list[1].Morning);
Assert.AreEqual("2", list[1].Noon);
Assert.AreEqual("1", list[1].Evening);
Assert.AreEqual("0", list[1].Night);
Assert.AreEqual("neu", list[1].Comment);
}
[Test]
public void PrescriptionWithoutTypicalDosing()
{
Prescription p = Prescription.FromLine("Eusaprim forte\t alle zwei Tage");
Assert.AreEqual("Eusaprim forte", p.Drug);
Assert.AreEqual("alle zwei Tage", p.Comment);
Assert.AreEqual("Eusaprim forte\talle zwei Tage", p.ToString(), "ToString");
}
[Test]
[TestCase("CellCept 500 mg", true)]
[TestCase("Cell CEpt 500 mg", true)]
[TestCase("Myfortic", true)]
[TestCase("Mycophenolatmofetil 500 mg", true)]
[TestCase("Cellophan 5 g", false)]
[TestCase("MMF 500 mg", true)]
public void MmfProperty(string drug, bool isMmf)
{
Prescription p = new Prescription(drug);
Assert.AreEqual(isMmf, p.IsMmf);
}
}
}

View File

@ -41,16 +41,20 @@
<AssemblyOriginatorKeyFile>zaaReloaded2.pfx</AssemblyOriginatorKeyFile>
</PropertyGroup>
<ItemGroup>
<Reference Include="Bovender, Version=0.4.0.0, Culture=neutral, PublicKeyToken=df1c15557d8b6df8, processorArchitecture=MSIL">
<HintPath>..\packages\Bovender.0.4.0.0\lib\net40\Bovender.dll</HintPath>
<Reference Include="Bovender, Version=0.14.5.0, Culture=neutral, PublicKeyToken=df1c15557d8b6df8, processorArchitecture=MSIL">
<HintPath>..\packages\Bovender.0.14.5.0\lib\net40\Bovender.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Office.Interop.Word, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
<EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
<Reference Include="nunit.framework, Version=2.6.4.14350, Culture=neutral, PublicKeyToken=96d09a1eb7f44a77, processorArchitecture=MSIL">
<SpecificVersion>False</SpecificVersion>
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.7\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="nunit.framework, Version=3.4.1.0, Culture=neutral, PublicKeyToken=2638cd05610744eb, processorArchitecture=MSIL">
<HintPath>..\packages\NUnit.3.4.1\lib\net40\nunit.framework.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
@ -66,6 +70,10 @@
<Reference Include="System.Xaml" />
<Reference Include="System.XML" />
<Reference Include="WindowsBase" />
<Reference Include="YamlDotNet, Version=3.9.0.0, Culture=neutral, PublicKeyToken=ec19458f3c15af5e, processorArchitecture=MSIL">
<HintPath>..\packages\YamlDotNet.Signed.3.9.0\lib\net35\YamlDotNet.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<Choose>
<When Condition="('$(VisualStudioVersion)' == '10.0' or '$(VisualStudioVersion)' == '') and '$(TargetFrameworkVersion)' == 'v3.5'">
@ -83,6 +91,8 @@
<Compile Include="Controller\Comments\CommentPoolTest.cs" />
<Compile Include="Controller\Comments\ItemCommentTest.cs" />
<Compile Include="Controller\Elements\CloneTest.cs" />
<Compile Include="Medication\ImporterTest.cs" />
<Compile Include="Medication\PrescriptionTest.cs" />
<Compile Include="SerializationTest.cs" />
<Compile Include="Controller\SettingsRepositoryTest.cs" />
<Compile Include="Controller\SettingsTest.cs" />
@ -105,6 +115,7 @@
<Compile Include="ViewModels\SettingsViewModelTest.cs" />
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="packages.config" />
<None Include="Tests.licenseheader" />
<None Include="zaaReloaded2.pfx" />

29
Tests/app.config Executable file
View File

@ -0,0 +1,29 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
app.config
part of zaaReloaded2
Copyright 2016 Daniel Kraus
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<configuration>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="YamlDotNet" publicKeyToken="ec19458f3c15af5e" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.9.0.0" newVersion="3.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -1,6 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Bovender" version="0.4.0.0" targetFramework="net40" />
<package id="Bovender" version="0.14.5.0" targetFramework="net40" />
<package id="Expression.Blend.Sdk" version="1.0.2" targetFramework="net40" />
<package id="NUnit" version="2.6.4" targetFramework="net40" />
<package id="NLog" version="4.3.7" targetFramework="net40" />
<package id="NUnit" version="3.4.1" targetFramework="net40" />
<package id="YamlDotNet.Signed" version="3.9.0" targetFramework="net40" />
</packages>

32
deploy/make-installer.iss Executable file
View File

@ -0,0 +1,32 @@
#expr Exec("C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com", \
"x:\Code\zaaReloaded2\zaaReloaded2\zaaReloaded2.csproj /Build Release")
#define VERSIONFILE "..\zaaReloaded2\VERSION"
#define PUB_YEARS "2015-2016"
#define TARGET_HOST "word"
#define APP_GUID "{{8520B887-3AB1-422B-AB6B-A265D14FE4E5}"
#define ADDIN_NAME "zaaReloaded"
#define COMPANY "Daniel Kraus (bovender)"
#define DESCRIPTION "Word-Addin, das Lauris-Laborwerte in der Zentralen Arztbriefablage formatiert."
#define HOMEPAGE "https://doktorkraus.de/zaareloaded"
#define REGKEY "zaaReloaded2"
#define SOURCEDIR "..\zaaReloaded2\bin\Release\"
#define VSTOFILE "zaaReloaded2.vsto"
; OUTPUTDIR is the directory where the installer will be saved.
#define OUTPUTDIR "releases\"
#define LOGFILE "ZAARELOADED2-INSTALL-LOG.TXT"
#define SETUPFILESDIR "setup-files\"
#define LICENSE_FILE "license.rtf"
#define INSTALLER_ICO "icon.ico"
#define INSTALLER_IMAGE_LARGE "installbanner.bmp"
#define INSTALLER_IMAGE_SMALL "installbanner-small.bmp"
; If the VstoAddinInstaller files are in a different subdirectory
; than 'VstoAddinInstaller', change the path below.
#include "VstoAddinInstaller\vsto-installer.iss"
; vim: ts=2 sts=2 sw=2 et

View File

Before

Width:  |  Height:  |  Size: 204 KiB

After

Width:  |  Height:  |  Size: 204 KiB

View File

Before

Width:  |  Height:  |  Size: 38 KiB

After

Width:  |  Height:  |  Size: 38 KiB

View File

Before

Width:  |  Height:  |  Size: 6.8 KiB

After

Width:  |  Height:  |  Size: 6.8 KiB

View File

Before

Width:  |  Height:  |  Size: 153 KiB

After

Width:  |  Height:  |  Size: 153 KiB

BIN
gimp/m.xcf Normal file

Binary file not shown.

BIN
gimp/mm.xcf Normal file

Binary file not shown.

View File

@ -1,760 +0,0 @@
; Inno Setup script for zaaReloaded2
; (c) 2015 Daniel Kraus
; Apache License Version 2.0
[Setup]
; #define DEBUG
; Read the semantic and the installer file version from the VERSION file
#define FILE_HANDLE FileOpen("..\zaaReloaded2\VERSION")
#define SEMVER FileRead(FILE_HANDLE)
#define VER FileRead(FILE_HANDLE)
#expr FileClose(FILE_HANDLE)
#define YEAR "2015"
#define DEV "Daniel Kraus"
#define LOGFILE "INST-LOG.TXT"
#define REGKEY "Software\Microsoft\Office\Word\Addins\zaaReloaded2"
#define APPNAME "zaaReloaded"
#define SLOGAN "Word-Addin, das Lauris-Laborwerte in der Zentralen Arztbriefablage formatiert"
#define UNINSTALLDIR "{app}\setup"
#define ADDINNAME "zaaReloaded2"
#define DOTNETSHA1 "58da3d74db353aad03588cbb5cea8234166d8b99"
#define VSTORSHA1 "ad1dcc5325cb31754105c8c783995649e2208571"
#ifndef DEBUG
#define SOURCEDIR "Release"
#define VSTORURL "http://download.microsoft.com/download/2/E/9/2E9D2603-6D1F-4B12-BD37-DB1410B23597/vstor_redist.exe"
#define DOTNETURL "http://download.microsoft.com/download/9/5/A/95A9616B-7A37-4AF6-BC36-D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe"
; Build the solution with Release configuration
#expr Exec("C:\Program Files (x86)\Microsoft Visual Studio 12.0\Common7\IDE\devenv.com", \
"x:\Code\zaaReloaded2\zaaReloaded2\zaaReloaded2.csproj /Build Release")
#else
#define SOURCEDIR "Debug"
#define VSTORURL "http://vhost/vstor_redist.exe"
#define DOTNETURL "http://vhost/dotNetFx40_Full_x86_x64.exe"
#endif
; Specific AppID - NEVER CHANGE THIS!
AppId={{8520B887-3AB1-422B-AB6B-A265D14FE4E5}
; Compiler info
OutputDir=release
#ifndef DEBUG
OutputBaseFilename=zaaReloaded-{#SEMVER}
#else
OutputBaseFilename=zaaReloaded-debug
#endif
Compression=lzma
InternalCompressLevel=max
SolidCompression=true
LicenseFile=setup-files\license.rtf
; Application name, version, etc.
AppName={#APPNAME}
AppVersion={#SEMVER}
AppPublisher={#DEV}
AppCopyright=2008-{#YEAR} {#DEV}
AppComments={#SLOGAN}
VersionInfoDescription={#SLOGAN}
VersionInfoVersion={#VER}
VersionInfoProductVersion={#VER}
VersionInfoTextVersion={#SEMVER}
VersionInfoProductTextVersion={#SEMVER}
AppContact={#DEV}
AppPublisherURL=http://zaa.nephrowiki.de
AppSupportURL=http://zaa.nephrowiki.de
AppUpdatesURL=http://zaa.nephrowiki.de
; Setup wizard
SetupIconFile=setup-files\icon.ico
WizardImageFile=setup-files\installbanner.bmp
WizardSmallImageFile=setup-files\installbanner-small.bmp
ArchitecturesAllowed=x86 x64
ArchitecturesInstallIn64BitMode=x64
DisableProgramGroupPage=true
DisableDirPage=false
DisableReadyPage=false
LanguageDetectionMethod=locale
TimeStampsInUTC=false
PrivilegesRequired=lowest
WizardImageStretch=false
WizardImageBackColor=clWhite
; ChangesAssociations=true
AppendDefaultDirName=false
DefaultDirName={code:SuggestInstallDir}
CreateAppDir=true
CloseApplicationsFilter=*.*
DefaultDialogFontName=Segoe UI
; Uninstall
;UninstallDisplayIcon={#UNINSTALLDIR}\xltoolbox.ico
UninstallFilesDir={#UNINSTALLDIR}
; Inno Downloader Plugin is required for this
; Note that this include directive MUST be located at the end of the [setup]
; section.
#include <idp.iss>
[Languages]
Name: en; MessagesFile: compiler:Default.isl;
Name: de; MessagesFile: compiler:Languages\German.isl;
; Name: Brasileiro; MessagesFile: compiler:Languages\BrazilianPortuguese.isl;
; Name: Portugues; MessagesFile: compiler:Languages\Portuguese.isl;
#include "c:\Program Files (x86)\Inno Download Plugin\Unicode\idplang\german.iss"
[Files]
Source: "..\zaaReloaded2\bin\{#SOURCEDIR}\*"; DestDir: "{app}"; Flags: ignoreversion createallsubdirs recursesubdirs
; Source: "setup-files\xltoolbox.ico"; DestDir: "{#UNINSTALLDIR}"
; NOTE: Don't use "Flags: ignoreversion" on any shared system files
[Registry]
; Keys for single-user install (HKCU)
Check: not IsMultiUserInstall; ValueName: Description; ValueData: {#SLOGAN}; ValueType: string; Root: HKCU; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: not IsMultiUserInstall; ValueName: FriendlyName; ValueData: {#APPNAME}; ValueType: string; Root: HKCU; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: not IsMultiUserInstall; ValueName: LoadBehavior; ValueData: 3; ValueType: dword; Root: HKCU; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: not IsMultiUserInstall; ValueName: Warmup; ValueData: 1; ValueType: dword; Root: HKCU; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: not IsMultiUserInstall; ValueName: Manifest; ValueData: file:///{code:ConvertSlash|{app}}/{#ADDINNAME}.vsto|vstolocal; ValueType: string; Root: HKCU; Subkey: {#REGKEY}; Flags: uninsdeletekey
; Same keys again, this time for multi-user install (HKLM)
Check: IsMultiUserInstall; ValueName: Description; ValueData: {#SLOGAN}; ValueType: string; Root: HKLM; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: IsMultiUserInstall; ValueName: FriendlyName; ValueData: {#APPNAME}; ValueType: string; Root: HKLM; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: IsMultiUserInstall; ValueName: LoadBehavior; ValueData: 3; ValueType: dword; Root: HKLM; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: IsMultiUserInstall; ValueName: Warmup; ValueData: 1; ValueType: dword; Root: HKLM; Subkey: {#REGKEY}; Flags: uninsdeletekey
Check: IsMultiUserInstall; ValueName: Manifest; ValueData: file:///{code:ConvertSlash|{app}}/{#ADDINNAME}.vsto|vstolocal; ValueType: string; Root: HKLM; Subkey: {#REGKEY}; Flags: uninsdeletekey
[Run]
; Filename: http://xltoolbox.sourceforge.net/welcome.html; Flags: shellexec nowait; Check: ShowWelcomePageInBrowser
[UninstallRun]
; Filename: http://xltoolbox.sourceforge.net/uninstall.html; Flags: shellexec nowait
[CustomMessages]
; General messages [EN]
en.SingleOrMulti=Single-user or system-wide install
en.SingleOrMultiSubcaption=Install for the current user only or for all users
en.SingleOrMultiDesc=Please indicate the scope of this installation:
en.SingleOrMultiSingle=Single user (only for me)
en.SingleOrMultiAll=All users (system-wide)
en.Word2007Required=zaaReloaded requires Word 2007 or later.
; CannotInstallPage [EN]
en.CannotInstallCaption=Administrator privileges required
en.CannotInstallDesc=You do not have the necessary rights to install additional required runtime files.
en.CannotInstallMsg=Additional runtime files from Microsoft are required to run this add-in. You may continue the installation, but the add-in won't start unless the required runtime files are installed by an administrator. Note: On Windows Vista and newer, right-click the installer file and choose 'Run as administrator'.
en.CannotInstallCont=Continue anyway, although it won't work without the required runtime files
en.CannotInstallAbort=Abort the installation (come back when the admin has installed the files)
; DownloadInfoPage [EN]
en.RequiredCaption=Additional runtime files required
en.RequiredDesc=Additional runtime files for the .NET framework from Microsoft are required in order to run the add-in.
en.RequiredMsg=%d file(s) totalling about %s MiB need to be downloaded from the Microsoft servers. Click 'Next' to start downloading.
; InstallInfoPage [EN]
en.InstallCaption=Runtime files downloaded
en.InstallDesc=The required runtime files are ready to install.
en.InstallMsg=Click 'Next' to beginn the installation.
en.StillNotInstalled=The required additional runtime files are still not installed. Setup cannot continue. You may try again, or abort the add-in installation.
en.DownloadNotValidated=A downloaded file has unexpected content. It may have not been downloaded correctly, or someone might have hampered with it. You may click 'Back' and then 'Next' to download it again.
; General messages [DE]
de.SingleOrMulti=Einzelner oder alle Benutzer
de.SingleOrMultiSubcaption=Geben Sie an, f<>r wen die Installation sein soll
de.SingleOrMultiDesc=Bitte geben Sie an, ob das Addin nur f<>r Sie oder f<>r alle Benutzer installiert werden soll.
de.SingleOrMultiSingle=Ein Benutzer (nur f<>r mich)
de.SingleOrMultiAll=Alle Benutzer (systemweit)
de.Word2007Required=Dieses Addin erfordert mindestens Word 2007.
; "Download required" messages (.NET and VSTOR runtimes) [DE]
de.CannotInstallCaption=Administratorrechte ben<65>tigt
de.CannotInstallDesc=Sie haben nicht die erforderlichen Benutzerrechte, um weitere ben<65>tigte Laufzeitdateien zu installieren.
de.CannotInstallMsg=Sie k<>nnen mit der Installation fortfahren, aber das Addin wird nicht starten, solange die VSTO-Laufzeitdateien nicht von einem Admin installiert wurden. Tipp: Wenn Sie Windows Vista oder neuer verwenden, klicken Sie mit der rechten Maustaste auf die Installationsdatei und w<>hlen "Als Administrator ausf<73>hren".
de.CannotInstallCont=Trotzdem installieren, obwohl es nicht funktionieren wird
de.CannotInstallAbort=Installation abbrechen
; DownloadInfoPage [EN]
de.RequiredCaption=Weitere Laufzeitdateien erforderlich
de.RequiredDesc=Weitere Laufzeitdateien f<>r das .NET-Framework von Microsoft werden ben<65>tigt, um das Addin verwenden zu k<>nnen.
de.RequiredMsg=%d Datei(en) mit ca. %s MiB mu<6D>/m<>ssen von den Microsoft-Servern heruntergeladen werden. Klicken Sie 'Weiter', um den Download zu beginnen.
; InstallInfoPage [EN]
de.InstallCaption=Weitere .NET-Laufzeitdateien heruntergeladen
de.InstallDesc=Die zus<75>tzlichen ben<65>tigten Dateien von Microsoft k<>nnen jetzt installiert werden.
de.InstallMsg=Klicken Sie 'Weiter', um mit der Installation zu beginnen.
de.StillNotInstalled=Die zus<75>tzlichen ben<65>tigten Dateien wurden leider nicht korrekt installiert, so da<64> die Installation nicht fortgesetzt werden kann.
de.DownloadNotValidated=Es wurde unerwarteter Inhalt in einer heruntergeladenen Datei gefunden. Die Installation kann so nicht fortgesetzt werden. Sie k<>nnen aber 'Zur<75>ck' und dann 'Weiter' klicken, um den Download neu zu beginnen.
[Code]
const
maxWord = 24; //< highest Word version number to check for.
var
PageDevelopmentInfo: TInputOptionWizardPage;
PageSingleOrMultiUser: TInputOptionWizardPage;
PageCannotInstall: TInputOptionWizardPage;
PageDownloadInfo: TOutputMsgWizardPage;
PageInstallInfo: TOutputMsgWizardPage;
prerequisitesChecked: boolean;
prerequisitesMet: boolean;
/// Returns the path for the Wow6432Node registry tree if the current operating
/// system is 64-bit, i.e., simulates WOW64 redirection.
function GetWowNode(): string;
begin
if IsWin64 then
begin
result := 'Wow6432Node\';
end
else
begin
result := '';
end;
end;
/// Checks if a given Word version is installed
function IsWordVersionInstalled(version: integer): boolean;
var key: string;
var lookup1, lookup2: boolean;
begin
key := 'Microsoft\Office\' + IntToStr(version) + '.0\Word\InstallRoot';
lookup1 := RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\' + GetWowNode + key);
// If checking for version >= 14.0 ("2010"), which was the first version
// that was produced in both 32-bit and 64-bit, on a 64-bit system we
// also need to check a path without 'Wow6434Node'.
if IsWin64 and (version >= 14) then
begin
lookup2 := RegKeyExists(HKEY_LOCAL_MACHINE, 'SOFTWARE\' + key);
end;
result := lookup1 or lookup2;
end;
/// Checks if only Word 2007 is installed
function IsOnlyWord2007Installed(): boolean;
var
i: integer;
begin
result := IsWordVersionInstalled(12);
// Iterate through all
for i := 14 to maxWord do
begin
if IsWordVersionInstalled(i) then
begin
result := false;
break;
end;
end;
end;
/// Checks if hotfix KB976477 is installed. This hotfix
/// is required to make Word 2007 recognize add-ins in
/// the HKLM hive as well.
function IsHotfixInstalled(): boolean;
begin
result := RegKeyExists(HKEY_LOCAL_MACHINE,
'SOFTWARE\Microsoft\Windows\Current Version\Uninstall\KB976477');
end;
/// Retrieves the build number of an installed Office version
/// in OutBuild. Returns true if the requested Office version
/// is installed and false if it is not installed.
function GetOfficeBuild(OfficeVersion: integer; var OutBuild: integer): boolean;
var
key: string;
value: string;
build: string;
begin
key := 'SOFTWARE\' + GetWowNode + 'Microsoft\Office\' +
IntToStr(OfficeVersion) + '.0\Common\ProductVersion';
if RegQueryStringValue(HKEY_LOCAL_MACHINE, key, 'LastProduct', value) then
begin
// Office build numbers always have 4 digits, at least as of Feb. 2015;
// from a string '14.0.1234.5000' simply copy 4 characters from the 5th
// position to get the build number. TODO: Make this future-proof.
build := Copy(value, 6, 4);
Log('Found ProductVersion "' + value + '" for queried Office version '
+ IntToStr(OfficeVersion) + ', extracted build number ' + build);
OutBuild := StrToInt(build);
result := true;
end
else
Log('Did not find LastProduct key for Office version ' +
IntToStr(OfficeVersion) + '.0.');
end;
/// Asserts if Office 2007 is installed. Does not check whether other Office
/// versions are concurrently installed.
function IsOffice2007Installed(): boolean;
begin
result := IsWordVersionInstalled(12);
if result then Log('Detected Office 2007.');
end;
/// Asserts if Office 2010 without service pack is installed.
/// For build number, see http://support.microsoft.com/kb/2121559/en-us
function IsOffice2010NoSpInstalled(): boolean;
var
build: integer;
begin
if GetOfficeBuild(14, build) then
begin
result := build = 4763; // 4763 is the original Office 2007 build
if result then
Log('Detected Office 2010 without service pack (v. 14.0, build 4763)')
else
Log('Detected Office 2010, apparently with some service pack (build ' +
IntToStr(build) + ').');
end;
end;
/// Checks if the VSTO runtime is installed. This is relevant if only
/// Word 2007 is installed. Since Office 2010, the CLR is
/// automatically included.
/// The presence of the VSTO runtime is indicated by the presence one of
/// four possible registry keys.
/// See: http://xltoolbox.sf.net/blog/2015/01/net-vsto-add-ins-getting-prerequisites-right
/// HKLM\SOFTWARE\Microsoft\VSTO Runtime Setup\v4R (32-bit)
/// HKLM\SOFTWARE\Wow6432Node\Microsoft\VSTO Runtime Setup\v4R (64-bit)
function IsVstorInstalled(): boolean;
var
software, vstorPath: string;
begin
software := 'SOFTWARE\';
vstorPath := 'Microsoft\VSTO Runtime Setup\v4R';
result := RegKeyExists(HKEY_LOCAL_MACHINE, software + GetWowNode + vstorPath);
end;
/// Checks if the .NET 4.0 (or 4.5) runtime is installed.
/// See https://msdn.microsoft.com/en-us/library/hh925568
function IsNetInstalled(): boolean;
begin
result := RegKeyExists(HKEY_LOCAL_MACHINE,
'SOFTWARE\' + GetWowNode + 'Microsoft\NET Framework Setup\NDP\v4');
end;
/// Asserts if the VSTO runtime for .NET 4.0 redistributable needs to be
/// downloaded and installed.
/// If Office 2010 SP 1 or newer is installed on the system, the VSTOR runtime
/// will be automagically configured as long as the .NET 4.0 runtime is present.
/// Office 2007 and Office 2010 without service pack need the VSTO runtime
/// redistributable. For details, see:
/// http://xltoolbox.sf.net/blog/2015/01/net-vsto-add-ins-getting-prerequisites-right
function NeedToInstallVstor(): boolean;
begin
result := false; // Default for Office 2010 SP1 or newer
if IsOffice2007Installed or IsOffice2010NoSpInstalled then
result := not IsVstorInstalled;
end;
/// Checks if all required prerequisites are met, i.e. if the necessary
/// runtimes are installed on the system
function PrerequisitesAreMet(): boolean;
begin
// Cache check result to avoid multiple registry lookups and log messages
if not prerequisitesChecked then
begin
prerequisitesMet := IsNetInstalled and not NeedToInstallVstor;
prerequisitesChecked := true;
end;
result := prerequisitesMet;
end;
/// Checks if a file exists and has a valid Sha1 sum.
function IsFileValid(file: string; expectedSha1: string): boolean;
var
actualSha1: string;
begin
try
if FileExists(file) then
begin
actualSha1 := GetSHA1OfFile(file);
end;
finally
result := actualSha1 = expectedSha1;
end;
end;
/// Returns the path to the downloaded VSTO runtime installer.
function GetVstorInstallerPath(): string;
begin
result := ExpandConstant('{%temp}\vstor_redist_40.exe');
end;
/// Returns the path to the downloaded .NET runtime installer.
function GetNetInstallerPath(): string;
begin
result := ExpandConstant('{%temp}\dotNetFx40_Full_x86_x64.exe');
end;
/// Checks if the VSTO runtime redistributable setup file has already been
/// downloaded by comparing SHA1 checksums.
function IsVstorDownloaded(): boolean;
begin
result := IsFileValid(GetVstorInstallerPath, '{#VSTORSHA1}');
end;
/// Checks if the .NET runtime setup file has already been
/// downloaded by comparing SHA1 checksums.
function IsNetDownloaded(): boolean;
begin
result := IsFileValid(GetNetInstallerPath, '{#DOTNETSHA1}');
end;
/// Determines if the VSTO runtime needs to be downloaded.
/// This is not the case it the runtime is already installed,
/// or if there is a file with a valid Sha1 sum.
function NeedToDownloadVstor: boolean;
begin
result := NeedToInstallVstor and not IsVstorDownloaded;
end;
/// Determines if the VSTO runtime needs to be downloaded.
/// This is not the case it the runtime is already installed,
/// or if there is a file with a valid Sha1 sum.
function NeedToDownloadNet: boolean;
begin
result := not IsNetInstalled and not IsNetDownloaded;
end;
/// Determines whether or not a system-wide installation
/// is possible. This depends on whether the current user
/// is an administrator, and whether the hotfix KB976477
/// is present on the system if Word 2007 is the only version
/// of Word that is present (without that hotfix, Word
/// 2007 does not load add-ins that are registered in the
/// HKLM hive).
function CanInstallSystemWide(): boolean;
begin
if IsAdminLoggedOn then
begin
if IsOnlyWord2007Installed then
begin
result := IsHotfixInstalled;
end
else
begin
result := true;
end;
end
else
begin
result := false;
end;
end;
procedure CreateSingleOrAllUserPage();
begin
PageSingleOrMultiUser := CreateInputOptionPage(wpLicense,
CustomMessage('SingleOrMulti'), CustomMessage('SingleOrMultiSubcaption'),
CustomMessage('SingleOrMultiDesc'), True, False);
PageSingleOrMultiUser.Add(CustomMessage('SingleOrMultiSingle'));
PageSingleOrMultiUser.Add(CustomMessage('SingleOrMultiAll'));
if CanInstallSystemWide then
begin
PageSingleOrMultiUser.Values[1] := True;
end
else
begin
PageSingleOrMultiUser.Values[0] := True;
end;
end;
procedure CreateCannotInstallPage();
begin
PageCannotInstall := CreateInputOptionPage(wpWelcome,
CustomMessage('CannotInstallCaption'),
CustomMessage('CannotInstallDesc'),
CustomMessage('CannotInstallMsg'), True, False);
PageCannotInstall.Add(CustomMessage('CannotInstallCont'));
PageCannotInstall.Add(CustomMessage('CannotInstallAbort'));
PageCannotInstall.Values[1] := True;
end;
procedure CreateDownloadInfoPage();
var
bytes: Int64;
mib: Single;
size: String;
begin
if idpGetFilesSize(bytes) then
begin
mib := bytes / 1048576;
size := Format('%.1f', [ mib ]);
end
else
begin
size := '[?]'
end;
PageDownloadInfo := CreateOutputMsgPage(PageSingleOrMultiUser.Id,
CustomMessage('RequiredCaption'),
CustomMessage('RequiredDesc'),
Format(CustomMessage('RequiredMsg'), [idpFilesCount, size]));
end;
procedure CreateInstallInfoPage();
begin
PageInstallInfo := CreateOutputMsgPage(PageDownloadInfo.Id,
CustomMessage('InstallCaption'),
CustomMessage('InstallDesc'),
CustomMessage('InstallMsg'));
end;
function InitializeSetup(): boolean;
var
minWordInstalled: boolean;
i: integer;
begin
// Determine if Word 2007 or newer is installed (absolute requirement
// for this VSTO add-in). Word 2007 ist version 12.0.
for i := 12 to maxWord do
begin
minWordInstalled := minWordInstalled or IsWordVersionInstalled(i);
end;
if not minWordInstalled then
begin
result := False;
Log('Informing user that Word 2007 or newer is required.');
MsgBox(CustomMessage('Word2007Required'), mbInformation, MB_OK);
end
else
begin
result := True;
end
end;
procedure InitializeWizard();
begin
// CreateDevelopmentInfoPage;
CreateSingleOrAllUserPage;
if not PrerequisitesAreMet then
begin
Log('Not all prerequisites are met...');
CreateCannotInstallPage;
if NeedToDownloadNet then
begin
Log('Mark {#DOTNETURL} for download.');
idpAddFileSize('{#DOTNETURL}', GetNetInstallerPath, 50449456);
end;
if NeedToDownloadVstor then
begin
Log('Mark {#VSTORURL} for download.');
idpAddFileSize('{#VSTORURL}', GetVstorInstallerPath, 40123576);
end;
CreateDownloadInfoPage;
CreateInstallInfoPage;
idpDownloadAfter(PageDownloadInfo.Id);
end;
end;
function ExecuteNetSetup(): boolean;
var
exitCode: integer;
begin
result := true;
if not IsNetInstalled then
begin
if IsNetDownloaded then
begin
Log('Valid .NET runtime download found, installing.');
Exec(GetNetInstallerPath, '/norestart',
'', SW_SHOW, ewWaitUntilTerminated, exitCode);
BringToFrontAndRestore;
if not IsNetInstalled then
begin
MsgBox(CustomMessage('StillNotInstalled'), mbInformation, MB_OK);
result := False;
end;
end
else
begin
Log('No or invalid .NET runtime download found, will not install.');
MsgBox(CustomMessage('DownloadNotValidated'), mbInformation, MB_OK);
result := False;
end;
end; // not IsNetInstalled
end;
function ExecuteVstorSetup(): boolean;
var
exitCode: integer;
begin
result := true;
if NeedToInstallVstor then
begin
if IsVstorDownloaded then
begin
Log('Valid VSTO runtime download found, installing.');
Exec(GetVstorInstallerPath, '/norestart', '', SW_SHOW,
ewWaitUntilTerminated, exitCode);
BringToFrontAndRestore;
if not IsVstorInstalled then
begin
MsgBox(CustomMessage('StillNotInstalled'), mbInformation, MB_OK);
result := False;
end;
end
else
begin
Log('No or invalid VSTO runtime download found, will not install.');
MsgBox(CustomMessage('DownloadNotValidated'), mbInformation, MB_OK);
result := False;
end;
end; // not IsVstorInstalled
end;
function NextButtonClick(CurPageID: Integer): Boolean;
begin
result := True;
{
if not WizardSilent then
begin
if CurPageID = PageDevelopmentInfo.Id then
begin
if PageDevelopmentInfo.Values[0] = False then
begin
Log('Requesting user to acknowledge use of a developmental version.');
MsgBox(CustomMessage('DevVerMsgBox'), mbInformation, MB_OK);
result := False;
end;
end;
end;
}
if not PrerequisitesAreMet then
begin
// Abort the installation if any of the runtimes are missing, the user
// is not an administrator, and requested to abort the installation.
if CurPageID = PageCannotInstall.ID then
begin
if PageCannotInstall.Values[1] = true then
begin
WizardForm.Close;
result := False;
end
else
begin
Log('Non-admin user continues although not all required runtimes are installed.');
end;
end;
if CurPageID = PageInstallInfo.ID then
begin
// Return true if installation succeeds (or no installation required)
result := ExecuteNetSetup and ExecuteVstorSetup;
end;
end; // not PrerequisitesAreMet
end;
/// Skips the folder selection, single/multi user, and ready pages for
/// normal users without power privileges.
/// This function also takes care of dynamically determining what wizard
/// pages to install, depending on the current system setup and whether
/// the current user is an administrator.
function ShouldSkipPage(PageID: Integer): Boolean;
begin
result := False;
if not PrerequisitesAreMet then
begin
// The PageDownloadCannotInstall will only have been initialized if
// PrerequisitesAreMet returned false.
if PageID = PageCannotInstall.ID then
begin
// Skip the warning if the user is an admin.
result := IsAdminLoggedOn
if not result then
begin
Log('Warning user that required runtimes cannot be installed due to missing privileges');
end;
end;
if PageID = PageDownloadInfo.ID then
begin
// Skip page informing about downloads if no files need to be downloaded.
result := idpFilesCount = 0;
end;
if PageID = IDPForm.Page.ID then
begin
// Skip downloader plugin if there are no files to download.
result := idpFilesCount = 0;
if not result then
begin
Log('Beginning download of ' + IntToStr(idpFilesCount) + ' file(s).');
end;
end;
end; // not PrerequisitesAreMet
if PageID = PageSingleOrMultiUser.ID then
begin
if IsOnlyWord2007Installed then
begin
Log('Only Word 2007 appears to be installed on this system.');
if IsHotfixInstalled then
begin
Log('Hotfix KB976477 found; can install for all users.');
end
else
begin
Log('Hotfix KB976477 not found; cannot install for all users.');
end;
end
else
begin
Log('Word 2010 or newer found on this system.');
end;
if CanInstallSystemWide then
begin
Log('Offer installation for all users.');
result := False;
end
else
begin
Log('Offer single-user installation only.');
result := True;
end;
end;
if (PageID = wpSelectDir) or (PageID = wpReady) then
begin
// Do not show the pages to select the target directory, and the ready
// page if the user is not an admin.
result := not IsAdminLoggedOn;
end
end;
/// Helper function that evaluates the custom PageSingleOrMultiUser page.
function IsMultiUserInstall(): Boolean;
begin
result := PageSingleOrMultiUser.Values[1];
end;
/// Suggest an initial target directory depending on whether
/// the installer is run with admin privileges.
function SuggestInstallDir(Param: string): string;
var
dir: string;
begin
if CanInstallSystemWide then
begin
dir := ExpandConstant('{pf}');
end
else
begin
dir := ExpandConstant('{userappdata}');
end;
result := AddBackslash(dir) + 'zaaReloaded';
end;
/// Converts backslashes to forward slashes.
function ConvertSlash(Value: string): string;
begin
StringChangeEx(Value, '\', '/', True);
Result := Value;
end;

View File

@ -368,7 +368,7 @@
<footer class="footer">
<p>
&copy; 2015 <a href="http://www.bovender.de">Daniel Kraus</a>
&copy; 2015-2016 <a href="http://www.bovender.de">Daniel Kraus</a>
<span class="pull-right">
Handarbeit mit
<a href="http://www.vim.org">

View File

@ -1,4 +1,4 @@
2.1.8
http://zaa.nephrowiki.de/downloads/zaaReloaded-$VERSION.exe
8c4cb2782b2e97bfd645ece175878e99e8a56c37 publish/release/zaaReloaded-2.1.8.exe
2.2.5
https://doktorkraus.de/zaareloaded/downloads/zaaReloaded-$VERSION.exe
f5f348b5ffdc532240b63af8fbfd1983219adeee338b9decb3ac3df5f23965ca deploy/releases/zaaReloaded-2.2.5.exe

View File

@ -42,7 +42,7 @@ namespace zaaReloaded2
if (CanFormat())
{
SettingsRepository repository = SettingsRepository.Load();
Guid lastSettingsUid = Properties.Settings.Default.LastSettings;
Guid lastSettingsUid = UserSettings.Default.LastSettings;
Settings lastSettings = repository.FindByGuid(lastSettingsUid);
if (lastSettings != null)
{
@ -72,8 +72,7 @@ namespace zaaReloaded2
SettingsViewModel settingsVM = args.Content.ViewModel as SettingsViewModel;
Settings settings = settingsVM.RevealModelObject() as Settings;
DoFormat(settings);
Properties.Settings.Default.LastSettings = settings.Uid;
Properties.Settings.Default.Save();
UserSettings.Default.LastSettings = settings.Uid;
};
vm.InjectInto<SettingsRepositoryView>().ShowDialog();
}
@ -108,7 +107,7 @@ namespace zaaReloaded2
+ "wenn Word in der Zentralen Arztbriefablage ausgeführt wird.\r"
+ "Bitte Word als eigenständige Anwendung starten und dann "
+ "noch einmal versuchen.";
a.OkButtonLabel = "Schließen";
a.OkButtonText = "Schließen";
a.Invoke();
}
else
@ -127,8 +126,8 @@ namespace zaaReloaded2
public static void ShowPreferences()
{
ViewModels.PreferencesViewModel.Default.InjectInto<Views.PreferencesView>()
.ShowDialog();
ViewModels.PreferencesViewModel vm = new PreferencesViewModel();
vm.InjectInto<Views.PreferencesView>().ShowDialog();
}
public static void ApplyDanielsStyle()
@ -138,6 +137,58 @@ namespace zaaReloaded2
Globals.ThisAddIn.Application.Selection);
}
public static void FormatDrugs(int columns)
{
if (columns < 1 || columns > 2)
{
throw new ArgumentOutOfRangeException("Can only format 1 or 2 columns, not " + columns);
}
// If no "real" selection exists, attempt to auto-detect the drugs section.
// (NB Technically, there is never _no_ selection in a document.)
Word.Window activeWindow = Globals.ThisAddIn.Application.ActiveWindow;
Word.Selection sel = activeWindow.Selection;
Word.Paragraphs paragraphs = sel.Paragraphs;
Word.Document document = activeWindow.Document;
if (!(paragraphs.Count > 1
|| (sel.Text.Length > 1 && sel.Text.EndsWith("\r"))))
{
Logger.Info("FormatDrugs: Attempting to auto-detect");
if (!Medication.Importer.AutoDetect(document))
{
Logger.Info("FormatDrugs: Failed to auto-detect");
NotificationAction a = new NotificationAction();
a.Caption = "Formatieren nicht möglich";
a.Message = "Das Dokument scheint keine Medikationsliste zu enthalten.";
a.OkButtonText = "Schließen";
a.Invoke();
return;
}
}
Logger.Info("FormatDrugs: Importing");
Medication.Importer importer = new Medication.Importer(sel.Text);
Medication.Formatter formatter = new Medication.Formatter(importer.Prescriptions);
Logger.Info("FormatDrugs: Formatting");
switch (columns)
{
case 1:
formatter.FormatOneColumn(document);
break;
case 2:
formatter.FormatTwoColumns(document);
break;
default:
break;
}
Logger.Info("FormatDrugs: Cleaning up");
Bovender.ComHelpers.ReleaseComObject(document);
Bovender.ComHelpers.ReleaseComObject(paragraphs);
Bovender.ComHelpers.ReleaseComObject(sel);
Bovender.ComHelpers.ReleaseComObject(activeWindow);
}
#endregion
#region Private methods
@ -146,57 +197,84 @@ namespace zaaReloaded2
{
// If no "real" selection exists, attempt to auto-detect the lab data.
// (NB Technically, there is never _no_ selection in a document.)
Word.Window activeWindow = Globals.ThisAddIn.Application.ActiveWindow;
Word.Selection sel = activeWindow.Selection;
if (!(sel.Paragraphs.Count > 1
|| (sel.Text.Length > 1 && sel.Text.EndsWith("\r"))))
Word.Application word = Globals.ThisAddIn.Application;
Word.Document activeDocument = word.ActiveDocument;
Word.Window activeWindow = word.ActiveWindow;
Word.Selection selection = activeWindow.Selection;
Word.Paragraphs paragraphs = selection.Paragraphs;
if (!(paragraphs.Count > 1
|| (selection.Text.Length > 1 && selection.Text.EndsWith("\r"))))
{
if (!AutoDetect.Detect(activeWindow.Document))
Logger.Info("DoFormat: Attempting to auto-detect");
Word.Document doc = activeWindow.Document;
if (!AutoDetect.Detect(doc))
{
Logger.Info("DoFormat: Automatic detection failed");
NotificationAction a = new NotificationAction();
a.Caption = "Formatieren nicht möglich";
a.Message = "Das Dokument scheint keine Lauris-Labordaten zu enthalten.";
a.OkButtonLabel = "Schließen";
a.OkButtonText = "Schließen";
a.Invoke();
return;
}
// Don't release the COM object here
// Bovender.ComHelpers.ReleaseComObject(doc);
}
Logger.Info("DoFormat: Importing");
ZaaImporter importer = new ZaaImporter();
importer.Import(Globals.ThisAddIn.Application.ActiveWindow.Selection.Text);
Formatter.Formatter formatter = new Formatter.Formatter(
Globals.ThisAddIn.Application.ActiveDocument);
importer.Import(selection.Text);
Formatter.Formatter formatter = new Formatter.Formatter(activeDocument);
formatter.Settings = settings;
formatter.Laboratory = importer.Laboratory;
CommentPool.Default.Reset();
CommentPool.Default.FillInComment += CommentPool_FillInComment;
try
{
Logger.Info("DoFormat: Formatting");
formatter.Run();
}
catch (NoLaboratoryDataException)
catch (NoLaboratoryDataException e)
{
Logger.Warn("DoFormat: No lab data?!");
Logger.Warn(e);
NotificationAction a = new NotificationAction();
a.Caption = "Formatieren nicht möglich";
a.Message = "Die aktuelle Markierung scheint keine Labordaten zu enthalten.";
a.OkButtonLabel = "Schließen";
a.OkButtonText = "Schließen";
a.Invoke();
}
Bovender.ComHelpers.ReleaseComObject(paragraphs);
Bovender.ComHelpers.ReleaseComObject(selection);
Bovender.ComHelpers.ReleaseComObject(activeWindow);
Bovender.ComHelpers.ReleaseComObject(activeDocument);
Logger.Info("DoFormat: Finished");
}
private static void CommentPool_FillInComment(object sender, ItemCommentEventArgs e)
{
if (Preferences.Default.SuppressItemCommentInteraction)
if (UserSettings.Default.SuppressItemCommentInteraction)
{
Logger.Info("CommentPool_FillInComment: Comment interaction is suppressed by user settings");
e.Comment.IsCancelled = true;
}
else
{
Logger.Info("CommentPool_FillInComment: Requesting user interaction");
ItemCommentViewModel vm = new ItemCommentViewModel(e.Comment);
vm.InjectInto<ItemCommentView>().ShowDialog();
}
}
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -59,7 +59,7 @@ namespace zaaReloaded2.Controller
/// </remarks>
public static SettingsRepository Load()
{
string s = Properties.Settings.Default.SettingsRepository;
string s = UserSettings.Default.SettingsRepository;
if (String.IsNullOrEmpty(s))
{
return new SettingsRepository();
@ -67,7 +67,7 @@ namespace zaaReloaded2.Controller
else
{
MemoryStream stream = new MemoryStream();
string encoded = Properties.Settings.Default.SettingsRepository;
string encoded = UserSettings.Default.SettingsRepository;
byte[] bytes = Convert.FromBase64String(encoded);
stream.Write(bytes, 0, bytes.Length);
stream.Position = 0;
@ -94,8 +94,7 @@ namespace zaaReloaded2.Controller
serializer.Serialize(stream, this);
stream.Position = 0;
string encoded = Convert.ToBase64String(stream.ToArray());
Properties.Settings.Default.SettingsRepository = encoded;
Properties.Settings.Default.Save();
UserSettings.Default.SettingsRepository = encoded;
}
#endregion

View File

@ -3,17 +3,17 @@
<a1:Settings id="ref-1" xmlns:a1="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Uid xsi:type="a2:Guid" xmlns:a2="http://schemas.microsoft.com/clr/ns/System">
<_a>-1270038762</_a>
<_b>9928</_b>
<_c>17935</_c>
<_d>135</_d>
<_e>162</_e>
<_f>115</_f>
<_g>222</_g>
<_h>187</_h>
<_i>100</_i>
<_j>73</_j>
<_k>169</_k>
<_a>-903942278</_a>
<_b>-22298</_b>
<_c>17811</_c>
<_d>139</_d>
<_e>190</_e>
<_f>233</_f>
<_g>83</_g>
<_h>158</_h>
<_i>73</_i>
<_j>21</_j>
<_k>115</_k>
</Uid>
<Name id="ref-3">Kopie von Standard für NepA</Name>
<ReferenceStyle xsi:type="a3:ReferenceStyle" xmlns:a3="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Formatter/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">IfSpecialItem</ReferenceStyle>
@ -66,13 +66,13 @@
<Child16Object href="#ref-25"/>
<Child17Type href="#ref-8"/>
<Child17Object href="#ref-26"/>
<Child18Type href="#ref-27"/>
<Child18Object href="#ref-28"/>
<Child19Type href="#ref-27"/>
<Child18Type href="#ref-8"/>
<Child18Object href="#ref-27"/>
<Child19Type href="#ref-28"/>
<Child19Object href="#ref-29"/>
<Child20Type href="#ref-27"/>
<Child20Type href="#ref-28"/>
<Child20Object href="#ref-30"/>
<Child21Type href="#ref-8"/>
<Child21Type href="#ref-28"/>
<Child21Object href="#ref-31"/>
</a4:SelectEachDay>
<a2:UnitySerializationHolder id="ref-8" xmlns:a2="http://schemas.microsoft.com/clr/ns/System">
@ -90,7 +90,7 @@
</a4:Items>
<a4:Items id="ref-11" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-35">Kardiale Marker: CK, CKMB, hsTnT, NT-proBNP</Content>
<Content id="ref-35">Kardiale Marker: CK, CK-MB, hsTnT, NT-proBNP</Content>
</a4:Items>
<a4:Items id="ref-12" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
@ -102,11 +102,11 @@
</a4:Items>
<a4:Items id="ref-14" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-38">Spot-Urin: U-TPCR, U-ACR, U-Alb, U-Ery, U-Leu, U-Bakt</Content>
<Content id="ref-38">Spot-Urin: U-TPCR, U-ACR, U-Alb, U-Ery, U-Leu, U-Bakt, U-Schwangerschaftstest</Content>
</a4:Items>
<a4:Items id="ref-15" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-39">Leber: GOT, GGT, GPT, AP, Bilirubin, CHE</Content>
<Content id="ref-39">Leber: GOT, GGT, GPT, AP, Bilirubin, CHE, CDT</Content>
</a4:Items>
<a4:Items id="ref-16" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
@ -130,7 +130,7 @@
</a4:Items>
<a4:Items id="ref-21" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-45">Hormone: iPTH, TSH, fT3, fT4</Content>
<Content id="ref-45">Hormone: iPTH, TSH, fT3, fT4, Aldosteron, Renin, ARQ</Content>
</a4:Items>
<a4:Items id="ref-22" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
@ -152,26 +152,26 @@
<Version>2</Version>
<Content id="ref-50">Medikamente: TAC &#34;(Ziel-Talspiegel: &#60;&#62; µg/l)&#34;, CsA (C0) &#34;(Ziel-Talspiegel: &#60;&#62; µg/l)&#34;, SIR &#34;(Ziel-Talspiegel: &#60;&#62; µg/l)&#34;, Vancomycin, Gentamicin, Tobramicin</Content>
</a4:Items>
<a2:UnitySerializationHolder id="ref-27" xmlns:a2="http://schemas.microsoft.com/clr/ns/System">
<Data id="ref-51">zaaReloaded2.Controller.Elements.CustomText</Data>
<a4:Items id="ref-27" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-51">Tumormarker: PSA, AFP</Content>
</a4:Items>
<a2:UnitySerializationHolder id="ref-28" xmlns:a2="http://schemas.microsoft.com/clr/ns/System">
<Data id="ref-52">zaaReloaded2.Controller.Elements.CustomText</Data>
<UnityType>4</UnityType>
<AssemblyName href="#ref-7"/>
</a2:UnitySerializationHolder>
<a4:CustomText id="ref-28" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-52">Nephrolog. Sediment: pH, Proteinurie, Ery /µl, Leu /µl, Plattenep. /µl, Bakt., Schleimfäden</Content>
</a4:CustomText>
<a4:CustomText id="ref-29" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-53">Virologie (EDTA-Blut): CMV-PCR, BKV-PCR</Content>
<Content id="ref-53">Nephrolog. Sediment: pH, Proteinurie, Ery /µl, Leu /µl, Plattenep. /µl, Bakt., Schleimfäden</Content>
</a4:CustomText>
<a4:CustomText id="ref-30" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-54">Autoantikörper: ANCA (IF), MPO-ANCA (ELISA), PR3-ANCA (ELISA), ANA (IF), AnDNA (ELISA), AnDNA (RIA)</Content>
<Content id="ref-54">Virologie (EDTA-Blut): CMV-PCR, BKV-PCR</Content>
</a4:CustomText>
<a4:Items id="ref-31" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<a4:CustomText id="ref-31" xmlns:a4="http://schemas.microsoft.com/clr/nsassem/zaaReloaded2.Controller.Elements/zaaReloaded2%2C%20Version%3D1.0.0.0%2C%20Culture%3Dneutral%2C%20PublicKeyToken%3D6ec8d075a1ab1383">
<Version>2</Version>
<Content id="ref-55">Tumormarker: PSA, AFP</Content>
</a4:Items>
<Content id="ref-55">Autoantikörper: ANCA (IF) 1: (Ref. &#60; 1:40), MPO-ANCA (ELISA) IU/ml (Ref. &#60; 9), PR3-ANCA (ELISA) IU/ml (Ref. &#60; 3,5), ANA (IF), AnDNA (ELISA), AnDNA (RIA)</Content>
</a4:CustomText>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>

View File

@ -10,6 +10,8 @@ Albumin Alb S
"Albumin (SU)/die" Alb SU
"Albumin - Fraktion" Albumin-Fraktion S --- X
"Albumin/Creatinin (PU)" ACR U 0
Aldosteron Aldosteron S --- X
Aldosteron-Renin-Quotient ARQ S --- X
"Alk. Phosphatase" AP S 0
"Alpha1-Globulin - Fraktion" a1-Globulin S --- X
"Alpha2-Globulin - Fraktion" a2-Globulin S --- X
@ -79,12 +81,14 @@ Kalium K S
"Kalium (SU)" K U
"Kalium (SU)/die" K SU
"Ketonkörper (U)" KK U
"kohlenhyd. def. Transferrin" CDT S 1 X
"Komplementfaktor C3c" C3c S --- X
"Komplementfaktor C4" C4 S --- X
"Lactat Dehydrogenase" LDH S
"LDL - Cholesterin" LDL S
Leukozyten Leu E
"Leukozyten (U)" Leu U
"Lipoprotein (a) (Gen. 2)" Lp(a) S 0 X
Lymphozyten Lym E
Magnesium Mg S --- X
"MCH (HbE)" MCH E 0
@ -105,14 +109,16 @@ pH pH BGA
"Plattenepithelien (U)" Plattenep U
"PO2 (art.)" pO2 BGA
"Protein (U)" Protein U
"PSA ges. (ECL,Elecsys,Roche)" PSA S --- X
"PSA ges. (ECL,Elecsys,Roche)" PSA S --- X
"PTH intakt" iPTH S
PTT PTT Z
"Ratio int. norm." INR Z
Plasma-Renin-Konzentration Renin S --- X
Retikulozyten Retikulozyten E --- X
"Sammelmenge (U)" Volumen SU
"Sammelzeit (U)" Zeit SU
"Sauerstoffsättigung (art.)" SO2 BGA
"Schwangerschaftstest (U)" Schwangerschaftstest U
Sirolimus SIR S
"spezifisches Gewicht (U)" "spez. Gew." U
"Standard Bicarbonat" "Std.-Bic." BGA

Binary file not shown.

View File

@ -48,7 +48,7 @@ namespace zaaReloaded2.ExceptionHandler
{
get
{
return zaaReloaded2.Updater.Version.CurrentVersion().ToString();
return zaaReloaded2.Updater.Version.Current.ToString();
}
}
@ -86,6 +86,11 @@ namespace zaaReloaded2.ExceptionHandler
return @"x:\Code\zaaReloaded2\zaaReloaded2\";
}
protected override Bovender.UserSettings.UserSettingsBase UserSettings
{
get { return zaaReloaded2.UserSettings.Default; }
}
#endregion
}
}

View File

@ -171,6 +171,14 @@ namespace zaaReloaded2.Formatter
_buffer.AppendLine(text);
}
/// <summary>
/// Appends a newline to the buffer.
/// </summary>
public void WriteLine()
{
_buffer.AppendLine();
}
/// <summary>
/// Inserts text at the start of the buffer.
/// </summary>

View File

@ -142,13 +142,7 @@ namespace zaaReloaded2.Formatter
// Create undo record and styles prior to iterating over the elements
// because a column switching element might trigger output to the
// document.
bool hasAddin = Globals.ThisAddIn != null;
if (hasAddin)
{
Globals.ThisAddIn.Application.UndoRecord.StartCustomRecord(
String.Format("Laborformatierung ({0})", Properties.Settings.Default.AddinName)
);
}
Helpers.StartUndo("Laborformatierung");
CreateStyles();
int current = 0;
@ -177,10 +171,7 @@ namespace zaaReloaded2.Formatter
}
_secondaryBuffer.Flush();
if (hasAddin)
{
Globals.ThisAddIn.Application.UndoRecord.EndCustomRecord();
}
Helpers.EndUndo();
}
/// <summary>
@ -281,15 +272,18 @@ namespace zaaReloaded2.Formatter
{
if (Document != null)
{
Logger.Info("CreateStyles");
Style style;
// Don't see a better way to check for the existence of a particular
// paragraph style than by using a try...catch construction.
try
{
style = Document.Styles[Properties.Settings.Default.StyleParagraph];
Logger.Info("CreateStyles: Found paragraph style in document");
}
catch
{
Logger.Info("CreateStyles: Need to create paragraph style");
// Add default paragraph style for laboratory
style = Document.Styles.Add(Properties.Settings.Default.StyleParagraph);
style.Font.Size = 10; // pt
@ -302,13 +296,16 @@ namespace zaaReloaded2.Formatter
style.ParagraphFormat.FirstLineIndent = -36; // pt
style.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphJustify;
}
Bovender.ComHelpers.ReleaseComObject(style);
try
{
style = Document.Styles[Properties.Settings.Default.StyleHeader];
Logger.Info("CreateStyles: Found header style in document");
}
catch
{
Logger.Info("CreateStyles: Need to create header style");
// Add header paragraph style for laboratory
style = Document.Styles.Add(Properties.Settings.Default.StyleHeader);
style.Font.Size = 10; // pt
@ -322,6 +319,7 @@ namespace zaaReloaded2.Formatter
style.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphJustify;
style.set_NextParagraphStyle(Document.Styles[Properties.Settings.Default.StyleParagraph]);
}
Bovender.ComHelpers.ReleaseComObject(style);
/*
try
@ -431,5 +429,13 @@ namespace zaaReloaded2.Formatter
Table _table;
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

69
zaaReloaded2/Helpers.cs Executable file
View File

@ -0,0 +1,69 @@
/* Helpers.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
namespace zaaReloaded2
{
/// <summary>
/// Common helper methods.
/// </summary>
public static class Helpers
{
/// <summary>
/// Splits a text into paragraphs.
/// </summary>
/// <param name="paragraph">Text to split.</param>
/// <returns>Array of paragraphs in the text.</returns>
/// <remarks>
/// This implementation relies on the fact that the order of
/// splitting strings in C#'s String.Split() method is
/// important; see http://stackoverflow.com/a/8664639/270712
/// </remarks>
public static string[] SplitParagraphs(string text)
{
return text.Split(
new string[] { "\r\n", "\n\r", "\r", "\n" },
StringSplitOptions.RemoveEmptyEntries);
}
/// <summary>
/// Starts a custom undo record.
/// </summary>
/// <param name="message"></param>
public static void StartUndo(string message)
{
if (Globals.ThisAddIn != null)
{
Globals.ThisAddIn.Application.UndoRecord.StartCustomRecord(
String.Format("{0} ({1})", message, Properties.Settings.Default.AddinName)
);
}
}
/// <summary>
/// Ends an undo record.
/// </summary>
public static void EndUndo()
{
if (Globals.ThisAddIn != null)
{
Globals.ThisAddIn.Application.UndoRecord.EndCustomRecord();
}
}
}
}

BIN
zaaReloaded2/Icons/m.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 778 B

BIN
zaaReloaded2/Icons/mm.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 723 B

View File

@ -103,14 +103,17 @@ namespace zaaReloaded2.Importer.ZaaImporter
// "HBs-Antigen: neg. ;"
// "Erythrozyten (U): + [negativ]"
Match match;
Logger.Debug("ParseLauris: {0}", LaurisText);
if (_numericalRegex.IsMatch(LaurisText))
{
Logger.Debug("ParseLauris: Numerical match");
match = _numericalRegex.Match(LaurisText);
ParseLimits(match);
Value = match.Groups["value"].Value.Trim().Replace(',', '.');
}
else
{
Logger.Debug("ParseLauris: Not a numerical match");
match = _categoricalRegex.Match(LaurisText);
Normal = match.Groups["normal"].Value.Trim();
Value = match.Groups["value"].Value.Trim();
@ -120,6 +123,11 @@ namespace zaaReloaded2.Importer.ZaaImporter
OriginalName = match.Groups["name"].Value.Trim();
Name = OriginalName;
Unit = match.Groups["unit"].Value.Trim();
Logger.Debug("ParseLauris: Match: {0}, {1}", Name, Unit);
}
else
{
Logger.Debug("ParseLauris: No match: \"{0}\"", LaurisText);
}
}
@ -132,9 +140,11 @@ namespace zaaReloaded2.Importer.ZaaImporter
{
if (match.Groups["limits"].Success)
{
Logger.Debug("ParseLimits: Has limits: {0}", match.Groups["limits"].Value);
Match limitMatch = _limitRegex.Match(match.Groups["limits"].Value);
if (limitMatch.Groups["limit1"].Success && limitMatch.Groups["limit2"].Success)
{
Logger.Debug("ParseLimits: Upper and lower limit detected");
// Use InvariantCulture because Lauris always outputs dots as decimal separator
// Only in rare cases, a comma sneaks in...
LowerLimit = Double.Parse(limitMatch.Groups["limit1"].Value.Replace(',', '.'),
@ -144,6 +154,7 @@ namespace zaaReloaded2.Importer.ZaaImporter
}
else
{
Logger.Debug("ParseLimits: Single limit detected");
switch (limitMatch.Groups["operator"].Value.Trim())
{
case "<=":
@ -159,9 +170,9 @@ namespace zaaReloaded2.Importer.ZaaImporter
// Fixes exception ID 65ca8575.
break;
default:
throw new InvalidOperationException(
String.Format("Unknown operator in {0}",
match.Groups["limits"].Value));
string unknown = match.Groups["limits"].Value;
Logger.Fatal("ParseLimits: Unknown operator \"{0}\"", unknown);
throw new InvalidOperationException(String.Format("Unknown operator in {0}",unknown));
}
}
}
@ -210,5 +221,13 @@ namespace zaaReloaded2.Importer.ZaaImporter
static readonly Regex _materialRegex = new Regex(@"\((?<material>(SU|PU))\)");
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -23,6 +23,7 @@ using System.Text;
using System.Text.RegularExpressions;
using zaaReloaded2.Thesaurus;
using zaaReloaded2.LabModel;
using Bovender.Extensions;
namespace zaaReloaded2.Importer.ZaaImporter
{
@ -109,9 +110,11 @@ namespace zaaReloaded2.Importer.ZaaImporter
/// </summary>
void Parse()
{
Logger.Info("Parse: \"{0}\"", OriginalParagraph.TruncateWithEllipsis(40));
Match m = _expectedFormat.Match(OriginalParagraph);
if (m.Success)
{
Logger.Info("Parse: Matches Lauris paragraph format");
Items = new ItemDictionary();
if (m.Groups["caption"].Success)
{
@ -127,6 +130,7 @@ namespace zaaReloaded2.Importer.ZaaImporter
}
else
{
Logger.Info("Parse: Does not match Lauris paragraph format");
IsLaurisParagraph = false;
}
}
@ -140,5 +144,13 @@ namespace zaaReloaded2.Importer.ZaaImporter
Thesaurus.Units _unitDictionary;
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -199,6 +199,7 @@ namespace zaaReloaded2.Importer.ZaaImporter
Match m = _timeStampRegex.Match(paragraph);
if (m.Success)
{
Logger.Info("ParseParagraph: Matches time stamp");
DateTime dt;
if (DateTime.TryParseExact(
m.Groups["datetime"].Value,
@ -218,22 +219,25 @@ namespace zaaReloaded2.Importer.ZaaImporter
// the normal format of a paragraph generated from Lauris.
if (m.Groups["tail"].Success)
{
Logger.Info("ParseParagraph: Time stamp has a tail -- putting it back with a dummy caption");
paragraph = "DUMMY CAPTION: " + m.Groups["tail"].Value;
}
else
{
paragraph = String.Empty;
paragraph = null;
}
}
if (!String.IsNullOrEmpty(paragraph))
{
Logger.Info("ParseParagraph: Not a time stamp");
LaurisParagraph lp = new LaurisParagraph(
paragraph,
_parameterDictionary,
_unitDictionary);
if (lp.IsLaurisParagraph)
{
Logger.Debug("ParseParagraph: Merging Lauris paragraph");
Items.Merge(lp.Items);
}
}
@ -259,5 +263,13 @@ namespace zaaReloaded2.Importer.ZaaImporter
Units _unitDictionary;
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -67,20 +67,19 @@ namespace zaaReloaded2.Importer.ZaaImporter
/// <param name="text">ZAA-formatted Lauris output to import.</param>
public void Import(string text)
{
// Split the text into parargraphs. This implementation relies on the fact
// that the order or splitting strings in C#'s String.Split() method is
// important; see http://stackoverflow.com/a/8664639/270712
string[] paragraphs = text.Split(
new string[] { "\r\n", "\n\r", "\r", "\n" },
StringSplitOptions.RemoveEmptyEntries);
Logger.Info("Import: \"{0}\"", text.TruncateWithEllipsis(120));
string[] paragraphs = Helpers.SplitParagraphs(text);
Logger.Info("Import: {0} paragraph(s)", paragraphs.Length);
LaurisTimePoint timePoint = null;
foreach (string paragraph in paragraphs)
{
Logger.Info("Import: \"{0}\"", paragraph.TruncateWithEllipsis(40));
// If the current paragraph looks like a Lauris time stamp,
// create a new time point.
if (LaurisTimePoint.IsTimeStampLine(paragraph))
{
Logger.Info("Import: Time stamp detected", paragraph);
timePoint = new LaurisTimePoint(paragraph, _parameters, _units);
// Add the time point to the laboratory only if none
// with the same time stamp exists yet.
@ -99,6 +98,7 @@ namespace zaaReloaded2.Importer.ZaaImporter
// if no time point exists yet, create one.
else if (LaurisParagraph.ResemblesLaurisParagraph(paragraph))
{
Logger.Info("Import: Lauris paragraph detected");
if (timePoint == null)
{
timePoint = new LaurisTimePoint(_parameters, _units);
@ -106,6 +106,10 @@ namespace zaaReloaded2.Importer.ZaaImporter
}
timePoint.AddParagraph(paragraph);
}
else
{
Logger.Debug("Import: Neither time stamp, nor Lauris paragraph");
}
}
}
@ -128,5 +132,13 @@ namespace zaaReloaded2.Importer.ZaaImporter
Units _units;
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -206,13 +206,14 @@ namespace zaaReloaded2.LabModel
{
get
{
if (Material == LabModel.Material.B)
switch (Material)
{
return Name;
}
else
{
return String.Format("{0}-{1}", Material.ToString(), Name);
case Material.S:
case Material.E:
case Material.B:
return Name;
default:
return String.Format("{0}-{1}", Material.ToString(), Name);
}
}
}

View File

@ -28,6 +28,12 @@ namespace zaaReloaded2.LabModel
/// </summary>
public enum Material
{
[Description("Serum")]
/// Serum (default -- first declared)
S,
[Description("EDTA-Blut")]
/// EDTA blood
E,
[Description("Blut")]
/// Blood
B,

109
zaaReloaded2/LogFile.cs Executable file
View File

@ -0,0 +1,109 @@
/* LogFile.cs
* part of zaaReloaded2
*
* Copyright 2016 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NLog;
using NLog.Config;
using NLog.Targets;
using NLog.Targets.Wrappers;
namespace zaaReloaded2
{
/// <summary>
/// Provides logging to file and to the debug console; wraps
/// NLog configuration and targets.
/// </summary>
public class LogFile : Bovender.Logging.LogFile
{
#region Singleton
new public static LogFile Default { get { return _lazy.Value; } }
private static readonly Lazy<LogFile> _lazy = new Lazy<LogFile>(
() =>
{
LogFile logFile = new LogFile();
Bovender.Logging.LogFile.LogFileProvider = new Func<Bovender.Logging.LogFile>(() => logFile);
return logFile;
});
#endregion
#region Static properties
/// <summary>
/// Gets whether file logging is enabled, without initializing
/// the singleton instance if it isn't.
/// </summary>
new public static bool IsInitializedAndEnabled
{
get
{
return _lazy.IsValueCreated && Default.IsFileLoggingEnabled;
}
}
#endregion
#region Properties
/// <summary>
/// Gets the folder where log files are stored.
/// </summary>
public override string LogFolder
{
get
{
if (_logFolder == null)
{
_logFolder = System.IO.Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
Properties.Settings.Default.AppDataFolder,
Properties.Settings.Default.UserFolder);
}
return _logFolder;
}
}
#endregion
#region Constructor
private LogFile()
: base()
{ }
#endregion
#region Private fields
string _logFolder;
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -0,0 +1,210 @@
using Microsoft.Office.Interop.Word;
/* Formatter.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace zaaReloaded2.Medication
{
/// <summary>
/// Formats prescriptions
/// </summary>
public class Formatter
{
#region Properties
public IList<Prescription> Prescriptions { get; set; }
#endregion
#region Constructor
public Formatter() { }
public Formatter(IList<Prescription> prescriptions)
: this()
{
Prescriptions = prescriptions;
}
#endregion
#region Methods
/// <summary>
/// Writes a block of prescriptions with one column to a
/// Word document.
/// </summary>
/// <param name="document"></param>
public void FormatOneColumn(Document document)
{
DoFormat("Medikation einspaltig formatieren",
document,
writer =>
{
foreach (Prescription p in Prescriptions)
{
writer.WriteLine(p.ToString());
}
});
}
/// <summary>
/// Writes a block of prescriptions with two columns to a
/// Word document.
/// </summary>
/// <param name="document"></param>
public void FormatTwoColumns(Document document)
{
DoFormat("Medikation zweispaltig formatieren",
document,
writer =>
{
int half = Prescriptions.Count / 2 + Prescriptions.Count % 2;
for (int i = 0; i < half; i++)
{
writer.Write(Prescriptions[i].ToString());
if (i + half < Prescriptions.Count)
{
writer.Write("\t" + Prescriptions[i + half].ToString());
}
writer.WriteLine();
}
});
}
/// <summary>
/// Creates a table containing all prescriptions and copies it to
/// the clipboard.
/// </summary>
public void CreatePrescriptionsTable()
{
throw new NotImplementedException();
}
#endregion
#region Private methods
void AddDisclaimer(zaaReloaded2.Formatter.DocumentWriter writer)
{
if (HasMMF())
{
writer.WriteLine();
writer.WriteLine("<b>Hinweis: Während und nach Therapie mit Mycophenolsäurederivaten wie CellCept\u00ae " +
"und Myfortic\u00ae müssen Frauen und Männer eine Schwangerschaft sicher verhüten (siehe Rote-Hand-Brief zu " +
"CellCept\u00ae vom 10.11.2015).</b>");
writer.WriteLine();
}
writer.WriteLine("<highlight><b>Bitte Medikation überprüfen!</b></highlight>");
}
/// <summary>
/// Creates a paragraph and character styles in the document.
/// </summary>
void CreateStyles(Document document)
{
if (document != null)
{
Style style;
// Don't see a better way to check for the existence of a particular
// paragraph style than by using a try...catch construction.
try
{
style = document.Styles[Properties.Settings.Default.DrugsParagraph];
}
catch
{
// Add default paragraph style for laboratory
style = document.Styles.Add(Properties.Settings.Default.DrugsParagraph);
style.Font.Size = 10; // pt
style.Font.Bold = 0;
style.Font.Italic = 0;
style.Font.Underline = 0;
style.ParagraphFormat.SpaceAfter = 0;
style.ParagraphFormat.SpaceBefore = 0;
style.ParagraphFormat.LeftIndent = 0; // pt
style.ParagraphFormat.FirstLineIndent = 0; // pt
style.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphLeft;
style.ParagraphFormat.TabStops.ClearAll();
int tabStop = 108; // 108 pt = 2.5 in = 3.8 cm
int halfWay = 227; // 227 pt = 3.15 in = 8 cm
style.ParagraphFormat.TabStops.Add(tabStop);
style.ParagraphFormat.TabStops.Add(halfWay);
style.ParagraphFormat.TabStops.Add(halfWay + tabStop);
}
// try
// {
// style = document.Styles[Properties.Settings.Default.DrugsHeader];
// }
// catch
// {
// // Add header paragraph style for laboratory
// style = document.Styles.Add(Properties.Settings.Default.DrugsHeader);
// style.Font.Size = 10; // pt
// style.Font.Bold = 1;
// style.Font.Italic = 0;
// style.Font.Underline = WdUnderline.wdUnderlineSingle;
// style.ParagraphFormat.SpaceAfter = 0;
// style.ParagraphFormat.SpaceBefore = 12;
// style.ParagraphFormat.LeftIndent = 36; // pt
// style.ParagraphFormat.FirstLineIndent = -36; // pt
// style.ParagraphFormat.Alignment = WdParagraphAlignment.wdAlignParagraphJustify;
// style.set_NextParagraphStyle(document.Styles[Properties.Settings.Default.DrugsParagraph]);
// }
}
}
/// <summary>
/// Does the heavy lifting in a DRY way.
/// </summary>
void DoFormat(string description, Document document,
Action<zaaReloaded2.Formatter.DocumentWriter> outputAction)
{
if (document == null)
{
throw new ArgumentNullException(
"Cannot format prescriptions because no document was given.");
}
Helpers.StartUndo(description);
zaaReloaded2.Formatter.DocumentWriter writer = new zaaReloaded2.Formatter.DocumentWriter(document);
CreateStyles(document);
writer.Write(String.Format("<style:{0}>", Properties.Settings.Default.DrugsParagraph));
outputAction(writer);
AddDisclaimer(writer);
// writer.Write("</style>"); // causes COM exceptions, needs fix
writer.Flush();
Helpers.EndUndo();
}
/// <summary>
/// Determines whether MMF or MPA is contained in the prescriptions.
/// </summary>
/// <returns>True if MMF or MPA is prescribed.</returns>
bool HasMMF()
{
return Prescriptions.FirstOrDefault(p => p.IsMmf) != null;
}
#endregion
}
}

View File

@ -0,0 +1,208 @@
using Microsoft.Office.Interop.Word;
/* Importer.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace zaaReloaded2.Medication
{
/// <summary>
/// Imports prescriptions from a physician's letter.
/// </summary>
public class Importer
{
#region Static methods
/// <summary>
/// Attempts to automatically detect a block of prescriptions
/// in a document. The document is screened from end to start.
/// The detected block is selected.
/// </summary>
/// <returns>True if a block was detected, false if not.</returns>
/// <remarks>
/// <para>
/// Autodetection works by examining the document paragraph by
/// paragraph, starting at the end of the document. The first
/// block of at least two lines that are identified as prescription
/// lines is selected.
/// </para>
/// <para>
/// It should be noted that every paragraph (a.k.a. line) may
/// be regarded as one of three things:
/// </para>
/// <list type="ol">
/// <item>A typical prescription line (in the form "Ramipril 5 mg 1-0-0")</item>
/// <item>A typical non-prescription text line</item>
/// <item>Something inbetween, e.g. a line with tab stops as in
/// "Ramipril 5 mg \t alle zwei Tage" or in "Prof. B. Oss \t Dr. A. Sistent"
/// </item>
/// </list>
/// <para>
/// It is the third type of line that may cause confusion. If such a line
/// is encountered at the start of a putative block of prescriptions, we
/// therefore enter a "fuzzy" state in the detection algorithm and take
/// it from there, i.e. disregard the block if there are no lines that
/// are clearly prescriptions lines, or accept the block if we do detect
/// adjacent lines with unequivocal prescriptions.
/// </para>
///
/// </remarks>
public static bool AutoDetect(Document document)
{
Paragraph start = null;
Paragraph end = null;
bool insideBlock = false;
bool fuzzy = false;
bool result = false;
int i = document.Paragraphs.Count;
while (i > 1)
{
string line = document.Paragraphs[i].Range.Text;
if (Prescription.IsCanonicalPrescriptionLine(line))
{
// The current line is unequivocally a prescription line:
// If we're not inside a block already, mark the bottom
// of the block.
// If we are inside a block already, make sure to leave
// the 'fuzzy' state because this clearly now is a prescription
// block.
if (insideBlock)
{
fuzzy = false;
}
else
{
end = document.Paragraphs[i];
insideBlock = true;
}
}
else if (Prescription.IsPotentialPrescriptionLine(line))
{
// The current line is a putative prescription line:
// If we're not inside a block already, enter the
// "fuzzy" state.
// If we are inside a block, no special action is
// needed, we can continue with the next paragraph.
if (!insideBlock)
{
fuzzy = true;
insideBlock = true;
end = document.Paragraphs[i];
}
}
else
{
// The current line is not a prescription line:
// If we are currently in a definitive block of prescriptions,
// mark the line below the current line as the start of the block.
// If we're in a putative block, discard the information
// about the bottom end of the block and reset all flags.
if (insideBlock)
{
if (!fuzzy)
{
start = document.Paragraphs[i + 1];
break;
}
else
{
fuzzy = false;
insideBlock = false;
end = null;
}
}
}
i--;
}
if (end != null)
{
// If we don't have a start paragraph,
// but do have an end paragraph, we set the start paragraph to the
// first paragraph of the document.
if (start == null)
{
start = document.Paragraphs[1];
}
document.Range(start.Range.Start, end.Range.End).Select();
result = true;
}
return result;
}
#endregion
#region Properties
public List<Prescription> Prescriptions { get; protected set; }
#endregion
#region Constructor
public Importer() { }
public Importer(string text)
: this()
{
Import(text);
}
#endregion
#region Private methods
protected virtual void Import(string text)
{
List<Prescription> list = new List<Prescription>();
IList<Prescription> addition;
int columns = 1;
string[] lines = Helpers.SplitParagraphs(text);
foreach (string line in lines)
{
if (Prescription.IsPotentialPrescriptionLine(line))
{
addition = Prescription.ManyFromLine(line);
columns = System.Math.Max(columns, addition.Count);
list.AddRange(addition);
}
}
// If the input had several columns, sort the prescriptions by
// column.
// TODO: Make this more generic so it works with 3 or 4 columns as well.
if (columns == 2)
{
var firstCol = list.Where((item, index) => index % 2 == 0);
var secondCol = list.Where((item, index) => index % 2 != 0);
Prescriptions = firstCol.Concat(secondCol).ToList();
}
else
{
Prescriptions = list;
}
}
#endregion
}
}

View File

@ -0,0 +1,273 @@
/* Prescription.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
namespace zaaReloaded2.Medication
{
/// <summary>
/// Represents a prescription
/// </summary>
public class Prescription
{
#region Static methods
/// <summary>
/// Determines whether a line contains prescriptions.
/// </summary>
/// <param name="line">Line to inspect.</param>
/// <returns>True if the line contains prescriptions.</returns>
public static bool IsCanonicalPrescriptionLine(string line)
{
return canonicalRegex.IsMatch(line);
}
/// <summary>
/// Determines if a line contains prescriptions, either canonical
/// ones or alternative ones (in the form "Ramipril 5 mg \t alle 2 Tage").
/// </summary>
/// <param name="line">Line to examine.</param>
/// <returns>True if the line potentially contains prescriptions.</returns>
public static bool IsPotentialPrescriptionLine(string line)
{
return unifiedRegex.IsMatch(line);
}
#endregion
#region Factory
/// <summary>
/// Creates a new Prescription object by parsing a line (e.g.,
/// from a physician's letter).
/// </summary>
/// <param name="line">Line to parse</param>
/// <returns>Prescription created from the <paramref name="Line"/></returns>
public static Prescription FromLine(string line)
{
// Replace any runs of whitespace with a single space
// (from http://stackoverflow.com/a/206946/270712)
// line = Regex.Replace(line, @"\s+", " ");
Match m = unifiedRegex.Match(line);
int n = m.Groups[DOSE_GROUP].Captures.Count;
return new Prescription(
spaceRegex.Replace(m.Groups["drug"].Value, " "),
n > 0 ? m.Groups[DOSE_GROUP].Captures[0].Value : String.Empty,
n > 1 ? m.Groups[DOSE_GROUP].Captures[1].Value : String.Empty,
n > 2 ? m.Groups[DOSE_GROUP].Captures[2].Value : String.Empty,
n > 3 ? m.Groups[DOSE_GROUP].Captures[3].Value : String.Empty,
m.Groups["comment"].Value
);
}
/// <summary>
/// Extracts several prescriptions from a given line.
/// </summary>
/// <param name="line">Line that contains several prescriptions.</param>
/// <returns>Enumerable with <see cref="Prescription"/>s.</returns>
public static IList<Prescription> ManyFromLine(string line)
{
// line = Regex.Replace(line, @"\s+", " ");
MatchCollection mc = unifiedRegex.Matches(line);
List<Prescription> list = new List<Prescription>();
foreach (Match m in mc)
{
int n = m.Groups[DOSE_GROUP].Captures.Count;
list.Add(new Prescription(
spaceRegex.Replace(m.Groups["drug"].Value, " "),
n > 0 ? m.Groups[DOSE_GROUP].Captures[0].Value : String.Empty,
n > 1 ? m.Groups[DOSE_GROUP].Captures[1].Value : String.Empty,
n > 2 ? m.Groups[DOSE_GROUP].Captures[2].Value : String.Empty,
n > 3 ? m.Groups[DOSE_GROUP].Captures[3].Value : String.Empty,
m.Groups["comment"].Value
)
);
}
return list;
}
#endregion
#region Properties
public string Drug { get; set; }
public string Morning { get; set; }
public string Noon { get; set; }
public string Evening { get; set; }
public string Night { get; set; }
public string Comment { get; set; }
/// <summary>
/// Determines whether the drug is MMF or a derivative.
/// </summary>
public bool IsMmf
{
get
{
string d = Drug.ToLower();
return
d.StartsWith("mmf") ||
d.StartsWith("cellcept") ||
d.StartsWith("cell cept") ||
d.StartsWith("myfortic") ||
d.StartsWith("mycophenol");
}
}
#endregion
#region Overrides
public override string ToString()
{
string s = Drug + "\t";
if (!String.IsNullOrEmpty(Morning))
{
s += Morning;
}
else
{
if (!(String.IsNullOrEmpty(Noon) && String.IsNullOrEmpty(Evening) &&
String.IsNullOrEmpty(Night)))
{
s += "0";
}
}
if (!String.IsNullOrEmpty(Noon))
{
s += "-" + Noon;
}
else
{
if (!(String.IsNullOrEmpty(Evening) && String.IsNullOrEmpty(Night)))
{
s += "-0";
}
}
if (!String.IsNullOrEmpty(Evening))
{
s += "-" + Evening;
}
else
{
if (!String.IsNullOrEmpty(Night))
{
s += "-0";
}
}
if (!String.IsNullOrEmpty(Night))
{
s += "-" + Night;
}
if (!String.IsNullOrEmpty(Comment))
{
if (!s.EndsWith("\t"))
{
s += " ";
}
s += Comment;
}
return s;
}
#endregion
#region Constructors
public Prescription() { }
public Prescription(string drug)
: this()
{
Drug = drug.Trim();
}
public Prescription(string drug, string morning, string noon,
string evening, string night)
: this(drug)
{
Morning = morning.Trim();
Noon = noon.Trim();
Evening = evening.Trim();
Night = night.Trim();
}
public Prescription(string drug, string morning, string noon,
string evening, string night, string comment)
: this(drug, morning, noon, evening, night)
{
Comment = comment.Trim();
}
#endregion
#region Fields
private const string DOSE_GROUP = "dose";
private const string DOSE = @"(\d\s+1/[234]|(\d\s?)?[\u00bd\u2153\u00bc]|\d+)";
private const string SPACER = @"(\s*[-\u2012\u2013\u2014]+\s*)";
/// <summary>
/// The 'canonical' regex matches a prescription the form "Ramipril 5 mg 1-0-0"
/// with or without trailing comment.
/// </summary>
/// <remarks>
/// Enclose entire regular expression in parentheses so we can use it
/// with or without trailing comment.
/// </remarks>
private const string canonicalPattern =
@"((?<drug>[^\t]+)\s+" +
@"(?<dose>" + DOSE + @")" + SPACER +
@"(?<dose>" + DOSE + @")" + SPACER +
@"(?<dose>" + DOSE + @")" +
@"(" + SPACER + @"(?<dose>" + DOSE + @"))?" +
@"( +(?<comment>[^\t]+))?\s*)";
private static readonly Regex canonicalRegex = new Regex(canonicalPattern);
/// <summary>
/// The 'alternative' regex matches prescriptions that do not contain regular
/// dosing intervals ("1-0-0"), but free-style comments: "Cotrim forte alle 2 Tage".
/// </summary>
/// <remarks>
/// Because this alternative pattern matches other lines as well (e.g. with
/// signature names), it requires special handling.
/// </remarks>
private const string alternativePattern =
@"((?<drug>[^\t]+)( +|\t+)(?<comment>[^\t]+))";
private static readonly Regex alternativeRegex = new Regex(alternativePattern);
private static readonly Regex unifiedRegex = new Regex(
"(" + canonicalPattern + "|" + alternativePattern + ")");
/// <summary>
/// A 'cached', reusable regex to match several whitespace characters.
/// </summary>
private static readonly Regex spaceRegex = new Regex(@"\s+");
#endregion
}
}

View File

@ -1,73 +0,0 @@
/* Preferences.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace zaaReloaded2
{
/// <summary>
/// Holds user preferences.
/// </summary>
public class Preferences
{
#region Singleton
public static Preferences Default
{
get
{
return _instance;
}
}
static readonly Preferences _instance = new Preferences();
static Preferences() { }
#endregion
#region Properties
/// <summary>
/// Gets or sets whether the add-in should not ask for
/// item comments (i.e. typist mode).
/// </summary>
public bool SuppressItemCommentInteraction
{
get
{
return Properties.Settings.Default.SuppressItemCommentInteraction;
}
set
{
Properties.Settings.Default.SuppressItemCommentInteraction = value;
Properties.Settings.Default.Save();
}
}
#endregion
#region Constructors
protected Preferences() { }
#endregion
}
}

View File

@ -23,18 +23,6 @@ namespace zaaReloaded2.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string SettingsRepository {
get {
return ((string)(this["SettingsRepository"]));
}
set {
this["SettingsRepository"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("zaaReloaded2")]
@ -46,7 +34,7 @@ namespace zaaReloaded2.Properties {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("2015")]
[global::System.Configuration.DefaultSettingValueAttribute("2016")]
public string PubYear {
get {
return ((string)(this["PubYear"]));
@ -64,7 +52,7 @@ namespace zaaReloaded2.Properties {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("http://zaa.nephrowiki.de")]
[global::System.Configuration.DefaultSettingValueAttribute("https://doktorkraus.de/zaareloaded")]
public global::System.Uri Homepage {
get {
return ((global::System.Uri)(this["Homepage"]));
@ -73,7 +61,7 @@ namespace zaaReloaded2.Properties {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("http://zaa.nephrowiki.de/versioninfo.txt")]
[global::System.Configuration.DefaultSettingValueAttribute("https://doktorkraus.de/zaareloaded/versioninfo.txt")]
public string VersionInfoFile {
get {
return ((string)(this["VersionInfoFile"]));
@ -82,24 +70,13 @@ namespace zaaReloaded2.Properties {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("http://zaa.nephrowiki.de/postreport.php")]
[global::System.Configuration.DefaultSettingValueAttribute("https://doktorkraus.de/zaareloaded/postreport.php")]
public string ExceptionPostUrl {
get {
return ((string)(this["ExceptionPostUrl"]));
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
public global::System.DateTime LastUpdateCheck {
get {
return ((global::System.DateTime)(this["LastUpdateCheck"]));
}
set {
this["LastUpdateCheck"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("http://www.apache.org/licenses/LICENSE-2.0")]
@ -127,18 +104,6 @@ namespace zaaReloaded2.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("00000000-0000-0000-0000-000000000000")]
public global::System.Guid LastSettings {
get {
return ((global::System.Guid)(this["LastSettings"]));
}
set {
this["LastSettings"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("zaaReloaded2-Laborwerte")]
@ -184,18 +149,6 @@ namespace zaaReloaded2.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("")]
public string ImportExportPath {
get {
return ((string)(this["ImportExportPath"]));
}
set {
this["ImportExportPath"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("zaaReloaded2-Überschrift")]
@ -223,30 +176,6 @@ namespace zaaReloaded2.Properties {
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool SuppressItemCommentInteraction {
get {
return ((bool)(this["SuppressItemCommentInteraction"]));
}
set {
this["SuppressItemCommentInteraction"] = value;
}
}
[global::System.Configuration.UserScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("False")]
public bool FirstRunWizardShown {
get {
return ((bool)(this["FirstRunWizardShown"]));
}
set {
this["FirstRunWizardShown"] = value;
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("BITTE_ERGÄNZEN")]
@ -258,11 +187,47 @@ namespace zaaReloaded2.Properties {
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("http://git.bovender.de")]
[global::System.Configuration.DefaultSettingValueAttribute("https://git.bovender.de")]
public string Repository {
get {
return ((string)(this["Repository"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("zaaReloaded2-Medikamente")]
public string DrugsParagraph {
get {
return ((string)(this["DrugsParagraph"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("user")]
public string UserFolder {
get {
return ((string)(this["UserFolder"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("zaaReloaded2")]
public string AppDataFolder {
get {
return ((string)(this["AppDataFolder"]));
}
}
[global::System.Configuration.ApplicationScopedSettingAttribute()]
[global::System.Diagnostics.DebuggerNonUserCodeAttribute()]
[global::System.Configuration.DefaultSettingValueAttribute("settings.yml")]
public string UserSettingsFile {
get {
return ((string)(this["UserSettingsFile"]));
}
}
}
}

View File

@ -2,29 +2,23 @@
<SettingsFile xmlns="http://schemas.microsoft.com/VisualStudio/2004/01/settings" CurrentProfile="(Default)" GeneratedClassNamespace="zaaReloaded2.Properties" GeneratedClassName="Settings">
<Profiles />
<Settings>
<Setting Name="SettingsRepository" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="AddinName" Type="System.String" Scope="Application">
<Value Profile="(Default)">zaaReloaded2</Value>
</Setting>
<Setting Name="PubYear" Type="System.String" Scope="Application">
<Value Profile="(Default)">2015</Value>
<Value Profile="(Default)">2016</Value>
</Setting>
<Setting Name="Authors" Type="System.String" Scope="Application">
<Value Profile="(Default)">Daniel Kraus</Value>
</Setting>
<Setting Name="Homepage" Type="System.Uri" Scope="Application">
<Value Profile="(Default)">http://zaa.nephrowiki.de</Value>
<Value Profile="(Default)">https://doktorkraus.de/zaareloaded</Value>
</Setting>
<Setting Name="VersionInfoFile" Type="System.String" Scope="Application">
<Value Profile="(Default)">http://zaa.nephrowiki.de/versioninfo.txt</Value>
<Value Profile="(Default)">https://doktorkraus.de/zaareloaded/versioninfo.txt</Value>
</Setting>
<Setting Name="ExceptionPostUrl" Type="System.String" Scope="Application">
<Value Profile="(Default)">http://zaa.nephrowiki.de/postreport.php</Value>
</Setting>
<Setting Name="LastUpdateCheck" Type="System.DateTime" Scope="User">
<Value Profile="(Default)" />
<Value Profile="(Default)">https://doktorkraus.de/zaareloaded/postreport.php</Value>
</Setting>
<Setting Name="LicenseUrl" Type="System.Uri" Scope="Application">
<Value Profile="(Default)">http://www.apache.org/licenses/LICENSE-2.0</Value>
@ -35,9 +29,6 @@
<Setting Name="SettingsNameClinic" Type="System.String" Scope="Application">
<Value Profile="(Default)">Standard für NepA</Value>
</Setting>
<Setting Name="LastSettings" Type="System.Guid" Scope="User">
<Value Profile="(Default)">00000000-0000-0000-0000-000000000000</Value>
</Setting>
<Setting Name="StyleParagraph" Type="System.String" Scope="Application">
<Value Profile="(Default)">zaaReloaded2-Laborwerte</Value>
</Setting>
@ -53,9 +44,6 @@
<Setting Name="SerializationVersion" Type="System.Int32" Scope="Application">
<Value Profile="(Default)">2</Value>
</Setting>
<Setting Name="ImportExportPath" Type="System.String" Scope="User">
<Value Profile="(Default)" />
</Setting>
<Setting Name="StyleHeader" Type="System.String" Scope="Application">
<Value Profile="(Default)">zaaReloaded2-Überschrift</Value>
</Setting>
@ -65,17 +53,23 @@
<Setting Name="AbnormalStyle" Type="zaaReloaded2.Formatter.AbnormalStyle" Scope="Application">
<Value Profile="(Default)">None</Value>
</Setting>
<Setting Name="SuppressItemCommentInteraction" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="FirstRunWizardShown" Type="System.Boolean" Scope="User">
<Value Profile="(Default)">False</Value>
</Setting>
<Setting Name="ManualCommentPrompt" Type="System.String" Scope="Application">
<Value Profile="(Default)">BITTE_ERGÄNZEN</Value>
</Setting>
<Setting Name="Repository" Type="System.String" Scope="Application">
<Value Profile="(Default)">http://git.bovender.de</Value>
<Value Profile="(Default)">https://git.bovender.de</Value>
</Setting>
<Setting Name="DrugsParagraph" Type="System.String" Scope="Application">
<Value Profile="(Default)">zaaReloaded2-Medikamente</Value>
</Setting>
<Setting Name="UserFolder" Type="System.String" Scope="Application">
<Value Profile="(Default)">user</Value>
</Setting>
<Setting Name="AppDataFolder" Type="System.String" Scope="Application">
<Value Profile="(Default)">zaaReloaded2</Value>
</Setting>
<Setting Name="UserSettingsFile" Type="System.String" Scope="Application">
<Value Profile="(Default)">settings.yml</Value>
</Setting>
</Settings>
</SettingsFile>

View File

@ -87,7 +87,7 @@ namespace zaaReloaded2
{
switch (control.Id)
{
case "zrlFormat":
case "zrlFormatLab":
Commands.Format();
break;
case "zrlSettings":
@ -105,6 +105,12 @@ namespace zaaReloaded2
case "zrlDemo":
Commands.LoadDemo();
break;
case "zrlFormatDrugsOneCol":
Commands.FormatDrugs(1);
break;
case "zrlFormatDrugsTwoCol":
Commands.FormatDrugs(2);
break;
default:
throw new InvalidOperationException("No operation defined for " + control.Id);
}
@ -150,6 +156,11 @@ namespace zaaReloaded2
return Commands.CanFormat();
}
public bool CanFormatDrugs(Office.IRibbonControl control)
{
return Commands.CanFormat();
}
#endregion
#region Public methods

View File

@ -23,12 +23,22 @@
<ribbon>
<tabs>
<tab id="zaaReloaded2" label="zaaReloaded2">
<group id="zrlFormatGroup" label="Formatieren">
<button id="zrlFormat" label="Formatieren" image="f.png" onAction="Ribbon_Click" size="large"
<group id="zrlGroupLab" label="Laborwerte">
<button id="zrlFormatLab" label="Formatieren" image="f.png" onAction="Ribbon_Click" size="large"
supertip="Formatiert den ausgewählten Bereich mit dem zuletzt verwendeten Stil."
getEnabled="CanFormat" />
<button id="zrlSettings" label="Stilauswahl" image="fff.png" onAction="Ribbon_Click" size="large"
supertip="Zeigt eine Liste vorhandener Stile an. Stile können bearbeitet, hinzugefügt, gelöscht werden." />
</group>
<group id="zrlGroupDrugs" label="Medikamente">
<button id="zrlFormatDrugsOneCol" label="Einspaltig" image="m.png" onAction="Ribbon_Click" size="large"
supertip="Formatiert die Medikationsliste einspaltig"
getEnabled="CanFormatDrugs" />
<button id="zrlFormatDrugsTwoCol" label="Zweispaltig" image="mm.png" onAction="Ribbon_Click" size="large"
supertip="Formatiert die Medikationsliste zweispaltig"
getEnabled="CanFormatDrugs" />
</group>
<group id="zrlSpecial" label="Spezial">
<button id="zrlDaniel" label="Daniels Spezial" image="dk.png" onAction="Ribbon_Click" size="large"
getVisible="Daniel_GetVisible"/>
</group>

View File

@ -24,11 +24,14 @@ using System.Windows;
using System.Windows.Input;
using System.Windows.Controls;
using System.Windows.Media;
using System.Configuration;
namespace zaaReloaded2
{
public partial class ThisAddIn
{
#region Static property
/// <summary>
/// Gets the subdirectory for addin data in the user profile directory.
/// </summary>
@ -42,37 +45,77 @@ namespace zaaReloaded2
}
}
#endregion
#region Start up and shut down
private void ThisAddIn_Startup(object sender, System.EventArgs e)
{
#if DEBUG
Bovender.Logging.LogFile.Default.EnableDebugLogging();
#endif
try
{
Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.PerUserRoamingAndLocal);
if (System.IO.File.Exists(config.FilePath))
{
System.IO.File.Delete(config.FilePath);
}
}
catch (Exception ex)
{
Logger.Warn("ThisAddIn_Startup: Unable to delete user config file");
Logger.Warn(ex);
}
Bovender.ExceptionHandler.CentralHandler.ManageExceptionCallback += CentralHandler_ManageExceptionCallback;
Bovender.Win32Window.MainWindowHandleProvider = () =>
{
return IntPtr.Zero;
};
Bovender.WpfHelpers.RegisterTextBoxSelectAll();
Properties.Settings.Default.Upgrade();
UserSettings userSettings = UserSettings.Default;
CheckForUpdates();
_oldCaption = Globals.ThisAddIn.Application.Caption;
Globals.ThisAddIn.Application.Caption =
Microsoft.Office.Interop.Word.Application word = Globals.ThisAddIn.Application;
_oldCaption = word.Caption;
word.Caption =
String.Format(
"{0} ({1} {2})",
_oldCaption,
Properties.Settings.Default.AddinName,
Updater.Version.CurrentVersion().ToString()
Updater.Version.Current.ToString()
);
ViewModels.FirstRunViewModel.InjectIntoIfNeeded<Views.FirstRunView>();
Logger.Info("ThisAddIn_Startup: Finished startup");
}
private void ThisAddIn_Shutdown(object sender, System.EventArgs e)
{
if (_updaterVM != null && _updaterVM.IsUpdatePending)
UserSettings.Default.LastVersionSeen = Updater.Version.Current.ToString();
UserSettings.Default.Save();
if (_updaterVM != null && _updaterVM.InstallCommand.CanExecute(null))
{
if (_updaterVM.InstallUpdateCommand.CanExecute(null))
_updaterVM.InstallUpdateCommand.Execute(null);
Logger.Info("ThisAddIn_Shutdown: Installing update");
_updaterVM.InstallCommand.Execute(null);
}
try
{
Logger.Info("ThisAddIn_Shutdown: Resetting application caption");
Globals.ThisAddIn.Application.Caption = _oldCaption;
}
catch { }
catch (Exception ex)
{
Logger.Warn("ThisAddIn_Shutdown: Failed to reset application caption");
Logger.Warn(ex);
}
Logger.Info("ThisAddIn_Shutdown: Finished shutdown");
}
#endregion
#region Properties
public Ribbon Ribbon
@ -102,24 +145,23 @@ namespace zaaReloaded2
void CheckForUpdates()
{
if (DateTime.Today == Properties.Settings.Default.LastUpdateCheck.Date)
// Check only once per day
if (DateTime.Today == UserSettings.Default.LastUpdateCheck.Date)
return;
Properties.Settings.Default.LastUpdateCheck = DateTime.Today;
Properties.Settings.Default.Save();
_updaterVM = new UpdaterViewModel(new Updater.Updater());
if (!_updaterVM.CanCheckForUpdate) return;
_updaterVM.UpdateAvailableMessage.Sent += UpdateAvailableMessage_Sent;
_updaterVM.CheckForUpdateCommand.Execute(null);
}
void UpdateAvailableMessage_Sent(object sender, MessageArgs<ViewModelMessageContent> e)
{
UpdaterViewModel uvm = e.Content.ViewModel as UpdaterViewModel;
uvm.DestinationFolder = System.IO.Path.GetTempPath();
uvm.DownloadUpdateCommand.Execute(null);
Logger.Info("CheckForUpdates");
UserSettings.Default.LastUpdateCheck = DateTime.Today;
ReleaseInfo releaseInfo = new ReleaseInfo(new Uri(Properties.Settings.Default.VersionInfoFile));
ReleaseInfoViewModel releaseInfoVM = new ReleaseInfoViewModel(releaseInfo, Updater.Version.Current);
releaseInfoVM.UpdateAvailableMessage.Sent += (sender, args) =>
{
Logger.Info("CheckForUpdates: Received update-available message");
Updater.Updater updater = Updater.Updater.CreateDefault(releaseInfo);
updater.DestinationFolder = System.IO.Path.GetTempPath();
_updaterVM = new UpdaterViewModel(updater);
_updaterVM.StartProcess();
};
releaseInfoVM.StartProcess();
}
#endregion
@ -138,8 +180,8 @@ namespace zaaReloaded2
#region Private fields
Ribbon _ribbon;
UpdaterViewModel _updaterVM;
string _oldCaption;
UpdaterViewModel _updaterVM;
#endregion
@ -156,5 +198,13 @@ namespace zaaReloaded2
}
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -1,4 +1,5 @@
/* Updater.cs
using Bovender.Versioning;
/* Updater.cs
* part of zaaReloaded2
*
* Copyright 2015 Daniel Kraus
@ -24,23 +25,38 @@ namespace zaaReloaded2.Updater
{
class Updater : Bovender.Versioning.Updater
{
protected override Bovender.Versioning.SemanticVersion GetCurrentVersion()
#region Static properties
public static Updater Default { get; set; }
#endregion
#region Public static methods
public static Updater CreateDefault(IReleaseInfo releaseInfo)
{
return Version.CurrentVersion();
Default = new Updater(releaseInfo);
return Default;
}
protected override Uri GetVersionInfoUri()
#endregion
#region Constructor
public Updater(Bovender.Versioning.IReleaseInfo releaseInfo)
: base(releaseInfo)
{
return new Uri(Properties.Settings.Default.VersionInfoFile);
CurrentVersion = Version.Current;
}
protected override string BuildDestinationFileName()
{
return System.IO.Path.Combine(
DestinationFolder,
DownloadUri.ToString().Split('/').Last()
);
}
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -26,18 +26,41 @@ namespace zaaReloaded2.Updater
{
class Version : SemanticVersion
{
#region Static 'overrides'
#region Current version singleton
public static SemanticVersion Current
{
get
{
return _lazy.Value;
}
}
private static readonly Lazy<SemanticVersion> _lazy =
new Lazy<SemanticVersion>(() => new Version());
#endregion
#region Public method
public string BrandName
{
get
{
return Properties.Settings.Default.AddinName + " " + ToString();
}
}
#endregion
#region Constructors
/// <summary>
/// Returns the current version of the XL Toolbox addin.
/// Creates an instance with the current zaaReloaded2 version
/// </summary>
/// <returns></returns>
new public static SemanticVersion CurrentVersion()
{
return Bovender.Versioning.SemanticVersion.CurrentVersion(
Assembly.GetExecutingAssembly()
);
}
private Version() : base(Assembly.GetExecutingAssembly()) { }
public Version(string version) : base(version) { }
#endregion
}

198
zaaReloaded2/UserSettings.cs Executable file
View File

@ -0,0 +1,198 @@
/* UserSettings.cs
* part of zaaReloaded2
*
* Copyright 2016 Daniel Kraus
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
namespace zaaReloaded2
{
[Serializable]
class UserSettings : Bovender.UserSettings.UserSettingsBase
{
#region Static property
public static string UserSettingsFile
{
get
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
Properties.Settings.Default.AppDataFolder,
Properties.Settings.Default.UserFolder,
Properties.Settings.Default.UserSettingsFile);
}
}
#endregion
#region Singleton factory
new public static UserSettings Default
{
get
{
return _lazy.Value;
}
}
private static Lazy<UserSettings> _lazy = new Lazy<UserSettings>(() =>
{
// Logger.Info("Initializing singleton instance");
UserSettings s = FromFileOrDefault<UserSettings>(UserSettingsFile);
Bovender.UserSettings.UserSettingsBase.Default = s;
return s;
});
#endregion
#region User settings
public DateTime LastUpdateCheck
{
get
{
if (_lastUpdateCheck == null)
{
_lastUpdateCheck = new DateTime(2016, 1, 1);
}
return _lastUpdateCheck;
}
set
{
_lastUpdateCheck = value;
}
}
public string LastVersionSeen
{
get
{
if (_lastVersionSeen == null)
{
_lastVersionSeen = DEFAULT_VERSION;
}
return _lastVersionSeen;
}
set
{
_lastVersionSeen = value;
}
}
public int UpdateCheckInterval
{
get
{
if (_updateCheckInterval <= 0)
{
_updateCheckInterval = 7;
}
return _updateCheckInterval;
}
set
{
_updateCheckInterval = value;
}
}
public bool EnableLogging
{
get
{
return LogFile.IsInitializedAndEnabled;
}
set
{
if (value)
{
LogFile.Default.IsFileLoggingEnabled = true;
}
else if (LogFile.IsInitializedAndEnabled)
{
LogFile.Default.IsFileLoggingEnabled = true;
}
}
}
public string ImportExportPath { get; set; }
public bool SuppressItemCommentInteraction { get; set; }
public Guid LastSettings
{
get
{
if (_lastSettings == null)
{
_lastSettings = new Guid("00000000-0000-0000-0000-000000000000");
}
return _lastSettings;
}
set
{
_lastSettings = value;
}
}
public string SettingsRepository { get; set; }
[YamlDotNet.Serialization.YamlIgnore]
public bool FirstRun { get { return LastVersionSeen == DEFAULT_VERSION; } }
#endregion
#region Private fields
private DateTime _lastUpdateCheck;
private int _updateCheckInterval;
private string _lastVersionSeen;
private Guid _lastSettings;
private const string DEFAULT_VERSION = "0.0.0";
#endregion
#region Overrides
public override string GetSettingsFilePath()
{
return UserSettingsFile;
}
#endregion
#region Constructor
/// <summary>
/// Creates a new instance. This should never be called directly, use
/// the singleton factory instead. The constructor must be public to
/// enable deserialization.
/// </summary>
public UserSettings() { }
#endregion
#region Class logger
private static NLog.Logger Logger { get { return _logger.Value; } }
private static readonly Lazy<NLog.Logger> _logger = new Lazy<NLog.Logger>(() => NLog.LogManager.GetCurrentClassLogger());
#endregion
}
}

View File

@ -1,2 +1,2 @@
2.1.8
2.1.8.0
2.2.5
2.2.5.0

View File

@ -67,7 +67,7 @@ namespace zaaReloaded2.ViewModels
{
get
{
return zaaReloaded2.Updater.Version.CurrentVersion().ToString();
return zaaReloaded2.Updater.Version.Current.ToString();
}
}

View File

@ -40,7 +40,7 @@ namespace zaaReloaded2.ViewModels
public static void InjectIntoIfNeeded<T>()
where T: System.Windows.Window, new()
{
if (!Properties.Settings.Default.FirstRunWizardShown)
if (UserSettings.Default.FirstRun)
{
FirstRunViewModel vm = new FirstRunViewModel();
vm.InjectInto<T>().Show();
@ -93,34 +93,19 @@ namespace zaaReloaded2.ViewModels
void DoSelectDoctorsMode()
{
// Properties will be saved by the DoCloseView override.
Properties.Settings.Default.SuppressItemCommentInteraction = false;
UserSettings.Default.SuppressItemCommentInteraction = false;
CloseViewCommand.Execute(null);
}
void DoSelectTypistsMode()
{
// Properties will be saved by the DoCloseView override.
Properties.Settings.Default.SuppressItemCommentInteraction = true;
UserSettings.Default.SuppressItemCommentInteraction = true;
CloseViewCommand.Execute(null);
}
#endregion
#region Overrides
/// <summary>
/// Sets the FirstRunWizardShown property of the assembly properties
/// to true and calls the base function to close the associated view.
/// </summary>
protected override void DoCloseView()
{
Properties.Settings.Default.FirstRunWizardShown = true;
Properties.Settings.Default.Save();
base.DoCloseView();
}
#endregion
#region Implementation of ViewModelBase
public override object RevealModelObject()

View File

@ -29,25 +29,47 @@ namespace zaaReloaded2.ViewModels
/// </summary>
public class PreferencesViewModel : ViewModelBase
{
#region Singleton
#region Properties
public static PreferencesViewModel Default
public bool SuppressItemCommentInteraction
{
get
{
return _instance;
return _suppressCommentInteraction;
}
set
{
if (value != _suppressCommentInteraction)
{
_suppressCommentInteraction = value;
OnPropertyChanged("SuppressItemCommentInteraction");
}
}
}
static PreferencesViewModel() { }
public bool EnableLogging
{
get
{
return _enableLogging;
}
set
{
if (value != _enableLogging)
{
_enableLogging = value;
OnPropertyChanged("EnableLogging");
}
}
}
static readonly PreferencesViewModel _instance = new PreferencesViewModel();
#endregion
#region Properties
public bool SuppressItemCommentInteraction { get; set; }
public string LogFolder
{
get
{
return LogFile.Default.LogFolder;
}
}
#endregion
@ -67,13 +89,32 @@ namespace zaaReloaded2.ViewModels
}
}
public DelegatingCommand OpenLogFolderCommand
{
get
{
if (_openLogFolderCommand == null)
{
_openLogFolderCommand = new DelegatingCommand(
param => DoOpenLogFolder(),
param => CanOpenLogFolder());
}
return _openLogFolderCommand;
}
}
#endregion
#region Constructor
public PreferencesViewModel()
{
SuppressItemCommentInteraction = Preferences.Default.SuppressItemCommentInteraction;
_suppressCommentInteraction = UserSettings.Default.SuppressItemCommentInteraction;
_enableLogging = UserSettings.Default.EnableLogging;
PropertyChanged += (sender, args) =>
{
_dirty = true;
};
}
#endregion
@ -82,20 +123,45 @@ namespace zaaReloaded2.ViewModels
void DoSave()
{
Preferences.Default.SuppressItemCommentInteraction = SuppressItemCommentInteraction;
if (_dirty)
{
UserSettings.Default.SuppressItemCommentInteraction = SuppressItemCommentInteraction;
UserSettings.Default.EnableLogging = EnableLogging;
}
DoCloseView();
}
bool CanSave()
{
return true;
return _dirty;
}
void DoOpenLogFolder()
{
if (CanOpenLogFolder())
{
System.Diagnostics.Process.Start(LogFolder);
if (!_dirty)
{
CloseViewCommand.Execute(null);
}
}
}
bool CanOpenLogFolder()
{
return !String.IsNullOrEmpty(LogFolder);
}
#endregion
#region Field
#region Fields
DelegatingCommand _saveCommand;
DelegatingCommand _openLogFolderCommand;
bool _dirty;
bool _enableLogging;
bool _suppressCommentInteraction;
#endregion
@ -103,7 +169,7 @@ namespace zaaReloaded2.ViewModels
public override object RevealModelObject()
{
throw new NotImplementedException();
return UserSettings.Default;
}
#endregion

View File

@ -445,8 +445,7 @@ namespace zaaReloaded2.ViewModels
{
if (message.Confirmed)
{
Properties.Settings.Default.ImportExportPath = message.Value;
Properties.Settings.Default.Save();
UserSettings.Default.ImportExportPath = message.Value;
Settings settings = LastSelected.RevealModelObject() as Settings;
try
{
@ -477,8 +476,7 @@ namespace zaaReloaded2.ViewModels
{
if (message.Confirmed)
{
Properties.Settings.Default.ImportExportPath = message.Value;
Properties.Settings.Default.Save();
UserSettings.Default.ImportExportPath = message.Value;
try
{
Settings settings = Settings.LoadFromFile(message.Value);
@ -495,7 +493,7 @@ namespace zaaReloaded2.ViewModels
string SuggestImportExportPath()
{
string path = Properties.Settings.Default.ImportExportPath;
string path = UserSettings.Default.ImportExportPath;
if (String.IsNullOrEmpty(path))
{
return Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);

View File

@ -38,7 +38,7 @@
<TextBlock TextAlignment="Center" Margin="0, 10, 0, 10">
Homepage:
<Hyperlink Command="{Binding GotoHomepageCommand}">
<TextBlock Text="zaa.nephrowiki.de" />
<TextBlock Text="doktorkraus.de/zaareloaded" />
</Hyperlink>
<LineBreak />
Quellcode:

View File

@ -23,22 +23,36 @@
xmlns:b="clr-namespace:Bovender.Mvvm.Views.Settings;assembly=Bovender"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:action="clr-namespace:Bovender.Mvvm.Actions;assembly=Bovender"
SizeToContent="WidthAndHeight" ResizeMode="NoResize" ShowInTaskbar="False"
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
ShowInTaskbar="False" Topmost="True"
b:WindowState.CenterScreen="True" b:WindowState.Save="True"
Title="Einstellungen"
>
<Window.Resources>
<ResourceDictionary Source="/Bovender;component/Style.xaml" />
</Window.Resources>
<DockPanel Margin="10">
<DockPanel Margin="20">
<UniformGrid DockPanel.Dock="Bottom" Columns="2" Rows="1"
HorizontalAlignment="Right" Margin="0 10 0 0">
HorizontalAlignment="Right" Margin="0 20 0 0">
<Button Command="{Binding SaveCommand}" Content="OK" IsDefault="True" Margin="0 0 5 0" />
<Button Command="{Binding CloseViewCommand}" Content="Abbrechen" IsCancel="True" Margin="5 0 0 0" />
</UniformGrid>
<GroupBox Header="Sekretariatsmodus" Padding="10">
<CheckBox IsChecked="{Binding SuppressItemCommentInteraction}" Content="Keine Interaktion für _Kommentare">
</CheckBox>
</GroupBox>
<StackPanel>
<GroupBox Header="Sekretariatsmodus" Margin="0 0 0 5" Padding="10">
<StackPanel>
<CheckBox IsChecked="{Binding SuppressItemCommentInteraction}" Content="Keine Interaktion für _Kommentare" />
</StackPanel>
</GroupBox>
<GroupBox Header="Debugging" Margin="0 5 0 0" Padding="10">
<StackPanel>
<CheckBox IsChecked="{Binding EnableLogging}" Content="_Logfile aktivieren" />
<TextBlock Margin="0 10 0 0">
<Hyperlink Command="{Binding OpenLogFolderCommand}">
<TextBlock Text="{Binding LogFolder}" />
</Hyperlink>
</TextBlock>
</StackPanel>
</GroupBox>
</StackPanel>
</DockPanel>
</Window>

View File

@ -38,11 +38,11 @@
<action:ShowViewAction View="zaaReloaded2.Views.SettingsView" Assembly="zaaReloaded2" />
</i:EventTrigger>
<i:EventTrigger SourceObject="{Binding ConfirmDeleteSettingsMessage}" EventName="Sent">
<action:ConfirmationAction Caption="Stil entfernen" OkButtonLabel="Ja" CancelButtonLabel="Nein"
<action:ConfirmationAction Caption="Stil entfernen" OkButtonText="Ja" CancelButtonText="Nein"
Message="Soll dieser Stil wirklich unwiederbringlich entfernt werden?" />
</i:EventTrigger>
<i:EventTrigger SourceObject="{Binding ConfirmResetSettingsMessage}" EventName="Sent">
<action:ConfirmationAction Caption="Stile zurücksetzen" OkButtonLabel="Ja" CancelButtonLabel="Nein"
<action:ConfirmationAction Caption="Stile zurücksetzen" OkButtonText="Ja" CancelButtonText="Nein"
Message="Sollen alle Stile gelöscht und die eingebauten Stile geladen werden?" />
</i:EventTrigger>
<i:EventTrigger SourceObject="{Binding ChooseExportFileNameMessage}" EventName="Sent">

View File

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8" ?>
<?xml version="1.0" encoding="utf-8"?>
<!--
app.config
@ -20,12 +20,9 @@
-->
<configuration>
<configSections>
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
<section name="zaaReloaded2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</sectionGroup>
<sectionGroup name="userSettings" type="System.Configuration.UserSettingsGroup, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
<section name="zaaReloaded2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" allowExeDefinition="MachineToLocalUser" requirePermission="false" />
</sectionGroup>
</configSections>
<applicationSettings>
<zaaReloaded2.Properties.Settings>
@ -33,19 +30,19 @@
<value>zaaReloaded2</value>
</setting>
<setting name="PubYear" serializeAs="String">
<value>2015</value>
<value>2016</value>
</setting>
<setting name="Authors" serializeAs="String">
<value>Daniel Kraus</value>
</setting>
<setting name="Homepage" serializeAs="String">
<value>http://zaa.nephrowiki.de</value>
<value>https://doktorkraus.de/zaareloaded</value>
</setting>
<setting name="VersionInfoFile" serializeAs="String">
<value>http://zaa.nephrowiki.de/versioninfo.txt</value>
<value>https://doktorkraus.de/zaareloaded/versioninfo.txt</value>
</setting>
<setting name="ExceptionPostUrl" serializeAs="String">
<value>http://zaa.nephrowiki.de/postreport.php</value>
<value>https://doktorkraus.de/zaareloaded/postreport.php</value>
</setting>
<setting name="LicenseUrl" serializeAs="String">
<value>http://www.apache.org/licenses/LICENSE-2.0</value>
@ -84,30 +81,28 @@
<value>BITTE_ERGÄNZEN</value>
</setting>
<setting name="Repository" serializeAs="String">
<value>http://git.bovender.de</value>
<value>https://git.bovender.de</value>
</setting>
<setting name="DrugsParagraph" serializeAs="String">
<value>zaaReloaded2-Medikamente</value>
</setting>
<setting name="UserFolder" serializeAs="String">
<value>user</value>
</setting>
<setting name="AppDataFolder" serializeAs="String">
<value>zaaReloaded2</value>
</setting>
<setting name="UserSettingsFile" serializeAs="String">
<value>settings.yml</value>
</setting>
</zaaReloaded2.Properties.Settings>
</applicationSettings>
<userSettings>
<zaaReloaded2.Properties.Settings>
<setting name="SettingsRepository" serializeAs="String">
<value />
</setting>
<setting name="LastUpdateCheck" serializeAs="String">
<value />
</setting>
<setting name="LastSettings" serializeAs="String">
<value>00000000-0000-0000-0000-000000000000</value>
</setting>
<setting name="ImportExportPath" serializeAs="String">
<value />
</setting>
<setting name="SuppressItemCommentInteraction" serializeAs="String">
<value>False</value>
</setting>
<setting name="FirstRunWizardShown" serializeAs="String">
<value>False</value>
</setting>
</zaaReloaded2.Properties.Settings>
</userSettings>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="YamlDotNet" publicKeyToken="ec19458f3c15af5e" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-3.9.0.0" newVersion="3.9.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

View File

@ -19,6 +19,8 @@
limitations under the License.
-->
<packages>
<package id="Bovender" version="0.4.0.0" targetFramework="net40" />
<package id="Bovender" version="0.14.5.0" targetFramework="net40" />
<package id="Expression.Blend.Sdk" version="1.0.2" targetFramework="net40" />
<package id="NLog" version="4.3.7" targetFramework="net40" />
<package id="YamlDotNet.Signed" version="3.9.0" targetFramework="net40" />
</packages>

View File

@ -29,6 +29,7 @@
<AssemblyName>zaaReloaded2</AssemblyName>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<DefineConstants>VSTO40</DefineConstants>
<IsWebBootstrapper>False</IsWebBootstrapper>
<BootstrapperEnabled>true</BootstrapperEnabled>
<PublishUrl>publish\</PublishUrl>
<InstallUrl />
@ -38,7 +39,6 @@
<UpdateEnabled>true</UpdateEnabled>
<UpdateInterval>7</UpdateInterval>
<UpdateIntervalUnits>days</UpdateIntervalUnits>
<IsWebBootstrapper>False</IsWebBootstrapper>
<ProductName>zaaReloaded2</ProductName>
<PublisherName />
<SupportUrl />
@ -134,14 +134,19 @@
-->
<ItemGroup>
<Reference Include="Accessibility" />
<Reference Include="Bovender, Version=0.4.0.0, Culture=neutral, PublicKeyToken=df1c15557d8b6df8, processorArchitecture=MSIL">
<HintPath>..\packages\Bovender.0.4.0.0\lib\net40\Bovender.dll</HintPath>
<Reference Include="Bovender, Version=0.14.5.0, Culture=neutral, PublicKeyToken=df1c15557d8b6df8, processorArchitecture=MSIL">
<HintPath>..\packages\Bovender.0.14.5.0\lib\net40\Bovender.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="Microsoft.Expression.Interactions, Version=4.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
<HintPath>..\packages\NLog.4.3.7\lib\net40\NLog.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="PresentationCore" />
<Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.configuration" />
<Reference Include="System.Data" />
<Reference Include="System.Drawing" />
<Reference Include="System.Runtime.Serialization.Formatters.Soap" />
@ -156,6 +161,10 @@
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="WindowsBase" />
<Reference Include="YamlDotNet, Version=3.9.0.0, Culture=neutral, PublicKeyToken=ec19458f3c15af5e, processorArchitecture=MSIL">
<HintPath>..\packages\YamlDotNet.Signed.3.9.0\lib\net35\YamlDotNet.dll</HintPath>
<Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Reference Include="Microsoft.Office.Tools.v4.0.Framework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
@ -194,6 +203,7 @@
-->
<ItemGroup>
<Compile Include="Commands.cs" />
<Compile Include="Helpers.cs" />
<Compile Include="Importer\ZaaImporter\AutoDetect.cs" />
<Compile Include="Controller\Comments\CommentPool.cs" />
<Compile Include="Controller\Elements\ControlElementBase.cs" />
@ -221,7 +231,10 @@
<Compile Include="Formatter\DanielsStyle.cs" />
<Compile Include="Formatter\DocumentWriter.cs" />
<Compile Include="Formatter\NoLaboratoryDataException.cs" />
<Compile Include="Preferences.cs" />
<Compile Include="LogFile.cs" />
<Compile Include="Medication\Formatter.cs" />
<Compile Include="Medication\Importer.cs" />
<Compile Include="Medication\Prescription.cs" />
<Compile Include="Ribbon.cs" />
<Compile Include="Thesaurus\ThesaurusBase.cs" />
<Compile Include="Formatter\IItemFormatterDictionary.cs" />
@ -254,6 +267,7 @@
<SubType>Code</SubType>
</Compile>
<Compile Include="Updater\Updater.cs" />
<Compile Include="UserSettings.cs" />
<Compile Include="ViewModels\AboutViewModel.cs" />
<Compile Include="ViewModels\CategoryViewModel.cs" />
<Compile Include="ViewModels\ElementPickerViewModel.cs" />
@ -446,6 +460,12 @@
<ItemGroup>
<Resource Include="Icons\gear.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\m.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\mm.png" />
</ItemGroup>
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">10.0</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
@ -454,10 +474,11 @@
<SignManifests>true</SignManifests>
</PropertyGroup>
<PropertyGroup>
<ManifestKeyFile>zaaReloaded2_TemporaryKey.pfx</ManifestKeyFile>
<ManifestKeyFile>
</ManifestKeyFile>
</PropertyGroup>
<PropertyGroup>
<ManifestCertificateThumbprint>0EDB0CD8E3605AC48387A527A80943403E568BD9</ManifestCertificateThumbprint>
<ManifestCertificateThumbprint>6322CFC6CFA69B4D2DEFAE4A901473C8B35B0DB9</ManifestCertificateThumbprint>
</PropertyGroup>
<PropertyGroup>
<SignAssembly>true</SignAssembly>