1 /* This file is part of the KDE project
2    Copyright (C) 2004-2007 Jarosław Staniek <staniek@kde.org>
3 
4    This program is free software; you can redistribute it and,or
5    modify it under the terms of the GNU Library General Public
6    License as published by the Free Software Foundation; either
7    version 2 of the License, or (at your option) any later version.
8 
9    This program is distributed in the hope that it will be useful,
10    but WITHOUT ANY WARRANTY; without even the implied warranty of
11    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12    Library General Public License for more details.
13 
14    You should have received a copy of the GNU Library General Public License
15    along with this program; see the file COPYING.  If not, write to
16    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18 */
19 
20 #include "kexicelleditorfactory.h"
21 #include "kexidatetableedit.h"
22 #include "kexitimetableedit.h"
23 #include "kexidatetimetableedit.h"
24 #include "kexitableedit.h"
25 #include "kexiinputtableedit.h"
26 #include "kexicomboboxtableedit.h"
27 #include "kexiblobtableedit.h"
28 #include "kexibooltableedit.h"
29 
30 #include <KDbQueryColumnInfo>
31 #include <KDbIndexSchema>
32 #include <KDbTableSchema>
33 #include <KDbTableViewData>
34 
35 #include <QSet>
36 #include <QHash>
37 
38 //============= KexiCellEditorFactoryItem ============
39 
40 KexiCellEditorFactoryItem::KexiCellEditorFactoryItem()
41 {
42 }
43 
44 KexiCellEditorFactoryItem::~KexiCellEditorFactoryItem()
45 {
46 }
47 
48 //============= KexiCellEditorFactoryPrivate ============
49 
50 //! @internal
51 class KexiCellEditorFactoryPrivate
52 {
53 public:
54     KexiCellEditorFactoryPrivate() {
55         // Initialize standard editor cell editor factories
56         registerItem(*new KexiBlobEditorFactoryItem(), KDbField::BLOB);
57         registerItem( *new KexiDateEditorFactoryItem(), KDbField::Date);
58         registerItem( *new KexiTimeEditorFactoryItem(), KDbField::Time);
59         registerItem( *new KexiDateTimeEditorFactoryItem(), KDbField::DateTime);
60         registerItem(*new KexiComboBoxEditorFactoryItem(), KDbField::Enum);
61         registerItem(*new KexiBoolEditorFactoryItem(), KDbField::Boolean);
62         registerItem(*new KexiKIconTableEditorFactoryItem(), KDbField::Text, "QIcon");
63         //default type
64         registerItem(*new KexiInputEditorFactoryItem(), KDbField::InvalidType);
65     }
66     ~KexiCellEditorFactoryPrivate() {
67         qDeleteAll(items);
68     }
69 
70     QString key(int type, const QString& subType) const {
71         QString key = QString::number(type);
72         if (!subType.isEmpty())
73             key += (QString(" ") + subType);
74         return key;
75     }
76 
77     void registerItem(KexiCellEditorFactoryItem& item, int type, const QString& subType = QString()) {
78         if (!items.contains(&item))
79             items.insert(&item);
80 
81         items_by_type.insert(key(type, subType), &item);
82     }
83 
84     KexiCellEditorFactoryItem *findItem(int type, const QString& subType) {
85         KexiCellEditorFactoryItem *item = items_by_type.value(key(type, subType));
86         if (item)
87             return item;
88         item = items_by_type.value(key(type, QString()));
89         if (item)
90             return item;
91         return items_by_type.value(key(KDbField::InvalidType, QString()));
92     }
93 
94     QSet<KexiCellEditorFactoryItem*> items; //!< list of editor factory items (for later destroy)
95 
96     QHash<QString, KexiCellEditorFactoryItem*> items_by_type; //!< editor factory items accessed by a key
97 };
98 
99 Q_GLOBAL_STATIC(KexiCellEditorFactoryPrivate, KexiCellEditorFactory_static)
100 
101 //============= KexiCellEditorFactory ============
102 
103 KexiCellEditorFactory::KexiCellEditorFactory()
104 {
105 }
106 
107 KexiCellEditorFactory::~KexiCellEditorFactory()
108 {
109 }
110 
111 void KexiCellEditorFactory::registerItem(KexiCellEditorFactoryItem& item, int type, const QString& subType)
112 {
113     KexiCellEditorFactory_static->registerItem(item, type, subType);
114 }
115 
116 static bool hasEnumType(const KDbTableViewColumn &column)
117 {
118     /*not db-aware case*/
119     if (column.relatedData())
120         return true;
121     /*db-aware case*/
122     if (!column.field() || !column.field()->table())
123         return false;
124     const KDbLookupFieldSchema *lookupFieldSchema
125         = column.field()->table()->lookupFieldSchema(*column.field());
126     if (!lookupFieldSchema)
127         return false;
128     if (lookupFieldSchema->recordSource().name().isEmpty())
129         return false;
130     return true;
131 }
132 
133 KexiTableEdit* KexiCellEditorFactory::createEditor(KDbTableViewColumn *column, QWidget* parent)
134 {
135     KDbField *realField;
136     if (column->visibleLookupColumnInfo()) {
137         realField = column->visibleLookupColumnInfo()->field();
138     } else {
139         realField = column->field();
140     }
141 
142     KexiCellEditorFactoryItem *item = 0;
143 
144     if (hasEnumType(*column)) {
145         //--we need to create combo box because of relationship:
146         item = KexiCellEditorFactory::item(KDbField::Enum);
147     } else {
148         item = KexiCellEditorFactory::item(realField->type(), realField->subType());
149     }
150 
151 //! @todo later
152 #if 0
153     //--check if we need to create combo box because of relationship:
154     //WARNING: it's assumed that indices are one-field long
155     KDbTableSchema *table = f.table();
156     if (table) {
157         //find index that contain this field
158         KDbIndexSchema::ListIterator it = table->indicesIterator();
159         for (;it.current();++it) {
160             KDbIndexSchema *idx = it.current();
161             if (idx->fields()->contains(&f)) {
162                 //find details-side rel. for this index
163                 KDbRelationship *rel = idx->detailsRelationships()->first();
164                 if (rel) {
165 
166                 }
167             }
168         }
169     }
170 #endif
171     return item->createEditor(column, parent);
172 }
173 
174 KexiCellEditorFactoryItem* KexiCellEditorFactory::item(int type, const QString& subType)
175 {
176     return KexiCellEditorFactory_static->findItem(type, subType);
177 }
178