unit SWTXTDSP;
interface
uses
istreams, SWModule, SWVSKey, Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
StdCtrls, ComCtrls;
var
defRTFHeader :AnsiString;
defRTFTrailer :AnsiString;
defRTFChapterMarkPre :AnsiString;
defRTFChapterMarkPost :AnsiString;
defRTFVerseMarkPre :AnsiString;
defRTFVerseMarkPost :AnsiString;
defRTFVersePre :AnsiString;
defRTFVersePost :AnsiString;
type
charrange = record
min : longint;
max : longint;
end;
TSWTextDisp = class(TRichEdit)
private
FSWModule: TSWModule;
FCurVerseMrk : boolean;
FCurVersePos : boolean;
FRTFHeader: AnsiString;
FRTFTrailer: AnsiString;
FRTFChapterMarkPre :AnsiString;
FRTFChapterMarkPost :AnsiString;
FRTFVerseMarkPre :AnsiString;
FRTFVerseMarkPost :AnsiString;
FRTFVersePre :AnsiString;
FRTFVersePost :AnsiString;
FMarkCurrentVerse :boolean;
FCharRange : charrange;
FAutoPosition : boolean;
function GetMySelStart: integer;
procedure SetMySelStart(iselstart : integer);
protected
RTFStream: TMemoryStream;
procedure SetSWModule(imodule: TSWModule); virtual;
function GetSWModule: TSWModule; virtual;
procedure Loaded; override;
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;
procedure Display; virtual;
published
property CurVersePos : boolean read FCurVersePos write FCurVersePos default True;
property CurVerseMrk : boolean read FCurVerseMrk write FCurVerseMrk default True;
property SWModule: TSWModule read GetSWModule write SetSWModule;
property RTFHeader: AnsiString read FRTFHeader write FRTFHeader;
property RTFChapterMarkPre: AnsiString read FRTFChapterMarkPre write FRTFChapterMarkPre;
property RTFChapterMarkPost: AnsiString read FRTFChapterMarkPost write FRTFChapterMarkPost;
property RTFVerseMarkPre: AnsiString read FRTFVerseMarkPre write FRTFVerseMarkPre;
property RTFVerseMarkPost: AnsiString read FRTFVerseMarkPost write FRTFVerseMarkPost;
property RTFVersePre: AnsiString read FRTFVersePre write FRTFVersePre;
property RTFVersePost: AnsiString read FRTFVersePost write FRTFVersePost;
property RTFTrailer: AnsiString read FRTFTrailer write FRTFTrailer;
property MarkCurrentVerse: boolean read FMarkCurrentVerse write FMarkCurrentVerse default true;
Property AutoPosition: boolean read FAutoPosition write FAutoPosition default true;
// property SelStart read GetMySelStart write SetMySelStart;
end;
procedure Register;
implementation
constructor TSWTextDisp.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCurVersePos := True;
FCurVerseMrk := True;
RTFHeader := defRTFHeader;
RTFTrailer := defRTFTrailer;
RTFChapterMarkPre := defRTFChapterMarkPre;
RTFChapterMarkPost := defRTFChapterMarkPost;
RTFVerseMarkPre := defRTFVerseMarkPre;
RTFVerseMarkPost := defRTFVerseMarkPost;
RTFVersePre := defRTFVersePre;
RTFVersePost := defRTFVersePost;
// RTFStream := TMemoryStream.Create;
MarkCurrentVerse := true;
AutoPosition := true;
end;
destructor TSWTextDisp.Destroy;
begin
if (RTFStream <> nil) then
RTFStream.Free;
inherited Destroy;
end;
procedure TSWTextDisp.Loaded;
begin
inherited Loaded;
if (RTFHeader = '') then
RTFHeader := defRTFHeader;
if (RTFTrailer = '') then
RTFTrailer := defRTFTrailer;
if (RTFChapterMarkPre = '') then
RTFChapterMarkPre := defRTFChapterMarkPre;
if (RTFChapterMarkPost = '') then
RTFChapterMarkPost := defRTFChapterMarkPost;
if (RTFVerseMarkPre = '') then
RTFVerseMarkPre := defRTFVerseMarkPre;
if (RTFVerseMarkPost = '') then
RTFVerseMarkPost := defRTFVerseMarkPost;
if (RTFVersePre = '') then
RTFVersePre := defRTFVersePre;
if (RTFVersePost = '') then
RTFVersePost := defRTFVersePost;
if not (csDesigning in ComponentState) then
begin
if (RTFStream = nil) then
RTFStream := TMemoryStream.Create;
end;
end;
//#define EM_EXGETSEL (WM_USER + 52)
//#define EM_EXSETSEL (WM_USER + 55)
function TSWTextDisp.GetMySelStart: integer;
begin
SendMessage(Handle, (WM_USER + 52), 0, longint(@Fcharrange));
GetMySelStart := Fcharrange.min;
end;
procedure TSWTextDisp.SetMySelStart(iselstart : integer);
begin
Fcharrange.min := iselstart;
Fcharrange.max := iselstart;
SendMessage(Handle, (WM_USER + 55), 0, longint(@Fcharrange));
end;
procedure TSWTextDisp.Display;
var
book, chap, verse, versepos, currentpos: integer;
newtext, tmptext: AnsiString;
buf: PChar;
begin
chap := TSWVerseKey(SWModule.Key).Chapter;
book := TSWVerseKey(SWModule.Key).Book;
verse:= TSWVerseKey(SWModule.Key).Verse;
TSWVerseKey(SWModule.Key).Verse := 1;
newtext := RTFHeader;
newtext := newtext + RTFChapterMarkPre + IntToStr(TSWVerseKey(SWModule.Key).Chapter) + RTFChapterMarkPost;
SWModule.Error; // clear error;
currentpos := 0;
while ((TSWVerseKey(SWModule.Key).Book = book) and (TSWVerseKey(SWModule.Key).Chapter = chap) and (SWModule.Error = 0)) do
begin
if (TSWVerseKey(SWModule.Key).Verse = verse) then
begin
if (MarkCurrentVerse = true) then {This does not work for shading background of current verse, but should }
newtext := newtext + '\pard \nowidctlpar \shading2000 \cf2' // \cf2 = second color in color table
else newtext := newtext + '\pard \nowidctlpar \cf0';
end else newtext := newtext + '\pard \nowidctlpar \cf0';
newtext := newtext + RTFVerseMarkPre + IntToStr(TSWVerseKey(SWModule.Key).Verse) + RTFVerseMarkPost;
newtext := newtext + RTFVersePre + SWModule.Text + RTFVersePost;
if ((TSWVerseKey(SWModule.Key).Verse = verse) and (AutoPosition = true)) then
begin
tmptext := newtext + RTFTrailer;
RTFStream.Clear;
RTFStream.WriteBuffer(Pointer(tmptext)^, Length(tmptext));
RTFStream.Position := 0;
FMarkCurrentVerse := true;
Lines.LoadFromStream(RTFStream);
PlainText := true;
versepos := GetTextLen; //RTFStream.Position;
PlainText := false;
end;
SWModule.Inc;
end;
newtext := newtext + RTFTrailer;
TSWVerseKey(SWModule.Key).Verse := 1; { When setting chapter: if (verse <> new chapter range) don't autonormalize. (we could've just turned the autonormalize option off then back on, but this is cooler) }
TSWVerseKey(SWModule.Key).Book := book;
TSWVerseKey(SWModule.Key).Chapter := chap;
TSWVerseKey(SWModule.Key).Verse := verse;
RTFStream.Clear;
RTFStream.WriteBuffer(Pointer(newtext)^, Length(newtext));
RTFStream.Position := 0;
Lines.LoadFromStream(RTFStream);
{ Position control text at current verse }
if (AutoPosition = true) then
begin
SelStart := versepos;
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
end;
end;
procedure TSWTextDisp.SetSWModule(imodule: TSWModule);
begin
FSWModule := imodule;
end;
function TSWTextDisp.GetSWModule: TSWModule;
begin
GetSWModule := FSWModule;
end;
procedure Register;
begin
RegisterComponents('SWORD', [TSWTextDisp]);
end;
initialization
defRTFHeader := '{\rtf1\ansi{\fonttbl{\f4\froman\fcharset0\fprq2 Times New Roman;}}{\colortbl;\red0\green0\blue255;\red0\green200\blue50;}';
defRTFTrailer := '{\fs24 \par }}';
defRTFChapterMarkPre := '\pard \qc\nowidctlpar{\fs30\b Chapter ';
defRTFChapterMarkPost := '\par\fs10\par}';
defRTFVerseMarkPre := '{\fs20\cf1\super ';
defRTFVerseMarkPost := '}';
defRTFVersePre := '{\fs24';
defRTFVersePost := ' }';
finalization
end.