6
1
Fork 0
Você não pode selecionar mais de 25 tópicos Os tópicos devem começar com uma letra ou um número, podem incluir traços ('-') e podem ter até 35 caracteres.
bibletime/bibletime/frontend/cinfodisplay.cpp

465 linhas
13 KiB

//
// C++ Implementation: cinfodisplay
//
// Description:
//
//
// Author: The BibleTime team <info@bibletime.info>, (C) 2004
//
// Copyright: See COPYING file that comes with this distribution
//
//
//BibleTime includes
#include "cinfodisplay.h"
#include "backend/cswordmoduleinfo.h"
#include "backend/cswordkey.h"
#include "backend/cswordversekey.h"
#include "backend/creferencemanager.h"
#include "backend/cdisplaytemplatemgr.h"
#include "frontend/cbtconfig.h"
#include "frontend/crossrefrendering.h"
#include "frontend/display/cdisplay.h"
#include "frontend/display/creaddisplay.h"
#include "frontend/display/chtmlreaddisplay.h"
#include "util/scoped_resource.h"
//Sword includes
#include <listkey.h>
//TQt includes
#include <tqlayout.h>
#include <tqlabel.h>
#include <tqscrollview.h>
#include <tqregexp.h>
//KDE includes
#include <tdelocale.h>
#include <kstdaction.h>
using namespace Rendering;
using namespace sword;
namespace InfoDisplay {
CInfoDisplay::CInfoDisplay(TQWidget *parent, const char *name)
: TQWidget(parent, name) {
TQVBoxLayout* layout = new TQVBoxLayout(this);
TQLabel* headingLabel = new TQLabel(i18n("Mag (\"shift\" to lock)"),this);
headingLabel->setMargin(5);
m_htmlPart = CDisplay::createReadInstance(0, this);
m_htmlPart->setMouseTracking(false); //we don't want strong/lemma/note mouse infos
KStdAction::copy(m_htmlPart->connectionsProxy(), TQT_SLOT(copySelection()), 0, "copyMagSelection");
connect(
m_htmlPart->connectionsProxy(),
TQT_SIGNAL(referenceClicked(const TQString&, const TQString&)),
TQT_SLOT(lookup(const TQString&, const TQString&))
);
layout->addWidget(headingLabel);
layout->addWidget(m_htmlPart->view());
}
CInfoDisplay::~CInfoDisplay() {}
void CInfoDisplay::lookup(const TQString &mod_name, const TQString &key_text) {
tqWarning("%s %s", mod_name.ascii(), key_text.ascii());
CSwordModuleInfo* m = CPointers::backend()->findModuleByName(mod_name);
Q_ASSERT(m);
if (!m)
return;
util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(m) );
key->key( key_text );
CDisplayTemplateMgr* mgr = CPointers::displayTemplateManager();
CDisplayTemplateMgr::Settings settings;
settings.pageCSS_ID = "infodisplay";
// settings.langAbbrev = "";
TQString content = mgr->fillTemplate(CBTConfig::get
(CBTConfig::displayStyle), key->renderedText(), settings);
// tqWarning("setting text:\n%s", content.latin1());
m_htmlPart->setText(content); // scroll to top
CHTMLReadDisplay *d = dynamic_cast<CHTMLReadDisplay *>(m_htmlPart);
d->view()->ensureVisible(0, 0);
}
void CInfoDisplay::setInfo(const InfoType type, const TQString& data) {
ListInfoData list;
list.append( tqMakePair(type, data) );
setInfo(list);
}
void CInfoDisplay::setInfo(const ListInfoData& list) {
//if the widget is hidden it would be inefficient to render and display the data
if (!isVisible()) {
return;
}
if (list.count() == 0) {
m_htmlPart->setText("<html></html>");
return;
}
TQString text;
ListInfoData::const_iterator end = list.end();
for (ListInfoData::const_iterator it = list.begin(); it != end; ++it) {
switch ( (*it).first ) {
case Lemma:
text.append( decodeStrongs( (*it).second ) );
continue;
case Morph:
text.append( decodeMorph( (*it).second ) );
continue;
case CrossReference:
text.append( decodeCrossReference( (*it).second ) );
continue;
case Footnote:
text.append( decodeFootnote( (*it).second ) );
continue;
case WordTranslation:
text.append( getWordTranslation( (*it).second ) );
continue;
case WordGloss:
//text.append( getWordTranslation( (*it).second ) );
continue;
case Abbreviation:
text.append( decodeAbbreviation( (*it).second ) );
continue;
default:
continue;
};
}
CDisplayTemplateMgr* mgr = CPointers::displayTemplateManager();
CDisplayTemplateMgr::Settings settings;
settings.pageCSS_ID = "infodisplay";
// settings.langAbbrev = "";
TQString content = mgr->fillTemplate(CBTConfig::get
(CBTConfig::displayStyle), text, settings);
// tqWarning("setting text:\n%s", content.latin1());
m_htmlPart->setText(content);
}
const TQString CInfoDisplay::decodeAbbreviation( const TQString& data ) {
// TQStringList strongs = TQStringList::split("|", data);
TQString ret;
TQString text = data;
ret.append(
TQString("<div class=\"abbreviation\"><h3>%1: %2</h3><p>%3</p></div>")
.arg(i18n("Abbreviation"))
.arg("text")
.arg(text));
return ret;
}
const TQString CInfoDisplay::decodeCrossReference( const TQString& data ) {
Q_ASSERT(!data.isEmpty());
if (data.isEmpty()) {
return TQString("<div class=\"crossrefinfo\"><h3>%1</h3></div>")
.arg(i18n("Cross references"));
}
// tqWarning("setting crossref %s", data.latin1());
CSwordBackend::DisplayOptions dispOpts;
dispOpts.lineBreaks = false;
dispOpts.verseNumbers = true;
CSwordBackend::FilterOptions filterOpts;
filterOpts.headings = false;
filterOpts.strongNumbers = false;
filterOpts.morphTags = false;
filterOpts.lemmas = false;
filterOpts.footnotes = false;
filterOpts.scriptureReferences = false;
CrossRefRendering renderer(dispOpts, filterOpts);
CTextRendering::KeyTree tree;
// const bool isBible = true;
CSwordModuleInfo* module = CBTConfig::get
(CBTConfig::standardBible);
//a prefixed module gives the module to look into
TQRegExp re("^[^ ]+:");
// re.setMinimal(true);
int pos = re.search(data,0);
if (pos != -1) {
pos += re.matchedLength()-1;
}
if (pos > 0) {
const TQString moduleName = data.left(pos);
// tqWarning("found module %s", moduleName.latin1());
module = CPointers::backend()->findModuleByName(moduleName);
if (!module) {
module = CBTConfig::get
(CBTConfig::standardBible);
}
// Q_ASSERT(module);
}
Q_ASSERT(module);
CTextRendering::KeyTreeItem::Settings settings (
false,
CTextRendering::KeyTreeItem::Settings::CompleteShort
);
if (module && (module->type() == CSwordModuleInfo::Bible)) {
VerseKey vk;
sword::ListKey refs = vk.ParseVerseList((const char*)data.mid((pos == -1) ? 0 : pos+1).utf8(), "Gen 1:1", true);
for (int j = 0; j < refs.Count(); ++j) {
SWKey* key = refs.getElement(j);
Q_ASSERT(key);
VerseKey* vk = dynamic_cast<VerseKey*>(key);
CTextRendering::KeyTreeItem* i = 0;
if (vk && vk->isBoundSet()) { //render a range of keys
i = new CTextRendering::KeyTreeItem(
TQString::fromUtf8(vk->LowerBound().getText()),
TQString::fromUtf8(vk->UpperBound().getText()),
module,
settings
);
}
else {
i = new CTextRendering::KeyTreeItem(
TQString::fromUtf8(key->getText()),
TQString::fromUtf8(key->getText()),
module,
settings
);
}
Q_ASSERT(i);
tree.append( i );
}
}
else if (module) {
CTextRendering::KeyTreeItem* i = new CTextRendering::KeyTreeItem(
data.mid((pos == -1) ? 0 : pos+1),
module,
settings
);
tree.append( i );
}
// tqWarning("rendered the tree: %s", renderer.renderKeyTree(tree).latin1());
//spanns containing rtl text need dir=rtl on their parent tag to be aligned properly
return TQString("<div class=\"crossrefinfo\"><h3>%1</h3><div class=\"para\" dir=\"%2\">%3</div></div>")
.arg(i18n("Cross references"))
.arg(module ? ((module->textDirection() == CSwordModuleInfo::LeftToRight) ? "ltr" : "rtl") : "")
.arg(renderer.renderKeyTree(tree));
}
/*!
\fn CInfoDisplay::decodeFootnote( const TQString& data )
*/
const TQString CInfoDisplay::decodeFootnote( const TQString& data ) {
TQStringList list = TQStringList::split("/", data);
Q_ASSERT(list.count() >= 3);
if (!list.count()) {
return TQString();
}
const TQString modulename = list.first();
const TQString swordFootnote = list.last();
// remove the first and the last and then rejoin it to get a key
list.pop_back(); list.pop_front();
const TQString keyname = list.join("/");
CSwordModuleInfo* module = CPointers::backend()->findModuleByName(modulename);
if (!module) {
return TQString();
}
util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) );
key->key(keyname);
key->renderedText(); //force entryAttributes
const char* note = module->module()->getEntryAttributes()["Footnote"][swordFootnote.latin1()]["body"].c_str();
TQString text = module->isUnicode() ? TQString::fromUtf8(note) : TQString(note);
text = TQString::fromUtf8(module->module()->RenderText(
module->isUnicode()
? (const char*)text.utf8()
: (const char*)text.latin1()
));
return TQString("<div class=\"footnoteinfo\"><h3>%1</h3><p>%2</p></div>")
.arg(i18n("Footnote"))
.arg(text);
}
const TQString CInfoDisplay::decodeStrongs( const TQString& data ) {
TQStringList strongs = TQStringList::split("|", data);
TQString ret;
TQStringList::const_iterator end = strongs.end();
for (TQStringList::const_iterator it = strongs.begin(); it != end; ++it) {
CSwordModuleInfo* const module = CBTConfig::get
(
((*it).left(1) == TQString("H")) ?
CBTConfig::standardHebrewStrongsLexicon :
CBTConfig::standardGreekStrongsLexicon
);
TQString text;
if (module) {
util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) );
key->key( (*it).mid(1) ); //skip H or G (language sign), will have to change later if we have better modules
text = key->renderedText();
}
//if the module could not be found just display an empty lemma info
ret.append(
TQString("<div class=\"strongsinfo\"><h3>%1: %2</h3><p>%3</p></div>")
.arg(i18n("Strongs"))
.arg(*it)
.arg(text)
);
}
return ret;
}
const TQString CInfoDisplay::decodeMorph( const TQString& data ) {
TQStringList morphs = TQStringList::split("|", data);
TQString ret;
for (TQStringList::iterator it = morphs.begin(); it != morphs.end(); ++it) {
CSwordModuleInfo* module = 0;
bool skipFirstChar = false;
TQString value = "";
TQString valueClass = "";
int valStart = (*it).find(':');
if (valStart > -1) {
valueClass = (*it).mid(0, valStart);
module = CPointers::backend()->findModuleByName( valueClass );
Q_ASSERT(module);
}
value = (*it).mid(valStart+1); //works for prepended module and without (-1 +1 == 0).
// if we don't have a class assigned or desired one isn't installed...
if (!module) {
// Morphs usually don't have [GH] prepended, but some old OLB
// codes do. We should check if we're digit after first char
// to better guess this.
// No need to check len, if at(1) is > len TQChar::null is
// returned which is ok to .isDigit()
if (value.at(1).isDigit()) {
switch (value.at(0).latin1()) {
case 'G':
module = CBTConfig::get
(CBTConfig::standardGreekMorphLexicon);
skipFirstChar = true;
break;
case 'H':
module = CBTConfig::get
(CBTConfig::standardHebrewMorphLexicon);
skipFirstChar = true;
break;
default:
skipFirstChar = false;
//TODO: we can't tell here if it's a greek or hebrew moprh code, that's a problem we have to solve
// module = CBTConfig::get(CBTConfig::standardGreekMorphLexicon);
break;
}
}
//if it is still not set use the default
if (!module) {
module = CBTConfig::get
(CBTConfig::standardGreekMorphLexicon);
}
}
TQString text;
Q_ASSERT(module);
if (module) {
util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) );
//skip H or G (language sign) if we have to skip it
const bool isOk = key->key( skipFirstChar ? value.mid(1) : value );
Q_ASSERT(isOk);
if (!isOk) { //try to use the other morph lexicon, because this one failed with the current morph code
key->module(CBTConfig::get
(CBTConfig::standardHebrewMorphLexicon));
key->key( skipFirstChar ? value.mid(1) : value );
}
text = key->renderedText();
}
//if the module wasn't found just display an empty morph info
ret.append( TQString("<div class=\"morphinfo\"><h3>%1: %2</h3><p>%3</p></div>")
.arg(i18n("Morphology"))
.arg(value)
.arg(text)
);
}
return ret;
}
const TQString CInfoDisplay::getWordTranslation( const TQString& data ) {
CSwordModuleInfo* const module = CBTConfig::get
(CBTConfig::standardLexicon);
if (!module) {
return TQString();
}
util::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) );
key->key( data );
if (key->key().upper() != data.upper()) { //key not present in the lexicon
return TQString();
}
TQString ret = TQString("<div class=\"translationinfo\"><h3>%1: %2</h3><p>%3</p></div>")
.arg(i18n("Word lookup"))
.arg(data)
.arg(key->renderedText());
return ret;
}
/*!
\fn CInfoDisplay::clearInfo()
*/
void CInfoDisplay::clearInfo() {
CDisplayTemplateMgr* tmgr = CPointers::displayTemplateManager();
CDisplayTemplateMgr::Settings settings;
settings.pageCSS_ID = "infodisplay";
m_htmlPart->setText( tmgr->fillTemplate(CBTConfig::get
(CBTConfig::displayStyle), TQString(), settings) );
}
} //end of namespace InfoDisplay
#include "cinfodisplay.moc"