Added zpos attribute to all elements. Changed architecture to allow detailscreen...
[jspeed] / src / textelement.cpp
1 /*
2  * This file is part of jSpeed.
3  *
4  * jSpeed is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * jSpeed 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
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with jSpeed.  If not, see <http://www.gnu.org/licenses/>.
16  *
17  */
18
19 #include <QtCore/QString>
20 #include <QtCore/QDebug>
21 #include <QtCore/QTime>
22 #include <QtGui/QGraphicsScene>
23 #include <QtGui/QGraphicsTextItem>
24 #include "textelement.h"
25 #include "reader.h"
26 #include "odometer.h"
27 #include "graphicsscene.h"
28
29 namespace
30 {
31     const GraphicsElement::AttributeDetails ATTRIBUTES[TextElement::ATTRIBUTE_COUNT] =
32     {
33      {"xpos", true},
34      {"ypos", true},
35      {"zpos", true},
36      {"data", false},
37      {"format", false},
38      {"width", true},
39      {"align", false},
40      {"color", false},
41      {"size", true},
42      {"font", false},
43      {"bold", false},
44      {"italic", false},
45      {"uppercase", false},
46      {"letterspacing", true},
47      {"timeformat", false},
48      {"dateformat", false}
49     };
50
51     const QString FIELDS[TextElement::FIELD_COUNT] =  {"TRIP", "TOTAL", "SPEED",
52                                                        "MAXSPEED", "AVGSPEED",
53                                                        "UNIT", "SPEEDUNIT", "TIME", "DATE"};
54 }
55
56 TextElement::TextElement(Reader* reader): GraphicsElement(reader),
57 data_(""), format_(""), align_("left"), timeFormat_("hh:mm"), dateFormat_("dd.MM.yyyy"), fontSize_(16), bold_(false), italic_(false),
58 uppercase_(false), letterSpacing_(0)
59 {
60     element_ = new QGraphicsTextItem();
61 }
62
63 bool TextElement::setAttribute(QString const& name, QString const& value)
64 {
65     int intVal = 0;
66     int attrId = -1;
67
68     if((attrId = getAttribute(name, value, ATTRIBUTES, ATTRIBUTE_COUNT, intVal)) != -1)
69     {
70         Attribute attr = static_cast<Attribute>(attrId);
71
72         bool fontChanged = false;
73
74         switch(attr)
75         {
76         case XPOS:
77             element_->setX(intVal);
78             break;
79         case YPOS:
80             element_->setY(intVal);
81             break;
82         case ZPOS:
83             element_->setZValue(intVal);
84             break;
85         case DATA:
86             data_ = value;
87             break;
88         case FORMAT:
89             format_ = value;
90             break;
91         case WIDTH:
92             element_->setTextWidth(intVal);
93             break;
94         case ALIGN:
95             align_ = value;
96             break;
97         case COLOR:
98             element_->setDefaultTextColor(QColor(value));
99             break;
100         case SIZE:
101             fontSize_ = intVal;
102             fontChanged = true;
103             break;
104         case FONT:
105             fontFile_ = value;
106             fontChanged = true;
107             break;
108         case BOLD:
109             if(value != "false" && value != "0")
110             {
111                 bold_ = true;
112                 fontChanged = true;
113             }
114             break;
115         case ITALIC:
116             if(value != "false" && value != "0")
117             {
118                 italic_ = true;
119                 fontChanged = true;
120             }
121             break;
122         case UPPERCASE:
123             if(value != "false" && value != "0")
124             {
125                 uppercase_ = true;
126             }
127             break;
128         case LETTERSPACING:
129             letterSpacing_ = intVal;
130             fontChanged = true;
131             break;
132         case TIMEFORMAT:
133             timeFormat_ = value;
134             break;
135         case DATEFORMAT:
136             dateFormat_ = value;
137             break;
138         default:
139             qDebug() << "Unknown attribute: " << attr;
140             return false;
141         }
142
143         if(fontChanged)
144         {
145             return applyFont();
146         }
147
148         return true;
149
150     }
151     else
152     {
153         return false;
154     }
155 }
156
157 bool TextElement::applyFont()
158 {
159     QFont font;
160
161     if(!fontFile_.isEmpty())
162     {
163         if(!getFont(fontFile_, font))
164         {
165             return false;
166         }
167     }
168
169     font.setPointSize(fontSize_);
170
171     if(bold_)
172     {
173         font.setBold(true);
174     }
175
176     if(italic_)
177     {
178         font.setItalic(true);
179     }
180
181     if(letterSpacing_)
182     {
183         font.setLetterSpacing(QFont::PercentageSpacing, letterSpacing_);
184     }
185
186     element_->setFont(font);
187
188     return true;
189 }
190
191 void TextElement::addToScene(GraphicsScene* scene)
192 {
193     specialFields_.clear();
194
195     for(int i = 0; i < FIELD_COUNT; i++)
196     {
197         if(data_.indexOf("{" + FIELDS[i] + "}") != -1)
198         {
199             specialFields_.push_back(static_cast<Field>(i));
200         }
201
202     }
203
204     QString replaced = data_;
205     replaceSpecialFields(replaced);
206     updateHtml(replaced);
207
208     scene->addItem(element_);
209 }
210
211 void TextElement::update()
212 {
213     if(specialFields_.isEmpty())
214     {
215         return;
216     }
217
218     QString replaced = data_;
219     replaceSpecialFields(replaced);
220
221     updateHtml(replaced);
222 }
223
224 void TextElement::updateHtml(QString data)
225 {
226     if(uppercase_)
227     {
228         data = data.toUpper();
229     }
230
231     element_->setHtml("<div align='"+align_+"'>"+data+"</div>");
232 }
233
234 void TextElement::replaceSpecialFields(QString& value)
235 {
236     for(int i = 0; i < specialFields_.size(); i++)
237     {
238         Field f = specialFields_.at(i);
239         Odometer* o = &(Odometer::instance());
240
241         switch(f)
242         {
243         case TRIP:
244             replaceValue(value, f, formatString(o->getTrip()));
245             break;
246         case TOTAL:
247             replaceValue(value, f, formatString(o->getTotal()));
248             break;
249         case SPEED:
250             replaceValue(value, f, formatString(o->getLatestFix().speed));
251             break;
252         case MAXSPEED:
253             replaceValue(value, f, formatString(o->getMaxSpeed()));
254             break;
255         case AVGSPEED:
256             replaceValue(value, f, formatString(o->getAverageSpeed()));
257             break;
258         case UNIT:
259             replaceValue(value, f, o->getUnit());
260             break;
261         case SPEEDUNIT:
262             replaceValue(value, f, o->getSpeedUnit());
263             break;
264         case TIME:
265             replaceValue(value, f, QTime::currentTime().toString(timeFormat_));
266             break;
267         case DATE:
268             replaceValue(value, f, QDate::currentDate().toString(dateFormat_));
269             break;
270         default:
271             qDebug() << "Unknown field: " << f;
272         }
273     }
274 }
275
276 void TextElement::replaceValue(QString& value,
277                                TextElement::Field field,
278                                QString const& replace)
279 {
280     value = value.replace("{" + FIELDS[field] + "}", replace);
281 }
282
283 QString TextElement::formatString(double val)
284 {
285     QString format = format_;
286
287     if(format.isEmpty())
288     {
289         format = "%.1lf";
290     }
291
292     QString result;
293     result.sprintf(format.toLatin1().data(), val);
294
295     return result;
296 }
297
298
299 QGraphicsItem* TextElement::getElement() const
300 {
301     return element_;
302 }