~ubuntu-branches/ubuntu/precise/grantlee/precise

« back to all changes in this revision

Viewing changes to scriptabletags/scriptablenode.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Harald Sitter
  • Date: 2010-06-11 23:41:45 UTC
  • Revision ID: james.westby@ubuntu.com-20100611234145-oas7rhdrbwy8j55c
Tags: upstream-0.1.1
ImportĀ upstreamĀ versionĀ 0.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
  This file is part of the Grantlee template system.
 
3
 
 
4
  Copyright (c) 2009,2010 Stephen Kelly <steveire@gmail.com>
 
5
 
 
6
  This library is free software; you can redistribute it and/or
 
7
  modify it under the terms of the GNU Lesser General Public
 
8
  License as published by the Free Software Foundation; either version
 
9
  2 of the Licence, or (at your option) any later version.
 
10
 
 
11
  This library is distributed in the hope that it will be useful,
 
12
  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
13
  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 
14
  Library General Public License for more details.
 
15
 
 
16
  You should have received a copy of the GNU Lesser General Public
 
17
  License along with this library.  If not, see <http://www.gnu.org/licenses/>.
 
18
 
 
19
*/
 
20
 
 
21
#include "scriptablenode.h"
 
22
 
 
23
#include <QtScript/QScriptEngine>
 
24
 
 
25
#include "context.h"
 
26
#include "scriptablecontext.h"
 
27
#include "scriptableparser.h"
 
28
#include "engine.h"
 
29
#include "exception.h"
 
30
#include "parser.h"
 
31
 
 
32
Q_DECLARE_METATYPE( Engine* )
 
33
 
 
34
QScriptValue nodeToScriptValue( QScriptEngine *engine, Node* const &node )
 
35
{
 
36
  return engine->newQObject( node );
 
37
}
 
38
 
 
39
void nodeFromScriptValue( const QScriptValue &object, Node* &out )
 
40
{
 
41
  out = qobject_cast<Node*>( object.toQObject() );
 
42
}
 
43
 
 
44
 
 
45
Q_SCRIPT_DECLARE_QMETAOBJECT( ScriptableNode, Node* )
 
46
 
 
47
QScriptValue ScriptableNodeConstructor( QScriptContext *context,
 
48
                                        QScriptEngine *engine )
 
49
{
 
50
  QString scriptableNodeName = context->argument( 0 ).toString();
 
51
  QScriptValue concreteNode = engine->globalObject().property( scriptableNodeName );
 
52
 
 
53
  QScriptValueList args;
 
54
  // First is the node type
 
55
  for ( int i = 1; i < context->argumentCount(); ++i ) {
 
56
    args << context->argument( i );
 
57
  }
 
58
 
 
59
  concreteNode.call( concreteNode, args );
 
60
 
 
61
  QScriptValue renderMethod = concreteNode.property( "render" );
 
62
 
 
63
  ScriptableNode *object = new ScriptableNode( engine );
 
64
  object->setObjectName( scriptableNodeName );
 
65
  object->setScriptEngine( engine );
 
66
  object->init( concreteNode, renderMethod );
 
67
  return engine->newQObject( object );
 
68
}
 
69
 
 
70
 
 
71
ScriptableNode::ScriptableNode( QObject* parent ): Node( parent ), m_scriptEngine( 0 )
 
72
{
 
73
}
 
74
 
 
75
 
 
76
void ScriptableNode::setScriptEngine( QScriptEngine *engine )
 
77
{
 
78
  m_scriptEngine = engine;
 
79
}
 
80
 
 
81
void ScriptableNode::init( const QScriptValue &concreteNode,
 
82
                           const QScriptValue &renderMethod )
 
83
{
 
84
  m_concreteNode = concreteNode;
 
85
  m_renderMethod = renderMethod;
 
86
}
 
87
 
 
88
void ScriptableNode::render( OutputStream *stream, Context *c )
 
89
{
 
90
  ScriptableContext sc( c );
 
91
  QScriptValue contextObject = m_scriptEngine->newQObject( &sc );
 
92
 
 
93
  QScriptValueList args;
 
94
  args << contextObject;
 
95
 
 
96
  // Call the render method in the context of the concreteNode
 
97
  QScriptValue value = m_renderMethod.call( m_concreteNode, args );
 
98
 
 
99
  if ( value.isValid() && !value.isUndefined() )
 
100
    ( *stream ) << value.toString();
 
101
}
 
102
 
 
103
ScriptableNodeFactory::ScriptableNodeFactory( QObject* parent )
 
104
    : AbstractNodeFactory( parent ), m_scriptEngine( 0 )
 
105
{
 
106
 
 
107
}
 
108
 
 
109
void ScriptableNodeFactory::setScriptEngine( QScriptEngine *engine )
 
110
{
 
111
  m_scriptEngine = engine;
 
112
}
 
113
 
 
114
void ScriptableNodeFactory::setEngine(Engine* engine)
 
115
{
 
116
  m_scriptEngine->setProperty( "templateEngine", QVariant::fromValue( engine ) );
 
117
}
 
118
 
 
119
void ScriptableNodeFactory::setFactory( QScriptValue factoryMethod )
 
120
{
 
121
  m_factoryMethod = factoryMethod;
 
122
}
 
123
 
 
124
Node* ScriptableNodeFactory::getNode( const QString &tagContent, Parser *p ) const
 
125
{
 
126
  if ( m_scriptEngine->hasUncaughtException() ) {
 
127
    throw Grantlee::Exception( TagSyntaxError, m_scriptEngine->uncaughtExceptionBacktrace().join( " " ) );
 
128
  }
 
129
  ScriptableParser *sp = new ScriptableParser( p, m_scriptEngine );
 
130
  QScriptValue parserObject = m_scriptEngine->newQObject( sp );
 
131
 
 
132
  QScriptValueList args;
 
133
  args << tagContent;
 
134
  args << parserObject;
 
135
 
 
136
  QScriptValue factory = m_factoryMethod;
 
137
 
 
138
  QScriptValue scriptNode = factory.call( factory, args );
 
139
  if ( m_scriptEngine->hasUncaughtException() )
 
140
    throw Grantlee::Exception( TagSyntaxError, m_scriptEngine->uncaughtExceptionBacktrace().join( " " ) );
 
141
 
 
142
  Node* node = qscriptvalue_cast<Node*>( scriptNode );
 
143
  node->setParent( p );
 
144
  return node;
 
145
}
 
146
 
 
147
QScriptEngine* ScriptableNode::engine()
 
148
{
 
149
  return m_scriptEngine;
 
150
}
 
151
 
 
152
void ScriptableNode::setNodeList( const QString &name, QObjectList objectList )
 
153
{
 
154
  QScriptValue objectListArray = m_scriptEngine->newArray( objectList.size() );
 
155
 
 
156
  for ( int i = 0; i < objectList.size(); ++i ) {
 
157
    objectListArray.setProperty( i, m_scriptEngine->newQObject( objectList.at( i ) ) );
 
158
  }
 
159
  m_concreteNode.setProperty( name, objectListArray );
 
160
}
 
161
 
 
162
 
 
163
#include "scriptablenode.moc"