//--------------------------------------------------------------------------- #include #pragma hdrstop #include "RxRichEditX.h" #include #include #include #include "mainfrm.h" #include #include 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("", start, len, TRichSearchTypes()); if (foundAt == -1) break; SelStart = foundAt; SelLength = 11; this->SelText = ""; endAt = this->SearchText("", 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("", start, len, TRichSearchTypes()); if (foundAt == -1) break; SelStart = foundAt; SelLength = 11; this->SelText = ""; endAt = this->SearchText("", foundAt, len, TRichSearchTypes()); if (foundAt == -1) break; SelStart = endAt; SelLength = 4; this->SelText = ""; SelStart = foundAt; SelLength = endAt - foundAt; this->SelAttributes->Link = true; } if (Visible) { this->SetFocus(); SelStart = 0; SelLength = 0; SendMessage(Handle, EM_SCROLLCARET, 0, 0); } 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)entryColor.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; }