Theme Editor: Began integrating device configuration panel with renderer
[kugel-rb.git] / utils / themeeditor / models / parsetreemodel.cpp
blobff8a27c66057c46517a496d0a775ad38f9514729
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 ****************************************************************************/
23 #include "parsetreemodel.h"
24 #include "symbols.h"
25 #include "rbscreen.h"
26 #include "rbrenderinfo.h"
28 #include <cstdlib>
30 #include <QObject>
31 #include <QPixmap>
32 #include <QMap>
33 #include <QDir>
35 #include <iostream>
37 ParseTreeModel::ParseTreeModel(const char* document, QObject* parent):
38 QAbstractItemModel(parent)
40 this->tree = skin_parse(document);
42 if(tree)
43 this->root = new ParseTreeNode(tree);
44 else
45 this->root = 0;
47 scene = new QGraphicsScene();
51 ParseTreeModel::~ParseTreeModel()
53 if(root)
54 delete root;
55 if(tree)
56 skin_free_tree(tree);
59 QString ParseTreeModel::genCode()
61 if(root)
62 return root->genCode();
63 else
64 return "";
67 QString ParseTreeModel::changeTree(const char *document)
69 struct skin_element* test = skin_parse(document);
71 if(!test)
73 QString error = tr("Error on line ") +
74 QString::number(skin_error_line())
75 + tr(": ") + QString(skin_error_message());
76 return error;
79 ParseTreeNode* temp = new ParseTreeNode(test);
80 if(root && temp->genHash() == root->genHash())
82 delete temp;
83 return tr("Document Parses Successfully");
86 if(root)
88 emit beginRemoveRows(QModelIndex(), 0, root->numChildren() - 1);
89 delete root;
90 emit endRemoveRows();
93 root = temp;
95 emit beginInsertRows(QModelIndex(), 0, temp->numChildren() - 1);
96 emit endInsertRows();
98 return tr("Document Parses Successfully");
102 QModelIndex ParseTreeModel::index(int row, int column,
103 const QModelIndex& parent) const
105 if(!hasIndex(row, column, parent))
106 return QModelIndex();
108 ParseTreeNode* foundParent;
110 if(parent.isValid())
111 foundParent = static_cast<ParseTreeNode*>(parent.internalPointer());
112 else
113 foundParent = root;
115 if(row < foundParent->numChildren() && row >= 0)
116 return createIndex(row, column, foundParent->child(row));
117 else
118 return QModelIndex();
121 QModelIndex ParseTreeModel::parent(const QModelIndex &child) const
123 if(!child.isValid())
124 return QModelIndex();
126 ParseTreeNode* foundParent = static_cast<ParseTreeNode*>
127 (child.internalPointer())->getParent();
129 if(foundParent == root)
130 return QModelIndex();
132 return createIndex(foundParent->getRow(), 0, foundParent);
135 int ParseTreeModel::rowCount(const QModelIndex &parent) const
137 if(!root)
138 return 0;
140 if(!parent.isValid())
141 return root->numChildren();
143 if(parent.column() != typeColumn)
144 return 0;
146 return static_cast<ParseTreeNode*>(parent.internalPointer())->numChildren();
149 int ParseTreeModel::columnCount(const QModelIndex &parent) const
151 if(parent.isValid())
152 return numColumns;
153 else
154 return numColumns;
157 QVariant ParseTreeModel::data(const QModelIndex &index, int role) const
159 if(!index.isValid())
160 return QVariant();
162 if(role != Qt::DisplayRole)
163 return QVariant();
165 return static_cast<ParseTreeNode*>(index.internalPointer())->
166 data(index.column());
169 QVariant ParseTreeModel::headerData(int col, Qt::Orientation orientation,
170 int role) const
172 if(orientation != Qt::Horizontal)
173 return QVariant();
175 if(col >= numColumns)
176 return QVariant();
178 if(role != Qt::DisplayRole)
179 return QVariant();
181 switch(col)
183 case typeColumn:
184 return QObject::tr("Type");
186 case lineColumn:
187 return QObject::tr("Line");
189 case valueColumn:
190 return QObject::tr("Value");
193 return QVariant();
196 Qt::ItemFlags ParseTreeModel::flags(const QModelIndex &index) const
198 Qt::ItemFlags retval = Qt::ItemIsEnabled | Qt::ItemIsSelectable;
200 ParseTreeNode* element = static_cast<ParseTreeNode*>
201 (index.internalPointer());
203 if((element->isParam()
204 || element->getElement()->type == TEXT
205 || element->getElement()->type == COMMENT)
206 && index.column() == valueColumn)
208 retval |= Qt::ItemIsEditable;
211 return retval;
214 bool ParseTreeModel::setData(const QModelIndex &index, const QVariant &value,
215 int role)
217 if(role != Qt::EditRole)
218 return false;
220 if(index.column() != valueColumn)
221 return false;
223 ParseTreeNode* node = static_cast<ParseTreeNode*>
224 (index.internalPointer());
226 if(node->isParam())
228 struct skin_tag_parameter* param = node->getParam();
230 /* Now that we've established that we do, in fact, have a parameter,
231 * set it to its new value if an acceptable one has been entered
233 if(value.toString().trimmed() == QString(QChar(DEFAULTSYM)))
235 if(islower(param->type_code))
236 param->type = skin_tag_parameter::DEFAULT;
237 else
238 return false;
240 else if(tolower(param->type_code) == 's'
241 || tolower(param->type_code) == 'f')
243 if(param->type == skin_tag_parameter::STRING)
244 free(param->data.text);
246 param->type = skin_tag_parameter::STRING;
247 param->data.text = strdup(value.toString().trimmed().toAscii());
249 else if(tolower(param->type_code) == 'i')
251 if(!value.canConvert(QVariant::Int))
252 return false;
254 param->type = skin_tag_parameter::NUMERIC;
255 param->data.numeric = value.toInt();
257 else
259 return false;
262 else
264 struct skin_element* element = node->getElement();
266 if(element->type != COMMENT && element->type != TEXT)
267 return false;
269 free(element->data);
270 element->data = strdup(value.toString().trimmed().toAscii());
273 emit dataChanged(index, index);
274 return true;
277 QGraphicsScene* ParseTreeModel::render(ProjectModel* project,
278 DeviceState* device, const QString* file)
280 scene->clear();
282 /* Setting the background */
283 scene->setBackgroundBrush(QBrush(QPixmap(":/render/scenebg.png")));
285 /* Preparing settings */
286 QMap<QString, QString> settings;
287 if(project)
288 settings = project->getSettings();
290 /* Setting themebase if it can't be derived from the project */
291 if(settings.value("themebase", "") == "" && file && QFile::exists(*file))
293 QDir base(*file);
294 base.cdUp();
295 settings.insert("themebase", base.canonicalPath());
298 if(file)
300 QString skinFile = *file;
301 QStringList decomp = skinFile.split("/");
302 skinFile = decomp[decomp.count() - 1];
303 skinFile.chop(skinFile.length() - skinFile.lastIndexOf("."));
304 settings.insert("imagepath", settings.value("themebase","") + "/wps/" +
305 skinFile);
308 RBScreen* screen = 0;
309 RBRenderInfo info(this, project, &settings, device, screen);
311 /* Adding the screen */
312 screen = new RBScreen(info);
313 scene->addItem(screen);
315 info = RBRenderInfo(this, project, &settings, device, screen);
318 /* Rendering the tree */
319 if(root)
320 root->render(info);
322 return scene;