1 /***************************************************************************
3 * Open \______ \ ____ ____ | | _\_ |__ _______ ___
4 * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
5 * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
6 * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
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 ****************************************************************************/
23 #include "tag_table.h"
25 #include "parsetreenode.h"
26 #include "parsetreemodel.h"
28 int ParseTreeNode::openConditionals
= 0;
30 /* Root element constructor */
31 ParseTreeNode::ParseTreeNode(struct skin_element
* data
)
32 : parent(0), element(0), param(0), children()
36 children
.append(new ParseTreeNode(data
, this));
41 /* Normal element constructor */
42 ParseTreeNode::ParseTreeNode(struct skin_element
* data
, ParseTreeNode
* parent
)
43 : parent(parent
), element(data
), param(0), children()
49 for(int i
= 0; i
< element
->params_count
; i
++)
51 if(element
->params
[i
].type
== skin_tag_parameter::CODE
)
52 children
.append(new ParseTreeNode(element
->params
[i
].data
.code
,
55 children
.append(new ParseTreeNode(&element
->params
[i
], this));
60 for(int i
= 0; i
< element
->params_count
; i
++)
61 children
.append(new ParseTreeNode(&data
->params
[i
], this));
62 for(int i
= 0; i
< element
->children_count
; i
++)
63 children
.append(new ParseTreeNode(data
->children
[i
], this));
67 for(int i
= 0; i
< element
->children_count
; i
++)
69 children
.append(new ParseTreeNode(data
->children
[i
], this));
74 for(int i
= 0; i
< element
->params_count
; i
++)
75 children
.append(new ParseTreeNode(&data
->params
[i
], this));
76 /* Deliberate fall-through here */
79 for(int i
= 0; i
< data
->children_count
; i
++)
81 for(struct skin_element
* current
= data
->children
[i
]; current
;
82 current
= current
->next
)
84 children
.append(new ParseTreeNode(current
, this));
94 /* Parameter constructor */
95 ParseTreeNode::ParseTreeNode(skin_tag_parameter
*data
, ParseTreeNode
*parent
)
96 : parent(parent
), element(0), param(data
), children()
101 QString
ParseTreeNode::genCode() const
107 switch(element
->type
)
111 /* Generating the Viewport tag, if necessary */
114 buffer
.append(TAGSYM
);
115 buffer
.append(element
->tag
->name
);
116 buffer
.append(ARGLISTOPENSYM
);
117 for(int i
= 0; i
< element
->params_count
; i
++)
119 buffer
.append(children
[i
]->genCode());
120 if(i
!= element
->params_count
- 1)
121 buffer
.append(ARGLISTSEPERATESYM
);
123 buffer
.append(ARGLISTCLOSESYM
);
127 for(int i
= element
->params_count
; i
< children
.count(); i
++)
128 buffer
.append(children
[i
]->genCode());
132 for(int i
= 0; i
< children
.count(); i
++)
134 buffer
.append(children
[i
]->genCode());
136 if(openConditionals
== 0
137 && !(parent
&& parent
->element
->type
== SUBLINES
))
144 for(int i
= 0; i
< children
.count(); i
++)
146 buffer
.append(children
[i
]->genCode());
147 if(i
!= children
.count() - 1)
148 buffer
.append(MULTILINESYM
);
150 if(openConditionals
== 0)
157 /* Inserting the tag part */
158 buffer
.append(TAGSYM
);
159 buffer
.append(CONDITIONSYM
);
160 buffer
.append(element
->tag
->name
);
161 if(element
->params_count
> 0)
163 buffer
.append(ARGLISTOPENSYM
);
164 for(int i
= 0; i
< element
->params_count
; i
++)
166 buffer
.append(children
[i
]->genCode());
167 if( i
!= element
->params_count
- 1)
168 buffer
.append(ARGLISTSEPERATESYM
);
169 buffer
.append(ARGLISTCLOSESYM
);
173 /* Inserting the sublines */
174 buffer
.append(ENUMLISTOPENSYM
);
175 for(int i
= element
->params_count
; i
< children
.count(); i
++)
177 buffer
.append(children
[i
]->genCode());
178 if(i
!= children
.count() - 1)
179 buffer
.append(ENUMLISTSEPERATESYM
);
181 buffer
.append(ENUMLISTCLOSESYM
);
186 buffer
.append(TAGSYM
);
187 buffer
.append(element
->tag
->name
);
189 if(element
->params_count
> 0)
191 /* Rendering parameters if there are any */
192 buffer
.append(ARGLISTOPENSYM
);
193 for(int i
= 0; i
< children
.count(); i
++)
195 buffer
.append(children
[i
]->genCode());
196 if(i
!= children
.count() - 1)
197 buffer
.append(ARGLISTSEPERATESYM
);
199 buffer
.append(ARGLISTCLOSESYM
);
204 for(char* cursor
= (char*)element
->data
; *cursor
; cursor
++)
206 if(find_escape_character(*cursor
))
207 buffer
.append(TAGSYM
);
208 buffer
.append(*cursor
);
213 buffer
.append(COMMENTSYM
);
214 buffer
.append((char*)element
->data
);
223 case skin_tag_parameter::STRING
:
224 for(char* cursor
= param
->data
.text
; *cursor
; cursor
++)
226 if(find_escape_character(*cursor
))
227 buffer
.append(TAGSYM
);
228 buffer
.append(*cursor
);
232 case skin_tag_parameter::NUMERIC
:
233 buffer
.append(QString::number(param
->data
.numeric
, 10));
236 case skin_tag_parameter::DEFAULT
:
237 buffer
.append(DEFAULTSYM
);
240 case skin_tag_parameter::CODE
:
241 buffer
.append(QObject::tr("This doesn't belong here"));
248 for(int i
= 0; i
< children
.count(); i
++)
249 buffer
.append(children
[i
]->genCode());
255 /* A more or less random hashing algorithm */
256 int ParseTreeNode::genHash() const
263 hash
+= element
->type
;
264 switch(element
->type
)
270 hash
+= element
->children_count
;
274 for(unsigned int i
= 0; i
< strlen(element
->tag
->name
); i
++)
275 hash
+= element
->tag
->name
[i
];
280 text
= (char*)element
->data
;
281 for(unsigned int i
= 0; i
< strlen(text
); i
++)
284 hash
+= text
[i
] % element
->type
;
286 hash
+= text
[i
] % element
->type
* 2;
298 case skin_tag_parameter::DEFAULT
:
299 case skin_tag_parameter::CODE
:
302 case skin_tag_parameter::NUMERIC
:
303 hash
+= param
->data
.numeric
* (param
->data
.numeric
/ 4);
306 case skin_tag_parameter::STRING
:
307 for(unsigned int i
= 0; i
< strlen(param
->data
.text
); i
++)
310 hash
+= param
->data
.text
[i
] * 2;
312 hash
+= param
->data
.text
[i
];
318 for(int i
= 0; i
< children
.count(); i
++)
320 hash
+= children
[i
]->genHash();
326 ParseTreeNode
* ParseTreeNode::child(int row
)
328 if(row
< 0 || row
>= children
.count())
331 return children
[row
];
334 int ParseTreeNode::numChildren() const
336 return children
.count();
340 QVariant
ParseTreeNode::data(int column
) const
344 case ParseTreeModel::typeColumn
:
347 switch(element
->type
)
350 return QObject::tr("Viewport");
353 return QObject::tr("Logical Line");
356 return QObject::tr("Alternator");
359 return QObject::tr("Comment");
362 return QObject::tr("Conditional Tag");
365 return QObject::tr("Tag");
368 return QObject::tr("Plaintext");
375 case skin_tag_parameter::STRING
:
376 return QObject::tr("String");
378 case skin_tag_parameter::NUMERIC
:
379 return QObject::tr("Number");
381 case skin_tag_parameter::DEFAULT
:
382 return QObject::tr("Default Argument");
384 case skin_tag_parameter::CODE
:
385 return QObject::tr("This doesn't belong here");
390 return QObject::tr("Root");
395 case ParseTreeModel::valueColumn
:
398 switch(element
->type
)
406 return QString(element
->tag
->name
);
410 return QString((char*)element
->data
);
413 return QString(element
->tag
->name
);
420 case skin_tag_parameter::DEFAULT
:
421 return QObject::tr("-");
423 case skin_tag_parameter::STRING
:
424 return QString(param
->data
.text
);
426 case skin_tag_parameter::NUMERIC
:
427 return QString::number(param
->data
.numeric
, 10);
429 case skin_tag_parameter::CODE
:
430 return QObject::tr("Seriously, something's wrong here");
439 case ParseTreeModel::lineColumn
:
441 return QString::number(element
->line
, 10);
451 int ParseTreeNode::getRow() const
456 return parent
->children
.indexOf(const_cast<ParseTreeNode
*>(this));
459 ParseTreeNode
* ParseTreeNode::getParent() const
464 ParseTreeNode::~ParseTreeNode()
466 for(int i
= 0; i
< children
.count(); i
++)