Theme Editor: Fixed code generation with escaped characters
[kugel-rb.git] / utils / themeeditor / parsetreenode.cpp
blobb283e130384f53cece0b442034575c760d11e7fa
1 /***************************************************************************
2 * __________ __ ___.
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
7 * \/ \/ \/ \/ \/
8 * $Id$
10 * Copyright (C) 2010 Robert Bieber
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation; either version 2
15 * of the License, or (at your option) any later version.
17 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
18 * KIND, either express or implied.
20 ****************************************************************************/
22 #include "symbols.h"
23 #include "tag_table.h"
25 #include "parsetreenode.h"
26 #include "parsetreemodel.h"
28 /* Root element constructor */
29 ParseTreeNode::ParseTreeNode(struct skin_element* data)
30 : parent(0), element(0), param(0), children()
32 while(data)
34 children.append(new ParseTreeNode(data, this));
35 data = data->next;
39 /* Normal element constructor */
40 ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent)
41 : parent(parent), element(data), param(0), children()
43 switch(element->type)
46 case TAG:
47 for(int i = 0; i < element->params_count; i++)
49 if(element->params[i].type == skin_tag_parameter::CODE)
50 children.append(new ParseTreeNode(element->params[i].data.code,
51 this));
52 else
53 children.append(new ParseTreeNode(&element->params[i], this));
55 break;
57 /* CONDITIONAL and SUBLINES fall through to the same code */
58 case CONDITIONAL:
59 case SUBLINES:
60 for(int i = 0; i < element->children_count; i++)
62 children.append(new ParseTreeNode(data->children[i], this));
64 break;
66 case VIEWPORT:
67 case LINE:
68 for(int i = 0; i < data->children_count; i++)
70 for(struct skin_element* current = data->children[i]; current;
71 current = current->next)
73 children.append(new ParseTreeNode(current, this));
76 break;
78 default:
79 break;
83 /* Parameter constructor */
84 ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent)
85 : parent(parent), element(0), param(data), children()
90 QString ParseTreeNode::genCode() const
92 QString buffer = "";
94 if(element)
96 switch(element->type)
99 case VIEWPORT:
100 case LINE:
101 for(int i = 0; i < children.count(); i++)
104 Adding a % in case of tag, because the tag rendering code
105 doesn't insert its own
107 if(children[i]->element->type == TAG)
108 buffer.append(TAGSYM);
109 buffer.append(children[i]->genCode());
111 break;
113 case SUBLINES:
114 for(int i = 0; i < children.count(); i++)
116 buffer.append(children[i]->genCode());
117 if(i != children.count() - 1)
118 buffer.append(MULTILINESYM);
120 break;
122 case CONDITIONAL:
123 /* Inserts a %?, the tag renderer doesn't deal with the TAGSYM */
124 buffer.append(TAGSYM);
125 buffer.append(CONDITIONSYM);
126 buffer.append(children[0]->genCode());
128 /* Inserting the sublines */
129 buffer.append(ENUMLISTOPENSYM);
130 for(int i = 1; i < children.count(); i++)
132 buffer.append(children[i]->genCode());
133 if(i != children.count() - 1)
134 buffer.append(ENUMLISTSEPERATESYM);
136 buffer.append(ENUMLISTCLOSESYM);
137 break;
139 case TAG:
140 /* When generating code, we DO NOT insert the leading TAGSYM, leave
141 * the calling functions to handle that
143 buffer.append(element->tag->name);
145 if(element->params_count > 0)
147 /* Rendering parameters if there are any */
148 buffer.append(ARGLISTOPENSYM);
149 for(int i = 0; i < children.count(); i++)
151 buffer.append(children[i]->genCode());
152 if(i != children.count() - 1)
153 buffer.append(ARGLISTSEPERATESYM);
155 buffer.append(ARGLISTCLOSESYM);
157 break;
159 case NEWLINE:
160 buffer.append('\n');
161 break;
163 case TEXT:
164 for(char* cursor = element->text; *cursor; cursor++)
166 if(find_escape_character(*cursor))
167 buffer.append(TAGSYM);
168 buffer.append(*cursor);
170 break;
172 case COMMENT:
173 buffer.append(COMMENTSYM);
174 buffer.append(element->text);
175 buffer.append('\n');
176 break;
179 else if(param)
181 switch(param->type)
183 case skin_tag_parameter::STRING:
184 for(char* cursor = param->data.text; *cursor; cursor++)
186 if(find_escape_character(*cursor))
187 buffer.append(TAGSYM);
188 buffer.append(*cursor);
190 break;
192 case skin_tag_parameter::NUMERIC:
193 buffer.append(QString::number(param->data.numeric, 10));
194 break;
196 case skin_tag_parameter::DEFAULT:
197 buffer.append(DEFAULTSYM);
198 break;
200 case skin_tag_parameter::CODE:
201 buffer.append(QObject::tr("This doesn't belong here"));
202 break;
206 else
208 for(int i = 0; i < children.count(); i++)
209 buffer.append(children[i]->genCode());
212 return buffer;
215 ParseTreeNode* ParseTreeNode::child(int row)
217 if(row < 0 || row >= children.count())
218 return 0;
220 return children[row];
223 int ParseTreeNode::numChildren() const
225 return children.count();
229 QVariant ParseTreeNode::data(int column) const
231 switch(column)
233 case ParseTreeModel::typeColumn:
234 if(element)
236 switch(element->type)
238 case VIEWPORT:
239 return QObject::tr("Viewport");
241 case LINE:
242 return QObject::tr("Logical Line");
244 case SUBLINES:
245 return QObject::tr("Alternator");
247 case COMMENT:
248 return QObject::tr("Comment");
250 case CONDITIONAL:
251 return QObject::tr("Conditional Tag");
253 case TAG:
254 return QObject::tr("Tag");
256 case NEWLINE:
257 return QObject::tr("Newline");
259 case TEXT:
260 return QObject::tr("Plaintext");
263 else if(param)
265 switch(param->type)
267 case skin_tag_parameter::STRING:
268 return QObject::tr("String");
270 case skin_tag_parameter::NUMERIC:
271 return QObject::tr("Number");
273 case skin_tag_parameter::DEFAULT:
274 return QObject::tr("Default Argument");
276 case skin_tag_parameter::CODE:
277 return QObject::tr("This doesn't belong here");
280 else
282 return QObject::tr("Root");
285 break;
287 case ParseTreeModel::valueColumn:
288 if(element)
290 switch(element->type)
292 case VIEWPORT:
293 case LINE:
294 case SUBLINES:
295 case CONDITIONAL:
296 return QString();
298 case NEWLINE:
299 return QObject::tr("\\n");
301 case TEXT:
302 case COMMENT:
303 return QString(element->text);
305 case TAG:
306 return QString(element->tag->name);
309 else if(param)
311 switch(param->type)
313 case skin_tag_parameter::DEFAULT:
314 return QObject::tr("-");
316 case skin_tag_parameter::STRING:
317 return QString(param->data.text);
319 case skin_tag_parameter::NUMERIC:
320 return QString::number(param->data.numeric, 10);
322 case skin_tag_parameter::CODE:
323 return QObject::tr("Seriously, something's wrong here");
326 else
328 return QString();
330 break;
332 case ParseTreeModel::lineColumn:
333 if(element)
334 return QString::number(element->line, 10);
335 else
336 return QString();
337 break;
340 return QVariant();
344 int ParseTreeNode::getRow() const
346 if(!parent)
347 return -1;
349 return parent->children.indexOf(const_cast<ParseTreeNode*>(this));
352 ParseTreeNode* ParseTreeNode::getParent() const
354 return parent;
357 ParseTreeNode::~ParseTreeNode()
359 for(int i = 0; i < children.count(); i++)
360 delete children[i];