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 "parsetreemodel.h"
26 #include "rbrenderinfo.h"
37 ParseTreeModel::ParseTreeModel(const char* document
, QObject
* parent
):
38 QAbstractItemModel(parent
)
40 this->tree
= skin_parse(document
);
43 this->root
= new ParseTreeNode(tree
);
47 scene
= new QGraphicsScene();
51 ParseTreeModel::~ParseTreeModel()
59 QString
ParseTreeModel::genCode()
62 return root
->genCode();
67 QString
ParseTreeModel::changeTree(const char *document
)
69 struct skin_element
* test
= skin_parse(document
);
73 QString error
= tr("Error on line ") +
74 QString::number(skin_error_line())
75 + tr(": ") + QString(skin_error_message());
79 ParseTreeNode
* temp
= new ParseTreeNode(test
);
83 emit
beginRemoveRows(QModelIndex(), 0, root
->numChildren() - 1);
90 emit
beginInsertRows(QModelIndex(), 0, temp
->numChildren() - 1);
93 return tr("Document Parses Successfully");
97 QModelIndex
ParseTreeModel::index(int row
, int column
,
98 const QModelIndex
& parent
) const
100 if(!hasIndex(row
, column
, parent
))
101 return QModelIndex();
103 ParseTreeNode
* foundParent
;
106 foundParent
= static_cast<ParseTreeNode
*>(parent
.internalPointer());
110 if(row
< foundParent
->numChildren() && row
>= 0)
111 return createIndex(row
, column
, foundParent
->child(row
));
113 return QModelIndex();
116 QModelIndex
ParseTreeModel::parent(const QModelIndex
&child
) const
119 return QModelIndex();
121 ParseTreeNode
* foundParent
= static_cast<ParseTreeNode
*>
122 (child
.internalPointer())->getParent();
124 if(foundParent
== root
)
125 return QModelIndex();
127 return createIndex(foundParent
->getRow(), 0, foundParent
);
130 int ParseTreeModel::rowCount(const QModelIndex
&parent
) const
135 if(!parent
.isValid())
136 return root
->numChildren();
138 if(parent
.column() != typeColumn
)
141 return static_cast<ParseTreeNode
*>(parent
.internalPointer())->numChildren();
144 int ParseTreeModel::columnCount(const QModelIndex
&parent
) const
152 QVariant
ParseTreeModel::data(const QModelIndex
&index
, int role
) const
157 if(role
!= Qt::DisplayRole
)
160 return static_cast<ParseTreeNode
*>(index
.internalPointer())->
161 data(index
.column());
164 QVariant
ParseTreeModel::headerData(int col
, Qt::Orientation orientation
,
167 if(orientation
!= Qt::Horizontal
)
170 if(col
>= numColumns
)
173 if(role
!= Qt::DisplayRole
)
179 return QObject::tr("Type");
182 return QObject::tr("Line");
185 return QObject::tr("Value");
191 Qt::ItemFlags
ParseTreeModel::flags(const QModelIndex
&index
) const
193 Qt::ItemFlags retval
= Qt::ItemIsEnabled
| Qt::ItemIsSelectable
;
195 ParseTreeNode
* element
= static_cast<ParseTreeNode
*>
196 (index
.internalPointer());
198 if((element
->isParam()
199 || element
->getElement()->type
== TEXT
200 || element
->getElement()->type
== COMMENT
)
201 && index
.column() == valueColumn
)
203 retval
|= Qt::ItemIsEditable
;
209 bool ParseTreeModel::setData(const QModelIndex
&index
, const QVariant
&value
,
212 if(role
!= Qt::EditRole
)
215 if(index
.column() != valueColumn
)
218 ParseTreeNode
* node
= static_cast<ParseTreeNode
*>
219 (index
.internalPointer());
223 struct skin_tag_parameter
* param
= node
->getParam();
225 /* Now that we've established that we do, in fact, have a parameter,
226 * set it to its new value if an acceptable one has been entered
228 if(value
.toString().trimmed() == QString(QChar(DEFAULTSYM
)))
230 if(islower(param
->type_code
))
231 param
->type
= skin_tag_parameter::DEFAULT
;
235 else if(tolower(param
->type_code
) == 's'
236 || tolower(param
->type_code
) == 'f')
238 if(param
->type
== skin_tag_parameter::STRING
)
239 free(param
->data
.text
);
241 param
->type
= skin_tag_parameter::STRING
;
242 param
->data
.text
= strdup(value
.toString().trimmed().toAscii());
244 else if(tolower(param
->type_code
) == 'i')
246 if(!value
.canConvert(QVariant::Int
))
249 param
->type
= skin_tag_parameter::INTEGER
;
250 param
->data
.number
= value
.toInt();
259 struct skin_element
* element
= node
->getElement();
261 if(element
->type
!= COMMENT
&& element
->type
!= TEXT
)
265 element
->data
= strdup(value
.toString().trimmed().toAscii());
268 emit
dataChanged(index
, index
);
272 QGraphicsScene
* ParseTreeModel::render(ProjectModel
* project
,
273 DeviceState
* device
, const QString
* file
)
277 /* Setting the background */
278 scene
->setBackgroundBrush(QBrush(QPixmap(":/render/scenebg.png")));
280 /* Preparing settings */
281 QMap
<QString
, QString
> settings
;
283 settings
= project
->getSettings();
285 /* Setting themebase if it can't be derived from the project */
286 if(settings
.value("themebase", "") == "" && file
&& QFile::exists(*file
))
290 settings
.insert("themebase", base
.canonicalPath());
293 /* Finding imagebase and determining remote/wps status */
298 QString skinFile
= *file
;
299 QStringList decomp
= skinFile
.split("/");
300 skinFile
= decomp
[decomp
.count() - 1];
301 skinFile
.chop(skinFile
.length() - skinFile
.lastIndexOf("."));
302 settings
.insert("imagepath", settings
.value("themebase","") + "/wps/" +
305 decomp
= file
->split(".");
306 QString extension
= decomp
.last();
307 if(extension
[0] == 'r')
309 if(extension
.right(3) == "wps")
313 /* Rendering SBS, if necessary */
314 RBScreen
* sbsScreen
= 0;
315 if(wps
&& device
->data("rendersbs").toBool())
317 QString sbsFile
= settings
.value(remote
? "rsbs" : "sbs", "");
318 sbsFile
.replace("/.rockbox" , settings
.value("themebase",""));
320 if(QFile::exists(sbsFile
))
323 sbs
.open(QFile::ReadOnly
| QFile::Text
);
324 ParseTreeModel
sbsModel(QString(sbs
.readAll()).toAscii());
326 if(sbsModel
.root
!= 0)
328 RBRenderInfo
sbsInfo(&sbsModel
, project
, &settings
, device
,
331 sbsScreen
= new RBScreen(sbsInfo
, remote
);
332 scene
->addItem(sbsScreen
);
334 sbsInfo
= RBRenderInfo(&sbsModel
, project
, &settings
, device
,
336 sbsModel
.root
->render(sbsInfo
);
342 RBScreen
* screen
= 0;
343 RBRenderInfo
info(this, project
, &settings
, device
, screen
, sbsScreen
);
345 /* Adding the screen */
347 screen
= new RBScreen(info
, remote
, sbsScreen
->getCustomUI());
349 screen
= new RBScreen(info
, remote
);
352 scene
->addItem(screen
);
354 info
= RBRenderInfo(this, project
, &settings
, device
, screen
, sbsScreen
);
357 /* Rendering the tree */