-
Notifications
You must be signed in to change notification settings - Fork 2
/
MLPrescriptionTextFinderClient.m
197 lines (175 loc) · 7.51 KB
/
MLPrescriptionTextFinderClient.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
//
// MLPrescriptionTextFinderClient.m
// AmiKo
//
// Created by b123400 on 2020/10/15.
// Copyright © 2020 Ywesee GmbH. All rights reserved.
//
#import "MLPrescriptionTextFinderClient.h"
#import "MLPrescriptionCellView.h"
@interface MLPrescriptionTextFinderClient ()
@property (nonatomic, strong) MLPrescriptionsAdapter *adapter;
@property (nonatomic, weak) MLMainWindowController *mainWindowController;
// e.g.
// ["patient name", "doctor name", "med 1", "med 2"]
@property (nonatomic, strong) NSArray<NSString*> *searchStrings;
// The index of search string of patient in searchString, or -1
@property (nonatomic, assign) NSInteger patientIndex;
// The index of search string of doctor in searchString, or -1
@property (nonatomic, assign) NSInteger doctorIndex;
// The index of beginning of search strings of packages, e.g. prescriptions start with this index
@property (nonatomic, assign) NSInteger prescriptionIndex;
@end
@implementation MLPrescriptionTextFinderClient
- (instancetype)initWithAdapter:(MLPrescriptionsAdapter*)adapter mainWindowController:(MLMainWindowController*)mainWindowController {
if (self = [super init]) {
self.adapter = adapter;
self.mainWindowController = mainWindowController;
self.searchStrings = @[];
self.patientIndex = -1;
self.doctorIndex = -1;
self.prescriptionIndex = 0;
}
return self;
}
- (BOOL)isSelectable {
return NO;
}
- (BOOL)allowsMultipleSelection {
return NO;
}
- (NSRange)firstSelectedRange {
return NSMakeRange(0, 0);
}
- (void)reloadSearchString {
self.patientIndex = -1;
self.doctorIndex = -1;
NSInteger index = 0;
NSMutableArray<NSString *> *strings = [NSMutableArray array];
NSString *patientString = [[self.adapter patient] asString];
if ([patientString length]) {
[strings addObject:patientString];
self.patientIndex = index;
index++;
}
if ([self.adapter.doctor.familyName length] && [self.adapter.doctor.givenName length]) {
NSString *doctorString = [self.adapter.doctor retrieveOperatorAsString];
if ([doctorString length]) {
[strings addObject:doctorString];
self.doctorIndex = index;
index++;
}
}
MLPrescriptionsCart *cart = [MLMainWindowController prescriptionsCartWithId:0];
NSArray<MLPrescriptionItem*> *items = cart.cart;
self.prescriptionIndex = index;
for (MLPrescriptionItem *item in items) {
[strings addObject:[item fullPackageInfo]];
}
self.searchStrings = strings;
}
- (NSString *)stringAtIndex:(NSUInteger)characterIndex effectiveRange:(NSRangePointer)outRange endsWithSearchBoundary:(BOOL *)outFlag {
int currentCharacterIndex = 0;
for (NSString *string in self.searchStrings) {
BOOL isThisString = currentCharacterIndex <= characterIndex && characterIndex < currentCharacterIndex + string.length;
if (isThisString) {
*outFlag = YES;
(*outRange).location = currentCharacterIndex;
(*outRange).length = [string length];
return string;
} else {
currentCharacterIndex += string.length;
}
}
return nil;
}
- (NSUInteger)stringLength {
return [[self.searchStrings valueForKeyPath:@"@sum.length"] unsignedIntegerValue];
}
- (void)scrollRangeToVisible:(NSRange)range {
int currentCharacterIndex = 0;
NSUInteger characterIndex = range.location;
for (NSInteger i = 0; i < self.searchStrings.count; i++) {
NSString *string = self.searchStrings[i];
BOOL isThisString = currentCharacterIndex <= characterIndex && characterIndex < currentCharacterIndex + string.length;
if (isThisString) {
if (i >= self.prescriptionIndex) {
NSUInteger rowIndex = i - self.prescriptionIndex;
[self.mainWindowController.myPrescriptionsTableView scrollRowToVisible:rowIndex];
return;
}
} else {
currentCharacterIndex += string.length;
}
}
}
- (NSView *)contentViewAtIndex:(NSUInteger)characterIndex effectiveCharacterRange:(NSRangePointer)outRange {
int currentCharacterIndex = 0;
for (NSInteger i = 0; i < self.searchStrings.count; i++) {
NSString *string = self.searchStrings[i];
BOOL isThisString = currentCharacterIndex <= characterIndex && characterIndex < currentCharacterIndex + string.length;
if (isThisString) {
(*outRange).location = currentCharacterIndex;
(*outRange).length = [string length];
if (i == self.patientIndex) {
NSLog(@"returning paitent");
return self.mainWindowController.myPatientAddressTextField;
} else if (i == self.doctorIndex) {
NSLog(@"returning doctor");
return self.mainWindowController.myOperatorIDTextField;
} else {
MLPrescriptionCellView *cellView = [self.mainWindowController.myPrescriptionsTableView viewAtColumn: 0
row: i - self.prescriptionIndex
makeIfNecessary:NO];
NSLog(@"cell view: %@", [cellView description]);
return [cellView textField];
}
} else {
currentCharacterIndex += string.length;
}
}
NSLog(@"return no view");
return nil;
}
- (NSArray<NSValue *> *)rectsForCharacterRange:(NSRange)inRange {
NSRange r = NSMakeRange(0, 0);
NSView *view = [self contentViewAtIndex:inRange.location effectiveCharacterRange:&r];
NSRange range = NSMakeRange(inRange.location - r.location, inRange.length);
if ([view isKindOfClass:[NSTextField class]]) {
NSTextField *textField = (NSTextField*)view;
NSRect textBounds = [textField.cell titleRectForBounds:textField.bounds];
NSTextContainer* textContainer = [[NSTextContainer alloc] init];
NSLayoutManager* layoutManager = [[NSLayoutManager alloc] init];
NSTextStorage* textStorage = [[NSTextStorage alloc] init];
[layoutManager addTextContainer:textContainer];
[textStorage addLayoutManager:layoutManager];
textContainer.lineFragmentPadding = 2;
layoutManager.typesetterBehavior = NSTypesetterBehavior_10_2_WithCompatibility;
textContainer.containerSize = textBounds.size;
[textStorage beginEditing];
textStorage.attributedString = textField.attributedStringValue;
[textStorage endEditing];
NSUInteger count;
NSRectArray rects = [layoutManager rectArrayForCharacterRange:range
withinSelectedCharacterRange:range
inTextContainer:textContainer
rectCount:&count];
NSMutableArray<NSValue *> *values = [NSMutableArray array];
for (NSUInteger i = 0; i < count; i++)
{
NSRect rect = NSOffsetRect(rects[i], textBounds.origin.x, textBounds.origin.y);
[values addObject:[NSValue valueWithRect:rect]];
}
return values;
} else {
NSLog(@"what type %@", [view description]);
return nil;
}
}
- (void)drawCharactersInRange:(NSRange)range forContentView:(NSView *)view {
NSArray<NSValue *> *values = [self rectsForCharacterRange:range];
for (NSValue *v in values) {
[view drawRect:v.rectValue];
}
}
@end