Theme Editor: Made Viewport the top level parse tree element, along with a bugfix...
[kugel-rb.git] / utils / themeeditor / parsetreenode.cpp
blob7b77b62eccba5ec95b521e2ff5f431d02e09aa47
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 extern "C"
24 #include "symbols.h"
27 #include "parsetreenode.h"
29 /* Root element constructor */
30 ParseTreeNode::ParseTreeNode(struct skin_element* data)
31 : parent(0), element(0), param(0), children()
33 while(data)
35 children.append(new ParseTreeNode(data, this));
36 data = data->next;
40 /* Normal element constructor */
41 ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent)
42 : parent(parent), element(data), param(0), children()
44 switch(element->type)
47 case TAG:
48 for(int i = 0; i < element->params_count; i++)
50 if(element->params[i].type == skin_tag_parameter::CODE)
51 children.append(new ParseTreeNode(element->params[i].data.code,
52 this));
53 else
54 children.append(new ParseTreeNode(&element->params[i], this));
56 break;
58 /* CONDITIONAL and SUBLINES fall through to the same code */
59 case CONDITIONAL:
60 case SUBLINES:
61 for(int i = 0; i < element->children_count; i++)
63 children.append(new ParseTreeNode(data->children[i], this));
65 break;
67 case VIEWPORT:
68 case LINE:
69 for(struct skin_element* current = data->children[0]; current;
70 current = current->next)
72 children.append(new ParseTreeNode(current, this));
74 break;
76 default:
77 break;
81 /* Parameter constructor */
82 ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent)
83 : parent(parent), element(0), param(data), children()
88 QString ParseTreeNode::genCode() const
90 QString buffer = "";
92 if(element)
94 switch(element->type)
97 case VIEWPORT:
98 buffer.append(children[0]->genCode());
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->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 buffer.append(element->text);
165 break;
167 case COMMENT:
168 buffer.append(COMMENTSYM);
169 buffer.append(element->text);
170 break;
173 else if(param)
175 switch(param->type)
177 case skin_tag_parameter::STRING:
178 buffer.append(param->data.text);
179 break;
181 case skin_tag_parameter::NUMERIC:
182 buffer.append(QString::number(param->data.numeric, 10));
183 break;
185 case skin_tag_parameter::DEFAULT:
186 buffer.append(DEFAULTSYM);
187 break;
189 case skin_tag_parameter::CODE:
190 buffer.append(QObject::tr("This doesn't belong here"));
191 break;
195 else
197 for(int i = 0; i < children.count(); i++)
198 buffer.append(children[i]->genCode());
201 return buffer;
204 ParseTreeNode* ParseTreeNode::child(int row)
206 if(row < 0 || row >= children.count())
207 return 0;
209 return children[row];
212 int ParseTreeNode::numChildren() const
214 return children.count();
218 QVariant ParseTreeNode::data(int column) const
220 switch(column)
222 /* Column 0 is the element type */
223 case 0:
224 if(element)
226 switch(element->type)
228 case VIEWPORT:
229 return QObject::tr("Viewport");
231 case LINE:
232 return QObject::tr("Logical Line");
234 case SUBLINES:
235 return QObject::tr("Alternator");
237 case COMMENT:
238 return QObject::tr("Comment");
240 case CONDITIONAL:
241 return QObject::tr("Conditional Tag");
243 case TAG:
244 return QObject::tr("Tag");
246 case NEWLINE:
247 return QObject::tr("Newline");
249 case TEXT:
250 return QObject::tr("Plaintext");
253 else if(param)
255 switch(param->type)
257 case skin_tag_parameter::STRING:
258 return QObject::tr("String");
260 case skin_tag_parameter::NUMERIC:
261 return QObject::tr("Number");
263 case skin_tag_parameter::DEFAULT:
264 return QObject::tr("Default Argument");
266 case skin_tag_parameter::CODE:
267 return QObject::tr("This doesn't belong here");
270 else
272 return QObject::tr("Root");
275 break;
277 /* Column 1 is the value */
278 case 1:
279 if(element)
281 switch(element->type)
283 case VIEWPORT:
284 case LINE:
285 case SUBLINES:
286 case CONDITIONAL:
287 return QString();
289 case NEWLINE:
290 return QObject::tr("\\n");
292 case TEXT:
293 case COMMENT:
294 return QString(element->text);
296 case TAG:
297 return QString(element->name);
300 else if(param)
302 switch(param->type)
304 case skin_tag_parameter::DEFAULT:
305 return QObject::tr("-");
307 case skin_tag_parameter::STRING:
308 return QString(param->data.text);
310 case skin_tag_parameter::NUMERIC:
311 return QString::number(param->data.numeric, 10);
313 case skin_tag_parameter::CODE:
314 return QObject::tr("Seriously, something's wrong here");
317 else
319 return QString();
321 break;
323 /* Column 2 is the line number */
324 case 2:
325 if(element)
326 return QString::number(element->line, 10);
327 else
328 return QString();
329 break;
332 return QVariant();
336 int ParseTreeNode::getRow() const
338 if(!parent)
339 return -1;
341 return parent->children.indexOf(const_cast<ParseTreeNode*>(this));
344 ParseTreeNode* ParseTreeNode::getParent() const
346 return parent;
349 ParseTreeNode::~ParseTreeNode()
351 for(int i = 0; i < children.count(); i++)
352 delete children[i];