//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "RxRichEditX.h"
#include <clipbrd.hpp>
#include <swdisprtf.h>
#include <swdisprtfchap.h>
#include "mainfrm.h"
#include <localemgr.h>
#include <unicodertf.h>
char TRxRichEditX::platformID = 0;
TRxRichEditX::TRxRichEditX(TWinControl *parent) : TRxRichEdit(parent)
{
OSVERSIONINFO osvi;
memset(&osvi, 0, sizeof(OSVERSIONINFO));
osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx(&osvi);
platformID = osvi.dwPlatformId;
type = "Default";
}
void TRxRichEditX::RenderModule(SWModule* module, RTF_FORMAT format)
{
format_ops = format;
TMemoryStream* RTFStream = new TMemoryStream();
AnsiString rtfText = "{\\rtf1\\ansi{\\fonttbl{\\f0\\fdecor\\fprq2 ";
rtfText += format_ops.fontFace;
rtfText += ";}}{\\colortbl;\\red0\\green0\\blue0;}";
rtfText += "{\\fs8\\cf1\\par\\pard} ";
//if(!strcmp(module->Type(), "Biblical Texts"))
rtfText += GetFormattedBible(module);
/*
else if(!strcmp(module->Type(), "Commentaries"))
rtfText += GetFormattedComm(module);
else if(!strcmp(module->Type(), "Lexicons / Dictionaries"))
rtfText += GetFormattedLD(module);
else
rtfText += GetFormattedBook(module);
*/
rtfText += "{ \\par }}";
RTFStream->Clear();
RTFStream->WriteBuffer(rtfText.c_str(), rtfText.Length());
RTFStream->Position = 0;
Lines->LoadFromStream(RTFStream);
delete RTFStream;
// clear HTML link tags
while (true) {
int start, len, foundAt, endAt;
start = (SelLength) ? SelStart + SelLength : 0;
len = Text.Length() - start;
foundAt = this->SearchText("<a href=\"\">", start, len, TRichSearchTypes());
if (foundAt == -1)
break;
SelStart = foundAt;
SelLength = 11;
this->SelText = "";
endAt = this->SearchText("</a>", foundAt, len, TRichSearchTypes());
if (foundAt == -1)
break;
SelStart = endAt;
SelLength = 4;
this->SelText = "";
SelStart = foundAt;
SelLength = endAt - foundAt;
//this->SelAttributes->Link = true;
}
SelLength = 0;
}
AnsiString TRxRichEditX::GetFormattedBible(SWModule* module)
{
AnsiString rtfText = "";
VerseKey key;
int lastChap, lastBook;
AnsiString bookName;
key = (VerseKey)module->Key();
lastChap = key.Chapter();
lastBook = key.Book();
bookName = (AnsiString)key.getText();
bookName = bookName.SubString(0,bookName.Pos(lastChap) - 2);
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, bookName);
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, lastChap);
for ((*module) = TOP; !module->Error(); (*module)++){
key = (VerseKey)module->Key();
if(key.Book() != lastBook){
rtfText += "\\par\\par";
bookName = (AnsiString)key.getText();
bookName = bookName.SubString(0,bookName.Pos(key.Chapter()) - 2);
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, bookName);
lastBook = key.Book();
lastChap = -1; // Reset the last Chapter since we could jump from Jude 1 to Revelation 1
}
if(key.Chapter() != lastChap){
rtfText += "\\par";
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, key.Chapter());
lastChap = key.Chapter();
}
rtfText += PrintEntry(module, key.Verse());
}
return rtfText;
}
/*
AnsiString TRxRichEditX::GetFormattedComm(SWModule* module)
{
AnsiString rtfText = "";
VerseKey key;
int lastChap;
AnsiString lastBook;
key = (VerseKey)module->Key();
lastChap = key.Chapter();
lastBook = (AnsiString)key.Book();
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, lastBook);
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, lastChap);
for ((*module) = TOP; !module->Error(); (*module)++){
key = (VerseKey)module->Key();
if((AnsiString)key.Book() == lastBook){
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, lastBook);
lastBook = key.Book();
}
if(key.Chapter() != lastChap){
rtfText += "\\par\\par";
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, key.Chapter());
lastChap = key.Chapter();
}
rtfText += PrintEntry(module, key.Verse());
}
return rtfText;
}
AnsiString TRxRichEditX::GetFormattedLD(SWModule* module)
{
AnsiString rtfText = "";
VerseKey key;
int lastChap;
AnsiString lastBook;
key = (VerseKey)module->Key();
lastChap = key.Chapter();
lastBook = (AnsiString)key.Book();
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, lastBook);
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, lastChap);
for ((*module) = TOP; !module->Error(); (*module)++){
key = (VerseKey)module->Key();
if((AnsiString)key.Book() == lastBook){
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, lastBook);
lastBook = key.Book();
}
if(key.Chapter() != lastChap){
rtfText += "\\par\\par";
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, key.Chapter());
lastChap = key.Chapter();
}
rtfText += PrintEntry(module, key.Verse());
}
return rtfText;
}
AnsiString TRxRichEditX::GetFormattedBook(SWModule* module)
{
AnsiString rtfText = "";
VerseKey key;
int lastChap;
AnsiString lastBook;
key = (VerseKey)module->Key();
lastChap = key.Chapter();
lastBook = (AnsiString)key.Book();
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, lastBook);
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, lastChap);
for ((*module) = TOP; !module->Error(); (*module)++){
key = (VerseKey)module->Key();
if((AnsiString)key.Book() == lastBook){
rtfText += "\\par\\par";
if(format_ops.prBookHeadings)
rtfText += BookHeading(module, lastBook);
lastBook = key.Book();
}
if(key.Chapter() != lastChap){
rtfText += "\\par\\par";
if(format_ops.prChHeadings)
rtfText += ChapterHeading(module, key.Chapter());
lastChap = key.Chapter();
}
rtfText += PrintEntry(module, key.Verse());
}
return rtfText;
}
*/
AnsiString TRxRichEditX::PrintEntry(SWModule* module, int nVerse)
{
AnsiString rtfText = "";
if (module->Direction() == DIRECTION_RTL) {
rtfText += "\\qr ";
}else
rtfText += "\\ql ";
if (module->Direction() == DIRECTION_RTL && (platformID == WINNT && (!strnicmp(module->Lang(), "he", 2) || !strnicmp(module->Lang(), "ar", 2)))) {
rtfText = rtfText + "\\rtlpar ";
}
if(!format_ops.paragraph)
rtfText += "\\par";
if(format_ops.prPreFix)
rtfText += PrintFix(module) + (AnsiString)" ";
if(format_ops.prVerseNum){
rtfText += (AnsiString)"{\\fs" + format_ops.vsNumFontSize;
if(format_ops.superVSNum)
rtfText += "\\super ";
else rtfText += " ";
rtfText += IntToStr(nVerse);
rtfText += " }";
}
rtfText += (AnsiString)"{\\fs" + format_ops.bodyFontSize + (AnsiString)" ";
rtfText += module->RenderText();
rtfText += " }";
if(format_ops.prPostFix)
rtfText += (AnsiString)" " + PrintFix(module);
return rtfText;
}
AnsiString TRxRichEditX::ChapterHeading(SWModule* module, int nChapter)
{
AnsiString rtfText = "";
rtfText += (AnsiString)" \\qc{\\f1\\cf7\\fs" + format_ops.bkFontHeadSize + (AnsiString)"\\b ";
rtfText += _tr("Chapter");
rtfText += " ";
rtfText += IntToStr(nChapter);
rtfText += "\\par\\par}";
return rtfText;
}
AnsiString TRxRichEditX::BookHeading(SWModule* module, AnsiString name)
{
AnsiString rtfText = "";
rtfText += (AnsiString)" \\qc{\\f1\\cf7\\fs" + format_ops.bkFontHeadSize + (AnsiString)"\\b\\ul ";
rtfText += name;
rtfText += "\\par\\par}";
return rtfText;
}
AnsiString TRxRichEditX::PrintFix(SWModule* module)
{
AnsiString rtfText = "";
rtfText += (AnsiString)"{\\fs" + format_ops.vsNumFontSize;
rtfText += (AnsiString)"(" + (AnsiString)module->KeyText() + (AnsiString)" " + (AnsiString)module->Name() + (AnsiString)")}";
return rtfText;
}
int TRxRichEditX::paintTo(HDC hdc, TRect *size, int margin) {
TFormatRange Range;
int LastChar, MaxLen, LogX, LogY, OldMap;
TRect SaveRect;
TGetTextLengthEx TextLenEx;
bool calcBestSize = (size) ? IsRectEmpty(size): true;
TRect trySizeRect[] = {
TRect(0, 0, 200, 50),
TRect(0, 0, 200, 100),
TRect(0, 0, 250, 100),
TRect(0, 0, 300, 50),
TRect(0, 0, 300, 100),
TRect(0, 0, 350, 100),
TRect(0, 0, 400, 50),
TRect(0, 0, 400, 100),
TRect(0, 0, 400, 150),
TRect(0, 0, 400, 200),
TRect(0, 0, 500, 100),
TRect(0, 0, 500, 150),
TRect(0, 0, 500, 200),
TRect(0, 0, 500, 250),
TRect(0, 0, 550, 300),
TRect(0, 0, 550, 350),
TRect(0, 0, 0, 0)
};
int trySize = 0;
TRect *dispSize = size;
LogX = GetDeviceCaps(hdc, LOGPIXELSX);
LogY = GetDeviceCaps(hdc, LOGPIXELSY);
do {
if (calcBestSize) {
dispSize = &trySizeRect[trySize++];
if (IsRectEmpty(dispSize)) {
dispSize = &trySizeRect[trySize-2];
break;
}
}
memset(&Range, 0, sizeof(TFormatRange));
// with Printer, Range do begin
Range.hdc = hdc;
Range.hdcTarget = Range.hdc;
// if (IsRectEmpty(&PageRect)) {
// Range.rc.right = dispSize->Right * 1440 / LogX;
// Range.rc.bottom = dispSize->Bottom * 1440 / LogY;
// }
// else {
Range.rc.left = (dispSize->Left + margin) * 1440 / LogX;
Range.rc.top = (dispSize->Top + margin) * 1440 / LogY;
Range.rc.right = dispSize->Right * 1440 / LogX;
Range.rc.bottom = (dispSize->Bottom)* 1440 / LogY;
// }
Range.rcPage = Range.rc;
SaveRect = Range.rc;
// Range.rcPage.top = Range.rcPage.top + (5 * 1440) / LogY;
// Range.rcPage.bottom = Range.rcPage.bottom + (5 * 1440) / LogY;
LastChar = 0;
if (RichEditVersion >= 2) {
// with TextLenEx do begin
TextLenEx.flags = GTL_DEFAULT;
TextLenEx.codepage = CP_ACP;
MaxLen = Perform(EM_GETTEXTLENGTHEX, (WPARAM)&TextLenEx, 0);
}
else MaxLen = GetTextLen();
Range.chrg.cpMax = -1;
// { ensure printer DC is in text map mode }
OldMap = SetMapMode(hdc, MM_TEXT);
SendMessage(Handle, EM_FORMATRANGE, 0, 0); // { flush buffer }
try {
Range.rc = SaveRect;
Range.chrg.cpMin = LastChar;
LastChar = SendMessage(Handle, EM_FORMATRANGE, 1, Longint(&Range));
// if ((LastChar < MaxLen) && (LastChar != -1)) ;//NewPage();
// } while ((LastChar >= MaxLen) || (LastChar = -1));
}
__finally {
SendMessage(Handle, EM_FORMATRANGE, 0, 0);// { flush buffer }
SetMapMode(hdc, OldMap); // { restore previous map mode }
}
LastChar = (LastChar < 0) ? 0: MaxLen - LastChar;
LastChar = (LastChar < 0) ? 0: LastChar;
} while (LastChar && calcBestSize);
if (calcBestSize && size)
*size = *dispSize;
return LastChar;
}
void TRxRichEditX::fillWithRTFString(SWModule *module, const char *text, const char *type) {
TMemoryStream *RTFStream = new TMemoryStream();
System::AnsiString newtext, tmptext;
this->module = module;
this->type = type;
recalcAppearance();
newtext = RTFHeader;
newtext += RTFHeadMargin;
newtext += "\\pard \\nowidctlpar \\cf7\\f0 ";
newtext += "{";
tmptext = "";
for (const char *loop = text; *loop; loop++) {
if (*loop == '\n') {
tmptext += "\\par ";
}
else tmptext += *loop;
}
newtext += RTFVersePre + tmptext + RTFVersePost;
newtext += "}";
newtext += RTFTrailer;
RTFStream->Clear();
RTFStream->WriteBuffer(newtext.c_str(), newtext.Length());
RTFStream->Position = 0;
Lines->LoadFromStream(RTFStream);
Repaint();
delete RTFStream;
}
void TRxRichEditX::fillWithVerses(SWModule *module, ListKey *verses, bool heading, bool verseNum, const char *type, bool stripNewlines) {
string fontname;
TMemoryStream *RTFStream = new TMemoryStream();
System::AnsiString newtext, tmptext;
static UnicodeRTF filter;
char buf[255];
this->module = module;
this->type = type;
recalcAppearance();
newtext = RTFHeader;
newtext += RTFHeadMargin;
// newtext += "\\pard\\nowidctlpar\\cf7\\f0 ";
if (module->Direction() == DIRECTION_RTL) {
newtext += "\\qr ";
}
if (module->Direction() == DIRECTION_RTL && (platformID == WINNT && (!strnicmp(module->Lang(), "he", 2) || !strnicmp(module->Lang(), "ar", 2)))) {
newtext += "\\rtlpar ";
}
verses->Persist(1);
(*verses) = TOP;
SWKey *saveKey = (SWKey *)(*module);
SWKey origKeyValue = *saveKey;
if (!saveKey->Persist())
saveKey = 0;
module->setKey(verses);
SWKey *lastKey = 0;
bool first = true;
SWKey *testKey = module->CreateKey();
while (verses->Count() && !module->Error() && newtext.Length() < 40000 ) {
if (heading) {
if (SWDYNAMIC_CAST(VerseKey, testKey)) {
if (lastKey != verses->GetElement()) {
if (!first)
newtext += "{\\par\\par}";
newtext += RTFHeadingPre;
newtext += verses->GetElement()->getRangeText();
newtext += ":";
newtext += RTFHeadingPost;
newtext += "{\\par}";
}
}
else {
char *buf2 = 0;
stdstr(&buf2, (const char *)*verses);
toupperstr_utf8(buf2);
module->getRawEntry();
strcpy(buf, module->KeyText());
toupperstr_utf8(buf);
int i;
char *start1 = buf;
char *start2 = buf2;
int len = strlen(buf);
for (i = 0; i < len; i++) {
if (*start1 == '0') {
start1++;
}
if (*start2 == '0') {
start2++;
}
if ((start1[0] != '0') && (start2[0] != '0'))
// if ((buf[i] == buf2[i]) || (buf[i] != '0'))
break;
}
for (i = 0; i < strlen(start1) && (i < strlen(start2)); i++) {
if ((start1[i] != start2[i]) &&
(SW_toupper(start1[i]) != SW_toupper(start2[i])))
break;
}
if (!i || i < (strlen(start1)/2)) {
delete [] buf2;
verses->Remove();
continue;
}
delete [] buf2;
if (!first)
newtext += "{\\par\\par}";
newtext += RTFHeadingPre;
strcpy(buf, module->KeyText());
// VerseKey locales are not yet UTF8, so don't try to convert them.
if (!SWDYNAMIC_CAST(VerseKey, testKey))
filter.ProcessText(buf, 253, *module, module);
newtext = newtext + RTFHeadingPre + buf + RTFHeadingPost + ":\\par ";
newtext += RTFHeadingPost;
newtext += "{\\par}";
}
// newtext += RTFHeadingPost;
}
else { // hack to make searchlist entries fit in box better
newtext += "";
}
lastKey = verses->GetElement();
first = false;
newtext = newtext + "{";
tmptext = "";
for (const char *loop = (const char *)*module; *loop; loop++) {
if (stripNewlines) {
if (!strnicmp(loop, "\\par", 4)) {
loop += (loop[4] == 'd') ? 4 : 3;
continue;
}
}
if (*loop == '\n') {
if (!stripNewlines)
tmptext += "{\\par}";
}
else tmptext += *loop;
}
if (tmptext.Length() > 3) { // make sure we have an entry
if (module->Direction() == DIRECTION_RTL && (SWDispRTFChap::platformID == WIN9X || (module->Lang() && strnicmp(module->Lang(), "he", 2) && strnicmp(module->Lang(), "ar", 2)))) {
newtext = newtext + RTFVersePre + tmptext + RTFVersePost;
if (verseNum)
newtext = newtext + RTFVerseMarkPre + IntToStr(VerseKey(module->KeyText()).Verse()) + RTFVerseMarkPost;
newtext = newtext + "{\\par}";
}
else {
if (verseNum)
newtext = newtext + RTFVerseMarkPre + IntToStr(VerseKey(module->KeyText()).Verse()) + RTFVerseMarkPost;
newtext = newtext + RTFVersePre + tmptext + RTFVersePost;
}
}
newtext = newtext + "}";
(*module)++;
}
delete testKey;
if (saveKey)
module->setKey(saveKey);
else module->setKey(origKeyValue); //remove our persist key
newtext += RTFTrailer;
RTFStream->Clear();
RTFStream->WriteBuffer(newtext.c_str(), newtext.Length());
RTFStream->Position = 0;
Lines->LoadFromStream(RTFStream);
// make links
while (true) {
int start, len, foundAt, endAt;
start = (SelLength) ? SelStart + SelLength : 0;
len = Text.Length() - start;
foundAt = this->SearchText("<a href=\"\">", start, len, TRichSearchTypes());
if (foundAt == -1)
break;
SelStart = foundAt;
SelLength = 11;
this->SelText = "";
endAt = this->SearchText("</a>", foundAt, len, TRichSearchTypes());
if (foundAt == -1)
break;
SelStart = endAt;
SelLength = 4;
this->SelText = "";
SelStart = foundAt;
SelLength = endAt - foundAt;
this->SelAttributes->Link = true;
}
if (Visible) {
TComponent *owner = this->Owner;
TForm *parentForm = dynamic_cast<TForm *>(owner);
TWinControl *focus = 0;
if (parentForm)
focus = parentForm->ActiveControl;
this->SetFocus();
SelStart = 0;
SelLength = 0;
SendMessage(Handle, EM_SCROLLCARET, 0, 0);
if (focus)
focus->SetFocus();
}
Repaint();
delete RTFStream;
}
void TRxRichEditX::getDisplayPrefs(DISP_ATTRIBS *attribs, SWModule *module /*, const char *type*/) {
string keyBackColor = (string)getType().c_str() + "BackColor";
string backColor = Form1->optionsconf->Sections["Appearance"][keyBackColor];
// This portion of the code sets the default values (If needed) of the background
// for either typical windows or for popup windows
if (backColor == "") {
if (getType() == "Popup") {
attribs->backColor = 14680063;
}
else attribs->backColor = clWindow;
}
else attribs->backColor = StrToInt((AnsiString)backColor.c_str());
string keyFontColor = (string)getType().c_str() + "FontColor";
string fontColor = Form1->optionsconf->Sections["Appearance"][keyFontColor];
// This portion of the code sets the default values (If needed) of the background
// for either typical windows or for popup windows
if (backColor == "") {
attribs->fontColor = clBlack;
}
else attribs->fontColor = StrToInt((AnsiString)fontColor.c_str());
// If the module uses it's own font load that else we will try the config file else we will use the default
ConfigEntMap::const_iterator eit = module->getConfig().find("Font");
if (eit != module->getConfig().end())
attribs->fontName = (*eit).second.c_str();
else {
string keyFontName = (string)getType().c_str() + "FontName";
attribs->fontName = (AnsiString)Form1->optionsconf->Sections["Appearance"][keyFontName].c_str();
}
// If we still have no name we will set it to a default value
if (attribs->fontName == "")
attribs->fontName = "Times New Roman";
// If the module uses it's own font size load that else we will try the config file else we will use the default
AnsiString fontSize;
eit = module->getConfig().find("FontSize");
if (eit != module->getConfig().end())
fontSize = (*eit).second.c_str();
else {
string keyFontSize = (string)getType().c_str() + "FontSize";
fontSize = (AnsiString)Form1->optionsconf->Sections["Appearance"][keyFontSize].c_str();
}
// If we still have no size we will set it to a default value
if (fontSize == "")
attribs->fontSize = 10;
else attribs->fontSize = StrToInt(fontSize);
string entryColor = Form1->optionsconf->Sections["Appearance"]["VSNumberColor"];
if (entryColor == "")
attribs->entryKeyColor = clBlue;
else attribs->entryKeyColor = StrToInt((AnsiString)entryColor.c_str());
string currentVSColor = Form1->optionsconf->Sections["Appearance"]["CurrentVSColor"];
if (currentVSColor == "")
attribs->currentVSColor = clBlue;
else attribs->currentVSColor = StrToInt((AnsiString)currentVSColor.c_str());
string morphColor = Form1->optionsconf->Sections["Appearance"]["MorphColor"];
if (morphColor == "")
attribs->morphColor = clBlue;
else attribs->morphColor = StrToInt((AnsiString)morphColor.c_str());
string strongColor = Form1->optionsconf->Sections["Appearance"]["StrongsColor"];
if (strongColor == "")
attribs->strongsColor = clBlue;
else attribs->strongsColor = StrToInt((AnsiString)strongColor.c_str());
string fieldColor = Form1->optionsconf->Sections["Appearance"]["FieldColor"];
if (fieldColor == "")
attribs->lookupFieldColor = clBlue;
else attribs->lookupFieldColor = StrToInt((AnsiString)fieldColor.c_str());
string autoVSColor = Form1->optionsconf->Sections["Appearance"]["AutoVSColor"];
if (autoVSColor == "")
attribs->markCurrentVerse = true;
else attribs->markCurrentVerse = (atoi(autoVSColor.c_str())) ? true : false;
}
void TRxRichEditX::recalcAppearance() {
static UnicodeRTF filter;
char buf[4096];
getDisplayPrefs(&dispAttribs, module /*, type.c_str()*/);
Color = dispAttribs.backColor;
Font->Name = dispAttribs.fontName;
Font->Size = dispAttribs.fontSize;
RTFHeadMargin = "{\\cf1\\pard}";
RTFVerseMarkPost = "}";
RTFVersePost = " }";
buildRTFHeader();
// build headers with proportional font sizes to single user selected
// font size.
double fontBase = dispAttribs.fontSize;
fontBase /= 4.0;
sprintf(buf,
"{\\fs%d \\par }}",
(int)(fontBase * 8));
RTFTrailer = buf;
char chapBuf[1024];
strcpy(chapBuf, _tr("Chapter"));
filter.ProcessText(chapBuf, 1022, *module, module);
sprintf(buf,
"\\pard \\qc\\nowidctlpar{\\f1\\cf7\\fs%d\\b %s ",
(int)(fontBase * 10), chapBuf);
RTFChapterMarkPre = buf;
sprintf(buf,
"\\par\\fs%d\\par}",
(int)(fontBase * 4));
RTFChapterMarkPost = buf;
sprintf(buf,
"{\\fs%d\\cf1\\b ",
(int)(fontBase * 7));
RTFHeadingPre = buf;
RTFHeadingPost = "}";
sprintf(buf,
"{\\fs%d\\cf1\\super ",
(int)(fontBase * 7));
RTFVerseMarkPre = buf;
sprintf(buf,
"{\\fs%d\\cf7 ",
(int)(fontBase * 8));
RTFVersePre = buf;
}
void TRxRichEditX::TColorToRGB(const TColor& color, int& red, int& green, int& blue) {
red = (color & 0xFF);
green = ((color >> 8) & 0xFF);
blue =((color >> 16) & 0xFF);
}
void TRxRichEditX::buildRTFHeader() {
char buf1[1024], buf2[1024];
SectionMap::iterator sit;
string value;
ConfigEntMap::iterator entry;
string tmpval;
int CurrVSRed, CurrVSGreen, CurrVSBlue, BodyRed, BodyGreen, BodyBlue,
VSNumRed, VSNumGreen, VSNumBlue, MorphRed, MorphGreen, MorphBlue,
StrongsRed, StrongsGreen, StrongsBlue;
TColor CurrVSColor, VSNumColor, BodyColor, MorphColor, StrongsColor;
sprintf(buf1, "{\\rtf1\\ansi");
if (dispAttribs.fontName.Length()) {
// Font Table
// 0: Text Body
sprintf(buf2, "{\\fonttbl{\\f0\\fdecor\\fprq2 %s;}" , dispAttribs.fontName.c_str());
strcat(buf1, buf2);
// 1: Chapter Heading
sprintf(buf2, "{\\f1\\froman\\fcharset0\\fprq2 %s;}", dispAttribs.fontName.c_str());
strcat(buf1, buf2);
// 2: Unknown
sprintf(buf2, "{\\f2\\froman\\fcharset0\\fprq2 %s;}", dispAttribs.fontName.c_str());
strcat(buf1, buf2);
// 3: Unknown
sprintf(buf2, "{\\f3\\froman\\fcharset0\\fprq2 %s;}", dispAttribs.fontName.c_str());
strcat(buf1, buf2);
// 4: Unknown
sprintf(buf2, "{\\f4\\froman\\fcharset0\\fprq2 %s;}", dispAttribs.fontName.c_str());
strcat(buf1, buf2);
// 7, 8: Unknown
strcat(buf1, "{\\f7\\froman\\fcharset2\\fprq2 Symbol;}{\\f8\\froman\\fcharset2\\fprq2 Symbol;}}");
}
else {
sprintf(buf2, "{\\fonttbl{\\f0\\fdecor\\fprq2 Times New Roman;}{\\f1\\froman\\fcharset0\\fprq2 Times New Roman;}{\\f7\\froman\\fcharset2\\fprq2 Symbol;}{\\f8\\froman\\fcharset2\\fprq2 Symbol;}}");
strcat(buf1, buf2);
}
TColorToRGB(dispAttribs.currentVSColor, CurrVSRed, CurrVSGreen, CurrVSBlue);
TColorToRGB(dispAttribs.entryKeyColor, VSNumRed, VSNumGreen, VSNumBlue);
TColorToRGB(dispAttribs.strongsColor, StrongsRed, StrongsGreen, StrongsBlue);
TColorToRGB(dispAttribs.morphColor, MorphRed, MorphGreen, MorphBlue);
TColorToRGB(dispAttribs.fontColor, BodyRed, BodyGreen, BodyBlue);
// Color Table:
// 1: Verse Number/ Verse info
sprintf(buf2, "{\\colortbl;\\red%d\\green%d\\blue%d;" , VSNumRed, VSNumGreen, VSNumBlue);
strcat(buf1, buf2);
// 2: Current Verse Color
sprintf(buf2, "\\red%d\\green%d\\blue%d;", CurrVSRed, CurrVSGreen, CurrVSBlue);
strcat(buf1, buf2);
// 3: Strong's Def
sprintf(buf2, "\\red%d\\green%d\\blue%d;", StrongsRed, StrongsGreen, StrongsBlue);
strcat(buf1, buf2);
// 4: Strongs' Tense (Morph)
sprintf(buf2, "\\red%d\\green%d\\blue%d;", MorphRed, MorphGreen, MorphBlue);
strcat(buf1, buf2);
// 5: Unknown
strcat(buf1, "\\red0\\green0\\blue255;");
// 6: Unknown
strcat(buf1, "\\red255\\green0\\blue0;");
// 7: Verse/Body Text Color
sprintf(buf2, "\\red%d\\green%d\\blue%d;}",BodyRed, BodyGreen, BodyBlue);
strcat(buf1, buf2);
/*
}
else {
sprintf(buf2, "{\\colortbl;\\red0\\green0\\blue255;\\red0\\green200\\blue50;\\red0\\green0\\blue255;\\red0\\green200\\blue50;\\red0\\green0\\blue255;\\red255\\green0\\blue0;\\red0\\green\\blue0;\\red0\\green\\blue0;\\red0\\green\\blue0;}");
strcat(buf1, buf2);
}
*/
RTFHeader = buf1;
}
AnsiString TRxRichEditX::getType() {
AnsiString retVal;
if (!strcmp(type.c_str(), "Default")) {
if (!strcmp(module->Type(), "Biblical Texts"))
retVal = "Text";
if ((!strcmp(module->Type(), "Commentaries")) ||
(!strcmp(module->Type(), "Generic Books")))
retVal = "Comment";
if (!strcmp(module->Type(), "Lexicons / Dictionaries"))
retVal = "LD";
}
else retVal = type;
return retVal;
}
long __fastcall TRxRichEditX::TextLen() {
long MaxLen;
if (RichEditVersion >= 2) {
TGetTextLengthEx TextLenEx;
// with TextLenEx do begin
TextLenEx.flags = GTL_DEFAULT;
TextLenEx.codepage = 1200;
MaxLen = Perform(EM_GETTEXTLENGTHEX, (WPARAM)&TextLenEx, 0);
}
else MaxLen = GetTextLen();
return MaxLen;
}
WideString __fastcall TRxRichEditX::GetText() {
long MaxLen = TextLen();
wchar_t *buf = new wchar_t [ MaxLen + 2 ];
GETTEXTEX params;
params.cb = (MaxLen + 1) * sizeof(wchar_t);
params.flags = GT_DEFAULT;
params.codepage = 1200; //CP_ACP;
params.lpDefaultChar = 0;
params.lpUsedDefChar = 0;
LONG lResult;
lResult = SendMessage(Handle, EM_GETTEXTEX, (WPARAM)¶ms, (LPARAM)buf);
WideString Result = buf;
delete [] buf;
return Result;
}
WideString __fastcall TRxRichEditX::GetTextRange(int StartPos, int EndPos) {
WideString Result = GetText();
Result = Result.SubString(StartPos+1, (EndPos - StartPos));
return Result;
}
WideString TRxRichEditX::Trim(WideString &src) {
WideString Result = src;
int length = Result.Length();
int start = 1;
while (length) {
if (Result[length] != ' ')
break;
Result.SetLength(--length);
}
while (start < length) {
if (Result[start] != ' ')
break;
start++;
}
if (start > 1)
Result = Result.SubString(start, length - start);
return Result;
}
WideString __fastcall TRxRichEditX::WordAtCursor(void) {
TCharRange Range;
WideString Result = "";
if (HandleAllocated()) {
long max = TextLen() - 1;
for (int i = 0; (SelStart + i) < max; i++) {
Range.cpMax = SelStart + i;
if (!Range.cpMax)
Range.cpMin = 0;
else if (SendMessage(Handle, EM_FINDWORDBREAK, WB_ISDELIMITER, Range.cpMax))
Range.cpMin = SendMessage(Handle, EM_FINDWORDBREAK, WB_MOVEWORDLEFT, Range.cpMax);
else Range.cpMin = SendMessage(Handle, EM_FINDWORDBREAK, WB_LEFT, Range.cpMax);
while (SendMessage(Handle, EM_FINDWORDBREAK, WB_ISDELIMITER, Range.cpMin))
Range.cpMin++;
Range.cpMax = SendMessage(Handle, EM_FINDWORDBREAK, WB_RIGHTBREAK, Range.cpMax);
Result = Trim(GetTextRange(Range.cpMin, Range.cpMax));
if (Range.cpMax - Range.cpMin)
break;
}
}
int start = 1;
int end = Result.Length();
if (end) {
if (strchr(",", Result[end]))
end--;
if (strchr(",", Result[start]))
start++;
// see if we're a verse number
if (isdigit(Result[start]) && (end > 3)) {
if (isalpha(Result[start+3])) {
start++;
if (isdigit(Result[start]))
start++;
if (isdigit(Result[start]))
start++;
}
}
Result = Result.SubString(start, end-(start-1));
}
return Result;
}