//--------------------------------------------------------------------------- #include #pragma hdrstop #include "TntSystem.hpp" #include "PrintFrm.h" #include "mainfrm.h" #include #include #include #include "PreviewForm.h" //--------------------------------------------------------------------------- #pragma package(smart_init) //#pragma link "RxCombos" #pragma resource "*.dfm" TPrintForm *PrintForm; //--------------------------------------------------------------------------- __fastcall TPrintForm::TPrintForm(TComponent* Owner) : TForm(Owner) { rtfPrint = new TRxRichEditX(this); rtfPrint->Parent = this; rtfPrint->Visible = false; rtfPrint->Font->Name = "Arial"; // Put in the RXLib Font combobox component cmbFont = new TFontComboBox(this); cmbFont->Parent = pnlFontComboBox; cmbFont->Align = alClient; cmbFont->Font->Size = 12; cmbFont->ParentFont = true; cmbFont->UseFonts = true; cmbFont->ItemIndex = cmbFont->Items->IndexOf("Arial"); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::FormShow(TObject *Sender) { /* TODO -oDavid T -cPrinting : Remove this once Printing is in a finished form */ if(Form1->optionsconf->Sections["Printing"]["Notice"] != "1"){ MessageBoxW(0, _tr("This release of The SWORD Printer is preliminary and is not yet fully functional, therefore some of the features here have been disabled. Please be sure to take a look at the formatting options to be able to fully take control of how your page will look. Also be sure to use the \"Print Preview\" feature to preview how your page(s) will look on paper before printing. Enjoy! -- The SWORD Project Development Team!"), _tr("The SWORD Printer"), MB_ICONINFORMATION | MB_OK); Form1->optionsconf->Sections["Printing"]["Notice"] = "1"; Form1->optionsconf->Save(); } } //TODO: fix! :) I added wishlist functionality with parameters that isn't implemented! :) Sorry. void TPrintForm::print(ListKey *keys, SWModule *module) { ConfigEntMap::iterator eit; AnsiString fontName; BibleCSMGR *manager = Form1->mainmgr; ModMap::iterator mods; TPageControl* pc; if ((Form1->ActiveControl == Form1->CommentaryPageControl) || (IsChild(Form1->CommentaryPageControl->Handle, Form1->ActiveControl->Handle))){ pc = Form1->CommentaryPageControl; radComm->Checked = true; staticRange->Caption = _tr("Verse Range or List"); editStart->Text = (keys) ? keys->getRangeText() : Form1->DefaultVSKey->getText(); } else if ((Form1->ActiveControl == Form1->LexDictPageControl) || (IsChild(Form1->LexDictPageControl->Handle, Form1->ActiveControl->Handle))){ pc = Form1->LexDictPageControl; radLD->Checked = true; staticRange->Caption = _tr("Lookup Range"); editStart->Text = (keys) ? WideString(keys->getRangeText()) : Form1->DictKeyEdit->Text; } else { pc = Form1->TextPageControl; radText->Checked = true; staticRange->Caption = _tr("Verse Range or List"); editStart->Text = (keys) ? keys->getRangeText() : Form1->DefaultVSKey->getText(); } FillModuleCombo(); AnsiString temp; for (int count = 0; count < cmbModule->Items->Count; count++) { temp = cmbModule->Items->Strings[count].SubString(2, cmbModule->Items->Strings[count].Pos("]") - 2); if (temp == pc->ActivePage->Caption) cmbModule->ItemIndex = count; } SetHint(); // Removed this because I want to place it in a central location which will load all // the printed page settings -- David Trotz // fontName = ((eit = Form1->optionsconf->Sections["PrintedPage"].find("TextFontName")) != Form1->optionsconf->Sections["PrintedPage"].end())? (*eit).second.c_str() : "Times New Roman"; // cmbFont->ItemIndex = cmbFont->Items->IndexOf(fontName); PageControl1->ActivePage = shtSelection; SetDefaultOps(); ShowModal(); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::btnCloseClick(TObject *Sender) { Close(); } //--------------------------------------------------------------------------- void TPrintForm::FillModuleCombo() { TStringList *moduleNames = new TStringList; BibleCSMGR *manager = Form1->mainmgr; ModMap::iterator mods; AnsiString modName; for (mods = manager->Modules.begin(); mods != manager->Modules.end(); mods++) { modName = "[" + (AnsiString)mods->second->Name() + "] " + (AnsiString)mods->second->Description(); if(!strncmp(mods->second->Type(), "Bibl", 4) && radText->Checked){ moduleNames->Add(modName); }else if(!strncmp(mods->second->Type(), "Comm", 4) && radComm->Checked){ moduleNames->Add(modName); }else if(!strncmp(mods->second->Type(), "Lexi", 4) && radLD->Checked){ moduleNames->Add(modName); } } cmbModule->Items = moduleNames; cmbModule->ItemIndex = 0; } void __fastcall TPrintForm::radTextClick(TObject *Sender) { cmbModule->Enabled = true; staticRange->Caption = _tr("Verse Range or List"); SetHint(); FillModuleCombo(); SetDefaultOps(); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::radCommClick(TObject *Sender) { staticRange->Caption = _tr("Verse Range or List"); SetHint(); FillModuleCombo(); SetDefaultOps(); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::radLDClick(TObject *Sender) { cmbModule->Enabled = true; staticRange->Caption = _tr("Lookup Entry"); SetHint(); FillModuleCombo(); SetDefaultOps(); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::spnLeftClick(TObject *Sender, TUDBtnType Button) { if(Button == Comctrls::btNext) editLeft->Text = FloatToStr(StrToFloat(editLeft->Text) + .05); else editLeft->Text = FloatToStr(StrToFloat(editLeft->Text) - .05); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::spnRightClick(TObject *Sender, TUDBtnType Button) { if(Button == Comctrls::btNext) editRight->Text = FloatToStr(StrToFloat(editRight->Text) + .05); else editRight->Text = FloatToStr(StrToFloat(editRight->Text) - .05); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::spnBottomClick(TObject *Sender, TUDBtnType Button) { if(Button == Comctrls::btNext) editBottom->Text = FloatToStr(StrToFloat(editBottom->Text) + .05); else editBottom->Text = FloatToStr(StrToFloat(editBottom->Text) - .05); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::spnTopClick(TObject *Sender, TUDBtnType Button) { if(Button == Comctrls::btNext) editTop->Text = FloatToStr(StrToFloat(editTop->Text) + .05); else editTop->Text = FloatToStr(StrToFloat(editTop->Text) - .05); } //--------------------------------------------------------------------------- void __fastcall TPrintForm::btnPrintClick(TObject *Sender) { SavePrintPrefs(); if(cmbModule->Text.data() != NULL && editStart->Text.data() != NULL){ PrepareRTF(); OnPrint(rtfPrint); } } //--------------------------------------------------------------------------- void __fastcall TPrintForm::OnPrint(TRxRichEdit* rtfPrint) { /* TODO 2 -oDavid -cPrinting : Add Printing of Headers and Footers */ float leftMargin = StrToFloat(editLeft->Text), rightMargin = StrToFloat(editRight->Text), topMargin = StrToFloat(editTop->Text), bottomMargin = StrToFloat(editBottom->Text); // Sets the font we will use for the headers and footers Printer()->Canvas->Font->Name = "Arial"; Printer()->Canvas->Font->Size = -8; Printer()->Canvas->Font->Color = clBlack; int wPage = ::GetDeviceCaps(Printer()->Handle, PHYSICALWIDTH); int hPage = ::GetDeviceCaps(Printer()->Handle, PHYSICALHEIGHT); int xPPI = ::GetDeviceCaps(Printer()->Handle, LOGPIXELSX); int yPPI = ::GetDeviceCaps(Printer()->Handle, LOGPIXELSY); int wTwips = ::MulDiv(wPage, 1440, xPPI); int hTwips = ::MulDiv(hPage, 1440, yPPI); /* // Adjust for the headers and footers if needed if(ckHeader->Checked){ int headerCoord = hTwips; hTwips -= (Printer()->Canvas->Font->Height + (.25 * Printer()->Canvas->Font->Height)); } if(ckFooter->Checked){ int footerCoord = hTwips; hTwips -= (Printer()->Canvas->Font->Height + (.25 * Printer()->Canvas->Font->Height)); } */ RECT pageRect; pageRect.left = pageRect.top = 0; pageRect.right = wTwips; pageRect.bottom = hTwips; RECT rendRect; rendRect.left = rendRect.top = 0; rendRect.right = pageRect.right - 1440 * (leftMargin + rightMargin); rendRect.bottom = pageRect.bottom - 1440 * (topMargin + bottomMargin); std::vector FPageOffsets; TPageOffsets po; po.Start = 0; TFormatRange fr; fr.hdc = Printer()->Handle; fr.hdcTarget = Printer()->Handle; fr.chrg.cpMin = po.Start; fr.chrg.cpMax = -1; int lastOffset = ::SendMessage(rtfPrint->Handle, WM_GETTEXTLENGTH, 0, 0); ::SendMessage(rtfPrint->Handle, EM_FORMATRANGE, (WPARAM) 0, (LPARAM) 0); ::SaveDC(fr.hdc); ::SetMapMode(fr.hdc, MM_TEXT); int xOffset = -::GetDeviceCaps(Printer()->Handle, PHYSICALOFFSETX); int yOffset = -::GetDeviceCaps(Printer()->Handle, PHYSICALOFFSETY); xOffset += ::MulDiv((leftMargin * 1440), xPPI, 1440); yOffset += ::MulDiv((topMargin * 1440), yPPI, 1440); ::SetViewportOrgEx(fr.hdc, xOffset, yOffset, NULL); do { fr.rc = rendRect; fr.rcPage = pageRect; po.Start = fr.chrg.cpMin; fr.chrg.cpMin = ::SendMessage(rtfPrint->Handle, EM_FORMATRANGE,(WPARAM) 0, (LPARAM) &fr); // I don't know why I need to do this, but there is an apparent bug in the TRXRichEdit control // and it doesn't handle the last page properly if there are more than 3 pages of text. if(fr.chrg.cpMin == po.End) fr.chrg.cpMin = lastOffset; po.End = fr.chrg.cpMin - 1; po.rendRect = fr.rc; if(fr.chrg.cpMin < lastOffset) FPageOffsets.push_back(po); } while (fr.chrg.cpMin != -1 && fr.chrg.cpMin < lastOffset); int pageCount = FPageOffsets.size(); ::SendMessage(rtfPrint->Handle, EM_FORMATRANGE, (WPARAM) 0, (LPARAM) 0); ::RestoreDC(fr.hdc, -1); Printer()->BeginDoc(); fr.hdc = Printer()->Handle; fr.hdcTarget = Printer()->Handle; ::SaveDC(fr.hdc); /* if(ckHeader->Checked == true){ Printer()->Canvas->TextOut(100,100,"This is my test"); } */ bool firstPage = true; int currPage = 0; do { if (firstPage) firstPage = false; else Printer()->NewPage(); ::SetViewportOrgEx(fr.hdc, xOffset, yOffset, NULL); fr.rc = FPageOffsets[currPage].rendRect; fr.rcPage = pageRect; fr.chrg.cpMin = FPageOffsets[currPage].Start; fr.chrg.cpMax = FPageOffsets[currPage].End; fr.chrg.cpMin = ::SendMessage(rtfPrint->Handle, EM_FORMATRANGE, (WPARAM) 1, (LPARAM) &fr); } while (++currPage < pageCount); ::RestoreDC(fr.hdc, -1); Printer()->EndDoc(); ::SendMessage(rtfPrint->Handle, EM_FORMATRANGE, (WPARAM) 0, (LPARAM) 0); FPageOffsets.erase(FPageOffsets.begin(), FPageOffsets.end()); } void TPrintForm::SetHint() { TStringList* strList = new TStringList; if(radText->Checked || radComm->Checked){ strList->Add(_tr("Examples:")); strList->Add(_tr("John 1:1 Prints John chapter 1 verse 1")); strList->Add(_tr("John 1 Prints the entire first chapter of John")); strList->Add(_tr("John 1,2 Prints chapters 1 and 2 of John")); strList->Add(_tr("John 3:16;Rom 3:23 Prints John 3:16 and Romans 3:23")); }else{ strList->Add(_tr("Examples:")); /* TODO 2 -oDavid -cPrinting : Make printing ranges of dictionaries work */ // The ranges don't work yet. //strList->Add(_tr("Aaron - David Prints dictionary entries from Aaron to David")); strList->Add(_tr("Jesus Prints dictionary entry for Jesus")); //strList->Add(_tr("0051 - 0054 Prints dictionary entry for range 0051 to 0054")); strList->Add(_tr("0051 Prints dictionary entry for 0051")); } editStart->Hint = strList->Text; delete strList; } void __fastcall TPrintForm::btnSetupClick(TObject *Sender) { PrinterSetupDialog->Execute(); } //--------------------------------------------------------------------------- void TPrintForm::PrepareRTF() { BibleCSMGR* manager = Form1->mainmgr; //RTF_FORMAT format; AnsiString newtext = ""; AnsiString moduleName = cmbModule->Text.SubString(2,cmbModule->Text.Pos("]") - 2); SWModule *module = manager->Modules[moduleName.c_str()]; ListKey lstKey; StrKey testKey; SavePrintPrefs(); lstKey.Persist(1); if(!radLD->Checked){ lstKey = VerseKey().ParseVerseList(editStart->Text.c_str(),*(Form1->DefaultVSKey), true); module->setKey(&lstKey); rtfPrint->type = "PrintedPage"; rtfPrint->RenderModule(module); module->setKey(Form1->DefaultVSKey); } else{ testKey.setText(WideStringToUTF8(editStart->Text).c_str()); lstKey << testKey; module->setKey(&lstKey); rtfPrint->type = "PrintedPage"; rtfPrint->RenderModule(module); module->setKey(Form1->DefaultStrKey); } } void __fastcall TPrintForm::btnPreviewClick(TObject *Sender) { SavePrintPrefs(); if(cmbModule->Text.data() != NULL && editStart->Text.data() != NULL){ PrepareRTF(); PreviewForm->currPage = 0; if(PreviewForm->ShowModal() == mrOk) OnPrint(rtfPrint); } } void __fastcall TPrintForm::ckHeaderClick(TObject *Sender) { editHeader->Enabled = ckHeader->Checked; } //--------------------------------------------------------------------------- void __fastcall TPrintForm::ckFooterClick(TObject *Sender) { editFooter->Enabled = ckFooter->Checked; } //--------------------------------------------------------------------------- void __fastcall TPrintForm::ckVSNumClick(TObject *Sender) { ckSuperVS->Enabled = ckVSNum->Checked; } //--------------------------------------------------------------------------- void TPrintForm::SetDefaultOps() { SWBuf modType = "", tempVal = ""; if(radText->Checked) modType = "Text"; else if(radComm->Checked) modType = "Comm"; else modType = "LD"; //**** Print Chapter Headings? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "ChHead")]; if (tempVal == "") ckChHead->Checked = true; else ckChHead->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Print Book Name? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType +"BkName")]; if (tempVal == "") ckBookHead->Checked = true; else ckBookHead->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Prefix Each Verse? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType +"PreFixTag")]; if (tempVal == "") ckPrefix->Checked = true; else ckPrefix->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Postfix Each Verse? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType +"PostFixTag")]; if (tempVal == "") ckPostfix->Checked = true; else ckPostfix->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Print the verse number? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "VSNum")]; if (tempVal == "") ckVSNum->Checked = true; else ckVSNum->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Superscript the verse number? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "SuperVS")]; if (tempVal == "") ckSuperVS->Checked = true; else ckSuperVS->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Print as a paragraph? ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "Paragraph")]; if (tempVal == "") ckParagraph->Checked = true; else ckParagraph->Checked = (atoi(tempVal.c_str())) ? true : false; //**** Chapter Heading Size ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "ChHeadSize")]; if (tempVal != "") spnHeading->Position = (atoi(tempVal.c_str())); //**** Body Text Size ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "FontSize")]; if (tempVal != "") spnBody->Position = (atoi(tempVal.c_str())); //**** Verse Number Size ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "VSNumSize")]; if (tempVal != "") spnNumbers->Position = (atoi(tempVal.c_str())); //**** Left Margin ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][("LeftMargin")]; if (tempVal != ""){ spnLeft->Position = GetSpinPos(atof(tempVal.c_str())); editLeft->Text = roundMargin(atof(tempVal.c_str())); } //**** Right Margin ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][("RightMargin")]; if (tempVal != ""){ spnRight->Position = GetSpinPos(atof(tempVal.c_str())); editRight->Text = roundMargin(atof(tempVal.c_str())); } //**** Top Margin ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][("TopMargin")]; if (tempVal != ""){ spnTop->Position = GetSpinPos(atof(tempVal.c_str())); editTop->Text = roundMargin(atof(tempVal.c_str())); } //**** Bottom Margin ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][("BottomMargin")]; if (tempVal != ""){ spnBottom->Position = GetSpinPos(atof(tempVal.c_str())); editBottom->Text = roundMargin(atof(tempVal.c_str())); } //**** Font Name ****// tempVal = Form1->optionsconf->Sections["PrintedPage"][(modType + "FontName")]; if (tempVal != "") cmbFont->ItemIndex = cmbFont->Items->IndexOf(tempVal.c_str()); /* if(radText->Checked){ ckBookHead->Checked = true; ckChHead->Checked = true; ckParagraph->Checked = true; ckVSNum->Checked = true; ckSuperVS->Checked = true; ckPrefix->Checked = false; ckPostfix->Checked = false; }else if(radComm->Checked){ ckBookHead->Checked = false; ckChHead->Checked = false; ckParagraph->Checked = false; ckVSNum->Checked = false; ckSuperVS->Checked = false; ckPrefix->Checked = false; ckPostfix->Checked = true; }else if(radLD->Checked){ ckBookHead->Checked = false; ckChHead->Checked = false; ckParagraph->Checked = false; ckVSNum->Checked = false; ckSuperVS->Checked = false; ckPrefix->Checked = false; ckPostfix->Checked = false; } */ } /* TODO -oDavid -cPrinting : Find a good place to call this */ void TPrintForm::SavePrintPrefs() { ConfigEntMap emap; SWConfig* config = Form1->optionsconf; SWBuf type; if(radText->Checked){ type = "Text"; }else if(radComm->Checked){ type = "Comment"; }else if(radLD->Checked){ type = "LD"; } emap = config->Sections["PrintedPage"]; emap[(type + "BkName")] = IntToStr((ckBookHead->Checked)?1:0).c_str(); emap[type + "ChHead"] = IntToStr((ckChHead->Checked)?1:0).c_str(); emap[type + "Paragraph"] = IntToStr((ckParagraph->Checked)?1:0).c_str(); emap[type + "VSNum"] = IntToStr((ckVSNum->Checked)?1:0).c_str(); emap[type + "SuperVS"] = IntToStr((ckSuperVS->Checked)?1:0).c_str(); emap[type + "PreFixTag"] = IntToStr((ckPrefix->Checked)?1:0).c_str(); emap[type + "PostFixTag"] = IntToStr((ckPostfix->Checked)?1:0).c_str(); emap[type + "ChHeadSize"] = editHeading->Text.c_str(); emap[type + "FontSize"] = editBody->Text.c_str(); emap[type + "VSNumSize"] = editNumbers->Text.c_str(); emap[type + "FontName"] = cmbFont->Text.c_str(); // Non text type dependent settings emap["LeftMargin"] = editLeft->Text.c_str(); emap["RightMargin"] = editRight->Text.c_str(); emap["TopMargin"] = editTop->Text.c_str(); emap["BottomMargin"] = editBottom->Text.c_str(); emap["PrnHeader"] = IntToStr((ckHeader->Checked)?1:0).c_str(); emap["PrnFooter"] = IntToStr((ckFooter->Checked)?1:0).c_str(); emap["Header"] = editHeader->Text.c_str(); emap["Footer"] = editFooter->Text.c_str(); config->Sections["PrintedPage"] = emap; config->Save(); } int inline TPrintForm::GetSpinPos(const float & value) { return ((int)(roundMargin(value) / .05)); } float TPrintForm::roundMargin(float value) { value *= 100; // Move the decimal right two positions int nVal = Ceil(value); // Round up if(nVal % 5) nVal = nVal - (nVal % 5) + 5; return nVal / 100.00; // Move decimal left two positions }