1 | /* |
2 | Qalculate |
3 | |
4 | Copyright (C) 2004-2006 Niklas Knutsson (nq@altern.org) |
5 | |
6 | This program is free software; you can redistribute it and/or modify |
7 | it under the terms of the GNU General Public License as published by |
8 | the Free Software Foundation; either version 2 of the License, or |
9 | (at your option) any later version. |
10 | */ |
11 | |
12 | #ifndef DATA_SET_H |
13 | #define DATA_SET_H |
14 | |
15 | #include <libqalculate/includes.h> |
16 | #include <libqalculate/Function.h> |
17 | |
18 | /** @file */ |
19 | |
20 | typedef Sgi::vector<DataProperty*>::iterator DataObjectPropertyIter; |
21 | |
22 | /// A a data set object. |
23 | /** Data objects consist of property-value pairs. */ |
24 | class DataObject { |
25 | |
26 | protected: |
27 | |
28 | vector<DataProperty*> properties; |
29 | vector<string> s_properties; |
30 | vector<string> s_nonlocalized_properties; |
31 | vector<MathStructure*> m_properties; |
32 | vector<int> a_properties; |
33 | DataSet *parent; |
34 | bool b_uchanged; |
35 | |
36 | public: |
37 | |
38 | /** Create a data object. |
39 | * |
40 | * @param parent_set Data set that the object will belong to. |
41 | */ |
42 | DataObject(DataSet *parent_set); |
43 | |
44 | /** Unset (erase value) a property. |
45 | * |
46 | * @param property Property to unset. |
47 | */ |
48 | void eraseProperty(DataProperty *property); |
49 | /** Set value for a property. |
50 | * |
51 | * @param property Property to set (must belong to parent data set). |
52 | * @param s_vale Value for the property. |
53 | * @param is_approximate If the value is approximate. 1 for approximate, 0 for exact, -1 for property default. |
54 | */ |
55 | void setProperty(DataProperty *property, string s_value, int is_approximate = -1); |
56 | /** Set an untranslated value for a key property. Used when a text value is translated, but the original value still is needed as a reference key. |
57 | * |
58 | * @param property Property to set (must belong to parent data set). |
59 | * @param s_vale Value for the property. |
60 | */ |
61 | void setNonlocalizedKeyProperty(DataProperty *property, string s_value); |
62 | |
63 | /** Returns parsed value for a property. Parses the text string value if not parsed before |
64 | * |
65 | * @param property Property to read. |
66 | * @returns Parsed value or NULL if property value is not set. |
67 | */ |
68 | const MathStructure *getPropertyStruct(DataProperty *property); |
69 | /** Returns unparsed value for a property. |
70 | * |
71 | * @param property Property to read. |
72 | * @param[out] is_approximate If the value is approximate. Is set to 1 for approximate, 0 for exact, -1 for property default, if not NULL. |
73 | * @returns Unparsed value or empty string if property value is not set. |
74 | */ |
75 | const string &getProperty(DataProperty *property, int *is_approximate = NULL); |
76 | /** Returns unparsed untranslated value for a key property. Used when a text value is translated, but the original value still is needed as a reference key. |
77 | * |
78 | * @param property Property to read. |
79 | * @returns Unparsed untranslated value or empty string if property value is not set. |
80 | */ |
81 | const string &getNonlocalizedKeyProperty(DataProperty *property); |
82 | /** Returns value for a property in a format suitable for use in expressions with unit appended. |
83 | * |
84 | * @param property Property to read. |
85 | * @returns Value in input format or empty string if property value is not set. |
86 | */ |
87 | string getPropertyInputString(DataProperty *property); |
88 | /** Returns value for a property in a format suitable for display with unit appended. |
89 | * |
90 | * @param property Property to read. |
91 | * @returns Value in display format or empty string if property value is not set. |
92 | */ |
93 | string getPropertyDisplayString(DataProperty *property); |
94 | |
95 | /** If the object has been modified by the end user (if setUserModified() has been called). |
96 | * |
97 | * @returns true if the object has been modified by the user. |
98 | */ |
99 | bool isUserModified() const; |
100 | /** Specify if the object has been modified by the end user. |
101 | * |
102 | * @param user_modified true if the object has been modified by the user. |
103 | */ |
104 | void setUserModified(bool user_modified = true); |
105 | |
106 | /** Returns the data set that the object belongs to. |
107 | * |
108 | * @returns Parent data set. |
109 | */ |
110 | DataSet *parentSet() const; |
111 | |
112 | }; |
113 | |
114 | typedef enum { |
115 | PROPERTY_EXPRESSION, |
116 | PROPERTY_NUMBER, |
117 | PROPERTY_STRING |
118 | } PropertyType; |
119 | |
120 | /// A data set property. |
121 | /** Property definitions for use with data set objects. */ |
122 | class DataProperty { |
123 | |
124 | protected: |
125 | |
126 | vector<string> names; |
127 | vector<bool> name_is_ref; |
128 | string sdescr, stitle, sunit; |
129 | MathStructure *m_unit; |
130 | bool b_approximate, b_brackets, b_key, b_case, b_hide; |
131 | DataSet *parent; |
132 | PropertyType ptype; |
133 | bool b_uchanged; |
134 | |
135 | public: |
136 | |
137 | /** Create a data property. |
138 | * |
139 | * @param s_name Property name (initial) used for reference. |
140 | * @param s_title Descriptive name/title. |
141 | * @param s_description Description. |
142 | */ |
143 | DataProperty(DataSet *parent_set, string s_name = "" , string s_title = "" , string s_description = "" ); |
144 | DataProperty(const DataProperty &dp); |
145 | |
146 | void set(const DataProperty &dp); |
147 | void setName(string s_name, bool is_ref = false); |
148 | void setNameIsReference(size_t index = 1, bool is_ref = true); |
149 | bool nameIsReference(size_t index = 1) const; |
150 | void clearNames(); |
151 | void addName(string s_name, bool is_ref = false, size_t index = 0); |
152 | size_t hasName(const string &s_name); |
153 | size_t countNames() const; |
154 | const string &getName(size_t index = 1) const; |
155 | const string &getReferenceName() const; |
156 | void setTitle(string s_title); |
157 | const string &title(bool return_name_if_no_title = true) const; |
158 | void setDescription(string s_description); |
159 | const string &description() const; |
160 | void setUnit(string s_unit); |
161 | const string &getUnitString() const; |
162 | const MathStructure *getUnitStruct(); |
163 | string getInputString(const string &valuestr); |
164 | string getDisplayString(const string &valuestr); |
165 | MathStructure *generateStruct(const string &valuestr, int is_approximate = -1); |
166 | void setKey(bool is_key = true); |
167 | bool isKey() const; |
168 | void setHidden(bool is_hidden = true); |
169 | bool isHidden() const; |
170 | void setCaseSensitive(bool is_case_sensitive = true); |
171 | bool isCaseSensitive() const; |
172 | void setUsesBrackets(bool uses_brackets = true); |
173 | bool usesBrackets() const; |
174 | void setApproximate(bool is_approximate = true); |
175 | bool isApproximate() const; |
176 | void setPropertyType(PropertyType property_type); |
177 | PropertyType propertyType() const; |
178 | |
179 | bool isUserModified() const; |
180 | void setUserModified(bool user_modified = true); |
181 | |
182 | DataSet *parentSet() const; |
183 | |
184 | }; |
185 | |
186 | typedef vector<DataProperty*>::iterator DataPropertyIter; |
187 | typedef vector<DataObject*>::iterator DataObjectIter; |
188 | |
189 | /// A data set. |
190 | /** This is a simple database class for storage of many grouped values, when ordinary variables is not practical. |
191 | * |
192 | * A data set consists of properties and objects, with values for the properties. Qalculate! includes for example a "Planets" data set with properties such as name, mass, speed and density, and an object for each planet in solar system. |
193 | * |
194 | * A data set is also mathemtical function, dataset(object, property), which retrieves values for objects and properties. |
195 | * Data sets can be saved and loaded from a XML file. |
196 | */ |
197 | class DataSet : public MathFunction { |
198 | |
199 | protected: |
200 | |
201 | string sfile, scopyright; |
202 | bool b_loaded; |
203 | vector<DataProperty*> properties; |
204 | vector<DataObject*> objects; |
205 | |
206 | public: |
207 | |
208 | DataSet(string s_category = "" , string s_name = "" , string s_default_file = "" , string s_title = "" , string s_description = "" , bool is_local = true); |
209 | DataSet(const DataSet *o); |
210 | |
211 | ExpressionItem *copy() const; |
212 | void set(const ExpressionItem *item); |
213 | int subtype() const; |
214 | |
215 | void setCopyright(string s_copyright); |
216 | const string ©right() const; |
217 | void setDefaultDataFile(string s_file); |
218 | const string &defaultDataFile() const; |
219 | |
220 | void setDefaultProperty(string property); |
221 | const string &defaultProperty() const; |
222 | |
223 | virtual int calculate(MathStructure &mstruct, const MathStructure &vargs, const EvaluationOptions &eo); |
224 | |
225 | bool loadObjects(const char *file_name = NULL, bool is_user_defs = true); |
226 | int saveObjects(const char *file_name = NULL, bool save_global = false); |
227 | bool objectsLoaded() const; |
228 | void setObjectsLoaded(bool objects_loaded); |
229 | |
230 | void addProperty(DataProperty *dp); |
231 | void delProperty(DataProperty *dp); |
232 | void delProperty(DataPropertyIter *it); |
233 | DataProperty *getPrimaryKeyProperty(); |
234 | DataProperty *getProperty(string property); |
235 | DataProperty *getFirstProperty(DataPropertyIter *it); |
236 | DataProperty *getNextProperty(DataPropertyIter *it); |
237 | const string &getFirstPropertyName(DataPropertyIter *it); |
238 | const string &getNextPropertyName(DataPropertyIter *it); |
239 | |
240 | void addObject(DataObject *o); |
241 | void delObject(DataObject *o); |
242 | void delObject(DataObjectIter *it); |
243 | DataObject *getObject(string object); |
244 | DataObject *getObject(const MathStructure &object); |
245 | DataObject *getFirstObject(DataObjectIter *it); |
246 | DataObject *getNextObject(DataObjectIter *it); |
247 | |
248 | const MathStructure *getObjectProperyStruct(string property, string object); |
249 | const string &getObjectProperty(string property, string object); |
250 | string getObjectPropertyInputString(string property, string object); |
251 | string getObjectPropertyDisplayString(string property, string object); |
252 | |
253 | string printProperties(string object); |
254 | string printProperties(DataObject *o); |
255 | |
256 | }; |
257 | |
258 | /// Data property function argument. |
259 | class DataPropertyArgument : public Argument { |
260 | |
261 | protected: |
262 | |
263 | DataSet *o_data; |
264 | |
265 | virtual bool subtest(MathStructure &value, const EvaluationOptions &eo) const; |
266 | virtual string subprintlong() const; |
267 | |
268 | public: |
269 | |
270 | DataPropertyArgument(DataSet *data_set, string name_ = "" , bool does_test = true, bool does_error = true); |
271 | DataPropertyArgument(const DataPropertyArgument *arg); |
272 | ~DataPropertyArgument(); |
273 | int type() const; |
274 | Argument *copy() const; |
275 | string print() const; |
276 | DataSet *dataSet() const; |
277 | void setDataSet(DataSet *data_set); |
278 | |
279 | }; |
280 | |
281 | /// Data object function argument. |
282 | class DataObjectArgument : public Argument { |
283 | |
284 | protected: |
285 | |
286 | DataSet *o_data; |
287 | |
288 | virtual bool subtest(MathStructure &value, const EvaluationOptions &eo) const; |
289 | virtual string subprintlong() const; |
290 | |
291 | public: |
292 | |
293 | DataObjectArgument(DataSet *data_set, string name_ = "" , bool does_test = true, bool does_error = true); |
294 | DataObjectArgument(const DataObjectArgument *arg); |
295 | ~DataObjectArgument(); |
296 | int type() const; |
297 | Argument *copy() const; |
298 | string print() const; |
299 | DataSet *dataSet() const; |
300 | void setDataSet(DataSet *data_set); |
301 | |
302 | }; |
303 | |
304 | #endif |
305 | |