~vcs-imports/bibletime/trunk

« back to all changes in this revision

Viewing changes to bibletime/frontend/keychooser/cbookkeychooser.cpp

  • Committer: mgruner
  • Date: 2007-05-08 15:51:07 UTC
  • Revision ID: vcs-imports@canonical.com-20070508155107-0rj7jdmm5ivf8685
-imported source and data files to new svn module
-this is where KDE4-based development will take place

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*********
 
2
*
 
3
* This file is part of BibleTime's source code, http://www.bibletime.info/.
 
4
*
 
5
* Copyright 1999-2006 by the BibleTime developers.
 
6
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
 
7
*
 
8
**********/
 
9
 
 
10
 
 
11
 
 
12
#include "cbookkeychooser.h"
 
13
#include "backend/cswordtreekey.h"
 
14
#include "backend/cswordbookmoduleinfo.h"
 
15
#include "frontend/cbtconfig.h"
 
16
 
 
17
//Qt includes
 
18
#include <qlayout.h>
 
19
#include <qmap.h>
 
20
 
 
21
QMap<QObject*, int> boxes;
 
22
 
 
23
CBookKeyChooser::CBookKeyChooser(ListCSwordModuleInfo modules, CSwordKey *key, QWidget *parent, const char *name)
 
24
: CKeyChooser(modules, key, parent,name), m_layout(0) {
 
25
 
 
26
        setModules(modules, false);
 
27
        m_key = dynamic_cast<CSwordTreeKey*>(key);
 
28
        if (!m_modules.count()) {
 
29
                m_key = 0;
 
30
        }
 
31
 
 
32
        setModules(modules, true);
 
33
        setKey(key);
 
34
 
 
35
        adjustFont();
 
36
}
 
37
 
 
38
CBookKeyChooser::~CBookKeyChooser() {}
 
39
 
 
40
void CBookKeyChooser::setKey(CSwordKey* newKey) {
 
41
        setKey(newKey, true);
 
42
}
 
43
 
 
44
/** Sets a new key to this keychooser */
 
45
void CBookKeyChooser::setKey(CSwordKey* newKey, const bool emitSignal) {
 
46
        if (m_key != newKey) {
 
47
                m_key = dynamic_cast<CSwordTreeKey*>(newKey);
 
48
        }
 
49
 
 
50
        /*const */QString oldKey = m_key->key();
 
51
 
 
52
        if (oldKey.isEmpty()) { //don't set keys equal to "/", always use a key which may have content
 
53
                m_key->firstChild();
 
54
                oldKey = m_key->key();
 
55
        }
 
56
        const int oldOffset = m_key->getOffset();
 
57
 
 
58
        QStringList siblings;
 
59
        if (m_key && !oldKey.isEmpty()) {
 
60
                siblings = QStringList::split("/", oldKey, false);
 
61
        }
 
62
 
 
63
        int depth = 0;
 
64
        int index = 0;
 
65
 
 
66
        m_key->root();
 
67
 
 
68
        while( m_key->firstChild() && (depth <= int(siblings.count())) ) {
 
69
                const QString key = m_key->key();
 
70
                index = (depth == 0) ? -1 : 0;
 
71
                const QString sibling = siblings[depth];
 
72
 
 
73
                if (!sibling.isEmpty()) { //found it
 
74
                        bool found = false;
 
75
 
 
76
                        do {
 
77
                                ++index;
 
78
                                found = (m_key->getLocalName() == sibling);
 
79
                        }
 
80
                        while (!found && m_key->nextSibling());
 
81
 
 
82
                        if (!found) {
 
83
                                m_key->key( key );
 
84
                        }
 
85
                }
 
86
 
 
87
                setupCombo(key, depth, index);
 
88
                depth++;
 
89
        }
 
90
 
 
91
        //clear the combos which were not filled
 
92
        for (; depth < m_modules.first()->depth(); ++depth)  {
 
93
                CKeyChooserWidget* chooser = m_chooserWidgets.at(depth);
 
94
                if (chooser) {
 
95
                        chooser->reset(0,0,false);
 
96
                }
 
97
        }
 
98
 
 
99
        if (oldKey.isEmpty()) {
 
100
                m_key->root();
 
101
        }
 
102
        else {
 
103
                //m_key->key(oldKey);
 
104
                m_key->setOffset(oldOffset);
 
105
        }
 
106
 
 
107
        if (emitSignal) {
 
108
                emit keyChanged(m_key);
 
109
        }
 
110
}
 
111
 
 
112
/** Returns the key of this kechooser. */
 
113
CSwordKey* const CBookKeyChooser::key() {
 
114
        return m_key;
 
115
}
 
116
 
 
117
/** Sets another module to this keychooser */
 
118
void CBookKeyChooser::setModules(const ListCSwordModuleInfo& modules, const bool refresh) {
 
119
        m_modules.clear();
 
120
 
 
121
        //   for (modules.first(); modules.current(); modules.next()) {
 
122
        ListCSwordModuleInfo::const_iterator end_it = modules.end();
 
123
        for (ListCSwordModuleInfo::const_iterator it(modules.begin()); it != end_it; ++it) {
 
124
                if ( (*it)->type() == CSwordModuleInfo::GenericBook ) {
 
125
                        if (CSwordBookModuleInfo* book = dynamic_cast<CSwordBookModuleInfo*>(*it)) {
 
126
                                m_modules.append(book);
 
127
                        }
 
128
                }
 
129
        }
 
130
 
 
131
        //refresh the number of combos
 
132
        if (refresh && m_modules.count() && m_key) {
 
133
                if (!m_layout) {
 
134
                        m_layout = new QHBoxLayout(this);
 
135
                }
 
136
 
 
137
                //delete old widgets
 
138
                m_chooserWidgets.setAutoDelete(true);
 
139
                m_chooserWidgets.clear();
 
140
                m_chooserWidgets.setAutoDelete(false);
 
141
 
 
142
                for (int i = 0; i < m_modules.first()->depth(); ++i) {
 
143
                        // Create an empty keychooser, don't handle next/prev signals
 
144
                        CKeyChooserWidget* w = new CKeyChooserWidget(0, false, this);
 
145
                        m_chooserWidgets.append( w );
 
146
 
 
147
                        //don't allow a too high width, try to keep as narrow as possible
 
148
                        //to aid users with smaller screen resolutions
 
149
                        int totalWidth = 200; //only 1 level
 
150
                        if (m_modules.first()->depth() > 1) {
 
151
                                if (m_modules.first()->depth() > 3)
 
152
                                        totalWidth = 400; //4+ levels
 
153
                                else
 
154
                                        totalWidth = 300; //2-3 levels
 
155
                        }
 
156
 
 
157
                        int maxWidth = (int) ((float) totalWidth / (float) m_modules.first()->depth());
 
158
 
 
159
                        w->comboBox()->setMaximumWidth(maxWidth);
 
160
                        w->comboBox()->setCurrentItem(0);
 
161
 
 
162
                        connect(w, SIGNAL(changed(int)), SLOT(keyChooserChanged(int)));
 
163
                        connect(w, SIGNAL(focusOut(int)), SLOT(keyChooserChanged(int)));
 
164
 
 
165
                        m_layout->addWidget(w);
 
166
                        boxes[w] = i;
 
167
 
 
168
                        w->show();
 
169
                }
 
170
 
 
171
                //set the tab order of the key chooser widgets
 
172
 
 
173
                CKeyChooserWidget* chooser = 0;
 
174
                CKeyChooserWidget* chooser_prev = 0;
 
175
                const int count = m_chooserWidgets.count();
 
176
                for (int i = 0; i < count; ++i) {
 
177
                        chooser = m_chooserWidgets.at(i);
 
178
                        Q_ASSERT(chooser);
 
179
 
 
180
                        if (chooser && chooser_prev) {
 
181
                                QWidget::setTabOrder(chooser_prev, chooser);
 
182
                        }
 
183
 
 
184
                        chooser_prev = chooser;
 
185
                }
 
186
                QWidget::setTabOrder(chooser, 0);
 
187
 
 
188
                updateKey(m_key);
 
189
                adjustFont(); // only when refresh is set.
 
190
        }
 
191
}
 
192
 
 
193
/** No descriptions */
 
194
void CBookKeyChooser::adjustFont() {
 
195
 
 
196
        //Make sure the entries are displayed correctly.
 
197
        for ( CKeyChooserWidget* idx = m_chooserWidgets.first(); idx; idx = m_chooserWidgets.next() ) {
 
198
                idx->comboBox()->setFont( CBTConfig::get
 
199
                                                                          ( m_modules.first()->language() ).second );
 
200
        }
 
201
}
 
202
 
 
203
/** Refreshes the content. */
 
204
void CBookKeyChooser::refreshContent() {
 
205
        if (m_key) {
 
206
                updateKey( m_key ); //refresh with current key
 
207
        }
 
208
}
 
209
 
 
210
void CBookKeyChooser::setupCombo(const QString key, const int depth, const int currentItem) {
 
211
        CKeyChooserWidget* chooserWidget = m_chooserWidgets.at(depth);
 
212
 
 
213
        const unsigned long oldOffset = m_key->getOffset();
 
214
        m_key->key(key);
 
215
 
 
216
        if ((depth == 0) && chooserWidget && chooserWidget->comboBox()->count()) { //has already items
 
217
                //set now the right item
 
218
                if (CKeyChooserWidget* chooserWidget = m_chooserWidgets.at(depth)) {
 
219
                        chooserWidget->setItem( chooserWidget->comboBox()->text(currentItem) );
 
220
                }
 
221
 
 
222
                m_key->setOffset(oldOffset);
 
223
                return;
 
224
        }
 
225
 
 
226
 
 
227
        //insert an empty item at the top
 
228
        QStringList items;
 
229
        if (depth > 0) {
 
230
                items << QString::null;
 
231
        }
 
232
 
 
233
        do {
 
234
                items << QString::fromLocal8Bit(m_key->getLocalName());
 
235
        }
 
236
        while (m_key->nextSibling());
 
237
 
 
238
        if (chooserWidget) {
 
239
                chooserWidget->reset(items,currentItem,false);
 
240
        }
 
241
 
 
242
        //restore old key
 
243
        //  m_key->key(oldKey);
 
244
        m_key->setOffset( oldOffset );
 
245
}
 
246
 
 
247
/** A keychooser changed. Update and emit a signal if necessary. */
 
248
void CBookKeyChooser::keyChooserChanged(int /*newIndex*/) {
 
249
        const int activeID = boxes[const_cast<QObject*>(sender())]; //no so good code!
 
250
 
 
251
        QStringList items;
 
252
        CKeyChooserWidget* chooser;
 
253
        const int count = m_chooserWidgets.count();
 
254
 
 
255
        for (int i = 0; i < count; ++i) {
 
256
                chooser = m_chooserWidgets.at(i);
 
257
                const QString currentText =
 
258
                        (chooser && chooser->comboBox())
 
259
                        ? chooser->comboBox()->currentText()
 
260
                        : QString::null;
 
261
 
 
262
                if (currentText.isEmpty() || i > activeID) {
 
263
                        break;
 
264
                }
 
265
 
 
266
                items << currentText;
 
267
        }
 
268
 
 
269
        QString newKey("/");
 
270
        newKey.append(items.join("/"));
 
271
        if (newKey.length() > 1) {
 
272
                newKey.remove(newKey.length(),1); //remove the traling slash
 
273
        }
 
274
 
 
275
        //  qWarning("key changed: setting to %s", newKey.latin1());
 
276
        m_key->key(newKey);
 
277
        setKey(m_key);
 
278
}
 
279
 
 
280
/** Updates the keychoosers for the given key but emit no signal. */
 
281
void CBookKeyChooser::updateKey(CSwordKey* key) {
 
282
        setKey(key, false);
 
283
}
 
284