|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the ActiveQt framework of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:BSD$ |
|
10 ** You may use this file under the terms of the BSD license as follows: |
|
11 ** |
|
12 ** "Redistribution and use in source and binary forms, with or without |
|
13 ** modification, are permitted provided that the following conditions are |
|
14 ** met: |
|
15 ** * Redistributions of source code must retain the above copyright |
|
16 ** notice, this list of conditions and the following disclaimer. |
|
17 ** * Redistributions in binary form must reproduce the above copyright |
|
18 ** notice, this list of conditions and the following disclaimer in |
|
19 ** the documentation and/or other materials provided with the |
|
20 ** distribution. |
|
21 ** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor |
|
22 ** the names of its contributors may be used to endorse or promote |
|
23 ** products derived from this software without specific prior written |
|
24 ** permission. |
|
25 ** |
|
26 ** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|
27 ** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|
28 ** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|
29 ** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|
30 ** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
31 ** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
32 ** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|
33 ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|
34 ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
35 ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
36 ** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE." |
|
37 ** $QT_END_LICENSE$ |
|
38 ** |
|
39 ****************************************************************************/ |
|
40 |
|
41 #include "qaxscript.h" |
|
42 |
|
43 #ifndef QT_NO_WIN_ACTIVEQT |
|
44 |
|
45 #if defined(Q_CC_GNU) |
|
46 # define QT_NO_QAXSCRIPT |
|
47 #elif defined(Q_CC_BOR) && __BORLANDC__ < 0x560 |
|
48 # define QT_NO_QAXSCRIPT |
|
49 #endif |
|
50 |
|
51 #include <qapplication.h> |
|
52 #include <qfile.h> |
|
53 #include <qhash.h> |
|
54 #include <qmetaobject.h> |
|
55 #include <quuid.h> |
|
56 #include <qwidget.h> |
|
57 |
|
58 #include <qt_windows.h> |
|
59 #ifndef QT_NO_QAXSCRIPT |
|
60 #include <initguid.h> |
|
61 #include <activscp.h> |
|
62 #endif |
|
63 |
|
64 #include "../shared/qaxtypes.h" |
|
65 |
|
66 QT_BEGIN_NAMESPACE |
|
67 |
|
68 struct QAxEngineDescriptor { QString name, extension, code; }; |
|
69 static QList<QAxEngineDescriptor> engines; |
|
70 |
|
71 class QAxScriptManagerPrivate |
|
72 { |
|
73 public: |
|
74 QHash<QString, QAxScript*> scriptDict; |
|
75 QHash<QString, QAxBase*> objectDict; |
|
76 }; |
|
77 |
|
78 /* |
|
79 \class QAxScriptSite |
|
80 \brief The QAxScriptSite class implements a Windows Scripting Host |
|
81 \internal |
|
82 |
|
83 The QAxScriptSite is used internally to communicate callbacks from the script |
|
84 engine to the script manager. |
|
85 */ |
|
86 |
|
87 #ifndef QT_NO_QAXSCRIPT |
|
88 |
|
89 class QAxScriptSite : public IActiveScriptSite, public IActiveScriptSiteWindow |
|
90 { |
|
91 public: |
|
92 QAxScriptSite(QAxScript *script); |
|
93 |
|
94 ULONG WINAPI AddRef(); |
|
95 ULONG WINAPI Release(); |
|
96 HRESULT WINAPI QueryInterface(REFIID iid, void **ppvObject); |
|
97 |
|
98 HRESULT WINAPI GetLCID(LCID *plcid); |
|
99 HRESULT WINAPI GetItemInfo(LPCOLESTR pstrName, DWORD dwReturnMask, IUnknown **ppiunkItem, ITypeInfo **ppti); |
|
100 HRESULT WINAPI GetDocVersionString(BSTR *pbstrVersion); |
|
101 |
|
102 HRESULT WINAPI OnScriptTerminate(const VARIANT *pvarResult, const EXCEPINFO *pexcepinfo); |
|
103 HRESULT WINAPI OnStateChange(SCRIPTSTATE ssScriptState); |
|
104 HRESULT WINAPI OnScriptError(IActiveScriptError *pscripterror); |
|
105 HRESULT WINAPI OnEnterScript(); |
|
106 HRESULT WINAPI OnLeaveScript(); |
|
107 |
|
108 HRESULT WINAPI GetWindow(HWND *phwnd); |
|
109 HRESULT WINAPI EnableModeless(BOOL fEnable); |
|
110 |
|
111 protected: |
|
112 QWidget *window() const; |
|
113 |
|
114 private: |
|
115 QAxScript *script; |
|
116 unsigned long ref; |
|
117 }; |
|
118 |
|
119 /* |
|
120 Constructs the site for the \a s. |
|
121 */ |
|
122 QAxScriptSite::QAxScriptSite(QAxScript *s) |
|
123 : script(s), ref(1) |
|
124 { |
|
125 } |
|
126 |
|
127 /* |
|
128 Implements IUnknown::AddRef |
|
129 */ |
|
130 ULONG WINAPI QAxScriptSite::AddRef() |
|
131 { |
|
132 return ++ref; |
|
133 } |
|
134 |
|
135 /* |
|
136 Implements IUnknown::Release |
|
137 */ |
|
138 ULONG WINAPI QAxScriptSite::Release() |
|
139 { |
|
140 if (!--ref) { |
|
141 delete this; |
|
142 return 0; |
|
143 } |
|
144 return ref; |
|
145 } |
|
146 |
|
147 /* |
|
148 Implements IUnknown::QueryInterface |
|
149 */ |
|
150 HRESULT WINAPI QAxScriptSite::QueryInterface(REFIID iid, void **ppvObject) |
|
151 { |
|
152 *ppvObject = 0; |
|
153 if (iid == IID_IUnknown) |
|
154 *ppvObject = (IUnknown*)(IActiveScriptSite*)this; |
|
155 else if (iid == IID_IActiveScriptSite) |
|
156 *ppvObject = (IActiveScriptSite*)this; |
|
157 else if (iid == IID_IActiveScriptSiteWindow) |
|
158 *ppvObject = (IActiveScriptSiteWindow*)this; |
|
159 else |
|
160 return E_NOINTERFACE; |
|
161 |
|
162 AddRef(); |
|
163 return S_OK; |
|
164 } |
|
165 |
|
166 /* |
|
167 Implements IActiveScriptSite::GetLCID |
|
168 |
|
169 This method is not implemented. Use the system-defined locale. |
|
170 */ |
|
171 HRESULT WINAPI QAxScriptSite::GetLCID(LCID * /*plcid*/) |
|
172 { |
|
173 return E_NOTIMPL; |
|
174 } |
|
175 |
|
176 /* |
|
177 Implements IActiveScriptSite::GetItemInfo |
|
178 |
|
179 Tries to find the QAxBase for \a pstrName and returns the |
|
180 relevant interfaces in \a item and \a type as requested through \a mask. |
|
181 */ |
|
182 HRESULT WINAPI QAxScriptSite::GetItemInfo(LPCOLESTR pstrName, DWORD mask, IUnknown **item, ITypeInfo **type) |
|
183 { |
|
184 if (item) |
|
185 *item = 0; |
|
186 else if (mask & SCRIPTINFO_IUNKNOWN) |
|
187 return E_POINTER; |
|
188 |
|
189 if (type) |
|
190 *type = 0; |
|
191 else if (mask & SCRIPTINFO_ITYPEINFO) |
|
192 return E_POINTER; |
|
193 |
|
194 QAxBase *object = script->findObject(QString::fromWCharArray(pstrName)); |
|
195 if (!object) |
|
196 return TYPE_E_ELEMENTNOTFOUND; |
|
197 |
|
198 if (mask & SCRIPTINFO_IUNKNOWN) |
|
199 object->queryInterface(IID_IUnknown, (void**)item); |
|
200 if (mask & SCRIPTINFO_ITYPEINFO) { |
|
201 IProvideClassInfo *classInfo = 0; |
|
202 object->queryInterface(IID_IProvideClassInfo, (void**)&classInfo); |
|
203 if (classInfo) { |
|
204 classInfo->GetClassInfo(type); |
|
205 classInfo->Release(); |
|
206 } |
|
207 } |
|
208 return S_OK; |
|
209 } |
|
210 |
|
211 /* |
|
212 Implements IActiveScriptSite::GetDocVersionString |
|
213 |
|
214 This method is not implemented. The scripting engine should assume |
|
215 that the script is in sync with the document. |
|
216 */ |
|
217 HRESULT WINAPI QAxScriptSite::GetDocVersionString(BSTR * /*version*/) |
|
218 { |
|
219 return E_NOTIMPL; |
|
220 } |
|
221 |
|
222 /* |
|
223 Implements IActiveScriptSite::OnScriptTerminate |
|
224 |
|
225 This method is usually not called, but if it is it fires |
|
226 QAxScript::finished(). |
|
227 */ |
|
228 HRESULT WINAPI QAxScriptSite::OnScriptTerminate(const VARIANT *result, const EXCEPINFO *exception) |
|
229 { |
|
230 emit script->finished(); |
|
231 |
|
232 if (result && result->vt != VT_EMPTY) |
|
233 emit script->finished(VARIANTToQVariant(*result, 0)); |
|
234 if (exception) |
|
235 emit script->finished(exception->wCode, |
|
236 QString::fromWCharArray(exception->bstrSource), |
|
237 QString::fromWCharArray(exception->bstrDescription), |
|
238 QString::fromWCharArray(exception->bstrHelpFile) |
|
239 ); |
|
240 return S_OK; |
|
241 } |
|
242 |
|
243 /* |
|
244 Implements IActiveScriptSite::OnEnterScript |
|
245 |
|
246 Fires QAxScript::entered() to inform the host that the |
|
247 scripting engine has begun executing the script code. |
|
248 */ |
|
249 HRESULT WINAPI QAxScriptSite::OnEnterScript() |
|
250 { |
|
251 emit script->entered(); |
|
252 return S_OK; |
|
253 } |
|
254 |
|
255 /* |
|
256 Implements IActiveScriptSite::OnLeaveScript |
|
257 |
|
258 Fires QAxScript::finished() to inform the host that the |
|
259 scripting engine has returned from executing the script code. |
|
260 */ |
|
261 HRESULT WINAPI QAxScriptSite::OnLeaveScript() |
|
262 { |
|
263 emit script->finished(); |
|
264 return S_OK; |
|
265 } |
|
266 |
|
267 /* |
|
268 Implements IActiveScriptSite::OnScriptError |
|
269 |
|
270 Fires QAxScript::error() to inform the host that an |
|
271 that an execution error occurred while the engine was running the script. |
|
272 */ |
|
273 HRESULT WINAPI QAxScriptSite::OnScriptError(IActiveScriptError *error) |
|
274 { |
|
275 EXCEPINFO exception; |
|
276 memset(&exception, 0, sizeof(exception)); |
|
277 DWORD context; |
|
278 ULONG lineNumber; |
|
279 LONG charPos; |
|
280 BSTR bstrLineText; |
|
281 QString lineText; |
|
282 |
|
283 error->GetExceptionInfo(&exception); |
|
284 error->GetSourcePosition(&context, &lineNumber, &charPos); |
|
285 HRESULT hres = error->GetSourceLineText(&bstrLineText); |
|
286 if (hres == S_OK) { |
|
287 lineText = QString::fromWCharArray(bstrLineText); |
|
288 SysFreeString(bstrLineText); |
|
289 } |
|
290 SysFreeString(exception.bstrSource); |
|
291 SysFreeString(exception.bstrDescription); |
|
292 SysFreeString(exception.bstrHelpFile); |
|
293 |
|
294 emit script->error(exception.wCode, QString::fromWCharArray(exception.bstrDescription), lineNumber, lineText); |
|
295 |
|
296 return S_OK; |
|
297 } |
|
298 |
|
299 /* |
|
300 Implements IActiveScriptSite::OnStateChange |
|
301 |
|
302 Fires QAxScript::stateChanged() to inform the |
|
303 the host that the scripting engine has changed states. |
|
304 */ |
|
305 HRESULT WINAPI QAxScriptSite::OnStateChange(SCRIPTSTATE ssScriptState) |
|
306 { |
|
307 emit script->stateChanged(ssScriptState); |
|
308 return S_OK; |
|
309 } |
|
310 |
|
311 /* |
|
312 \internal |
|
313 Returns the toplevel widget parent of this script, or |
|
314 the application' active window if there is no widget parent. |
|
315 */ |
|
316 QWidget *QAxScriptSite::window() const |
|
317 { |
|
318 QWidget *w = 0; |
|
319 QObject *p = script->parent(); |
|
320 while (!w && p) { |
|
321 w = qobject_cast<QWidget*>(p); |
|
322 p = p->parent(); |
|
323 } |
|
324 |
|
325 if (w) |
|
326 w = w->window(); |
|
327 if (!w && qApp) |
|
328 w = qApp->activeWindow(); |
|
329 |
|
330 return w; |
|
331 } |
|
332 |
|
333 /* |
|
334 Implements IActiveScriptSiteWindow::GetWindow |
|
335 |
|
336 Retrieves the handle to a window that can act as the owner of a |
|
337 pop-up window that the scripting engine must display. |
|
338 */ |
|
339 HRESULT WINAPI QAxScriptSite::GetWindow(HWND *phwnd) |
|
340 { |
|
341 if (!phwnd) |
|
342 return E_POINTER; |
|
343 |
|
344 *phwnd = 0; |
|
345 QWidget *w = window(); |
|
346 if (!w) |
|
347 return E_FAIL; |
|
348 |
|
349 *phwnd = w->winId(); |
|
350 return S_OK; |
|
351 } |
|
352 |
|
353 /* |
|
354 Implements IActiveScriptSiteWindow::EnableModeless |
|
355 |
|
356 Causes the host to enable or disable its main window |
|
357 as well as any modeless dialog boxes. |
|
358 */ |
|
359 HRESULT WINAPI QAxScriptSite::EnableModeless(BOOL fEnable) |
|
360 { |
|
361 QWidget *w = window(); |
|
362 if (!w) |
|
363 return E_FAIL; |
|
364 |
|
365 EnableWindow(w->winId(), fEnable); |
|
366 return S_OK; |
|
367 } |
|
368 |
|
369 #endif //QT_NO_QAXSCRIPT |
|
370 |
|
371 |
|
372 /*! |
|
373 \class QAxScriptEngine |
|
374 \brief The QAxScriptEngine class provides a wrapper around a script engine. |
|
375 \inmodule QAxContainer |
|
376 |
|
377 Every instance of the QAxScriptEngine class represents an interpreter |
|
378 for script code in a particular scripting language. The class is usually |
|
379 not used directly. The QAxScript and QAxScriptManager classes provide |
|
380 convenient functions to handle and call script code. |
|
381 |
|
382 Direct access to the script engine is provided through |
|
383 queryInterface(). |
|
384 |
|
385 \warning This class is not available with the bcc5.5 and MingW |
|
386 compilers. |
|
387 |
|
388 \sa QAxScript, QAxScriptManager, QAxBase, {ActiveQt Framework} |
|
389 */ |
|
390 |
|
391 /*! |
|
392 \enum QAxScriptEngine::State |
|
393 |
|
394 The State enumeration defines the different states a script |
|
395 engine can be in. |
|
396 |
|
397 \value Uninitialized The script has been created, but not yet initialized |
|
398 \value Initialized The script has been initialized, but is not running |
|
399 \value Started The script can execute code, but does not yet handle events |
|
400 \value Connected The script can execute code and is connected so |
|
401 that it can handle events |
|
402 \value Disconnected The script is loaded, but is not connected to |
|
403 event sources |
|
404 \value Closed The script has been closed. |
|
405 */ |
|
406 |
|
407 /*! |
|
408 Constructs a QAxScriptEngine object interpreting script code in \a language |
|
409 provided by the code in \a script. This is usually done by the QAxScript |
|
410 class when \link QAxScript::load() loading a script\endlink. |
|
411 |
|
412 Instances of QAxScriptEngine should always have both a language and a |
|
413 script. |
|
414 */ |
|
415 QAxScriptEngine::QAxScriptEngine(const QString &language, QAxScript *script) |
|
416 : QAxObject(script), script_code(script), engine(0), script_language(language) |
|
417 { |
|
418 #ifdef QT_CHECK_STATE |
|
419 if (language.isEmpty()) |
|
420 qWarning("QAxScriptEngine: created without language"); |
|
421 |
|
422 if (!script_code) |
|
423 qWarning("QAxScriptEngine: created without script"); |
|
424 #endif |
|
425 setObjectName(QLatin1String("QAxScriptEngine_") + language); |
|
426 disableClassInfo(); |
|
427 disableEventSink(); |
|
428 } |
|
429 |
|
430 /*! |
|
431 Destroys the QAxScriptEngine object, releasing all allocated |
|
432 resources. |
|
433 */ |
|
434 QAxScriptEngine::~QAxScriptEngine() |
|
435 { |
|
436 #ifndef QT_NO_QAXSCRIPT |
|
437 if (engine) { |
|
438 engine->SetScriptState(SCRIPTSTATE_DISCONNECTED); |
|
439 engine->Close(); |
|
440 engine->Release(); |
|
441 } |
|
442 #endif |
|
443 } |
|
444 |
|
445 /*! |
|
446 \fn QString QAxScriptEngine::scriptLanguage() const |
|
447 Returns the scripting language, for example "VBScript", |
|
448 or "JScript". |
|
449 */ |
|
450 |
|
451 /*! |
|
452 \reimp |
|
453 */ |
|
454 bool QAxScriptEngine::initialize(IUnknown **ptr) |
|
455 { |
|
456 *ptr = 0; |
|
457 |
|
458 #ifndef QT_NO_QAXSCRIPT |
|
459 if (!script_code || script_language.isEmpty()) |
|
460 return false; |
|
461 |
|
462 CLSID clsid; |
|
463 HRESULT hres = CLSIDFromProgID((wchar_t*)script_language.utf16(), &clsid); |
|
464 if(FAILED(hres)) |
|
465 return false; |
|
466 |
|
467 CoCreateInstance(clsid, 0, CLSCTX_INPROC_SERVER, IID_IActiveScript, (void**)&engine); |
|
468 if (!engine) |
|
469 return false; |
|
470 |
|
471 IActiveScriptParse *parser = 0; |
|
472 engine->QueryInterface(IID_IActiveScriptParse, (void**)&parser); |
|
473 if (!parser) { |
|
474 engine->Release(); |
|
475 engine = 0; |
|
476 return false; |
|
477 } |
|
478 |
|
479 if (engine->SetScriptSite(script_code->script_site) != S_OK) { |
|
480 engine->Release(); |
|
481 engine = 0; |
|
482 return false; |
|
483 } |
|
484 if (parser->InitNew() != S_OK) { |
|
485 parser->Release(); |
|
486 engine->Release(); |
|
487 engine = 0; |
|
488 return false; |
|
489 } |
|
490 |
|
491 BSTR bstrCode = QStringToBSTR(script_code->scriptCode()); |
|
492 #ifdef Q_OS_WIN64 |
|
493 hres = parser->ParseScriptText(bstrCode, 0, 0, 0, DWORDLONG(this), 0, SCRIPTTEXT_ISVISIBLE, 0, 0); |
|
494 #else |
|
495 hres = parser->ParseScriptText(bstrCode, 0, 0, 0, DWORD(this), 0, SCRIPTTEXT_ISVISIBLE, 0, 0); |
|
496 #endif |
|
497 SysFreeString(bstrCode); |
|
498 |
|
499 parser->Release(); |
|
500 parser = 0; |
|
501 |
|
502 script_code->updateObjects(); |
|
503 |
|
504 if (engine->SetScriptState(SCRIPTSTATE_CONNECTED) != S_OK) { |
|
505 engine = 0; |
|
506 return false; |
|
507 } |
|
508 |
|
509 IDispatch *scriptDispatch = 0; |
|
510 engine->GetScriptDispatch(0, &scriptDispatch); |
|
511 if (scriptDispatch) { |
|
512 scriptDispatch->QueryInterface(IID_IUnknown, (void**)ptr); |
|
513 scriptDispatch->Release(); |
|
514 } |
|
515 #endif |
|
516 |
|
517 return *ptr != 0; |
|
518 } |
|
519 |
|
520 /*! |
|
521 \fn bool QAxScriptEngine::isValid() const |
|
522 |
|
523 Returns true if the script engine has been initialized |
|
524 correctly; otherwise returns false. |
|
525 */ |
|
526 |
|
527 /*! |
|
528 Returns true if the script engine supports introspection; |
|
529 otherwise returns false. |
|
530 */ |
|
531 bool QAxScriptEngine::hasIntrospection() const |
|
532 { |
|
533 if (!isValid()) |
|
534 return false; |
|
535 |
|
536 IDispatch *scriptDispatch = 0; |
|
537 QAxBase::queryInterface(IID_IDispatch, (void**)&scriptDispatch); |
|
538 if (!scriptDispatch) |
|
539 return false; |
|
540 |
|
541 UINT tic = 0; |
|
542 HRESULT hres = scriptDispatch->GetTypeInfoCount(&tic); |
|
543 scriptDispatch->Release(); |
|
544 return hres == S_OK && tic > 0; |
|
545 } |
|
546 |
|
547 /*! |
|
548 Requests the interface \a uuid from the script engine object and |
|
549 sets the value of \a iface to the provided interface, or to 0 if |
|
550 the requested interface could not be provided. |
|
551 |
|
552 Returns the result of the QueryInterface implementation of the COM |
|
553 object. |
|
554 */ |
|
555 long QAxScriptEngine::queryInterface(const QUuid &uuid, void **iface) const |
|
556 { |
|
557 *iface = 0; |
|
558 if (!engine) |
|
559 return E_NOTIMPL; |
|
560 |
|
561 #ifndef QT_NO_QAXSCRIPT |
|
562 return engine->QueryInterface(uuid, iface); |
|
563 #else |
|
564 return E_NOTIMPL; |
|
565 #endif |
|
566 } |
|
567 |
|
568 /*! |
|
569 Returns the state of the script engine. |
|
570 */ |
|
571 QAxScriptEngine::State QAxScriptEngine::state() const |
|
572 { |
|
573 if (!engine) |
|
574 return Uninitialized; |
|
575 |
|
576 #ifndef QT_NO_QAXSCRIPT |
|
577 SCRIPTSTATE state; |
|
578 engine->GetScriptState(&state); |
|
579 return (State)state; |
|
580 #else |
|
581 return Uninitialized; |
|
582 #endif |
|
583 } |
|
584 |
|
585 /*! |
|
586 Sets the state of the script engine to \a st. |
|
587 Calling this function is usually not necessary. |
|
588 */ |
|
589 void QAxScriptEngine::setState(State st) |
|
590 { |
|
591 #ifndef QT_NO_QAXSCRIPT |
|
592 if (!engine) |
|
593 return; |
|
594 |
|
595 engine->SetScriptState((SCRIPTSTATE)st); |
|
596 #endif |
|
597 } |
|
598 |
|
599 /*! |
|
600 Registers an item with the script engine. Script code can |
|
601 refer to this item using \a name. |
|
602 */ |
|
603 void QAxScriptEngine::addItem(const QString &name) |
|
604 { |
|
605 #ifndef QT_NO_QAXSCRIPT |
|
606 if (!engine) |
|
607 return; |
|
608 |
|
609 engine->AddNamedItem((wchar_t*)name.utf16(), SCRIPTITEM_ISSOURCE|SCRIPTITEM_ISVISIBLE); |
|
610 #endif |
|
611 } |
|
612 |
|
613 /*! |
|
614 \class QAxScript |
|
615 \brief The QAxScript class provides a wrapper around script code. |
|
616 \inmodule QAxContainer |
|
617 |
|
618 Every instance of the QAxScript class represents a piece of |
|
619 scripting code in a particular scripting language. The code is |
|
620 loaded into the script engine using load(). Functions declared |
|
621 in the code can be called using call(). |
|
622 |
|
623 The script provides scriptEngine() provides feedback to the |
|
624 application through signals. The most important signal is the |
|
625 error() signal. Direct access to the QAxScriptEngine is provided |
|
626 through the scriptEngine() function. |
|
627 |
|
628 \warning This class is not available with the bcc5.5 and MingW |
|
629 compilers. |
|
630 |
|
631 \sa QAxScriptEngine, QAxScriptManager, QAxBase, {ActiveQt Framework} |
|
632 */ |
|
633 |
|
634 /*! |
|
635 \enum QAxScript::FunctionFlags |
|
636 |
|
637 This FunctionFlags enum describes formatting for function introspection. |
|
638 |
|
639 \value FunctionNames Only function names are returned. |
|
640 \value FunctionSignatures Returns the functions with signatures. |
|
641 */ |
|
642 |
|
643 /*! |
|
644 Constructs a QAxScript object called \a name and registers |
|
645 it with the QAxScriptManager \a manager. This is usually done by the |
|
646 QAxScriptManager class when \link QAxScriptManager::load() loading a |
|
647 script\endlink. |
|
648 |
|
649 A script should always have a name. A manager is necessary to allow |
|
650 the script code to reference objects in the application. The \a manager |
|
651 takes ownership of the object. |
|
652 */ |
|
653 QAxScript::QAxScript(const QString &name, QAxScriptManager *manager) |
|
654 : QObject(manager), script_name(name), script_manager(manager), |
|
655 script_engine(0) |
|
656 { |
|
657 if (manager) { |
|
658 manager->d->scriptDict.insert(name, this); |
|
659 connect(this, SIGNAL(error(int,QString,int,QString)), |
|
660 manager, SLOT(scriptError(int,QString,int,QString))); |
|
661 } |
|
662 |
|
663 #ifndef QT_NO_QAXSCRIPT |
|
664 script_site = new QAxScriptSite(this); |
|
665 #else |
|
666 script_site = 0; |
|
667 #endif |
|
668 } |
|
669 |
|
670 /*! |
|
671 Destroys the object, releasing all allocated resources. |
|
672 */ |
|
673 QAxScript::~QAxScript() |
|
674 { |
|
675 delete script_engine; |
|
676 script_engine = 0; |
|
677 |
|
678 #ifndef QT_NO_QAXSCRIPT |
|
679 script_site->Release(); |
|
680 #endif |
|
681 } |
|
682 |
|
683 /*! |
|
684 Loads the script source \a code written in language \a language |
|
685 into the script engine. Returns true if \a code was successfully |
|
686 entered into the script engine; otherwise returns false. |
|
687 |
|
688 If \a language is empty (the default) it will be determined |
|
689 heuristically. If \a code contains the string \c {End Sub} it will |
|
690 be interpreted as VBScript, otherwise as JScript. Additional |
|
691 scripting languages can be registered using |
|
692 QAxScript::registerEngine(). |
|
693 |
|
694 This function can only be called once for each QAxScript object, |
|
695 which is done automatically when using QAxScriptManager::load(). |
|
696 */ |
|
697 bool QAxScript::load(const QString &code, const QString &language) |
|
698 { |
|
699 if (script_engine || code.isEmpty()) |
|
700 return false; |
|
701 |
|
702 script_code = code; |
|
703 QString lang = language; |
|
704 if (lang.isEmpty()) { |
|
705 if (code.contains(QLatin1String("End Sub"), Qt::CaseInsensitive)) |
|
706 lang = QLatin1String("VBScript"); |
|
707 |
|
708 QList<QAxEngineDescriptor>::ConstIterator it; |
|
709 for (it = engines.begin(); it != engines.end(); ++it) { |
|
710 QAxEngineDescriptor engine = *it; |
|
711 if (engine.code.isEmpty()) |
|
712 continue; |
|
713 |
|
714 if (code.contains(engine.code)) { |
|
715 lang = engine.name; |
|
716 break; |
|
717 } |
|
718 } |
|
719 } |
|
720 if (lang.isEmpty()) |
|
721 lang = QLatin1String("JScript"); |
|
722 |
|
723 script_engine = new QAxScriptEngine(lang, this); |
|
724 // trigger call to initialize |
|
725 script_engine->metaObject(); |
|
726 |
|
727 return script_engine->isValid(); |
|
728 } |
|
729 |
|
730 /*! |
|
731 Returns a list of all the functions in this script if the respective |
|
732 script engine supports introspection; otherwise returns an empty list. |
|
733 The functions are either provided with full prototypes or only as |
|
734 names, depending on the value of \a flags. |
|
735 |
|
736 \sa QAxScriptEngine::hasIntrospection() |
|
737 */ |
|
738 QStringList QAxScript::functions(FunctionFlags flags) const |
|
739 { |
|
740 QStringList functions; |
|
741 |
|
742 const QMetaObject *mo = script_engine->metaObject(); |
|
743 for (int i = mo->methodOffset(); i < mo->methodCount(); ++i) { |
|
744 const QMetaMethod slot(mo->method(i)); |
|
745 if (slot.methodType() != QMetaMethod::Slot || slot.access() != QMetaMethod::Public) |
|
746 continue; |
|
747 QString slotname = QString::fromLatin1(slot.signature()); |
|
748 if (slotname.contains(QLatin1Char('_'))) |
|
749 continue; |
|
750 |
|
751 if (flags == FunctionSignatures) |
|
752 functions << slotname; |
|
753 else |
|
754 functions << slotname.left(slotname.indexOf(QLatin1Char('('))); |
|
755 } |
|
756 |
|
757 return functions; |
|
758 } |
|
759 |
|
760 /*! |
|
761 Calls \a function, passing the parameters \a var1, \a var1, |
|
762 \a var2, \a var3, \a var4, \a var5, \a var6, \a var7 and \a var8 |
|
763 as arguments and returns the value returned by the function, or an |
|
764 invalid QVariant if the function does not return a value or when |
|
765 the function call failed. |
|
766 |
|
767 See QAxScriptManager::call() for more information about how to call |
|
768 script functions. |
|
769 */ |
|
770 QVariant QAxScript::call(const QString &function, const QVariant &var1, |
|
771 const QVariant &var2, |
|
772 const QVariant &var3, |
|
773 const QVariant &var4, |
|
774 const QVariant &var5, |
|
775 const QVariant &var6, |
|
776 const QVariant &var7, |
|
777 const QVariant &var8) |
|
778 { |
|
779 if (!script_engine) |
|
780 return QVariant(); |
|
781 |
|
782 return script_engine->dynamicCall(function.toLatin1(), var1, var2, var3, var4, var5, var6, var7, var8); |
|
783 } |
|
784 |
|
785 /*! |
|
786 \overload |
|
787 |
|
788 Calls \a function passing \a arguments as parameters, and returns |
|
789 the result. Returns when the script's execution has finished. |
|
790 |
|
791 See QAxScriptManager::call() for more information about how to call |
|
792 script functions. |
|
793 */ |
|
794 QVariant QAxScript::call(const QString &function, QList<QVariant> &arguments) |
|
795 { |
|
796 if (!script_engine) |
|
797 return QVariant(); |
|
798 |
|
799 return script_engine->dynamicCall(function.toLatin1(), arguments); |
|
800 } |
|
801 |
|
802 /*! \internal |
|
803 Registers all objects in the manager with the script engine. |
|
804 */ |
|
805 void QAxScript::updateObjects() |
|
806 { |
|
807 if (!script_manager) |
|
808 return; |
|
809 |
|
810 script_manager->updateScript(this); |
|
811 } |
|
812 |
|
813 /*! \internal |
|
814 Returns the object \a name registered with the manager. |
|
815 */ |
|
816 QAxBase *QAxScript::findObject(const QString &name) |
|
817 { |
|
818 if (!script_manager) |
|
819 return 0; |
|
820 |
|
821 return script_manager->d->objectDict.value(name); |
|
822 } |
|
823 |
|
824 /*! \fn QString QAxScript::scriptName() const |
|
825 Returns the name of the script. |
|
826 */ |
|
827 |
|
828 /*! \fn QString QAxScript::scriptCode() const |
|
829 Returns the script's code, or the null-string if no |
|
830 code has been loaded yet. |
|
831 |
|
832 \sa load() |
|
833 */ |
|
834 |
|
835 /*! \fn QAxScriptEngine* QAxScript::scriptEngine() const |
|
836 Returns a pointer to the script engine. |
|
837 |
|
838 You can use the object returned to connect signals to the |
|
839 script functions, or to access the script engine directly. |
|
840 */ |
|
841 |
|
842 /*! \fn void QAxScript::entered() |
|
843 |
|
844 This signal is emitted when a script engine has started executing code. |
|
845 */ |
|
846 |
|
847 /*! \fn void QAxScript::finished() |
|
848 |
|
849 This signal is emitted when a script engine has finished executing code. |
|
850 */ |
|
851 |
|
852 /*! |
|
853 \fn void QAxScript::finished(const QVariant &result) |
|
854 \overload |
|
855 |
|
856 \a result contains the script's result. This will be an invalid |
|
857 QVariant if the script has no return value. |
|
858 */ |
|
859 |
|
860 /*! \fn void QAxScript::finished(int code, const QString &source, |
|
861 const QString &description, const QString &help) |
|
862 \overload |
|
863 |
|
864 \a code, \a source, \a description and \a help contain exception information |
|
865 when the script terminated. |
|
866 */ |
|
867 |
|
868 /*! \fn void QAxScript::stateChanged(int state); |
|
869 |
|
870 This signal is emitted when a script engine changes state. |
|
871 \a state can be any value in the QAxScriptEngineState enumeration. |
|
872 */ |
|
873 |
|
874 /*! |
|
875 \fn void QAxScript::error(int code, const QString &description, |
|
876 int sourcePosition, const QString &sourceText) |
|
877 |
|
878 This signal is emitted when an execution error occurred while |
|
879 running a script. |
|
880 |
|
881 \a code, \a description, \a sourcePosition and \a sourceText |
|
882 contain information about the execution error. |
|
883 */ |
|
884 |
|
885 |
|
886 |
|
887 /*! |
|
888 \class QAxScriptManager |
|
889 \brief The QAxScriptManager class provides a bridge between application objects |
|
890 and script code. |
|
891 \inmodule QAxContainer |
|
892 |
|
893 The QAxScriptManager acts as a bridge between the COM objects embedded |
|
894 in the Qt application through QAxObject or QAxWidget, and the scripting |
|
895 languages available through the Windows Script technologies, usually JScript |
|
896 and VBScript. |
|
897 |
|
898 Create one QAxScriptManager for each separate document in your |
|
899 application, and add the COM objects the scripts need to access |
|
900 using addObject(). Then load() the script sources and invoke the |
|
901 functions using call(). |
|
902 |
|
903 \warning This class is not available with the bcc5.5 and MingW |
|
904 compilers. |
|
905 |
|
906 \sa QAxScript, QAxScriptEngine, QAxBase, {ActiveQt Framework} |
|
907 */ |
|
908 |
|
909 /*! |
|
910 Creates a QAxScriptManager object. \a parent is passed on to the |
|
911 QObject constructor. |
|
912 |
|
913 It is usual to create one QAxScriptManager for each document in an |
|
914 application. |
|
915 */ |
|
916 QAxScriptManager::QAxScriptManager(QObject *parent) |
|
917 : QObject(parent) |
|
918 { |
|
919 d = new QAxScriptManagerPrivate; |
|
920 } |
|
921 |
|
922 /*! |
|
923 Destroys the objects, releasing all allocated resources. |
|
924 */ |
|
925 QAxScriptManager::~QAxScriptManager() |
|
926 { |
|
927 delete d; |
|
928 } |
|
929 |
|
930 /*! |
|
931 Returns a list with all the functions that are available. |
|
932 Functions provided by script engines that don't support |
|
933 introspection are not included in the list. |
|
934 The functions are either provided with full prototypes or |
|
935 only as names, depending on the value of \a flags. |
|
936 */ |
|
937 QStringList QAxScriptManager::functions(QAxScript::FunctionFlags flags) const |
|
938 { |
|
939 QStringList functions; |
|
940 |
|
941 QHash<QString, QAxScript*>::ConstIterator scriptIt; |
|
942 for (scriptIt = d->scriptDict.begin(); scriptIt != d->scriptDict.end(); ++scriptIt) { |
|
943 QAxScript *script = scriptIt.value(); |
|
944 functions += script->functions(flags); |
|
945 } |
|
946 |
|
947 return functions; |
|
948 } |
|
949 |
|
950 /*! |
|
951 Returns a list with the names of all the scripts. |
|
952 */ |
|
953 QStringList QAxScriptManager::scriptNames() const |
|
954 { |
|
955 QStringList scripts; |
|
956 |
|
957 QHash<QString, QAxScript*>::ConstIterator scriptIt; |
|
958 for (scriptIt = d->scriptDict.begin(); scriptIt != d->scriptDict.end(); ++scriptIt) { |
|
959 scripts << scriptIt.key(); |
|
960 } |
|
961 |
|
962 return scripts; |
|
963 } |
|
964 |
|
965 /*! |
|
966 Returns the script called \a name. |
|
967 |
|
968 You can use the returned pointer to call functions directly |
|
969 through QAxScript::call(), to access the script engine directly, or |
|
970 to delete and thus unload the script. |
|
971 */ |
|
972 QAxScript *QAxScriptManager::script(const QString &name) const |
|
973 { |
|
974 return d->scriptDict.value(name); |
|
975 } |
|
976 |
|
977 /*! |
|
978 Adds \a object to the manager. Scripts handled by this manager |
|
979 can access the object in the code using the object's |
|
980 \l{QObject::objectName}{objectName} property. |
|
981 |
|
982 You must add all the necessary objects before loading any scripts. |
|
983 */ |
|
984 void QAxScriptManager::addObject(QAxBase *object) |
|
985 { |
|
986 QObject *obj = object->qObject(); |
|
987 QString name = obj->objectName(); |
|
988 if (d->objectDict.contains(name)) |
|
989 return; |
|
990 |
|
991 d->objectDict.insert(name, object); |
|
992 connect(obj, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(QObject*))); |
|
993 } |
|
994 |
|
995 /*! \fn void QAxScriptManager::addObject(QObject *object) |
|
996 \overload |
|
997 |
|
998 Adds a generic COM wrapper for \a object to the manager. \a object |
|
999 must be exposed as a COM object using the functionality provided |
|
1000 by the QAxServer module. Applications |
|
1001 using this function you must link against the qaxserver library. |
|
1002 */ |
|
1003 |
|
1004 /*! |
|
1005 Loads the script source \a code using the script engine for \a |
|
1006 language. The script can later be referred to using its \a name |
|
1007 which should not be empty. |
|
1008 |
|
1009 The function returns a pointer to the script for the given |
|
1010 \a code if the \a code was loaded successfully; otherwise it |
|
1011 returns 0. |
|
1012 |
|
1013 If \a language is empty it will be determined heuristically. If \a |
|
1014 code contains the string "End Sub" it will be interpreted as |
|
1015 VBScript, otherwise as JScript. Additional script engines can be |
|
1016 registered using registerEngine(). |
|
1017 |
|
1018 You must add all the objects necessary (using addObject()) \e |
|
1019 before loading any scripts. If \a code declares a function that is |
|
1020 already available (no matter in which language) the first function |
|
1021 is overloaded and can no longer be called via call(); but it will |
|
1022 still be available by calling its \link script() script \endlink |
|
1023 directly. |
|
1024 |
|
1025 \sa addObject(), scriptNames(), functions() |
|
1026 */ |
|
1027 QAxScript *QAxScriptManager::load(const QString &code, const QString &name, const QString &language) |
|
1028 { |
|
1029 QAxScript *script = new QAxScript(name, this); |
|
1030 if (script->load(code, language)) |
|
1031 return script; |
|
1032 |
|
1033 delete script; |
|
1034 return 0; |
|
1035 } |
|
1036 |
|
1037 /*! |
|
1038 \overload |
|
1039 |
|
1040 Loads the source code from the \a file. The script can later be |
|
1041 referred to using its \a name which should not be empty. |
|
1042 |
|
1043 The function returns a pointer to the script engine for the code |
|
1044 in \a file if \a file was loaded successfully; otherwise it |
|
1045 returns 0. |
|
1046 |
|
1047 The script engine used is determined from the file's extension. By |
|
1048 default ".js" files are interpreted as JScript files, and ".vbs" |
|
1049 and ".dsm" files are interpreted as VBScript. Additional script |
|
1050 engines can be registered using registerEngine(). |
|
1051 */ |
|
1052 QAxScript *QAxScriptManager::load(const QString &file, const QString &name) |
|
1053 { |
|
1054 QFile f(file); |
|
1055 if (!f.open(QIODevice::ReadOnly)) |
|
1056 return 0; |
|
1057 QByteArray data = f.readAll(); |
|
1058 QString contents = QString::fromLocal8Bit(data, data.size()); |
|
1059 f.close(); |
|
1060 |
|
1061 if (contents.isEmpty()) |
|
1062 return 0; |
|
1063 |
|
1064 QString language; |
|
1065 if (file.endsWith(QLatin1String(".js"))) { |
|
1066 language = QLatin1String("JScript"); |
|
1067 } else { |
|
1068 QList<QAxEngineDescriptor>::ConstIterator it; |
|
1069 for (it = engines.begin(); it != engines.end(); ++it) { |
|
1070 QAxEngineDescriptor engine = *it; |
|
1071 if (engine.extension.isEmpty()) |
|
1072 continue; |
|
1073 |
|
1074 if (file.endsWith(engine.extension)) { |
|
1075 language = engine.name; |
|
1076 break; |
|
1077 } |
|
1078 } |
|
1079 } |
|
1080 |
|
1081 if (language.isEmpty()) |
|
1082 language = QLatin1String("VBScript"); |
|
1083 |
|
1084 QAxScript *script = new QAxScript(name, this); |
|
1085 if (script->load(contents, language)) |
|
1086 return script; |
|
1087 |
|
1088 delete script; |
|
1089 return 0; |
|
1090 } |
|
1091 |
|
1092 /*! |
|
1093 Calls \a function, passing the parameters \a var1, \a var1, |
|
1094 \a var2, \a var3, \a var4, \a var5, \a var6, \a var7 and \a var8 |
|
1095 as arguments and returns the value returned by the function, or an |
|
1096 invalid QVariant if the function does not return a value or when |
|
1097 the function call failed. The call returns when the script's |
|
1098 execution has finished. |
|
1099 |
|
1100 In most script engines the only supported parameter type is "const |
|
1101 QVariant&", for example, to call a JavaScript function |
|
1102 \snippet doc/src/snippets/code/src_activeqt_container_qaxscript.cpp 0 |
|
1103 use |
|
1104 \snippet doc/src/snippets/code/src_activeqt_container_qaxscript.cpp 1 |
|
1105 As with \link QAxBase::dynamicCall() dynamicCall \endlink the |
|
1106 parameters can directly be embedded in the function string. |
|
1107 \snippet doc/src/snippets/code/src_activeqt_container_qaxscript.cpp 2 |
|
1108 However, this is slower. |
|
1109 |
|
1110 Functions provided by script engines that don't support |
|
1111 introspection are not available and must be called directly |
|
1112 using QAxScript::call() on the respective \link script() |
|
1113 script \endlink object. |
|
1114 |
|
1115 Note that calling this function can be significantely slower than |
|
1116 using call() on the respective QAxScript directly. |
|
1117 */ |
|
1118 QVariant QAxScriptManager::call(const QString &function, const QVariant &var1, |
|
1119 const QVariant &var2, |
|
1120 const QVariant &var3, |
|
1121 const QVariant &var4, |
|
1122 const QVariant &var5, |
|
1123 const QVariant &var6, |
|
1124 const QVariant &var7, |
|
1125 const QVariant &var8) |
|
1126 { |
|
1127 QAxScript *s = script(function); |
|
1128 if (!s) { |
|
1129 #ifdef QT_CHECK_STATE |
|
1130 qWarning("QAxScriptManager::call: No script provides function %s, or this function\n" |
|
1131 "\tis provided through an engine that does not support introspection", function.latin1()); |
|
1132 #endif |
|
1133 return QVariant(); |
|
1134 } |
|
1135 |
|
1136 return s->call(function, var1, var2, var3, var4, var5, var6, var7, var8); |
|
1137 } |
|
1138 |
|
1139 /*! \overload |
|
1140 |
|
1141 Calls \a function passing \a arguments as parameters, and returns |
|
1142 the result. Returns when the script's execution has finished. |
|
1143 */ |
|
1144 QVariant QAxScriptManager::call(const QString &function, QList<QVariant> &arguments) |
|
1145 { |
|
1146 QAxScript *s = script(function); |
|
1147 if (!s) { |
|
1148 #ifdef QT_CHECK_STATE |
|
1149 qWarning("QAxScriptManager::call: No script provides function %s, or this function\n" |
|
1150 "\tis provided through an engine that does not support introspection", function.latin1()); |
|
1151 #endif |
|
1152 return QVariant(); |
|
1153 } |
|
1154 |
|
1155 QList<QVariant> args(arguments); |
|
1156 return s->call(function, args); |
|
1157 } |
|
1158 |
|
1159 /*! |
|
1160 Registers the script engine called \a name and returns true if the |
|
1161 engine was found; otherwise does nothing and returns false. |
|
1162 |
|
1163 The script engine will be used when loading files with the given |
|
1164 \a extension, or when loading source code that contains the string |
|
1165 \a code. |
|
1166 */ |
|
1167 bool QAxScriptManager::registerEngine(const QString &name, const QString &extension, const QString &code) |
|
1168 { |
|
1169 if (name.isEmpty()) |
|
1170 return false; |
|
1171 |
|
1172 CLSID clsid; |
|
1173 HRESULT hres = CLSIDFromProgID((wchar_t*)name.utf16(), &clsid); |
|
1174 if (hres != S_OK) |
|
1175 return false; |
|
1176 |
|
1177 QAxEngineDescriptor engine; |
|
1178 engine.name = name; |
|
1179 engine.extension = extension; |
|
1180 engine.code = code; |
|
1181 |
|
1182 engines.prepend(engine); |
|
1183 return true; |
|
1184 } |
|
1185 |
|
1186 /*! |
|
1187 Returns a file filter listing all the supported script languages. |
|
1188 This filter string is convenient for use with QFileDialog. |
|
1189 */ |
|
1190 QString QAxScriptManager::scriptFileFilter() |
|
1191 { |
|
1192 QString allFiles = QLatin1String("Script Files (*.js *.vbs *.dsm"); |
|
1193 QString specialFiles = QLatin1String(";;VBScript Files (*.vbs *.dsm)" |
|
1194 ";;JavaScript Files (*.js)"); |
|
1195 |
|
1196 QList<QAxEngineDescriptor>::ConstIterator it; |
|
1197 for (it = engines.begin(); it != engines.end(); ++it) { |
|
1198 QAxEngineDescriptor engine = *it; |
|
1199 if (engine.extension.isEmpty()) |
|
1200 continue; |
|
1201 |
|
1202 allFiles += QLatin1String(" *") + engine.extension; |
|
1203 specialFiles += QLatin1String(";;") + engine.name + QLatin1String(" Files (*") + engine.extension + QLatin1Char(')'); |
|
1204 } |
|
1205 allFiles += QLatin1Char(')'); |
|
1206 |
|
1207 return allFiles + specialFiles + QLatin1String(";;All Files (*.*)"); |
|
1208 } |
|
1209 |
|
1210 /*! |
|
1211 \fn void QAxScriptManager::error(QAxScript *script, int code, const QString &description, |
|
1212 int sourcePosition, const QString &sourceText) |
|
1213 |
|
1214 This signal is emitted when an execution error occurred while |
|
1215 running \a script. |
|
1216 |
|
1217 \a code, \a description, \a sourcePosition and \a sourceText |
|
1218 contain information about the execution error. |
|
1219 |
|
1220 \warning Do not delete \a script in a slot connected to this signal. Use deleteLater() |
|
1221 instead. |
|
1222 */ |
|
1223 |
|
1224 /*! |
|
1225 \internal |
|
1226 |
|
1227 Returns a pointer to the first QAxScript that knows |
|
1228 about \a function, or 0 if this function is unknown. |
|
1229 */ |
|
1230 QAxScript *QAxScriptManager::scriptForFunction(const QString &function) const |
|
1231 { |
|
1232 // check full prototypes if included |
|
1233 if (function.contains(QLatin1Char('('))) { |
|
1234 QHash<QString, QAxScript*>::ConstIterator scriptIt; |
|
1235 for (scriptIt = d->scriptDict.begin(); scriptIt != d->scriptDict.end(); ++scriptIt) { |
|
1236 QAxScript *script = scriptIt.value(); |
|
1237 |
|
1238 if (script->functions(QAxScript::FunctionSignatures).contains(function)) |
|
1239 return script; |
|
1240 } |
|
1241 } |
|
1242 |
|
1243 QString funcName = function; |
|
1244 funcName = funcName.left(funcName.indexOf(QLatin1Char('('))); |
|
1245 // second try, checking only names, not prototypes |
|
1246 QHash<QString, QAxScript*>::ConstIterator scriptIt; |
|
1247 for (scriptIt = d->scriptDict.begin(); scriptIt != d->scriptDict.end(); ++scriptIt) { |
|
1248 QAxScript *script = scriptIt.value(); |
|
1249 |
|
1250 if (script->functions(QAxScript::FunctionNames).contains(funcName)) |
|
1251 return script; |
|
1252 } |
|
1253 |
|
1254 return 0; |
|
1255 } |
|
1256 |
|
1257 /*! |
|
1258 \internal |
|
1259 */ |
|
1260 void QAxScriptManager::updateScript(QAxScript *script) |
|
1261 { |
|
1262 QHash<QString, QAxBase*>::ConstIterator objectIt; |
|
1263 for (objectIt = d->objectDict.constBegin(); objectIt != d->objectDict.constEnd(); ++objectIt) { |
|
1264 QString name = objectIt.key(); |
|
1265 |
|
1266 QAxScriptEngine *engine = script->scriptEngine(); |
|
1267 if (engine) |
|
1268 engine->addItem(name); |
|
1269 } |
|
1270 } |
|
1271 |
|
1272 /*! |
|
1273 \internal |
|
1274 */ |
|
1275 void QAxScriptManager::objectDestroyed(QObject *o) |
|
1276 { |
|
1277 d->objectDict.take(o->objectName()); |
|
1278 } |
|
1279 |
|
1280 /*! |
|
1281 \internal |
|
1282 */ |
|
1283 void QAxScriptManager::scriptError(int code, const QString &desc, int spos, const QString &stext) |
|
1284 { |
|
1285 QAxScript *source = qobject_cast<QAxScript*>(sender()); |
|
1286 emit error(source, code, desc, spos, stext); |
|
1287 } |
|
1288 |
|
1289 QT_END_NAMESPACE |
|
1290 #endif // QT_NO_WIN_ACTIVEQT |