Diffstat (limited to 'noncore/apps/tableviewer/db/datacache.cpp') (more/less context) (ignore whitespace changes)
-rw-r--r-- | noncore/apps/tableviewer/db/datacache.cpp | 293 |
1 files changed, 293 insertions, 0 deletions
diff --git a/noncore/apps/tableviewer/db/datacache.cpp b/noncore/apps/tableviewer/db/datacache.cpp new file mode 100644 index 0000000..7c14eef --- a/dev/null +++ b/noncore/apps/tableviewer/db/datacache.cpp | |||
@@ -0,0 +1,293 @@ | |||
1 | /********************************************************************** | ||
2 | ** Copyright (C) 2000 Trolltech AS. All rights reserved. | ||
3 | ** | ||
4 | ** This file is part of Qtopia Environment. | ||
5 | ** | ||
6 | ** This file may be distributed and/or modified under the terms of the | ||
7 | ** GNU General Public License version 2 as published by the Free Software | ||
8 | ** Foundation and appearing in the file LICENSE.GPL included in the | ||
9 | ** packaging of this file. | ||
10 | ** | ||
11 | ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE | ||
12 | ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. | ||
13 | ** | ||
14 | ** See http://www.trolltech.com/gpl/ for GPL licensing information. | ||
15 | ** | ||
16 | ** Contact info@trolltech.com if any conditions of this licensing are | ||
17 | ** not clear to you. | ||
18 | ** | ||
19 | **********************************************************************/ | ||
20 | /* | ||
21 | * This file is used to load the xml files that represent the database. | ||
22 | * The main requirment for said file is each data entry must contain a key, | ||
23 | * otherwise any other data headings are allowed. | ||
24 | */ | ||
25 | |||
26 | #include "datacache.h" | ||
27 | #include "xmlsource.h" | ||
28 | #include "csvsource.h" | ||
29 | #include <stdlib.h> | ||
30 | #include <qheader.h> | ||
31 | |||
32 | #define INIT_TABLE_SIZE 128 | ||
33 | |||
34 | /*! | ||
35 | \class DBStore datastore.h | ||
36 | |||
37 | \brief The DBStore class is the class responsible for storing, sorting and | ||
38 | searching the data loaded by the application | ||
39 | |||
40 | */ | ||
41 | |||
42 | /*! | ||
43 | Constructs a DBStore item | ||
44 | */ | ||
45 | DBStore::DBStore() | ||
46 | { | ||
47 | name = ""; | ||
48 | number_elems = 0; | ||
49 | full = false; | ||
50 | kRep = new KeyList(); | ||
51 | master_table.resize(INIT_TABLE_SIZE); | ||
52 | table_size = INIT_TABLE_SIZE; | ||
53 | |||
54 | current_elem = 0; | ||
55 | archive = 0; | ||
56 | } | ||
57 | |||
58 | //TODO | ||
59 | /*! | ||
60 | Reinitializes the table to empty (include a resize of the master table, | ||
61 | which should free some memory) | ||
62 | */ | ||
63 | void DBStore::freeTable() | ||
64 | { | ||
65 | name = ""; | ||
66 | if(archive) { | ||
67 | delete archive; | ||
68 | archive = 0; | ||
69 | } | ||
70 | kRep->clear(); /* clear the current key list */ | ||
71 | |||
72 | number_elems = 0; | ||
73 | table_size = INIT_TABLE_SIZE; | ||
74 | master_table.resize(table_size); | ||
75 | full = false; | ||
76 | current_elem = 0; | ||
77 | } | ||
78 | |||
79 | /*! | ||
80 | Removes all items from the DBStore and destroys the DBStore | ||
81 | */ | ||
82 | DBStore::~DBStore() | ||
83 | { | ||
84 | freeTable(); | ||
85 | } | ||
86 | |||
87 | /*! | ||
88 | This function opens the given xml file, loads it and sets up the | ||
89 | appropriate data structures. | ||
90 | |||
91 | \param file_name A string representing the name of the file to be opened | ||
92 | \return true if successful, false otherwise. | ||
93 | */ | ||
94 | bool DBStore::openSource(QIODevice *inDev, const QString &source) { | ||
95 | |||
96 | /* first check if db is already open, if contains data.. then clear */ | ||
97 | if(number_elems > 0) { | ||
98 | freeTable(); | ||
99 | } | ||
100 | |||
101 | if (source == "text/x-xml-tableviewer") { | ||
102 | archive = new DBXml(this); | ||
103 | } else if (source == "text/csv") { | ||
104 | archive = new DBCsv(this); | ||
105 | } else | ||
106 | return false; | ||
107 | |||
108 | return (archive->openSource(inDev)); | ||
109 | } | ||
110 | |||
111 | bool DBStore::saveSource(QIODevice *outDev, const QString &source) | ||
112 | { | ||
113 | /* saving a new file */ | ||
114 | if(!archive) { | ||
115 | if (source == "text/x-xml-tableviewer") { | ||
116 | archive = new DBXml(this); | ||
117 | } else if (source == "text/x-xml-tableviewer") { | ||
118 | archive = new DBCsv(this); | ||
119 | } else | ||
120 | return false; | ||
121 | } | ||
122 | |||
123 | /* changing file type */ | ||
124 | if(archive->type() != source) { | ||
125 | delete archive; | ||
126 | if (source == "text/x-xml-tableviewer") { | ||
127 | archive = new DBXml(this); | ||
128 | } else if (source == "text/x-xml-tableviewer") { | ||
129 | archive = new DBCsv(this); | ||
130 | } else | ||
131 | return false; | ||
132 | } | ||
133 | |||
134 | return (archive->saveSource(outDev)); | ||
135 | } | ||
136 | |||
137 | /*! | ||
138 | This function is used to add new elements to the database. If the database | ||
139 | has already reached the maximum allowable size this function does not alter | ||
140 | the database. | ||
141 | |||
142 | \param delm An already allocated and initialized data element to be added | ||
143 | */ | ||
144 | void DBStore::addItem(DataElem *delem) | ||
145 | { | ||
146 | addItemInternal(delem); | ||
147 | } | ||
148 | |||
149 | void DBStore::addItemInternal(DataElem *delem) | ||
150 | { | ||
151 | /* if already full, don't over fill, do a qWarning though */ | ||
152 | if (full) { | ||
153 | qWarning("Attempted to add items to already full table"); | ||
154 | return; | ||
155 | } | ||
156 | |||
157 | master_table.insert(number_elems, delem); | ||
158 | |||
159 | current_elem = number_elems; | ||
160 | number_elems++; | ||
161 | |||
162 | if(number_elems >= table_size) { | ||
163 | /* filled current table, double if we can */ | ||
164 | table_size = table_size << 1; | ||
165 | |||
166 | /* check that the new table size is still valid, i.e. that we didn't | ||
167 | just shift the 1 bit of the end of the int. */ | ||
168 | if (!table_size) { | ||
169 | full = true; | ||
170 | /* no point in doing antying else. */ | ||
171 | return; | ||
172 | } | ||
173 | master_table.resize(table_size); | ||
174 | } | ||
175 | } | ||
176 | |||
177 | void DBStore::removeItem(DataElem *r) | ||
178 | { | ||
179 | int position = master_table.findRef(r); | ||
180 | if(position != -1) { | ||
181 | /* there is at least one item, this is it */ | ||
182 | /* replace this with the last element, decrease the element count */ | ||
183 | master_table.insert(position, master_table.at(--number_elems)); | ||
184 | master_table.remove(number_elems); | ||
185 | delete r; | ||
186 | } | ||
187 | } | ||
188 | |||
189 | /*! | ||
190 | Sets the name of the database | ||
191 | |||
192 | \param n A string representing the new name of the database. | ||
193 | */ | ||
194 | void DBStore::setName(const QString &n) | ||
195 | { | ||
196 | name = n; | ||
197 | } | ||
198 | |||
199 | /*! | ||
200 | Gets the name of the database | ||
201 | |||
202 | \return A string representing the name of the database. | ||
203 | */ | ||
204 | QString DBStore::getName() | ||
205 | { | ||
206 | return name; | ||
207 | } | ||
208 | |||
209 | /*! | ||
210 | Retrieves a pointer to the key representation of the database for | ||
211 | other classes to use as reference. | ||
212 | |||
213 | \return a pointer to the databases key representaion | ||
214 | */ | ||
215 | KeyList *DBStore::getKeys() | ||
216 | { | ||
217 | return kRep; | ||
218 | } | ||
219 | |||
220 | /*! | ||
221 | sets the database's key representation the passed pointer | ||
222 | \param a pointer to a key representaton | ||
223 | */ | ||
224 | void DBStore::setKeys(KeyList *k) | ||
225 | { | ||
226 | kRep = k; | ||
227 | } | ||
228 | |||
229 | /*! | ||
230 | Sets the current element to the first element of the database | ||
231 | */ | ||
232 | void DBStore::first() | ||
233 | { | ||
234 | current_elem = 0; | ||
235 | } | ||
236 | |||
237 | /*! | ||
238 | Sets the current element to the last element of the database | ||
239 | */ | ||
240 | void DBStore::last() | ||
241 | { | ||
242 | current_elem = number_elems - 1; | ||
243 | } | ||
244 | |||
245 | /*! | ||
246 | Sets the current element to the next element of the database if | ||
247 | there exists an element after the current one. | ||
248 | */ | ||
249 | bool DBStore::next() | ||
250 | { | ||
251 | unsigned int new_current_elem = current_elem + 1; | ||
252 | if (current_elem < number_elems) | ||
253 | /* was valid before inc (it is possible but unlikely that inc current | ||
254 | elem will change it from invalid to valid) */ | ||
255 | if (new_current_elem < number_elems) { | ||
256 | /* is valid after inc */ | ||
257 | current_elem = new_current_elem; | ||
258 | return true; | ||
259 | } | ||
260 | return false; | ||
261 | } | ||
262 | |||
263 | /*! | ||
264 | Sets the current element to the previous element of the database if | ||
265 | there exists an element before the current one. | ||
266 | */ | ||
267 | bool DBStore::previous() | ||
268 | { | ||
269 | unsigned int new_current_elem = current_elem -1; | ||
270 | if (current_elem < number_elems) | ||
271 | /* was valid */ | ||
272 | if (new_current_elem < number_elems) { | ||
273 | /* still is (if was 0, then now -1, but as is unsigned will wrap | ||
274 | and hence be invalid */ | ||
275 | current_elem = new_current_elem; | ||
276 | return true; | ||
277 | } | ||
278 | return false; | ||
279 | } | ||
280 | |||
281 | /*! | ||
282 | Returns the current data element in the database. Which element is current | ||
283 | is affected by newly added items, findItem, next, previous, first and | ||
284 | last functions | ||
285 | |||
286 | \return a pointer to the current data element | ||
287 | */ | ||
288 | DataElem *DBStore::getCurrentData() | ||
289 | { | ||
290 | if (current_elem >= number_elems) | ||
291 | return NULL; | ||
292 | return master_table[current_elem]; | ||
293 | } | ||