src/activeqt/container/qaxscript.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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