source: trunk/tools/designer/src/lib/uilib/formscriptrunner.cpp@ 561

Last change on this file since 561 was 561, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.1 sources.

File size: 6.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the Qt Designer of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "formscriptrunner_p.h"
43#include "formbuilderextra_p.h"
44#include "ui4_p.h"
45
46#include <QtScript/QScriptEngine>
47#include <QtGui/QWidget>
48#include <QtCore/QDebug>
49#include <QtCore/QCoreApplication>
50
51QT_BEGIN_NAMESPACE
52
53namespace {
54 enum { debugFormScriptRunner = 0 };
55}
56
57#ifdef QFORMINTERNAL_NAMESPACE
58namespace QFormInternal {
59#endif
60
61class QFormScriptRunner::QFormScriptRunnerPrivate {
62public:
63 QFormScriptRunnerPrivate() : m_options(DisableScripts) {}
64 void clearErrors() { m_errors.clear(); }
65
66 bool run(const QString &script, QWidget *widget, const WidgetList &children, QString *errorMessage);
67
68 static void initializeEngine(QWidget *w, const WidgetList &children, QScriptEngine &scriptEngine);
69 static QString engineError(QScriptEngine &scriptEngine);
70
71 Options options() const { return m_options; }
72 void setOptions(Options options) { m_options = options; }
73
74 Errors errors() const { return m_errors; }
75private:
76 QScriptEngine m_scriptEngine;
77 Options m_options;
78 Errors m_errors;
79};
80
81bool QFormScriptRunner::QFormScriptRunnerPrivate::run(const QString &script, QWidget *widget, const WidgetList &children, QString *errorMessage) {
82 bool rc = false;
83 initializeEngine(widget, children, m_scriptEngine);
84
85 do {
86 m_scriptEngine.evaluate(script);
87 if (m_scriptEngine.hasUncaughtException ()) {
88 *errorMessage = QCoreApplication::tr("Exception at line %1: %2").arg(m_scriptEngine.uncaughtExceptionLineNumber()).arg(engineError(m_scriptEngine));
89 break;
90 }
91 rc = true;
92 } while (false);
93 m_scriptEngine.popContext();
94
95 if (!rc) {
96 Error error;
97 error.objectName = widget->objectName();
98 error.script = script;
99 error.errorMessage = *errorMessage;
100 m_errors.push_back(error);
101 }
102 return rc;
103}
104
105void QFormScriptRunner::QFormScriptRunnerPrivate::initializeEngine(QWidget *w, const WidgetList &children, QScriptEngine &scriptEngine) {
106 // Populate the script variables. This pushes a context which must be popped.
107 QScriptContext *ctx = scriptEngine.pushContext();
108 QScriptValue widgetObject = scriptEngine.newQObject(w);
109 QScriptValue childrenArray = scriptEngine.newArray (children.size());
110
111 for(int i = 0; i < children.size(); i++) {
112 childrenArray.setProperty(i, scriptEngine.newQObject(children[i]));
113 }
114
115 const QFormBuilderStrings &strings = QFormBuilderStrings::instance();
116 ctx ->activationObject().setProperty(strings.scriptWidgetVariable, widgetObject);
117 ctx ->activationObject().setProperty(strings.scriptChildWidgetsVariable, childrenArray);
118}
119
120QString QFormScriptRunner::QFormScriptRunnerPrivate::engineError(QScriptEngine &scriptEngine) {
121 QScriptValue error = scriptEngine.evaluate(QLatin1String("Error"));
122 if (error.isValid())
123 return error.toString();
124 return QCoreApplication::tr("Unknown error");
125}
126// -- QFormScriptRunner
127
128QFormScriptRunner::QFormScriptRunner() : m_impl(new QFormScriptRunnerPrivate)
129{
130}
131
132QFormScriptRunner::~QFormScriptRunner()
133{
134 delete m_impl;
135}
136
137bool QFormScriptRunner::run(const DomWidget *domWidget,
138 const QString &customWidgetScript,
139 QWidget *widget, const WidgetList &children,
140 QString *errorMessage)
141{
142 typedef QList<DomScript*> DomScripts;
143
144 const Options scriptOptions = m_impl->options();
145 if (scriptOptions & DisableScripts)
146 return true;
147 // get list
148 const DomScripts domScripts = domWidget->elementScript();
149 // Concatenate snippets, starting with custom widget script
150 QString script = customWidgetScript;
151 if (script.isEmpty() && domScripts.empty())
152 return true;
153
154 foreach (const DomScript *scriptSnippet, domScripts) {
155 // Ensure new line
156 if (!script.isEmpty() && !script.endsWith(QLatin1Char('\n')))
157 script += QLatin1Char('\n');
158 script += scriptSnippet->text();
159 }
160
161 if (script.isEmpty())
162 return true;
163
164 const bool rc = m_impl->run(script, widget, children, errorMessage);
165
166 if (debugFormScriptRunner) {
167 qDebug() << "For " << widget << " with " << children.size() << " children, ran: " << script;
168 if (!rc)
169 qDebug() << *errorMessage;
170 }
171
172 if (!rc) {
173 if (!(scriptOptions & DisableWarnings)) {
174 const QString message = QCoreApplication::tr("An error occurred while running the script for %1: %2\nScript: %3").
175 arg(widget->objectName()).arg(*errorMessage).arg(script);
176 qWarning() << message;
177 }
178 }
179 return rc;
180}
181
182QFormScriptRunner::Options QFormScriptRunner::options() const
183{
184 return m_impl->options();
185}
186
187void QFormScriptRunner::setOptions(Options options)
188{
189 m_impl->setOptions(options);
190}
191
192
193QFormScriptRunner::Errors QFormScriptRunner::errors() const
194{
195 return m_impl->errors();
196}
197
198void QFormScriptRunner::clearErrors()
199{
200 m_impl->clearErrors();
201}
202
203
204#ifdef QFORMINTERNAL_NAMESPACE
205} // namespace QFormInternal
206#endif
207
208QT_END_NAMESPACE
Note: See TracBrowser for help on using the repository browser.