Code For CPRSChart
CodeForCPRSChart
Here is the code for the unit fNotes used in CPRS Chart. This module was in version 1.0.19.16
Note: To find the code CHANGES for CPRSImager, search this page (i.e. via CTRL-F) for "//kt".
Beware of formatting changes. I couldn't get it to all be formatted perfectly. Don't cut and paste this file. Just look for the changes and put them into your own source file.
Kevin Toppenberg
unit fNotes; interface uses Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs, fHSplit, StdCtrls, ExtCtrls, Menus, ComCtrls, ORCtrls, ORFn, uConst, ORDtTm, uPCE, ORClasses, fDrawers, ImgList, rTIU, uTIU, uDocTree, fRptBox; type TfrmNotes = class(TfrmHSplit) mnuNotes: TMainMenu; mnuView: TMenuItem; mnuViewChart: TMenuItem; mnuChartReports: TMenuItem; mnuChartLabs: TMenuItem; mnuChartDCSumm: TMenuItem; mnuChartCslts: TMenuItem; mnuChartNotes: TMenuItem; mnuChartOrders: TMenuItem; mnuChartMeds: TMenuItem; mnuChartProbs: TMenuItem; mnuChartCover: TMenuItem; Z1: TMenuItem; mnuViewDetail: TMenuItem; mnuAct: TMenuItem; mnuActNew: TMenuItem; Z2: TMenuItem; mnuActSave: TMenuItem; mnuActDelete: TMenuItem; mnuActEdit: TMenuItem; mnuActSign: TMenuItem; mnuActAddend: TMenuItem; lblNotes: TOROffsetLabel; pnlRead: TPanel; lblTitle: TOROffsetLabel; memNote: TRichEdit; pnlWrite: TPanel; memNewNote: TRichEdit; Z3: TMenuItem; mnuViewAll: TMenuItem; mnuViewByAuthor: TMenuItem; mnuViewByDate: TMenuItem; mnuViewUncosigned: TMenuItem; mnuViewUnsigned: TMenuItem; mnuActSignList: TMenuItem; cmdNewNote: TORAlignButton; cmdPCE: TORAlignButton; lblSpace1: TLabel; popNoteMemo: TPopupMenu; popNoteMemoCut: TMenuItem; popNoteMemoCopy: TMenuItem; popNoteMemoPaste: TMenuItem; Z10: TMenuItem; popNoteMemoSignList: TMenuItem; popNoteMemoDelete: TMenuItem; popNoteMemoEdit: TMenuItem; popNoteMemoSave: TMenuItem; popNoteMemoSign: TMenuItem; popNoteList: TPopupMenu; popNoteListAll: TMenuItem; popNoteListByAuthor: TMenuItem; popNoteListByDate: TMenuItem; popNoteListUncosigned: TMenuItem; popNoteListUnsigned: TMenuItem; sptVert: TSplitter; memPCEShow: TRichEdit; mnuActIdentifyAddlSigners: TMenuItem; popNoteMemoAddlSign: TMenuItem; Z11: TMenuItem; popNoteMemoSpell: TMenuItem; popNoteMemoGrammar: TMenuItem; mnuViewCustom: TMenuItem; N1: TMenuItem; mnuViewSaveAsDefault: TMenuItem; ReturntoDefault1: TMenuItem; pnlDrawers: TPanel; lstNotes: TORListBox; splDrawers: TSplitter; popNoteMemoTemplate: TMenuItem; Z12: TMenuItem; mnuOptions: TMenuItem; mnuEditTemplates: TMenuItem; mnuNewTemplate: TMenuItem; N2: TMenuItem; mnuEditSharedTemplates: TMenuItem; mnuNewSharedTemplate: TMenuItem; popNoteMemoAddend: TMenuItem; pnlFields: TPanel; lblNewTitle: TLabel; lblRefDate: TLabel; lblAuthor: TLabel; lblVisit: TLabel; lblCosigner: TLabel; cmdChange: TButton; lblSubject: TLabel; txtSubject: TEdit; timAutoSave: TTimer; popNoteMemoPaste2: TMenuItem; popNoteMemoReformat: TMenuItem; Z4: TMenuItem; mnuActChange: TMenuItem; mnuActLoadBoiler: TMenuItem; bvlNewTitle: TBevel; popNoteMemoSaveContinue: TMenuItem; N3: TMenuItem; mnuEditDialgFields: TMenuItem; tvNotes: TORTreeView; lvNotes: TListView; sptList: TSplitter; N4: TMenuItem; popNoteListExpandSelected: TMenuItem; popNoteListExpandAll: TMenuItem; popNoteListCollapseSelected: TMenuItem; popNoteListCollapseAll: TMenuItem; popNoteListCustom: TMenuItem; mnuActDetachFromIDParent: TMenuItem; N5: TMenuItem; popNoteListDetachFromIDParent: TMenuItem; popNoteListAddIDEntry: TMenuItem; mnuActAddIDEntry: TMenuItem; mnuIconLegend: TMenuItem; N6: TMenuItem; popNoteMemoFind: TMenuItem; dlgFindText: TFindDialog; dlgReplaceText: TReplaceDialog; popNoteMemoReplace: TMenuItem; N7: TMenuItem; mnuChartSurgery: TMenuItem; mnuActAttachtoIDParent: TMenuItem; popNoteListAttachtoIDParent: TMenuItem; procedure mnuChartTabClick(Sender: TObject); procedure lstNotesClick(Sender: TObject); procedure pnlRightResize(Sender: TObject); procedure cmdNewNoteClick(Sender: TObject); procedure mnuActNewClick(Sender: TObject); procedure mnuActAddIDEntryClick(Sender: TObject); procedure mnuActSaveClick(Sender: TObject); procedure mnuViewClick(Sender: TObject); procedure mnuActAddendClick(Sender: TObject); procedure mnuActDetachFromIDParentClick(Sender: TObject); procedure mnuActSignListClick(Sender: TObject); procedure mnuActDeleteClick(Sender: TObject); procedure mnuActEditClick(Sender: TObject); procedure mnuActSignClick(Sender: TObject); procedure cmdPCEClick(Sender: TObject); procedure popNoteMemoCutClick(Sender: TObject); procedure popNoteMemoCopyClick(Sender: TObject); procedure popNoteMemoPasteClick(Sender: TObject); procedure popNoteMemoPopup(Sender: TObject); procedure pnlWriteResize(Sender: TObject); procedure FormCreate(Sender: TObject); procedure mnuViewDetailClick(Sender: TObject); procedure FormClose(Sender: TObject; var Action: TCloseAction); procedure mnuActIdentifyAddlSignersClick(Sender: TObject); procedure popNoteMemoAddlSignClick(Sender: TObject); procedure popNoteMemoSpellClick(Sender: TObject); procedure popNoteMemoGrammarClick(Sender: TObject); procedure mnuViewSaveAsDefaultClick(Sender: TObject); procedure mnuViewReturntoDefaultClick(Sender: TObject); procedure popNoteMemoTemplateClick(Sender: TObject); procedure mnuEditTemplatesClick(Sender: TObject); procedure mnuNewTemplateClick(Sender: TObject); procedure mnuEditSharedTemplatesClick(Sender: TObject); procedure mnuNewSharedTemplateClick(Sender: TObject); procedure mnuOptionsClick(Sender: TObject); procedure FormDestroy(Sender: TObject); procedure cmdChangeClick(Sender: TObject); procedure pnlFieldsResize(Sender: TObject); procedure timAutoSaveTimer(Sender: TObject); procedure memNewNoteChange(Sender: TObject); procedure popNoteMemoReformatClick(Sender: TObject); procedure mnuActChangeClick(Sender: TObject); procedure mnuActLoadBoilerClick(Sender: TObject); procedure popNoteMemoSaveContinueClick(Sender: TObject); procedure mnuEditDialgFieldsClick(Sender: TObject); procedure tvNotesChange(Sender: TObject; Node: TTreeNode); procedure tvNotesClick(Sender: TObject); procedure tvNotesCollapsed(Sender: TObject; Node: TTreeNode); procedure tvNotesExpanded(Sender: TObject; Node: TTreeNode); procedure tvNotesStartDrag(Sender: TObject; var DragObject: TDragObject); procedure tvNotesDragDrop(Sender, Source: TObject; X, Y: Integer); procedure tvNotesDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); procedure lvNotesColumnClick(Sender: TObject; Column: TListColumn); procedure lvNotesCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); procedure lvNotesSelectItem(Sender: TObject; Item: TListItem; Selected: Boolean); procedure popNoteListExpandAllClick(Sender: TObject); procedure popNoteListCollapseAllClick(Sender: TObject); procedure popNoteListExpandSelectedClick(Sender: TObject); procedure popNoteListCollapseSelectedClick(Sender: TObject); procedure popNoteListPopup(Sender: TObject); procedure lvNotesResize(Sender: TObject); procedure mnuIconLegendClick(Sender: TObject); procedure popNoteMemoFindClick(Sender: TObject); procedure dlgFindTextFind(Sender: TObject); procedure popNoteMemoReplaceClick(Sender: TObject); procedure dlgReplaceTextReplace(Sender: TObject); procedure dlgReplaceTextFind(Sender: TObject); procedure mnuActAttachtoIDParentClick(Sender: TObject); private FEditingIndex: Integer; // index of note being currently edited FChanged: Boolean; // true if any text has changed in the note FEditCtrl: TCustomEdit; FSilent: Boolean; FCurrentContext: TTIUContext; FDefaultContext: TTIUContext; FOrderID: string; FImageFlag: TBitmap; FEditNote: TEditNoteRec; FVerifyNoteTitle: Integer; FDocList: TStringList; FConfirmed: boolean; FLastNoteID: string; FNewIDChild: boolean; FEditingNotePCEObj: boolean; FDeleted: boolean; procedure ClearEditControls; procedure DoAutoSave; function GetTitleText(AnIndex: Integer): string; procedure InsertAddendum; procedure InsertNewNote(IsIDChild: boolean; AnIDParent: integer); function LacksRequiredForCreate: Boolean; procedure LoadForEdit; function LockConsultRequest(AConsult: Integer): Boolean; function LockConsultRequestAndNote(AnIEN: Int64): Boolean; procedure RemovePCEFromChanges(IEN: Int64; AVisitStr: string = ); procedure SaveEditedNote(var Saved: Boolean); procedure SaveCurrentNote(var Saved: Boolean); procedure SetEditingIndex(const Value: Integer); procedure SetSubjectVisible(ShouldShow: Boolean); procedure ShowPCEControls(ShouldShow: Boolean); function StartNewEdit(NewNoteType: integer): Boolean; procedure UnlockConsultRequest(ANote: Int64; AConsult: Integer = 0); procedure ProcessNotifications; procedure SetViewContext(AContext: TTIUContext); property EditingIndex: Integer read FEditingIndex write SetEditingIndex; function GetDrawers: TFrmDrawers; function CanFinishReminder: boolean; procedure DisplayPCE; function VerifyNoteTitle: Boolean; // added for treeview procedure LoadNotes; procedure UpdateTreeView(DocList: TStringList; Tree: TORTreeView); procedure EnableDisableIDNotes; procedure ShowPCEButtons(Editing: boolean); procedure DoAttachIDChild(AChild, AParent: TORTreeNode); function SetNoteTreeLabel(AContext: TTIUContext): string; //kt added \\ function CheckForImageLink(ImageList : TStringList) : boolean; //kt added \\ public function ActiveEditOf(AnIEN: Int64; ARequest: integer): Boolean; function AllowContextChange: Boolean; override; procedure ClearPtData; override; procedure DisplayPage; override; procedure RequestPrint; override; procedure SetFontSize(NewFontSize: Integer); override; procedure SaveSignItem(const ItemID, ESCode: string); procedure AssignRemForm; property OrderID: string read FOrderID; published property Drawers: TFrmDrawers read GetDrawers; // Keep Drawers published end; var frmNotes: TfrmNotes; implementation {$R *.DFM} uses fFrame, fVisit, fEncnt, rCore, uCore, fNoteBA, fNoteBD, fSignItem, fEncounterFrame, rPCE, Clipbrd, fNoteCslt, fNotePrt, rVitals, fAddlSigners, fNoteDR, fConsults, uSpell, fTIUView, fTemplateEditor, uReminders, fReminderDialog, uOrders, rConsults, fReminderTree, fNoteProps, fNotesBP, fTemplateFieldEditor, dShared, rTemplates, FIconLegend, fPCEEdit, fNoteIDParents, rSurgery, uSurgery, StrUtils, //kt added \\ uTemplates; const NT_NEW_NOTE = -10; // Holder IEN for a new note NT_ADDENDUM = -20; // Holder IEN for a new addendum NT_ACT_NEW_NOTE = 2; NT_ACT_ADDENDUM = 3; NT_ACT_EDIT_NOTE = 4; NT_ACT_ID_ENTRY = 5; TX_NEED_VISIT = 'A visit is required before creating a new progress note.'; TX_CREATE_ERR = 'Error Creating Note'; TX_UPDATE_ERR = 'Error Updating Note'; TX_NO_NOTE = 'No progress note is currently being edited'; TX_SAVE_NOTE = 'Save Progress Note'; TX_ADDEND_NO = 'Cannot make an addendum to a note that is being edited'; TX_DEL_OK = CRLF + CRLF + 'Delete this progress note?'; TX_DEL_ERR = 'Unable to Delete Note'; TX_SIGN = 'Sign Note'; TX_COSIGN = 'Cosign Note'; TX_SIGN_ERR = 'Unable to Sign Note'; // TX_SCREQD = 'This progress note title requires the service connected questions to be '+ // 'answered. The Encounter form will now be opened. Please answer all '+ // 'service connected questions.'; // TX_SCREQD_T = 'Response required for SC questions.'; TX_NONOTE = 'No progress note is currently selected.'; TX_NONOTE_CAP = 'No Note Selected'; TX_NOPRT_NEW = 'This progress note may not be printed until it is saved'; TX_NOPRT_NEW_CAP = 'Save Progress Note'; TX_NO_ALERT = 'There is insufficient information to process this alert.' + CRLF + 'Either the alert has already been deleted, or it contained invalid data.' + CRLF + CRLF + 'Click the NEXT button if you wish to continue processing more alerts.'; TX_CAP_NO_ALERT = 'Unable to Process Alert'; TX_ORDER_LOCKED = 'This record is locked by an action underway on the Consults tab'; TC_ORDER_LOCKED = 'Unable to access record'; TX_NO_ORD_CHG = 'The note is still associated with the previously selected request.' + CRLF + 'Finish the pending action on the consults tab, then try again.'; TC_NO_ORD_CHG = 'Locked Consult Request'; TX_NEW_SAVE1 = 'You are currently editing:' + CRLF + CRLF; TX_NEW_SAVE2 = CRLF + CRLF + 'Do you wish to save this note and begin a new one?'; TX_NEW_SAVE3 = CRLF + CRLF + 'Do you wish to save this note and begin a new addendum?'; TX_NEW_SAVE4 = CRLF + CRLF + 'Do you wish to save this note and edit the one selected?'; TX_NEW_SAVE5 = CRLF + CRLF + 'Do you wish to save this note and begin a new Interdisciplinary entry?'; TC_NEW_SAVE2 = 'Create New Note'; TC_NEW_SAVE3 = 'Create New Addendum'; TC_NEW_SAVE4 = 'Edit Different Note'; TC_NEW_SAVE5 = 'Create New Interdisciplinary Entry'; TX_EMPTY_NOTE = CRLF + CRLF + 'This note contains no text and will not be saved.' + CRLF + 'Do you wish to delete this note?'; TC_EMPTY_NOTE = 'Empty Note'; TC_NO_LOCK = 'Unable to Lock Note'; TX_ABSAVE = 'It appears the session terminated abnormally when this' + CRLF + 'note was last edited. Some text may not have been saved.' + CRLF + CRLF + 'Do you wish to continue and sign the note?'; TC_ABSAVE = 'Possible Missing Text'; TX_NO_BOIL = 'There is no boilerplate text associated with this title.'; TC_NO_BOIL = 'Load Boilerplate Text'; TX_BLR_CLEAR = 'Do you want to clear the previously loaded boilerplate text?'; TC_BLR_CLEAR = 'Clear Previous Boilerplate Text'; TX_DETACH_CNF = 'Confirm Detachment'; TX_DETACH_FAILURE = 'Detach failed'; var uPCEShow, uPCEEdit: TPCEData; ViewContext: Integer; frmDrawers: TfrmDrawers; uTIUContext: TTIUContext; ColumnToSort: Integer; ColumnSortForward: Boolean; uChanging: Boolean; uIDNotesActive: Boolean; { TPage common methods --------------------------------------------------------------------- } function TfrmNotes.AllowContextChange: Boolean; begin dlgFindText.CloseDialog; Result := inherited AllowContextChange; // sets result = true if EditingIndex <> -1 then SaveCurrentNote(Result); end; procedure TfrmNotes.ClearPtData; { clear all controls that contain patient specific information } begin inherited ClearPtData; ClearEditControls; uChanging := True; tvNotes.Items.BeginUpdate; KilldocTreeObjects(tvNotes); tvNotes.Items.Clear; tvNotes.Items.EndUpdate; lvNotes.Items.Clear; uChanging := False; lstNotes.Clear; memNote.Clear; memPCEShow.Clear; uPCEShow.Clear; uPCEEdit.Clear; frmDrawers.ResetTemplates;
end; procedure TfrmNotes.DisplayPage; { causes page to be visible and conditionally executes initialization code } begin
inherited DisplayPage; frmFrame.ShowHideChartTabMenus(mnuViewChart); frmFrame.mnuFilePrint.Tag := CT_NOTES; frmFrame.mnuFilePrint.Enabled := True; frmFrame.mnuFilePrintSetup.Enabled := True; if InitPage then begin EnableDisableIDNotes; FDefaultContext := GetCurrentTIUContext; FCurrentContext := FDefaultContext; popNoteMemoSpell.Visible := SpellCheckAvailable; popNoteMemoGrammar.Visible := popNoteMemoSpell.Visible; Z11.Visible := popNoteMemoSpell.Visible; timAutoSave.Interval := User.AutoSave * 1000; // convert seconds to milliseconds SetEqualTabStops(memNewNote); end; // to indent the right margin need to set Paragraph.RightIndent for each paragraph? if InitPatient and not (CallingContext = CC_NOTIFICATION) then begin SetViewContext(FDefaultContext); end; case CallingContext of CC_INIT_PATIENT: if not InitPatient then begin SetViewContext(FDefaultContext); end; CC_NOTIFICATION: ProcessNotifications; end;
end; procedure TfrmNotes.RequestPrint; var
Saved: Boolean;
begin
with lstNotes do begin if ItemIndex = EditingIndex then //if ItemIEN < 0 then begin SaveCurrentNote(Saved); if not Saved then Exit; end; if ItemIEN > 0 then PrintNote(ItemIEN, MakeNoteDisplayText(Items[ItemIndex])) else begin if ItemIEN = 0 then InfoBox(TX_NONOTE, TX_NONOTE_CAP, MB_OK); if ItemIEN < 0 then InfoBox(TX_NOPRT_NEW, TX_NOPRT_NEW_CAP, MB_OK); end; end;
end; procedure TfrmNotes.SetFontSize(NewFontSize: Integer); { adjusts the font size of any controls that don't have ParentFont = True } begin
inherited SetFontSize(NewFontSize); memNote.Font.Size := NewFontSize; memNewNote.Font.Size := NewFontSize; lblTitle.Font.Size := NewFontSize; frmDrawers.Font.Size := NewFontSize; SetEqualTabStops(memNewNote); // adjust heights of pnlAction, pnlFields, and lstEncntShow
end; procedure TfrmNotes.mnuChartTabClick(Sender: TObject); { reroute to Chart Tab menu of the parent form: frmFrame } begin
inherited; frmFrame.mnuChartTabClick(Sender);
end; { General procedures ----------------------------------------------------------------------- } procedure TfrmNotes.ClearEditControls; { resets controls used for entering a new progress note } begin
// clear FEditNote (should FEditNote be an object with a clear method?) with FEditNote do begin DocType := 0; Title := 0; TitleName := ; DateTime := 0; Author := 0; AuthorName := ; Cosigner := 0; CosignerName := ; Subject := ; Location := 0; LocationName := ; PkgIEN := 0; PkgPtr := ; PkgRef := ; NeedCPT := False; Addend := 0; {LastCosigner & LastCosignerName aren't cleared because they're used as default for next note.} Lines := nil; end; // clear the editing controls (also clear the new labels?) txtSubject.Text := ; memNewNote.Clear; timAutoSave.Enabled := False; // clear the PCE object for editing uPCEEdit.Clear; // set the tracking variables to initial state EditingIndex := -1; FChanged := False;
end; procedure TfrmNotes.ShowPCEControls(ShouldShow: Boolean); begin
sptVert.Visible := ShouldShow; memPCEShow.Visible := ShouldShow; if(ShouldShow) then sptVert.Top := memPCEShow.Top - sptVert.Height; memNote.Invalidate;
end; procedure TfrmNotes.DisplayPCE; { displays PCE information if appropriate & enables/disabled editing of PCE data } var
EnableList, ShowList: TDrawers; VitalStr: TStringlist; NoPCE: boolean; ActionSts: TActionRec; AnIEN: integer;
begin
memPCEShow.Clear; with lstNotes do if ItemIndex = EditingIndex then begin with uPCEEdit do begin AddStrData(memPCEShow.Lines); NoPCE := (memPCEShow.Lines.Count = 0); VitalStr := TStringList.create; try GetVitalsFromDate(VitalStr, uPCEEdit); AddVitalData(VitalStr, memPCEShow.Lines); finally VitalStr.free; end; ShowPCEButtons(TRUE); ShowPCEControls(cmdPCE.Enabled or (memPCEShow.Lines.Count > 0)); if(NoPCE and memPCEShow.Visible) then memPCEShow.Lines.Insert(0, TX_NOPCE); if(InteractiveRemindersActive) then begin if(GetReminderStatus = rsNone) then EnableList := [odTemplates] else EnableList := [odTemplates, odReminders]; ShowList := [odTemplates, odReminders]; end else begin EnableList := [odTemplates]; ShowList := [odTemplates]; end; frmDrawers.DisplayDrawers(TRUE, EnableList, ShowList); end; end else begin ShowPCEButtons(FALSE); frmDrawers.DisplayDrawers(TRUE, [odTemplates], [odTemplates]); AnIEN := lstNotes.ItemIEN; ActOnDocument(ActionSts, AnIEN, 'VIEW'); if ActionSts.Success then begin StatusText('Retrieving encounter information...'); with uPCEShow do begin NoteDateTime := MakeFMDateTime(Piece(lstNotes.Items[lstNotes.ItemIndex], U, 3)); PCEForNote(AnIEN, uPCEEdit); AddStrData(memPCEShow.Lines); NoPCE := (memPCEShow.Lines.Count = 0); VitalStr := TStringList.create; try GetVitalsFromNote(VitalStr, uPCEShow, AnIEN); AddVitalData(VitalStr, memPCEShow.Lines); finally VitalStr.free; end; ShowPCEControls(memPCEShow.Lines.Count > 0); if(NoPCE and memPCEShow.Visible) then memPCEShow.Lines.Insert(0, TX_NOPCE); end; StatusText(); end else ShowPCEControls(FALSE); end; {if ItemIndex}
end; { supporting calls for writing notes } function TfrmNotes.GetTitleText(AnIndex: Integer): string; { returns non-tabbed text for the title of a note given the ItemIndex in lstNotes } begin
with lstNotes do Result := FormatFMDateTime('mmm dd,yy', MakeFMDateTime(Piece(Items[AnIndex], U, 3))) + ' ' + Piece(Items[AnIndex], U, 2) + ', ' + Piece(Items[AnIndex], U, 6) + ', ' + Piece(Piece(Items[AnIndex], U, 5), ';', 2)
end; function TfrmNotes.LacksRequiredForCreate: Boolean; { determines if the fields required to create the note are present } var
CurTitle: Integer;
begin
Result := False; with FEditNote do begin if Title <= 0 then Result := True; if Author <= 0 then Result := True; if DateTime <= 0 then Result := True; if IsConsultTitle(Title) and (PkgIEN = 0) then Result := True; if IsSurgeryTitle(Title) and (PkgIEN = 0) then Result := True; if (DocType = TYP_ADDENDUM) then begin if AskCosignerForDocument(Addend, Author) and (Cosigner <= 0) then Result := True; end else begin if Title > 0 then CurTitle := Title else CurTitle := DocType; if AskCosignerForTitle(CurTitle, Author) and (Cosigner <= 0) then Result := True; end; end;
end; function TfrmNotes.VerifyNoteTitle: Boolean; const
VNT_UNKNOWN = 0; VNT_NO = 1; VNT_YES = 2;
var
AParam: string;
begin
if FVerifyNoteTitle = VNT_UNKNOWN then begin AParam := GetUserParam('ORWOR VERIFY NOTE TITLE'); if AParam = '1' then FVerifyNoteTitle := VNT_YES else FVerifyNoteTitle := VNT_NO; end; Result := FVerifyNoteTitle = VNT_YES;
end; procedure TfrmNotes.SetSubjectVisible(ShouldShow: Boolean); { hide/show subject & resize panel accordingly - leave 6 pixel margin above memNewNote } begin
if ShouldShow then begin lblSubject.Visible := True; txtSubject.Visible := True; pnlFields.Height := txtSubject.Top + txtSubject.Height + 6; end else begin lblSubject.Visible := False; txtSubject.Visible := False; pnlFields.Height := lblVisit.Top + lblVisit.Height + 6; end;
end; { consult request and note locking } function TfrmNotes.LockConsultRequest(AConsult: Integer): Boolean; { returns true if consult successfully locked } begin
// *** I'm not sure about the FOrderID field - if the user is editing one note and // deletes another, FOrderID will be for editing note, then delete note, then null Result := True; FOrderID := GetConsultOrderIEN(AConsult); if (FOrderID <> ) and (FOrderID = frmConsults.OrderID) then begin InfoBox(TX_ORDER_LOCKED, TC_ORDER_LOCKED, MB_OK); Result := False; Exit; end; if (FOrderId <> ) then if not OrderCanBeLocked(FOrderID) then Result := False; if not Result then FOrderID := ;
end; function TfrmNotes.LockConsultRequestAndNote(AnIEN: Int64): Boolean; { returns true if note and associated request successfully locked } var
AConsult: Integer; LockMsg, x: string;
begin
Result := True; AConsult := 0; if frmConsults.ActiveEditOf(AnIEN) then begin InfoBox(TX_ORDER_LOCKED, TC_ORDER_LOCKED, MB_OK); Result := False; Exit; end; if Changes.Exist(CH_DOC, IntToStr(AnIEN)) then Exit; // already locked // try to lock the consult request first, if there is one if IsConsultTitle(TitleForNote(AnIEN)) then begin x := GetPackageRefForNote(lstNotes.ItemIEN); AConsult := StrToIntDef(Piece(x, ';', 1), 0); Result := LockConsultRequest(AConsult); end; // now try to lock the note if Result then begin LockDocument(AnIEN, LockMsg); if LockMsg <> then begin Result := False; // if can't lock the note, unlock the consult request that was just locked if AConsult > 0 then begin UnlockOrderIfAble(FOrderID); FOrderID := ; end; InfoBox(LockMsg, TC_NO_LOCK, MB_OK); end; end;
end; procedure TfrmNotes.UnlockConsultRequest(ANote: Int64; AConsult: Integer = 0); (*var
x: string;*)
begin (* if (AConsult = 0) and IsConsultTitle(TitleForNote(ANote)) then
begin x := GetPackageRefForNote(ANote); AConsult := StrToIntDef(Piece(x, ';', 1), 0); end; if AConsult = 0 then Exit;*) if AConsult = 0 then AConsult := GetConsultIENForNote(ANote); if AConsult <= 0 then exit; FOrderID := GetConsultOrderIEN(AConsult); UnlockOrderIfAble(FOrderID); FOrderID := ;
end; function TfrmNotes.ActiveEditOf(AnIEN: Int64; ARequest: integer): Boolean; begin
Result := False; if EditingIndex < 0 then Exit; if lstNotes.GetIEN(EditingIndex) = AnIEN then begin Result := True; Exit; end; with FEditNote do if (PkgIEN = ARequest) and (PkgPtr = PKG_CONSULTS) then Result := True;
end; { create, edit & save notes } procedure TfrmNotes.InsertNewNote(IsIDChild: boolean; AnIDParent: integer); { creates the editing context for a new progress note & inserts stub into top of view list } var
EnableAutosave, HaveRequired: Boolean; CreatedNote: TCreatedDoc; TmpBoilerPlate: TStringList; tmpNode: TTreeNode; x, WhyNot: string;
begin
FNewIDChild := IsIDChild; EnableAutosave := FALSE; TmpBoilerPlate := nil; try ClearEditControls; FillChar(FEditNote, SizeOf(FEditNote), 0); //v15.7 with FEditNote do begin DocType := TYP_PROGRESS_NOTE; Title := DfltNoteTitle; TitleName := DfltNoteTitleName; if IsIDChild and (not CanTitleBeIDChild(Title, WhyNot)) then begin Title := 0; TitleName := ; end; if IsSurgeryTitle(Title) then // Don't want surgery title sneaking in unchallenged begin Title := 0; TitleName := ; end; DateTime := FMNow; Author := User.DUZ; AuthorName := User.Name; Location := Encounter.Location; LocationName := Encounter.LocationName; VisitDate := Encounter.DateTime; if IsIDChild then IDParent := AnIDParent else IDParent := 0; // Cosigner & PkgRef, if needed, will be set by fNoteProps end; // check to see if interaction necessary to get required fields if LacksRequiredForCreate or VerifyNoteTitle then HaveRequired := ExecuteNoteProperties(FEditNote, CT_NOTES, IsIDChild, FNewIDChild, , 0) else HaveRequired := True; // lock the consult request if there is a consult with FEditNote do if (PkgIEN > 0) and (PkgPtr = PKG_CONSULTS) then HaveRequired := LockConsultRequest(PkgIEN); if HaveRequired then begin // set up uPCEEdit for entry of new note uPCEEdit.UseEncounter := True; uPCEEdit.NoteDateTime := FEditNote.DateTime; uPCEEdit.PCEForNote(USE_CURRENT_VISITSTR, uPCEShow); FEditNote.NeedCPT := uPCEEdit.CPTRequired; // create the note PutNewNote(CreatedNote, FEditNote); uPCEEdit.NoteIEN := CreatedNote.IEN; if CreatedNote.IEN > 0 then LockDocument(CreatedNote.IEN, CreatedNote.ErrorText); if CreatedNote.ErrorText = then begin //x := $$RESOLVE^TIUSRVLO formatted string //7348^Note Title^3000913^NERD, YOURA (N0165)^1329;Rich Vertigan;VERTIGAN,RICH^8E REHAB MED^complete^Adm: 11/05/98;2981105.095547^ ;^^0^^^2 with FEditNote do begin x := IntToStr(CreatedNote.IEN) + U + TitleName + U + FloatToStr(FEditNote.DateTime) + U + Patient.Name + U + IntToStr(Author) + ';' + AuthorName + U + LocationName + U + 'new' + U + U + U + U + U + U + U + U; end; lstNotes.Items.Insert(0, x); uChanging := True; tvNotes.Items.BeginUpdate; if IsIDChild then begin tmpNode := tvNotes.FindPieceNode(IntToStr(AnIDParent), 1, U, tvNotes.Items.GetFirstNode); tmpNode.ImageIndex := IMG_IDNOTE_OPEN; tmpNode.SelectedIndex := IMG_IDNOTE_OPEN; tmpNode := tvNotes.Items.AddChildObjectFirst(tmpNode, MakeNoteDisplayText(x), MakeNoteTreeObject(x)); tmpNode.ImageIndex := IMG_ID_CHILD; tmpNode.SelectedIndex := IMG_ID_CHILD; end else begin tmpNode := tvNotes.Items.AddObjectFirst(tvNotes.Items.GetFirstNode, 'New Note in Progress', MakeNoteTreeObject('NEW^New Note in Progress^^^^^^^^^^^%^0')); TORTreeNode(tmpNode).StringData := 'NEW^New Note in Progress^^^^^^^^^^^%^0'; tmpNode.ImageIndex := IMG_TOP_LEVEL; tmpNode := tvNotes.Items.AddChildObjectFirst(tmpNode, MakeNoteDisplayText(x), MakeNoteTreeObject(x)); tmpNode.ImageIndex := IMG_SINGLE; tmpNode.SelectedIndex := IMG_SINGLE; end; tmpNode.StateIndex := IMG_NO_IMAGES; TORTreeNode(tmpNode).StringData := x; tvNotes.Selected := tmpNode; tvNotes.Items.EndUpdate; uChanging := False; Changes.Add(CH_DOC, IntToStr(CreatedNote.IEN), GetTitleText(0), , CH_SIGN_YES); lstNotes.ItemIndex := 0; EditingIndex := 0; SetSubjectVisible(AskSubjectForNotes); if not assigned(TmpBoilerPlate) then TmpBoilerPlate := TStringList.Create; LoadBoilerPlate(TmpBoilerPlate, FEditNote.Title); FChanged := False; cmdChangeClick(Self); // will set captions, sign state for Changes lstNotesClick(Self); // will make pnlWrite visible if timAutoSave.Interval <> 0 then EnableAutosave := TRUE; if txtSubject.Visible then txtSubject.SetFocus else memNewNote.SetFocus; end else begin // if note creation failed or failed to get note lock (both unlikely), unlock consult with FEditNote do if (PkgIEN > 0) and (PkgPtr = PKG_CONSULTS) then UnlockConsultRequest(0, PkgIEN); InfoBox(CreatedNote.ErrorText, TX_CREATE_ERR, MB_OK); HaveRequired := False; end; {if CreatedNote.IEN} end; {if HaveRequired} if not HaveRequired then ClearEditControls; finally if assigned(TmpBoilerPlate) then begin ExecuteTemplateOrBoilerPlate(TmpBoilerPlate, FEditNote.Title, ltTitle, Self, 'Title: ' + FEditNote.TitleName); memNewNote.Lines.Assign(TmpBoilerPlate); TmpBoilerPlate.Free; end; if EnableAutosave then // Don't enable autosave until after dialog fields have been resolved timAutoSave.Enabled := True; end;
end; procedure TfrmNotes.InsertAddendum; { sets up fields of pnlWrite to write an addendum for the selected note } const
AS_ADDENDUM = True; IS_ID_CHILD = False;
var
HaveRequired: Boolean; CreatedNote: TCreatedDoc; tmpNode: TTreeNode; x: string;
begin
ClearEditControls; with FEditNote do begin DocType := TYP_ADDENDUM; Title := TitleForNote(lstNotes.ItemIEN); TitleName := Piece(lstNotes.Items[lstNotes.ItemIndex], U, 2); if Copy(TitleName,1,1) = '+' then TitleName := Copy(TitleName, 3, 199); DateTime := FMNow; Author := User.DUZ; AuthorName := User.Name; x := GetPackageRefForNote(lstNotes.ItemIEN); if Piece(x, U, 1) <> '-1' then begin PkgRef := GetPackageRefForNote(lstNotes.ItemIEN); PkgIEN := StrToIntDef(Piece(PkgRef, ';', 1), 0); PkgPtr := Piece(PkgRef, ';', 2); end; Addend := lstNotes.ItemIEN; //Lines := memNewNote.Lines; // Cosigner, if needed, will be set by fNoteProps // Location info will be set after the encounter is loaded end; // check to see if interaction necessary to get required fields if LacksRequiredForCreate then HaveRequired := ExecuteNoteProperties(FEditNote, CT_NOTES, IS_ID_CHILD, False, , 0) else HaveRequired := True; // lock the consult request if there is a consult with FEditNote do if (PkgIEN > 0) and (PkgPtr = PKG_CONSULTS) then HaveRequired := LockConsultRequest(PkgIEN); if HaveRequired then begin uPCEEdit.NoteDateTime := FEditNote.DateTime; uPCEEdit.PCEForNote(FEditNote.Addend, uPCEShow); FEditNote.Location := uPCEEdit.Location; FEditNote.LocationName := ExternalName(uPCEEdit.Location, 44); FEditNote.VisitDate := uPCEEdit.DateTime; PutAddendum(CreatedNote, FEditNote, FEditNote.Addend); uPCEEdit.NoteIEN := CreatedNote.IEN; if CreatedNote.IEN > 0 then LockDocument(CreatedNote.IEN, CreatedNote.ErrorText); if CreatedNote.ErrorText = then begin with FEditNote do begin x := IntToStr(CreatedNote.IEN) + U + 'Addendum to ' + TitleName + U + FloatToStr(DateTime) + U + Patient.Name + U + IntToStr(Author) + ';' + AuthorName + U + LocationName + U + 'new' + U + U + U + U + U + U + U + U; end; lstNotes.Items.Insert(0, x); uChanging := True; tvNotes.Items.BeginUpdate; tmpNode := tvNotes.Items.AddObjectFirst(tvNotes.Items.GetFirstNode, 'New Addendum in Progress', MakeNoteTreeObject('ADDENDUM^New Addendum in Progress^^^^^^^^^^^%^0')); TORTreeNode(tmpNode).StringData := 'ADDENDUM^New Addendum in Progress^^^^^^^^^^^%^0'; tmpNode.ImageIndex := IMG_TOP_LEVEL; tmpNode := tvNotes.Items.AddChildObjectFirst(tmpNode, MakeNoteDisplayText(x), MakeNoteTreeObject(x)); TORTreeNode(tmpNode).StringData := x; tmpNode.ImageIndex := IMG_ADDENDUM; tmpNode.SelectedIndex := IMG_ADDENDUM; tvNotes.Selected := tmpNode; tvNotes.Items.EndUpdate; uChanging := False; Changes.Add(CH_DOC, IntToStr(CreatedNote.IEN), GetTitleText(0), , CH_SIGN_YES); lstNotes.ItemIndex := 0; EditingIndex := 0; SetSubjectVisible(AskSubjectForNotes); cmdChangeClick(Self); // will set captions, sign state for Changes lstNotesClick(Self); // will make pnlWrite visible if timAutoSave.Interval <> 0 then timAutoSave.Enabled := True; memNewNote.SetFocus; end else begin // if note creation failed or failed to get note lock (both unlikely), unlock consult with FEditNote do if (PkgIEN > 0) and (PkgPtr = PKG_CONSULTS) then UnlockConsultRequest(0, PkgIEN); InfoBox(CreatedNote.ErrorText, TX_CREATE_ERR, MB_OK); HaveRequired := False; end; {if CreatedNote.IEN} end; {if HaveRequired} if not HaveRequired then ClearEditControls;
end; procedure TfrmNotes.LoadForEdit; { retrieves an existing note and places the data in the fields of pnlWrite } var
tmpNode: TTreeNode; x: string;
begin
ClearEditControls; if not LockConsultRequestAndNote(lstNotes.ItemIEN) then Exit; EditingIndex := lstNotes.ItemIndex; Changes.Add(CH_DOC, lstNotes.ItemID, GetTitleText(EditingIndex), , CH_SIGN_YES); GetNoteForEdit(FEditNote, lstNotes.ItemIEN); memNewNote.Lines.Assign(FEditNote.Lines); FChanged := False; if FEditNote.Title = TYP_ADDENDUM then begin FEditNote.DocType := TYP_ADDENDUM; FEditNote.TitleName := Piece(lstNotes.Items[lstNotes.ItemIndex], U, 2); if Copy(FEditNote.TitleName,1,1) = '+' then FEditNote.TitleName := Copy(FEditNote.TitleName, 3, 199); if CompareText(Copy(FEditNote.TitleName, 1, 8), 'Addendum') <> 0 then FEditNote.TitleName := FEditNote.TitleName + 'Addendum to '; end; uChanging := True; tvNotes.Items.BeginUpdate; tmpNode := tvNotes.FindPieceNode('EDIT', 1, U, nil); if tmpNode = nil then begin tmpNode := tvNotes.Items.AddObjectFirst(tvNotes.Items.GetFirstNode, 'Note being edited', MakeNoteTreeObject('EDIT^Note being edited^^^^^^^^^^^%^0')); TORTreeNode(tmpNode).StringData := 'EDIT^Note being edited^^^^^^^^^^^%^0'; end else tmpNode.DeleteChildren; x := lstNotes.Items[lstNotes.ItemIndex]; tmpNode.ImageIndex := IMG_TOP_LEVEL; tmpNode := tvNotes.Items.AddChildObjectFirst(tmpNode, MakeNoteDisplayText(x), MakeNoteTreeObject(x)); TORTreeNode(tmpNode).StringData := x; if CompareText(Copy(FEditNote.TitleName, 1, 8), 'Addendum') <> 0 then tmpNode.ImageIndex := IMG_SINGLE else tmpNode.ImageIndex := IMG_ADDENDUM; tmpNode.SelectedIndex := tmpNode.ImageIndex; tvNotes.Selected := tmpNode; tvNotes.Items.EndUpdate; uChanging := False; uPCEEdit.NoteDateTime := MakeFMDateTime(Piece(lstNotes.Items[lstNotes.ItemIndex], U, 3)); uPCEEdit.PCEForNote(lstNotes.ItemIEN, uPCEShow); FEditNote.NeedCPT := uPCEEdit.CPTRequired; txtSubject.Text := FEditNote.Subject; SetSubjectVisible(AskSubjectForNotes); cmdChangeClick(Self); // will set captions, sign state for Changes lstNotesClick(Self); // will make pnlWrite visible if timAutoSave.Interval <> 0 then timAutoSave.Enabled := True; memNewNote.SetFocus;
end; procedure TfrmNotes.SaveEditedNote(var Saved: Boolean); { validates fields and sends the updated note to the server } var
UpdatedNote: TCreatedDoc; x: string;
begin
Saved := False; if (memNewNote.GetTextLen = 0) or (not ContainsVisibleChar(memNewNote.Text)) then begin lstNotes.ItemIndex := EditingIndex; x := lstNotes.ItemID; uChanging := True; tvNotes.Selected := tvNotes.FindPieceNode(x, 1, U, tvNotes.Items.GetFirstNode); uChanging := False; tvNotesChange(Self, tvNotes.Selected); if not FSilent and (InfoBox(GetTitleText(EditingIndex) + TX_EMPTY_NOTE, TC_EMPTY_NOTE, MB_YESNO) = IDYES) then begin FConfirmed := True; mnuActDeleteClick(Self); Saved := True; FDeleted := True; end else FConfirmed := False; Exit; end; //ExpandTabsFilter(memNewNote.Lines, TAB_STOP_CHARS); FEditNote.Lines := memNewNote.Lines; //FEditNote.Lines:= SetLinesTo74ForSave(memNewNote.Lines, Self); FEditNote.Subject := txtSubject.Text; FEditNote.NeedCPT := uPCEEdit.CPTRequired; PutEditedNote(UpdatedNote, FEditNote, lstNotes.GetIEN(EditingIndex)); FChanged := False; // there's no unlocking here since the note is still in Changes after a save if UpdatedNote.IEN > 0 then begin if lstNotes.ItemIndex = EditingIndex then begin EditingIndex := -1; lstNotesClick(Self); end; EditingIndex := -1; // make sure EditingIndex reset even if not viewing edited note Saved := True; FNewIDChild := False; end else begin if not FSilent then InfoBox(UpdatedNote.ErrorText, TX_UPDATE_ERR, MB_OK or MB_ICONWARNING); end;
end; procedure TfrmNotes.SaveCurrentNote(var Saved: Boolean); { called whenever a note should be saved - uses IEN to call appropriate save logic } begin
if EditingIndex < 0 then Exit; SaveEditedNote(Saved);
end; { Form events ------------------------------------------------------------------------------ } procedure TfrmNotes.FormCreate(Sender: TObject); begin
inherited; memNote.Color := ReadOnlyColor; memPCEShow.Color := ReadOnlyColor; lblNewTitle.Color := ReadOnlyColor; EditingIndex := -1; FEditNote.LastCosigner := 0; FEditNote.LastCosignerName := ; FLastNoteID := ; frmDrawers := TfrmDrawers.CreateDrawers(Self, pnlDrawers, [],[]); frmDrawers.Align := alBottom; frmDrawers.RichEditControl := memNewNote; frmDrawers.NewNoteButton := cmdNewNote; frmDrawers.Splitter := splDrawers; frmDrawers.DefTempPiece := 1; tvNotes.Images := dmodShared.imgNotes; tvNotes.StateImages := dmodShared.imgImages; lvNotes.StateImages := dmodShared.imgImages; lvNotes.SmallImages := dmodShared.imgNotes; FImageFlag := TBitmap.Create; FDocList := TStringList.Create;
end; procedure TfrmNotes.pnlRightResize(Sender: TObject); { memNote (TRichEdit) doesn't repaint appropriately unless it's parent panel is refreshed } begin
inherited; pnlRight.Refresh; memNote.Repaint;
end; procedure TfrmNotes.pnlWriteResize(Sender: TObject); begin
inherited; LimitEditWidth(memNewNote, MAX_ENTRY_WIDTH); memNewNote.Constraints.MinWidth := TextWidthByFont(memNewNote.Font.Handle, StringOfChar('X', MAX_ENTRY_WIDTH)) + ScrollBarWidth;
end; { Left panel (selector) events ------------------------------------------------------------- } procedure TfrmNotes.lstNotesClick(Sender: TObject); { loads the text for the selected note or displays the editing panel for the selected note } var
ImageList : TStringList; //kt added \\ i : integer; //kt added \\
begin
inherited; with lstNotes do if ItemIndex = -1 then Exit else if ItemIndex = EditingIndex then begin pnlWrite.Visible := True; pnlRead.Visible := False; mnuViewDetail.Enabled := False; if (FEditNote.IDParent <> 0) and (not FNewIDChild) then mnuActChange.Enabled := False else mnuActChange.Enabled := True; mnuActLoadBoiler.Enabled := True; UpdateReminderFinish; end else begin StatusText('Retrieving selected progress note...'); Screen.Cursor := crHourGlass; pnlRead.Visible := True; pnlWrite.Visible := False; UpdateReminderFinish; lblTitle.Caption := Piece(Piece(Items[ItemIndex], U, 8), ';', 1) + #9 + Piece(Items[ItemIndex], U, 2) + ', ' + Piece(Items[ItemIndex], U, 6) + ', ' + Piece(Piece(Items[ItemIndex], U, 5), ';', 2) + ' (' + FormatFMDateTime('mmm dd,yy@hh:nn', MakeFMDateTime(Piece(Items[ItemIndex], U, 3))) + ')'; LoadDocumentText(memNote.Lines, ItemIEN); mnuViewDetail.Enabled := True; mnuViewDetail.Checked := False; mnuActChange.Enabled := False; mnuActLoadBoiler.Enabled := False; Screen.Cursor := crDefault; StatusText(); end; if(assigned(frmReminderTree)) then frmReminderTree.EnableActions; DisplayPCE; pnlRight.Refresh; memNewNote.Repaint; memNote.Repaint; NotifyOtherApps(NAE_REPORT, 'TIU^' + lstNotes.ItemID); //-----------------------------\\ //kt added the following block:\\ ImageList := TStringList.Create;\\ if CheckForImageLink(ImageList) then begin\\ for i:= 0 to ImageList.Count-1 do begin\\ NotifyOtherApps(NAE_REPORT, 'IMAGE^' + ImageList.Strings[i]);\\ end;\\ end;\\ ImageList.Free;\\ //kt end of addition\\ //-----------------------------\\
end; //kt added the following\\ function TfrmNotes.CheckForImageLink(ImageList : TStringList) : boolean;\\ {Purpose: To scan memNote memo for a link to an image. If found, return link(s)\\ input: none:\\ output: Will return a string list holding 1 or more links\\ Notes: Here will be the <img .. > format scanned for:\\
Here is some opening text...\\ <img src="http://www.geocities.com/kdtop3/OpenVistA.jpg" alt="Image Title 1">\\ And here is some more text\\ <img src="http://www.geocities.com/kdtop3/OpenVistA_small.jpg" alt="Image Title 2">\\ And the saga continues...\\ <img src="http://www.geocities.com/kdtop3/pics/Image100.gif" alt="Image Title 3">\\ As with html, end-of-lines and white space is not preserved or significant
}\\
function GetBetween (var Text : AnsiString; OpenTag,CloseTag : string;\\ KeepTags : Boolean) : string;\\ {Purpose: Gets text between Open and Close tags. Removes any CR's or LF's\\ Input: Text - the text to work on. It IS changed as code is removed\\ KeepTags - true if want tag return in result\\ false if tag not in result (still is removed from Text)\\ Output: Text is changed.\\ Result=the code between the opening and closing tags\\ Note: Both OpenTag and CloseTag MUST be present for anything to happen.\\ }\\ procedure CutInThree(var Text : AnsiString; p1, p2 : Integer; var s1,s2,s3 : AnsiString);\\ {Purpose: Cut input string Text into 3 parts, with cut points given by p1 & p2.\\ p1 points to first character to be in s2\\ p2 points to last character to be in s2 }\\ begin\\ s1 := ; s2 := ; s3 := ;\\ if p1 > 1 then s1 := MidStr(Text, 1, p1-1);\\ s2 := MidStr(Text, p1, p2-p1+1);\\ s3 := MidStr(Text, p2+1, Length(Text)-p2);\\ end;\\ var\\ p1,p2 : integer;\\ s1,s2,s3 : AnsiString;\\ begin\\ Result := ; //default of no result.\\ p1 := Pos(UpperCase(OpenTag), UpperCase(Text));\\ if (p1 > 0) then begin\\ p2 := Pos(UpperCase(CloseTag),UpperCase(Text)) + Length(CloseTag) -1;\\ if ((p2 > 0) and (p2 > p1)) then begin\\ CutInThree (Text, p1,p2, s1,Result,s3);\\ Text := s1+s3;\\ //Now, remove any CR's or LF's\\ repeat\\ p1 := Pos (Chr(13),Result);\\ if p1= 0 then p1 := Pos (Chr(10),Result);\\ if (p1 > 0) then begin\\ CutInThree (Result, p1,p1, s1,s2,s3);\\ Result := s1+s3;\\
// Text := MidStr(Text,1,p1-1) + MidStr(Text,p1+1,Length(Text)-p1);\\
end;\\ until (p1=0);\\ //Now cut off boundry tags if requested.\\ if not KeepTags then begin\\ p1 := Length(OpenTag) + 1;\\ p2 := Length (Result) - Length (CloseTag);\\ CutInThree (Result, p1,p2, s1,s2,s3);\\ Result := s2;\\ end;\\ end;\\ end;\\ end;\\
var\\
Text : AnsiString;\\ Line : string;\\
begin\\
Result := false; //set default\\ if (ImageList <> nil) then begin\\ ImageList.Clear; //set default\\ Text := memNote.Lines.Text; //Get entire note into one long string\\ repeat\\ Line := GetBetween (Text, '<img', '>', true);\\ if Line <> then begin\\ ImageList.Add(Line);\\ Result := true;\\ end;\\ until Line = ;\\ //Note: The following works, but need to replace removed links\\ // with "[Title]" Work on later...\\ //memNote.Lines.Text := Text;\\ end;\\
end;\\ //KT End of addition\\ procedure TfrmNotes.cmdNewNoteClick(Sender: TObject); { maps 'New Note' button to the New Progress Note menu item } begin
inherited; mnuActNewClick(Self);
end; procedure TfrmNotes.cmdPCEClick(Sender: TObject); var
Refresh: boolean; ActionSts: TActionRec; AnIEN: integer; PCEObj, tmpPCEEdit: TPCEData; procedure UpdateEncounterInfo; begin if not FEditingNotePCEObj then begin PCEObj := nil; AnIEN := lstNotes.ItemIEN; if (AnIEN <> 0) and (memNote.Lines.Count > 0) then begin ActOnDocument(ActionSts, AnIEN, 'VIEW'); if ActionSts.Success then begin uPCEShow.CopyPCEData(uPCEEdit); PCEObj := uPCEEdit; end; end; Refresh := EditPCEData(PCEObj); end else begin UpdatePCE(uPCEEdit); Refresh := TRUE; end; if Refresh and (not frmFrame.Closing) then DisplayPCE; end;
begin
inherited; if lstNotes.ItemIndex <> EditingIndex then // save uPCEEdit for note being edited, before updating current note's encounter, then restore (RV - TAM-0801-31056) begin tmpPCEEdit := TPCEData.Create; try uPCEEdit.CopyPCEData(tmpPCEEdit); UpdateEncounterInfo; tmpPCEEdit.CopyPCEData(uPCEEdit); finally tmpPCEEdit.Free; end; end else // no other note being edited, so just proceed as before. UpdateEncounterInfo;
end; { Right panel (editor) events -------------------------------------------------------------- } procedure TfrmNotes.mnuActChangeClick(Sender: TObject); begin
inherited; if (FEditingIndex < 0) or (lstNotes.ItemIndex <> FEditingIndex) then Exit; cmdChangeClick(Sender);
end; procedure TfrmNotes.mnuActLoadBoilerClick(Sender: TObject); var
NoteEmpty: Boolean; BoilerText: TStringList; procedure AssignBoilerText; begin ExecuteTemplateOrBoilerPlate(BoilerText, FEditNote.Title, ltTitle, Self, 'Title: ' + FEditNote.TitleName); memNewNote.Lines.Assign(BoilerText); FChanged := False; end;
begin
inherited; if (FEditingIndex < 0) or (lstNotes.ItemIndex <> FEditingIndex) then Exit; BoilerText := TStringList.Create; try NoteEmpty := memNewNote.Text = ; LoadBoilerPlate(BoilerText, FEditNote.Title); if (BoilerText.Text <> ) or assigned(GetLinkedTemplate(IntToStr(FEditNote.Title), ltTitle)) then begin if NoteEmpty then AssignBoilerText else begin case QueryBoilerPlate(BoilerText) of 0: { do nothing } ; // ignore 1: begin ExecuteTemplateOrBoilerPlate(BoilerText, FEditNote.Title, ltTitle, Self, 'Title: ' + FEditNote.TitleName); memNewNote.Lines.AddStrings(BoilerText); // append end; 2: AssignBoilerText; // replace end; end; end else begin if Sender = mnuActLoadBoiler then InfoBox(TX_NO_BOIL, TC_NO_BOIL, MB_OK) else begin if not NoteEmpty then
// if not FChanged and (InfoBox(TX_BLR_CLEAR, TC_BLR_CLEAR, MB_YESNO) = ID_YES)
if (InfoBox(TX_BLR_CLEAR, TC_BLR_CLEAR, MB_YESNO) = ID_YES) then memNewNote.Lines.Clear; end; end; {if BoilerText.Text <> } finally BoilerText.Free; end;
end; procedure TfrmNotes.cmdChangeClick(Sender: TObject); var
LastTitle, LastConsult: Integer; OKPressed, IsIDChild: Boolean; x: string;
begin
inherited; IsIDChild := uIDNotesActive and (FEditNote.IDParent > 0); LastTitle := FEditNote.Title; if FEditNote.PkgPtr = PKG_CONSULTS then LastConsult := FEditNote.PkgIEN else LastConsult := 0;; if Sender <> Self then OKPressed := ExecuteNoteProperties(FEditNote, CT_NOTES, IsIDChild, FNewIDChild, , 0) else OKPressed := True; if not OKPressed then Exit; // update display fields & uPCEEdit lblNewTitle.Caption := ' ' + FEditNote.TitleName + ' '; if (FEditNote.Addend > 0) and (CompareText(Copy(lblNewTitle.Caption, 2, 8), 'Addendum') <> 0) then lblNewTitle.Caption := ' Addendum to:' + lblNewTitle.Caption; with lblNewTitle do bvlNewTitle.SetBounds(Left - 1, Top - 1, Width + 2, Height + 2); lblRefDate.Caption := FormatFMDateTime('mmm dd,yyyy@hh:nn', FEditNote.DateTime); lblAuthor.Caption := FEditNote.AuthorName; if uPCEEdit.Inpatient then x := 'Adm: ' else x := 'Vst: '; x := x + FormatFMDateTime('mm/dd/yy', FEditNote.VisitDate) + ' ' + FEditNote.LocationName; lblVisit.Caption := x; if Length(FEditNote.CosignerName) > 0 then lblCosigner.Caption := 'Expected Cosigner: ' + FEditNote.CosignerName else lblCosigner.Caption := ; uPCEEdit.NoteTitle := FEditNote.Title; // modify signature requirements if author or cosigner changed if (User.DUZ <> FEditNote.Author) and (User.DUZ <> FEditNote.Cosigner) then Changes.ReplaceSignState(CH_DOC, lstNotes.ItemID, CH_SIGN_NA) else Changes.ReplaceSignState(CH_DOC, lstNotes.ItemID, CH_SIGN_YES); x := lstNotes.Items[EditingIndex]; SetPiece(x, U, 2, lblNewTitle.Caption); SetPiece(x, U, 3, FloatToStr(FEditNote.DateTime)); tvNotes.Selected.Text := MakeNoteDisplayText(x); TORTreeNode(tvNotes.Selected).StringData := x; lstNotes.Items[EditingIndex] := x; Changes.ReplaceText(CH_DOC, lstNotes.ItemID, GetTitleText(EditingIndex)); with FEditNote do if (PkgPtr = PKG_CONSULTS) and (LastConsult <> PkgIEN) then begin // try to lock the new consult, reset to previous if unable if (PkgIEN > 0) and not LockConsultRequest(PkgIEN) then begin Infobox(TX_NO_ORD_CHG, TC_NO_ORD_CHG, MB_OK); PkgIEN := LastConsult; end else begin // unlock the previous consult if LastConsult > 0 then UnlockOrderIfAble(GetConsultOrderIEN(LastConsult)); if PkgIEN = 0 then FOrderID := ; end; end; if LastTitle <> FEditNote.Title then mnuActLoadBoilerClick(Self);
end; procedure TfrmNotes.memNewNoteChange(Sender: TObject); begin
inherited; FChanged := True;
end; procedure TfrmNotes.pnlFieldsResize(Sender: TObject); { center the reference date on the panel } begin
inherited; lblRefDate.Left := (pnlFields.Width - lblRefDate.Width) div 2; if lblRefDate.Left < (lblNewTitle.Left + lblNewTitle.Width + 6) then lblRefDate.Left := (lblNewTitle.Left + lblNewTitle.Width);
end; procedure TfrmNotes.DoAutoSave; var
ErrMsg: string;
begin
if (EditingIndex > -1) and FChanged then begin StatusText('Autosaving note...'); //PutTextOnly(ErrMsg, memNewNote.Lines, lstNotes.GetIEN(EditingIndex)); SetText(ErrMsg, memNewNote.Lines, lstNotes.GetIEN(EditingIndex),1); FChanged := False; StatusText(); end; Assert(ErrMsg = , 'AutoSave: ' + ErrMsg);
end; procedure TfrmNotes.timAutoSaveTimer(Sender: TObject); begin
inherited; DoAutoSave;
end; { View menu events ------------------------------------------------------------------------- } procedure TfrmNotes.mnuViewClick(Sender: TObject); { changes the list of notes available for viewing } var
AuthCtxt: TAuthorContext; DateRange: TNoteDateRange; Saved: Boolean;
begin
inherited; // save note at EditingIndex? if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; end; FLastNoteID := lstNotes.ItemID; mnuViewDetail.Checked := False; StatusText('Retrieving progress note list...'); if Sender is TMenuItem then ViewContext := TMenuItem(Sender).Tag else if FCurrentContext.Status <> then ViewContext := NC_CUSTOM else ViewContext := NC_RECENT; case ViewContext of NC_RECENT: begin FillChar(FCurrentContext, SizeOf(FCurrentContext), 0); lblNotes.Caption := 'Last ' + IntToStr(ReturnMaxNotes) + ' Notes'; FCurrentContext.Status := IntToStr(ViewContext); FCurrentContext.MaxDocs := ReturnMaxNotes; LoadNotes; end; NC_ALL: begin FillChar(FCurrentContext, SizeOf(FCurrentContext), 0); lblNotes.Caption := 'All Signed Notes'; FCurrentContext.Status := IntToStr(ViewContext); LoadNotes; end; NC_UNSIGNED: begin FillChar(FCurrentContext, SizeOf(FCurrentContext), 0); lblNotes.Caption := 'Unsigned Notes'; FCurrentContext.Status := IntToStr(ViewContext); LoadNotes; end; NC_UNCOSIGNED: begin FillChar(FCurrentContext, SizeOf(FCurrentContext), 0); lblNotes.Caption := 'Uncosigned Notes'; FCurrentContext.Status := IntToStr(ViewContext); LoadNotes; end; NC_BY_AUTHOR: begin SelectAuthor(Font.Size, FCurrentContext, AuthCtxt); with AuthCtxt do if Changed then begin FillChar(FCurrentContext, SizeOf(FCurrentContext), 0); lblNotes.Caption := AuthorName + ': Signed Notes'; FCurrentContext.Status := IntToStr(NC_BY_AUTHOR); FCurrentContext.Author := Author; FCurrentContext.TreeAscending := Ascending; LoadNotes; end; end; NC_BY_DATE: begin SelectNoteDateRange(Font.Size, FCurrentContext, DateRange); with DateRange do if Changed then begin FillChar(FCurrentContext, SizeOf(FCurrentContext), 0); lblNotes.Caption := FormatFMDateTime('mmm dd,yy', FMBeginDate) + ' to ' + FormatFMDateTime('mmm dd,yy', FMEndDate) + ': Signed Notes'; FCurrentContext.BeginDate := BeginDate; FCurrentContext.EndDate := EndDate; FCurrentContext.FMBeginDate := FMBeginDate; FCurrentContext.FMEndDate := FMEndDate; FCurrentContext.TreeAscending := Ascending; FCurrentContext.Status := IntToStr(NC_BY_DATE); LoadNotes; end; end; NC_CUSTOM: begin if Sender is TMenuItem then begin SelectTIUView(Font.Size, True, FCurrentContext, uTIUContext); //lblNotes.Caption := 'Custom List'; end; with uTIUContext do if Changed then begin //if not (Sender is TMenuItem) then lblNotes.Caption := 'Default List'; //if MaxDocs = 0 then MaxDocs := ReturnMaxNotes; FCurrentContext.BeginDate := BeginDate; FCurrentContext.EndDate := EndDate; FCurrentContext.FMBeginDate := FMBeginDate; FCurrentContext.FMEndDate := FMEndDate; FCurrentContext.Status := Status; FCurrentContext.Author := Author; FCurrentContext.MaxDocs := MaxDocs; FCurrentContext.ShowSubject := ShowSubject; // NEW PREFERENCES: FCurrentContext.SortBy := SortBy; FCurrentContext.ListAscending := ListAscending; FCurrentContext.GroupBy := GroupBy; FCurrentContext.TreeAscending := TreeAscending; FCurrentContext.SearchField := SearchField; FCurrentContext.Keyword := Keyword; FCurrentContext.Filtered := Filtered; LoadNotes; end; end; end; {case} lblNotes.Caption := SetNoteTreeLabel(FCurrentContext); lblNotes.hint := lblNotes.Caption; StatusText();
end; { Action menu events ----------------------------------------------------------------------- } function TfrmNotes.StartNewEdit(NewNoteType: integer): Boolean; { if currently editing a note, returns TRUE if the user wants to start a new one } var
Saved: Boolean; Msg, CapMsg: string;
begin
Result := True; if EditingIndex > -1 then begin case NewNoteType of NT_ACT_ADDENDUM: begin Msg := TX_NEW_SAVE1 + MakeNoteDisplayText(lstNotes.Items[EditingIndex]) + TX_NEW_SAVE3; CapMsg := TC_NEW_SAVE3; end; NT_ACT_EDIT_NOTE: begin Msg := TX_NEW_SAVE1 + MakeNoteDisplayText(lstNotes.Items[EditingIndex]) + TX_NEW_SAVE4; CapMsg := TC_NEW_SAVE4; end; NT_ACT_ID_ENTRY: begin Msg := TX_NEW_SAVE1 + MakeNoteDisplayText(lstNotes.Items[EditingIndex]) + TX_NEW_SAVE5; CapMsg := TC_NEW_SAVE5; end; else begin Msg := TX_NEW_SAVE1 + MakeNoteDisplayText(lstNotes.Items[EditingIndex]) + TX_NEW_SAVE2; CapMsg := TC_NEW_SAVE2; end; end; if InfoBox(Msg, CapMsg, MB_YESNO) = IDNO then Result := False else begin SaveCurrentNote(Saved); if not Saved then Result := False else LoadNotes; end; end;
end; procedure TfrmNotes.mnuActNewClick(Sender: TObject); const
IS_ID_CHILD = False;
{ switches to current new note or creates a new note if none is being edited already } begin
inherited; if not StartNewEdit(NT_ACT_NEW_NOTE) then Exit; //LoadNotes; // make sure a visit (time & location) is available before creating the note if Encounter.NeedVisit then begin UpdateVisit(Font.Size); frmFrame.DisplayEncounterText; end; if Encounter.NeedVisit then begin InfoBox(TX_NEED_VISIT, TX_NO_VISIT, MB_OK or MB_ICONWARNING); Exit; end; InsertNewNote(IS_ID_CHILD, 0);
end; procedure TfrmNotes.mnuActAddIDEntryClick(Sender: TObject); const
IS_ID_CHILD = True;
var
AnIDParent: integer;
{ switches to current new note or creates a new note if none is being edited already } begin
inherited; AnIDParent := lstNotes.ItemIEN; if not StartNewEdit(NT_ACT_ID_ENTRY) then Exit; //LoadNotes; with tvNotes do Selected := FindPieceNode(IntToStr(AnIDParent), U, Items.GetFirstNode); // make sure a visit (time & location) is available before creating the note if Encounter.NeedVisit then begin UpdateVisit(Font.Size); frmFrame.DisplayEncounterText; end; if Encounter.NeedVisit then begin InfoBox(TX_NEED_VISIT, TX_NO_VISIT, MB_OK or MB_ICONWARNING); Exit; end; InsertNewNote(IS_ID_CHILD, AnIDParent);
end; procedure TfrmNotes.mnuActAddendClick(Sender: TObject); { make an addendum to an existing note } var
ActionSts: TActionRec; ANoteID: string;
begin
inherited; if lstNotes.ItemIEN <= 0 then Exit; ANoteID := lstNotes.ItemID; if not StartNewEdit(NT_ACT_ADDENDUM) then Exit; //LoadNotes; with tvNotes do Selected := FindPieceNode(ANoteID, 1, U, Items.GetFirstNode); if lstNotes.ItemIndex = EditingIndex then begin InfoBox(TX_ADDEND_NO, TX_ADDEND_MK, MB_OK); Exit; end; ActOnDocument(ActionSts, lstNotes.ItemIEN, 'MAKE ADDENDUM'); if not ActionSts.Success then begin InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK); Exit; end; with lstNotes do if TitleForNote(lstNotes.ItemIEN) = TYP_ADDENDUM then begin InfoBox(TX_ADDEND_AD, TX_ADDEND_MK, MB_OK); Exit; end; InsertAddendum;
end; procedure TfrmNotes.mnuActDetachFromIDParentClick(Sender: TObject); var
DocID, WhyNot: string; Saved: boolean; SavedDocID: string;
begin
if lstNotes.ItemIEN = 0 then exit; SavedDocID := lstNotes.ItemID; if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); end; if not CanBeAttached(PDocTreeObject(tvNotes.Selected.Data)^.DocID, WhyNot) then begin WhyNot := StringReplace(WhyNot, 'ATTACH', 'DETACH', [rfIgnoreCase]); WhyNot := StringReplace(WhyNot, 'to an ID', 'from an ID', [rfIgnoreCase]); InfoBox(WhyNot, TX_DETACH_FAILURE, MB_OK); Exit; end; if (InfoBox('DETACH: ' + tvNotes.Selected.Text + CRLF + CRLF + ' FROM: ' + tvNotes.Selected.Parent.Text + CRLF + CRLF + 'Are you sure?', TX_DETACH_CNF, MB_YESNO or MB_DEFBUTTON2 or MB_ICONQUESTION) <> IDYES) then Exit; DocID := PDocTreeObject(tvNotes.Selected.Data)^.DocID; SavedDocID := PDocTreeObject(tvNotes.Selected.Parent.Data)^.DocID; if DetachEntryFromParent(DocID, WhyNot) then begin LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); if tvNotes.Selected <> nil then tvNotes.Selected.Expand(False); end else begin WhyNot := StringReplace(WhyNot, 'ATTACH', 'DETACH', [rfIgnoreCase]); WhyNot := StringReplace(WhyNot, 'to an ID', 'from an ID', [rfIgnoreCase]); InfoBox(WhyNot, TX_DETACH_FAILURE, MB_OK); end;
end; procedure TfrmNotes.mnuActSignListClick(Sender: TObject); { add the note to the Encounter object, see mnuActSignClick - copied} const
SIG_COSIGN = 'COSIGNATURE'; SIG_SIGN = 'SIGNATURE';
var
ActionType, SignTitle: string; ActionSts: TActionRec;
begin
inherited; if lstNotes.ItemIEN = 0 then Exit; if lstNotes.ItemIndex = EditingIndex then Exit; // already in signature list if not LastSaveClean(lstNotes.ItemIEN) and (InfoBox(TX_ABSAVE, TC_ABSAVE, MB_YESNO or MB_DEFBUTTON2) <> IDYES) then Exit; if CosignDocument(lstNotes.ItemIEN) then begin SignTitle := TX_COSIGN; ActionType := SIG_COSIGN; end else begin SignTitle := TX_SIGN; ActionType := SIG_SIGN; end; ActOnDocument(ActionSts, lstNotes.ItemIEN, ActionType); if not ActionSts.Success then begin InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK); Exit; end; LockConsultRequestAndNote(lstNotes.ItemIEN); with lstNotes do Changes.Add(CH_DOC, ItemID, GetTitleText(ItemIndex), , CH_SIGN_YES);
end; procedure TfrmNotes.RemovePCEFromChanges(IEN: Int64; AVisitStr: string = ); begin
if IEN = NT_ADDENDUM then Exit; // no PCE information entered for an addendum // do we need to call DeletePCE(AVisitStr), as was done with NT_NEW_NOTE (ien=-10)??? if AVisitStr = then AVisitStr := VisitStrForNote(IEN); Changes.Remove(CH_PCE, 'V' + AVisitStr); Changes.Remove(CH_PCE, 'P' + AVisitStr); Changes.Remove(CH_PCE, 'D' + AVisitStr); Changes.Remove(CH_PCE, 'I' + AVisitStr); Changes.Remove(CH_PCE, 'S' + AVisitStr); Changes.Remove(CH_PCE, 'A' + AVisitStr); Changes.Remove(CH_PCE, 'H' + AVisitStr); Changes.Remove(CH_PCE, 'E' + AVisitStr); Changes.Remove(CH_PCE, 'T' + AVisitStr);
end; procedure TfrmNotes.mnuActDeleteClick(Sender: TObject); { delete the selected progress note & remove from the Encounter object if necessary } var
DeleteSts, ActionSts: TActionRec; SaveConsult, SavedDocIEN: Integer; ReasonForDelete, AVisitStr, SavedDocID, x: string; Saved: boolean;
begin
inherited; if lstNotes.ItemIEN = 0 then Exit; ActOnDocument(ActionSts, lstNotes.ItemIEN, 'DELETE RECORD'); if ShowMsgOn(not ActionSts.Success, ActionSts.Reason, TX_IN_AUTH) then Exit; ReasonForDelete := SelectDeleteReason(lstNotes.ItemIEN); if ReasonForDelete = DR_CANCEL then Exit; // suppress prompt for deletion when called from SaveEditedNote (Sender = Self) if (Sender <> Self) and (InfoBox(MakeNoteDisplayText(lstNotes.Items[lstNotes.ItemIndex]) + TX_DEL_OK, TX_DEL_CNF, MB_YESNO or MB_DEFBUTTON2 or MB_ICONQUESTION) <> IDYES) then Exit; // do the appropriate locking if not LockConsultRequestAndNote(lstNotes.ItemIEN) then Exit; SavedDocID := lstNotes.ItemID; SavedDocIEN := lstNotes.ItemIEN; if (EditingIndex > -1) and (not FConfirmed) and (lstNotes.ItemIndex <> EditingIndex) and (memNewNote.GetTextLen > 0) then begin SaveCurrentNote(Saved); if not Saved then Exit; end; EditingIndex := -1; FConfirmed := False; (* if Saved then begin EditingIndex := -1; mnuViewClick(Self); with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); end;*) // remove the note DeleteSts.Success := True; x := GetPackageRefForNote(SavedDocIEN); SaveConsult := StrToIntDef(Piece(x, ';', 1), 0); AVisitStr := VisitStrForNote(SavedDocIEN); RemovePCEFromChanges(SavedDocIEN, AVisitStr); if (SavedDocIEN > 0) and (lstNotes.ItemIEN = SavedDocIEN) then DeleteDocument(DeleteSts, SavedDocIEN, ReasonForDelete); if not Changes.Exist(CH_DOC, SavedDocID) then UnlockDocument(SavedDocIEN); Changes.Remove(CH_DOC, SavedDocID); // this will unlock the document if in Changes UnlockConsultRequest(0, SaveConsult); // note has been deleted, so 1st param = 0 // reset the display now that the note is gone if DeleteSts.Success then begin DeletePCE(AVisitStr); // removes PCE data if this was the only note pointing to it ClearEditControls; //ClearPtData; WRONG - fixed in v15.10 - RV LoadNotes;
(* with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode);
if tvNotes.Selected <> nil then tvNotesChange(Self, tvNotes.Selected) else begin*) pnlWrite.Visible := False; pnlRead.Visible := True; UpdateReminderFinish; ShowPCEControls(False); frmDrawers.DisplayDrawers(TRUE, [odTemplates], [odTemplates]); //FALSE); ShowPCEButtons(FALSE); //end; {if ItemIndex} end {if DeleteSts} else InfoBox(DeleteSts.Reason, TX_DEL_ERR, MB_OK or MB_ICONWARNING);
end; procedure TfrmNotes.mnuActEditClick(Sender: TObject); { load the selected progress note for editing } var
ActionSts: TActionRec; ANoteID: string;
begin
inherited; if lstNotes.ItemIndex = EditingIndex then Exit; ANoteID := lstNotes.ItemID; if not StartNewEdit(NT_ACT_EDIT_NOTE) then Exit; //LoadNotes; with tvNotes do Selected := FindPieceNode(ANoteID, 1, U, Items.GetFirstNode); ActOnDocument(ActionSts, lstNotes.ItemIEN, 'EDIT RECORD'); if not ActionSts.Success then begin InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK); Exit; end; LoadForEdit;
end; procedure TfrmNotes.mnuActSaveClick(Sender: TObject); { saves the note that is currently being edited } var
Saved: Boolean; SavedDocID: string;
begin
inherited; if EditingIndex > -1 then begin SavedDocID := Piece(lstNotes.Items[EditingIndex], U, 1); FLastNoteID := SavedDocID; SaveCurrentNote(Saved); if Saved and (EditingIndex < 0) then {RV - v16.2} //if Saved then begin LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); end; end else InfoBox(TX_NO_NOTE, TX_SAVE_NOTE, MB_OK or MB_ICONWARNING);
end; procedure TfrmNotes.mnuActSignClick(Sender: TObject); { sign the currently selected note, save first if necessary } const
SIG_COSIGN = 'COSIGNATURE'; SIG_SIGN = 'SIGNATURE';
var
Saved, NoteUnlocked: Boolean; ActionType, ESCode, SignTitle: string; ActionSts, SignSts: TActionRec; OK: boolean; SavedDocID, tmpItem: string; tmpNode: TTreeNode;
begin
inherited; if lstNotes.ItemIndex = EditingIndex then begin SaveCurrentNote(Saved); if (not Saved) or FDeleted then Exit; end else if EditingIndex > -1 then tmpItem := lstNotes.Items[EditingIndex]; SavedDocID := lstNotes.ItemID; if not LastSaveClean(lstNotes.ItemIEN) and (InfoBox(TX_ABSAVE, TC_ABSAVE, MB_YESNO or MB_DEFBUTTON2) <> IDYES) then Exit; if CosignDocument(lstNotes.ItemIEN) then begin SignTitle := TX_COSIGN; ActionType := SIG_COSIGN; end else begin SignTitle := TX_SIGN; ActionType := SIG_SIGN; end; if not LockConsultRequestAndNote(lstNotes.ItemIEN) then Exit; // no exits after things are locked NoteUnlocked := False; ActOnDocument(ActionSts, lstNotes.ItemIEN, ActionType); if ActionSts.Success then begin if IsSurgeryTitle(TitleForNote(lstNotes.ItemIEN)) then DisplayOpTop(lstNotes.ItemIEN); OK := IsOK2Sign(uPCEShow, lstNotes.ItemIEN); if frmFrame.Closing then exit; if(uPCEShow.Updated) then begin uPCEShow.CopyPCEData(uPCEEdit); uPCEShow.Updated := FALSE; lstNotesClick(Self); end; if(OK) then begin with lstNotes do SignatureForItem(Font.Size, MakeNoteDisplayText(Items[ItemIndex]), SignTitle, ESCode); if Length(ESCode) > 0 then begin SignDocument(SignSts, lstNotes.ItemIEN, ESCode); RemovePCEFromChanges(lstNotes.ItemIEN); NoteUnlocked := Changes.Exist(CH_DOC, lstNotes.ItemID); Changes.Remove(CH_DOC, lstNotes.ItemID); // this will unlock if in Changes if SignSts.Success then begin SendMessage(frmConsults.Handle, UM_NEWORDER, ORDER_SIGN, 0); {*REV*} lstNotesClick(Self); end else InfoBox(SignSts.Reason, TX_SIGN_ERR, MB_OK); end {if Length(ESCode)} else NoteUnlocked := Changes.Exist(CH_DOC, lstNotes.ItemID); end; end else InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK); if not NoteUnlocked then UnlockDocument(lstNotes.ItemIEN); UnlockConsultRequest(lstNotes.ItemIEN); mnuViewClick(Self); //v15.9 - REV //LoadNotes; //v15.9 - REV if EditingIndex > -1 then begin lstNotes.Items.Insert(0, tmpItem); tmpNode := tvNotes.Items.AddObjectFirst(tvNotes.Items.GetFirstNode, 'Note being edited', MakeNoteTreeObject('EDIT^Note being edited^^^^^^^^^^^%^0')); TORTreeNode(tmpNode).StringData := 'EDIT^Note being edited^^^^^^^^^^^%^0'; tmpNode.ImageIndex := IMG_TOP_LEVEL; tmpNode := tvNotes.Items.AddChildObjectFirst(tmpNode, MakeNoteDisplayText(tmpItem), MakeNoteTreeObject(tmpItem)); TORTreeNode(tmpNode).StringData := tmpItem; SetTreeNodeImagesAndFormatting(TORTreeNode(tmpNode), FCurrentContext, CT_NOTES); end; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode);
end; procedure TfrmNotes.SaveSignItem(const ItemID, ESCode: string); { saves and optionally signs a progress note or addendum } var
AnIndex, IEN, i: Integer; Saved, ContinueSign: Boolean; {*RAB* 8/26/99} SignSts: TActionRec; APCEObject: TPCEData; OK: boolean;
begin
AnIndex := -1; IEN := StrToIntDef(ItemID, 0); if IEN = 0 then Exit; if frmFrame.TimedOut and (EditingIndex <> -1) then FSilent := True; with lstNotes do for i := 0 to Items.Count - 1 do if lstNotes.GetIEN(i) = IEN then begin AnIndex := i; break; end; if (AnIndex > -1) and (AnIndex = EditingIndex) then begin SaveCurrentNote(Saved); if not Saved then Exit; if FDeleted then begin FDeleted := False; Exit; end; IEN := lstNotes.GetIEN(AnIndex); // saving will change IEN end; if Length(ESCode) > 0 then begin if not LastSaveClean(IEN) and (InfoBox(TX_ABSAVE, TC_ABSAVE, MB_YESNO or MB_DEFBUTTON2) <> IDYES) then ContinueSign := False else ContinueSign := True; if ContinueSign then begin if (AnIndex >= 0) and (AnIndex = lstNotes.ItemIndex) then APCEObject := uPCEShow else APCEObject := nil; OK := IsOK2Sign(APCEObject, IEN); if frmFrame.Closing then exit; if(assigned(APCEObject)) and (uPCEShow.Updated) then begin uPCEShow.CopyPCEData(uPCEEdit); uPCEShow.Updated := FALSE; lstNotesClick(Self); end else uPCEEdit.Clear; if(OK) then begin if ((not FSilent) and IsSurgeryTitle(TitleForNote(IEN))) then DisplayOpTop(IEN); SignDocument(SignSts, IEN, ESCode); if not SignSts.Success then InfoBox(SignSts.Reason, TX_SIGN_ERR, MB_OK); end; {if OK} end; {if ContinueSign} end; {if Length(ESCode)} UnlockConsultRequest(IEN); if (AnIndex = lstNotes.ItemIndex) and (not frmFrame.ContextChanging) then begin LoadNotes; with tvNotes do Selected := FindPieceNode(IntToStr(IEN), U, Items.GetFirstNode); end;
end; procedure TfrmNotes.popNoteMemoPopup(Sender: TObject); begin
inherited; if PopupComponent(Sender, popNoteMemo) is TCustomEdit then FEditCtrl := TCustomEdit(PopupComponent(Sender, popNoteMemo)) else FEditCtrl := nil; if FEditCtrl <> nil then begin popNoteMemoCut.Enabled := FEditCtrl.SelLength > 0; popNoteMemoCopy.Enabled := popNoteMemoCut.Enabled; popNoteMemoPaste.Enabled := (not TORExposedCustomEdit(FEditCtrl).ReadOnly) and Clipboard.HasFormat(CF_TEXT); popNoteMemoTemplate.Enabled := frmDrawers.CanEditTemplates and popNoteMemoCut.Enabled; popNoteMemoFind.Enabled := FEditCtrl.GetTextLen > 0; end else begin popNoteMemoCut.Enabled := False; popNoteMemoCopy.Enabled := False; popNoteMemoPaste.Enabled := False; popNoteMemoTemplate.Enabled := False; end; if pnlWrite.Visible then begin popNoteMemoSpell.Enabled := True; popNoteMemoGrammar.Enabled := True; popNoteMemoReformat.Enabled := True; popNoteMemoReplace.Enabled := (FEditCtrl.GetTextLen > 0); end else begin popNoteMemoSpell.Enabled := False; popNoteMemoGrammar.Enabled := False; popNoteMemoReformat.Enabled := False; popNoteMemoReplace.Enabled := False; end;
end; procedure TfrmNotes.popNoteMemoCutClick(Sender: TObject); begin
inherited; FEditCtrl.CutToClipboard;
end; procedure TfrmNotes.popNoteMemoCopyClick(Sender: TObject); begin
inherited; FEditCtrl.CopyToClipboard;
end; procedure TfrmNotes.popNoteMemoPasteClick(Sender: TObject); begin
inherited; FEditCtrl.SelText := Clipboard.AsText; {*KCM*} //FEditCtrl.PasteFromClipboard; // use AsText to prevent formatting
end; procedure TfrmNotes.popNoteMemoReformatClick(Sender: TObject); begin
inherited; if Screen.ActiveControl <> memNewNote then Exit; ReformatMemoParagraph(memNewNote);
end; procedure TfrmNotes.popNoteMemoSaveContinueClick(Sender: TObject); begin
inherited; FChanged := True; DoAutoSave;
end; procedure TfrmNotes.popNoteMemoFindClick(Sender: TObject); begin
inherited; SendMessage(TRichEdit(popNoteMemo.PopupComponent).Handle, WM_VSCROLL, SB_TOP, 0); with dlgFindText do begin Position := Point(Application.MainForm.Left + pnlLeft.Width, Application.MainForm.Top); FindText := ; Options := [frDown, frHideUpDown]; Execute; end;
end; procedure TfrmNotes.dlgFindTextFind(Sender: TObject); begin
dmodShared.FindRichEditText(dlgFindText, TRichEdit(popNoteMemo.PopupComponent));
end; procedure TfrmNotes.popNoteMemoReplaceClick(Sender: TObject); begin
inherited; SendMessage(TRichEdit(popNoteMemo.PopupComponent).Handle, WM_VSCROLL, SB_TOP, 0); with dlgReplaceText do begin Position := Point(Application.MainForm.Left + pnlLeft.Width, Application.MainForm.Top); FindText := ; ReplaceText := ; Options := [frDown, frHideUpDown]; Execute; end;
end; procedure TfrmNotes.dlgReplaceTextFind(Sender: TObject); begin
inherited; dmodShared.FindRichEditText(dlgFindText, TRichEdit(popNoteMemo.PopupComponent));
end; procedure TfrmNotes.dlgReplaceTextReplace(Sender: TObject); begin
inherited; dmodShared.ReplaceRichEditText(dlgReplaceText, TRichEdit(popNoteMemo.PopupComponent));
end; procedure TfrmNotes.popNoteMemoSpellClick(Sender: TObject); begin
inherited; DoAutoSave; SpellCheckForControl(memNewNote);
end; procedure TfrmNotes.popNoteMemoGrammarClick(Sender: TObject); begin
inherited; DoAutoSave; GrammarCheckForControl(memNewNote);
end; procedure TfrmNotes.mnuViewDetailClick(Sender: TObject); begin
inherited; if lstNotes.ItemIEN <= 0 then Exit; mnuViewDetail.Checked := not mnuViewDetail.Checked; if mnuViewDetail.Checked then begin StatusText('Retrieving progress note details...'); Screen.Cursor := crHourGlass; LoadDetailText(memNote.Lines, lstNotes.ItemIEN); Screen.Cursor := crDefault; StatusText(); memNote.SelStart := 0; memNote.Repaint; end else lstNotesClick(Self); SendMessage(memNote.Handle, WM_VSCROLL, SB_TOP, 0);
end; procedure TfrmNotes.FormClose(Sender: TObject; var Action: TCloseAction); var
Saved: Boolean; IEN: Int64; ErrMsg: string; DeleteSts: TActionRec;
begin
inherited; if frmFrame.TimedOut and (EditingIndex <> -1) then begin FSilent := True; if memNewNote.GetTextLen > 0 then SaveCurrentNote(Saved) else begin IEN := lstNotes.GetIEN(EditingIndex); if not LastSaveClean(IEN) then // means note hasn't been committed yet begin LockDocument(IEN, ErrMsg); if ErrMsg = then begin DeleteDocument(DeleteSts, IEN, ); UnlockDocument(IEN); end; {if ErrMsg} end; {if not LastSaveClean} end; {else} end; {if frmFrame}
end; procedure TfrmNotes.mnuActIdentifyAddlSignersClick(Sender: TObject); var
Exclusions: TStrings; Saved, x, y: boolean; SignerList: TSignerList; ActionSts: TActionRec; SigAction: integer; SavedDocID: string;
begin
inherited; if lstNotes.ItemIEN = 0 then exit; SavedDocID := lstNotes.ItemID; if lstNotes.ItemIndex = EditingIndex then begin SaveCurrentNote(Saved); if not Saved then Exit; LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); end; x := CanChangeCosigner(lstNotes.ItemIEN); ActOnDocument(ActionSts, lstNotes.ItemIEN, 'IDENTIFY SIGNERS'); y := ActionSts.Success; if x and not y then begin if InfoBox(ActionSts.Reason + CRLF + CRLF + 'Would you like to change the cosigner?', TX_IN_AUTH, MB_YESNO or MB_DEFBUTTON2 or MB_ICONQUESTION) = ID_YES then SigAction := SG_COSIGNER else
Exit;
end else if y and not x then SigAction := SG_ADDITIONAL else if x and y then SigAction := SG_BOTH else begin InfoBox(ActionSts.Reason, TX_IN_AUTH, MB_OK); Exit; end; if not LockConsultRequestAndNote(lstNotes.ItemIEN) then Exit; Exclusions := GetCurrentSigners(lstNotes.ItemIEN); SelectAdditionalSigners(Font.Size, lstNotes.ItemIEN, SigAction, Exclusions, SignerList, CT_NOTES); with SignerList do begin case SigAction of SG_ADDITIONAL: if Changed and (Signers <> nil) and (Signers.Count > 0) then UpdateAdditionalSigners(lstNotes.ItemIEN, Signers); SG_COSIGNER: if Changed then ChangeCosigner(lstNotes.ItemIEN, Cosigner); SG_BOTH: if Changed then begin if (Signers <> nil) and (Signers.Count > 0) then UpdateAdditionalSigners(lstNotes.ItemIEN, Signers); ChangeCosigner(lstNotes.ItemIEN, Cosigner); end; end; lstNotesClick(Self); end; UnlockDocument(lstNotes.ItemIEN); UnlockConsultRequest(lstNotes.ItemIEN);
end; procedure TfrmNotes.popNoteMemoAddlSignClick(Sender: TObject); begin
inherited; mnuActIdentifyAddlSignersClick(Self);
end; procedure TfrmNotes.ProcessNotifications; var
x: string; Saved: boolean; tmpNode: TTreeNode; AnObject: PDocTreeObject;
begin
if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; end; lblNotes.Caption := Notifications.Text; EditingIndex := -1; lstNotes.Enabled := True ; pnlRead.BringToFront ; // show ALL unsigned/uncosigned for a patient, not just the alerted one // what about cosignature? How to get correct list? ORB FOLLOWUP TYPE = OR alerts only x := Notifications.AlertData; if StrToIntDef(Piece(x, U, 1), 0) = 0 then begin InfoBox(TX_NO_ALERT, TX_CAP_NO_ALERT, MB_OK); Exit; end; uChanging := True; tvNotes.Items.BeginUpdate; lstNotes.Clear; KillDocTreeObjects(tvNotes); tvNotes.Items.Clear; lstNotes.Items.Add(x); AnObject := MakeNoteTreeObject('ALERT^Alerted Note^^^^^^^^^^^%^0'); tmpNode := tvNotes.Items.AddObjectFirst(tvNotes.Items.GetFirstNode, AnObject.NodeText, AnObject); TORTreeNode(tmpNode).StringData := 'ALERT^Alerted Note^^^^^^^^^^^%^0'; tmpNode.ImageIndex := IMG_TOP_LEVEL; AnObject := MakeNoteTreeObject(x); tmpNode := tvNotes.Items.AddChildObjectFirst(tmpNode, AnObject.NodeText, AnObject); TORTreeNode(tmpNode).StringData := x; SetTreeNodeImagesAndFormatting(TORTreeNode(tmpNode), FCurrentContext, CT_NOTES); tvNotes.Selected := tmpNode; tvNotes.Items.EndUpdate; uChanging := False; tvNotesChange(Self, tvNotes.Selected); case Notifications.Followup of NF_NOTES_UNSIGNED_NOTE: ; //Automatically deleted by sig action!!! end; if Copy(Piece(Notifications.RecordID, U, 2), 1, 6) = 'TIUADD' then Notifications.Delete; if Copy(Piece(Notifications.RecordID, U, 2), 1, 5) = 'TIUID' then Notifications.Delete;
end; procedure TfrmNotes.SetViewContext(AContext: TTIUContext); var
Saved: boolean;
begin
if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; end; FCurrentContext := AContext; EditingIndex := -1; tvNotes.Enabled := True ; pnlRead.BringToFront ; if FCurrentContext.Status <> then with uTIUContext do begin BeginDate := FCurrentContext.BeginDate; EndDate := FCurrentContext.EndDate; FMBeginDate := FCurrentContext.FMBeginDate; FMEndDate := FCurrentContext.FMEndDate; Status := FCurrentContext.Status; Author := FCurrentContext.Author; MaxDocs := FCurrentContext.MaxDocs; ShowSubject := FCurrentContext.ShowSubject; GroupBy := FCurrentContext.GroupBy; SortBy := FCurrentContext.SortBy; ListAscending := FCurrentContext.ListAscending; TreeAscending := FCurrentContext.TreeAscending; Keyword := FCurrentContext.Keyword; SearchField := FCurrentContext.SearchField; Filtered := FCurrentContext.Filtered; Changed := True; mnuViewClick(Self); end else begin ViewContext := NC_RECENT ; mnuViewClick(Self); end;
end; procedure TfrmNotes.mnuViewSaveAsDefaultClick(Sender: TObject); const
TX_NO_MAX = 'You have not specified a maximum number of notes to be returned.' + CRLF + 'If you save this preference, the result will be that ALL notes for every' + CRLF + 'patient will be saved as your default view.' + CRLF + CRLF + 'For patients with large numbers of notes, this could result in some lengthy' + CRLF + 'delays in loading the list of notes.' + CRLF + CRLF + 'Are you sure you mean to do this?'; TX_REPLACE = 'Replace current defaults?';
begin
inherited; if FCurrentContext.MaxDocs = 0 then if MessageDlg(TX_NO_MAX, mtWarning, [mbYes, mbNo], 0) = mrNo then begin mnuViewClick(mnuViewCustom); Exit; end; if MessageDlg(TX_REPLACE, mtConfirmation, [mbYes, mbNo], 0) = mrYes then begin SaveCurrentTIUContext(FCurrentContext); FDefaultContext := FCurrentContext; //lblNotes.Caption := 'Default List'; end;
end; procedure TfrmNotes.mnuViewReturntoDefaultClick(Sender: TObject); begin
inherited; SetViewContext(FDefaultContext);
end; procedure TfrmNotes.popNoteMemoTemplateClick(Sender: TObject); begin
inherited; EditTemplates(Self, TRUE, FEditCtrl.SelText);
end; procedure TfrmNotes.popNoteListPopup(Sender: TObject); begin
inherited; N4.Visible := (popNoteList.PopupComponent is TORTreeView); popNoteListExpandAll.Visible := N4.Visible; popNoteListExpandSelected.Visible := N4.Visible; popNoteListCollapseAll.Visible := N4.Visible; popNoteListCollapseSelected.Visible := N4.Visible;
end; procedure TfrmNotes.popNoteListExpandAllClick(Sender: TObject); begin
inherited; tvNotes.FullExpand;
end; procedure TfrmNotes.popNoteListCollapseAllClick(Sender: TObject); begin
inherited; tvNotes.Selected := nil; lvNotes.Items.Clear; memNote.Clear; tvNotes.FullCollapse; tvNotes.Selected := tvNotes.TopItem;
end; procedure TfrmNotes.popNoteListExpandSelectedClick(Sender: TObject); begin
inherited; if tvNotes.Selected = nil then exit; with tvNotes.Selected do if HasChildren then Expand(True);
end; procedure TfrmNotes.popNoteListCollapseSelectedClick(Sender: TObject); begin
inherited; if tvNotes.Selected = nil then exit; with tvNotes.Selected do if HasChildren then Collapse(True);
end; procedure TfrmNotes.mnuEditTemplatesClick(Sender: TObject); begin
inherited; EditTemplates(Self);
end; procedure TfrmNotes.mnuNewTemplateClick(Sender: TObject); begin
inherited; EditTemplates(Self, TRUE);
end; procedure TfrmNotes.mnuEditSharedTemplatesClick(Sender: TObject); begin
inherited; EditTemplates(Self, FALSE, , TRUE);
end; procedure TfrmNotes.mnuNewSharedTemplateClick(Sender: TObject); begin
inherited; EditTemplates(Self, TRUE, , TRUE);
end; procedure TfrmNotes.mnuOptionsClick(Sender: TObject); begin
inherited; mnuEditTemplates.Enabled := frmDrawers.CanEditTemplates; mnuNewTemplate.Enabled := frmDrawers.CanEditTemplates; mnuEditSharedTemplates.Enabled := frmDrawers.CanEditShared; mnuNewSharedTemplate.Enabled := frmDrawers.CanEditShared; mnuEditDialgFields.Enabled := CanEditTemplateFields;
end; procedure TfrmNotes.SetEditingIndex(const Value: Integer); begin
FEditingIndex := Value; if(FEditingIndex < 0) then KillReminderDialog(Self); if(assigned(frmReminderTree)) then frmReminderTree.EnableActions;
end; function TfrmNotes.CanFinishReminder: boolean; begin
if(EditingIndex < 0) then Result := FALSE else Result := (lstNotes.ItemIndex = EditingIndex);
end; procedure TfrmNotes.FormDestroy(Sender: TObject); begin
FDocList.Free; FImageFlag.Free; KillDocTreeObjects(tvNotes); inherited;
end; function TfrmNotes.GetDrawers: TFrmDrawers; begin
Result := frmDrawers;
end; procedure TfrmNotes.AssignRemForm; begin
with RemForm do begin Form := Self; PCEObj := uPCEEdit; RightPanel := pnlRight; CanFinishProc := CanFinishReminder; DisplayPCEProc := DisplayPCE; Drawers := frmDrawers; NewNoteRE := memNewNote; NoteList := lstNotes; end;
end; procedure TfrmNotes.mnuEditDialgFieldsClick(Sender: TObject); begin
inherited; EditDialogFields;
end; //=================== Added for sort/search enhancements ====================== procedure TfrmNotes.LoadNotes; var
tmpList: TStringList; ANode: TORTreeNode;
begin
tmpList := TStringList.Create; try FDocList.Clear; uChanging := True; RedrawSuspend(memNote.Handle); RedrawSuspend(lvNotes.Handle); tvNotes.Items.BeginUpdate; lstNotes.Items.Clear; KillDocTreeObjects(tvNotes); tvNotes.Items.Clear; tvNotes.Items.EndUpdate; lvNotes.Items.Clear; memNote.Clear; memNote.Invalidate; lblTitle.Caption := ; with FCurrentContext do begin if Status <> IntToStr(NC_UNSIGNED) then begin ListNotesForTree(tmpList, NC_UNSIGNED, 0, 0, 0, 0, TreeAscending); if tmpList.Count > 0 then begin CreateListItemsforDocumentTree(FDocList, tmpList, NC_UNSIGNED, GroupBy, TreeAscending, CT_NOTES); UpdateTreeView(FDocList, tvNotes); end; tmpList.Clear; FDocList.Clear; end; if Status <> IntToStr(NC_UNCOSIGNED) then begin ListNotesForTree(tmpList, NC_UNCOSIGNED, 0, 0, 0, 0, TreeAscending); if tmpList.Count > 0 then begin CreateListItemsforDocumentTree(FDocList, tmpList, NC_UNCOSIGNED, GroupBy, TreeAscending, CT_NOTES); UpdateTreeView(FDocList, tvNotes); end; tmpList.Clear; FDocList.Clear; end; ListNotesForTree(tmpList, StrToIntDef(Status, 0), FMBeginDate, FMEndDate, Author, MaxDocs, TreeAscending); CreateListItemsforDocumentTree(FDocList, tmpList, StrToIntDef(Status, 0), GroupBy, TreeAscending, CT_NOTES); UpdateTreeView(FDocList, tvNotes); end; with tvNotes do begin uChanging := True; tvNotes.Items.BeginUpdate; RemoveParentsWithNoChildren(tvNotes, FCurrentContext); // moved here in v15.9 (RV) if FLastNoteID <> then Selected := FindPieceNode(FLastNoteID, 1, U, nil); if Selected = nil then begin if (FCurrentContext.GroupBy <> ) or (FCurrentContext.Filtered) then begin ANode := TORTreeNode(Items.GetFirstNode); while ANode <> nil do begin ANode.Expand(False); Selected := ANode; ANode := TORTreeNode(ANode.GetNextSibling); end; end else begin ANode := tvNotes.FindPieceNode(FCurrentContext.Status, 1, U, nil); if ANode <> nil then ANode.Expand(False); ANode := tvNotes.FindPieceNode(IntToStr(NC_UNSIGNED), 1, U, nil); if ANode = nil then ANode := tvNotes.FindPieceNode(IntToStr(NC_UNCOSIGNED), 1, U, nil); if ANode = nil then ANode := tvNotes.FindPieceNode(FCurrentContext.Status, 1, U, nil); if ANode <> nil then begin if ANode.getFirstChild <> nil then Selected := ANode.getFirstChild else Selected := ANode; end; end; end; memNote.Clear; with lvNotes do begin Selected := nil; if FCurrentContext.SortBy <> then ColumnToSort := Pos(FCurrentContext.SortBy, 'RDSAL') - 1; if not FCurrentContext.ShowSubject then begin Columns[1].Width := 2 * (Width div 5); Columns[2].Width := 0; end else begin Columns[1].Width := Width div 5; Columns[2].Width := Columns[1].Width; end; end; //RemoveParentsWithNoChildren(tvNotes, FCurrentContext); // moved FROM here in v15.9 (RV) tvNotes.Items.EndUpdate; uChanging := False; SendMessage(tvNotes.Handle, WM_VSCROLL, SB_TOP, 0); if Selected <> nil then tvNotesChange(Self, Selected); end; finally RedrawActivate(memNote.Handle); RedrawActivate(lvNotes.Handle); tmpList.Free; end;
end; procedure TfrmNotes.UpdateTreeView(DocList: TStringList; Tree: TORTreeView); begin
with Tree do begin uChanging := True; Items.BeginUpdate; lstNotes.Items.AddStrings(DocList); BuildDocumentTree(DocList, '0', Tree, nil, FCurrentContext, CT_NOTES); Items.EndUpdate; uChanging := False; end;
end; procedure TfrmNotes.tvNotesChange(Sender: TObject; Node: TTreeNode); var
x, MySearch, MyNodeID: string; i: integer; WhyNot: string;
begin
if uChanging then Exit; with tvNotes do begin memNote.Clear; if Selected = nil then Exit; if uIDNotesActive then begin mnuActDetachFromIDParent.Enabled := (Selected.ImageIndex in [IMG_ID_CHILD, IMG_ID_CHILD_ADD]); popNoteListDetachFromIDParent.Enabled := mnuActDetachFromIDParent.Enabled; if (Selected.ImageIndex in [IMG_SINGLE, IMG_PARENT, IMG_ID_CHILD, IMG_ID_CHILD_ADD]) then mnuActAttachtoIDParent.Enabled := CanBeAttached(PDocTreeObject(Selected.Data)^.DocID, WhyNot) else mnuActAttachtoIDParent.Enabled := False; popNoteListAttachtoIDParent.Enabled := mnuActAttachtoIDParent.Enabled; if (Selected.ImageIndex in [IMG_SINGLE, IMG_PARENT, IMG_IDNOTE_OPEN, IMG_IDNOTE_SHUT, IMG_IDPAR_ADDENDA_OPEN, IMG_IDPAR_ADDENDA_SHUT]) then mnuActAddIDEntry.Enabled := CanReceiveAttachment(PDocTreeObject(Selected.Data)^.DocID, WhyNot) else mnuActAddIDEntry.Enabled := False; popNoteListAddIDEntry.Enabled := mnuActAddIDEntry.Enabled end; RedrawSuspend(lvNotes.Handle); RedrawSuspend(memNote.Handle); popNoteListExpandSelected.Enabled := Selected.HasChildren; popNoteListCollapseSelected.Enabled := Selected.HasChildren; x := TORTreeNode(Selected).StringData; if (Selected.ImageIndex in [IMG_TOP_LEVEL, IMG_GROUP_OPEN, IMG_GROUP_SHUT]) then begin lvNotes.Visible := True; lvNotes.Items.Clear; lvNotes.Height := (2 * lvNotes.Parent.Height) div 5; with lblTitle do begin Caption := Trim(Selected.Text); if (FCurrentContext.SearchField <> ) and (FCurrentContext.Filtered) then begin case FCurrentContext.SearchField[1] of 'T': MySearch := 'TITLE'; 'S': MySearch := 'SUBJECT'; 'B': MySearch := 'TITLE or SUBJECT'; end; Caption := Caption + ' where ' + MySearch + ' contains "' + UpperCase(FCurrentContext.Keyword) + '"'; end; end; if Selected.ImageIndex = IMG_TOP_LEVEL then MyNodeID := Piece(TORTreeNode(Selected).StringData, U, 1) else if Selected.Parent.ImageIndex = IMG_TOP_LEVEL then MyNodeID := Piece(TORTreeNode(Selected.Parent).StringData, U, 1) else if Selected.Parent.Parent.ImageIndex = IMG_TOP_LEVEL then MyNodeID := Piece(TORTreeNode(Selected.Parent.Parent).StringData, U, 1); uChanging := True; TraverseTree(tvNotes, lvNotes, Selected.GetFirstChild, MyNodeID, FCurrentContext); with lvNotes do begin for i := 0 to Columns.Count - 1 do Columns[i].ImageIndex := IMG_NONE; ColumnSortForward := FCurrentContext.ListAscending; if ColumnToSort = 5 then ColumnToSort := 0; if ColumnSortForward then Columns[ColumnToSort].ImageIndex := IMG_ASCENDING else Columns[ColumnToSort].ImageIndex := IMG_DESCENDING; if ColumnToSort = 0 then ColumnToSort := 5; AlphaSort; Columns[5].Width := 0; Columns[6].Width := 0; end; uChanging := False; with lvNotes do if Items.Count > 0 then begin Selected := Items[0]; lvNotesSelectItem(Self, Selected, True); end else begin Selected := nil; lstNotes.ItemIndex := -1; memPCEShow.Clear; ShowPCEControls(False); end; pnlWrite.Visible := False; pnlRead.Visible := True; // uncommented next 4 lines in v17.5 (RV) //----------------------------- UpdateReminderFinish; ShowPCEControls(False); frmDrawers.DisplayDrawers(TRUE, [odTemplates], [odTemplates]); //FALSE); ShowPCEButtons(FALSE); //----------------------------- //memNote.Clear; end else if StrToIntDef(Piece(x, U, 1), 0) > 0 then begin memNote.Clear; lvNotes.Visible := False; lstNotes.SelectByID(Piece(x, U, 1)); lstNotesClick(Self); SendMessage(memNote.Handle, WM_VSCROLL, SB_TOP, 0); end; SendMessage(tvNotes.Handle, WM_HSCROLL, SB_THUMBTRACK, 0); RedrawActivate(lvNotes.Handle); RedrawActivate(memNote.Handle); end;
end; procedure TfrmNotes.tvNotesCollapsed(Sender: TObject; Node: TTreeNode); begin
with Node do begin if (ImageIndex in [IMG_GROUP_OPEN, IMG_IDNOTE_OPEN, IMG_IDPAR_ADDENDA_OPEN]) then ImageIndex := ImageIndex - 1; if (SelectedIndex in [IMG_GROUP_OPEN, IMG_IDNOTE_OPEN, IMG_IDPAR_ADDENDA_OPEN]) then SelectedIndex := SelectedIndex - 1; end;
end; procedure TfrmNotes.tvNotesExpanded(Sender: TObject; Node: TTreeNode);
function SortByTitle(Node1, Node2: TTreeNode; Data: Longint): Integer; stdcall; begin { Within an ID parent node, sorts in ascending order by title BUT - addenda to parent document are always at the top of the sort, in date order} if (Copy(PDocTreeObject(Node1.Data)^.DocTitle, 1, 8) = 'Addendum') and (Copy(PDocTreeObject(Node2.Data)^.DocTitle, 1, 8) = 'Addendum') then begin Result := AnsiStrIComp(PChar(PDocTreeObject(Node1.Data)^.DocFMDate), PChar(PDocTreeObject(Node2.Data)^.DocFMDate)); end else if Copy(PDocTreeObject(Node1.Data)^.DocTitle, 1, 8) = 'Addendum' then Result := -1 else if Copy(PDocTreeObject(Node2.Data)^.DocTitle, 1, 8) = 'Addendum' then Result := 1 else begin if Data = 0 then Result := AnsiStrIComp(PChar(PDocTreeObject(Node1.Data)^.DocTitle), PChar(PDocTreeObject(Node2.Data)^.DocTitle)) else Result := -AnsiStrIComp(PChar(PDocTreeObject(Node1.Data)^.DocTitle), PChar(PDocTreeObject(Node2.Data)^.DocTitle)); end end; function SortByDate(Node1, Node2: TTreeNode; Data: Longint): Integer; stdcall; begin { Within an ID parent node, sorts in ascending order by document date BUT - addenda to parent document are always at the top of the sort, in date order} if (Copy(PDocTreeObject(Node1.Data)^.DocTitle, 1, 8) = 'Addendum') and (Copy(PDocTreeObject(Node2.Data)^.DocTitle, 1, 8) = 'Addendum') then begin Result := AnsiStrIComp(PChar(PDocTreeObject(Node1.Data)^.DocFMDate), PChar(PDocTreeObject(Node2.Data)^.DocFMDate)); end else if Copy(PDocTreeObject(Node1.Data)^.DocTitle, 1, 8) = 'Addendum' then Result := -1 else if Copy(PDocTreeObject(Node2.Data)^.DocTitle, 1, 8) = 'Addendum' then Result := 1 else begin if Data = 0 then Result := AnsiStrIComp(PChar(PDocTreeObject(Node1.Data)^.DocFMDate), PChar(PDocTreeObject(Node2.Data)^.DocFMDate)) else Result := -AnsiStrIComp(PChar(PDocTreeObject(Node1.Data)^.DocFMDate), PChar(PDocTreeObject(Node2.Data)^.DocFMDate)); end; end;
begin
with Node do begin if Assigned(Data) then if (Pos('<', PDocTreeObject(Data)^.DocHasChildren) > 0) then begin if (PDocTreeObject(Node.Data)^.OrderByTitle) then CustomSort(@SortByTitle, 0) else CustomSort(@SortByDate, 0); end; if (ImageIndex in [IMG_GROUP_SHUT, IMG_IDNOTE_SHUT, IMG_IDPAR_ADDENDA_SHUT]) then ImageIndex := ImageIndex + 1; if (SelectedIndex in [IMG_GROUP_SHUT, IMG_IDNOTE_SHUT, IMG_IDPAR_ADDENDA_SHUT]) then SelectedIndex := SelectedIndex + 1; end;
end; procedure TfrmNotes.tvNotesClick(Sender: TObject); begin (* if tvNotes.Selected = nil then exit;
if (tvNotes.Selected.ImageIndex in [IMG_TOP_LEVEL, IMG_GROUP_OPEN, IMG_GROUP_SHUT]) then begin uChanging := True; lvNotes.Selected := nil; uChanging := False; memNote.Clear; end;*)
end; procedure TfrmNotes.tvNotesDragOver(Sender, Source: TObject; X, Y: Integer; State: TDragState; var Accept: Boolean); var
AnItem: TORTreeNode;
begin
Accept := False; if not uIDNotesActive then exit; AnItem := TORTreeNode(tvNotes.GetNodeAt(X, Y)); if (AnItem = nil) or (AnItem.ImageIndex in [IMG_GROUP_OPEN, IMG_GROUP_SHUT, IMG_TOP_LEVEL]) then Exit; with tvNotes.Selected do if (ImageIndex in [IMG_SINGLE, IMG_PARENT, IMG_ID_CHILD, IMG_ID_CHILD_ADD]) then Accept := (AnItem.ImageIndex in [IMG_SINGLE, IMG_PARENT, IMG_IDNOTE_OPEN, IMG_IDNOTE_SHUT, IMG_IDPAR_ADDENDA_OPEN, IMG_IDPAR_ADDENDA_SHUT]) else if (ImageIndex in [IMG_IDNOTE_OPEN, IMG_IDNOTE_SHUT, IMG_IDPAR_ADDENDA_OPEN, IMG_IDPAR_ADDENDA_SHUT]) then Accept := (AnItem.ImageIndex in [IMG_GROUP_OPEN, IMG_GROUP_SHUT, IMG_TOP_LEVEL]) else if (ImageIndex in [IMG_ADDENDUM, IMG_GROUP_OPEN, IMG_GROUP_SHUT, IMG_TOP_LEVEL]) then Accept := False;
end; procedure TfrmNotes.tvNotesDragDrop(Sender, Source: TObject; X, Y: Integer); var
HT: THitTests; Saved: boolean; ADestNode: TORTreeNode;
begin
if not uIDNotesActive then begin CancelDrag; exit; end; if tvNotes.Selected = nil then exit; if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; end; HT := tvNotes.GetHitTestInfoAt(X, Y); ADestNode := TORTreeNode(tvNotes.GetNodeAt(X, Y)); DoAttachIDChild(TORTreeNode(tvNotes.Selected), ADestNode);
end; procedure TfrmNotes.tvNotesStartDrag(Sender: TObject; var DragObject: TDragObject); const
TX_CAP_NO_DRAG = 'Item cannot be moved'; var WhyNot: string; Saved: boolean;
begin
if (tvNotes.Selected.ImageIndex in [IMG_ADDENDUM, IMG_GROUP_OPEN, IMG_GROUP_SHUT, IMG_TOP_LEVEL]) or (not uIDNotesActive) or (lstNotes.ItemIEN = 0) then begin CancelDrag; Exit; end; if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; end; if not CanBeAttached(PDocTreeObject(tvNotes.Selected.Data)^.DocID, WhyNot) then begin InfoBox(WhyNot, TX_CAP_NO_DRAG, MB_OK); CancelDrag; end;
end; //===================== Listview events ================================= procedure TfrmNotes.lvNotesColumnClick(Sender: TObject; Column: TListColumn); var
i, ClickedColumn: Integer;
begin
if Column.Index = 0 then ClickedColumn := 5 else ClickedColumn := Column.Index; if ClickedColumn = ColumnToSort then ColumnSortForward := not ColumnSortForward else ColumnSortForward := True; for i := 0 to lvNotes.Columns.Count - 1 do lvNotes.Columns[i].ImageIndex := IMG_NONE; if ColumnSortForward then lvNotes.Columns[Column.Index].ImageIndex := IMG_ASCENDING else lvNotes.Columns[Column.Index].ImageIndex := IMG_DESCENDING; ColumnToSort := ClickedColumn; case ColumnToSort of 5: FCurrentContext.SortBy := 'R'; 1: FCurrentContext.SortBy := 'D'; 2: FCurrentContext.SortBy := 'S'; 3: FCurrentContext.SortBy := 'A'; 4: FCurrentContext.SortBy := 'L'; else FCurrentContext.SortBy := 'R'; end; FCurrentContext.ListAscending := ColumnSortForward; (Sender as TCustomListView).AlphaSort; //with lvNotes do if Selected <> nil then Scroll(0, Selected.Top - TopItem.Top);
end; procedure TfrmNotes.lvNotesCompare(Sender: TObject; Item1, Item2: TListItem; Data: Integer; var Compare: Integer); var
ix: Integer;
begin
if ColumnToSort = 0 then Compare := CompareText(Item1.Caption,Item2.Caption) else begin ix := ColumnToSort - 1; Compare := CompareText(Item1.SubItems[ix],Item2.SubItems[ix]); end; if not ColumnSortForward then Compare := -Compare;
end; procedure TfrmNotes.lvNotesSelectItem(Sender: TObject; Item: TListItem;
Selected: Boolean);
begin
if uChanging or (not Selected) then Exit; with lvNotes do begin StatusText('Retrieving selected progress note...'); lstNotes.SelectByID(Item.SubItems[5]); lstNotesClick(Self); SendMessage(memNote.Handle, WM_VSCROLL, SB_TOP, 0); end;
end; procedure TfrmNotes.lvNotesResize(Sender: TObject); begin
inherited; with lvNotes do begin if not FCurrentContext.ShowSubject then begin Columns[1].Width := 2 * (Width div 5); Columns[2].Width := 0; end else begin Columns[1].Width := Width div 5; Columns[2].Width := Columns[1].Width; end; end;
end; procedure TfrmNotes.EnableDisableIDNotes; begin
uIDNotesActive := IDNotesInstalled; mnuActDetachFromIDParent.Visible := uIDNotesActive; popNoteListDetachFromIDParent.Visible := uIDNotesActive; mnuActAddIDEntry.Visible := uIDNotesActive; popNoteListAddIDEntry.Visible := uIDNotesActive; mnuActAttachtoIDParent.Visible := uIDNotesActive; popNoteListAttachtoIDParent.Visible := uIDNotesActive; if uIDNotesActive then tvNotes.DragMode := dmAutomatic else tvNotes.DragMode := dmManual;
end; procedure TfrmNotes.ShowPCEButtons(Editing: boolean); begin
FEditingNotePCEObj := Editing; if Editing or AnytimeEncounters then begin cmdPCE.Visible := TRUE; if Editing then begin cmdPCE.Enabled := CanEditPCE(uPCEEdit); cmdNewNote.Visible := AnytimeEncounters; cmdNewNote.Enabled := FALSE; end else begin cmdPCE.Enabled := (GetAskPCE(0) <> apDisable); cmdNewNote.Visible := TRUE; cmdNewNote.Enabled := TRUE; end; if cmdNewNote.Visible then cmdPCE.Top := cmdNewNote.Top-cmdPCE.Height; end else begin cmdPCE.Enabled := FALSE; cmdPCE.Visible := FALSE; cmdNewNote.Visible := TRUE; cmdNewNote.Enabled := TRUE; end; if cmdPCE.Visible then lblSpace1.Top := cmdPCE.Top - lblSpace1.Height else lblSpace1.Top := cmdNewNote.Top - lblSpace1.Height;
end; procedure TfrmNotes.mnuIconLegendClick(Sender: TObject); begin
inherited; ShowIconLegend(ilNotes);
end; procedure TfrmNotes.mnuActAttachtoIDParentClick(Sender: TObject); var
AChildNode: TORTreeNode; AParentID: string; SavedDocID: string; Saved: boolean;
begin
inherited; if not uIDNotesActive then exit; if lstNotes.ItemIEN = 0 then exit; SavedDocID := lstNotes.ItemID; if EditingIndex <> -1 then begin SaveCurrentNote(Saved); if not Saved then Exit; LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); end; if tvNotes.Selected = nil then exit; AChildNode := TORTreeNode(tvNotes.Selected); AParentID := SelectParentNodeFromList(tvNotes); if AParentID = then exit; with tvNotes do Selected := FindPieceNode(AParentID, 1, U, Items.GetFirstNode); DoAttachIDChild(AChildNode, TORTreeNode(tvNotes.Selected));
end; procedure TfrmNotes.DoAttachIDChild(AChild, AParent: TORTreeNode); const
TX_ATTACH_CNF = 'Confirm Attachment'; TX_ATTACH_FAILURE = 'Attachment failed';
var
ErrMsg, WhyNot: string; SavedDocID: string;
begin
if (AChild = nil) or (AParent = nil) then exit; ErrMsg := ; if not CanBeAttached(PDocTreeObject(AChild.Data)^.DocID, WhyNot) then ErrMsg := ErrMsg + WhyNot + CRLF + CRLF; if not CanReceiveAttachment(PDocTreeObject(AParent.Data)^.DocID, WhyNot) then ErrMsg := ErrMsg + WhyNot; if ErrMsg <> then begin InfoBox(ErrMsg, TX_ATTACH_FAILURE, MB_OK); Exit; end else begin WhyNot := ; if (InfoBox('ATTACH: ' + AChild.Text + CRLF + CRLF + ' TO: ' + AParent.Text + CRLF + CRLF + 'Are you sure?', TX_ATTACH_CNF, MB_YESNO or MB_DEFBUTTON2 or MB_ICONQUESTION) <> IDYES) then Exit; SavedDocID := PDocTreeObject(AParent.Data)^.DocID; end; if AChild.ImageIndex in [IMG_ID_CHILD, IMG_ID_CHILD_ADD] then begin if DetachEntryFromParent(PDocTreeObject(AChild.Data)^.DocID, WhyNot) then begin if AttachEntryToParent(PDocTreeObject(AChild.Data)^.DocID, PDocTreeObject(AParent.Data)^.DocID, WhyNot) then begin LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); if tvNotes.Selected <> nil then tvNotes.Selected.Expand(False); end else InfoBox(WhyNot, TX_ATTACH_FAILURE, MB_OK); end else begin WhyNot := StringReplace(WhyNot, 'ATTACH', 'DETACH', [rfIgnoreCase]); WhyNot := StringReplace(WhyNot, 'to an ID', 'from an ID', [rfIgnoreCase]); InfoBox(WhyNot, TX_DETACH_FAILURE, MB_OK); Exit; end; end else begin if AttachEntryToParent(PDocTreeObject(AChild.Data)^.DocID, PDocTreeObject(AParent.Data)^.DocID, WhyNot) then begin LoadNotes; with tvNotes do Selected := FindPieceNode(SavedDocID, U, Items.GetFirstNode); if tvNotes.Selected <> nil then tvNotes.Selected.Expand(False); end else InfoBox(WhyNot, TX_ATTACH_FAILURE, MB_OK); end;
end; function TfrmNotes.SetNoteTreeLabel(AContext: TTIUContext): string; var
x: string; function SetDateRangeText(AContext: TTIUContext): string; var x1: string; begin with AContext do if BeginDate <> then begin x1 := ' from ' + UpperCase(BeginDate); if EndDate <> then x1 := x1 + ' to ' + UpperCase(EndDate) else x1 := x1 + ' to TODAY'; end; Result := x1; end;
begin
with AContext do begin if MaxDocs > 0 then x := 'Last ' + IntToStr(MaxDocs) + ' ' else x := 'All '; case StrToIntDef(Status, 0) of NC_ALL : x := x + 'Signed Notes'; NC_UNSIGNED : begin x := x + 'Unsigned Notes for '; if Author > 0 then x := x + ExternalName(Author, 200) else x := x + User.Name; x := x + SetDateRangeText(AContext); end; NC_UNCOSIGNED : begin x := x + 'Uncosigned Notes for '; if Author > 0 then x := x + ExternalName(Author, 200) else x := x + User.Name; x := x + SetDateRangeText(AContext); end; NC_BY_AUTHOR : x := x + 'Signed Notes for ' + ExternalName(Author, 200) + SetDateRangeText(AContext); NC_BY_DATE : x := x + 'Signed Notes ' + SetDateRangeText(AContext); else x := 'Custom List'; end; end; Result := x;
end; initialization
uPCEEdit := TPCEData.Create; uPCEShow := TPCEData.Create;
finalization
uPCEEdit.Free; uPCEShow.Free;
end.
June 11, 2004