bf79a68e79aab0e8cedce9a07d11f9f1e0fb0cc3
[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      {"data", false},
36      {"format", false},
37      {"width", true},
38      {"align", false},
39      {"color", false},
40      {"size", true},
41      {"font", false},
42      {"bold", false},
43      {"italic", false},
44      {"uppercase", false},
45      {"letterspacing", true}
46     };
47
48     const QString FIELDS[TextElement::FIELD_COUNT] =  {"TRIP", "TOTAL", "SPEED",
49                                                        "MAXSPEED", "AVGSPEED",
50                                                        "UNIT", "SPEEDUNIT", "TIME"};
51 }
52
53 TextElement::TextElement(Reader* reader): GraphicsElement(reader),
54 data_(""), format_(""), align_("left"), fontSize_(16), bold_(false), italic_(false),
55 uppercase_(false), letterSpacing_(0)
56 {
57     element_ = new QGraphicsTextItem();
58 }
59
60 bool TextElement::setAttribute(QString const& name, QString const& value)
61 {
62     int intVal = 0;
63     int attrId = -1;
64
65     if((attrId = getAttribute(name, value, ATTRIBUTES, ATTRIBUTE_COUNT, intVal)) != -1)
66     {
67         Attribute attr = static_cast<Attribute>(attrId);
68
69         bool fontChanged = false;
70
71         switch(attr)
72         {
73         case XPOS:
74             element_->setX(intVal);
75             break;
76         case YPOS:
77             element_->setY(intVal);
78             break;
79         case DATA:
80             data_ = value;
81             break;
82         case FORMAT:
83             format_ = value;
84             break;
85         case WIDTH:
86             element_->setTextWidth(intVal);
87             break;
88         case ALIGN:
89             align_ = value;
90             break;
91         case COLOR:
92             element_->setDefaultTextColor(QColor(value));
93             break;
94         case SIZE:
95             fontSize_ = intVal;
96             fontChanged = true;
97             break;
98         case FONT:
99             fontFile_ = value;
100             fontChanged = true;
101             break;
102         case BOLD:
103             if(value != "false" && value != "0")
104             {
105                 bold_ = true;
106                 fontChanged = true;
107             }
108             break;
109         case ITALIC:
110             if(value != "false" && value != "0")
111             {
112                 italic_ = true;
113                 fontChanged = true;
114             }
115             break;
116         case UPPERCASE:
117             if(value != "false" && value != "0")
118             {
119                 uppercase_ = true;
120             }
121             break;
122         case LETTERSPACING:
123             letterSpacing_ = intVal;
124             fontChanged = true;
125             break;
126         default:
127             qDebug() << "Unknown attribute: " << attr;
128             return false;
129         }
130
131         if(fontChanged)
132         {
133             return applyFont();
134         }
135
136         return true;
137
138     }
139     else
140     {
141         return false;
142     }
143 }
144
145 bool TextElement::applyFont()
146 {
147     QFont font;
148
149     if(!fontFile_.isEmpty())
150     {
151         if(!getFont(fontFile_, font))
152         {
153             return false;
154         }
155     }
156
157     font.setPointSize(fontSize_);
158
159     if(bold_)
160     {
161         font.setBold(true);
162     }
163
164     if(italic_)
165     {
166         font.setItalic(true);
167     }
168
169     if(letterSpacing_)
170     {
171         font.setLetterSpacing(QFont::PercentageSpacing, letterSpacing_);
172     }
173
174     element_->setFont(font);
175
176     return true;
177 }
178
179 void TextElement::addToScene(GraphicsScene* scene)
180 {
181     specialFields_.clear();
182
183     for(int i = 0; i < FIELD_COUNT; i++)
184     {
185         if(data_.indexOf("{" + FIELDS[i] + "}") != -1)
186         {
187             specialFields_.push_back(static_cast<Field>(i));
188         }
189
190     }
191
192     QString replaced = data_;
193     replaceSpecialFields(replaced);
194     updateHtml(replaced);
195
196     scene->addItem(element_);
197 }
198
199 void TextElement::update()
200 {
201     if(specialFields_.isEmpty())
202     {
203         return;
204     }
205
206     QString replaced = data_;
207     replaceSpecialFields(replaced);
208
209     updateHtml(replaced);
210 }
211
212 void TextElement::updateHtml(QString data)
213 {
214     if(uppercase_)
215     {
216         data = data.toUpper();
217     }
218
219     element_->setHtml("<div align='"+align_+"'>"+data+"</div>");
220 }
221
222 void TextElement::replaceSpecialFields(QString& value)
223 {
224     for(int i = 0; i < specialFields_.size(); i++)
225     {
226         Field f = specialFields_.at(i);
227         Odometer* o = &(Odometer::instance());
228
229         switch(f)
230         {
231         case TRIP:
232             replaceValue(value, f, formatString(o->getTrip()));
233             break;
234         case TOTAL:
235             replaceValue(value, f, formatString(o->getTotal()));
236             break;
237         case SPEED:
238             replaceValue(value, f, formatString(o->getLatestFix().speed));
239             break;
240         case MAXSPEED:
241             replaceValue(value, f, formatString(o->getMaxSpeed()));
242             break;
243         case AVGSPEED:
244             replaceValue(value, f, formatString(o->getAverageSpeed()));
245             break;
246         case UNIT:
247             replaceValue(value, f, o->getUnit());
248             break;
249         case SPEEDUNIT:
250             replaceValue(value, f, o->getSpeedUnit());
251             break;
252         case TIME:
253             replaceValue(value, f, QTime::currentTime().toString("hh:mm"));
254             break;
255         default:
256             qDebug() << "Unknown field: " << f;
257         }
258     }
259 }
260
261 void TextElement::replaceValue(QString& value,
262                                TextElement::Field field,
263                                QString const& replace)
264 {
265     value = value.replace("{" + FIELDS[field] + "}", replace);
266 }
267
268 QString TextElement::formatString(double val)
269 {
270     QString format = format_;
271
272     if(format.isEmpty())
273     {
274         format = "%.1lf";
275     }
276
277     QString result;
278     result.sprintf(format.toLatin1().data(), val);
279
280     return result;
281 }
282
283
284 QGraphicsItem* TextElement::getElement() const
285 {
286     return element_;
287 }