You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
1030 lines
30 KiB
1030 lines
30 KiB
/***************************************************************************
|
|
File: renderer.cpp
|
|
Project: Kio-Sword -- An ioslave for SWORD and KDE
|
|
Copyright: Copyright (C) 2004-2005 Luke Plant
|
|
***************************************************************************/
|
|
|
|
/***************************************************************************
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, *
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
|
* GNU General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, write to the *
|
|
* Free Software Foundation, Inc., *
|
|
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
|
***************************************************************************/
|
|
|
|
// Mine
|
|
#include "renderer.h"
|
|
#include "swordoptions.h"
|
|
#include "ks_osishtml.h"
|
|
#include "ks_gbfhtml.h"
|
|
#include "ks_thmlhtml.h"
|
|
#include "utils.h"
|
|
#include "swordutils.h"
|
|
#include "template.h"
|
|
|
|
// Sword
|
|
#include <swmgr.h>
|
|
#include <swkey.h>
|
|
#include <versekey.h>
|
|
#include <treekey.h>
|
|
#include <treekeyidx.h>
|
|
#include <plainhtml.h>
|
|
#include <rtfhtml.h>
|
|
#include <encfiltmgr.h>
|
|
#include <localemgr.h>
|
|
#include <regex.h>
|
|
|
|
|
|
// KDE
|
|
#include <tdelocale.h>
|
|
|
|
// QT
|
|
#include <ntqstring.h>
|
|
#include <ntqstringlist.h>
|
|
|
|
// Standard C/C++
|
|
#include <vector>
|
|
#include <cstring>
|
|
#include <string>
|
|
#include <set>
|
|
|
|
|
|
using std::string;
|
|
using std::vector;
|
|
using std::set;
|
|
using std::list;
|
|
|
|
using namespace sword;
|
|
|
|
namespace KioSword
|
|
{
|
|
static const TQString prev(" <li><a href=\"%2\" accesskey=\"p\">« %1</a>");
|
|
static TQString makePrevLink(const TQString& caption, const TQString& url)
|
|
{
|
|
return prev.arg(caption).arg(url);
|
|
}
|
|
|
|
static const TQString next(" <li><a href=\"%2\" accesskey=\"n\">%1 »</a>");
|
|
static TQString makeNextLink(const TQString& caption, const TQString& url)
|
|
{
|
|
return next.arg(caption).arg(url);
|
|
}
|
|
|
|
static const TQString treeup(" <li><a href=\"%3\" accesskey=\"u\">%1 %2</a>");
|
|
static TQString makeTreeUpLink(const TQString& caption1, const TQString& caption2, const TQString& url)
|
|
{
|
|
return treeup.arg(caption1).arg(caption2).arg(url);
|
|
}
|
|
|
|
static const TQString bibleup(" <li><a href=\"%2\" accesskey=\"u\">%1</a>");
|
|
static TQString makeBibleUpLink(const TQString& caption, const TQString& url)
|
|
{
|
|
return bibleup.arg(caption).arg(url);
|
|
}
|
|
|
|
static const TQString genlink(" <li><a href=\"%2\">%1</a>");
|
|
static TQString makeGeneralLink(const TQString& caption, const TQString& url)
|
|
{
|
|
return genlink.arg(caption).arg(url);
|
|
}
|
|
|
|
Renderer::Renderer() :
|
|
sword::SWMgr(0, 0, true, new sword::EncodingFilterMgr(sword::ENC_UTF8)),
|
|
m_osisfilter(0),
|
|
m_gbffilter(0),
|
|
m_thmlfilter(0),
|
|
m_plainfilter(0),
|
|
m_rtffilter(0)
|
|
{
|
|
for (int i = 0; i < NUM_MODULE_TYPES; i++) {
|
|
m_moduleTypes.push_back("");
|
|
m_moduleTypeNames.push_back(TQString(""));
|
|
}
|
|
|
|
m_moduleTypes[BIBLE] = "Biblical Texts";
|
|
m_moduleTypes[COMMENTARY] = "Commentaries";
|
|
m_moduleTypes[LEXDICT] = "Lexicons / Dictionaries";
|
|
m_moduleTypes[GENERIC] = "Generic Books";
|
|
|
|
m_moduleTypeNames[BIBLE] = i18n("Bibles");
|
|
m_moduleTypeNames[COMMENTARY] = i18n("Commentaries");
|
|
m_moduleTypeNames[LEXDICT] = i18n("Lexicons & Dictionaries");
|
|
m_moduleTypeNames[GENERIC] = i18n("Other Books");
|
|
}
|
|
|
|
|
|
Renderer::~Renderer() {
|
|
delete m_osisfilter;
|
|
delete m_gbffilter;
|
|
delete m_thmlfilter;
|
|
delete m_plainfilter;
|
|
delete m_rtffilter;
|
|
}
|
|
|
|
|
|
void Renderer::setOptions(const SwordOptions& options) {
|
|
setGlobalOption("Footnotes", (options.footnotes() ? "On" : "Off"));
|
|
setGlobalOption("Headings", (options.headings() ? "On" : "Off"));
|
|
setGlobalOption("Strong's Numbers", (options.strongs() ? "On" : "Off"));
|
|
setGlobalOption("Morphological Tags", (options.morph() ? "On" : "Off"));
|
|
setGlobalOption("Hebrew Cantillation", (options.cantillation() ? "On" : "Off"));
|
|
setGlobalOption("Hebrew Vowel Points", (options.hebrewVowelPoints() ? "On" : "Off"));
|
|
setGlobalOption("Greek Accents", (options.greekAccents() ? "On" : "Off"));
|
|
setGlobalOption("Lemmas", (options.lemmas() ? "On" : "Off"));
|
|
setGlobalOption("Cross-references", (options.crossRefs() ? "On" : "Off"));
|
|
setGlobalOption("Words of Christ in Red",(options.redWords() ? "On" : "Off"));
|
|
|
|
|
|
if (options.variants() == -1)
|
|
setGlobalOption("Variants", "All Readings");
|
|
else if (options.variants() == 1)
|
|
setGlobalOption("Variants", "Secondary Readings");
|
|
else
|
|
setGlobalOption("Variants", "Primary Readings");
|
|
|
|
LocaleMgr::getSystemLocaleMgr()->setDefaultLocaleName(options.locale().latin1());
|
|
}
|
|
|
|
/** Return an HTML hyperlinked list of all modules,
|
|
* categorised, and including descriptions
|
|
*/
|
|
TQString Renderer::listModules(const SwordOptions &options) {
|
|
TQString output;
|
|
TQString temp;
|
|
ModMap::iterator it;
|
|
vector<const char *>::size_type i;
|
|
SWModule *curMod;
|
|
|
|
setOptions(options);
|
|
|
|
if (Modules.empty()) {
|
|
output += ("<p>" + i18n("No modules installed!") + "</p>\n");
|
|
return output;
|
|
}
|
|
|
|
output += TQString("<div class='moduleslist'><h1>%1</h1>")
|
|
.arg(i18n("Modules"));
|
|
|
|
for (i = 0; i < m_moduleTypes.size(); i++) {
|
|
output += TQString("<h2 class='moduletype'>%1</h2>\n"
|
|
"<ul>\n").arg(m_moduleTypeNames[i]);
|
|
for (it = Modules.begin(); it != Modules.end(); it++) {
|
|
curMod = (*it).second;
|
|
if (!strcmp(curMod->Type(), m_moduleTypes[i])) {
|
|
output += TQString("<li class='module'><a class='module' href=\"%3\">%1</a> : %2\n")
|
|
.arg(curMod->Name())
|
|
.arg(curMod->Description())
|
|
.arg(swordUrl(curMod->Name(), options));
|
|
}
|
|
}
|
|
output += "</ul>";
|
|
}
|
|
output += "</div>";
|
|
return output;
|
|
}
|
|
|
|
/** Return a sorted list of all module names
|
|
*
|
|
*/
|
|
TQStringList Renderer::moduleList() {
|
|
TQStringList output;
|
|
ModMap::iterator it;
|
|
SWModule *curMod;
|
|
|
|
for (it = Modules.begin(); it != Modules.end(); it++) {
|
|
curMod = (*it).second;
|
|
output += TQString(curMod->Name());
|
|
}
|
|
output.sort();
|
|
return output;
|
|
}
|
|
|
|
Renderer::ModuleType Renderer::getModuleType(sword::SWModule *module) {
|
|
ModuleType modtype;
|
|
vector<const char *>::size_type i;
|
|
|
|
modtype = GENERIC; // default
|
|
for (i = 0; i < m_moduleTypes.size(); i++) {
|
|
if (!strcmp(module->Type(), m_moduleTypes[i])) {
|
|
modtype = (ModuleType)i;
|
|
break;
|
|
}
|
|
}
|
|
return modtype;
|
|
}
|
|
|
|
|
|
/** Add the relevant filter to a module
|
|
*
|
|
* This method checks to see whether we've already added
|
|
* the Render filter to a module. If so, then don't
|
|
* create or attach another, but ensure the options used
|
|
*
|
|
*/
|
|
void Renderer::setModuleFilter(SWModule *module, const SwordOptions* options) {
|
|
SectionMap::iterator sit;
|
|
ConfigEntMap::iterator eit;
|
|
SWTextMarkup modformat = FMT_UNKNOWN;
|
|
SWBuf encoding;
|
|
SWFilter *filter = 0;
|
|
|
|
if (m_modset.find(module) != m_modset.end())
|
|
// already added
|
|
return;
|
|
|
|
|
|
// From corediatheke.cpp
|
|
if ((sit = config->Sections.find(module->Name())) != config->Sections.end()) {
|
|
if ((eit = (*sit).second.find("SourceType")) != (*sit).second.end()) {
|
|
if (!strcasecmp((char *)(*eit).second.c_str(), "GBF"))
|
|
modformat = FMT_GBF;
|
|
else if (!strcasecmp((char *)(*eit).second.c_str(), "ThML"))
|
|
modformat = FMT_THML;
|
|
else if (!strcasecmp((char *)(*eit).second.c_str(), "OSIS"))
|
|
modformat = FMT_OSIS;
|
|
}
|
|
// FIXME - do something with this
|
|
if ((eit = (*sit).second.find("Encoding")) != (*sit).second.end())
|
|
encoding = (*eit).second;
|
|
else
|
|
encoding = (SWBuf)"";
|
|
}
|
|
|
|
|
|
switch (modformat)
|
|
{
|
|
// TODO - all filters used should subclass
|
|
// FilterBase and know how to write
|
|
// KioSword urls correctly using SwordOptions
|
|
case FMT_UNKNOWN :
|
|
case FMT_PLAIN :
|
|
if (!m_plainfilter)
|
|
m_plainfilter = new PLAINHTML();
|
|
filter = m_plainfilter;
|
|
break;
|
|
|
|
case FMT_THML :
|
|
if (!m_thmlfilter)
|
|
m_thmlfilter = new ThMLHTML();
|
|
m_thmlfilter->setSwordOptions(options);
|
|
filter = m_thmlfilter;
|
|
break;
|
|
|
|
case FMT_GBF:
|
|
if (!m_gbffilter)
|
|
m_gbffilter = new GBFHTML();
|
|
m_gbffilter->setSwordOptions(options);
|
|
filter = m_gbffilter;
|
|
break;
|
|
|
|
case FMT_HTML:
|
|
break;
|
|
|
|
case FMT_HTMLHREF:
|
|
break;
|
|
|
|
case FMT_RTF:
|
|
if (!m_rtffilter)
|
|
m_rtffilter = new RTFHTML();
|
|
filter = m_rtffilter;
|
|
break;
|
|
|
|
case FMT_OSIS:
|
|
if (!m_osisfilter)
|
|
m_osisfilter = new OSISHTML();
|
|
m_osisfilter->setSwordOptions(options);
|
|
filter = m_osisfilter;
|
|
break;
|
|
|
|
case FMT_WEBIF:
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
if (filter) {
|
|
module->AddRenderFilter(filter);
|
|
m_modset.insert(m_modset.begin(), module);
|
|
}
|
|
|
|
}
|
|
|
|
void Renderer::moduleQuery(const TQString &modname, const TQString &ref, const SwordOptions &options, Template* tmplt) {
|
|
TQString nav;
|
|
SWModule *module = 0;
|
|
SWKey *skey = 0;
|
|
KeyType keyt = SWKEY;
|
|
VerseKey *vk;
|
|
TreeKey *tk;
|
|
|
|
ModuleType modtype;
|
|
|
|
// Set the sword::Mgr options
|
|
setOptions(options);
|
|
|
|
// Find the module
|
|
module = getModule(modname.latin1());
|
|
|
|
if (module == 0) {
|
|
TQString output;
|
|
output += "<p><span class='error'>"
|
|
+ i18n("The module '%1' could not be found.").arg(modname)
|
|
+ "</span></p><hr/>";
|
|
output += listModules(options);
|
|
tmplt->setContent(output);
|
|
tmplt->setTitle(i18n("Module not found - Kio-Sword"));
|
|
}
|
|
else
|
|
{
|
|
setModuleFilter(module, &options);
|
|
|
|
// Determine key type.
|
|
skey = module->getKey();
|
|
if (!(vk = dynamic_cast<VerseKey*>(skey))) {
|
|
if (!(tk = dynamic_cast<TreeKey*>(skey))) {
|
|
keyt = SWKEY;
|
|
} else {
|
|
keyt = TREEKEY;
|
|
}
|
|
} else {
|
|
keyt = VERSEKEY;
|
|
}
|
|
modtype = getModuleType(module);
|
|
|
|
nav += TQString("<li class='first'>%1 <a href=\"%3\">%2</a></li>")
|
|
.arg(i18n("Module:"))
|
|
.arg(modname)
|
|
.arg(swordUrl(modname, options));
|
|
|
|
if (keyt == VERSEKEY) { // Should be just bibles and commentaries
|
|
verseQuery(module, ref, options, modtype, tmplt, nav);
|
|
} else if (keyt == TREEKEY) {
|
|
treeQuery(module, ref, options, modtype, tmplt, nav);
|
|
} else if (keyt == SWKEY) {
|
|
normalQuery(module, ref, options, modtype, tmplt, nav);
|
|
}
|
|
tmplt->setNav("<ul>" + nav + "</ul>");
|
|
tmplt->setShowToggles(true);
|
|
}
|
|
return;
|
|
}
|
|
|
|
TQString Renderer::search(const TQString &modname, const TQString &query, const SearchType searchType, const SwordOptions &options) {
|
|
SWModule *module = 0;
|
|
TQString output;
|
|
ListKey lk;
|
|
int stype = SEARCH_WORDS;
|
|
TQString stypename;
|
|
ModuleType modtype;
|
|
|
|
setOptions(options);
|
|
|
|
// Find the module
|
|
module = getModule(modname.latin1());
|
|
|
|
if (module == 0) {
|
|
output += "<p><span class='error'>"
|
|
+ i18n("The module '%1' could not be found.").arg(modname)
|
|
+ "</span></p>";
|
|
output += listModules(options);
|
|
return output;
|
|
}
|
|
|
|
modtype = getModuleType(module);
|
|
|
|
if (searchType == SEARCH_WORDS) {
|
|
stype = -2;
|
|
stypename = i18n("Word");
|
|
} else if (searchType == SEARCH_PHRASE) {
|
|
stype = -1;
|
|
stypename = i18n("Phrase");
|
|
} else if (searchType == SEARCH_REGEX) {
|
|
stype = 0;
|
|
stypename = i18n("Regular expression");
|
|
}
|
|
|
|
output += "<div class='searchresults'><h1>" + i18n("Search results:") + "</h1>";
|
|
output += TQString("<table><tr><td>%1</td><td><b>%2</b></td></tr><tr><td>%3</td><td><b>%4</b></td></tr><tr><td>%5</td><td><b>%6</b></td></tr></table>")
|
|
.arg(i18n("Module:"))
|
|
.arg(modname)
|
|
.arg(i18n("Query:"))
|
|
.arg(query)
|
|
.arg(i18n("Search type:"))
|
|
.arg(stypename);
|
|
|
|
|
|
lk = module->search(query.utf8(), stype, REG_ICASE);
|
|
if (lk.Count() == 0) {
|
|
output += "<p>" +i18n("No matches returned.");
|
|
} else {
|
|
output += "<p>" + i18n("1 match returned:", "%1 matches returned:", lk.Count()).arg(lk.Count());
|
|
output += "<ul>";
|
|
for (int i = 0; i < lk.Count(); ++i) {
|
|
TQString ref;
|
|
ref = TQString::fromUtf8(lk.getElement(i)->getText());
|
|
if (modtype == BIBLE) {
|
|
module->setKey(lk.getElement(i));
|
|
output += TQString("<li><a href=\"%3\">%1</a>: %2</li>")
|
|
.arg(ref)
|
|
.arg(renderText(module))
|
|
.arg(swordUrl(modname, ref, options));
|
|
|
|
} else {
|
|
output += TQString("<li><a href=\"%2\">%1</a></li>")
|
|
.arg(ref)
|
|
.arg(swordUrl(modname, ref, options));
|
|
}
|
|
}
|
|
output += "</ul>";
|
|
}
|
|
output += "</div>";
|
|
return output;
|
|
}
|
|
|
|
TQString Renderer::renderText(SWModule *module) {
|
|
return TQString::fromUtf8(module->RenderText());
|
|
}
|
|
|
|
/** Fill in template with formatted text for the query of a verse based module
|
|
* Links are appended to navlinks.
|
|
*/
|
|
void Renderer::verseQuery(SWModule *module, const TQString &ref, const SwordOptions &options,
|
|
ModuleType modtype, Template* tmplt, TQString &navlinks) {
|
|
TQString modname(module->Name());
|
|
TQString text;
|
|
bool doindex = false;
|
|
const char* modtextdir; // text direction of the module
|
|
|
|
ListKey lk;
|
|
VerseKey *vk = dynamic_cast<VerseKey*>(module->getKey());
|
|
|
|
if (!vk)
|
|
return;
|
|
|
|
// FIXME - why do I need this call to setLocale()?
|
|
vk->setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
|
|
|
|
modtextdir = textDirection(module);
|
|
|
|
vk->AutoNormalize(0);
|
|
do { // dummy loop
|
|
if (ref.isEmpty()) {
|
|
doindex = true;
|
|
break;
|
|
}
|
|
lk = vk->ParseVerseList(ref.utf8(), "Genesis 1:1", true);
|
|
if (lk.Count() == 0) {
|
|
text += "<p class=\"error\">" + i18n("Couldn't find reference '%1'.").arg(ref) + "</p>";
|
|
doindex = true;
|
|
break;
|
|
}
|
|
char book = 0;
|
|
char testament = 0;
|
|
int chapter = 0;
|
|
bool upToBookListShown = false;
|
|
for (int i = 0; i < lk.Count(); ++i) {
|
|
VerseKey *element = dynamic_cast<VerseKey*>(lk.GetElement(i));
|
|
if (element) {
|
|
// Multiple verses
|
|
char err = 0;
|
|
|
|
// Check whether we have an entire book selected
|
|
// (but treat single chapter books as if they were just
|
|
// one chapter from a book)
|
|
if (element->UpperBound().Chapter() > 1 &&
|
|
isEntireBook(element) && !options.wholeBook()) {
|
|
// List books and link for viewing entire book
|
|
SwordOptions options_wholebook(options);
|
|
options_wholebook.wholeBook.set(true); // set just for creating the URL
|
|
text += TQString("<h2>%1</h2>"
|
|
"<p>%2</p>"
|
|
"<p class='chapterlist'>%3</p>")
|
|
.arg(element->getBookName())
|
|
.arg(i18n("Chapters:"))
|
|
.arg(chapterList(modname, element, options))
|
|
+ TQString("<p><a href=\"%2\">%1</a></p>")
|
|
.arg(i18n("View entire book."))
|
|
.arg(swordUrl(module->Name(), element->getBookName(), options_wholebook));
|
|
if (!upToBookListShown)
|
|
{
|
|
navlinks += makeBibleUpLink(i18n("Books"),
|
|
swordUrl(modname, options));
|
|
upToBookListShown = true;
|
|
}
|
|
} else {
|
|
// chapter or verse range selected
|
|
module->Key(element->LowerBound());
|
|
if (lk.Count() == 1) {
|
|
// add some navigation links
|
|
if (isSingleChapter(element)) {
|
|
// get link to previous chapter
|
|
module->decrement();
|
|
if (!module->Error()) {
|
|
navlinks += makePrevLink(bookChapter(module->getKey()),
|
|
chapterLink(modname, module->getKey(), options));
|
|
}
|
|
// get link to book
|
|
module->Key(element->LowerBound());
|
|
navlinks += makeBibleUpLink(bookName(element),
|
|
bookLink(modname, element, options));
|
|
} else {
|
|
// less than a single chapter
|
|
// get link to book
|
|
navlinks += makeGeneralLink(bookName(element),
|
|
bookLink(modname, element, options));
|
|
// get link to chapter
|
|
navlinks += makeBibleUpLink(bookChapter(element),
|
|
chapterLink(modname, element, options));
|
|
}
|
|
}
|
|
|
|
// Headings plus text itself
|
|
bool inDirectionedDiv = false;
|
|
do {
|
|
VerseKey *curvk = dynamic_cast<VerseKey*>(module->getKey());
|
|
if (curvk->Book() != book || curvk->Testament() != testament) {
|
|
if (inDirectionedDiv)
|
|
{
|
|
// close it before carrying on
|
|
text += "</div>";
|
|
inDirectionedDiv = false;
|
|
}
|
|
text += "<h2>" + TQString(curvk->getBookName()) + "</h2>";
|
|
chapter = 0;
|
|
}
|
|
if (curvk->Chapter() != chapter) {
|
|
if (inDirectionedDiv)
|
|
{
|
|
// close it before carrying on
|
|
text += "</div>";
|
|
inDirectionedDiv = false;
|
|
}
|
|
text += "<h3>" + i18n("Chapter %1").arg(curvk->Chapter()) + "</h3>";
|
|
}
|
|
|
|
if (!inDirectionedDiv) {
|
|
text += TQString("<div dir='%1'>").arg(modtextdir);
|
|
inDirectionedDiv = true;
|
|
}
|
|
|
|
if (options.verseNumbers() && modtype == BIBLE) {
|
|
text += TQString("<a class=\"versenumber\" href=\"%2\">%1</a> ")
|
|
.arg(curvk->Verse())
|
|
.arg(swordUrl(module->Name(), module->KeyText(), options));
|
|
}
|
|
text += renderText(module);
|
|
text += " ";
|
|
if (options.verseLineBreaks())
|
|
text += "<br />";
|
|
book = curvk->Book();
|
|
testament = curvk->Testament();
|
|
chapter = curvk->Chapter();
|
|
|
|
module->increment(1);
|
|
} while (module->Key() <= element->UpperBound() && !(err = module->Error()));
|
|
|
|
// Close the final div
|
|
if (inDirectionedDiv)
|
|
{
|
|
text += "</div>";
|
|
inDirectionedDiv = false;
|
|
}
|
|
|
|
if (lk.Count() == 1) {
|
|
if (isSingleChapter(element)) {
|
|
// add some navigation links
|
|
if (!err) {
|
|
navlinks += makeNextLink(bookChapter(module->getKey()),
|
|
chapterLink(modname, module->getKey(), options));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} else {
|
|
// Reset flags used by the multiple verse path
|
|
book = 0;
|
|
testament = 0;
|
|
chapter = 0;
|
|
// Single verse
|
|
module->Key(*lk.GetElement(i));
|
|
element = dynamic_cast<VerseKey*>(module->getKey());
|
|
text += TQString("<h3>%1</h3>").arg(module->KeyText());
|
|
text += TQString("<div dir='%1'>").arg(modtextdir);
|
|
text += renderText(module);
|
|
text += "</div>";
|
|
if (lk.Count() == 1)
|
|
navlinks += makeBibleUpLink(bookChapter(element),
|
|
chapterLink(modname, element, options));
|
|
}
|
|
if (i+1 != lk.Count())
|
|
text += "<br />";
|
|
}
|
|
} while (false);
|
|
|
|
// Title: depends on what got printed above
|
|
TQString title;
|
|
if (doindex) {
|
|
if (!text.isEmpty()) { // an error message was printed
|
|
text = TQString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description()).arg(ref)
|
|
+ text;
|
|
title = "Error - Kio-Sword";
|
|
}
|
|
else
|
|
{
|
|
title = TQString("%1 - Kio-Sword").arg(module->Name());
|
|
}
|
|
} else {
|
|
if (modtype == COMMENTARY) {
|
|
text = TQString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description())
|
|
+ text;
|
|
title = TQString("%1 - %2 - Kio-Sword")
|
|
.arg(lk.getShortText())
|
|
.arg(module->Name());
|
|
} else if (modtype == BIBLE) {
|
|
text += TQString("<div class=\"biblename\">(%1)</div>").arg(module->Description());
|
|
title = TQString("%1 - %2 - Kio-Sword")
|
|
.arg(lk.getShortText())
|
|
.arg(module->Name());
|
|
}
|
|
}
|
|
tmplt->setTitle(title);
|
|
|
|
if (doindex) {
|
|
if (!text.isEmpty())
|
|
text += "<hr/>\n";
|
|
if (options.doBibleIndex()) {
|
|
text += "<h2>" + i18n("Books:") + "</h2>";
|
|
text += indexBible(module, options);
|
|
} else {
|
|
SwordOptions options_doindex(options);
|
|
options_doindex.doBibleIndex.set(true);
|
|
text += TQString("<p><a href=\"%2\">%1</a></p>")
|
|
.arg(i18n("Index of books"))
|
|
.arg(swordUrl(modname, options_doindex));
|
|
}
|
|
}
|
|
tmplt->setContent(text);
|
|
}
|
|
|
|
void Renderer::treeQuery(SWModule *module, const TQString &ref, const SwordOptions &options,
|
|
ModuleType modtype, Template* tmplt, TQString &navlinks) {
|
|
TQString output;
|
|
TQString modname(module->Name());
|
|
bool doindex;
|
|
TreeKey *tk = dynamic_cast<TreeKey*>(module->getKey());
|
|
|
|
if (!tk)
|
|
return;
|
|
|
|
output += TQString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description());
|
|
if (ref.isEmpty()) {
|
|
doindex = true;
|
|
} else {
|
|
tk->Error(); // clear
|
|
tk->setText(ref.utf8());
|
|
doindex = false;
|
|
if (tk->Error()) {
|
|
output += "<p class=\"error\">" + i18n("Couldn't find section '%1'.").arg(ref) + "</p>";
|
|
output += "<hr/>";
|
|
doindex = true;
|
|
} else {
|
|
TQString link;
|
|
output += renderText(module);
|
|
if (tk->previousSibling()) {
|
|
link = TQString::fromUtf8(module->KeyText()); // FIXME ? local8Bit or utf8
|
|
navlinks += makePrevLink(shorten(link.section('/', -1, -1), 20),
|
|
swordUrl(modname, link, options));
|
|
tk->nextSibling();
|
|
}
|
|
SWKey *saved = tk->clone();
|
|
if (tk->parent()) {
|
|
link = TQString::fromUtf8(module->KeyText());
|
|
navlinks += makeTreeUpLink(i18n("Up:"),
|
|
shorten(link.section('/', -1, -1), 20),
|
|
swordUrl(modname, link, options));
|
|
tk->copyFrom(*saved);
|
|
}
|
|
delete saved;
|
|
if (tk->nextSibling()) {
|
|
link = TQString::fromUtf8(module->KeyText());
|
|
navlinks += makeNextLink(shorten(link.section('/', -1, -1), 20),
|
|
swordUrl(modname, link, options));
|
|
tk->previousSibling();
|
|
}
|
|
if (tk->hasChildren()) {
|
|
if (tk->firstChild());
|
|
output += "<hr/>";
|
|
output += indexTree(module, options, false, 1);
|
|
}
|
|
}
|
|
}
|
|
|
|
if (doindex) {
|
|
output += "<h2>" + i18n("Contents:") + "</h2>";
|
|
SwordOptions options_doindex(options);
|
|
if (options.doFullTreeIndex()) {
|
|
options_doindex.doFullTreeIndex.set(false);
|
|
output += indexTree(module, options, true, -1);
|
|
output += TQString("<p><a href=\"%2\">%1</a></p>")
|
|
.arg(i18n("View simple index"))
|
|
.arg(swordUrl(modname, options_doindex));
|
|
} else {
|
|
options_doindex.doFullTreeIndex.set(true);
|
|
output += indexTree(module, options, true, 1);
|
|
output += TQString("<p><a href=\"%2\">%1</a></p>")
|
|
.arg(i18n("View full index"))
|
|
.arg(swordUrl(modname, options_doindex));
|
|
}
|
|
tmplt->setTitle(TQString("%1 - %2 - Kio-Sword").arg(tk->getShortText()).arg(module->Name()));
|
|
}
|
|
else
|
|
{
|
|
tmplt->setTitle(TQString("%1 - Kio-Sword").arg(module->Name()));
|
|
}
|
|
tmplt->setContent(output);
|
|
|
|
|
|
}
|
|
|
|
void Renderer::normalQuery(SWModule *module, const TQString &ref, const SwordOptions &options,
|
|
ModuleType modtype, Template* tmplt, TQString &navlinks) {
|
|
TQString output;
|
|
TQString modname(module->Name());
|
|
bool doindex;
|
|
SWKey *skey = module->getKey();
|
|
|
|
output += TQString("<h1 class=\"moduletitle\">%1</h1>").arg(module->Description());
|
|
|
|
if (ref.isEmpty()) {
|
|
doindex = true;
|
|
} else {
|
|
skey->Error(); // clear
|
|
skey->setText(ref.utf8());
|
|
doindex = false;
|
|
if (skey->Error()) {
|
|
output += "<p class=\"error\">" + TQString(i18n("Couldn't find reference '%1'.")).arg(ref) + "</p>";
|
|
output += "<hr>";
|
|
doindex = true;
|
|
} else {
|
|
output += TQString("<h3>%1</h3>").arg(module->KeyText());
|
|
output += renderText(module);
|
|
module->decrement();
|
|
TQString link;
|
|
if (!module->Error()) {
|
|
link = module->KeyText();
|
|
navlinks += makePrevLink(link, swordUrl(modname, link, options));
|
|
module->increment();
|
|
}
|
|
module->increment();
|
|
if (!module->Error()) {
|
|
link = module->KeyText();
|
|
navlinks += makeNextLink(link, swordUrl(modname, link, options));
|
|
module->decrement();
|
|
}
|
|
}
|
|
}
|
|
|
|
if (doindex) {
|
|
if (((modtype == LEXDICT) && options.doDictIndex()) ||
|
|
((modtype == GENERIC) && options.doOtherIndex())) {
|
|
output += "<h2>" + i18n("Index:") + "</h2>";
|
|
output += indexBook(module, options);
|
|
} else {
|
|
|
|
output += TQString("<form action='%2' method='get'>"
|
|
"%1 <input type='text' name='query'>"
|
|
"</form>")
|
|
.arg(i18n("Enter query term: "))
|
|
.arg(swordUrl(modname, options));
|
|
|
|
SwordOptions options_doindex(options);
|
|
options_doindex.doDictIndex.set(true);
|
|
options_doindex.doOtherIndex.set(true);
|
|
output += TQString("<p><a href=\"%2\">%1</a></p>")
|
|
.arg(i18n("View complete index"))
|
|
.arg(swordUrl(modname, options_doindex));
|
|
}
|
|
tmplt->setTitle(TQString("%1 - Kio-Sword").arg(module->Name()));
|
|
}
|
|
else
|
|
{
|
|
tmplt->setTitle(TQString("%1 - %2 - Kio-Sword").arg(skey->getShortText()).arg(module->Name()));
|
|
}
|
|
tmplt->setContent(output);
|
|
}
|
|
|
|
/** Retrieves an HTML list of all the books in the module
|
|
*
|
|
* @param module The module to retrieve. Must be a Bible/commentary
|
|
*/
|
|
|
|
TQString Renderer::indexBible(SWModule *module, const SwordOptions& options) {
|
|
TQString output;
|
|
char book;
|
|
char testament;
|
|
VerseKey *vk = dynamic_cast<VerseKey*>(module->getKey());
|
|
|
|
if (!vk)
|
|
return output;
|
|
vk->setLocale(LocaleMgr::getSystemLocaleMgr()->getDefaultLocaleName());
|
|
|
|
module->setSkipConsecutiveLinks(true);
|
|
vk->AutoNormalize(1);
|
|
module->setPosition(sword::TOP);
|
|
|
|
book = vk->Book();
|
|
testament = vk->Testament();
|
|
|
|
output += "<ul>\n";
|
|
while (vk->Testament() == testament) {
|
|
while (vk->Book() == book && !module->Error()) {
|
|
output += TQString("<li><a href=\"%2\">%1</a>\n")
|
|
.arg(vk->getBookName())
|
|
.arg(swordUrl(module->Name(), vk->getBookName(), options));
|
|
vk->Book(++book);
|
|
};
|
|
// Move to new testament, if not there already.
|
|
++testament;
|
|
module->setPosition(sword::BOTTOM);
|
|
book = 1;
|
|
vk->Book(book);
|
|
};
|
|
output += "</ul>\n";
|
|
module->setSkipConsecutiveLinks(false);
|
|
return output;
|
|
}
|
|
|
|
|
|
/** Retrieves an HTML list of all the keys in a module
|
|
*
|
|
* @param module The module to retrieve. Must have key type SWKey
|
|
*/
|
|
|
|
TQString Renderer::indexBook(SWModule *module, const SwordOptions& options) {
|
|
TQString output;
|
|
TQString ref;
|
|
|
|
module->setPosition(sword::TOP);
|
|
output += "<ul>\n";
|
|
do {
|
|
ref = TQString::fromUtf8(module->KeyText());
|
|
output += TQString("<li><a href=\"%2\">%1</a></li>")
|
|
.arg(ref)
|
|
.arg(swordUrl(module->Name(), ref, options));
|
|
(*module)++;
|
|
} while(!module->Error()) ;
|
|
output += "</ul>\n";
|
|
return output;
|
|
}
|
|
|
|
/** Return the index of a tree-key based module
|
|
*
|
|
* @param module The module to scan
|
|
* @param fromTop If true, get the index from the top level
|
|
* @param depth How many levels to scan, -1 for all
|
|
*/
|
|
TQString Renderer::indexTree(SWModule *module, const SwordOptions& options, bool fromTop, const int depth) {
|
|
TQString output;
|
|
TQString ref;
|
|
bool gonext;
|
|
bool cont;
|
|
|
|
TreeKey *tk = dynamic_cast<TreeKey*>(module->getKey());
|
|
int mydepth = 1;
|
|
|
|
if (!tk)
|
|
return output;
|
|
|
|
if (fromTop) {
|
|
tk->root();
|
|
tk->firstChild();
|
|
}
|
|
|
|
output += "<ul>";
|
|
cont = true;
|
|
gonext = false;
|
|
do {
|
|
if (!gonext) {
|
|
ref = TQString::fromUtf8(module->KeyText());
|
|
output += TQString("<li><a href=\"%2\">%1</a>\n")
|
|
.arg(ref.section('/', -1))
|
|
.arg(swordUrl(module->Name(), ref, options));
|
|
}
|
|
if (!gonext && tk->hasChildren() && (mydepth < depth || depth == -1) ) {
|
|
if (tk->firstChild()) {
|
|
mydepth++;
|
|
output += "<ul>";
|
|
cont = true;
|
|
} else {
|
|
cont = false;
|
|
}
|
|
} else {
|
|
if (tk->nextSibling()) {
|
|
gonext = false;
|
|
cont = true;
|
|
} else {
|
|
// try to go up a level
|
|
cont = false;
|
|
if (mydepth > 1) {
|
|
if (tk->parent()) {
|
|
mydepth--;
|
|
output += "</ul>";
|
|
cont = true;
|
|
gonext = true;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
} while (cont);
|
|
|
|
output += "</ul>";
|
|
return output;
|
|
|
|
}
|
|
|
|
TQString Renderer::chapterList(const TQString &modname, const VerseKey *vk, const SwordOptions& options) {
|
|
VerseKey cp(vk->LowerBound());
|
|
TQString output;
|
|
do {
|
|
cp.Verse(0);
|
|
if (!output.isNull()) output += " | ";
|
|
output += TQString("<a href=\"%2\">%1</a>")
|
|
.arg(cp.Chapter())
|
|
.arg(chapterLink(modname, &cp, options));
|
|
cp.Chapter(cp.Chapter()+1);
|
|
} while (cp.Chapter() <= vk->UpperBound().Chapter()) ;
|
|
return output;
|
|
}
|
|
|
|
TQString Renderer::chapterLink(const TQString &modname, const VerseKey *vk, const SwordOptions& options) {
|
|
return swordUrl(modname, bookChapter(vk), options);
|
|
}
|
|
|
|
TQString Renderer::chapterLink(const TQString &modname, const SWKey *sk, const SwordOptions& options) {
|
|
const VerseKey *vk = dynamic_cast<const VerseKey*>(sk);
|
|
if (vk)
|
|
return chapterLink(modname, vk, options);
|
|
else
|
|
return TQString::null;
|
|
}
|
|
|
|
TQString Renderer::bookLink(const TQString &modname, const VerseKey *vk, const SwordOptions& options) {
|
|
return swordUrl(modname, bookName(vk), options);
|
|
}
|
|
|
|
TQString Renderer::bookLink(const TQString &modname, const SWKey *sk, const SwordOptions& options) {
|
|
const VerseKey *vk = dynamic_cast<const VerseKey*>(sk);
|
|
if (vk)
|
|
return bookLink(modname, vk, options);
|
|
else
|
|
return TQString::null;
|
|
}
|
|
|
|
TQString Renderer::bookChapter(const VerseKey *vk) {
|
|
return TQString("%1 %2").arg(vk->getBookName()).arg(vk->Chapter());
|
|
}
|
|
|
|
TQString Renderer::bookChapter(const SWKey *sk) {
|
|
const VerseKey *vk = dynamic_cast<const VerseKey*>(sk);
|
|
if (vk)
|
|
return bookChapter(vk);
|
|
else
|
|
return TQString::null;
|
|
}
|
|
|
|
TQString Renderer::bookName(const VerseKey *vk) {
|
|
return TQString(vk->getBookName());
|
|
}
|
|
|
|
TQString Renderer::bookName(const SWKey *sk) {
|
|
const VerseKey *vk = dynamic_cast<const VerseKey*>(sk);
|
|
if (vk)
|
|
return bookName(vk);
|
|
else
|
|
return TQString::null;
|
|
}
|
|
|
|
TQStringList Renderer::availableLocales()
|
|
{
|
|
list<SWBuf> locales = LocaleMgr::getSystemLocaleMgr()->getAvailableLocales();
|
|
list<SWBuf>::const_iterator it;
|
|
list<SWBuf>::const_iterator it_end = locales.end();
|
|
TQStringList output;
|
|
for (it = locales.begin(); it != it_end; it++)
|
|
{
|
|
output.append(TQString((*it).c_str()));
|
|
}
|
|
return output;
|
|
}
|
|
}
|