summaryrefslogtreecommitdiff
path: root/src/backend/btmoduletreeitem.h
blob: b159c6ff5cbe40a7ca0713de46b997205d6ea108 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
/*********
*
* This file is part of BibleTime's source code, http://www.bibletime.info/.
*
* Copyright 1999-2008 by the BibleTime developers.
* The BibleTime source code is licensed under the GNU General Public License version 2.0.
*
**********/

#ifndef BTMODULETREEITEM_H
#define BTMODULETREEITEM_H

#include "backend/drivers/cswordmoduleinfo.h"

#include <QString>


/**
Item of a tree which represents Sword modules categorized and filtered.
Can be used when building trees for different views.

The tree will be created with the public constructor. It creates the root item and
populates it with the rest of the tree. The root item is the handle to the tree.
Users can get the list of the children and operate on it recursively.

The tree is meant to be created, read and then deleted. If you need to apply for example
different set of filters you have to create a new tree - it's not possible to modify the tree.

Example:

	...
	QList<BTModuleTreeItem::Filter*> noFilters
	BTModuleTreeItem root(noFilters, BTModuleTreeItem::CatLangMod);
	add_to_view(&root, qtreewidget->invisibleRootItem());
	...
	void add_to_view(BTModuleTreeItem* item, QTreeWidgetItem* widgetItem) {
		foreach (BTModuleTreeItem* i, item->children()) {
			add_to_view(i, new QTreeWidgetItem(widgetItem));
		}
		if (item->type() == BTModuleTreeItem::Category) prepare_category_item(widgetItem, item);
		...
	}


	@author The BibleTime team <info@bibletime.info>
*/
class BTModuleTreeItem {
    public:

        /**
        * A filter which is given to the root constructor. It filters some modules
        * out from the tree. If it returns true when the filter() is called the module will be added,
        * if it returns false the module will be left out.
        *
        * If you want for example to get only unindexed modules in the list you should
        * write a class (possibly a small inner class inside the calling class) which
        * inherits Filter and write the operator() function which returns true if the
        * module is unindexed and false if it's indexed.
        *
        * It's also possible to do arbitrary tasks to modules by using more complex subclasses.
        *
        * The filters will be applied in the order in which they are in the list.
        * A module will be filtered out if even one filter rejects it and testing
        * will stop with the first negative.
        *
        * Example:
        *	QList<BTModuleTreeItem::Filter*> filters;
        *	MyFilter filter; BTModuleTreeItem::HiddenOff hideFilter;
        *	filters.append(&hideFilter); filters.append(&filter);
        *	BTModuleTreeItem root(filters, BTModuleTreeItem::CatLangMod);
        */
        struct Filter {
            virtual bool filter(CSwordModuleInfo*) = 0;
            inline virtual ~Filter() {};
        };

        /**
        * One example of a filter which can be used with any view. If the module has been
        * set "hidden" it will be filtered out.
        */
        struct HiddenOff : public Filter {
            inline bool filter(CSwordModuleInfo* mi) {
                return !mi->isHidden();
            }
            inline virtual ~HiddenOff() {};
        };

        /**
        * Type of the item: root item, category (Bibles, Commentaries etc.), language or module.
        */
        enum Type {Root, Category, Language, Module};

        /**
        * Tells how to group the modules. For example:
        * CatLangMod: first category, second language, third module. Mod: don't use
        * Category or Language at all, Module is toplevel and tree is flat.
        */
        enum Grouping {CatLangMod, CatMod, LangCatMod, LangMod, Mod};


        /**
        * This constructor creates a root item. Create it for example with scoped_ptr or in stack.
        * The root item is populated with the item tree.
        * The constructor takes a list of filters (see Filter), grouping indicator (see Grouping)
        * and optionally the module list from which the tree is constructed
        * (by default CPointers::backend()->moduleList() is used).
        */
        BTModuleTreeItem(QList<BTModuleTreeItem::Filter*>& filters,
                         BTModuleTreeItem::Grouping grouping, QList<CSwordModuleInfo*>* modules = 0);

        /** When the root item is deleted the whole tree is deleted. */
        ~BTModuleTreeItem();

        /**
        * Returns the item type.
        */
        inline BTModuleTreeItem::Type type() const {
            return m_type;
        }
        /**
        * Returns the item text (category name, language name or module name).
        */
        inline QString text() const {
            return m_text;
        }
        /**
        * Returns the path to the icon which is appropriate for this type of item, or QString::null.
        */
        QString iconName() const;
        /**
        * If the type is Module returns a pointer to the corresponding CSwordModuleInfo object,
        * otherwise returns 0.
        */
        inline CSwordModuleInfo* moduleInfo() const {
            return m_moduleInfo;
        }
        /**
        * Returns a list of the direct children of this item.
        */
        QList<BTModuleTreeItem*> children() const;

        /**
        * For alphabetical sorting which uses text(). See QString::localeAwareCompare().
        * Categories will always be in the same order regardless of the i18n.
        */
        static bool localeAwareLessThan(BTModuleTreeItem* first, BTModuleTreeItem* second);


    private:
        /**
        * Private constructor which sets the members.
        */
        BTModuleTreeItem(BTModuleTreeItem* parentItem, const QString& text, Type type, CSwordModuleInfo* info = 0, CSwordModuleInfo::Category category = CSwordModuleInfo::UnknownCategory);
        /** Default ctor is private because it is not to be called.*/
        BTModuleTreeItem();

        /** Creates the tree under this root item (called only from root ctor). */
        void create_tree(QList<BTModuleTreeItem::Filter*>& filters, BTModuleTreeItem::Grouping grouping);
        /** Sorts recursively the children of of the given item. */
        void sort_children(BTModuleTreeItem* parent);
        /** Helper function for creating a group item while creating the tree. */
        BTModuleTreeItem* create_parent_item(BTModuleTreeItem* parent, const QString& text, BTModuleTreeItem::Type type, CSwordModuleInfo::Category category = CSwordModuleInfo::UnknownCategory);

        CSwordModuleInfo* m_moduleInfo;
        QString m_text;
        BTModuleTreeItem* m_firstChild;
        BTModuleTreeItem* m_next;
        Type m_type;
        CSwordModuleInfo::Category m_category;
        QList<CSwordModuleInfo*> m_originalModuleList;
};

#endif