//--------------------------------------------------------------------------- #include #pragma hdrstop #include "biblecsmgr.h" #include "paraldisp.h" #include #include using namespace std; //--------------------------------------------------------------------------- static inline ParallelDisp *ValidCtrCheck() { return new ParallelDisp(NULL); } //--------------------------------------------------------------------------- __fastcall ParallelDisp::ParallelDisp(TWinControl *Owner) : SWDispRTFChap(Owner) { modCount = 3; mods = 0; warnNoMod = false; } __fastcall ParallelDisp::~ParallelDisp() { if (mods) delete [] mods; } // Display for biblical text char ParallelDisp::Display(SWModule &Module) { Display(); } SWModule **ParallelDisp::getModules() { if (mods) delete [] mods; int realModCount = 0; for (int i = 0; i < modCount; i++) { ModMap::iterator it = (*mgr)->Modules.find(mod[i].c_str()); if (it != (*mgr)->Modules.end()) realModCount++; } mods = new SWModule *[realModCount+1]; realModCount = 0; for (int i = 0; i < modCount; i++) { ModMap::iterator it = (*mgr)->Modules.find(mod[i].c_str()); if (it != (*mgr)->Modules.end()) mods[realModCount++] = it->second; } mods[realModCount] = 0; return mods; } char ParallelDisp::Display() { int testmt, book, chap, verse, versepos; char buf[254]; System::AnsiString newtext, tmptext, tmptext2; SWModule **mods = getModules(); int realModCount; for (realModCount = 0; mods[realModCount]; realModCount++); // assert we have at least one module to display otherwise clear the display if (!realModCount){ newtext = " "; // This is a single space because if it is completly empty then the pop-up menu items copy, search etc. crash. RTFStream->Clear(); RTFStream->WriteBuffer(newtext.c_str(), newtext.Length()); RTFStream->Position = 0; Lines->LoadFromStream(RTFStream); if (!warnNoMod) { Application->MessageBox("This must be your first time using the new parallel display in SWORD. This tab is for viewing up to three of your installed Bibles on the screen together. You will notice that this page is currently blank. Right-click the page to get a menu for selecting Bibles to be compared.\n\nThis is our first pass at this feature, so Lord willing, it will improve in future versions.\n\nEnjoy!\n\nThe SWORD Project Development Team", "New Feature - Parallel Display", MB_OK); warnNoMod = true; } return 0; } VerseKey *key = (VerseKey *)(SWKey *)(*mods[0]); UnicodeRTF uToRTF; testmt = key->Testament(); chap = key->Chapter(); book = key->Book(); verse = key->Verse(); key->Verse(1); module = mods[0]; type = "Default"; recalcAppearance(); newtext = RTFHeader; newtext = newtext + RTFChapterMarkPre + IntToStr(chap) + RTFChapterMarkPost; newtext = newtext + "\\pard\\f0\\nowidctlpar\\cf7 "; mods[0]->Error(); // clear error; /* // Dunno if this first line does anything newtext += "{\\stylesheet{\\s1{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}\\rtlch\\afs24\\lang255\\ltrch\\dbch\\af2\\afs24\\langfe255\\loch\\f0\\fs24\\lang1033\\snext1 Default;}"; newtext += "{\\s2\\sa120{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}\\rtlch\\afs24\\lang255\\ltrch\\dbch\\af2\\afs24\\langfe255\\loch\\f0\\fs24\\lang1033\\sbasedon1\\snext2 Text body;}"; newtext += "{\\s3\\sa120{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}\\rtlch\\afs24\\lang255\\ltrch\\dbch\\af2\\afs24\\langfe255\\loch\\f0\\fs24\\lang1033\\sbasedon2\\snext3 Table Contents;}"; newtext += "{\\s4\\sa120\\qc{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}\\rtlch\\afs24\\lang255\\ai\\ab\\ltrch\\dbch\\af2\\afs24\\langfe255\\ai\\ab\\loch\\f0\\fs24\\lang1033\\i\\b\\sbasedon3\\snext4 Table Heading;}"; newtext += "}"; newtext += "{\\info{\\comment StarWriter}{\\vern6410}}"; newtext += "\\deftab1250"; newtext += "{\\*\\pgdsctbl"; newtext += "{\\pgdsc0\\pgdscuse195\\pgwsxn12240\\pghsxn15840\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\pgdscnxt0 Default;}}"; newtext += "\\paperh15840\\paperw12240\\margl1800\\margr1800\\margt1440\\margb1440\\sectd\\sbknone\\pgwsxn12240\\pghsxn15840\\marglsxn1800\\margrsxn1800\\margtsxn1440\\margbsxn1440\\ftnbj\\ftnstart1\\ftnrstcont\\ftnnar\\aenddoc\\aftnrstcont\\aftnstart1\\aftnnrlc"; newtext += "\\trowd\\trql\\trleft778\\clbrdrt\\brdrs\\brdrw1\\brdrcf1\\brsp0\\clbrdrl\\brdrs\\brdrw1\\brdrcf1\\brsp0\\clbrdrb\\brdrs\\brdrw1\\brdrcf1\\brsp0\\cellx4278\\clbrdrt\\brdrs\\brdrw1\\brdrcf1\\brsp0\\clbrdrl\\brdrs\\brdrw1\\brdrcf1\\brsp0\\clbrdrb\\brdrs\\brdrw1\\brdrcf1\\brsp0\\clbrdrr\\brdrs\\brdrw1\\brdrcf1\\brsp0\\cellx7772"; newtext += "\\pard\\intbl\\pard\\plain \\intbl\\s4\\sa120\\qc{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}\\rtlch\\afs24\\lang255\\ai\\ab\\ltrch\\dbch\\af2\\afs24\\langfe255\\ai\\ab\\loch\\f0\\fs24\\lang1033\\i\\b {\\ltrch\\loch\\f0 "; newtext += "HEADING COL 1"; newtext += "}"; newtext += "\\cell\\pard\\plain \\intbl\\s4\\sa120\\qc{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}\\rtlch\\afs24\\lang255\\ai\\ab\\ltrch\\dbch\\af2\\afs24\\langfe255\\ai\\ab\\loch\\f0\\fs24\\lang1033\\i\\b {\\ltrch\\loch\\f0 "; newtext += "HEADING COL 2"; newtext += "}"; newtext += "\\cell\\row\\pard "; */ SWBuf lastEntry = "something the first entry will never be"; // bool firstRow = true; while ((key->Book() == book) && (key->Chapter() == chap) && (mods[0]->Error() == 0)) { if (lastEntry == (SWBuf)mods[0]->getRawEntry()) { (*mods[0])++; continue; } /* // First Row data, notice the additional \\clbrdrt lines which aren't in following rows newtext += "\\trowd\\trql\\trleft778"; // if (firstRow) // newtext += "\\clbrdrt\\brdrs\\brdrw1\\brdrcf1\\brsp0"; newtext += "\\clbrdrl\\brdrs\\brdrw1\\brdrcf1\\brsp0"; newtext += "\\clbrdrb\\brdrs\\brdrw1\\brdrcf1\\brsp0"; // This line should change the background color but doesn't seem to work //newtext += "\\clcbpat2"; // if (firstRow) // newtext += "\\clbrdrt\\brdrs\\brdrw1\\brdrcf1\\brsp0"; newtext += "\\cellx4278"; newtext += "\\clbrdrl\\brdrs\\brdrw1\\brdrcf1\\brsp0"; newtext += "\\clbrdrb\\brdrs\\brdrw1\\brdrcf1\\brsp0"; newtext += "\\clbrdrr\\brdrs\\brdrw1\\brdrcf1\\brsp0"; newtext += "\\cellx7772"; newtext += "\\pard\\intbl\\pard\\plain "; */ bool firstRow = true; for (int z = 0; z < realModCount; z++) { // if (!firstRow) // newtext += "\\par__________________\\par"; firstRow = false; /* // Cell newtext += "\\intbl\\s3\\sa120"; newtext += "{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}"; newtext += "\\rtlch\\afs24\\lang255\\ltrch\\dbch\\af2\\afs24\\langfe255\\loch\\f0\\fs24\\lang1033 "; newtext += "{\\ltrch\\loch\\f0 "; */ /* if (mods[z]->Direction() == DIRECTION_RTL) { newtext = newtext + "\\qr "; } if (mods[z]->Direction() == DIRECTION_RTL && (platformID == VER_PLATFORM_WIN32_NT && (!strnicmp(mods[0]->Lang(), "he", 2) || !strnicmp(mods[0]->Lang(), "ar", 2)))) { newtext = newtext + "\\rtlpar "; } */ tmptext = "{\\b "; tmptext += mods[z]->Name(); tmptext += ": } "; lastEntry = mods[z]->getRawEntry(); for (const char *loop = (const char *)(*mods[z]); *loop; loop++) { if (*loop == '\n') { tmptext += "\\par "; } else tmptext += *loop; } if (tmptext.Length() > 3) { // make sure we have an entry int pvHeading = 0; do { sprintf(buf, "%i", pvHeading++); SWBuf preverseHeading = module->getEntryAttributes()["Heading"]["Preverse"][buf].c_str(); uToRTF.processText(preverseHeading); if (preverseHeading.length()) { newtext += ((AnsiString)"\\par\\par {\\i1\\b1 ") + preverseHeading.c_str() + "\\par}"; } else break; } while (true); if (mods[z]->Direction() == DIRECTION_RTL && (platformID == VER_PLATFORM_WIN32_WINDOWS || (mods[z]->Lang() && strnicmp(mods[z]->Lang(), "he", 2) && strnicmp(mods[z]->Lang(), "ar", 2)))) { newtext = newtext + RTFVersePre; if ((key->Verse() == verse) && (dispAttribs.markCurrentVerse)) { newtext = newtext + "\\cf2 "; // \cf2 = second color in color table } newtext += tmptext + RTFVersePost; newtext = newtext + RTFVerseMarkPre + IntToStr(key->Verse()) + RTFVerseMarkPost; newtext = newtext + "\\par "; } else { newtext = newtext + RTFVerseMarkPre + IntToStr(key->Verse()) + RTFVerseMarkPost; newtext = newtext + RTFVersePre; if ((key->Verse() == verse) && (dispAttribs.markCurrentVerse)) { newtext = newtext + "\\cf2 "; // \cf2 = second color in color table } newtext += tmptext + RTFVersePost; } } if (key->Verse() == verse) { tmptext = newtext + RTFTrailer + "}"; RTFStream->Clear(); RTFStream->WriteBuffer(tmptext.c_str(), tmptext.Length()); RTFStream->Position = 0; Lines->LoadFromStream(RTFStream); makeLinks(); makeImages(); versepos = GetTextLen() - 3; } // newtext = newtext + "}"; if (z < (realModCount-1)) newtext += "\\par{\\super _______}\\par "; else newtext += "\\par\\par "; // if (z < (realModCount-1)) // newtext += "\\cell\\pard\\plain "; // else newtext += "\\cell\\row\\pard "; } (*mods[0])++; } // ending stuff // newtext += "\\pard\\plain \\s1"; // newtext += "{\\*\\hyphen2\\hyphlead2\\hyphtrail2\\hyphmax0}"; // newtext += "\\rtlch\\afs24\\lang255\\ltrch\\dbch\\af2\\afs24\\langfe255\\loch\\f0\\fs24\\lang1033 "; newtext = newtext + RTFTrailer; 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) } key->Chapter(1); key->Book(1); key->Testament(testmt); key->Book(book); key->Chapter(chap); key->Verse(verse); RTFStream->Clear(); RTFStream->WriteBuffer(newtext.c_str(), newtext.Length()); RTFStream->Position = 0; Lines->LoadFromStream(RTFStream); makeLinks(); makeImages(); //{ Position control text at current verse } this->SetFocus(); SelStart = 1; SendMessage(Handle, EM_SCROLLCARET, 0, 0); SelStart = versepos; SendMessage(Handle, EM_SCROLLCARET, 0, 0); warnNoMod = true; // Set this true meaning the user already has selected some bibles. So that if they select none for all three they do not get the new feature message box. return 0; } //--------------------------------------------------------------------------- namespace Paraldisp { void __fastcall Register() { TComponentClass classes[1] = {__classid(ParallelDisp)}; RegisterComponents("SWORD", classes, 0); } } //---------------------------------------------------------------------------