Themeditor: Got the ParseTreeNode class in good shape, preparing to start on ParseTre...
[kugel-rb.git] / utils / themeeditor / parsetreenode.cpp
blob60a18b8dbc895872bc2eb8501985649cc7845de0
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 LINE:
68 for(struct skin_element* current = data->children[0]; current;
69 current = current->next)
71 children.append(new ParseTreeNode(current, this));
73 break;
75 default:
76 break;
80 /* Parameter constructor */
81 ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent)
82 : parent(parent), element(0), param(data), children()
87 QString ParseTreeNode::genCode() const
89 QString buffer = "";
91 if(element)
93 switch(element->type)
95 case LINE:
96 for(int i = 0; i < children.count(); i++)
99 Adding a % in case of tag, because the tag rendering code
100 doesn't insert its own
102 if(children[i]->element->type == TAG)
103 buffer.append(TAGSYM);
104 buffer.append(children[i]->genCode());
106 break;
108 case SUBLINES:
109 for(int i = 0; i < children.count(); i++)
111 buffer.append(children[i]->genCode());
112 if(i != children.count() - 1)
113 buffer.append(MULTILINESYM);
115 break;
117 case CONDITIONAL:
118 /* Inserts a %?, the tag renderer doesn't deal with the TAGSYM */
119 buffer.append(TAGSYM);
120 buffer.append(CONDITIONSYM);
121 buffer.append(children[0]->genCode());
123 /* Inserting the sublines */
124 buffer.append(ENUMLISTOPENSYM);
125 for(int i = 1; i < children.count(); i++)
127 buffer.append(children[i]->genCode());
128 if(i != children.count() - 1)
129 buffer.append(ENUMLISTSEPERATESYM);
131 buffer.append(ENUMLISTCLOSESYM);
132 break;
134 case TAG:
135 /* When generating code, we DO NOT insert the leading TAGSYM, leave
136 * the calling functions to handle that
138 buffer.append(element->name);
140 if(element->params_count > 0)
142 /* Rendering parameters if there are any */
143 buffer.append(ARGLISTOPENSYM);
144 for(int i = 0; i < children.count(); i++)
146 buffer.append(children[i]->genCode());
147 if(i != children.count() - 1)
148 buffer.append(ARGLISTSEPERATESYM);
150 buffer.append(ARGLISTCLOSESYM);
152 break;
154 case NEWLINE:
155 buffer.append('\n');
156 break;
158 case TEXT:
159 buffer.append(element->text);
160 break;
162 case COMMENT:
163 buffer.append(COMMENTSYM);
164 buffer.append(element->text);
165 break;
168 else if(param)
170 switch(param->type)
172 case skin_tag_parameter::STRING:
173 buffer.append(param->data.text);
174 break;
176 case skin_tag_parameter::NUMERIC:
177 buffer.append(QString::number(param->data.numeric, 10));
178 break;
180 case skin_tag_parameter::DEFAULT:
181 buffer.append(DEFAULTSYM);
182 break;
184 case skin_tag_parameter::CODE:
185 buffer.append(QObject::tr("This doesn't belong here"));
186 break;
190 else
192 for(int i = 0; i < children.count(); i++)
193 buffer.append(children[i]->genCode());
196 return buffer;
199 ParseTreeNode* ParseTreeNode::child(int row)
201 if(row < 0 || row >= children.count())
202 return 0;
204 return children[row];
207 int ParseTreeNode::numChildren() const
209 return children.count();
213 QVariant ParseTreeNode::data(int column) const
215 switch(column)
217 /* Column 0 is the element type */
218 case 0:
219 if(element)
221 switch(element->type)
223 case LINE:
224 return QObject::tr("Logical Line");
226 case SUBLINES:
227 return QObject::tr("Alternator");
229 case COMMENT:
230 return QObject::tr("Comment");
232 case CONDITIONAL:
233 return QObject::tr("Conditional Tag");
235 case TAG:
236 return QObject::tr("Tag");
238 case NEWLINE:
239 return QObject::tr("Newline");
241 case TEXT:
242 return QObject::tr("Plaintext");
245 else if(param)
247 switch(param->type)
249 case skin_tag_parameter::STRING:
250 return QObject::tr("String");
252 case skin_tag_parameter::NUMERIC:
253 return QObject::tr("Number");
255 case skin_tag_parameter::DEFAULT:
256 return QObject::tr("Default Argument");
258 case skin_tag_parameter::CODE:
259 return QObject::tr("This doesn't belong here");
262 else
264 return QObject::tr("Root");
267 break;
269 /* Column 1 is the value */
270 case 1:
271 if(element)
273 switch(element->type)
275 case LINE:
276 return QString();
278 case SUBLINES:
279 return QString();
281 case NEWLINE:
282 return QObject::tr("\\n");
284 case TEXT:
285 case COMMENT:
286 return QString(element->text);
288 case CONDITIONAL:
289 case TAG:
290 return QString(element->name);
293 else if(param)
295 switch(param->type)
297 case skin_tag_parameter::DEFAULT:
298 return QObject::tr("-");
300 case skin_tag_parameter::STRING:
301 return QString(param->data.text);
303 case skin_tag_parameter::NUMERIC:
304 return QString::number(param->data.numeric, 10);
306 case skin_tag_parameter::CODE:
307 return QObject::tr("Seriously, something's wrong here");
310 else
312 return QString();
314 break;
316 /* Column 2 is the line number */
317 case 2:
318 if(element)
319 return QString::number(element->line, 10);
320 else
321 return QString();
322 break;
325 return QVariant();
329 int ParseTreeNode::getRow() const
331 if(!parent)
332 return -1;
334 return parent->children.indexOf(const_cast<ParseTreeNode*>(this));
337 ParseTreeNode* ParseTreeNode::getParent() const
339 return parent;
342 ParseTreeNode::~ParseTreeNode()
344 for(int i = 0; i < children.count(); i++)
345 delete children[i];