CSwordModuleInfo* CSwordTreeKey::module( CSwordModuleInfo* const newModule ) {
    if (newModule && (newModule != m_module) && (newModule->type() == CSwordModuleInfo::GenericBook) ) {
        m_module = newModule;

        const QString oldKey = key();

        CSwordBookModuleInfo* newBook = dynamic_cast<CSwordBookModuleInfo*>(newModule);
        copyFrom( *(newBook->tree()) );

        key(oldKey); //try to restore our old key

        //set the key to the root node
        root();
        firstChild();
    }

    return m_module;
}
		void setModule(CSwordModuleInfo *module)
		{
			_module = module;

			if(!_module)
				return;

			if(_module->type() == CSwordModuleInfo::Bible ||
				_module->type() == CSwordModuleInfo::Commentary)
			{
				CSwordBibleModuleInfo *bm = qobject_cast<CSwordBibleModuleInfo*>(_module);

				_firstEntry = bm->lowerBound().getIndex();
				_maxEntries = bm->upperBound().getIndex() - _firstEntry + 1;

                _displayOptions.verseNumbers = true;
                _simpleVerseNumber = true;
			}

            if(_module->type() == CSwordModuleInfo::Lexicon)
			{
				CSwordLexiconModuleInfo *lm = qobject_cast<CSwordLexiconModuleInfo*>(_module);
				_maxEntries = lm->entries().size();
			}

            if(_module->type() == CSwordModuleInfo::GenericBook)
            {
                CSwordBookModuleInfo *bm = qobject_cast<CSwordBookModuleInfo*>(_module);

                sword::TreeKeyIdx tk(*bm->tree());
                tk.root();
                tk.firstChild();

                Q_ASSERT(tk.getOffset() == 4);

                tk.setPosition(sword::BOTTOM);

                _maxEntries = tk.getOffset() / 4;
            }
		}
/** 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 Rendering::CBookDisplay::text( const QList<CSwordModuleInfo*>& modules, const QString& keyName, const CSwordBackend::DisplayOptions displayOptions, const CSwordBackend::FilterOptions filterOptions ) {
    CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(modules.first());
    Q_ASSERT(book);

    CSwordBackend::DisplayOptions dOpts = displayOptions;
    dOpts.lineBreaks = true; //books should render with blocks, not with inlined sections

    CDisplayRendering render(dOpts, filterOptions);
    CDisplayRendering::KeyTree tree;
    CDisplayRendering::KeyTreeItem::Settings itemSettings;

    // the number of levels which should be display together, 1 means display no entries together
    int displayLevel = book->config( CSwordModuleInfo::DisplayLevel ).toInt();

    boost::scoped_ptr<CSwordTreeKey> key (
        dynamic_cast<CSwordTreeKey*>( CSwordKey::createInstance(book) )
    );
    key->key(keyName); //set the key to position we'd like to get

    const unsigned long offset = key->getOffset();

    // standard of DisplayLevel, display nothing together
    // if the current key is the root entry don't display anything together!

    if ((displayLevel <= 1) || (key->key().isEmpty() || (key->key() == "/") )) {
        tree.append( new CDisplayRendering::KeyTreeItem( key->key(), modules, itemSettings ) );

        const QString renderedText = render.renderKeyTree(tree);
        key->setOffset( offset );

        qDeleteAll(tree);      // Dispose of the heap allocated objects pointed to in tree.
        return renderedText;
    };

    /**
    * Check whether displaying displayLevel levels together is possible.
    * For this count the childs and parents
    * of the required position
    */

    int possibleLevels = 1; //we start with the default value of displayLevel, which means no entries together

    while ( key->sword::TreeKeyIdx::parent() && (key->key() != "/") && !key->key().isEmpty() ) {//add parents
        ++possibleLevels;
    };

    //   key->key(keyName); //set the key to the start position

    key->setOffset( offset );

    while ( key->firstChild( )) { //add childs
        ++possibleLevels;
    };

    if (possibleLevels < displayLevel) { //too few levels available!
        //display current level, we could also decide to display the available levels together
        tree.append( new CDisplayRendering::KeyTreeItem( key->key(), modules, itemSettings ) );

        const QString renderedText = render.renderKeyTree(tree);
        key->setOffset( offset );
        qDeleteAll(tree);      // Dispose of the heap allocated objects pointed to in tree.
        return renderedText;
    };

    if ((displayLevel > 2) && (displayLevel == possibleLevels)) { //fix not to diplay the whole module
        --displayLevel;
    }

    // at this point we're sure that we can display the required levels toogether
    // at the moment we're at the lowest level, so we only have to go up!
    for (int currentLevel = 1; currentLevel < displayLevel; ++currentLevel) { //we start again with 1 == standard of displayLevel

        if ( !key->sword::TreeKeyIdx::parent() ) { //something went wrong although we checked before! Be safe and return entry's text
            tree.append( new CDisplayRendering::KeyTreeItem( key->key(), modules, itemSettings ) );

            const QString renderedText = render.renderKeyTree(tree);
            key->setOffset( offset );
            qDeleteAll(tree);      // Dispose of the heap allocated objects pointed to in tree.
            return renderedText;
        };
    };

    // no we can display all sub levels together! We checked before that this is possible!
    itemSettings.highlight = (key->key() == keyName);

    tree.append( new CDisplayRendering::KeyTreeItem( key->key(), modules, itemSettings ) );

    //const bool hasToplevelText = !key->strippedText().isEmpty();
    key->firstChild(); //go to the first sibling on the same level

    setupRenderTree(key.get(), &tree, keyName);

    const QString renderedText = render.renderKeyTree(tree);

    key->setOffset( offset ); //restore key

    qDeleteAll(tree);      // Dispose of the heap allocated objects pointed to in tree.
    return renderedText;
}
QVariant BtMiniModuleTextModel::data(const QModelIndex &index, int role) const
{
    Q_D(const BtMiniModuleTextModel);

    switch(role)
	{
    case BtMini::PreviewUpdateRole:
	case BtMini::PreviewRole:
		{
            const BtMiniModuleTextModelPrivate::List *list = d->indexList(index);

            // put to thread processing
            if(role == BtMini::PreviewUpdateRole)
            {
                ;
            }


            if(list->_module->type() == CSwordModuleInfo::GenericBook)
            {
                CSwordBookModuleInfo *b = qobject_cast<CSwordBookModuleInfo*>(list->_module);
                CSwordTreeKey k(b->tree(), b);

                k.setIndex(index.row() * 4);

                return QString("<word-breaks/><font color='#aaaaaa'><center>%1</center></font><font size='1'><br>"
                               "&nbsp;</br></font>").arg(k.key().replace('/', ' '));
            }
            else
            {

                // there was issue with VerseKey::freshtext at simoultaneous call
                static CSwordVerseKey vk(list->_module);
                vk.setModule(list->_module);
                vk.setIndex(index.row() + list->_firstEntry);
                int v = vk.getVerse();

                if(v == 0)
                    return QString();

                QString r("<font color='#aaaaaa'>");

                if(v == 1)
                    r += QString("<center><b><font size='+1'>%1 %2</font></b></center>"
                    "<font size='1'><br>&nbsp;</br></font>").arg(vk.book()).arg(vk.getChapter());

                if(v > 0)
                    r += QString("<center>%1</center></font><font size='1'><br>&nbsp;</br>").arg(v);

                return r + "</font>";
            }
		}

	case Qt::DisplayRole:
        {
			switch(d->indexDepth(index))
			{
			case 1:
                {
                    const BtMiniModuleTextModelPrivate::List & l = d->_lists[index.internalId()];
                    return l._module == 0 ? "" : l._module->name();
                }
			case 2:
				{
					QString r;
                    const BtMiniModuleTextModelPrivate::List *l = d->indexList(index);

					if(l->_module && (l->_module->type() == CSwordModuleInfo::Bible ||
						l->_module->type() == CSwordModuleInfo::Commentary))
					{
						CSwordVerseKey key(d->indexToVerseKey(index));
						const int v = key.getVerse();

                        QList<const CSwordModuleInfo*> modules;
                        modules << l->_module;

                        // parallel display
                        if(l->_name.contains(','))
                            foreach(QString s, l->_name.split(',').mid(1))
                                if(CSwordModuleInfo *m = CSwordBackend::instance()->findModuleByName(s)) modules << m;

                        if(!d->_isSearch && v == 1)
                            r += "<center><b><font size='+2' face=\"" + btConfig().getDefaultFont().family() + "\">"
                                    + key.book() + " " + QString::number(key.getChapter()) + "</font></b></center>";

                        if(v != 0)
                            r += Rendering::CEntryDisplay().textKeyRendering(modules, key.key(),
                                l->_displayOptions, l->_filterOptions,
                                l->_simpleVerseNumber ? Rendering::CTextRendering::KeyTreeItem::Settings::SimpleKey :
                                                        Rendering::CTextRendering::KeyTreeItem::Settings::CompleteShort,
                                l->_introdutions);

                        if(!d->_isSearch && v == key.getVerseMax())
                            r += "<font size='1'><br>&nbsp;</font>";
					}
					else if(l->_module && l->_module->type() == CSwordModuleInfo::Lexicon)
					{
						CSwordLexiconModuleInfo *lm = qobject_cast<CSwordLexiconModuleInfo*>(l->_module);

						Rendering::CEntryDisplay ed;
                        r += ed.textKeyRendering(QList<const CSwordModuleInfo*>() << lm, lm->entries()[l->_hasScope ?
                            l->_scopeMap[index.row()] : index.row()],
                            l->_displayOptions, l->_filterOptions,
                            l->_simpleVerseNumber ? Rendering::CTextRendering::KeyTreeItem::Settings::SimpleKey :
                                                    Rendering::CTextRendering::KeyTreeItem::Settings::CompleteShort,
                            l->_introdutions);
					}
                    else if(l->_module && l->_module->type() == CSwordModuleInfo::GenericBook)
                    {
                        CSwordBookModuleInfo *b = reinterpret_cast<CSwordBookModuleInfo*>(l->_module);
                        CSwordTreeKey key(b->tree(), b);
                        key.setIndex(l->_hasScope ? l->_scopeMap[index.row()] : index.row() * 4);

						Rendering::CEntryDisplay ed;
                        r += ed.textKeyRendering(QList<const CSwordModuleInfo*>() << l->_module,
                            key.key(), l->_displayOptions, l->_filterOptions,
                            l->_simpleVerseNumber ? Rendering::CTextRendering::KeyTreeItem::Settings::SimpleKey :
                                                    Rendering::CTextRendering::KeyTreeItem::Settings::CompleteShort,
                            l->_introdutions);
                    }

                    if(d->_isSearch && !d->_searchText.isEmpty())
                        r = CSwordModuleSearch::highlightSearchedText(r, d->_searchText);

					if(l->_hasContents)
						r += l->_contents.toString();

					return r;
				}
			}
        }