From 6980c1e9988a7c959876ad77b760e042272a9ec2 Mon Sep 17 00:00:00 2001 From: Robert Bieber Date: Sat, 29 May 2010 00:04:04 +0000 Subject: Theme Editor: Got code generation tentatively working along with a solid C++ tree structure for WPS parse trees git-svn-id: svn://svn.rockbox.org/rockbox/trunk@26367 a1c6a512-1295-4272-9138-f99709370657 --- utils/themeeditor/parsetreenode.cpp | 228 ++++++++++++++++++++++++++++-------- 1 file changed, 177 insertions(+), 51 deletions(-) (limited to 'utils/themeeditor/parsetreenode.cpp') diff --git a/utils/themeeditor/parsetreenode.cpp b/utils/themeeditor/parsetreenode.cpp index 77ec897dd7..ccfac615be 100644 --- a/utils/themeeditor/parsetreenode.cpp +++ b/utils/themeeditor/parsetreenode.cpp @@ -1,74 +1,200 @@ -#include "parsetreenode.h" +/*************************************************************************** + * __________ __ ___. + * Open \______ \ ____ ____ | | _\_ |__ _______ ___ + * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / + * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < + * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ + * \/ \/ \/ \/ \/ + * $Id$ + * + * Copyright (C) 2010 Robert Bieber + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version 2 + * of the License, or (at your option) any later version. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + ****************************************************************************/ -ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent, - bool tree) +extern "C" { +#include "symbols.h" +} - if(tree) - { - while(data) - { - appendChild(new ParseTreeNode(data, this, false)); - data = data->next; - } - parentLink = 0; - } - else +#include "parsetreenode.h" + +/* Root element constructor */ +ParseTreeNode::ParseTreeNode(struct skin_element* data) + : parent(0), element(0), param(0), children() +{ + while(data) { - element = data; - parentLink = parent; + children.append(new ParseTreeNode(data, this)); + data = data->next; } - } -ParseTreeNode::ParseTreeNode(struct skin_tag_parameter* param, - ParseTreeNode* parent) - :parentLink(parent), element(0), param(param) +/* Normal element constructor */ +ParseTreeNode::ParseTreeNode(struct skin_element* data, ParseTreeNode* parent) + : parent(parent), element(data), param(0), children() { + switch(element->type) + { -} + case TAG: + for(int i = 0; i < element->params_count; i++) + { + if(element->params[i].type == skin_tag_parameter::CODE) + children.append(new ParseTreeNode(element->params[i].data.code, + this)); + else + children.append(new ParseTreeNode(&element->params[i], this)); + } + break; + /* CONDITIONAL and SUBLINES fall through to the same code */ + case CONDITIONAL: + case SUBLINES: + for(int i = 0; i < element->children_count; i++) + { + children.append(new ParseTreeNode(data->children[i], this)); + } + break; -ParseTreeNode::~ParseTreeNode() -{ - qDeleteAll(children); -} + case LINE: + for(struct skin_element* current = data->children[0]; current; + current = current->next) + { + children.append(new ParseTreeNode(current, this)); + } + break; -void ParseTreeNode::appendChild(ParseTreeNode* child) -{ - children.append(child); + default: + break; + } } -ParseTreeNode* ParseTreeNode::child(int row) +/* Parameter constructor */ +ParseTreeNode::ParseTreeNode(skin_tag_parameter *data, ParseTreeNode *parent) + : parent(parent), element(0), param(data), children() { - return children[row]; -} -int ParseTreeNode::childCount() const -{ - return children.count(); } -int ParseTreeNode::columnCount() const +QString ParseTreeNode::genCode() const { - return 2; -} + QString buffer = ""; -QVariant ParseTreeNode::data(int column) const -{ - if(column == 0) - return element->type; + if(element) + { + switch(element->type) + { + case LINE: + for(int i = 0; i < children.count(); i++) + { + /* + Adding a % in case of tag, because the tag rendering code + doesn't insert its own + */ + if(children[i]->element->type == TAG) + buffer.append(TAGSYM); + buffer.append(children[i]->genCode()); + } + break; + + case SUBLINES: + for(int i = 0; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + if(i != children.count() - 1) + buffer.append(MULTILINESYM); + } + break; + + case CONDITIONAL: + /* Inserts a %?, the tag renderer doesn't deal with the TAGSYM */ + buffer.append(TAGSYM); + buffer.append(CONDITIONSYM); + buffer.append(children[0]->genCode()); + + /* Inserting the sublines */ + buffer.append(ENUMLISTOPENSYM); + for(int i = 1; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + if(i != children.count() - 1) + buffer.append(ENUMLISTSEPERATESYM); + } + buffer.append(ENUMLISTCLOSESYM); + break; + + case TAG: + /* When generating code, we DO NOT insert the leading TAGSYM, leave + * the calling functions to handle that + */ + buffer.append(element->name); + + if(element->params_count > 0) + { + /* Rendering parameters if there are any */ + buffer.append(ARGLISTOPENSYM); + for(int i = 0; i < children.count(); i++) + { + buffer.append(children[i]->genCode()); + if(i != children.count() - 1) + buffer.append(ARGLISTSEPERATESYM); + } + buffer.append(ARGLISTCLOSESYM); + } + break; + + case NEWLINE: + buffer.append('\n'); + break; + + case TEXT: + buffer.append(element->text); + break; + + case COMMENT: + buffer.append(COMMENTSYM); + buffer.append(element->text); + break; + } + } + else if(param) + { + switch(param->type) + { + case skin_tag_parameter::STRING: + buffer.append(param->data.text); + break; + + case skin_tag_parameter::NUMERIC: + buffer.append(QString::number(param->data.numeric, 10)); + break; + + case skin_tag_parameter::DEFAULT: + buffer.append(DEFAULTSYM); + break; + + } + } else - return element->line; -} -int ParseTreeNode::row() const -{ - if(parentLink) - return parentLink->children.indexOf(const_cast(this)); - return 0; -} + { + for(int i = 0; i < children.count(); i++) + buffer.append(children[i]->genCode()); + } -ParseTreeNode* ParseTreeNode::parent() -{ - return parentLink; + return buffer; } +/* +ParseTreeNode* child(int row); +int numChildren() const; +QVariant data(int column) const; +int getRow() const; +ParseTreeNode* getParent(); +*/ -- cgit v1.2.3