Theme Editor: Fixed some more code generation bugs
[kugel-rb.git] / utils / themeeditor / parsetreenode.cpp
blob7530299870b9f96720c05a7d1810dc63a050f095
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 if(children[0]->element->type == TAG)
101 buffer.append(TAGSYM);
102 buffer.append(children[0]->genCode());
103 if(children[0]->element->type == TAG)
104 buffer.append('\n');
105 for(int i = 1; i < children.count(); i++)
106 buffer.append(children[i]->genCode());
107 break;
109 case LINE:
110 for(int i = 0; i < children.count(); i++)
113 Adding a % in case of tag, because the tag rendering code
114 doesn't insert its own
116 if(children[i]->element->type == TAG)
117 buffer.append(TAGSYM);
118 buffer.append(children[i]->genCode());
120 buffer.append('\n');
121 break;
123 case SUBLINES:
124 for(int i = 0; i < children.count(); i++)
126 buffer.append(children[i]->genCode());
127 if(i != children.count() - 1)
128 buffer.append(MULTILINESYM);
130 buffer.append('\n');
131 break;
133 case CONDITIONAL:
134 /* Inserts a %?, the tag renderer doesn't deal with the TAGSYM */
135 buffer.append(TAGSYM);
136 buffer.append(CONDITIONSYM);
137 buffer.append(children[0]->genCode());
139 /* Inserting the sublines */
140 buffer.append(ENUMLISTOPENSYM);
141 for(int i = 1; i < children.count(); i++)
143 buffer.append(children[i]->genCode());
144 if(i != children.count() - 1)
145 buffer.append(ENUMLISTSEPERATESYM);
147 buffer.append(ENUMLISTCLOSESYM);
148 break;
150 case TAG:
151 /* When generating code, we DO NOT insert the leading TAGSYM, leave
152 * the calling functions to handle that
154 buffer.append(element->tag->name);
156 if(element->params_count > 0)
158 /* Rendering parameters if there are any */
159 buffer.append(ARGLISTOPENSYM);
160 for(int i = 0; i < children.count(); i++)
162 buffer.append(children[i]->genCode());
163 if(i != children.count() - 1)
164 buffer.append(ARGLISTSEPERATESYM);
166 buffer.append(ARGLISTCLOSESYM);
168 break;
170 case TEXT:
171 for(char* cursor = element->text; *cursor; cursor++)
173 if(find_escape_character(*cursor))
174 buffer.append(TAGSYM);
175 buffer.append(*cursor);
177 break;
179 case COMMENT:
180 buffer.append(COMMENTSYM);
181 buffer.append(element->text);
182 buffer.append('\n');
183 break;
186 else if(param)
188 switch(param->type)
190 case skin_tag_parameter::STRING:
191 for(char* cursor = param->data.text; *cursor; cursor++)
193 if(find_escape_character(*cursor))
194 buffer.append(TAGSYM);
195 buffer.append(*cursor);
197 break;
199 case skin_tag_parameter::NUMERIC:
200 buffer.append(QString::number(param->data.numeric, 10));
201 break;
203 case skin_tag_parameter::DEFAULT:
204 buffer.append(DEFAULTSYM);
205 break;
207 case skin_tag_parameter::CODE:
208 buffer.append(QObject::tr("This doesn't belong here"));
209 break;
213 else
215 for(int i = 0; i < children.count(); i++)
216 buffer.append(children[i]->genCode());
219 return buffer;
222 ParseTreeNode* ParseTreeNode::child(int row)
224 if(row < 0 || row >= children.count())
225 return 0;
227 return children[row];
230 int ParseTreeNode::numChildren() const
232 return children.count();
236 QVariant ParseTreeNode::data(int column) const
238 switch(column)
240 case ParseTreeModel::typeColumn:
241 if(element)
243 switch(element->type)
245 case VIEWPORT:
246 return QObject::tr("Viewport");
248 case LINE:
249 return QObject::tr("Logical Line");
251 case SUBLINES:
252 return QObject::tr("Alternator");
254 case COMMENT:
255 return QObject::tr("Comment");
257 case CONDITIONAL:
258 return QObject::tr("Conditional Tag");
260 case TAG:
261 return QObject::tr("Tag");
263 case TEXT:
264 return QObject::tr("Plaintext");
267 else if(param)
269 switch(param->type)
271 case skin_tag_parameter::STRING:
272 return QObject::tr("String");
274 case skin_tag_parameter::NUMERIC:
275 return QObject::tr("Number");
277 case skin_tag_parameter::DEFAULT:
278 return QObject::tr("Default Argument");
280 case skin_tag_parameter::CODE:
281 return QObject::tr("This doesn't belong here");
284 else
286 return QObject::tr("Root");
289 break;
291 case ParseTreeModel::valueColumn:
292 if(element)
294 switch(element->type)
296 case VIEWPORT:
297 case LINE:
298 case SUBLINES:
299 case CONDITIONAL:
300 return QString();
302 case TEXT:
303 case COMMENT:
304 return QString(element->text);
306 case TAG:
307 return QString(element->tag->name);
310 else if(param)
312 switch(param->type)
314 case skin_tag_parameter::DEFAULT:
315 return QObject::tr("-");
317 case skin_tag_parameter::STRING:
318 return QString(param->data.text);
320 case skin_tag_parameter::NUMERIC:
321 return QString::number(param->data.numeric, 10);
323 case skin_tag_parameter::CODE:
324 return QObject::tr("Seriously, something's wrong here");
327 else
329 return QString();
331 break;
333 case ParseTreeModel::lineColumn:
334 if(element)
335 return QString::number(element->line, 10);
336 else
337 return QString();
338 break;
341 return QVariant();
345 int ParseTreeNode::getRow() const
347 if(!parent)
348 return -1;
350 return parent->children.indexOf(const_cast<ParseTreeNode*>(this));
353 ParseTreeNode* ParseTreeNode::getParent() const
355 return parent;
358 ParseTreeNode::~ParseTreeNode()
360 for(int i = 0; i < children.count(); i++)
361 delete children[i];