| [459] | 1 | unit dShared;
 | 
|---|
 | 2 | interface
 | 
|---|
 | 3 | 
 | 
|---|
 | 4 | uses
 | 
|---|
 | 5 |   Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
 | 
|---|
 | 6 |   ComCtrls, ImgList, uTemplates, ORFn, ORNet, ExtCtrls, ORCtrls, Richedit;
 | 
|---|
 | 7 | 
 | 
|---|
 | 8 | type
 | 
|---|
 | 9 |   TdmodShared = class(TDataModule)
 | 
|---|
 | 10 |     imgTemplates: TImageList;
 | 
|---|
 | 11 |     imgReminders: TImageList;
 | 
|---|
 | 12 |     imgNotes: TImageList;
 | 
|---|
 | 13 |     imgImages: TImageList;
 | 
|---|
 | 14 |     imgReminders2: TImageList;
 | 
|---|
 | 15 |     imgConsults: TImageList;
 | 
|---|
 | 16 |     imgSurgery: TImageList;
 | 
|---|
 | 17 |     procedure dmodSharedCreate(Sender: TObject);
 | 
|---|
 | 18 |     procedure dmodSharedDestroy(Sender: TObject);
 | 
|---|
 | 19 |   private
 | 
|---|
 | 20 |     FTIUObjects: TStringList;
 | 
|---|
 | 21 |     FInEditor: boolean;
 | 
|---|
 | 22 |     FOnTemplateLock: TNotifyEvent;
 | 
|---|
 | 23 |     FTagIndex: longint;
 | 
|---|
 | 24 |     FDrawerTrees: TList;
 | 
|---|
 | 25 |     FRefreshObject: boolean;
 | 
|---|
 | 26 |   protected
 | 
|---|
 | 27 |     procedure EncounterLocationChanged(Sender: TObject);
 | 
|---|
 | 28 |   public
 | 
|---|
 | 29 |     function ImgIdx(Node: TTreeNode): integer;
 | 
|---|
 | 30 |     procedure AddTemplateNode(Tree: TTreeView; var EmptyCount: integer;
 | 
|---|
 | 31 |                               const tmpl: TTemplate; AllowInactive: boolean = FALSE;
 | 
|---|
 | 32 |                               const Owner: TTreeNode = nil);
 | 
|---|
 | 33 |     function ExpandNode(Tree: TTreeView; Node: TTreeNode;
 | 
|---|
 | 34 |               var EmptyCount: integer; AllowInactive: boolean = FALSE): boolean;
 | 
|---|
 | 35 |     procedure Resync(SyncNode: TTreeNode; AllowInactive: boolean;
 | 
|---|
 | 36 |                                 var EmptyCount: integer);
 | 
|---|
 | 37 |     procedure AddDrawerTree(DrawerForm: TForm);
 | 
|---|
 | 38 |     procedure RemoveDrawerTree(DrawerForm: TForm);
 | 
|---|
 | 39 |     procedure Reload;
 | 
|---|
 | 40 |     procedure LoadTIUObjects;
 | 
|---|
 | 41 |     function BoilerplateOK(const Txt, CRDelim: string; ObjList: TStringList;
 | 
|---|
 | 42 |                                                        var Err: TStringList): boolean;
 | 
|---|
 | 43 |     function TemplateOK(tmpl: TTemplate; Msg: string = ''): boolean;
 | 
|---|
 | 44 |     function NeedsCollapsing(Tree: TTreeView): boolean;
 | 
|---|
 | 45 |     procedure SelectNode(Tree: TORTreeView; GotoNodeID: string; var EmptyCount: integer);
 | 
|---|
 | 46 |     procedure ExpandTree(Tree: TORTreeView; ExpandString: string; var EmptyCount: integer;
 | 
|---|
 | 47 |                          AllowInactive: boolean = FALSE);
 | 
|---|
 | 48 |     function InDialog(Node: TTreeNode): boolean;
 | 
|---|
 | 49 |     property InEditor: boolean read FInEditor write FInEditor;
 | 
|---|
 | 50 |     property OnTemplateLock: TNotifyEvent read FOnTemplateLock write FOnTemplateLock;
 | 
|---|
 | 51 |     property TIUObjects: TStringList read FTIUObjects;
 | 
|---|
 | 52 |     property RefreshObject: boolean read FRefreshObject write FRefreshObject;
 | 
|---|
 | 53 |     procedure FindRichEditText(AFindDialog: TFindDialog; ARichEdit: TRichEdit);
 | 
|---|
 | 54 |     procedure ReplaceRichEditText(AReplaceDialog: TReplaceDialog; ARichEdit: TRichEdit);
 | 
|---|
 | 55 |   end;
 | 
|---|
 | 56 | 
 | 
|---|
 | 57 | var
 | 
|---|
 | 58 |   dmodShared: TdmodShared;
 | 
|---|
 | 59 | 
 | 
|---|
 | 60 | const
 | 
|---|
 | 61 |   ObjMarker = '^@@^';
 | 
|---|
 | 62 |   ObjMarkerLen = length(ObjMarker);
 | 
|---|
 | 63 |   DlgPropMarker = '^@=';
 | 
|---|
 | 64 |   DlgPropMarkerLen = length(DlgPropMarker);
 | 
|---|
 | 65 |   NoTextMarker = '<@>';
 | 
|---|
 | 66 | 
 | 
|---|
 | 67 | implementation
 | 
|---|
 | 68 | 
 | 
|---|
 | 69 | uses fDrawers, rTemplates, uCore, uTemplateFields, uEventHooks;
 | 
|---|
 | 70 | 
 | 
|---|
 | 71 | {$R *.DFM}
 | 
|---|
 | 72 | 
 | 
|---|
 | 73 | const
 | 
|---|
 | 74 |   TemplateImageIdx: array[TTemplateType, Boolean, Boolean] of integer =
 | 
|---|
 | 75 |                           //    Personal       Shared
 | 
|---|
 | 76 |                           //  Closed  Open   Closed  Open
 | 
|---|
 | 77 |                           (((    0,    0), (    0,    0)),  //  ttNone,
 | 
|---|
 | 78 |                            ((    0,    1), (    0,    1)),  //  ttMyRoot
 | 
|---|
 | 79 |                            ((    0,    1), (    0,    1)),  //  ttRoot
 | 
|---|
 | 80 |                            ((    0,    1), (    0,    1)),  //  ttTitles
 | 
|---|
 | 81 |                            ((    0,    1), (    0,    1)),  //  ttConsults
 | 
|---|
 | 82 |                            ((    0,    1), (    0,    1)),  //  ttProcedures
 | 
|---|
 | 83 |                            ((    2,    3), (   16,   17)),  //  ttClass
 | 
|---|
 | 84 |                            ((    4,    4), (   10,   10)),  //  ttDoc
 | 
|---|
 | 85 |                            ((    5,    6), (   11,   12)),  //  ttGroup
 | 
|---|
 | 86 |                            ((    7,    7), (   13,   13)),  //  ttDocEx
 | 
|---|
 | 87 |                            ((    8,    9), (   14,   15))); //  ttGroupEx
 | 
|---|
 | 88 | 
 | 
|---|
 | 89 |   DialogConvMax = 7;
 | 
|---|
 | 90 |   DialogImageXRef: array[0..DialogConvMax, Boolean] of integer =
 | 
|---|
 | 91 |                            ((5,18), (6,19),
 | 
|---|
 | 92 |                             (8,20), (9,21),
 | 
|---|
 | 93 |                             (11,22),(12,23),
 | 
|---|
 | 94 |                             (14,24),(15,25));
 | 
|---|
 | 95 |                             
 | 
|---|
 | 96 |   RemDlgIdx: array[boolean] of integer = (26, 27);
 | 
|---|
 | 97 |   COMObjIdx: array[boolean] of integer = (29, 28);
 | 
|---|
 | 98 | 
 | 
|---|
 | 99 | function TdmodShared.ImgIdx(Node: TTreeNode): integer;
 | 
|---|
 | 100 | var
 | 
|---|
 | 101 |   Typ: TTemplateType;
 | 
|---|
 | 102 |   i: integer;
 | 
|---|
 | 103 | 
 | 
|---|
 | 104 | begin
 | 
|---|
 | 105 |   Result := -1;
 | 
|---|
 | 106 |   if(assigned(Node.Data)) then
 | 
|---|
 | 107 |   begin
 | 
|---|
 | 108 |     with TTemplate(Node.Data) do
 | 
|---|
 | 109 |     begin
 | 
|---|
 | 110 |       if (RealType = ttDoc) and (IsReminderDialog) then
 | 
|---|
 | 111 |         Result := RemDlgIdx[(PersonalOwner <= 0)]
 | 
|---|
 | 112 |       else
 | 
|---|
 | 113 |       if (RealType = ttDoc) and (IsCOMObject) then
 | 
|---|
 | 114 |         Result := COMObjIdx[COMObjectOK(COMObject)]
 | 
|---|
 | 115 |       else
 | 
|---|
 | 116 |       begin
 | 
|---|
 | 117 |         Typ := TemplateType;
 | 
|---|
 | 118 |         if(Exclude and (Typ in [ttDocEx, ttGroupEx])) then
 | 
|---|
 | 119 |         begin
 | 
|---|
 | 120 |           if(not assigned(Node.Parent)) or (TTemplate(Node.Parent.Data).RealType <> ttGroup) then
 | 
|---|
 | 121 |           begin
 | 
|---|
 | 122 |             case Typ of
 | 
|---|
 | 123 |               ttDocEx: Typ := ttDoc;
 | 
|---|
 | 124 |               ttGroupEx: Typ := ttGroup;
 | 
|---|
 | 125 |             end;
 | 
|---|
 | 126 |           end;
 | 
|---|
 | 127 |         end;
 | 
|---|
 | 128 |         Result := TemplateImageIdx[Typ, (PersonalOwner <= 0),
 | 
|---|
 | 129 |                   (Node.Expanded and Node.HasChildren)];
 | 
|---|
 | 130 |         if(Dialog and (Typ in [ttGroup, ttGroupEx])) then
 | 
|---|
 | 131 |         begin
 | 
|---|
 | 132 |           for i := 0 to DialogConvMax do
 | 
|---|
 | 133 |           begin
 | 
|---|
 | 134 |             if(Result = DialogImageXRef[i, FALSE]) then
 | 
|---|
 | 135 |             begin
 | 
|---|
 | 136 |               Result := DialogImageXRef[i, TRUE];
 | 
|---|
 | 137 |               break;
 | 
|---|
 | 138 |             end;
 | 
|---|
 | 139 |           end;
 | 
|---|
 | 140 |         end;
 | 
|---|
 | 141 |       end;
 | 
|---|
 | 142 |     end;
 | 
|---|
 | 143 |   end;
 | 
|---|
 | 144 | end;
 | 
|---|
 | 145 | 
 | 
|---|
 | 146 | procedure TdmodShared.AddTemplateNode(Tree: TTreeView; var EmptyCount: integer;
 | 
|---|
 | 147 |                               const tmpl: TTemplate; AllowInactive: boolean = FALSE;
 | 
|---|
 | 148 |                               const Owner: TTreeNode = nil);
 | 
|---|
 | 149 | var
 | 
|---|
 | 150 |   Cur, Next: TTreeNode;
 | 
|---|
 | 151 |   Done: boolean;
 | 
|---|
 | 152 |   NewNode: TTreeNode;
 | 
|---|
 | 153 | 
 | 
|---|
 | 154 |   procedure AddChildObject(Owner: TTreeNode);
 | 
|---|
 | 155 |   begin
 | 
|---|
 | 156 |     NewNode := Tree.Items.AddChildObject(Owner, tmpl.PrintName, tmpl);
 | 
|---|
 | 157 |     TORTreeNode(NewNode).StringData := tmpl.ID + U + tmpl.PrintName;
 | 
|---|
 | 158 |     NewNode.Cut := not tmpl.Active;
 | 
|---|
 | 159 |     tmpl.AddNode(NewNode);
 | 
|---|
 | 160 |     Done := TRUE;
 | 
|---|
 | 161 |   end;
 | 
|---|
 | 162 | 
 | 
|---|
 | 163 | begin
 | 
|---|
 | 164 |   if((assigned(tmpl)) and ((tmpl.Active) or AllowInactive)) then
 | 
|---|
 | 165 |   begin
 | 
|---|
 | 166 |     Done := FALSE;
 | 
|---|
 | 167 |     NewNode := nil;
 | 
|---|
 | 168 |     if(assigned(Owner)) then
 | 
|---|
 | 169 |     begin
 | 
|---|
 | 170 |       Cur := Owner.GetFirstChild;
 | 
|---|
 | 171 |       if(not assigned(Cur)) then
 | 
|---|
 | 172 |         AddChildObject(Owner);
 | 
|---|
 | 173 |     end
 | 
|---|
 | 174 |     else
 | 
|---|
 | 175 |     begin
 | 
|---|
 | 176 |       Cur := Tree.Items.GetFirstNode;
 | 
|---|
 | 177 |       if(not assigned(Cur)) then
 | 
|---|
 | 178 |         AddChildObject(nil);
 | 
|---|
 | 179 |     end;
 | 
|---|
 | 180 |     if(not Done) then
 | 
|---|
 | 181 |     begin
 | 
|---|
 | 182 |       repeat
 | 
|---|
 | 183 |         if(Cur.Data = tmpl) then
 | 
|---|
 | 184 |           Done := TRUE
 | 
|---|
 | 185 |         else
 | 
|---|
 | 186 |         begin
 | 
|---|
 | 187 |           Next := Cur.GetNextSibling;
 | 
|---|
 | 188 |           if(assigned(Next)) then
 | 
|---|
 | 189 |             Cur := Next
 | 
|---|
 | 190 |           else
 | 
|---|
 | 191 |             AddChildObject(Owner);
 | 
|---|
 | 192 |         end;
 | 
|---|
 | 193 |       until Done;
 | 
|---|
 | 194 |     end;
 | 
|---|
 | 195 |     if(assigned(NewNode) and (InEditor or (not tmpl.HideItems)) and 
 | 
|---|
 | 196 |                              ((tmpl.Children in [tcActive, tcBoth]) or
 | 
|---|
 | 197 |                              ((tmpl.Children <> tcNone) and AllowInactive))) then
 | 
|---|
 | 198 |     begin
 | 
|---|
 | 199 |       Tree.Items.AddChild(NewNode, EmptyNodeText);
 | 
|---|
 | 200 |       inc(EmptyCount);
 | 
|---|
 | 201 |     end;
 | 
|---|
 | 202 |   end;
 | 
|---|
 | 203 | end;
 | 
|---|
 | 204 | 
 | 
|---|
 | 205 | function TdmodShared.ExpandNode(Tree: TTreeView; Node: TTreeNode;
 | 
|---|
 | 206 |               var EmptyCount: integer; AllowInactive: boolean = FALSE): boolean;
 | 
|---|
 | 207 | 
 | 
|---|
 | 208 | var
 | 
|---|
 | 209 |   TmpNode: TTreeNode;
 | 
|---|
 | 210 |   tmpl: TTemplate;
 | 
|---|
 | 211 |   i :integer;
 | 
|---|
 | 212 | 
 | 
|---|
 | 213 | begin
 | 
|---|
 | 214 |   TmpNode := Node.GetFirstChild;
 | 
|---|
 | 215 |   Result := TRUE;
 | 
|---|
 | 216 |   if((assigned(TmpNode)) and (TmpNode.Text = EmptyNodeText)) then
 | 
|---|
 | 217 |   begin
 | 
|---|
 | 218 |     TmpNode.Delete;
 | 
|---|
 | 219 |     dec(EmptyCount);
 | 
|---|
 | 220 |     tmpl := TTemplate(Node.Data);
 | 
|---|
 | 221 |     ExpandTemplate(tmpl);
 | 
|---|
 | 222 |     for i := 0 to tmpl.Items.Count-1 do
 | 
|---|
 | 223 |       AddTemplateNode(Tree, EmptyCount, TTemplate(tmpl.Items[i]),
 | 
|---|
 | 224 |                       AllowInactive, Node);
 | 
|---|
 | 225 |     if((tmpl.Children = tcNone) or ((not AllowInactive) and (tmpl.Children = tcInactive))) then
 | 
|---|
 | 226 |       Result := FALSE;
 | 
|---|
 | 227 |   end;
 | 
|---|
 | 228 | end;
 | 
|---|
 | 229 | 
 | 
|---|
 | 230 | procedure TdmodShared.Resync(SyncNode: TTreeNode; AllowInactive: boolean;
 | 
|---|
 | 231 |                                 var EmptyCount: integer);
 | 
|---|
 | 232 | var
 | 
|---|
 | 233 |   FromGet: boolean;
 | 
|---|
 | 234 |   IDCount, SyncLevel, i: integer;
 | 
|---|
 | 235 |   SyncExpanded: boolean;
 | 
|---|
 | 236 |   //SelNode,
 | 
|---|
 | 237 |   Node: TTreeNode;
 | 
|---|
 | 238 |   Template: TTemplate;
 | 
|---|
 | 239 |   IDSort, CurExp: TStringList;
 | 
|---|
 | 240 |   SelID, TopID: string;
 | 
|---|
 | 241 |   DoSel, DoTop: boolean;
 | 
|---|
 | 242 |   Tree: TTreeView;
 | 
|---|
 | 243 |   First: boolean;
 | 
|---|
 | 244 |   TagCount: longint;
 | 
|---|
 | 245 | 
 | 
|---|
 | 246 |   function InSyncNode(Node: TTreeNode): boolean;
 | 
|---|
 | 247 |   var
 | 
|---|
 | 248 |     TmpNode: TTreeNode;
 | 
|---|
 | 249 | 
 | 
|---|
 | 250 |   begin
 | 
|---|
 | 251 |     Result := FALSE;
 | 
|---|
 | 252 |     TmpNode := Node;
 | 
|---|
 | 253 |     while((not Result) and assigned(TmpNode)) do
 | 
|---|
 | 254 |     begin
 | 
|---|
 | 255 |       if(TmpNode = SyncNode) then
 | 
|---|
 | 256 |         Result := TRUE
 | 
|---|
 | 257 |       else
 | 
|---|
 | 258 |         TmpNode := TmpNode.Parent;
 | 
|---|
 | 259 |     end;
 | 
|---|
 | 260 |   end;
 | 
|---|
 | 261 | 
 | 
|---|
 | 262 |   function GetID(Node: TTreeNode): string;
 | 
|---|
 | 263 |   var
 | 
|---|
 | 264 |     tmpl: TTemplate;
 | 
|---|
 | 265 |     IDX: string;
 | 
|---|
 | 266 |     
 | 
|---|
 | 267 |   begin
 | 
|---|
 | 268 |     inc(IDCount);
 | 
|---|
 | 269 |     Result := '';
 | 
|---|
 | 270 |     if(assigned(Node) and assigned(Node.Data)) then
 | 
|---|
 | 271 |     begin
 | 
|---|
 | 272 |       tmpl := TTemplate(Node.Data);
 | 
|---|
 | 273 |       if((tmpl.ID = '') or (tmpl.ID = '0')) then
 | 
|---|
 | 274 |       begin
 | 
|---|
 | 275 |         if(tmpl.LastTagIndex <> FTagIndex) then
 | 
|---|
 | 276 |         begin
 | 
|---|
 | 277 |           tmpl.LastTagIndex := FTagIndex;
 | 
|---|
 | 278 |           inc(TagCount);
 | 
|---|
 | 279 |           tmpl.tag := TagCount;
 | 
|---|
 | 280 |         end;
 | 
|---|
 | 281 |         IDX := '<'+IntToStr(tmpl.Tag)+'>';
 | 
|---|
 | 282 |       end
 | 
|---|
 | 283 |       else
 | 
|---|
 | 284 |         IDX := tmpl.ID;
 | 
|---|
 | 285 |       if(Node <> SyncNode) and (assigned(Node.Parent)) then
 | 
|---|
 | 286 |         Result := U + GetID(Node.Parent);
 | 
|---|
 | 287 |       Result := IDX + Result;
 | 
|---|
 | 288 |     end;
 | 
|---|
 | 289 |     dec(IDCount);
 | 
|---|
 | 290 |     if((not FromGet) and (IDCount = 0) and (Result <> '')) then
 | 
|---|
 | 291 |       Result := IntToStr(Node.AbsoluteIndex) + U + Result;
 | 
|---|
 | 292 |   end;
 | 
|---|
 | 293 | 
 | 
|---|
 | 294 |   function GetNode(ID: string): TTreeNode;
 | 
|---|
 | 295 |   var
 | 
|---|
 | 296 |     idx, i :integer;
 | 
|---|
 | 297 |     TrueID, TmpStr: string;
 | 
|---|
 | 298 |     TmpNode: TTreeNode;
 | 
|---|
 | 299 | 
 | 
|---|
 | 300 |   begin
 | 
|---|
 | 301 |     Result := nil;
 | 
|---|
 | 302 |     if(ID <> '') then
 | 
|---|
 | 303 |     begin
 | 
|---|
 | 304 |       idx := StrToIntDef(Piece(ID,U,1),0);
 | 
|---|
 | 305 |       i := pos(U,ID);
 | 
|---|
 | 306 |       if(i > 0) then
 | 
|---|
 | 307 |       begin
 | 
|---|
 | 308 |         delete(ID,1,i);
 | 
|---|
 | 309 |         FromGet := TRUE;
 | 
|---|
 | 310 |         try
 | 
|---|
 | 311 |           TmpNode := SyncNode.GetFirstChild;
 | 
|---|
 | 312 |           while ((not assigned(Result)) and (assigned(TmpNode)) and
 | 
|---|
 | 313 |                  (TmpNode.Level > SyncLevel)) do
 | 
|---|
 | 314 |           begin
 | 
|---|
 | 315 |             if(GetID(TmpNode) = ID) then
 | 
|---|
 | 316 |               Result := TmpNode
 | 
|---|
 | 317 |             else
 | 
|---|
 | 318 |               TmpNode := TmpNode.GetNext;
 | 
|---|
 | 319 |           end;
 | 
|---|
 | 320 |           if(not assigned(Result)) then
 | 
|---|
 | 321 |           begin
 | 
|---|
 | 322 |             TrueID := piece(ID,U,1);
 | 
|---|
 | 323 |             TmpNode := SyncNode.GetFirstChild;
 | 
|---|
 | 324 |             while ((not assigned(Result)) and (assigned(TmpNode)) and
 | 
|---|
 | 325 |                    (TmpNode.Level > SyncLevel)) do
 | 
|---|
 | 326 |             begin
 | 
|---|
 | 327 |               if(assigned(TmpNode.Data) and (TTemplate(TmpNode.Data).ID = TrueID)) then
 | 
|---|
 | 328 |               begin
 | 
|---|
 | 329 |                 TmpStr := IntToStr(abs(idx-TmpNode.AbsoluteIndex));
 | 
|---|
 | 330 |                 TmpStr := copy('000000',1,7-length(TmpStr))+TmpStr;
 | 
|---|
 | 331 |                 IDSort.AddObject(TmpStr,TmpNode);
 | 
|---|
 | 332 |               end;
 | 
|---|
 | 333 |               TmpNode := TmpNode.GetNext;
 | 
|---|
 | 334 |             end;
 | 
|---|
 | 335 |             if(IDSort.Count > 0) then
 | 
|---|
 | 336 |             begin
 | 
|---|
 | 337 |               IDSort.Sort;
 | 
|---|
 | 338 |               Result := TTreeNode(IDSort.Objects[0]);
 | 
|---|
 | 339 |               IDSort.Clear;
 | 
|---|
 | 340 |             end;
 | 
|---|
 | 341 |           end;
 | 
|---|
 | 342 |         finally
 | 
|---|
 | 343 |           FromGet := FALSE;
 | 
|---|
 | 344 |         end;
 | 
|---|
 | 345 |       end;
 | 
|---|
 | 346 |     end;
 | 
|---|
 | 347 |   end;
 | 
|---|
 | 348 | 
 | 
|---|
 | 349 |   procedure BuildNodes(tmpl: TTemplate; Owner: TTreeNode);
 | 
|---|
 | 350 |   var
 | 
|---|
 | 351 |     i: integer;
 | 
|---|
 | 352 |     TmpNode: TTreeNode;
 | 
|---|
 | 353 | 
 | 
|---|
 | 354 |   begin
 | 
|---|
 | 355 |     if(tmpl.Active or AllowInactive) then
 | 
|---|
 | 356 |     begin
 | 
|---|
 | 357 |       if(First) then
 | 
|---|
 | 358 |       begin
 | 
|---|
 | 359 |         First := FALSE;
 | 
|---|
 | 360 |         TmpNode := Owner;
 | 
|---|
 | 361 |       end
 | 
|---|
 | 362 |       else
 | 
|---|
 | 363 |       begin
 | 
|---|
 | 364 |         TmpNode := Tree.Items.AddChildObject(Owner, tmpl.PrintName, tmpl);
 | 
|---|
 | 365 |         TORTreeNode(TmpNode).StringData := tmpl.ID + U + tmpl.PrintName;
 | 
|---|
 | 366 |         TmpNode.Cut := not tmpl.Active;
 | 
|---|
 | 367 |         tmpl.AddNode(TmpNode);
 | 
|---|
 | 368 |       end;
 | 
|---|
 | 369 |       if(tmpl.Expanded) then
 | 
|---|
 | 370 |       begin
 | 
|---|
 | 371 |         for i := 0 to tmpl.Items.Count-1 do
 | 
|---|
 | 372 |           BuildNodes(TTemplate(tmpl.Items[i]), TmpNode);
 | 
|---|
 | 373 |       end
 | 
|---|
 | 374 |       else
 | 
|---|
 | 375 |       if(InEditor or (not tmpl.HideItems)) and
 | 
|---|
 | 376 |          ((tmpl.Children in [tcActive, tcBoth]) or
 | 
|---|
 | 377 |          (AllowInactive and (tmpl.Children = tcInactive))) then
 | 
|---|
 | 378 |       begin
 | 
|---|
 | 379 |         Tree.Items.AddChild(TmpNode, EmptyNodeText);
 | 
|---|
 | 380 |         inc(EmptyCount);
 | 
|---|
 | 381 |       end;
 | 
|---|
 | 382 |     end;
 | 
|---|
 | 383 |   end;
 | 
|---|
 | 384 | 
 | 
|---|
 | 385 | begin
 | 
|---|
 | 386 |   if(assigned(SyncNode)) then
 | 
|---|
 | 387 |   begin
 | 
|---|
 | 388 |     TagCount := 0;
 | 
|---|
 | 389 |     inc(FTagIndex);
 | 
|---|
 | 390 |     Tree := TTreeView(SyncNode.TreeView);
 | 
|---|
 | 391 |     Tree.Items.BeginUpdate;
 | 
|---|
 | 392 |     try
 | 
|---|
 | 393 |       SyncExpanded := SyncNode.Expanded;
 | 
|---|
 | 394 |       Template := TTemplate(SyncNode.Data);
 | 
|---|
 | 395 |       SyncLevel := SyncNode.Level;
 | 
|---|
 | 396 |       FromGet := FALSE;
 | 
|---|
 | 397 |       IDCount := 0;
 | 
|---|
 | 398 |       IDSort := TStringList.Create;
 | 
|---|
 | 399 |       try
 | 
|---|
 | 400 |       {-- Get the Current State of the tree --}
 | 
|---|
 | 401 |         CurExp := TStringList.Create;
 | 
|---|
 | 402 |         try
 | 
|---|
 | 403 |           Node := Tree.TopItem;
 | 
|---|
 | 404 |           DoTop := InSyncNode(Node);
 | 
|---|
 | 405 |           if(DoTop) then
 | 
|---|
 | 406 |             TopID := GetID(Node);
 | 
|---|
 | 407 | 
 | 
|---|
 | 408 |           Node := Tree.Selected;
 | 
|---|
 | 409 |           DoSel := InSyncNode(Node);
 | 
|---|
 | 410 |           if(DoSel) then
 | 
|---|
 | 411 |             SelID := GetID(Node);
 | 
|---|
 | 412 | 
 | 
|---|
 | 413 |           Node := SyncNode.GetFirstChild;
 | 
|---|
 | 414 |           while ((assigned(Node)) and (Node.Level > SyncLevel)) do
 | 
|---|
 | 415 |           begin
 | 
|---|
 | 416 |             if(Node.Text = EmptyNodeText) then
 | 
|---|
 | 417 |               dec(EmptyCount)
 | 
|---|
 | 418 |             else
 | 
|---|
 | 419 |             if(Node.Expanded) then
 | 
|---|
 | 420 |               CurExp.Add(GetID(Node));
 | 
|---|
 | 421 |             if(assigned(Node.Data)) then
 | 
|---|
 | 422 |               TTemplate(Node.Data).RemoveNode(Node);
 | 
|---|
 | 423 |             Node := Node.GetNext;
 | 
|---|
 | 424 |           end;
 | 
|---|
 | 425 | 
 | 
|---|
 | 426 |         {-- Recursively Rebuild the Tree --}
 | 
|---|
 | 427 |           SyncNode.DeleteChildren;
 | 
|---|
 | 428 |           First := TRUE;
 | 
|---|
 | 429 |           BuildNodes(Template, SyncNode);
 | 
|---|
 | 430 | 
 | 
|---|
 | 431 |         {-- Attempt to restore Tree to it's former State --}
 | 
|---|
 | 432 |           SyncNode.Expanded := SyncExpanded;
 | 
|---|
 | 433 |           for i := 0 to CurExp.Count-1 do
 | 
|---|
 | 434 |           begin
 | 
|---|
 | 435 |             Node := GetNode(CurExp[i]);
 | 
|---|
 | 436 |             if(assigned(Node)) then
 | 
|---|
 | 437 |               Node.Expand(FALSE);
 | 
|---|
 | 438 |           end;
 | 
|---|
 | 439 | 
 | 
|---|
 | 440 |           if(DoTop) and (TopID <> '') then
 | 
|---|
 | 441 |           begin
 | 
|---|
 | 442 |             Node := GetNode(TopID);
 | 
|---|
 | 443 |             if(assigned(Node)) then
 | 
|---|
 | 444 |               Tree.TopItem := Node;
 | 
|---|
 | 445 |           end;
 | 
|---|
 | 446 | 
 | 
|---|
 | 447 |           if(DoSel) and (SelID <> '') then
 | 
|---|
 | 448 |           begin
 | 
|---|
 | 449 |             Node := GetNode(SelID);
 | 
|---|
 | 450 |             if(assigned(Node)) then
 | 
|---|
 | 451 |             begin
 | 
|---|
 | 452 |               Tree.Selected := Node;
 | 
|---|
 | 453 |               Node.MakeVisible;
 | 
|---|
 | 454 |             end;
 | 
|---|
 | 455 |           end;
 | 
|---|
 | 456 | 
 | 
|---|
 | 457 |         finally
 | 
|---|
 | 458 |           CurExp.Free;
 | 
|---|
 | 459 |         end;
 | 
|---|
 | 460 | 
 | 
|---|
 | 461 |       finally
 | 
|---|
 | 462 |         IDSort.Free;
 | 
|---|
 | 463 |       end;
 | 
|---|
 | 464 | 
 | 
|---|
 | 465 |     finally
 | 
|---|
 | 466 |       Tree.Items.EndUpdate;
 | 
|---|
 | 467 |     end;
 | 
|---|
 | 468 |   end;
 | 
|---|
 | 469 | end;
 | 
|---|
 | 470 | 
 | 
|---|
 | 471 | 
 | 
|---|
 | 472 | procedure TdmodShared.dmodSharedCreate(Sender: TObject);
 | 
|---|
 | 473 | begin
 | 
|---|
 | 474 |   FDrawerTrees := TList.Create;
 | 
|---|
 | 475 |   imgReminders.Overlay(6,0);
 | 
|---|
 | 476 |   imgReminders.Overlay(7,1);
 | 
|---|
 | 477 |   imgReminders2.Overlay(4,0);
 | 
|---|
 | 478 | end;
 | 
|---|
 | 479 | 
 | 
|---|
 | 480 | procedure TdmodShared.dmodSharedDestroy(Sender: TObject);
 | 
|---|
 | 481 | begin
 | 
|---|
 | 482 |   KillObj(@FDrawerTrees);
 | 
|---|
 | 483 |   KillObj(@FTIUObjects);
 | 
|---|
 | 484 | end;
 | 
|---|
 | 485 | 
 | 
|---|
 | 486 | procedure TdmodShared.AddDrawerTree(DrawerForm: TForm);
 | 
|---|
 | 487 | begin
 | 
|---|
 | 488 |   if(assigned(FDrawerTrees)) and (FDrawerTrees.IndexOf(DrawerForm) < 0) then
 | 
|---|
 | 489 |     FDrawerTrees.Add(DrawerForm);
 | 
|---|
 | 490 |   Encounter.Notifier.NotifyWhenChanged(EncounterLocationChanged);
 | 
|---|
 | 491 | end;
 | 
|---|
 | 492 | 
 | 
|---|
 | 493 | procedure TdmodShared.RemoveDrawerTree(DrawerForm: TForm);
 | 
|---|
 | 494 | var
 | 
|---|
 | 495 |   idx: integer;
 | 
|---|
 | 496 | 
 | 
|---|
 | 497 | begin
 | 
|---|
 | 498 |   if(assigned(FDrawerTrees)) then
 | 
|---|
 | 499 |   begin
 | 
|---|
 | 500 |     idx := FDrawerTrees.IndexOf(DrawerForm);
 | 
|---|
 | 501 |     if(idx >= 0) then
 | 
|---|
 | 502 |       FDrawerTrees.Delete(idx);
 | 
|---|
 | 503 |   end;
 | 
|---|
 | 504 | end;
 | 
|---|
 | 505 | 
 | 
|---|
 | 506 | procedure TdmodShared.Reload;
 | 
|---|
 | 507 | var
 | 
|---|
 | 508 |   i: integer;
 | 
|---|
 | 509 | 
 | 
|---|
 | 510 | begin
 | 
|---|
 | 511 |   if(assigned(FDrawerTrees)) then
 | 
|---|
 | 512 |   begin
 | 
|---|
 | 513 |     ReleaseTemplates;
 | 
|---|
 | 514 |     for i := 0 to FDrawerTrees.Count-1 do
 | 
|---|
 | 515 |       TfrmDrawers(FDrawerTrees[i]).ExternalReloadTemplates;
 | 
|---|
 | 516 |   end;
 | 
|---|
 | 517 | end;
 | 
|---|
 | 518 | 
 | 
|---|
 | 519 | procedure TdmodShared.LoadTIUObjects;
 | 
|---|
 | 520 | var
 | 
|---|
 | 521 |   i: integer;
 | 
|---|
 | 522 | 
 | 
|---|
 | 523 | begin
 | 
|---|
 | 524 |   if(not assigned(FTIUObjects)) or (FRefreshObject = true)  then
 | 
|---|
 | 525 |   begin
 | 
|---|
| [460] | 526 |     if(not assigned(FTIUObjects)) then
 | 
|---|
 | 527 |       FTIUObjects := TStringList.Create;
 | 
|---|
| [459] | 528 |     FTIUObjects.Clear;
 | 
|---|
 | 529 |     GetObjectList;
 | 
|---|
 | 530 |     for i := 0 to RPCBrokerV.Results.Count-1 do
 | 
|---|
 | 531 |       FTIUObjects.Add(MixedCase(Piece(RPCBrokerV.Results[i],U,2))+U+RPCBrokerV.Results[i]);
 | 
|---|
 | 532 |     FTIUObjects.Sort;
 | 
|---|
 | 533 |     FRefreshObject := False;
 | 
|---|
 | 534 |    end;
 | 
|---|
 | 535 | end;
 | 
|---|
 | 536 | 
 | 
|---|
 | 537 | function TdmodShared.NeedsCollapsing(Tree: TTreeView): boolean;
 | 
|---|
 | 538 | var
 | 
|---|
 | 539 |   Node: TTreeNode;
 | 
|---|
 | 540 | 
 | 
|---|
 | 541 | begin
 | 
|---|
 | 542 |   Result := FALSE;
 | 
|---|
 | 543 |   if(assigned(Tree)) then
 | 
|---|
 | 544 |   begin
 | 
|---|
 | 545 |     Node := Tree.Items.GetFirstNode;
 | 
|---|
 | 546 |     while((not Result) and assigned(Node)) do
 | 
|---|
 | 547 |     begin
 | 
|---|
 | 548 |       Result := Node.Expanded;
 | 
|---|
 | 549 |       Node := Node.GetNextSibling;
 | 
|---|
 | 550 |     end;
 | 
|---|
 | 551 |   end;
 | 
|---|
 | 552 | end;
 | 
|---|
 | 553 | 
 | 
|---|
 | 554 | function TdmodShared.BoilerplateOK(const Txt, CRDelim: string; ObjList: TStringList;
 | 
|---|
 | 555 |                                                                var Err: TStringList): boolean;
 | 
|---|
 | 556 | var
 | 
|---|
 | 557 |   cnt, i, j, p: integer;
 | 
|---|
 | 558 |   tmp,obj: string;
 | 
|---|
 | 559 |   BadObj, ok: boolean;
 | 
|---|
 | 560 | 
 | 
|---|
 | 561 |   procedure AddErr(Amsg: string);
 | 
|---|
 | 562 |   begin
 | 
|---|
 | 563 |     if(not assigned(Err)) then
 | 
|---|
 | 564 |       Err := TStringList.Create;
 | 
|---|
 | 565 |     Err.Add(Amsg)
 | 
|---|
 | 566 |   end;
 | 
|---|
 | 567 | 
 | 
|---|
 | 568 |   function ErrCount: integer;
 | 
|---|
 | 569 |   begin
 | 
|---|
 | 570 |     if(Assigned(Err)) then
 | 
|---|
 | 571 |       Result := Err.Count
 | 
|---|
 | 572 |     else
 | 
|---|
 | 573 |       Result := 0;
 | 
|---|
 | 574 |   end;
 | 
|---|
 | 575 | 
 | 
|---|
 | 576 | begin
 | 
|---|
 | 577 |   if(assigned(ObjList)) then
 | 
|---|
 | 578 |     ObjList.Clear;
 | 
|---|
 | 579 |   cnt := ErrCount;
 | 
|---|
 | 580 |   tmp := Txt;
 | 
|---|
 | 581 |   BadObj := FALSE;
 | 
|---|
 | 582 |   repeat
 | 
|---|
 | 583 |     i := pos('|',tmp);
 | 
|---|
 | 584 |     if(i > 0) then
 | 
|---|
 | 585 |     begin
 | 
|---|
 | 586 |       delete(tmp,1,i);
 | 
|---|
 | 587 |       j := pos('|',tmp);
 | 
|---|
 | 588 |       if(j = 0) then
 | 
|---|
 | 589 |       begin
 | 
|---|
 | 590 |         AddErr('Unpaired "|" in Boilerplate');
 | 
|---|
 | 591 |         continue;
 | 
|---|
 | 592 |       end;
 | 
|---|
 | 593 |       obj := copy(tmp,1,j-1);
 | 
|---|
 | 594 |       delete(tmp,1,j);
 | 
|---|
 | 595 |       if(obj = '') then
 | 
|---|
 | 596 |       begin
 | 
|---|
 | 597 |         AddErr('Brackets "||" are there, but there''s no name inside it.');
 | 
|---|
 | 598 |         continue;
 | 
|---|
 | 599 |       end;
 | 
|---|
 | 600 |       j := pos(CRDelim, obj);
 | 
|---|
 | 601 |       if(j > 0) then
 | 
|---|
 | 602 |       begin
 | 
|---|
 | 603 |         AddErr('Object "'+copy(obj,1,j-1)+'" split between lines');
 | 
|---|
 | 604 |         continue;
 | 
|---|
 | 605 |       end;
 | 
|---|
 | 606 |       LoadTIUObjects;
 | 
|---|
 | 607 |       ok := FALSE;
 | 
|---|
 | 608 |       for j := 0 to FTIUObjects.Count-1 do
 | 
|---|
 | 609 |       begin
 | 
|---|
 | 610 |         for p := 3 to 5 do
 | 
|---|
 | 611 |         begin
 | 
|---|
 | 612 |           if(obj = piece(FTIUObjects[j],U,p)) then
 | 
|---|
 | 613 |           begin
 | 
|---|
 | 614 |             ok := TRUE;
 | 
|---|
 | 615 |             if(assigned(ObjList)) and (ObjList.IndexOf(ObjMarker + obj) < 0) then
 | 
|---|
 | 616 |             begin
 | 
|---|
 | 617 |               ObjList.Add(ObjMarker + obj);
 | 
|---|
 | 618 |               ObjList.Add('|' + obj + '|');
 | 
|---|
 | 619 |             end;
 | 
|---|
 | 620 |             break;
 | 
|---|
 | 621 |           end;
 | 
|---|
 | 622 |         end;
 | 
|---|
 | 623 |         if(ok) then break;
 | 
|---|
 | 624 |       end;
 | 
|---|
 | 625 |       if(not ok) then
 | 
|---|
 | 626 |       begin
 | 
|---|
 | 627 |         AddErr('Object "'+obj+'" not found.');
 | 
|---|
 | 628 |         BadObj := TRUE;
 | 
|---|
 | 629 |       end;
 | 
|---|
 | 630 |     end;
 | 
|---|
 | 631 |   until(i=0);
 | 
|---|
 | 632 |   Result := (cnt = ErrCount);
 | 
|---|
 | 633 |   if(not Result) then
 | 
|---|
 | 634 |   begin
 | 
|---|
 | 635 |     Err.Insert(0,'Boilerplate Contains Errors:'); 
 | 
|---|
 | 636 |     Err.Insert(1,'');
 | 
|---|
 | 637 |     if(BadObj) then
 | 
|---|
 | 638 |     begin
 | 
|---|
 | 639 |       Err.Add('');
 | 
|---|
 | 640 |       Err.Add('Use UPPERCASE and object''s exact NAME, PRINT NAME, or ABBREVIATION');
 | 
|---|
 | 641 |       Err.Add('Any of these may have changed since an object was embedded.');
 | 
|---|
 | 642 |     end;
 | 
|---|
 | 643 |   end;
 | 
|---|
 | 644 |   if(assigned(ObjList) and (ObjList.Count > 0)) then
 | 
|---|
 | 645 |     ObjList.Add(ObjMarker);
 | 
|---|
 | 646 | end;
 | 
|---|
 | 647 | 
 | 
|---|
 | 648 | function TdmodShared.TemplateOK(tmpl: TTemplate; Msg: string = ''): boolean;
 | 
|---|
 | 649 | var
 | 
|---|
 | 650 |   Err: TStringList;
 | 
|---|
 | 651 |   btns: TMsgDlgButtons;
 | 
|---|
 | 652 | 
 | 
|---|
 | 653 | begin
 | 
|---|
 | 654 |   Err := nil;
 | 
|---|
 | 655 |   try
 | 
|---|
 | 656 |     Result := BoilerplateOK(tmpl.FullBoilerplate, #13, nil, Err);
 | 
|---|
 | 657 |     if(not Result) then
 | 
|---|
 | 658 |     begin
 | 
|---|
 | 659 |       if(Msg = 'OK') then
 | 
|---|
 | 660 |         btns := [mbOK]
 | 
|---|
 | 661 |       else
 | 
|---|
 | 662 |       begin
 | 
|---|
 | 663 |         btns := [mbAbort, mbIgnore];
 | 
|---|
 | 664 |         Err.Add('');
 | 
|---|
 | 665 |         if(Msg = '') then
 | 
|---|
 | 666 |           Msg := 'template insertion';
 | 
|---|
 | 667 |         Err.Add('Do you want to Abort '+Msg+', or Ignore the error and continue?');
 | 
|---|
 | 668 |       end;
 | 
|---|
 | 669 |       Result := (MessageDlg(Err.Text, mtError, btns, 0) = mrIgnore);
 | 
|---|
 | 670 |     end;
 | 
|---|
 | 671 |   finally
 | 
|---|
 | 672 |     if(assigned(Err)) then
 | 
|---|
 | 673 |       Err.Free;
 | 
|---|
 | 674 |   end;
 | 
|---|
 | 675 |   if Result then
 | 
|---|
 | 676 |     Result := BoilerplateTemplateFieldsOK(tmpl.FullBoilerplate, Msg);
 | 
|---|
 | 677 | end;
 | 
|---|
 | 678 | 
 | 
|---|
 | 679 | procedure TdmodShared.EncounterLocationChanged(Sender: TObject);
 | 
|---|
 | 680 | var
 | 
|---|
 | 681 |   i: integer;
 | 
|---|
 | 682 | 
 | 
|---|
 | 683 | begin
 | 
|---|
 | 684 |   if(assigned(FDrawerTrees)) then
 | 
|---|
 | 685 |   begin
 | 
|---|
 | 686 |     for i:= 0 to FDrawerTrees.count-1 do
 | 
|---|
 | 687 |       TfrmDrawers(FDrawerTrees[i]).UpdatePersonalTemplates;
 | 
|---|
 | 688 |   end;
 | 
|---|
 | 689 | end;
 | 
|---|
 | 690 | 
 | 
|---|
 | 691 | procedure TdmodShared.SelectNode(Tree: TORTreeView; GotoNodeID: string; var EmptyCount: integer);
 | 
|---|
 | 692 | var
 | 
|---|
 | 693 |   i, j: integer;
 | 
|---|
 | 694 |   IEN, PIEN: string;
 | 
|---|
 | 695 |   Node: TORTreeNode;
 | 
|---|
 | 696 | 
 | 
|---|
 | 697 |   function FindNode(StartNode: TORTreeNode): TORTreeNode;
 | 
|---|
 | 698 |   begin
 | 
|---|
 | 699 |     Result := nil;
 | 
|---|
 | 700 |     while assigned(StartNode) do
 | 
|---|
 | 701 |     begin
 | 
|---|
 | 702 |       if(Piece(StartNode.StringData, U ,1) = IEN) then
 | 
|---|
 | 703 |       begin
 | 
|---|
 | 704 |         Result := StartNode;
 | 
|---|
 | 705 |         exit;
 | 
|---|
 | 706 |       end;
 | 
|---|
 | 707 |       StartNode := TORTreeNode(StartNode.GetNextSibling);
 | 
|---|
 | 708 |     end;
 | 
|---|
 | 709 |   end;
 | 
|---|
 | 710 | 
 | 
|---|
 | 711 | begin
 | 
|---|
 | 712 |   if(GotoNodeID <> '') then
 | 
|---|
 | 713 |   begin
 | 
|---|
 | 714 |     i := 1;
 | 
|---|
 | 715 |     for j := 1 to length(GotoNodeID) do
 | 
|---|
 | 716 |       if(GotoNodeID[j] = ';') then inc(i);
 | 
|---|
 | 717 |     PIEN := '';
 | 
|---|
 | 718 |     Node := TORTreeNode(Tree.Items.GetFirstNode);
 | 
|---|
 | 719 |     repeat
 | 
|---|
 | 720 |       IEN := piece(GotoNodeID, ';', i);
 | 
|---|
 | 721 |       if(IEN <> '') then
 | 
|---|
 | 722 |       begin
 | 
|---|
 | 723 |         Node := FindNode(Node);
 | 
|---|
 | 724 |         if(assigned(Node)) then
 | 
|---|
 | 725 |         begin
 | 
|---|
 | 726 |           if(PIEN <> '') then
 | 
|---|
 | 727 |             PIEN := ';' + PIEN;
 | 
|---|
 | 728 |           PIEN := IEN + PIEN;
 | 
|---|
 | 729 |           if(PIEN = GotoNodeID) then
 | 
|---|
 | 730 |           begin
 | 
|---|
 | 731 |             Node.EnsureVisible;
 | 
|---|
 | 732 |             Tree.Selected := Node;
 | 
|---|
 | 733 |             IEN := '';
 | 
|---|
 | 734 |           end
 | 
|---|
 | 735 |           else
 | 
|---|
 | 736 |           begin
 | 
|---|
 | 737 |             dmodShared.ExpandNode(Tree, Node, EmptyCount);
 | 
|---|
 | 738 |             Node := TORTreeNode(Node.GetFirstChild);
 | 
|---|
 | 739 |             if(assigned(Node)) then
 | 
|---|
 | 740 |               dec(i)
 | 
|---|
 | 741 |             else
 | 
|---|
 | 742 |               IEN := '';
 | 
|---|
 | 743 |           end;
 | 
|---|
 | 744 |         end
 | 
|---|
 | 745 |         else
 | 
|---|
 | 746 |           IEN := '';
 | 
|---|
 | 747 |       end;
 | 
|---|
 | 748 |     until (i < 1) or (IEN = '');
 | 
|---|
 | 749 |   end;
 | 
|---|
 | 750 | end;
 | 
|---|
 | 751 | 
 | 
|---|
 | 752 | function TdmodShared.InDialog(Node: TTreeNode): boolean;
 | 
|---|
 | 753 | begin
 | 
|---|
 | 754 |   Result := FALSE;
 | 
|---|
 | 755 |   while assigned(Node) and (not Result) do
 | 
|---|
 | 756 |   begin
 | 
|---|
 | 757 |     if TTemplate(Node.Data).IsDialog then
 | 
|---|
 | 758 |       Result := TRUE
 | 
|---|
 | 759 |     else
 | 
|---|
 | 760 |       Node := Node.Parent;
 | 
|---|
 | 761 |   end;
 | 
|---|
 | 762 | end;
 | 
|---|
 | 763 | 
 | 
|---|
 | 764 | procedure TdmodShared.ExpandTree(Tree: TORTreeView; ExpandString: string;
 | 
|---|
 | 765 |   var EmptyCount: integer; AllowInactive: boolean = FALSE);
 | 
|---|
 | 766 | 
 | 
|---|
 | 767 | var
 | 
|---|
 | 768 |   NStr: string;
 | 
|---|
 | 769 |   i: integer;
 | 
|---|
 | 770 |   Node: TTreeNode;
 | 
|---|
 | 771 | 
 | 
|---|
 | 772 | begin
 | 
|---|
 | 773 |   Tree.Items.BeginUpdate;
 | 
|---|
 | 774 |   try
 | 
|---|
 | 775 |     i := 1;
 | 
|---|
 | 776 |     repeat
 | 
|---|
 | 777 |       NStr := piece(ExpandString,U,i);
 | 
|---|
 | 778 |       if(NStr <> '') then
 | 
|---|
 | 779 |       begin
 | 
|---|
 | 780 |         inc(i);
 | 
|---|
 | 781 |         Node := Tree.FindPieceNode(NStr, 1, ';');
 | 
|---|
 | 782 |         if assigned(Node) then
 | 
|---|
 | 783 |         begin
 | 
|---|
 | 784 |           ExpandNode(Tree, Node, EmptyCount, AllowInactive);
 | 
|---|
 | 785 |           Node.Expand(False);
 | 
|---|
 | 786 |         end;
 | 
|---|
 | 787 |       end;
 | 
|---|
 | 788 |     until(NStr = '');
 | 
|---|
 | 789 |   finally
 | 
|---|
 | 790 |     Tree.Items.EndUpdate;
 | 
|---|
 | 791 |   end;
 | 
|---|
 | 792 | end;
 | 
|---|
 | 793 | 
 | 
|---|
 | 794 | procedure TdmodShared.FindRichEditText(AFindDialog: TFindDialog; ARichEdit: TRichEdit);
 | 
|---|
 | 795 | const
 | 
|---|
 | 796 |   TX_NOMATCH = 'The text was not found';
 | 
|---|
 | 797 |   TC_NOMATCH = 'No more matches';
 | 
|---|
 | 798 | var
 | 
|---|
 | 799 |   FoundAt, FoundLine, TopLine, BottomLine: LongInt;
 | 
|---|
 | 800 |   StartPos, ToEnd, CharPos: Integer;
 | 
|---|
 | 801 |   SearchOpts: TSearchTypes;
 | 
|---|
 | 802 | begin
 | 
|---|
 | 803 |   SearchOpts := [];
 | 
|---|
 | 804 |   with ARichEdit do
 | 
|---|
 | 805 |   begin
 | 
|---|
 | 806 |     { begin the search after the current selection if there is one }
 | 
|---|
 | 807 |     { otherwise, begin at the start of the text }
 | 
|---|
 | 808 |     if SelStart <> 0 then
 | 
|---|
 | 809 |       StartPos := SelStart + SelLength
 | 
|---|
 | 810 |     else
 | 
|---|
 | 811 |       StartPos := 0;
 | 
|---|
 | 812 |     { ToEnd is the length from StartPos to the end of the text in the rich edit control }
 | 
|---|
 | 813 |     ToEnd := Length(Text) - StartPos;
 | 
|---|
 | 814 |     if frMatchCase in AFindDialog.Options then Include(SearchOpts, stMatchCase);
 | 
|---|
 | 815 |     if frWholeWord in AFindDialog.Options then Include(SearchOpts, stWholeWord);
 | 
|---|
 | 816 |     FoundAt := FindText(AFindDialog.FindText, StartPos, ToEnd, SearchOpts);
 | 
|---|
 | 817 |     if FoundAt <> -1 then
 | 
|---|
 | 818 |     begin
 | 
|---|
 | 819 |       SetFocus;
 | 
|---|
 | 820 |       TopLine := SendMessage(Handle, EM_GETFIRSTVISIBLELINE, 0, 0);
 | 
|---|
 | 821 |       BottomLine := TopLine + (Height div FontHeightPixel(Font.Handle));
 | 
|---|
 | 822 |       FoundLine := SendMessage(Handle, EM_EXLINEFROMCHAR, 0, FoundAt);
 | 
|---|
 | 823 |       if (FoundLine + 10) > BottomLine then
 | 
|---|
 | 824 |         SendMessage(Handle, EM_LINESCROLL, 0, FoundLine - BottomLine + 10);
 | 
|---|
 | 825 |       CharPos := Pos(AFindDialog.FindText, Lines[FoundLine]);
 | 
|---|
 | 826 |       SendMessage(ARichEdit.Handle, EM_LINESCROLL, CharPos, 0);
 | 
|---|
 | 827 |       SelStart := FoundAt;
 | 
|---|
 | 828 |       SelLength := Length(AFindDialog.FindText);
 | 
|---|
 | 829 |     end
 | 
|---|
 | 830 |     else
 | 
|---|
 | 831 |     begin
 | 
|---|
 | 832 |       if not (frReplaceAll in AFindDialog.Options) then InfoBox(TX_NOMATCH, TC_NOMATCH, MB_OK);
 | 
|---|
 | 833 |       SelStart := 0;
 | 
|---|
 | 834 |       SelLength := 0;
 | 
|---|
 | 835 |       //AFindDialog.CloseDialog;
 | 
|---|
 | 836 |     end;
 | 
|---|
 | 837 |   end;
 | 
|---|
 | 838 | end;
 | 
|---|
 | 839 | 
 | 
|---|
 | 840 | procedure TdmodShared.ReplaceRichEditText(AReplaceDialog: TReplaceDialog; ARichEdit: TRichEdit);
 | 
|---|
 | 841 | const
 | 
|---|
 | 842 |   TC_COMPLETE  = 'Replacement Complete';
 | 
|---|
 | 843 |   TX_COMPLETE1 = 'CPRS has finished searching the document.  ' + CRLF;
 | 
|---|
 | 844 |   TX_COMPLETE2 = ' replacements were made.';
 | 
|---|
 | 845 | var
 | 
|---|
 | 846 |   Replacements: integer;
 | 
|---|
 | 847 |   NewStart: integer;
 | 
|---|
 | 848 | begin
 | 
|---|
 | 849 |   Replacements := 0;
 | 
|---|
 | 850 |   if (frReplace in AReplaceDialog.Options) then
 | 
|---|
 | 851 |     begin
 | 
|---|
 | 852 |       if ARichEdit.SelLength > 0 then
 | 
|---|
 | 853 |         begin
 | 
|---|
 | 854 |           NewStart := ARichEdit.SelStart + Length(AReplaceDialog.ReplaceText);
 | 
|---|
 | 855 |           ARichEdit.SelText := AReplaceDialog.ReplaceText;
 | 
|---|
 | 856 |           ARichEdit.SelStart := NewStart;
 | 
|---|
 | 857 |           //Replacements := Replacements + 1;
 | 
|---|
 | 858 |         end;
 | 
|---|
 | 859 |       FindRichEditText(AReplaceDialog, ARichEdit);
 | 
|---|
 | 860 |     end
 | 
|---|
 | 861 |   else if (frReplaceAll in AReplaceDialog.Options) then
 | 
|---|
 | 862 |     begin
 | 
|---|
 | 863 |       repeat
 | 
|---|
 | 864 |         if ARichEdit.SelLength > 0 then
 | 
|---|
 | 865 |           begin
 | 
|---|
 | 866 |             NewStart := ARichEdit.SelStart + Length(AReplaceDialog.ReplaceText);
 | 
|---|
 | 867 |             ARichEdit.SelText := AReplaceDialog.ReplaceText;
 | 
|---|
 | 868 |             ARichEdit.SelStart := NewStart;
 | 
|---|
 | 869 |             Replacements := Replacements + 1;
 | 
|---|
 | 870 |           end;
 | 
|---|
 | 871 |         FindRichEditText(AReplaceDialog, ARichEdit);
 | 
|---|
 | 872 |       until ARichEdit.SelLength = 0;
 | 
|---|
 | 873 |       InfoBox(TX_COMPLETE1 + IntToStr(Replacements) + TX_COMPLETE2, TC_COMPLETE, MB_OK);
 | 
|---|
 | 874 |     end
 | 
|---|
 | 875 |   else
 | 
|---|
 | 876 |     FindRichEditText(AReplaceDialog, ARichEdit);
 | 
|---|
 | 877 | end;
 | 
|---|
 | 878 | 
 | 
|---|
 | 879 | end.
 | 
|---|
 | 880 | 
 | 
|---|
 | 881 | 
 | 
|---|
 | 882 | 
 | 
|---|
 | 883 | 
 | 
|---|
 | 884 | 
 | 
|---|