~ubuntu-branches/ubuntu/intrepid/bibletime/intrepid

« back to all changes in this revision

Viewing changes to bibletime/frontend/mainindex/cmainindex.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Ralph Janke
  • Date: 2008-05-10 15:18:16 UTC
  • mfrom: (1.1.6 upstream) (3.1.1 lenny)
  • Revision ID: james.westby@ubuntu.com-20080510151816-bqp8y1to705zd0fm
Tags: 1.6.5.1-1
* New upstream version (Closes: #441161, #271502)
* fixes for new autotools and gcc 4.3 (Closes: #407291)
* added poxml to Build-Depends
* No DFSG necessary anymore since biblestudy howto has 
  now Commons Licence 
* Added libclucene-dev to dev-depends (Closes: #436677)

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
//BibleTime includes
 
13
#include "cmainindex.h"
 
14
#include "cindexitem.h"
 
15
 
 
16
#include "backend/creferencemanager.h"
 
17
#include "backend/cswordmoduleinfo.h"
 
18
 
 
19
#include "frontend/searchdialog/csearchdialog.h"
 
20
#include "frontend/cbtconfig.h"
 
21
#include "frontend/cdragdropmgr.h"
 
22
#include "frontend/cinfodisplay.h"
 
23
 
 
24
#include "frontend/cprinter.h"
 
25
 
 
26
#include "util/cresmgr.h"
 
27
#include "util/scoped_resource.h"
 
28
 
 
29
//Qt includes
 
30
#include <qheader.h>
 
31
#include <qlistview.h>
 
32
#include <qdragobject.h>
 
33
#include <qinputdialog.h>
 
34
#include <qregexp.h>
 
35
 
 
36
//KDE includes
 
37
#include <klocale.h>
 
38
#include <kstandarddirs.h>
 
39
#include <kpopupmenu.h>
 
40
#include <kmessagebox.h>
 
41
#include <kglobalsettings.h>
 
42
 
 
43
using namespace Printing;
 
44
 
 
45
CMainIndex::ToolTip::ToolTip(CMainIndex* parent) : QToolTip(parent->viewport()), m_mainIndex(parent) {}
 
46
 
 
47
void CMainIndex::ToolTip::maybeTip(const QPoint& p) {
 
48
        CItemBase* i = dynamic_cast<CItemBase*>(m_mainIndex->itemAt(p));
 
49
        Q_ASSERT(i);
 
50
        if ( !i ) {
 
51
                return;
 
52
        }
 
53
 
 
54
        QRect r = m_mainIndex->itemRect(i);
 
55
        if (!r.isValid()) {
 
56
                return;
 
57
        }
 
58
 
 
59
        //get type of item and display correct text
 
60
        const QString text = i->toolTip();
 
61
        if (!text.isEmpty()) {
 
62
                CBookmarkItem* bookmark = dynamic_cast<CBookmarkItem*>(i);
 
63
                if (bookmark) {
 
64
                        (CPointers::infoDisplay())->setInfo(
 
65
                                InfoDisplay::CInfoDisplay::CrossReference,
 
66
                                bookmark->module()->name() + ":" + bookmark->key()
 
67
                        );
 
68
                }
 
69
                else {
 
70
                        CPointers::infoDisplay()->clearInfo();
 
71
                }
 
72
 
 
73
                tip(r, text);
 
74
        }
 
75
        else {
 
76
                CPointers::infoDisplay()->clearInfo();
 
77
        }
 
78
}
 
79
 
 
80
CMainIndex::CMainIndex(QWidget *parent) : KListView(parent),
 
81
m_searchDialog(0), m_toolTip(0), m_itemsMovable(false), m_autoOpenFolder(0), m_autoOpenTimer(this) {
 
82
        initView();
 
83
        initConnections();
 
84
        //initTree() is called in polish()
 
85
}
 
86
 
 
87
CMainIndex::~CMainIndex() {
 
88
        saveSettings();
 
89
        saveBookmarks();
 
90
 
 
91
        m_toolTip->remove(this);
 
92
        delete m_toolTip;
 
93
}
 
94
 
 
95
/** Reimplementation. Adds the given group to the tree. */
 
96
void CMainIndex::addGroup(const CItemBase::Type type, const QString language) {
 
97
        CTreeFolder *i = 0;
 
98
        switch (type) {
 
99
                case CItemBase::BookmarkFolder:
 
100
                        i = new CBookmarkFolder(this);
 
101
                        break;
 
102
                case CItemBase::GlossaryModuleFolder:
 
103
                        //we have no second language
 
104
                        i = new CGlossaryFolder(this, type, language, QString::null); 
 
105
                        break;
 
106
                default:
 
107
                        i = new CTreeFolder(this, type, language);
 
108
                        break;
 
109
        }
 
110
        
 
111
        if (i) {
 
112
                i->init();
 
113
                if (i->childCount() == 0 && type != CItemBase::BookmarkFolder) {
 
114
                        delete i;
 
115
                }
 
116
        }
 
117
}
 
118
 
 
119
 
 
120
/** Initializes the view. */
 
121
void CMainIndex::initView() {
 
122
        addColumn(QString::null);
 
123
        header()->hide();
 
124
 
 
125
        m_toolTip = new ToolTip(this);
 
126
        setTooltipColumn(-1);
 
127
        //to disable Qt's tooltips
 
128
        setShowToolTips(false);
 
129
 
 
130
        setBackgroundMode(PaletteBase);
 
131
        setFullWidth(true);
 
132
        setFocusPolicy(WheelFocus);
 
133
 
 
134
        setAcceptDrops( true );
 
135
        setDragEnabled( true );
 
136
        setDropVisualizer( true );
 
137
        setDropHighlighter( true );
 
138
        setAutoOpen(true);
 
139
        viewport()->setAcceptDrops(true);
 
140
        setRootIsDecorated(false);
 
141
        setAllColumnsShowFocus(true);
 
142
        setItemsMovable(false);
 
143
        setSelectionModeExt(Extended);
 
144
 
 
145
        //setup the popup menu
 
146
        m_popup = new KPopupMenu(viewport());
 
147
        m_popup->insertTitle(i18n("Bookshelf"));
 
148
 
 
149
        m_actions.newFolder = new KAction(i18n("Create a new folder"), CResMgr::mainIndex::newFolder::icon, 0, this, SLOT(createNewFolder()), this);
 
150
        m_actions.changeFolder = new KAction(i18n("Change this folder"),CResMgr::mainIndex::changeFolder::icon, 0, this, SLOT(changeFolder()), this);
 
151
 
 
152
        m_actions.changeBookmark = new KAction(i18n("Change bookmark description"),CResMgr::mainIndex::changeBookmark::icon, 0, this, SLOT(changeBookmark()), this);
 
153
        m_actions.importBookmarks = new KAction(i18n("Import bookmarks"),CResMgr::mainIndex::importBookmarks::icon, 0, this, SLOT(importBookmarks()), this);
 
154
        m_actions.exportBookmarks = new KAction(i18n("Export bookmarks"),CResMgr::mainIndex::exportBookmarks::icon, 0, this, SLOT(exportBookmarks()), this);
 
155
        m_actions.printBookmarks = new KAction(i18n("Print bookmarks"),CResMgr::mainIndex::printBookmarks::icon, 0, this, SLOT(printBookmarks()), this);
 
156
 
 
157
        m_actions.deleteEntries = new KAction(i18n("Remove selected item(s)"),CResMgr::mainIndex::deleteItems::icon, 0, this, SLOT(deleteEntries()), this);
 
158
 
 
159
        m_actions.editModuleMenu = new KActionMenu(i18n("Edit this work"),CResMgr::mainIndex::editModuleMenu::icon, this);
 
160
        m_actions.editModuleMenu->setDelayed(false);
 
161
        m_actions.editModulePlain = new KAction(i18n("Plain text"),CResMgr::mainIndex::editModulePlain::icon, 0, this, SLOT(editModulePlain()), this);
 
162
        m_actions.editModuleHTML = new KAction(i18n("HTML"),CResMgr::mainIndex::editModuleHTML::icon, 0, this, SLOT(editModuleHTML()), this);
 
163
        
 
164
        m_actions.searchInModules = new KAction(i18n("Search in selected work(s)"),CResMgr::mainIndex::search::icon, 0, this, SLOT(searchInModules()), this);
 
165
        m_actions.unlockModule = new KAction(i18n("Unlock this work"),CResMgr::mainIndex::unlockModule::icon, 0, this, SLOT(unlockModule()), this);
 
166
        m_actions.aboutModule = new KAction(i18n("About this work"),CResMgr::mainIndex::aboutModule::icon, 0, this, SLOT(aboutModule()), this);
 
167
 
 
168
 
 
169
        //fill the popup menu itself
 
170
        m_actions.newFolder->plug(m_popup);
 
171
        m_actions.changeFolder->plug(m_popup);
 
172
        (new KActionSeparator(this))->plug(m_popup);
 
173
        m_actions.changeBookmark->plug(m_popup);
 
174
        m_actions.importBookmarks->plug(m_popup);
 
175
        m_actions.exportBookmarks->plug(m_popup);
 
176
        m_actions.printBookmarks->plug(m_popup);
 
177
        (new KActionSeparator(this))->plug(m_popup);
 
178
        m_actions.deleteEntries->plug(m_popup);
 
179
        (new KActionSeparator(this))->plug(m_popup);
 
180
        m_actions.editModuleMenu->plug(m_popup);
 
181
        //sub item of edit module menu
 
182
        m_actions.editModuleMenu->insert(m_actions.editModulePlain); 
 
183
        //sub item of edit module menu
 
184
        m_actions.editModuleMenu->insert(m_actions.editModuleHTML);  
 
185
 
 
186
        m_actions.searchInModules->plug(m_popup);
 
187
        m_actions.unlockModule->plug(m_popup);
 
188
        m_actions.aboutModule->plug(m_popup);
 
189
}
 
190
 
 
191
/** Initialize the SIGNAL<->SLOT connections */
 
192
void CMainIndex::initConnections() {
 
193
        connect(this, SIGNAL(executed(QListViewItem*)),
 
194
                        SLOT(slotExecuted(QListViewItem*)));
 
195
        connect(this, SIGNAL(dropped(QDropEvent*, QListViewItem*, QListViewItem*)),
 
196
                        SLOT(dropped(QDropEvent*, QListViewItem*, QListViewItem*)));
 
197
        connect(this, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)),
 
198
                        SLOT(contextMenu(KListView*, QListViewItem*, const QPoint&)));
 
199
        connect(&m_autoOpenTimer, SIGNAL(timeout()),
 
200
                        this, SLOT(autoOpenTimeout()));
 
201
}
 
202
 
 
203
/** Is called when an item was clicked/double clicked. */
 
204
void CMainIndex::slotExecuted( QListViewItem* i ) {
 
205
        CItemBase* ci = dynamic_cast<CItemBase*>(i);
 
206
        if (!ci) {
 
207
                return;
 
208
        }
 
209
 
 
210
        if (ci->isFolder()) {
 
211
                i->setOpen(!i->isOpen());
 
212
        }
 
213
        else if (CModuleItem* m = dynamic_cast<CModuleItem*>(i))  { //clicked on a module
 
214
                CSwordModuleInfo* mod = m->module();
 
215
                ListCSwordModuleInfo modules;
 
216
                modules.append(mod);
 
217
                emit createReadDisplayWindow(modules, QString::null);
 
218
        }
 
219
        else if (CBookmarkItem* b = dynamic_cast<CBookmarkItem*>(i) ) { //clicked on a bookmark
 
220
                if (CSwordModuleInfo* mod = b->module()) {
 
221
                        ListCSwordModuleInfo modules;
 
222
                        modules.append(mod);
 
223
                        emit createReadDisplayWindow(modules, b->key());
 
224
                }
 
225
        }
 
226
}
 
227
 
 
228
/** Reimplementation. Returns the drag object for the current selection. */
 
229
QDragObject* CMainIndex::dragObject() {
 
230
        if (!m_itemsMovable) {
 
231
                return false;
 
232
        }
 
233
 
 
234
        CDragDropMgr::ItemList dndItems;
 
235
 
 
236
        QPtrList<QListViewItem> items = selectedItems();
 
237
        for (items.first(); items.current(); items.next()) {
 
238
                if (CItemBase* i = dynamic_cast<CItemBase*>(items.current())) {
 
239
                        //we can move this item!
 
240
                        if (!i->isMovable()) { //we can only drag items which allow us to do it, e.g. which are movable
 
241
                                continue;
 
242
                        }
 
243
 
 
244
                        if (CBookmarkItem* bookmark = dynamic_cast<CBookmarkItem*>( items.current() )) {
 
245
                                //take care of bookmarks which have no valid module any more, e.g. if it was uninstalled
 
246
                                const QString moduleName = bookmark->module() ? bookmark->module()->name() : QString::null;
 
247
                                dndItems.append( CDragDropMgr::Item(moduleName, bookmark->key(), bookmark->description()) );
 
248
                        }
 
249
                }
 
250
        }
 
251
 
 
252
        return CDragDropMgr::dragObject( dndItems, viewport() );
 
253
}
 
254
 
 
255
/** Reimplementation from KListView. Returns true if the drag is acceptable for the listview. */
 
256
bool CMainIndex::acceptDrag( QDropEvent* event ) const {
 
257
        const QPoint pos = contentsToViewport(event->pos());
 
258
 
 
259
        CItemBase* i = dynamic_cast<CItemBase*>(itemAt(pos));
 
260
        return i ? (i->acceptDrop(event) || i->isMovable()) : false;
 
261
}
 
262
 
 
263
/** No descriptions */
 
264
void CMainIndex::initTree() {
 
265
        addGroup(CItemBase::BookmarkFolder, QString("*"));
 
266
        addGroup(CItemBase::BibleModuleFolder, QString("*"));
 
267
        addGroup(CItemBase::BookModuleFolder, QString("*"));
 
268
        addGroup(CItemBase::CommentaryModuleFolder, QString("*"));
 
269
        addGroup(CItemBase::DevotionalModuleFolder, QString("*"));
 
270
        addGroup(CItemBase::GlossaryModuleFolder, QString("*"));
 
271
        addGroup(CItemBase::LexiconModuleFolder, QString("*"));
 
272
}
 
273
 
 
274
/** No descriptions */
 
275
void CMainIndex::dropped( QDropEvent* e, QListViewItem* parent, QListViewItem* after) {
 
276
        Q_ASSERT(after);
 
277
        Q_ASSERT(parent);
 
278
 
 
279
        //the drop was started in this main index widget
 
280
        if (m_itemsMovable && ((e->source()) == (viewport()))) {
 
281
                /*
 
282
                * If the drag was started from the main index and should move items and if the destination is the bookmark
 
283
                * folder or one of its subfolders
 
284
                * we remove the current items because the new ones will be inserted soon.
 
285
                */
 
286
                if (dynamic_cast<CBookmarkFolder*>(parent) || dynamic_cast<Bookmarks::SubFolder*>(parent)) { 
 
287
                        // we drop onto the bookmark folder or one of it's subfolders
 
288
                        //       QPtrList<QListViewItem> items = selectedItems();
 
289
                        //       items.setAutoDelete(true);
 
290
                        //       items.clear(); //delete the selected items we dragged
 
291
                }
 
292
        }
 
293
 
 
294
        //finally do the drop, either with external drop data or with the moved items' data
 
295
        CItemBase* const parentItem = dynamic_cast<CItemBase*>(parent);
 
296
        CItemBase* const afterItem  = dynamic_cast<CItemBase*>(after);
 
297
 
 
298
        bool removeSelectedItems = true;
 
299
        bool moveSelectedItems = false;
 
300
 
 
301
        if (afterItem && afterItem->isFolder()) {
 
302
                moveSelectedItems = false;
 
303
                removeSelectedItems = false; //why TRUE?
 
304
 
 
305
                afterItem->setOpen(true);
 
306
                afterItem->dropped(e); //inserts new items, moving only works on the same level
 
307
        }
 
308
        else if (afterItem && !afterItem->isFolder() && parentItem) {
 
309
                const bool justMoveSelected =
 
310
                        (e->source() == viewport())
 
311
                        && m_itemsMovable
 
312
                        && parentItem->acceptDrop(e)
 
313
                        && !afterItem->acceptDrop(e);
 
314
 
 
315
                if (justMoveSelected) {
 
316
                        moveSelectedItems = true;
 
317
                        removeSelectedItems = false;
 
318
                }
 
319
                else {
 
320
                        moveSelectedItems = false;
 
321
                        removeSelectedItems = false;
 
322
 
 
323
                        if (afterItem->acceptDrop(e)) {
 
324
                                afterItem->dropped(e, after);
 
325
                        }
 
326
                        else { //insert in the parent folder and then move the inserted items
 
327
                                parentItem->dropped(e, after);
 
328
                        }
 
329
                }
 
330
 
 
331
                parentItem->setOpen(true);
 
332
        }
 
333
        else if (parentItem) { //no after item present, but a parent is there
 
334
                moveSelectedItems = false;
 
335
                removeSelectedItems = false;
 
336
 
 
337
                parentItem->setOpen(true);
 
338
                parentItem->dropped(e);
 
339
        }
 
340
 
 
341
        if (moveSelectedItems) {
 
342
                //move all selected items after the afterItem
 
343
                if (m_itemsMovable) {
 
344
                        QPtrList<QListViewItem> items = selectedItems();
 
345
                        QListViewItem* i = items.first();
 
346
                        QListViewItem* after = afterItem;
 
347
                        while (i && afterItem) {
 
348
                                i->moveItem(after);
 
349
                                after = i;
 
350
 
 
351
                                i = items.next();
 
352
                        }
 
353
                }
 
354
        }
 
355
 
 
356
        if (removeSelectedItems) {
 
357
                QPtrList<QListViewItem> items = selectedItems();
 
358
                items.setAutoDelete(true);
 
359
                items.clear(); //delete the selected items we dragged
 
360
        }
 
361
}
 
362
 
 
363
/** No descriptions */
 
364
void CMainIndex::emitModulesChosen( ListCSwordModuleInfo modules, QString key ) {
 
365
        emit createReadDisplayWindow(modules, key);
 
366
}
 
367
 
 
368
/** Returns the correct KAction object for the given type of action. */
 
369
KAction* const CMainIndex::action( const CItemBase::MenuAction type ) const {
 
370
        switch (type) {
 
371
        case CItemBase::NewFolder:
 
372
                return m_actions.newFolder;
 
373
        case CItemBase::ChangeFolder:
 
374
                return m_actions.changeFolder;
 
375
 
 
376
        case CItemBase::ChangeBookmark:
 
377
                return m_actions.changeBookmark;
 
378
        case CItemBase::ImportBookmarks:
 
379
                return m_actions.importBookmarks;
 
380
        case CItemBase::ExportBookmarks:
 
381
                return m_actions.exportBookmarks;
 
382
        case CItemBase::PrintBookmarks:
 
383
                return m_actions.printBookmarks;
 
384
 
 
385
        case CItemBase::DeleteEntries:
 
386
                return m_actions.deleteEntries;
 
387
 
 
388
        case CItemBase::EditModule:
 
389
                return m_actions.editModuleMenu;
 
390
        case CItemBase::SearchInModules:
 
391
                return m_actions.searchInModules;
 
392
        case CItemBase::UnlockModule:
 
393
                return m_actions.unlockModule;
 
394
        case CItemBase::AboutModule:
 
395
                return m_actions.aboutModule;
 
396
        default:
 
397
                return 0;
 
398
        }
 
399
}
 
400
 
 
401
/** Shows the context menu at the given position. */
 
402
void CMainIndex::contextMenu(KListView* /*list*/, QListViewItem* i, const QPoint& p) {
 
403
        //setup menu entries depending on current selection
 
404
        QPtrList<QListViewItem> items = selectedItems();
 
405
 
 
406
        if (items.count() == 0) { 
 
407
                //special handling for no selection
 
408
        }
 
409
        else if (items.count() == 1) { 
 
410
                //special handling for one selected item
 
411
                
 
412
                CItemBase* item = dynamic_cast<CItemBase*>(i);
 
413
                CItemBase::MenuAction actionType;
 
414
                for (int index = CItemBase::ActionBegin; index <= CItemBase::ActionEnd; ++index) {
 
415
                        actionType = static_cast<CItemBase::MenuAction>(index);
 
416
                        if (KAction* a = action(actionType))
 
417
                                a->setEnabled( item->enableAction(actionType) );
 
418
                }
 
419
        }
 
420
        else {
 
421
                //first disable all actions
 
422
                CItemBase::MenuAction actionType;
 
423
                for (int index = CItemBase::ActionBegin; index <= CItemBase::ActionEnd; ++index) {
 
424
                        actionType = static_cast<CItemBase::MenuAction>(index);
 
425
                        if (KAction* a = action(actionType))
 
426
                                a->setEnabled(false);
 
427
                }
 
428
 
 
429
                //enable the menu items depending on the types of the selected items.
 
430
                for (int index = CItemBase::ActionBegin; index <= CItemBase::ActionEnd; ++index) {
 
431
                        actionType = static_cast<CItemBase::MenuAction>(index);
 
432
                        bool enableAction = isMultiAction(actionType);
 
433
                        for (items.first(); items.current(); items.next()) {
 
434
                                CItemBase* i = dynamic_cast<CItemBase*>(items.current());
 
435
                                enableAction = enableAction && i->enableAction(actionType);
 
436
                        }
 
437
                        if (enableAction) {
 
438
                                KAction* a = action(actionType) ;
 
439
                                if (i && a)
 
440
                                        a->setEnabled(enableAction);
 
441
                        }
 
442
                }
 
443
        }
 
444
        
 
445
        //finally, open the popup
 
446
        m_popup->exec(p);
 
447
}
 
448
 
 
449
/** Adds a new subfolder to the current item. */
 
450
void CMainIndex::createNewFolder() {
 
451
        CFolderBase* i = dynamic_cast<CFolderBase*>(currentItem());
 
452
        Q_ASSERT(i);
 
453
        
 
454
        if (i) {
 
455
                i->newSubFolder();
 
456
        }
 
457
}
 
458
 
 
459
/** Opens a dialog to change the current folder. */
 
460
void CMainIndex::changeFolder() {
 
461
        CFolderBase* i = dynamic_cast<CFolderBase*>(currentItem());
 
462
        Q_ASSERT(i);
 
463
        if (i) {
 
464
                i->rename();
 
465
        }
 
466
}
 
467
 
 
468
/** Changes the current bookmark. */
 
469
void CMainIndex::changeBookmark() {
 
470
        CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(currentItem());
 
471
        Q_ASSERT(i);
 
472
        
 
473
        if (i) {
 
474
                i->rename();
 
475
        }
 
476
}
 
477
 
 
478
/** Exports the bookmarks being in the selected folder. */
 
479
void CMainIndex::exportBookmarks() {
 
480
        CBookmarkFolder* i = dynamic_cast<CBookmarkFolder*>(currentItem());
 
481
        Q_ASSERT(i);
 
482
        
 
483
        if (i) {
 
484
                i->exportBookmarks();
 
485
        }
 
486
}
 
487
 
 
488
/** Import bookmarks from a file and add them to the selected folder. */
 
489
void CMainIndex::importBookmarks() {
 
490
        CBookmarkFolder* i = dynamic_cast<CBookmarkFolder*>(currentItem());
 
491
        Q_ASSERT(i);
 
492
        
 
493
        if (i) {
 
494
                i->importBookmarks();
 
495
        }
 
496
}
 
497
 
 
498
/** Prints the selected bookmarks. */
 
499
void CMainIndex::printBookmarks() {
 
500
        CPrinter::KeyTree tree;
 
501
        CPrinter::KeyTreeItem::Settings settings;
 
502
        settings.keyRenderingFace = CPrinter::KeyTreeItem::Settings::CompleteShort;
 
503
 
 
504
        QPtrList<QListViewItem> items;
 
505
        CBookmarkFolder* bf = dynamic_cast<CBookmarkFolder*>(currentItem());
 
506
 
 
507
        if (bf) {
 
508
                items = bf->getChildList();
 
509
        }
 
510
        else {
 
511
                items = selectedItems();
 
512
        }
 
513
 
 
514
        //create a tree of keytreeitems using the bookmark hierarchy.
 
515
        for (items.first(); items.current(); items.next()) {
 
516
                CBookmarkItem* i = dynamic_cast<CBookmarkItem*>(items.current());
 
517
                if (i) {
 
518
                        tree.append( new CPrinter::KeyTreeItem( i->key(), i->module(), settings ) );
 
519
                }
 
520
        }
 
521
 
 
522
        util::scoped_ptr<CPrinter> printer( 
 
523
                new CPrinter( this, CBTConfig::getDisplayOptionDefaults(), CBTConfig::getFilterOptionDefaults() ) 
 
524
        );
 
525
        printer->printKeyTree(tree);
 
526
}
 
527
 
 
528
/** Deletes the selected entries. */
 
529
void CMainIndex::deleteEntries() {
 
530
        QPtrList<QListViewItem> items = selectedItems();
 
531
        if (!items.count())
 
532
                return;
 
533
 
 
534
        if (KMessageBox::warningYesNo(this, i18n("Do you really want to delete the selected items and child-items?"), i18n("Delete Items")) != KMessageBox::Yes) {
 
535
                return;
 
536
        }
 
537
 
 
538
        // We have to go backwards because otherwise deleting folders would delete their childs => crash before we delete those
 
539
        for (items.last(); items.current(); items.prev()) {
 
540
                if (CItemBase* i = dynamic_cast<CItemBase*>(items.current())) {
 
541
                        if (i->enableAction(CItemBase::DeleteEntries)) {
 
542
                                delete i;
 
543
                        }
 
544
                }
 
545
        }
 
546
}
 
547
 
 
548
/** Opens the searchdialog for the selected modules. */
 
549
void CMainIndex::searchInModules() {
 
550
        QPtrList<QListViewItem> items = selectedItems();
 
551
        ListCSwordModuleInfo modules;
 
552
        for (items.first(); items.current(); items.next()) {
 
553
                if (CModuleItem* i = dynamic_cast<CModuleItem*>(items.current())) {
 
554
                        if (i->module()) {
 
555
                                modules.append(i->module());
 
556
                        }
 
557
                }
 
558
        }
 
559
 
 
560
        if (modules.isEmpty()) { //get a list of useful default modules for the search if no modules were selected
 
561
                CSwordModuleInfo* m = CBTConfig::get(CBTConfig::standardBible);
 
562
                if (m) {
 
563
                        modules.append(m);
 
564
                }
 
565
        }
 
566
 
 
567
        Search::CSearchDialog::openDialog(modules, QString::null);
 
568
}
 
569
 
 
570
/** Unlocks the current module. */
 
571
void CMainIndex::unlockModule() {
 
572
        if (CModuleItem* i = dynamic_cast<CModuleItem*>(currentItem())) {
 
573
                bool ok = false;
 
574
                const QString unlockKey = QInputDialog::getText(i18n("BibleTime - Unlock work"),
 
575
                        i18n("Enter the unlock key for this work."),
 
576
                        QLineEdit::Normal, i->module()->config(CSwordModuleInfo::CipherKey), &ok);
 
577
                
 
578
                if (ok) {
 
579
                        i->module()->unlock( unlockKey );
 
580
                        emit signalSwordSetupChanged();
 
581
                }
 
582
        }
 
583
}
 
584
 
 
585
/** Shows information about the current module. */
 
586
void CMainIndex::aboutModule() {
 
587
        if (CModuleItem* i = dynamic_cast<CModuleItem*>(currentItem())) {
 
588
                KMessageBox::about(this, i->module()->aboutText(), i->module()->config(CSwordModuleInfo::Description), false);
 
589
        }
 
590
}
 
591
 
 
592
/** Reimplementation. Takes care of movable items. */
 
593
void CMainIndex::startDrag() {
 
594
        QPtrList<QListViewItem> items = selectedItems();
 
595
        m_itemsMovable = true;
 
596
 
 
597
        for (items.first(); items.current() && m_itemsMovable; items.next()) {
 
598
                if (CItemBase* i = dynamic_cast<CItemBase*>(items.current())) {
 
599
                        m_itemsMovable = (m_itemsMovable && i->isMovable());
 
600
                }
 
601
                else {
 
602
                        m_itemsMovable = false;
 
603
                }
 
604
        }
 
605
 
 
606
        KListView::startDrag();
 
607
}
 
608
 
 
609
/** Reimplementation to support the items dragEnter and dragLeave functions. */
 
610
void CMainIndex::contentsDragMoveEvent( QDragMoveEvent* event ) {
 
611
        //  qWarning("void CMainIndex:: drag move event ( QDragLeaveEvent* e )");
 
612
        CItemBase* i = dynamic_cast<CItemBase*>( itemAt( contentsToViewport(event->pos())) );
 
613
        if (i) {
 
614
                if (i->allowAutoOpen(event) || (i->acceptDrop(event) && i->isFolder() && i->allowAutoOpen(event) && !i->isOpen() && autoOpen()) ) {
 
615
                        if (m_autoOpenFolder != i)  {
 
616
                                m_autoOpenTimer.stop();
 
617
                        }
 
618
                        
 
619
                        m_autoOpenFolder = i;
 
620
                        m_autoOpenTimer.start( 400, true );
 
621
                }
 
622
                else {
 
623
                        m_autoOpenFolder = 0;
 
624
                }
 
625
        }
 
626
        else {
 
627
                m_autoOpenFolder = 0;
 
628
        }
 
629
 
 
630
        KListView::contentsDragMoveEvent(event);
 
631
}
 
632
 
 
633
QRect CMainIndex::drawItemHighlighter(QPainter* painter, QListViewItem* item) {
 
634
        CBookmarkItem* bookmark = dynamic_cast<CBookmarkItem*>(item);
 
635
        if (bookmark) { 
 
636
                //no drops on bookmarks allowed, just moving items after it
 
637
                return QRect();
 
638
        }
 
639
 
 
640
        return KListView::drawItemHighlighter(painter, item);
 
641
}
 
642
 
 
643
 
 
644
void CMainIndex::autoOpenTimeout() {
 
645
        m_autoOpenTimer.stop();
 
646
        if (m_autoOpenFolder && !m_autoOpenFolder->isOpen() && m_autoOpenFolder->childCount()) {
 
647
                m_autoOpenFolder->setOpen(true);
 
648
        }
 
649
}
 
650
 
 
651
/** No descriptions */
 
652
void CMainIndex::contentsDragLeaveEvent( QDragLeaveEvent* e ) {
 
653
        m_autoOpenTimer.stop();
 
654
        KListView::contentsDragLeaveEvent(e);
 
655
}
 
656
 
 
657
/** Returns true if more than one netry is supported by this action type. Returns false for actions which support only one entry, e.g. about module etc. */
 
658
const bool CMainIndex::isMultiAction( const CItemBase::MenuAction type ) const {
 
659
        switch (type) {
 
660
        case CItemBase::NewFolder:
 
661
                return false;
 
662
        case CItemBase::ChangeFolder:
 
663
                return false;
 
664
 
 
665
        case CItemBase::ChangeBookmark:
 
666
                return false;
 
667
        case CItemBase::ImportBookmarks:
 
668
                return false;
 
669
        case CItemBase::ExportBookmarks:
 
670
                return false;
 
671
        case CItemBase::PrintBookmarks:
 
672
                return true;
 
673
 
 
674
        case CItemBase::DeleteEntries:
 
675
                return true;
 
676
 
 
677
        case CItemBase::EditModule:
 
678
                return false;
 
679
        case CItemBase::SearchInModules:
 
680
                return true;
 
681
        case CItemBase::UnlockModule:
 
682
                return false;
 
683
        case CItemBase::AboutModule:
 
684
                return false;
 
685
        }
 
686
        
 
687
        return false;
 
688
}
 
689
 
 
690
/** Is called when items should be moved. */
 
691
void CMainIndex::moved( QPtrList<QListViewItem>& /*items*/, QPtrList<QListViewItem>& /*afterFirst*/, QPtrList<QListViewItem>& /*afterNow*/) {
 
692
        qDebug("move items");
 
693
}
 
694
 
 
695
/** Opens an editor window to edit the modules content. */
 
696
void CMainIndex::editModulePlain() {
 
697
        QPtrList<QListViewItem> items = selectedItems();
 
698
        ListCSwordModuleInfo modules;
 
699
        for (items.first(); items.current(); items.next()) {
 
700
                if (CModuleItem* i = dynamic_cast<CModuleItem*>(items.current())) {
 
701
                        modules.append(i->module());
 
702
                }
 
703
        }
 
704
        if (modules.count() == 1) {
 
705
                emit createWriteDisplayWindow(modules.first(), QString::null, CDisplayWindow::PlainTextWindow);
 
706
        };
 
707
}
 
708
 
 
709
/** Opens an editor window to edit the modules content. */
 
710
void CMainIndex::editModuleHTML() {
 
711
        QPtrList<QListViewItem> items = selectedItems();
 
712
        ListCSwordModuleInfo modules;
 
713
        for (items.first(); items.current(); items.next()) {
 
714
                if (CModuleItem* i = dynamic_cast<CModuleItem*>(items.current())) {
 
715
                        modules.append(i->module());
 
716
                }
 
717
        }
 
718
        
 
719
        if (modules.count() == 1) {
 
720
                emit createWriteDisplayWindow(modules.first(), QString::null, CDisplayWindow::HTMLWindow);
 
721
        }
 
722
}
 
723
 
 
724
/** Reloads the main index's Sword dependend things like modules */
 
725
void CMainIndex::reloadSword() {
 
726
        //reload the modules, save the open groups before removing the items
 
727
        saveSettings();
 
728
        clear();
 
729
        initTree();     
 
730
        readSettings();
 
731
}
 
732
 
 
733
/** Saves the bookmarks to disk */
 
734
void CMainIndex::saveBookmarks() {
 
735
        //find the bookmark folder
 
736
        CItemBase* i = 0;
 
737
 
 
738
        QListViewItemIterator it( this );
 
739
        while ( it.current() ) {
 
740
                i = dynamic_cast<CItemBase*>( it.current() );
 
741
 
 
742
                if (i && (i->type() == CItemBase::BookmarkFolder)) { 
 
743
                        //found the bookmark folder
 
744
                        KStandardDirs stdDirs;
 
745
 
 
746
                        const QString path = stdDirs.saveLocation("data", "bibletime/");
 
747
                        if (!path.isEmpty()) {
 
748
                                //save the bookmarks to the right file
 
749
                                if (CBookmarkFolder* f = dynamic_cast<CBookmarkFolder*>(i)) {
 
750
                                        f->saveBookmarks( path + "bookmarks.xml" );
 
751
                                }
 
752
                        }
 
753
                        break;
 
754
                }
 
755
 
 
756
                ++it;
 
757
        }
 
758
}
 
759
 
 
760
void CMainIndex::readSettings() {
 
761
        qDebug("CMainIndex::readSettings");
 
762
        
 
763
        QStringList openGroups = CBTConfig::get(CBTConfig::bookshelfOpenGroups);
 
764
        for (QStringList::Iterator it( openGroups.begin() ); it != openGroups.end(); ++it) {
 
765
                QStringList path = QStringList::split("/", (*it)); //e.g. with items parent, child
 
766
                QListViewItem* item = firstChild(); //begin on the top for each item
 
767
                Q_ASSERT(item);
 
768
                unsigned int index = 1;
 
769
 
 
770
                for (QStringList::Iterator p_it( path.begin() ); p_it != path.end(); ++p_it) {
 
771
                        QString itemName = (*p_it).replace("\\/", "/");
 
772
 
 
773
                        while (item && (item->text(0) != itemName)) {
 
774
                                item = item->nextSibling();
 
775
                        }
 
776
 
 
777
                        if (item && (item->text(0) == itemName)) {
 
778
                                if (index < path.count()) { //don't call firstChild on the right, i.e. last item of the list
 
779
                                        item = item->firstChild();
 
780
                                }
 
781
 
 
782
                                ++index;
 
783
                        }
 
784
                }
 
785
 
 
786
                if (item) {
 
787
                        item->setOpen(true);
 
788
                }
 
789
        }
 
790
 
 
791
        //restore the content position
 
792
//      setContentsPos(
 
793
//              CBTConfig::get(CBTConfig::bookshelfContentsX),
 
794
//              CBTConfig::get(CBTConfig::bookshelfContentsY)
 
795
//      );
 
796
//      horizontalScrollBar()->setValue(CBTConfig::get(CBTConfig::bookshelfContentsX));
 
797
//      verticalScrollBar()->setValue(CBTConfig::get(CBTConfig::bookshelfContentsY));
 
798
 
 
799
 
 
800
        //restore the selected item
 
801
        QStringList path = QStringList::split("/", CBTConfig::get(CBTConfig::bookshelfCurrentItem));
 
802
        QListViewItem* item = firstChild();
 
803
        Q_ASSERT(item);
 
804
        unsigned int index = 1;
 
805
        for (QStringList::iterator it( path.begin() ); it != path.end(); ++it) {
 
806
                //search for the current caption and go down to it's childs
 
807
                while (item && (item->text(0) != (*it)) ) {
 
808
                        item = item->nextSibling();
 
809
                }
 
810
 
 
811
                if (item && ((*it) == item->text(0))) {
 
812
                        if (index == path.count()) { //last item reached
 
813
                                setCurrentItem( item );
 
814
                                setSelected( item, true );
 
815
                                break;//for loop
 
816
                        }
 
817
                        else {
 
818
                                item = item->firstChild();
 
819
                        }
 
820
 
 
821
                        index++;
 
822
                }
 
823
        }
 
824
}
 
825
 
 
826
void CMainIndex::saveSettings() {
 
827
        //save the complete names of all open groups to the settings file (e.g. Bibles/German/,Bookmarks/Jeuss Christ
 
828
        QStringList openGroups;
 
829
 
 
830
        QListViewItemIterator it( this );
 
831
        while ( it.current() ) {
 
832
                if ( it.current()->isOpen() ) { //is a group and open
 
833
                        //it.current()'s full name needs to be added to the list
 
834
                        QListViewItem* i = it.current();
 
835
                        QString fullName = i->text(0);
 
836
                        while (i->parent()) {
 
837
                                i = i->parent();
 
838
                                fullName.prepend("/").prepend( i->text(0).replace("/", "\\/")); // parent / child
 
839
                        }
 
840
                        openGroups << fullName;
 
841
                }
 
842
 
 
843
                ++it;
 
844
        }
 
845
 
 
846
        CBTConfig::set(CBTConfig::bookshelfOpenGroups, openGroups);
 
847
 
 
848
        //now save the position of the scrollbars
 
849
//      CBTConfig::set(CBTConfig::bookshelfContentsX,
 
850
//              horizontalScrollBar() ? horizontalScrollBar()->value() : 0);
 
851
//      CBTConfig::set(CBTConfig::bookshelfContentsY,
 
852
//              verticalScrollBar() ? verticalScrollBar()->value() : 0);
 
853
 
 
854
        //save the currently selected item
 
855
        QListViewItem* item = currentItem();
 
856
        QString path;
 
857
        while (item) {
 
858
                path.prepend( item->text(0) + "/" );
 
859
                item = item->parent();
 
860
        }
 
861
        CBTConfig::set(CBTConfig::bookshelfCurrentItem, path);
 
862
}
 
863
 
 
864
void CMainIndex::polish()
 
865
{
 
866
        KListView::polish();
 
867
        initTree();
 
868
        readSettings();
 
869
}