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.
bibletime/bibletime/frontend/keychooser/cbookkeychooser.cpp

290 lines
7.2 KiB

/*********
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
* Copyright 1999-2007 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/
#include "cbookkeychooser.h"
#include "backend/cswordtreekey.h"
#include "backend/cswordbookmoduleinfo.h"
#include "frontend/cbtconfig.h"
//TQt includes
#include <tqlayout.h>
#include <tqmap.h>
TQMap<TQObject*, int> boxes;
CBookKeyChooser::CBookKeyChooser(ListCSwordModuleInfo modules, CSwordKey *key, TQWidget *parent, const char *name)
: CKeyChooser(modules, key, parent,name), m_layout(0) {
setModules(modules, false);
m_key = dynamic_cast<CSwordTreeKey*>(key);
if (!m_modules.count()) {
m_key = 0;
}
setModules(modules, true);
setKey(key);
adjustFont();
}
CBookKeyChooser::~CBookKeyChooser() {}
void CBookKeyChooser::setKey(CSwordKey* newKey) {
setKey(newKey, true);
}
/** Sets a new key to this keychooser */
void CBookKeyChooser::setKey(CSwordKey* newKey, const bool emitSignal) {
//tqDebug("CBookKeyChooser::setKey");
if (m_key != newKey) {
m_key = dynamic_cast<CSwordTreeKey*>(newKey);
}
/*const */TQString oldKey = m_key->key();
if (oldKey.isEmpty()) { //don't set keys equal to "/", always use a key which may have content
m_key->firstChild();
oldKey = m_key->key();
}
const int oldOffset = m_key->getOffset();
TQStringList siblings;
if (m_key && !oldKey.isEmpty()) {
siblings = TQStringList::split("/", oldKey, false);
}
int depth = 0;
int index = 0;
m_key->root();
while( m_key->firstChild() && (depth <= int(siblings.count())) ) {
const TQString key = m_key->key();
index = (depth == 0) ? -1 : 0;
const TQString sibling = siblings[depth];
if (!sibling.isEmpty()) { //found it
bool found = false;
do {
++index;
//tqDebug("set 'found'");
//found = (TQString::fromLocal8Bit(m_key->getLocalName()) == sibling);
found = (m_key->getLocalNameUnicode() == sibling);
}
while (!found && m_key->nextSibling());
if (!found) {
m_key->key( key );
}
}
setupCombo(key, depth, index);
depth++;
}
//clear the combos which were not filled
for (; depth < m_modules.first()->depth(); ++depth) {
CKeyChooserWidget* chooser = m_chooserWidgets.at(depth);
if (chooser) {
chooser->reset(0,0,false);
}
}
if (oldKey.isEmpty()) {
m_key->root();
}
else {
//m_key->key(oldKey);
m_key->setOffset(oldOffset);
}
if (emitSignal) {
emit keyChanged(m_key);
}
}
/** Returns the key of this kechooser. */
CSwordKey* const CBookKeyChooser::key() {
return m_key;
}
/** Sets another module to this keychooser */
void CBookKeyChooser::setModules(const ListCSwordModuleInfo& modules, const bool refresh) {
m_modules.clear();
// for (modules.first(); modules.current(); modules.next()) {
ListCSwordModuleInfo::const_iterator end_it = modules.end();
for (ListCSwordModuleInfo::const_iterator it(modules.begin()); it != end_it; ++it) {
if ( (*it)->type() == CSwordModuleInfo::GenericBook ) {
if (CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(*it)) {
m_modules.append(book);
}
}
}
//refresh the number of combos
if (refresh && m_modules.count() && m_key) {
if (!m_layout) {
m_layout = new TQHBoxLayout(this);
}
//delete old widgets
m_chooserWidgets.setAutoDelete(true);
m_chooserWidgets.clear();
m_chooserWidgets.setAutoDelete(false);
for (int i = 0; i < m_modules.first()->depth(); ++i) {
// Create an empty keychooser, don't handle next/prev signals
CKeyChooserWidget* w = new CKeyChooserWidget(0, false, this);
m_chooserWidgets.append( w );
//don't allow a too high width, try to keep as narrow as possible
//to aid users with smaller screen resolutions
int totalWidth = 200; //only 1 level
if (m_modules.first()->depth() > 1) {
if (m_modules.first()->depth() > 3)
totalWidth = 400; //4+ levels
else
totalWidth = 300; //2-3 levels
}
int maxWidth = (int) ((float) totalWidth / (float) m_modules.first()->depth());
w->comboBox()->setMaximumWidth(maxWidth);
w->comboBox()->setCurrentItem(0);
connect(w, TQT_SIGNAL(changed(int)), TQT_SLOT(keyChooserChanged(int)));
connect(w, TQT_SIGNAL(focusOut(int)), TQT_SLOT(keyChooserChanged(int)));
m_layout->addWidget(w);
boxes[TQT_TQOBJECT(w)] = i;
w->show();
}
//set the tab order of the key chooser widgets
CKeyChooserWidget* chooser = 0;
CKeyChooserWidget* chooser_prev = 0;
const int count = m_chooserWidgets.count();
for (int i = 0; i < count; ++i) {
chooser = m_chooserWidgets.at(i);
Q_ASSERT(chooser);
if (chooser && chooser_prev) {
TQWidget::setTabOrder(chooser_prev, chooser);
}
chooser_prev = chooser;
}
TQWidget::setTabOrder(chooser, 0);
updateKey(m_key);
adjustFont(); // only when refresh is set.
}
}
/** No descriptions */
void CBookKeyChooser::adjustFont() {
//Make sure the entries are displayed correctly.
for ( CKeyChooserWidget* idx = m_chooserWidgets.first(); idx; idx = m_chooserWidgets.next() ) {
idx->comboBox()->setFont( CBTConfig::get
( m_modules.first()->language() ).second );
}
}
/** Refreshes the content. */
void CBookKeyChooser::refreshContent() {
if (m_key) {
updateKey( m_key ); //refresh with current key
}
}
void CBookKeyChooser::setupCombo(const TQString key, const int depth, const int currentItem) {
CKeyChooserWidget* chooserWidget = m_chooserWidgets.at(depth);
const unsigned long oldOffset = m_key->getOffset();
m_key->key(key);
if ((depth == 0) && chooserWidget && chooserWidget->comboBox()->count()) { //has already items
//set now the right item
if (CKeyChooserWidget* chooserWidget = m_chooserWidgets.at(depth)) {
chooserWidget->setItem( chooserWidget->comboBox()->text(currentItem) );
}
m_key->setOffset(oldOffset);
return;
}
//insert an empty item at the top
TQStringList items;
if (depth > 0) {
items << TQString();
}
do {
//items << TQString::fromLocal8Bit(m_key->getLocalName());
items << m_key->getLocalNameUnicode();
}
while (m_key->nextSibling());
if (chooserWidget) {
chooserWidget->reset(items,currentItem,false);
}
//restore old key
// m_key->key(oldKey);
m_key->setOffset( oldOffset );
}
/** A keychooser changed. Update and emit a signal if necessary. */
void CBookKeyChooser::keyChooserChanged(int /*newIndex*/) {
const int activeID = boxes[TQT_TQOBJECT(const_cast<TQT_BASE_OBJECT_NAME*>(sender()))]; //no so good code!
TQStringList items;
CKeyChooserWidget* chooser;
const int count = m_chooserWidgets.count();
for (int i = 0; i < count; ++i) {
chooser = m_chooserWidgets.at(i);
const TQString currentText =
(chooser && chooser->comboBox())
? chooser->comboBox()->currentText()
: TQString();
if (currentText.isEmpty() || i > activeID) {
break;
}
items << currentText;
}
TQString newKey("/");
newKey.append(items.join("/"));
if (newKey.length() > 1) {
newKey.remove(newKey.length(),1); //remove the traling slash
}
// tqWarning("key changed: setting to %s", newKey.latin1());
m_key->key(newKey);
setKey(m_key);
}
/** Updates the keychoosers for the given key but emit no signal. */
void CBookKeyChooser::updateKey(CSwordKey* key) {
setKey(key, false);
}
#include "cbookkeychooser.moc"