void BtInstallThread::removeModule() { qDebug() << "BtInstallThread::removeModule start"; CSwordModuleInfo* m; m = CPointers::backend()->findModuleByName(m_module); if (!m) { m = instbackend::backend(instbackend::source(m_destination.toLatin1()))->findModuleByName(m_module); } if (m) { //module found? qDebug() << "BtInstallThread::removeModule, module" << m_module << "found"; QString prefixPath = m->config(CSwordModuleInfo::AbsoluteDataPath) + "/"; QString dataPath = m->config(CSwordModuleInfo::DataPath); if (dataPath.left(2) == "./") { dataPath = dataPath.mid(2); } if (prefixPath.contains(dataPath)) { prefixPath.remove( prefixPath.indexOf(dataPath), dataPath.length() ); } else { prefixPath = QString::fromLatin1(CPointers::backend()->prefixPath); } sword::SWMgr mgr(prefixPath.toLatin1()); BtInstallMgr iMgr; iMgr.removeModule(&mgr, m->name().toLatin1()); } else { qDebug() << "BtInstallThread::removeModule, module" << m_module << "not found"; } }
void CInfoDisplay::lookupInfo(const QString &mod_name, const QString &key_text) { qDebug("CInfoDisplay::lookup"); qDebug() << mod_name << key_text; CSwordModuleInfo* m = CPointers::backend()->findModuleByName(mod_name); Q_ASSERT(m); if (!m) return; boost::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(m) ); key->key( key_text ); CDisplayTemplateMgr* mgr = CPointers::displayTemplateManager(); CDisplayTemplateMgr::Settings settings; settings.pageCSS_ID = "infodisplay"; // lookup text and wrap in a "div" with language set to module language QString lang = m->language()->abbrev(); QString renderedText = key->renderedText(); QString divText = "<div class=\"infodisplay\" lang=\""; divText.append(lang); divText.append("\">"); divText.append(renderedText); divText.append("</div>"); QString content = mgr->fillTemplate(CBTConfig::get (CBTConfig::displayStyle), divText, settings); m_htmlPart->setText(content); }
QString ModuleInterface::module(int index) { if (index < 0 || index >= m_modules.count()) return ""; CSwordModuleInfo* module = m_modules.at(index); if (module == 0) return ""; return module->name(); }
void BtBookshelfDockWidget::slotPrepareItemContextMenu() { void *v = m_itemContextMenu->property("BtModule").value<void*>(); CSwordModuleInfo *module = static_cast<CSwordModuleInfo*>(v); m_itemOpenAction->setEnabled(!module->isLocked()); m_itemSearchAction->setText(tr("&Search in %1...").arg(module->name())); m_itemSearchAction->setEnabled(!module->isLocked()); m_itemUnlockAction->setEnabled(module->isLocked()); }
QString ModuleInterface::englishCategory(int index) { if (index < 0 || index >= m_modules.count()) return ""; CSwordModuleInfo* module = m_modules.at(index); if (module == 0) return ""; CSwordModuleInfo::Category category = module->category(); if (category == 0) return ""; return module->englishCategoryName(category); }
QString ModuleInterface::language(int index) { if (index < 0 || index >= m_modules.count()) return ""; CSwordModuleInfo* module = m_modules.at(index); if (module == 0) return ""; const CLanguageMgr::Language* language = module->language(); if (language == 0) return ""; return language->translatedName(); }
void ModuleInterface::unlock(const QString& moduleName, const QString& unlockKey) { CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); if (module) { module->unlock(unlockKey); // Re-initialize module pointers: CSwordBackend *backend = CSwordBackend::instance(); backend->reloadModules(CSwordBackend::OtherChange); module = CSwordBackend::instance()->findModuleByName(moduleName); updateWorksModel(); } }
/** Prints a key using the hyperlink created by CReferenceManager. */ bool CExportManager::printByHyperlink( const QString& hyperlink, CSwordBackend::DisplayOptions displayOptions, CSwordBackend::FilterOptions filterOptions ) { QString moduleName; QString keyName; CReferenceManager::Type type; CReferenceManager::decodeHyperlink(hyperlink, moduleName, keyName, type); if (moduleName.isEmpty()) { moduleName = CReferenceManager::preferredModule(type); } CPrinter::KeyTree tree; CPrinter::KeyTreeItem::Settings settings; settings.keyRenderingFace = displayOptions.verseNumbers ? CPrinter::KeyTreeItem::Settings::SimpleKey : CPrinter::KeyTreeItem::Settings::NoKey; CSwordModuleInfo* module = backend()->findModuleByName(moduleName); Q_ASSERT(module); if (module) { //check if we have a range of entries or a single one if ((module->type() == CSwordModuleInfo::Bible) || (module->type() == CSwordModuleInfo::Commentary)) { sword::ListKey verses = sword::VerseKey().ParseVerseList((const char*)keyName.toUtf8(), "Genesis 1:1", true); for (int i = 0; i < verses.Count(); ++i) { sword::VerseKey* element = dynamic_cast<sword::VerseKey*>(verses.GetElement(i)); if (element) { const QString startKey = QString::fromUtf8(element->LowerBound().getText()); const QString stopKey = QString::fromUtf8(element->UpperBound().getText()); tree.append( new CPrinter::KeyTreeItem(startKey, stopKey, module, settings) ); } else if (verses.GetElement(i)) { const QString key = QString::fromUtf8(verses.GetElement(i)->getText()); tree.append( new CPrinter::KeyTreeItem(key, module, settings) ); } } } else { tree.append( new CPrinter::KeyTreeItem(keyName, module, settings) ); } } boost::scoped_ptr<CPrinter> printer(new CPrinter(0, displayOptions, filterOptions)); printer->printKeyTree(tree); return true; }
bool ModuleInterface::isLocked(const QString& moduleName) { CSwordModuleInfo* module = CSwordBackend::instance()->findModuleByName(moduleName); if (module) { // Verse intros must be false for checking lock if (module->type() == CSwordModuleInfo::Bible || module->type() == CSwordModuleInfo::Commentary) { ((sword::VerseKey*)(module->module()->getKey()))->setIntros(false); } bool locked = module->isLocked(); return locked; } return false; }
void BtInstallThread::removeTempFiles() { qDebug("BtInstallThread::removeTempFiles start"); // (take the remote conf file for this module, take DataPath, // take the absolute path of the InstallMgr) //sword::InstallSource is = instbackend::source(m_source); if (instbackend::isRemote(*m_installSource)) { // get the path for the module temp files CSwordModuleInfo* mInfo = m_backendForSource->findModuleByName(m_module); QString dataPath = mInfo->config(CSwordModuleInfo::AbsoluteDataPath); qDebug() << "Delete path:" << dataPath; // it's easier to use sword than qt sword::FileMgr::removeDir(dataPath.toLatin1().data()); } }
const QString Rendering::CChapterDisplay::text( const QList<CSwordModuleInfo*>& modules, const QString& keyName, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions ) { Q_ASSERT( modules.count() >= 1 ); Q_ASSERT( !keyName.isEmpty() ); CSwordModuleInfo* module = modules.first(); if (modules.count() == 1) module->module()->setSkipConsecutiveLinks( true ); //skip empty, linked verses CTextRendering::KeyTreeItem::Settings settings; settings.keyRenderingFace = displayOptions.verseNumbers ? CTextRendering::KeyTreeItem::Settings::SimpleKey : CTextRendering::KeyTreeItem::Settings::NoKey; QString startKey = keyName; QString endKey = startKey; //check whether there's an intro we have to include Q_ASSERT((module->type() == CSwordModuleInfo::Bible)); if (module->type() == CSwordModuleInfo::Bible) { ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys CSwordBibleModuleInfo* bible = dynamic_cast<CSwordBibleModuleInfo*>(module); Q_ASSERT(bible); CSwordVerseKey k1(module); k1.Headings(1); k1.key(keyName); if (k1.Chapter() == 1) k1.Chapter(0); //Chapter 1, start with 0:0, otherwise X:0 k1.Verse(0); startKey = k1.key(); if (k1.Chapter() == 0) k1.Chapter(1); k1.Verse(bible->verseCount(k1.book(), k1.Chapter())); endKey = k1.key(); } CDisplayRendering render(displayOptions, filterOptions); return render.renderKeyRange( startKey, endKey, modules, keyName, settings ); }
/** Deletes indices for selected modules */ void BtIndexPage::deleteIndices() { bool indicesDeleted = false; for (int i = 0; i < m_modsWithIndices->childCount(); i++) { if (m_modsWithIndices->child(i)->checkState(0) == Qt::Checked) { CSwordModuleInfo* module = CPointers::backend()->findModuleByName(m_modsWithIndices->child(i)->text(0).toUtf8()); if (module) { CSwordModuleInfo::deleteIndexForModule( module->name() ); indicesDeleted = true; } } } // repopulate the list if an action was taken if (indicesDeleted) { populateModuleList(); } }
static void searchProgress(char percent, void *data) { typedef QPair<BtMiniMenu*, CSwordModuleInfo*> Pair; Pair *p = reinterpret_cast<Pair*>(data); if(!p) return; BtMiniMenu *dialog = p->first; CSwordModuleInfo *m = p->second; if(dialog && m) { if(dialog->wasCanceled()) m->module()->terminateSearch = true; dialog->setValue(percent); } }
void BtIndexPage::deleteOrphanedIndices() { QDir dir(CSwordModuleInfo::getGlobalBaseIndexLocation()); dir.setFilter(QDir::Dirs); CSwordModuleInfo* module; for (unsigned int i = 0; i < dir.count(); i++) { if (dir[i] != "." && dir[i] != "..") { if ( (module = CPointers::backend()->findModuleByName(dir[i])) ) { //mod exists if (!module->hasIndex()){ //index files found, but wrong version etc. CSwordModuleInfo::deleteIndexForModule( dir[i] ); } } else{ //no module exists if (CBTConfig::get( CBTConfig::autoDeleteOrphanedIndices ) ){ CSwordModuleInfo::deleteIndexForModule( dir[i] ); } } } } }
/** Returns the rendered text using the modules in the list and using the key parameter. * The displayoptions and filter options are used, too. */ const QString CEntryDisplay::text( const QList<CSwordModuleInfo*>& modules, const QString& keyName, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions ) { CDisplayRendering render(displayOptions, filterOptions); //no highlighted key and no extra key link in the text CTextRendering::KeyTreeItem::Settings normal_settings(false, CTextRendering::KeyTreeItem::Settings::CompleteShort); CSwordModuleInfo* module = modules.first(); Rendering::CTextRendering::KeyTree tree; //in Bibles and Commentaries we need to check if 0:0 and X:0 contain something if (module->type() == CSwordModuleInfo::Bible || module->type() == CSwordModuleInfo::Commentary) { ((sword::VerseKey*)(module->module()->getKey()))->Headings(1); //HACK: enable headings for VerseKeys CSwordVerseKey k1(module); k1.Headings(1); k1.key(keyName); // don't print the key CTextRendering::KeyTreeItem::Settings preverse_settings(false, CTextRendering::KeyTreeItem::Settings::NoKey); if (k1.Verse() == 1) { //X:1, prepend X:0 if (k1.Chapter() == 1) { //1:1, also prepend 0:0 before that k1.Chapter(0); k1.Verse(0); if ( k1.rawText().length() > 0 ) { tree.append( new Rendering::CTextRendering::KeyTreeItem(k1.key(), modules, preverse_settings) ); } k1.Chapter(1); } k1.Verse(0); if ( k1.rawText().length() > 0 ) { tree.append( new Rendering::CTextRendering::KeyTreeItem(k1.key(), modules, preverse_settings) ); } } } tree.append( new Rendering::CTextRendering::KeyTreeItem(keyName, modules, normal_settings) ); QString result(render.renderKeyTree(tree)); qDeleteAll(tree); return result; }
void BtInstallThread::removeModule() { CSwordModuleInfo* m = CPointers::backend()->findModuleByName(m_module); if (m) { //module found? QString prefixPath = m->config(CSwordModuleInfo::AbsoluteDataPath) + "/"; QString dataPath = m->config(CSwordModuleInfo::DataPath); if (dataPath.left(2) == "./") { dataPath = dataPath.mid(2); } if (prefixPath.contains(dataPath)) { prefixPath.remove( prefixPath.indexOf(dataPath), dataPath.length() ); } else { prefixPath = QString::fromLatin1(CPointers::backend()->prefixPath); } sword::SWMgr mgr(prefixPath.toLatin1()); //BtInstallMgr iMgr; //TODO: use SWModule name, see also removepage m_iMgr.removeModule(&mgr, m->name().toLatin1()); } }
void ModuleInterface::updateWorksModel() { m_worksModel.clear(); m_modules.clear(); QString currentLang = currentLanguage(); QString currentCat = currentCategory(); QHash<int, QByteArray> roleNames; roleNames[TextRole] = "modelText"; m_worksModel.setRoleNames(roleNames); BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model(); if (bookshelfModel == 0) return; int count = bookshelfModel->rowCount(); for (int row=0; row<count; ++row) { QModelIndex index = bookshelfModel->index(row); CSwordModuleInfo* module = getModule(bookshelfModel, index); CSwordModuleInfo::Category category = module->category(); QString categoryName = module->categoryName(category); const CLanguageMgr::Language* language = module->language(); QString languageName = language->translatedName(); if (languageName == currentLang && categoryName == currentCat) { m_modules << module; QString moduleName = module->name(); QStandardItem* item = new QStandardItem(); item->setData(moduleName, TextRole); m_worksModel.appendRow(item); } } QQuickItem* object = findQmlObject("moduleChooser"); if (object == 0) return; object->setProperty("worksModel", QVariant::fromValue(&m_worksModel)); }
void ModuleInterface::getCategoriesAndLanguages() { m_categories.clear(); m_languages.clear(); QQuickItem* object = findQmlObject("moduleChooser"); if (object == 0) return; BtBookshelfModel* bookshelfModel = CSwordBackend::instance()->model(); if (bookshelfModel == 0) return; int count = bookshelfModel->rowCount(); for (int row=0; row<count; ++row) { QModelIndex index = bookshelfModel->index(row); CSwordModuleInfo* module = getModule(bookshelfModel, index); CSwordModuleInfo::Category category = module->category(); QString categoryName = module->categoryName(category); const CLanguageMgr::Language* language = module->language(); QString languageName = language->translatedName(); m_categories.insert(categoryName); m_languages.insert(languageName); } }
void Filters::BT_OSISHTML::renderReference(const char *osisRef, sword::SWBuf &buf, sword::SWModule *myModule, BT_UserData *myUserData) { QString ref( osisRef ); QString hrefRef( ref ); //Q_ASSERT(!ref.isEmpty()); checked later if (!ref.isEmpty()) { //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. //If the osisRef is something like "ModuleID:key comes here" then the // modulename is given, so we'll use that one CSwordModuleInfo* mod = CPointers::backend()->findSwordModuleByPointer(myModule); //Q_ASSERT(mod); checked later if (!mod || (mod->type() != CSwordModuleInfo::Bible && mod->type() != CSwordModuleInfo::Commentary)) { mod = CBTConfig::get( CBTConfig::standardBible ); } // Q_ASSERT(mod); There's no necessarily a module or standard Bible //if the osisRef like "GerLut:key" contains a module, use that int pos = ref.indexOf(":"); if ((pos >= 0) && ref.at(pos-1).isLetter() && ref.at(pos+1).isLetter()) { QString newModuleName = ref.left(pos); hrefRef = ref.mid(pos+1); if (CPointers::backend()->findModuleByName(newModuleName)) { mod = CPointers::backend()->findModuleByName(newModuleName); } } if (mod) { CReferenceManager::ParseOptions options; options.refBase = QString::fromUtf8(myUserData->key->getText()); options.refDestinationModule = QString(mod->name()); options.sourceLanguage = QString(myModule->Lang()); options.destinationLanguage = QString("en"); buf.append("<a href=\""); buf.append( //create the hyperlink with key and mod CReferenceManager::encodeHyperlink( mod->name(), CReferenceManager::parseVerseReference(hrefRef, options), CReferenceManager::typeFromModule(mod->type()) ).toUtf8().constData() ); buf.append("\" crossrefs=\""); buf.append((const char*)CReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any buf.append("\">"); } // should we add something if there were no referenced module available? } }
QString remoteModuleToolTip(const CSwordModuleInfo & module, const QString & localVer) { QString text = "<p style='white-space:pre'><b>"; text += module.name(); text += "</b> "; if (module.category() == CSwordModuleInfo::Cult) { text += "<small><b>"; text += QObject::tr("Take care, this work contains cult / questionable " "material!"); text += "</b></small><br/>"; } text += "<small>("; text += module.config(CSwordModuleInfo::Description); text += ")</small><hr/>"; if (module.isEncrypted()) { text += QObject::tr("Encrypted - needs unlock key"); text += "<br/>"; } if (!localVer.isEmpty()) { text += "<b>"; text += QObject::tr("Updated version available!"); text += "</b><br/>"; } if (module.hasVersion()) { text += QObject::tr("Version"); text += ": "; text += module.config(CSwordModuleInfo::ModuleVersion); } // if installed already if (!localVer.isEmpty()) { text += " "; text += QObject::tr("Installed version"); text += ": "; text += localVer; } text += "<br/><small>("; text += QObject::tr("Double click for more information"); text += ")</small></p>"; return text; }
/*! \fn CInfoDisplay::decodeFootnote( const QString& data ) */ const QString CInfoDisplay::decodeFootnote( const QString& data ) { QStringList list = data.split("/"); Q_ASSERT(list.count() >= 3); if (!list.count()) { return QString::null; } const QString modulename = list.first(); const QString swordFootnote = list.last(); // remove the first and the last and then rejoin it to get a key list.pop_back(); list.pop_front(); const QString keyname = list.join("/"); CSwordModuleInfo* module = CPointers::backend()->findModuleByName(modulename); if (!module) { return QString::null; } boost::scoped_ptr<CSwordKey> key( CSwordKey::createInstance(module) ); key->key(keyname); key->renderedText(); //force entryAttributes const char* note = module->module()->getEntryAttributes() ["Footnote"][swordFootnote.toLatin1().data()]["body"].c_str(); QString text = module->isUnicode() ? QString::fromUtf8(note) : QString(note); text = QString::fromUtf8(module->module()->RenderText( module->isUnicode() ? (const char*)text.toUtf8() : (const char*)text.toLatin1() )); return QString("<div class=\"footnoteinfo\" lang=\"%1\"><h3>%2</h3><p>%3</p></div>") .arg(module->language()->abbrev()) .arg(tr("Footnote")) .arg(text); }
void BtSearchResultArea::updatePreview(const QString& key) { using namespace Rendering; CSwordModuleInfo* module = m_moduleListBox->activeModule(); if ( module ) { const QString searchedText = CSearchDialog::getSearchDialog()->searchText(); QString text; CDisplayRendering render; BtConstModuleList modules; modules.append(module); CTextRendering::KeyTreeItem::Settings settings; //for bibles render 5 context verses if (module->type() == CSwordModuleInfo::Bible) { CSwordVerseKey vk(module); vk.setIntros(true); vk.setKey(key); // HACK: enable headings for VerseKeys: static_cast<sword::VerseKey *>(module->module()->getKey()) ->setIntros(true); //first go back and then go forward the keys to be in context vk.previous(CSwordVerseKey::UseVerse); vk.previous(CSwordVerseKey::UseVerse); //include Headings in display, they are indexed and searched too if (vk.getVerse() == 1) { if (vk.getChapter() == 1) { vk.setChapter(0); } vk.setVerse(0); } const QString startKey = vk.key(); vk.setKey(key); vk.next(CSwordVerseKey::UseVerse); vk.next(CSwordVerseKey::UseVerse); const QString endKey = vk.key(); settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::CompleteShort; text = render.renderKeyRange(startKey, endKey, modules, key, settings); } //for commentaries only one verse, but with heading else if (module->type() == CSwordModuleInfo::Commentary) { CSwordVerseKey vk(module); vk.setIntros(true); vk.setKey(key); // HACK: enable headings for VerseKeys: static_cast<sword::VerseKey *>(module->module()->getKey()) ->setIntros(true); //include Headings in display, they are indexed and searched too if (vk.getVerse() == 1) { if (vk.getChapter() == 1) { vk.setChapter(0); } vk.setVerse(0); } const QString startKey = vk.key(); vk.setKey(key); const QString endKey = vk.key(); settings.keyRenderingFace = CTextRendering::KeyTreeItem::Settings::NoKey; text = render.renderKeyRange(startKey, endKey, modules, key, settings); } else { text = render.renderSingleKey(key, modules, settings); } m_previewDisplay->setText( CSwordModuleSearch::highlightSearchedText(text, searchedText) ); m_previewDisplay->moveToAnchor( CDisplayRendering::keyToHTMLAnchor(key) ); } }
char Filters::BT_ThMLHTML::processText(sword::SWBuf& buf, const sword::SWKey* key, const sword::SWModule* module) { sword::ThMLHTML::processText(buf, key, module); CSwordModuleInfo* m = CPointers::backend()->findModuleByName( module->Name() ); if (m && !(m->has(CSwordModuleInfo::lemmas) || m->has(CSwordModuleInfo::strongNumbers))) { //only parse if the module has strongs or lemmas return 1; } QString result; QString t = QString::fromUtf8(buf.c_str()); QRegExp tag("([.,;]?<sync[^>]+(type|value)=\"([^\"]+)\"[^>]+(type|value)=\"([^\"]+)\"([^<]*)>)+"); QStringList list; int lastMatchEnd = 0; int pos = tag.indexIn(t,0); if (pos == -1) { //no strong or morph code found in this text return 1; //WARNING: Return alread here } while (pos != -1) { list.append(t.mid(lastMatchEnd, pos+tag.matchedLength()-lastMatchEnd)); lastMatchEnd = pos+tag.matchedLength(); pos = tag.indexIn(t,pos+tag.matchedLength()); } if (!t.right(t.length() - lastMatchEnd).isEmpty()) { list.append(t.right(t.length() - lastMatchEnd)); } tag = QRegExp("<sync[^>]+(type|value|class)=\"([^\"]+)\"[^>]+(type|value|class)=\"([^\"]+)\"[^>]+((type|value|class)=\"([^\"]+)\")*([^<]*)>"); for (QStringList::iterator it = list.begin(); it != list.end(); ++it) { QString e( *it ); const bool textPresent = (e.trimmed().remove(QRegExp("[.,;:]")).left(1) != "<"); if (!textPresent) { continue; } bool hasLemmaAttr = false; bool hasMorphAttr = false; int pos = tag.indexIn(e, 0); bool insertedTag = false; QString value; QString valueClass; while (pos != -1) { bool isMorph = false; bool isStrongs = false; value = QString::null; valueClass = QString::null; // check 3 attribute/value pairs for (int i = 1; i < 6; i += 2) { if (i > 4) i++; if (tag.cap(i) == "type") { isMorph = (tag.cap(i+1) == "morph"); isStrongs = (tag.cap(i+1) == "Strongs"); } else if (tag.cap(i) == "value") { value = tag.cap(i+1); } else if (tag.cap(i) == "class") { valueClass = tag.cap(i+1); } } // prepend the class qualifier to the value if (!valueClass.isEmpty()) { value = valueClass + ":" + value; // value.append(":").append(value); } if (value.isEmpty()) { break; } //insert the span if (!insertedTag) { e.replace(pos, tag.matchedLength(), "</span>"); pos += 7; QString rep = QString("<span lemma=\"").append(value).append("\">"); int startPos = 0; QChar c = e[startPos]; while ((startPos < pos) && (c.isSpace() || c.isPunct())) { ++startPos; c = e[startPos]; } hasLemmaAttr = isStrongs; hasMorphAttr = isMorph; e.insert( startPos, rep ); pos += rep.length(); } else { //add the attribute to the existing tag e.remove(pos, tag.matchedLength()); if ((!isMorph && hasLemmaAttr) || (isMorph && hasMorphAttr)) { //we append another attribute value, e.g. 3000 gets 3000|5000 //search the existing attribute start QRegExp attrRegExp( isMorph ? "morph=\".+(?=\")" : "lemma=\".+(?=\")" ); attrRegExp.setMinimal(true); const int foundAttrPos = e.indexOf(attrRegExp, pos); if (foundAttrPos != -1) { e.insert(foundAttrPos + attrRegExp.matchedLength(), QString("|").append(value)); pos += value.length() + 1; hasLemmaAttr = !isMorph; hasMorphAttr = isMorph; } } else { //attribute was not yet inserted const int attrPos = e.indexOf(QRegExp("morph=|lemma="), 0); if (attrPos >= 0) { QString attr; attr.append(isMorph ? "morph" : "lemma").append("=\"").append(value).append("\" "); e.insert(attrPos, attr); hasMorphAttr = isMorph; hasLemmaAttr = !isMorph; pos += attr.length(); } } } insertedTag = true; pos = tag.indexIn(e, pos); } result.append( e ); } if (list.count()) { buf = (const char*)result.toUtf8(); } return 1; }
bool Filters::BT_ThMLHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { if (!substituteToken(buf, token) && !substituteEscapeString(buf, token)) { sword::XMLTag tag(token); BT_UserData* myUserData = dynamic_cast<BT_UserData*>(userData); sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack to be able to call stuff like Lang() if ( tag.getName() && !sword::stricmp(tag.getName(), "foreign") ) { // a text part in another language, we have to set the right font if (tag.getAttribute("lang")) { const char* abbrev = tag.getAttribute("lang"); //const CLanguageMgr::Language* const language = CPointers::languageMgr()->languageForAbbrev( QString::fromLatin1(abbrev) ); buf.append("<span class=\"foreign\" lang=\""); buf.append(abbrev); buf.append("\">"); } } else if (tag.getName() && !sword::stricmp(tag.getName(), "sync")) { //lemmas, morph codes or strongs if (tag.getAttribute("type") && (!sword::stricmp(tag.getAttribute("type"), "morph") || !sword::stricmp(tag.getAttribute("type"), "Strongs") || !sword::stricmp(tag.getAttribute("type"), "lemma"))) { // Morph or Strong buf.append('<'); buf.append(token); buf.append('>'); } } else if (tag.getName() && !sword::stricmp(tag.getName(), "note")) { // <note> tag if (!tag.isEndTag() && !tag.isEmpty()) { //appending is faster than appendFormatted buf.append(" <span class=\"footnote\" note=\""); buf.append(myModule->Name()); buf.append('/'); buf.append(myUserData->key->getShortText()); buf.append('/'); buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); buf.append("\">*</span> "); myUserData->suspendTextPassThru = true; myUserData->inFootnoteTag = true; } else if (tag.isEndTag() && !tag.isEmpty()) { //end tag //buf += ")</span>"; myUserData->suspendTextPassThru = false; myUserData->inFootnoteTag = false; } } else if (tag.getName() && !sword::stricmp(tag.getName(), "scripRef")) { // a scripRef //scrip refs which are embeded in footnotes may not be displayed! if (!myUserData->inFootnoteTag) { if (tag.isEndTag()) { if (myUserData->inscriptRef) { // like "<scripRef passage="John 3:16">See John 3:16</scripRef>" buf.append("</a></span>"); myUserData->inscriptRef = false; myUserData->suspendTextPassThru = false; } else { // like "<scripRef>John 3:16</scripRef>" CSwordModuleInfo* mod = CBTConfig::get(CBTConfig::standardBible); //Q_ASSERT(mod); tested later if (mod) { CReferenceManager::ParseOptions options; options.refBase = QString::fromUtf8(myUserData->key->getText()); //current module key options.refDestinationModule = QString(mod->name()); options.sourceLanguage = QString(myModule->Lang()); options.destinationLanguage = QString("en"); //it's ok to split the reference, because to descriptive text is given bool insertSemicolon = false; buf.append("<span class=\"crossreference\">"); QStringList refs = QString::fromUtf8(myUserData->lastTextNode.c_str()).split(";"); QString oldRef; //the previous reference to use as a base for the next refs for (QStringList::iterator it(refs.begin()); it != refs.end(); ++it) { if (! oldRef.isEmpty() ){ options.refBase = oldRef; //use the last ref as a base, e.g. Rom 1,2-3, when the next ref is only 3:3-10 } const QString completeRef( CReferenceManager::parseVerseReference((*it), options) ); oldRef = completeRef; //use the parsed result as the base for the next ref. if (insertSemicolon) { //prepend a ref divider if we're after the first one buf.append("; "); } buf.append("<a href=\""); buf.append( CReferenceManager::encodeHyperlink( mod->name(), completeRef, CReferenceManager::typeFromModule(mod->type()) ).toUtf8().constData() ); buf.append("\" crossrefs=\""); buf.append((const char*)completeRef.toUtf8()); buf.append("\">"); buf.append((const char*)(*it).toUtf8()); buf.append("</a>"); insertSemicolon = true; } buf.append("</span>"); //crossref end } myUserData->suspendTextPassThru = false; } } else if (tag.getAttribute("passage") ) { //the passage was given as a parameter value myUserData->inscriptRef = true; myUserData->suspendTextPassThru = false; const char* ref = tag.getAttribute("passage"); Q_ASSERT(ref); CSwordModuleInfo* mod = CBTConfig::get(CBTConfig::standardBible); //Q_ASSERT(mod); tested later CReferenceManager::ParseOptions options; options.refBase = QString::fromUtf8(myUserData->key->getText()); options.refDestinationModule = QString(mod->name()); options.sourceLanguage = myModule->Lang(); options.destinationLanguage = QString("en"); const QString completeRef = CReferenceManager::parseVerseReference(QString::fromUtf8(ref), options); if (mod) { buf.append("<span class=\"crossreference\">"); buf.append("<a href=\""); buf.append( CReferenceManager::encodeHyperlink( mod->name(), completeRef, CReferenceManager::typeFromModule(mod->type()) ).toUtf8().constData() ); buf.append("\" crossrefs=\""); buf.append((const char*)completeRef.toUtf8()); buf.append("\">"); } else { buf.append("<span><a>"); } } else if ( !tag.getAttribute("passage") ) { // we're starting a scripRef like "<scripRef>John 3:16</scripRef>" myUserData->inscriptRef = false; // let's stop text from going to output, the text get's added in the -tag handler myUserData->suspendTextPassThru = true; } } } else if (tag.getName() && !sword::stricmp(tag.getName(), "div")) { if (tag.isEndTag()) { buf.append("</div>"); } else if ( tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"),"sechead") ) { buf.append("<div class=\"sectiontitle\">"); } else if (tag.getAttribute("class") && !sword::stricmp(tag.getAttribute("class"), "title")) { buf.append("<div class=\"booktitle\">"); } } else if (tag.getName() && !sword::stricmp(tag.getName(), "img") && tag.getAttribute("src")) { const char* value = tag.getAttribute("src"); if (value[0] == '/') { value++; //strip the first / } buf.append("<img src=\"file:"); buf.append(myUserData->module->getConfigEntry("AbsoluteDataPath")); buf.append('/'); buf.append(value); buf.append("\" />"); } else { // let unknown token pass thru return sword::ThMLHTML::handleToken(buf, token, userData); } } return true; }
bool Filters::BT_OSISHTML::handleToken(sword::SWBuf &buf, const char *token, sword::BasicFilterUserData *userData) { // manually process if it wasn't a simple substitution if (!substituteToken(buf, token)) { BT_UserData* myUserData = dynamic_cast<BT_UserData*>(userData); sword::SWModule* myModule = const_cast<sword::SWModule*>(myUserData->module); //hack sword::XMLTag tag(token); // qWarning("found %s", token); const bool osisQToTick = ((!userData->module->getConfigEntry("OSISqToTick")) || (strcmp(userData->module->getConfigEntry("OSISqToTick"), "false"))); if (!tag.getName()) { return false; } // <div> tag if (!strcmp(tag.getName(), "div")) { //handle intro if ((!tag.isEmpty()) && (!tag.isEndTag())) { //start tag sword::SWBuf type( tag.getAttribute("type") ); if (type == "introduction") { buf.append("<div class=\"introduction\">"); } else if (type == "chapter") { buf.append("<div class=\"chapter\" />"); //don't open a div here, that would lead to a broken XML structure } else { buf.append("<div>"); } } else if (tag.isEndTag()) { //end tag buf.append("</div>"); } } else if (!strcmp(tag.getName(), "w")) { if ((!tag.isEmpty()) && (!tag.isEndTag())) { //start tag const char *attrib; const char *val; sword::XMLTag outTag("span"); sword::SWBuf attrValue; if ((attrib = tag.getAttribute("xlit"))) { val = strchr(attrib, ':'); val = (val) ? (val + 1) : attrib; outTag.setAttribute("xlit", val); } if ((attrib = tag.getAttribute("gloss"))) { val = strchr(attrib, ':'); val = (val) ? (val + 1) : attrib; outTag.setAttribute("gloss", val); } if ((attrib = tag.getAttribute("lemma"))) { char splitChar = '|'; const int countSplit1 = tag.getAttributePartCount("lemma", '|'); const int countSplit2 = tag.getAttributePartCount("lemma", ' '); //TODO: not allowed, remove soon int count = 0; if (countSplit1 > countSplit2) { //| split char splitChar = '|'; //TODO: not allowed, remove soon count = countSplit1; } else { splitChar = ' '; count = countSplit2; } int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 attrValue = ""; do { if (attrValue.length()) { attrValue.append( '|' ); } attrib = tag.getAttribute("lemma", i, splitChar); if (i < 0) { // to handle our -1 condition i = 0; } val = strchr(attrib, ':'); val = (val) ? (val + 1) : attrib; attrValue.append(val); } while (++i < count); if (attrValue.length()) { outTag.setAttribute("lemma", attrValue.c_str()); } } if ((attrib = tag.getAttribute("morph"))) { char splitChar = '|'; const int countSplit1 = tag.getAttributePartCount("morph", '|'); const int countSplit2 = tag.getAttributePartCount("morph", ' '); //TODO: not allowed, remove soon int count = 0; if (countSplit1 > countSplit2) { //| split char splitChar = '|'; count = countSplit1; } else { splitChar = ' '; count = countSplit2; } int i = (count > 1) ? 0 : -1; // -1 for whole value cuz it's faster, but does the same thing as 0 attrValue = ""; do { if (attrValue.length()) { attrValue.append('|'); } attrib = tag.getAttribute("morph", i, splitChar); if (i < 0) { i = 0; // to handle our -1 condition } val = strchr(attrib, ':'); if (val) { //the prefix gives the modulename //check the prefix if (!strncmp("robinson:", attrib, 9)) { //robinson attrValue.append( "Robinson:" ); //work is not the same as Sword's module name attrValue.append( val+1 ); } //strongs is handled by BibleTime /*else if (!strncmp("strongs", attrib, val-atrrib)) { attrValue.append( !strncmp(attrib, "x-", 2) ? attrib+2 : attrib ); }*/ else { attrValue.append( !strncmp(attrib, "x-", 2) ? attrib+2 : attrib ); } } else { //no prefix given const bool skipFirst = ((val[0] == 'T') && ((val[1] == 'H') || (val[1] == 'H'))); attrValue.append( skipFirst ? val+1 : val ); } } while (++i < count); if (attrValue.length()) { outTag.setAttribute("morph", attrValue.c_str()); } } if ((attrib = tag.getAttribute("POS"))) { val = strchr(attrib, ':'); val = (val) ? (val + 1) : attrib; outTag.setAttribute("pos", val); } buf.append( outTag.toString() ); } else if (tag.isEndTag()) { // end or empty <w> tag buf.append("</span>"); } } // <note> tag else if (!strcmp(tag.getName(), "note")) { if (!tag.isEndTag()) { //start tag const sword::SWBuf type( tag.getAttribute("type") ); if (type == "crossReference") { //note containing cross references myUserData->inCrossrefNote = true; myUserData->noteType = BT_UserData::CrossReference; myUserData->swordFootnote++; // cross refs count as notes, too /* //get the refList value of the right entry attribute AttributeList notes = myModule->getEntryAttributes()["Footnote"]; bool foundNote = false; SWBuf id( tag.getAttribute("osisID") ); SWBuf refList; for (AttributeList::iterator list_it = notes.begin(); (list_it != notes.end()) && !foundNote; ++list_it ) { for (AttributeValue::iterator val_it = list_it->second.begin(); (val_it != list_it->second.end()) && !foundNote; ++val_it ) { if ((val_it->first == "osisID") && (val_it->second == id)) { foundNote = true; //this break the loop refList = list_it->second["refList"]; } } } if (refList.length()) { buf.append(" <span class=\"crossreference\" crossrefs=\""); buf.append(refList.c_str()); buf.append("\"> "); myUserData->noteType = BT_UserData::CrossReference; } else { myUserData->noteType = BT_UserData::Unknown; }*/ buf.append("<span class=\"crossreference\">"); } /* else if (type == "explanation") { } */ else if ((type == "strongsMarkup") || (type == "x-strongsMarkup")) { /** * leave strong's markup notes out, in the future we'll probably have * different option filters to turn different note types on or off */ myUserData->suspendTextPassThru = true; myUserData->noteType = BT_UserData::StrongsMarkup; } else { // qWarning("found note in %s", myUserData->key->getShortText()); buf.append(" <span class=\"footnote\" note=\""); buf.append(myModule->Name()); buf.append('/'); buf.append(myUserData->key->getShortText()); buf.append('/'); buf.append( QString::number(myUserData->swordFootnote++).toUtf8().constData() ); //inefficient const sword::SWBuf n = tag.getAttribute("n"); buf.append("\">"); buf.append( (n.length() > 0) ? n.c_str() : "*" ); buf.append("</span> "); myUserData->noteType = BT_UserData::Footnote; myUserData->suspendTextPassThru = true; } } else { //if (tag.isEndTag()) { Q_ASSERT(myUserData->noteType != BT_UserData::Unknown); if (myUserData->noteType == BT_UserData::CrossReference) { buf.append("</span> "); // myUserData->suspendTextPassThru = false; myUserData->inCrossrefNote = false; } myUserData->noteType = BT_UserData::Unknown; myUserData->suspendTextPassThru = false; } } // The <p> paragraph tag is handled by OSISHTMLHref else if (!strcmp(tag.getName(), "reference")) { // <reference> tag if (!tag.isEndTag() && !tag.isEmpty()) { QString ref( tag.getAttribute("osisRef") ); QString hrefRef( ref ); Q_ASSERT(!ref.isEmpty()); if (!ref.isEmpty()) { //find out the mod, using the current module makes sense if it's a bible or commentary because the refs link into a bible by default. //If the osisRef is something like "ModuleID:key comes here" then the // modulename is given, so we'll use that one CSwordModuleInfo* mod = CPointers::backend()->findSwordModuleByPointer(myModule); Q_ASSERT(mod); if (!mod || (mod->type() != CSwordModuleInfo::Bible && mod->type() != CSwordModuleInfo::Commentary)) { mod = CBTConfig::get( CBTConfig::standardBible ); } Q_ASSERT(mod); //if the osisRef like "GerLut:key" contains a module, use that int pos = ref.indexOf(":"); if ((pos >= 0) && ref.at(pos-1).isLetter() && ref.at(pos+1).isLetter()) { QString newModuleName = ref.left(pos); hrefRef = ref.mid(pos+1); if (CPointers::backend()->findModuleByName(newModuleName)) { mod = CPointers::backend()->findModuleByName(newModuleName); } } CReferenceManager::ParseOptions options; options.refBase = QString::fromUtf8(myUserData->key->getText()); options.refDestinationModule = QString(mod->name()); options.sourceLanguage = QString(myModule->Lang()); options.destinationLanguage = QString("en"); buf.append("<a href=\""); buf.append( //create the hyperlink with key and mod CReferenceManager::encodeHyperlink( mod->name(), CReferenceManager::parseVerseReference(hrefRef, options), CReferenceManager::typeFromModule(mod->type()) ).toUtf8().constData() ); buf.append("\" crossrefs=\""); buf.append((const char*)CReferenceManager::parseVerseReference(ref, options).toUtf8().constData()); //ref must contain the osisRef module marker if there was any buf.append("\">"); } } else if (tag.isEndTag()) { buf.append("</a>"); } else { // empty reference marker // -- what should we do? nothing for now. } } // <l> is handled by OSISHTMLHref // <title> else if (!strcmp(tag.getName(), "title")) { if (!tag.isEndTag() && !tag.isEmpty()) { buf.append("<div class=\"sectiontitle\">"); } else if (tag.isEndTag()) { buf.append("</div>"); } else { // empty title marker // what to do? is this even valid? buf.append("<br/>"); } } // <hi> highlighted text else if (!strcmp(tag.getName(), "hi")) { const sword::SWBuf type = tag.getAttribute("type"); if ((!tag.isEndTag()) && (!tag.isEmpty())) { if (type == "bold") { buf.append("<span class=\"bold\">"); } else if (type == "illuminated") { buf.append("<span class=\"illuminated\">"); } else if (type == "italic") { buf.append("<span class=\"italic\">"); } else if (type == "line-through") { buf.append("<span class=\"line-through\">"); } else if (type == "normal") { buf.append("<span class=\"normal\">"); } else if (type == "small-caps") { buf.append("<span class=\"small-caps\">"); } else if (type == "underline") { buf.append("<span class=\"underline\">"); } else { buf.append("<span>"); //don't break markup, </span> is inserted later } } else if (tag.isEndTag()) { //all hi replacements are html spans buf.append("</span>"); } } //name else if (!strcmp(tag.getName(), "name")) { const sword::SWBuf type = tag.getAttribute("type"); if ((!tag.isEndTag()) && (!tag.isEmpty())) { if (type == "geographic") { buf.append("<span class=\"name\"><span class=\"geographic\">"); } else if (type == "holiday") { buf.append("<span class=\"name\"><span class=\"holiday\">"); } else if (type == "nonhuman") { buf.append("<span class=\"name\"><span class=\"nonhuman\">"); } else if (type == "person") { buf.append("<span class=\"name\"><span class=\"person\">"); } else if (type == "ritual") { buf.append("<span class=\"name\"><span class=\"ritual\">"); } else { buf.append("<span class=\"name\"><span>"); } } else if (tag.isEndTag()) { //all hi replacements are html spans buf.append("</span></span> "); } } else if (!strcmp(tag.getName(), "transChange")) { sword::SWBuf type( tag.getAttribute("type") ); if ( !type.length() ) { type = tag.getAttribute("changeType"); } if ((!tag.isEndTag()) && (!tag.isEmpty())) { if (type == "added") { buf.append("<span class=\"transchange\" title=\""); buf.append(QObject::tr("Added text").toUtf8().constData()); buf.append("\"><span class=\"added\">"); } else if (type == "amplified") { buf.append("<span class=\"transchange\"><span class=\"amplified\">"); } else if (type == "changed") { buf.append("<span class=\"transchange\"><span class=\"changed\">"); } else if (type == "deleted") { buf.append("<span class=\"transchange\"><span class=\"deleted\">"); } else if (type == "moved") { buf.append("<span class=\"transchange\"><span class=\"moved\">"); } else if (type == "tenseChange") { buf.append("<span class=\"transchange\" title=\""); buf.append(QObject::tr("Verb tense changed").toUtf8().constData()); buf.append("\"><span class=\"tenseChange\">"); } else { buf.append("<span class=\"transchange\"><span>"); } } else if (tag.isEndTag()) { //all hi replacements are html spans buf.append("</span></span>"); } } else if (!strcmp(tag.getName(), "p")) { if (tag.isEmpty()) { buf.append("<p/>"); } } // <q> quote else if (!strcmp(tag.getName(), "q")) { sword::SWBuf type = tag.getAttribute("type"); sword::SWBuf who = tag.getAttribute("who"); const char *lev = tag.getAttribute("level"); int level = (lev) ? atoi(lev) : 1; if ((!tag.isEndTag()) && (!tag.isEmpty())) { myUserData->quote.who = who; if(osisQToTick) //alternate " and ' buf.append((level % 2) ? '\"' : '\''); if (who == "Jesus") { buf.append("<span class=\"jesuswords\">"); } } else if (tag.isEndTag()) { if (myUserData->quote.who == "Jesus") { buf.append("</span>"); } if (osisQToTick) { //alternate " and ' buf.append((level % 2) ? '\"' : '\''); } myUserData->quote.who = ""; } } // abbr tag else if (!strcmp(tag.getName(), "abbr")) { if (!tag.isEndTag() && !tag.isEmpty()) { const sword::SWBuf expansion = tag.getAttribute("expansion"); buf.append("<span class=\"abbreviation\" expansion=\""); buf.append(expansion); buf.append("\">"); } else if (tag.isEndTag()) { buf.append("</span>"); } } // <milestone> tag else if (!strcmp(tag.getName(), "milestone")) { const sword::SWBuf type = tag.getAttribute("type"); if ((type == "screen") || (type == "line")) {//line break buf.append("<br/>"); userData->supressAdjacentWhitespace = true; } else if (type == "x-p") { //e.g. occurs in the KJV2006 module //buf.append("<br/>"); const sword::SWBuf marker = tag.getAttribute("marker"); if (marker.length() > 0) { buf.append(marker); } } } //seg tag else if (!strcmp(tag.getName(), "seg")) { if (!tag.isEndTag() && !tag.isEmpty()) { const sword::SWBuf type = tag.getAttribute("type"); if (type == "morph") {//line break //This code is for WLC and MORPH (WHI) sword::XMLTag outTag("span"); outTag.setAttribute("class", "morphSegmentation"); const char* attrValue; //Transfer the values to the span //Problem: the data is in hebrew/aramaic, how to encode in HTML/BibleTime? if ((attrValue = tag.getAttribute("lemma"))) outTag.setAttribute("lemma", attrValue); if ((attrValue = tag.getAttribute("morph"))) outTag.setAttribute("morph", attrValue); if ((attrValue = tag.getAttribute("homonym"))) outTag.setAttribute("homonym", attrValue); buf.append(outTag.toString()); //buf.append("<span class=\"morphSegmentation\">"); } else{ buf.append("<span>"); } } else { // seg end tag buf.append("</span>"); } //qWarning(QString("handled <seg> token. result: %1").arg(buf.c_str()).latin1()); } //divine name, don't use simple tag replacing because it may have attributes else if (!strcmp(tag.getName(), "divineName")) { if (!tag.isEndTag()) { buf.append("<span class=\"name\"><span class=\"divine\">"); } else { //all hi replacements are html spans buf.append("</span></span>"); } } else { //all tokens handled by OSISHTMLHref will run through the filter now return sword::OSISHTMLHREF::handleToken(buf, token, userData); } } return false; }
const QString CInfoDisplay::decodeCrossReference( const QString& data ) { Q_ASSERT(!data.isEmpty()); if (data.isEmpty()) { return QString("<div class=\"crossrefinfo\"><h3>%1</h3></div>") .arg(tr("Cross references")); } // qWarning("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 QRegExp re("^[^ ]+:"); // re.setMinimal(true); int pos = re.indexIn(data); if (pos != -1) { pos += re.matchedLength()-1; } if (pos > 0) { const QString moduleName = data.left(pos); // qWarning("found module %s", moduleName.latin1()); module = CPointers::backend()->findModuleByName(moduleName); if (!module) { module = CBTConfig::get (CBTConfig::standardBible); } // Q_ASSERT(module); } //Q_ASSERT(module); //why? the existense of the module is tested later 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).toUtf8(), "Gen 1:1", true); for (int i = 0; i < refs.Count(); ++i) { SWKey* key = refs.getElement(i); Q_ASSERT(key); VerseKey* vk = dynamic_cast<VerseKey*>(key); CTextRendering::KeyTreeItem* itm = (CTextRendering::KeyTreeItem*)0; //explicit conversion for MS VS if (vk && vk->isBoundSet()) { //render a range of keys itm = new CTextRendering::KeyTreeItem( QString::fromUtf8(vk->LowerBound().getText()), QString::fromUtf8(vk->UpperBound().getText()), module, settings ); } else { itm = new CTextRendering::KeyTreeItem( QString::fromUtf8(key->getText()), QString::fromUtf8(key->getText()), module, settings ); } Q_ASSERT(itm); tree.append( itm ); } } else if (module) { CTextRendering::KeyTreeItem* itm = new CTextRendering::KeyTreeItem( data.mid((pos == -1) ? 0 : pos+1), module, settings ); tree.append( itm ); } // qWarning("rendered the tree: %s", renderer.renderKeyTree(tree).latin1()); //spanns containing rtl text need dir=rtl on their parent tag to be aligned properly QString lang = "en"; // default english if (module) lang = module->language()->abbrev(); return QString("<div class=\"crossrefinfo\" lang=\"%1\"><h3>%2</h3><div class=\"para\" dir=\"%3\">%4</div></div>") .arg(lang) .arg(tr("Cross references")) .arg(module ? ((module->textDirection() == CSwordModuleInfo::LeftToRight) ? "ltr" : "rtl") : "") .arg(renderer.renderKeyTree(tree)); }
const QString CInfoDisplay::decodeMorph( const QString& data ) { QStringList morphs = data.split("|"); QString ret; foreach(QString morph, morphs) { //qDebug() << "CInfoDisplay::decodeMorph, morph: " << morph; CSwordModuleInfo* module = 0; bool skipFirstChar = false; QString value = ""; QString valueClass = ""; int valStart = morph.indexOf(':'); if (valStart > -1) { valueClass = morph.mid(0, valStart); //qDebug() << "valueClass: " << valueClass; module = CPointers::backend()->findModuleByName( valueClass ); } value = morph.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. if (value.size() > 1 && value.at(1).isDigit()) { switch (value.at(0).toLatin1()) { 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); } } QString text; //Q_ASSERT(module); if (module) { boost::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 QString lang = "en"; // default to english if (module) lang = module->language()->abbrev(); ret.append( QString("<div class=\"morphinfo\" lang=\"%1\"><h3>%2: %3</h3><p>%4</p></div>") .arg(lang) .arg(tr("Morphology")) .arg(value) .arg(text) ); }