| [456] | 1 | unit uDocTree; | 
|---|
|  | 2 |  | 
|---|
|  | 3 | interface | 
|---|
|  | 4 |  | 
|---|
|  | 5 | uses SysUtils, Classes, ORNet, ORFn, rCore, uCore, uConst, ORCtrls, ComCtrls, uTIU; | 
|---|
|  | 6 |  | 
|---|
|  | 7 |  | 
|---|
|  | 8 | type | 
|---|
|  | 9 | PDocTreeObject = ^TDocTreeObject; | 
|---|
|  | 10 | TDocTreeObject = record | 
|---|
|  | 11 | DocID          : string ;                 //Document IEN | 
|---|
|  | 12 | DocDate        : string;                  //Formatted date of document | 
|---|
|  | 13 | DocTitle       : string;                  //Document Title Text | 
|---|
|  | 14 | NodeText       : string;                  //Title, Location, Author  (depends on tab) | 
|---|
|  | 15 | ImageCount     : integer;                 //Number of images | 
|---|
|  | 16 | VisitDate      : string;                  //ADM/VIS: date;FMDate | 
|---|
|  | 17 | DocFMDate      : string;                  //FM date of document | 
|---|
|  | 18 | DocHasChildren : string;                  //Has children  (+,>,<) | 
|---|
|  | 19 | DocParent      : string;                  //Parent document, or context | 
|---|
|  | 20 | Author         : string;                  //DUZ;Author name | 
|---|
|  | 21 | PkgRef         : string;                  //IEN;Package    (consults only, for now) | 
|---|
|  | 22 | Location       : string;                  //Location name | 
|---|
|  | 23 | Status         : string;                  //Status | 
|---|
|  | 24 | Subject        : string;                  //Subject | 
|---|
|  | 25 | OrderID        : string;                  //Order file IEN (consults only, for now) | 
|---|
|  | 26 | OrderByTitle   : boolean;                 //Within ID Parents, order children by title, not date | 
|---|
|  | 27 | end; | 
|---|
|  | 28 |  | 
|---|
|  | 29 | // Procedures for document treeviews/listviews | 
|---|
|  | 30 | procedure CreateListItemsForDocumentTree(Dest, Source: TStrings; Context: integer; GroupBy: string; | 
|---|
|  | 31 | Ascending: boolean; TabIndex: integer); | 
|---|
|  | 32 | procedure BuildDocumentTree(DocList: TStrings; const Parent: string; Tree: TORTreeView; Node: TORTreeNode; | 
|---|
|  | 33 | TIUContext: TTIUContext; TabIndex: integer); | 
|---|
|  | 34 | procedure SetTreeNodeImagesAndFormatting(Node: TORTreeNode; CurrentContext: TTIUContext; TabIndex: integer); | 
|---|
|  | 35 | procedure ResetDocTreeObjectStrings(AnObject: PDocTreeObject); | 
|---|
|  | 36 | procedure KillDocTreeObjects(TreeView: TORTreeView); | 
|---|
|  | 37 | procedure KillDocTreeNode(ANode: TTreeNode); | 
|---|
|  | 38 | function  ContextMatch(ANode: TORTreeNode; AParentID: string; AContext: TTIUContext): Boolean; | 
|---|
|  | 39 | function  TextFound(ANode: TORTreeNode; CurrentContext: TTIUContext): Boolean; | 
|---|
|  | 40 | procedure RemoveParentsWithNoChildren(Tree: TTreeView; Context: TTIUContext); | 
|---|
|  | 41 | procedure TraverseTree(ATree: TTreeView; AListView: TListView; ANode: TTreeNode; MyNodeID: string; | 
|---|
|  | 42 | AContext: TTIUContext); | 
|---|
|  | 43 | procedure AddListViewItem(ANode: TTreeNode; AListView: TListView); | 
|---|
|  | 44 | function  MakeNoteTreeObject(x: string): PDocTreeObject; | 
|---|
|  | 45 | function  MakeDCSummTreeObject(x: string): PDocTreeObject; | 
|---|
|  | 46 | function  MakeConsultsNoteTreeObject(x: string): PDocTreeObject; | 
|---|
|  | 47 |  | 
|---|
|  | 48 | implementation | 
|---|
|  | 49 |  | 
|---|
|  | 50 | uses | 
|---|
|  | 51 | rConsults, uDCSumm, uConsults; | 
|---|
|  | 52 |  | 
|---|
|  | 53 | {============================================================== | 
|---|
|  | 54 | RPC [TIU DOCUMENTS BY CONTEXT] returns | 
|---|
|  | 55 | the following string '^' pieces: | 
|---|
|  | 56 | =============================================================== | 
|---|
|  | 57 | 1 -  Document IEN | 
|---|
|  | 58 | 2 -  Document Title | 
|---|
|  | 59 | 3 -  FM date of document | 
|---|
|  | 60 | 4 -  Patient Name | 
|---|
|  | 61 | 5 -  DUZ;Author name | 
|---|
|  | 62 | 6 -  Location | 
|---|
|  | 63 | 7 -  Status | 
|---|
|  | 64 | 8 -  ADM/VIS: date;FMDate | 
|---|
|  | 65 | 9 -  Discharge Date;FMDate | 
|---|
|  | 66 | 10 - Package variable pointer | 
|---|
|  | 67 | 11 - Number of images | 
|---|
|  | 68 | 12 - Subject | 
|---|
|  | 69 | 13 - Has children | 
|---|
|  | 70 | 14 - Parent document | 
|---|
|  | 71 | 15 - Order children of ID Note by title rather than date | 
|---|
|  | 72 | ===============================================================} | 
|---|
|  | 73 |  | 
|---|
|  | 74 | procedure CreateListItemsForDocumentTree(Dest, Source: TStrings; Context: integer; GroupBy: string; | 
|---|
|  | 75 | Ascending: Boolean; TabIndex: integer); | 
|---|
|  | 76 | const | 
|---|
|  | 77 | NO_MATCHES = '^No Matching Documents Found^^^^^^^^^^^%^0'; | 
|---|
|  | 78 | var | 
|---|
|  | 79 | i: Integer; | 
|---|
|  | 80 | x, x1, x2, x3, MyParent, MyTitle, MyLocation, MySubject: string; | 
|---|
|  | 81 | AList, SrcList: TStringList; | 
|---|
|  | 82 | begin | 
|---|
|  | 83 | AList := TStringList.Create; | 
|---|
|  | 84 | SrcList := TStringList.Create; | 
|---|
|  | 85 | try | 
|---|
| [830] | 86 | FastAssign(Source, SrcList); | 
|---|
| [456] | 87 | with SrcList do | 
|---|
|  | 88 | begin | 
|---|
|  | 89 | if (Count = 0) then | 
|---|
|  | 90 | begin | 
|---|
|  | 91 | Dest.Insert(0, IntToStr(Context) + NO_MATCHES); | 
|---|
|  | 92 | Exit; | 
|---|
|  | 93 | end; | 
|---|
|  | 94 | for i := 0 to Count - 1 do | 
|---|
|  | 95 | begin | 
|---|
|  | 96 | x := Strings[i]; | 
|---|
|  | 97 | MyParent   := Piece(x, U, 14); | 
|---|
|  | 98 | MyTitle    := Piece(x, U, 2); | 
|---|
|  | 99 | if Length(Trim(MyTitle)) = 0 then | 
|---|
|  | 100 | begin | 
|---|
|  | 101 | MyTitle := '** No Title **'; | 
|---|
|  | 102 | SetPiece(x, U, 2, MyTitle); | 
|---|
|  | 103 | end; | 
|---|
|  | 104 | MyLocation := Piece(x, U, 6); | 
|---|
|  | 105 | if Length(Trim(MyLocation)) = 0 then | 
|---|
|  | 106 | begin | 
|---|
|  | 107 | MyLocation := '** No Location **'; | 
|---|
|  | 108 | SetPiece(x, U, 6, MyLocation); | 
|---|
|  | 109 | end; | 
|---|
|  | 110 | MySubject  := Piece(x, U, 12); | 
|---|
|  | 111 | (*            case TIUContext.SearchField[1] of | 
|---|
|  | 112 | 'T': if ((TextFound(MyTitle)) then continue; | 
|---|
|  | 113 | 'S': if (not TextFound(MySubject)) then continue; | 
|---|
|  | 114 | 'B': if not ((TextFound(MyTitle)) or (TextFound(MySubject))) then continue; | 
|---|
|  | 115 | end;*) | 
|---|
|  | 116 | if GroupBy <> '' then case GroupBy[1] of | 
|---|
|  | 117 | 'D':  begin | 
|---|
|  | 118 | x1 := Piece(Piece(x, U, 8), ';', 1);                    // Visit date | 
|---|
|  | 119 | x2 := Piece(Piece(Piece(x, U, 8), ';', 2), '.', 1);     // Visit date (FM)   no time - v15.4 | 
|---|
|  | 120 | if x2 = '' then | 
|---|
|  | 121 | begin | 
|---|
|  | 122 | x2 := 'No Visit'; | 
|---|
|  | 123 | x1 := Piece(x1, ':', 1) + ':  No Visit'; | 
|---|
|  | 124 | end; | 
|---|
|  | 125 | (*else | 
|---|
|  | 126 | x1 := Piece(x1, ':', 1) + ':  ' + FormatFMDateTimeStr('mmm dd,yy@hh:nn',x2)*) //removed v15.4 | 
|---|
|  | 127 | if MyParent = IntToStr(Context) then | 
|---|
|  | 128 | SetPiece(x, U, 14, MyParent + x2 + Copy(x1, 1, 3));    // '2980324Adm' | 
|---|
|  | 129 | x3 := x2 + Copy(x1, 1, 3) + U + MixedCase(x1) + U + IntToStr(Context) + MixedCase(Copy(x1, 1, 3)); | 
|---|
|  | 130 | if (Copy(MyTitle, 1, 8) <> 'Addendum') and (AList.IndexOf(x3) = -1) then | 
|---|
|  | 131 | AList.Add(x3);   // '2980324Adm^Mar 24,98' | 
|---|
|  | 132 | end; | 
|---|
|  | 133 | 'L':  begin | 
|---|
|  | 134 | if MyParent = IntToStr(Context) then                  // keep ID notes together, or | 
|---|
|  | 135 | SetPiece(x, U, 14, MyParent + MyLocation); | 
|---|
|  | 136 | (*                        if (Copy(MyTitle, 1, 8) <> 'Addendum') then       // split ID Notes by location? | 
|---|
|  | 137 | SetPiece(x, U, 14, IntToStr(Context) + MyLocation);*) | 
|---|
|  | 138 | x3 := MyLocation + U + MixedCase(MyLocation) + U + IntToStr(Context); | 
|---|
|  | 139 | if (Copy(MyTitle, 1, 8) <> 'Addendum') and (AList.IndexOf(x3) = -1) then | 
|---|
|  | 140 | AList.Add(x3); | 
|---|
|  | 141 | end; | 
|---|
|  | 142 | 'T':  begin | 
|---|
|  | 143 | if MyParent = IntToStr(Context) then                  // keep ID notes together, or | 
|---|
|  | 144 | SetPiece(x, U, 14, MyParent + MyTitle); | 
|---|
|  | 145 | (*                        if (Copy(MyTitle, 1, 8) <> 'Addendum') then       // split ID Notes by title? | 
|---|
|  | 146 | SetPiece(x, U, 14, IntToStr(Context) + MyTitle);*) | 
|---|
|  | 147 | x3 := MyTitle + U + MixedCase(MyTitle) + U + IntToStr(Context); | 
|---|
|  | 148 | if (Copy(MyTitle, 1, 8) <> 'Addendum') and (AList.IndexOf(x3) = -1) then | 
|---|
|  | 149 | AList.Add(x3); | 
|---|
|  | 150 | end; | 
|---|
|  | 151 | 'A':  begin | 
|---|
|  | 152 | x1 := Piece(Piece(x, U, 5), ';', 3); | 
|---|
|  | 153 | if x1 = '' then x1 := '** No Author **'; | 
|---|
|  | 154 | if MyParent = IntToStr(Context) then                  // keep ID notes together, or | 
|---|
|  | 155 | SetPiece(x, U, 14, MyParent + x1); | 
|---|
|  | 156 | //if (Copy(MyTitle, 1, 8) <> 'Addendum') then         // split ID Notes by author? | 
|---|
|  | 157 | //  SetPiece(x, U, 14, IntToStr(Context) + x1); | 
|---|
|  | 158 | x3 := x1 + U + MixedCase(x1) + U + IntToStr(Context); | 
|---|
|  | 159 | if (Copy(MyTitle, 1, 8) <> 'Addendum') and(AList.IndexOf(x3) = -1) then | 
|---|
|  | 160 | AList.Add(x3); | 
|---|
|  | 161 | end; | 
|---|
|  | 162 | (*              'A':  begin                                                 // Makes note appear both places in tree, | 
|---|
|  | 163 | x1 := Piece(Piece(x, U, 5), ';', 3);                  // but also appears TWICE in lstNotes. | 
|---|
|  | 164 | if x1 = '' then x1 := '** No Author **';              // IS THIS REALLY A PROBLEM?? | 
|---|
|  | 165 | if MyParent = IntToStr(Context) then                  // Impact on EditingIndex? | 
|---|
|  | 166 | SetPiece(x, U, 14, MyParent + x1);                  // Careful when deleting note being edited!!! | 
|---|
|  | 167 | Dest.Add(x);                                          // Need to find and delete ALL occurrences! | 
|---|
|  | 168 | SetPiece(x, U, 14, IntToStr(Context) + x1); | 
|---|
|  | 169 | x3 := x1 + U + MixedCase(x1) + U + IntToStr(Context); | 
|---|
|  | 170 | if (AList.IndexOf(x3) = -1) then AList.Add(x3); | 
|---|
|  | 171 | end;*) | 
|---|
|  | 172 | end; | 
|---|
|  | 173 | Dest.Add(x); | 
|---|
|  | 174 | end; {for} | 
|---|
|  | 175 | SortByPiece(TStringList(Dest), U, 3); | 
|---|
|  | 176 | if not Ascending then InvertStringList(TStringList(Dest)); | 
|---|
|  | 177 | if GroupBy <> '' then if GroupBy[1] ='D' then | 
|---|
|  | 178 | begin | 
|---|
|  | 179 | AList.Add('Adm^Inpatient Notes' + U + IntToStr(Context)); | 
|---|
|  | 180 | AList.Add('Vis^Outpatient Notes' + U + IntToStr(Context)); | 
|---|
|  | 181 | end; | 
|---|
|  | 182 | Dest.Insert(0, IntToStr(Context) + '^' + NC_TV_TEXT[TabIndex, Context] + '^^^^^^^^^^^%^0'); | 
|---|
|  | 183 | Alist.Sort; | 
|---|
|  | 184 | InvertStringList(AList); | 
|---|
|  | 185 | if GroupBy <> '' then if GroupBy[1] ='D' then | 
|---|
|  | 186 | if (not Ascending) then InvertStringList(AList); | 
|---|
|  | 187 | for i := 0 to AList.Count-1 do | 
|---|
|  | 188 | Dest.Insert(0, IntToStr(Context) + Piece(AList[i], U, 1) + '^' + Piece(AList[i], U, 2) + '^^^^^^^^^^^%^' + Piece(AList[i], U, 3)); | 
|---|
|  | 189 | end; | 
|---|
|  | 190 | finally | 
|---|
|  | 191 | AList.Free; | 
|---|
|  | 192 | SrcList.Free; | 
|---|
|  | 193 | end; | 
|---|
|  | 194 | end; | 
|---|
|  | 195 |  | 
|---|
|  | 196 | procedure BuildDocumentTree(DocList: TStrings; const Parent: string; Tree: TORTreeView; Node: TORTreeNode; | 
|---|
|  | 197 | TIUContext: TTIUContext; TabIndex: integer); | 
|---|
|  | 198 | var | 
|---|
|  | 199 | MyID, MyParent, Name: string; | 
|---|
|  | 200 | i: Integer; | 
|---|
|  | 201 | ChildNode, tmpNode: TORTreeNode; | 
|---|
|  | 202 | DocHasChildren: Boolean; | 
|---|
|  | 203 | AnObject: PDocTreeObject; | 
|---|
|  | 204 | begin | 
|---|
|  | 205 | with DocList do for i := 0 to Count - 1 do | 
|---|
|  | 206 | begin | 
|---|
|  | 207 | tmpNode := nil; | 
|---|
|  | 208 | MyParent := Piece(Strings[i], U, 14); | 
|---|
|  | 209 | if (MyParent = Parent) then | 
|---|
|  | 210 | begin | 
|---|
|  | 211 | MyID := Piece(Strings[i], U, 1); | 
|---|
|  | 212 | if Piece(Strings[i], U, 13) <> '%' then | 
|---|
|  | 213 | case TabIndex of | 
|---|
|  | 214 | CT_NOTES:    Name := MakeNoteDisplayText(Strings[i]); | 
|---|
|  | 215 | CT_CONSULTS: Name := MakeConsultNoteDisplayText(Strings[i]); | 
|---|
|  | 216 | CT_DCSUMM:   Name := MakeDCSummDisplayText(Strings[i]); | 
|---|
|  | 217 | end | 
|---|
|  | 218 | else | 
|---|
|  | 219 | Name := Piece(Strings[i], U, 2); | 
|---|
|  | 220 | DocHasChildren := (Piece(Strings[i], U, 13) <> ''); | 
|---|
|  | 221 | if Node <> nil then if Node.HasChildren then | 
|---|
|  | 222 | tmpNode := Tree.FindPieceNode(MyID, 1, U, Node); | 
|---|
|  | 223 | if (tmpNode <> nil) and tmpNode.HasAsParent(Node) then | 
|---|
|  | 224 | Continue | 
|---|
|  | 225 | else | 
|---|
|  | 226 | begin | 
|---|
|  | 227 | case TabIndex of | 
|---|
|  | 228 | CT_NOTES:    AnObject := MakeNoteTreeObject(Strings[i]); | 
|---|
|  | 229 | CT_CONSULTS: AnObject := MakeConsultsNoteTreeObject(Strings[i]); | 
|---|
|  | 230 | CT_DCSUMM:   AnObject := MakeDCSummTreeObject(Strings[i]); | 
|---|
|  | 231 | else | 
|---|
|  | 232 | AnObject := nil; | 
|---|
|  | 233 | end; | 
|---|
|  | 234 | ChildNode := TORTreeNode(Tree.Items.AddChildObject(TORTreeNode(Node), Name, AnObject)); | 
|---|
|  | 235 | ChildNode.StringData := Strings[i]; | 
|---|
|  | 236 | SetTreeNodeImagesAndFormatting(ChildNode, TIUContext, TabIndex); | 
|---|
|  | 237 | if DocHasChildren then BuildDocumentTree(DocList, MyID, Tree, ChildNode, TIUContext, TabIndex); | 
|---|
|  | 238 | end; | 
|---|
|  | 239 | end; | 
|---|
|  | 240 | end; | 
|---|
|  | 241 | end; | 
|---|
|  | 242 |  | 
|---|
|  | 243 | procedure SetTreeNodeImagesAndFormatting(Node: TORTreeNode; CurrentContext: TTIUContext; TabIndex: integer); | 
|---|
|  | 244 | var | 
|---|
|  | 245 | tmpAuthor: int64; | 
|---|
|  | 246 | i: integer; | 
|---|
|  | 247 |  | 
|---|
|  | 248 | procedure MakeBold(ANode: TORTreeNode); | 
|---|
|  | 249 | var | 
|---|
|  | 250 | LookingForAddenda: boolean; | 
|---|
|  | 251 | begin | 
|---|
| [830] | 252 | if not assigned(Node) then exit; | 
|---|
| [456] | 253 | LookingForAddenda := (Pos('ADDENDUM', UpperCase(CurrentContext.Keyword)) > 0); | 
|---|
|  | 254 | with ANode do | 
|---|
|  | 255 | begin | 
|---|
|  | 256 | Bold := True; | 
|---|
| [830] | 257 | if assigned(Parent) then | 
|---|
| [456] | 258 | begin | 
|---|
|  | 259 | if (ImageIndex <> IMG_ADDENDUM) or ((ImageIndex = IMG_ADDENDUM) and LookingForAddenda) then | 
|---|
|  | 260 | Parent.Expand(False); | 
|---|
| [830] | 261 | if assigned(Parent.Parent) then | 
|---|
| [456] | 262 | begin | 
|---|
|  | 263 | if (Parent.ImageIndex <> IMG_ADDENDUM) or ((Parent.ImageIndex = IMG_ADDENDUM) and LookingForAddenda) then | 
|---|
|  | 264 | Parent.Parent.Expand(False); | 
|---|
| [830] | 265 | if assigned(Parent.Parent.Parent) then | 
|---|
| [456] | 266 | if (Parent.Parent.ImageIndex <> IMG_ADDENDUM) or ((Parent.Parent.ImageIndex = IMG_ADDENDUM) and LookingForAddenda) then | 
|---|
|  | 267 | Parent.Parent.Parent.Expand(False); | 
|---|
|  | 268 | end; | 
|---|
|  | 269 | end; | 
|---|
|  | 270 | end; | 
|---|
|  | 271 | end; | 
|---|
|  | 272 |  | 
|---|
|  | 273 | begin | 
|---|
|  | 274 | with Node, PDocTreeObject(Node.Data)^ do | 
|---|
|  | 275 | begin | 
|---|
|  | 276 | i := Pos('*', DocTitle); | 
|---|
|  | 277 | if i > 0 then i := i + 1 else i := 0; | 
|---|
|  | 278 | if (Copy(DocTitle, i + 1, 8) = 'Addendum') then | 
|---|
|  | 279 | ImageIndex := IMG_ADDENDUM | 
|---|
|  | 280 | else if (DocHasChildren = '') then | 
|---|
|  | 281 | ImageIndex := IMG_SINGLE | 
|---|
|  | 282 | else if Pos('+>', DocHasChildren) > 0 then | 
|---|
|  | 283 | ImageIndex := IMG_ID_CHILD_ADD | 
|---|
|  | 284 | else if (DocHasChildren = '>') then | 
|---|
|  | 285 | ImageIndex := IMG_ID_CHILD | 
|---|
|  | 286 | else if Pos('+<', DocHasChildren) > 0 then | 
|---|
|  | 287 | ImageIndex := IMG_IDPAR_ADDENDA_SHUT | 
|---|
|  | 288 | else if DocParent = '0' then | 
|---|
|  | 289 | begin | 
|---|
|  | 290 | ImageIndex    := IMG_TOP_LEVEL; | 
|---|
|  | 291 | SelectedIndex := IMG_TOP_LEVEL; | 
|---|
|  | 292 | StateIndex := -1; | 
|---|
|  | 293 | with CurrentContext, Node do | 
|---|
|  | 294 | begin | 
|---|
|  | 295 | if  Node.HasChildren and (GroupBy <> '') then case GroupBy[1] of | 
|---|
|  | 296 | 'T': Text := NC_TV_TEXT[TabIndex, StrToInt(DocID)] + ' by title'; | 
|---|
|  | 297 | 'D': Text := NC_TV_TEXT[TabIndex, StrToInt(DocID)] + ' by visit date'; | 
|---|
|  | 298 | 'L': Text := NC_TV_TEXT[TabIndex, StrToInt(DocID)] + ' by location'; | 
|---|
|  | 299 | 'A': Text := NC_TV_TEXT[TabIndex, StrToInt(DocID)] + ' by author'; | 
|---|
|  | 300 | end; | 
|---|
|  | 301 | if TabIndex <> CT_CONSULTS then | 
|---|
|  | 302 | begin | 
|---|
|  | 303 | if (DocID = '2') or (DocID ='3') then | 
|---|
|  | 304 | begin | 
|---|
|  | 305 | if StrToIntDef(Status, 0) in [NC_UNSIGNED, NC_UNCOSIGNED] then | 
|---|
|  | 306 | begin | 
|---|
|  | 307 | if Author = 0 then tmpAuthor := User.DUZ else tmpAuthor := Author; | 
|---|
|  | 308 | Text := Text + ' for ' + ExternalName(tmpAuthor, 200); | 
|---|
|  | 309 | end | 
|---|
|  | 310 | else | 
|---|
|  | 311 | Text := Text + ' for ' + User.Name; | 
|---|
|  | 312 | end; | 
|---|
|  | 313 | if DocID = '4' then | 
|---|
|  | 314 | Text := Text + ' for ' + ExternalName(Author, 200); | 
|---|
|  | 315 | end; | 
|---|
|  | 316 | end; | 
|---|
|  | 317 | end | 
|---|
|  | 318 | else | 
|---|
|  | 319 | case DocHasChildren[1] of | 
|---|
|  | 320 | '<': ImageIndex := IMG_IDNOTE_SHUT; | 
|---|
|  | 321 | '+': ImageIndex := IMG_PARENT; | 
|---|
|  | 322 | '%': begin | 
|---|
|  | 323 | StateIndex := -1; | 
|---|
|  | 324 | ImageIndex    := IMG_GROUP_SHUT; | 
|---|
|  | 325 | SelectedIndex := IMG_GROUP_OPEN; | 
|---|
|  | 326 | end; | 
|---|
|  | 327 | end; | 
|---|
|  | 328 | SelectedIndex := ImageIndex; | 
|---|
|  | 329 | if (ImageIndex in [IMG_TOP_LEVEL, IMG_GROUP_OPEN, IMG_GROUP_SHUT]) then | 
|---|
|  | 330 | StateIndex := IMG_NONE | 
|---|
|  | 331 | else | 
|---|
|  | 332 | begin | 
|---|
|  | 333 | if ImageCount > 0 then | 
|---|
|  | 334 | StateIndex := IMG_1_IMAGE | 
|---|
|  | 335 | else if ImageCount = 0 then | 
|---|
|  | 336 | StateIndex := IMG_NO_IMAGES | 
|---|
|  | 337 | else if ImageCount = -1 then | 
|---|
|  | 338 | StateIndex := IMG_IMAGES_HIDDEN; | 
|---|
|  | 339 | end; | 
|---|
|  | 340 | if (Parent <> nil) and | 
|---|
|  | 341 | (Parent.ImageIndex in [IMG_PARENT, IMG_IDNOTE_SHUT, IMG_IDNOTE_OPEN, IMG_IDPAR_ADDENDA_SHUT, IMG_IDPAR_ADDENDA_OPEN]) and | 
|---|
|  | 342 | (StateIndex in [IMG_1_IMAGE, IMG_IMAGES_HIDDEN]) then | 
|---|
|  | 343 | begin | 
|---|
|  | 344 | Parent.StateIndex := IMG_CHILD_HAS_IMAGES; | 
|---|
|  | 345 | end; | 
|---|
|  | 346 | (*        case ImageCount of | 
|---|
|  | 347 | 0: StateIndex := IMG_NO_IMAGES; | 
|---|
|  | 348 | 1: StateIndex := IMG_1_IMAGE; | 
|---|
|  | 349 | 2: StateIndex := IMG_2_IMAGES; | 
|---|
|  | 350 | else | 
|---|
|  | 351 | StateIndex := IMG_MANY_IMAGES; | 
|---|
|  | 352 | end;*) | 
|---|
|  | 353 | if Node.Parent <> nil then | 
|---|
|  | 354 | if not CurrentContext.Filtered then | 
|---|
|  | 355 | //don't bother to BOLD every entry | 
|---|
|  | 356 | else | 
|---|
|  | 357 | begin | 
|---|
|  | 358 | if (*ContextMatch(Node) then | 
|---|
|  | 359 | if (CurrentContext.KeyWord = '') or *)TextFound(Node, CurrentContext) then MakeBold(Node); | 
|---|
|  | 360 | end; | 
|---|
|  | 361 | end; | 
|---|
|  | 362 | end; | 
|---|
|  | 363 |  | 
|---|
|  | 364 | procedure TraverseTree(ATree: TTreeView; AListView: TListView; ANode: TTreeNode; MyNodeID: string; AContext: TTIUContext); | 
|---|
|  | 365 | var | 
|---|
|  | 366 | IncludeIt: Boolean; | 
|---|
|  | 367 | x: string; | 
|---|
|  | 368 | begin | 
|---|
|  | 369 | if ANode = nil then Exit; | 
|---|
|  | 370 | IncludeIt := False; | 
|---|
|  | 371 | if (ContextMatch(TORTreeNode(ANode), MyNodeID, AContext) and TextFound(TORTreeNode(ANode), AContext)) then | 
|---|
|  | 372 | with PDocTreeObject(ANode.Data)^ do | 
|---|
|  | 373 | begin | 
|---|
|  | 374 | if (AContext.GroupBy <> '') and | 
|---|
|  | 375 | (ATree.Selected.ImageIndex in [IMG_GROUP_OPEN, IMG_GROUP_SHUT]) then | 
|---|
|  | 376 | begin | 
|---|
|  | 377 | case AContext.GroupBy[1] of | 
|---|
|  | 378 | 'T': if (UpperCase(DocTitle) = UpperCase(PDocTreeObject(ATree.Selected.Data)^.DocTitle)) or | 
|---|
|  | 379 | (UpperCase(DocTitle) = UpperCase('Addendum to ' + PDocTreeObject(ATree.Selected.Data)^.DocTitle)) or | 
|---|
|  | 380 | (AContext.Filtered and TextFound(TORTreeNode(ANode), AContext)) then | 
|---|
|  | 381 | IncludeIt := True; | 
|---|
|  | 382 | 'D': begin | 
|---|
|  | 383 | x := PDocTreeObject(ATree.Selected.Data)^.DocID; | 
|---|
|  | 384 | if (Copy(x, 2, 3) = 'Vis') or (Copy(x, 2, 3) = 'Adm') then | 
|---|
|  | 385 | begin | 
|---|
|  | 386 | if Copy(VisitDate, 1, 3) = Copy(x, 2, 3) then | 
|---|
|  | 387 | IncludeIt := True; | 
|---|
|  | 388 | end | 
|---|
|  | 389 | else if Piece(Piece(VisitDate, ';', 2), '.', 1) = Copy(x, 2, Length(x) - 4) then | 
|---|
|  | 390 | IncludeIt := True; | 
|---|
|  | 391 | end; | 
|---|
|  | 392 | 'L': if MyNodeID + Location = PDocTreeObject(ATree.Selected.Data)^.DocID then | 
|---|
|  | 393 | IncludeIt := True; | 
|---|
|  | 394 | 'A': if MyNodeID + Piece(Author, ';', 2) = PDocTreeObject(ATree.Selected.Data)^.DocID then | 
|---|
|  | 395 | IncludeIt := True; | 
|---|
|  | 396 | end; | 
|---|
|  | 397 | end | 
|---|
|  | 398 | else | 
|---|
|  | 399 | IncludeIt := True; | 
|---|
|  | 400 | end; | 
|---|
|  | 401 | if IncludeIt then AddListViewItem(ANode, AListView); | 
|---|
|  | 402 | if ANode.HasChildren then TraverseTree(ATree, AListView, ANode.GetFirstChild, MyNodeID, AContext); | 
|---|
|  | 403 | TraverseTree(ATree, AListView, ANode.GetNextSibling, MyNodeID, AContext); | 
|---|
|  | 404 | end; | 
|---|
|  | 405 |  | 
|---|
|  | 406 | function ContextMatch(ANode: TORTreeNode; AParentID: string; AContext: TTIUContext): Boolean; | 
|---|
|  | 407 | var | 
|---|
|  | 408 | Status: string; | 
|---|
|  | 409 | Author: int64; | 
|---|
|  | 410 | begin | 
|---|
|  | 411 | Result := True; | 
|---|
|  | 412 | if not Assigned(ANode.Data) then Exit; | 
|---|
|  | 413 | Status := PDocTreeObject(ANode.Data)^.Status; | 
|---|
|  | 414 |  | 
|---|
|  | 415 | if (AContext.Status <> AParentID[1]) or (AContext.Author = 0) then | 
|---|
|  | 416 | Author := User.DUZ | 
|---|
|  | 417 | else | 
|---|
|  | 418 | Author := AContext.Author; | 
|---|
|  | 419 |  | 
|---|
|  | 420 | if Length(Trim(Status)) = 0 then exit; | 
|---|
|  | 421 | (*if PDocTreeObject(ANode.Data)^.DocHasChildren = '%' then Result := False else Result := True; | 
|---|
|  | 422 | Result := False;*) | 
|---|
|  | 423 | case AParentID[1] of | 
|---|
|  | 424 | '1':  Result := (Status = 'completed') or | 
|---|
|  | 425 | (Status = 'deleted')   or | 
|---|
|  | 426 | (Status = 'amended')   or | 
|---|
|  | 427 | (Status = 'uncosigned') or | 
|---|
|  | 428 | (Status = 'retracted'); | 
|---|
|  | 429 | '2':  Result := ((Status = 'unsigned')   or | 
|---|
|  | 430 | (Status = 'unreleased') or | 
|---|
|  | 431 | (Status = 'deleted')   or | 
|---|
|  | 432 | (Status = 'retracted') or | 
|---|
|  | 433 | (Status = 'unverified')) and | 
|---|
|  | 434 | (Piece(PDocTreeObject(ANode.Data)^.Author, ';', 1) = IntToStr(Author)); | 
|---|
|  | 435 | '3':  Result := ((Status = 'uncosigned') or | 
|---|
|  | 436 | (Status = 'unsigned')   or | 
|---|
|  | 437 | (Status = 'unreleased') or | 
|---|
|  | 438 | (Status = 'deleted')   or | 
|---|
|  | 439 | (Status = 'retracted') or | 
|---|
|  | 440 | (Status = 'unverified')) ;//and | 
|---|
|  | 441 | { TODO -oRich V. -cSort/Search : Uncosigned notes - need to check cosigner, not author, but don't have it } | 
|---|
|  | 442 | //(Piece(PDocTreeObject(ANode.Data)^.Author, ';', 1) = IntToStr(Author)); | 
|---|
|  | 443 | '4':  Result := (Piece(PDocTreeObject(ANode.Data)^.Author, ';', 1) = IntToStr(Author)); | 
|---|
|  | 444 | '5':  if PDocTreeObject(ANode.Data)^.DocHasChildren = '%' then Result := False | 
|---|
|  | 445 | else Result := (StrToFloat(PDocTreeObject(ANode.Data)^.DocFMDate) >= AContext.FMBeginDate) and | 
|---|
|  | 446 | (Trunc(StrToFloat(PDocTreeObject(ANode.Data)^.DocFMDate)) <= AContext.FMEndDate); | 
|---|
|  | 447 | 'N':  Result := True;     // NEW NOTE | 
|---|
|  | 448 | 'E':  Result := True;     // EDITING NOTE | 
|---|
|  | 449 | 'A':  Result := True;     // NEW ADDENDUM or processing alert | 
|---|
|  | 450 | end; | 
|---|
|  | 451 | end; | 
|---|
|  | 452 |  | 
|---|
|  | 453 | function TextFound(ANode: TORTreeNode; CurrentContext: TTIUContext): Boolean; | 
|---|
|  | 454 | var | 
|---|
|  | 455 | MySearch: string; | 
|---|
|  | 456 | begin | 
|---|
|  | 457 | Result := False; | 
|---|
|  | 458 | if not Assigned(ANode.Data) then Exit; | 
|---|
|  | 459 | if CurrentContext.SearchField <> '' then | 
|---|
|  | 460 | case CurrentContext.SearchField[1] of | 
|---|
|  | 461 | 'T': MySearch := PDocTreeObject(ANode.Data)^.DocTitle; | 
|---|
|  | 462 | 'S': MySearch := PDocTreeObject(ANode.Data)^.Subject; | 
|---|
|  | 463 | 'B': MySearch := PDocTreeObject(ANode.Data)^.DocTitle + ' ' + PDocTreeObject(ANode.Data)^.Subject; | 
|---|
|  | 464 | end; | 
|---|
|  | 465 | Result := (not CurrentContext.Filtered) or | 
|---|
|  | 466 | ((CurrentContext.Filtered) and (Pos(UpperCase(CurrentContext.KeyWord), UpperCase(MySearch)) > 0)); | 
|---|
|  | 467 | end; | 
|---|
|  | 468 |  | 
|---|
|  | 469 | procedure ResetDocTreeObjectStrings(AnObject: PDocTreeObject); | 
|---|
|  | 470 | begin | 
|---|
|  | 471 | with AnObject^ do | 
|---|
|  | 472 | begin | 
|---|
|  | 473 | DocID          := ''; | 
|---|
|  | 474 | DocDate        := ''; | 
|---|
|  | 475 | DocTitle       := ''; | 
|---|
|  | 476 | NodeText       := ''; | 
|---|
|  | 477 | VisitDate      := ''; | 
|---|
|  | 478 | DocFMDate      := ''; | 
|---|
|  | 479 | DocHasChildren := ''; | 
|---|
|  | 480 | DocParent      := ''; | 
|---|
|  | 481 | Author         := ''; | 
|---|
|  | 482 | PkgRef         := ''; | 
|---|
|  | 483 | Location       := ''; | 
|---|
|  | 484 | Status         := ''; | 
|---|
|  | 485 | Subject        := ''; | 
|---|
|  | 486 | OrderID        := ''; | 
|---|
|  | 487 | end; | 
|---|
|  | 488 | end; | 
|---|
|  | 489 |  | 
|---|
|  | 490 | procedure KillDocTreeObjects(TreeView: TORTreeView); | 
|---|
|  | 491 | var | 
|---|
|  | 492 | i: integer; | 
|---|
|  | 493 | begin | 
|---|
|  | 494 | with TreeView do | 
|---|
|  | 495 | for i := 0 to Items.Count-1 do | 
|---|
|  | 496 | begin | 
|---|
|  | 497 | if(Assigned(Items[i].Data)) then | 
|---|
|  | 498 | begin | 
|---|
|  | 499 | ResetDocTreeObjectStrings(PDocTreeObject(Items[i].Data)); | 
|---|
|  | 500 | Dispose(PDocTreeObject(Items[i].Data)); | 
|---|
|  | 501 | Items[i].Data := nil; | 
|---|
|  | 502 | end; | 
|---|
|  | 503 | end; | 
|---|
|  | 504 | end; | 
|---|
|  | 505 |  | 
|---|
|  | 506 | procedure KillDocTreeNode(ANode: TTreeNode); | 
|---|
|  | 507 | begin | 
|---|
|  | 508 | if(Assigned(ANode.Data)) then | 
|---|
|  | 509 | begin | 
|---|
|  | 510 | ResetDocTreeObjectStrings(PDocTreeObject(ANode.Data)); | 
|---|
|  | 511 | Dispose(PDocTreeObject(ANode.Data)); | 
|---|
|  | 512 | ANode.Data := nil; | 
|---|
|  | 513 | end; | 
|---|
|  | 514 | ANode.Owner.Delete(ANode); | 
|---|
|  | 515 | end; | 
|---|
|  | 516 |  | 
|---|
|  | 517 | procedure RemoveParentsWithNoChildren(Tree: TTreeView; Context: TTIUContext); | 
|---|
|  | 518 | var | 
|---|
|  | 519 | n: integer; | 
|---|
|  | 520 | begin | 
|---|
|  | 521 | with Tree do | 
|---|
|  | 522 | for n := Items.Count - 1 downto 0 do | 
|---|
|  | 523 | if ((Items[n].ImageIndex = IMG_GROUP_SHUT)) then | 
|---|
|  | 524 | begin | 
|---|
|  | 525 | if (not Items[n].HasChildren) then | 
|---|
|  | 526 | KillDocTreeNode(Items[n]) | 
|---|
|  | 527 | else if Context.Filtered then   // if any hits, would be IMG_GROUP_OPEN | 
|---|
|  | 528 | KillDocTreeNode(Items[n]); | 
|---|
|  | 529 | end; | 
|---|
|  | 530 | end; | 
|---|
|  | 531 |  | 
|---|
|  | 532 | procedure AddListViewItem(ANode: TTreeNode; AListView: TListView); | 
|---|
|  | 533 | var | 
|---|
|  | 534 | ListItem: TListItem; | 
|---|
|  | 535 | begin | 
|---|
|  | 536 | if not Assigned(ANode.Data) then Exit; | 
|---|
|  | 537 | with Anode, PDocTreeObject(ANode.Data)^, AListView do | 
|---|
|  | 538 | begin | 
|---|
|  | 539 | (*      if (FCurrentContext.Status = '1') and | 
|---|
|  | 540 | (Copy(DocTitle, 1 , 8) = 'Addendum') then Exit;*) | 
|---|
|  | 541 | if ANode.ImageIndex in [IMG_TOP_LEVEL, IMG_GROUP_OPEN, IMG_GROUP_SHUT] then Exit; | 
|---|
|  | 542 | ListItem := Items.Add; | 
|---|
|  | 543 | ListItem.Caption := DocDate;                     // date | 
|---|
|  | 544 | ListItem.StateIndex := ANode.StateIndex; | 
|---|
|  | 545 | ListItem.ImageIndex := ANode.ImageIndex; | 
|---|
|  | 546 | with ListItem.SubItems do | 
|---|
|  | 547 | begin | 
|---|
|  | 548 | Add(DocTitle);                               //  title | 
|---|
|  | 549 | Add(Subject);                                //  subject | 
|---|
|  | 550 | Add(MixedCase(Piece(Author, ';', 2)));       //  author | 
|---|
|  | 551 | Add(Location);                               //  location | 
|---|
|  | 552 | Add(DocFMDate);                              //  reference date (FM) | 
|---|
|  | 553 | Add(DocID);                                  //  TIUDA | 
|---|
|  | 554 | end; | 
|---|
|  | 555 | end; | 
|---|
|  | 556 | end; | 
|---|
|  | 557 |  | 
|---|
|  | 558 | function MakeNoteTreeObject(x: string): PDocTreeObject; | 
|---|
|  | 559 | var | 
|---|
|  | 560 | AnObject: PDocTreeObject; | 
|---|
|  | 561 | begin | 
|---|
|  | 562 | New(AnObject); | 
|---|
|  | 563 | with AnObject^ do | 
|---|
|  | 564 | begin | 
|---|
|  | 565 | DocID           := Piece(x, U, 1); | 
|---|
|  | 566 | DocDate         := FormatFMDateTime('mmm dd,yy', MakeFMDateTime(Piece(x, U, 3))); | 
|---|
|  | 567 | DocTitle        := Piece(x, U, 2); | 
|---|
|  | 568 | Location        := Piece(x, U, 6); | 
|---|
|  | 569 | NodeText        := MakeNoteDisplayText(x); | 
|---|
|  | 570 | ImageCount      := StrToIntDef(Piece(x, U, 11), 0); | 
|---|
|  | 571 | VisitDate       := Piece(x, U, 8); | 
|---|
|  | 572 | DocFMDate       := Piece(x, U, 3); | 
|---|
|  | 573 | DocHasChildren  := Piece(x, U, 13); | 
|---|
|  | 574 | if Copy(DocHasChildren, 1, 1) = '*' then | 
|---|
|  | 575 | DocHasChildren := Copy(DocHasChildren, 2, 5); | 
|---|
|  | 576 | DocParent       := Piece(x, U, 14); | 
|---|
|  | 577 | Author          := Piece(Piece(x, U, 5), ';', 1) + ';' + Piece(Piece(x, U, 5), ';', 3); | 
|---|
|  | 578 | PkgRef          := Piece(x, U, 10); | 
|---|
|  | 579 | Status          := Piece(x, U, 7); | 
|---|
|  | 580 | Subject         := Piece(x, U, 12); | 
|---|
|  | 581 | OrderByTitle    := Piece(x, U, 15) = '1'; | 
|---|
|  | 582 | end; | 
|---|
|  | 583 | Result := AnObject; | 
|---|
|  | 584 | end; | 
|---|
|  | 585 |  | 
|---|
|  | 586 | function MakeDCSummTreeObject(x: string): PDocTreeObject; | 
|---|
|  | 587 | var | 
|---|
|  | 588 | AnObject: PDocTreeObject; | 
|---|
|  | 589 | begin | 
|---|
|  | 590 | New(AnObject); | 
|---|
|  | 591 | if Copy(Piece(x, U, 9), 1, 4) = '    ' then SetPiece(x, U, 9, 'Dis: '); | 
|---|
|  | 592 | with AnObject^ do | 
|---|
|  | 593 | begin | 
|---|
|  | 594 | DocID            := Piece(x, U, 1); | 
|---|
|  | 595 | DocDate          := FormatFMDateTime('mmm dd,yy', MakeFMDateTime(Piece(x, U, 3))); | 
|---|
|  | 596 | DocTitle         := Piece(x, U, 2); | 
|---|
|  | 597 | Location         := Piece(x, U, 6); | 
|---|
|  | 598 | NodeText         := MakeDCSummDisplayText(x); | 
|---|
|  | 599 | DocFMDate        := Piece(x, U, 3); | 
|---|
|  | 600 | ImageCount       := StrToIntDef(Piece(x, U, 11), 0); | 
|---|
|  | 601 | DocHasChildren   := Piece(x, U, 13); | 
|---|
|  | 602 | if Copy(DocHasChildren, 1, 1) = '*' then | 
|---|
|  | 603 | DocHasChildren := Copy(DocHasChildren, 2, 5); | 
|---|
|  | 604 | DocParent        := Piece(x, U, 14); | 
|---|
|  | 605 | Author           := Piece(Piece(x, U, 5), ';', 1) + ';' + Piece(Piece(x, U, 5), ';', 3); | 
|---|
|  | 606 | PkgRef           := Piece(x, U, 10); | 
|---|
|  | 607 | Status           := Piece(x, U, 7); | 
|---|
|  | 608 | Subject          := Piece(x, U, 12); | 
|---|
|  | 609 | VisitDate        := Piece(x, U, 8); | 
|---|
|  | 610 | OrderByTitle    := Piece(x, U, 15) = '1'; | 
|---|
|  | 611 | end; | 
|---|
|  | 612 | Result := AnObject; | 
|---|
|  | 613 | end; | 
|---|
|  | 614 |  | 
|---|
|  | 615 | function MakeConsultsNoteTreeObject(x: string): PDocTreeObject; | 
|---|
|  | 616 | var | 
|---|
|  | 617 | AnObject: PDocTreeObject; | 
|---|
|  | 618 | begin | 
|---|
|  | 619 | New(AnObject); | 
|---|
|  | 620 | with AnObject^ do | 
|---|
|  | 621 | begin | 
|---|
|  | 622 | DocID           := Piece(x, U, 1); | 
|---|
|  | 623 | DocDate         := FormatFMDateTime('mmm dd,yy', MakeFMDateTime(Piece(x, U, 3))); | 
|---|
|  | 624 | DocTitle        := Piece(x, U, 2); | 
|---|
|  | 625 | Location        := Piece(x, U, 6); | 
|---|
|  | 626 | NodeText        := MakeConsultNoteDisplayText(x); | 
|---|
|  | 627 | DocFMDate       := Piece(x, U, 3); | 
|---|
|  | 628 | Status          := Piece(x, U, 7); | 
|---|
|  | 629 | Author          := Piece(Piece(x, U, 5), ';', 1) + ';' + Piece(Piece(x, U, 5), ';', 3); | 
|---|
|  | 630 | PkgRef          := Piece(x, U, 10); | 
|---|
|  | 631 | if Piece(PkgRef, ';', 2) = PKG_CONSULTS then | 
|---|
|  | 632 | OrderID       := GetConsultOrderIEN(StrToIntDef(Piece(PkgRef, ';', 1), 0)); | 
|---|
|  | 633 | ImageCount      := StrToIntDef(Piece(x, U, 11), 0); | 
|---|
|  | 634 | VisitDate       := Piece(x, U, 8); | 
|---|
|  | 635 | DocHasChildren  := Piece(x, U, 13); | 
|---|
|  | 636 | if Copy(DocHasChildren, 1, 1) = '*' then | 
|---|
|  | 637 | DocHasChildren := Copy(DocHasChildren, 2, 5); | 
|---|
|  | 638 | DocParent       := Piece(x, U, 14); | 
|---|
|  | 639 | OrderByTitle    := Piece(x, U, 15) = '1'; | 
|---|
|  | 640 | end; | 
|---|
|  | 641 | Result := AnObject; | 
|---|
|  | 642 | end; | 
|---|
|  | 643 |  | 
|---|
|  | 644 |  | 
|---|
|  | 645 | end. | 
|---|