Main Page | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

qcomponentfactory.cpp

Go to the documentation of this file.
00001 /****************************************************************************
00002 ** $Id: qcomponentfactory.cpp,v 1.2 2003/07/10 02:40:11 llornkcor Exp $
00003 **
00004 ** Implementation of the QComponentFactory class
00005 **
00006 ** Created : 990101
00007 **
00008 ** Copyright (C) 1992-2002 Trolltech AS.  All rights reserved.
00009 **
00010 ** This file is part of the tools module of the Qt GUI Toolkit.
00011 **
00012 ** This file may be distributed under the terms of the Q Public License
00013 ** as defined by Trolltech AS of Norway and appearing in the file
00014 ** LICENSE.QPL included in the packaging of this file.
00015 **
00016 ** This file may be distributed and/or modified under the terms of the
00017 ** GNU General Public License version 2 as published by the Free Software
00018 ** Foundation and appearing in the file LICENSE.GPL included in the
00019 ** packaging of this file.
00020 **
00021 ** Licensees holding valid Qt Enterprise Edition or Qt Professional Edition
00022 ** licenses may use this file in accordance with the Qt Commercial License
00023 ** Agreement provided with the Software.
00024 **
00025 ** This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
00026 ** WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
00027 **
00028 ** See http://www.trolltech.com/pricing.html or email sales@trolltech.com for
00029 **   information about Qt Commercial License Agreements.
00030 ** See http://www.trolltech.com/qpl/ for QPL licensing information.
00031 ** See http://www.trolltech.com/gpl/ for GPL licensing information.
00032 **
00033 ** Contact info@trolltech.com if any conditions of this licensing are
00034 ** not clear to you.
00035 **
00036 **********************************************************************/
00037 
00038 #include "qcomponentfactory_p.h"
00039 
00040 #ifndef QT_NO_COMPONENT
00041 #include "qsettings.h"
00042 #include <private/qcomlibrary_p.h>
00043 #include "qdir.h"
00044 #include "qapplication.h"
00045 
00103 static QPtrList<QComLibrary> *libraries = 0;
00104 
00105 static void cleanup()
00106 {
00107     delete libraries;
00108     libraries = 0;
00109 }
00110 
00111 static QPtrList<QComLibrary> *liblist()
00112 {
00113     if ( !libraries ) {
00114         libraries = new QPtrList<QComLibrary>();
00115         libraries->setAutoDelete( TRUE );
00116         qAddPostRoutine( cleanup );
00117     }
00118     return libraries;
00119 }
00120 
00146 QRESULT QComponentFactory::createInstance( const QString &cid, const QUuid &iid, QUnknownInterface** iface, QUnknownInterface *outer )
00147 {
00148     QSettings settings;
00149     settings.insertSearchPath( QSettings::Windows, "/Classes" );
00150     bool ok = FALSE;
00151     QString cidStr = cid;
00152     QRESULT res = QE_NOCOMPONENT;
00153 
00154     QUuid uuid( cidStr ); // try to parse, and resolve CLSID if necessary
00155     if ( uuid.isNull() ) {
00156         uuid = settings.readEntry( "/" + cid + "/CLSID/Default", QString::null, &ok );
00157         cidStr = uuid.toString().upper();
00158     }
00159 
00160     if ( cidStr.isEmpty() )
00161         return res;
00162 
00163     QString file = settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", QString::null, &ok );
00164     if ( !ok )
00165         return res;
00166 
00167     QComLibrary *library = new QComLibrary( file );
00168     library->setAutoUnload( FALSE );
00169 
00170     QComponentFactoryInterface *cfIface =0;
00171     library->queryInterface( IID_QComponentFactory, (QUnknownInterface**)&cfIface );
00172 
00173     if ( cfIface ) {
00174         res = cfIface->createInstance( uuid, iid, iface, outer );
00175         cfIface->release();
00176     } else {
00177         res = library->queryInterface( iid, iface );
00178     }
00179     QLibraryInterface *libiface = 0;
00180     if ( library->queryInterface( IID_QLibrary, (QUnknownInterface**)&libiface ) != QS_OK || !qApp ) {
00181         delete library; // only deletes the object, thanks to QLibrary::Manual
00182     } else {
00183         libiface->release();
00184         library->setAutoUnload( TRUE );
00185         liblist()->prepend( library );
00186     }
00187     return res;
00188 }
00189 
00199 QRESULT QComponentFactory::registerServer( const QString &filename )
00200 {
00201     QComLibrary lib( filename );
00202     lib.load();
00203     QComponentRegistrationInterface *iface = 0;
00204     QRESULT res = lib.queryInterface( IID_QComponentRegistration, (QUnknownInterface**)&iface );
00205     if ( res != QS_OK )
00206         return res;
00207     QDir dir( filename );
00208     bool ok = iface->registerComponents( dir.absPath() );
00209     iface->release();
00210     return ok ? QS_OK : QS_FALSE;
00211 }
00212 
00222 QRESULT QComponentFactory::unregisterServer( const QString &filename )
00223 {
00224     QComLibrary lib( filename );
00225     lib.load();
00226     QComponentRegistrationInterface *iface = 0;
00227     QRESULT res = lib.queryInterface( IID_QComponentRegistration, (QUnknownInterface**)&iface );
00228     if ( res != QS_OK )
00229         return res;
00230     bool ok = iface->unregisterComponents();
00231     iface->release();
00232     return ok ? QS_OK : QS_FALSE;
00233 }
00234 
00252 bool QComponentFactory::registerComponent( const QUuid &cid, const QString &filepath, const QString &name, int version, const QString &description )
00253 {
00254     bool ok = FALSE;
00255     QSettings settings;
00256     settings.insertSearchPath( QSettings::Windows, "/Classes" );
00257 
00258     QString cidStr = cid.toString().upper();
00259     settings.readEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", QString::null, &ok );
00260     if ( ok ) // don't overwrite existing component
00261         return FALSE;
00262 
00263     ok = settings.writeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default", filepath );
00264     if ( ok && !!description )
00265         settings.writeEntry( "/CLSID/" + cidStr + "/Default", description );
00266 
00267     // register the human readable part
00268     if ( ok && !!name ) {
00269         QString vName = version ? name + "." + QString::number( version ) : name;
00270         settings.writeEntry( "/CLSID/" + cidStr + "/ProgID/Default", vName );
00271         ok = settings.writeEntry( "/" + vName + "/CLSID/Default", cidStr );
00272         if ( ok && !!description )
00273             settings.writeEntry( "/" + vName + "/Default", description );
00274 
00275         if ( ok && version ) {
00276             settings.writeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", name );
00277             QString curVer = settings.readEntry( "/" + name + "/CurVer/Default" );
00278             if ( !curVer || curVer < vName ) { // no previous, or a lesser version installed
00279                 settings.writeEntry( "/" + name + "/CurVer/Default", vName );
00280                 ok = settings.writeEntry( "/" + name + "/CLSID/Default", cidStr );
00281                 if ( ok && !!description )
00282                     settings.writeEntry( "/" + name + "/Default", description );
00283             }
00284         }
00285     }
00286 
00287     return ok;
00288 }
00289 
00299 bool QComponentFactory::unregisterComponent( const QUuid &cid )
00300 {
00301     QSettings settings;
00302     bool ok = FALSE;
00303     settings.insertSearchPath( QSettings::Windows, "/Classes" );
00304 
00305     QString cidStr = cid.toString().upper();
00306     if ( cidStr.isEmpty() )
00307         return FALSE;
00308 
00309     // unregister the human readable part
00310     QString vName = settings.readEntry( "/CLSID/" + cidStr + "/ProgID/Default", QString::null, &ok );
00311     if ( ok ) {
00312         QString name = settings.readEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default", QString::null );
00313         if ( !!name && settings.readEntry( "/" + name + "/CurVer/Default" ) == vName ) {
00314             // unregistering the current version -> change CurVer to previous version
00315             QString version = vName.right( vName.length() - name.length() - 1 );
00316             QString newVerName;
00317             QString newCidStr;
00318             if ( version.find( '.' ) == -1 ) {
00319                 int ver = version.toInt();
00320                 // see if a lesser version is installed, and make that the CurVer
00321                 while ( ver-- ) {
00322                     newVerName = name + "." + QString::number( ver );
00323                     newCidStr = settings.readEntry( "/" + newVerName + "/CLSID/Default" );
00324                     if ( !!newCidStr )
00325                         break;
00326                 }
00327             } else {
00328                 // oh well...
00329             }
00330             if ( !!newCidStr ) {
00331                 settings.writeEntry( "/" + name + "/CurVer/Default", newVerName );
00332                 settings.writeEntry( "/" + name + "/CLSID/Default", newCidStr );
00333             } else {
00334                 settings.removeEntry( "/" + name + "/CurVer/Default" );
00335                 settings.removeEntry( "/" + name + "/CLSID/Default" );
00336                 settings.removeEntry( "/" + name + "/Default" );
00337             }
00338         }
00339 
00340         settings.removeEntry( "/" + vName + "/CLSID/Default" );
00341         settings.removeEntry( "/" + vName + "/Default" );
00342     }
00343 
00344     settings.removeEntry( "/CLSID/" + cidStr + "/VersionIndependentProgID/Default" );
00345     settings.removeEntry( "/CLSID/" + cidStr + "/ProgID/Default" );
00346     settings.removeEntry( "/CLSID/" + cidStr + "/InprocServer32/Default" );
00347     ok = settings.removeEntry( "/CLSID/" + cidStr + "/Default" );
00348 
00349     return ok;
00350 }
00351 
00352 #endif // QT_NO_COMPONENT

Generated on Sat Nov 5 16:18:29 2005 for OPIE by  doxygen 1.4.2