From 151c319a9a67ae420136fb23cc987d23059737f6 Mon Sep 17 00:00:00 2001 From: zecke Date: Wed, 27 Aug 2003 08:01:57 +0000 Subject: Did I say I love C++ templates. MetaProgramming is fun Here is my template based on Lokis and Simons work to quicklaunch applications --- diff --git a/libopie/oapplicationfactory.h b/libopie/oapplicationfactory.h new file mode 100644 index 0000000..418a82e --- a/dev/null +++ b/libopie/oapplicationfactory.h @@ -0,0 +1,262 @@ +/* + This work is derived from: + ---- + The Loki Library + Copyright (c) 2001 by Andrei Alexandrescu + This code accompanies the book: + Alexandrescu, Andrei. "Modern C++ Design: Generic Programming and Design + Patterns Applied". Copyright (c) 2001. Addison-Wesley. + Permission to use, copy, modify, distribute and sell this software for any + purpose is hereby granted without fee, provided that the above copyright + notice appear in all copies and that both that copyright notice and this + permission notice appear in supporting documentation. + The author or Addison-Welsey Longman make no representations about the + suitability of this software for any purpose. It is provided "as is" + without express or implied warranty. + ---- + + And KGenericFactor et all from Simon Hausmann + +*/ + +#include +#include + +#include +#include + +namespace Opie { + struct NullType; + + template + struct Typelist + { + typedef T Head; + typedef U Tail; + }; + template< + typename T1 = NullType, typename T2 = NullType, typename T3 = NullType, + typename T4 = NullType, typename T5 = NullType, typename T6 = NullType, + typename T7 = NullType, typename T8 = NullType, typename T9 = NullType, + typename T10 = NullType, typename T11 = NullType, typename T12 = NullType, + typename T13 = NullType, typename T14 = NullType, typename T15 = NullType, + typename T16 = NullType, typename T17 = NullType, typename T18 = NullType + > + struct MakeTypelist{ + private: + typedef typename MakeTypelist + < + T2 , T3 , T4 , + T5 , T6 , T7 , + T8 , T9 , T10, + T11, T12, T13, + T14, T15, T16, + T17, T18 + > + ::Result TailResult; + +public: + typedef Typelist Result; +}; + +template<> +struct MakeTypelist<> +{ + typedef NullType Result; +}; + +} + +/** + * To allow your application to be quick launched some one needs + * to create the QWidget. + * This is this factory. Make surce your widget has static QString Widget::appName() + * as one of its functions. + * + * This template takes one QWidget and initialized it in the form of + * MyWidget::MyWidget( QWidget* parent, const char* name, WFlags f ); + * + * To use it on your app do that: + * typedef OApplicationFactory MyFactory; + * OPIE_EXPORT_APP( MyFactory ) + * + */ +template +struct OApplicationFactory : public ApplicationInterface { + QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) { + *iface = 0; + if ( uuid == IID_QUnknown ) *iface = this; + else if ( uuid == IID_QtopiaApplication ) *iface = this; + else return QS_FALSE; + (*iface)->addRef(); + return QS_OK; + } + + /* + * + */ + virtual QWidget *createMainWindow( const QString& appName, QWidget* parent, + const char* name, Qt::WFlags f ) { + if (appName == Product::appName() ) + return new Product(parent, name, f ); + else + return 0l; + } + + virtual QStringList applications()const { + QStringList list; + list << Product::appName() ; + + return list; + } + Q_REFCOUNT + +}; + + +/* Internal */ + +template< class Product > +struct OPrivate { + inline static QWidget *multiFactory( const QString& appName, QWidget* parent, + const char* name, Qt::WFlags fl ) { + if ( appName == Product::appName() ) + return new Product( parent, name, fl ); + else + return 0; + } + + inline static QStringList multiString( const QStringList& _list ) { + QStringList list = _list; + list << Product::appName(); + return list; + } +}; + +template <> +struct OPrivate { + inline static QWidget* multiFactory ( const QString& , QWidget* , + const char* , Qt::WFlags ) { + return 0l; + } + inline static QStringList multiString( const QStringList& _list ) { + return _list; + } +}; + +/* +template <> +struct OPrivate { + inline static QWidget* multiFactory( const QString& , QWidget* , + const char* , Qt::WFlags ) { + return 0l; + } + + inline static QStringList multiString( const QStringList& _list ) { + return _list; + } +}; +*/ + +template +struct OPrivate< Opie::Typelist > { + inline static QWidget* multiFactory( const QString& appName, QWidget* parent, + const char* name, Qt::WFlags fl) { + QWidget* wid = OPrivate::multiFactory( appName, parent, name, fl ); + + if (!wid ) + wid = OPrivate::multiFactory( appName, parent, name, fl ); + + return wid; + } + + inline static QStringList multiString( const QStringList& _list ) { + QStringList list = _list; + + list = OPrivate::multiString( list ); + list = OPrivate::multiString( list ); + + return list; + } +}; + + + + + + + + +/* Internal END */ + +/* + * If you want to export more than one Widget use that function + * Make sure all your Widgets provide the appName() static method + * otherwise you'll get a compiler error + * + * typedef Opie::MakeTypeList::Result MyTypes; + * OPIE_EXPORT_APP( OApplicationFactory ) + */ + +template +struct OApplicationFactory< Opie::Typelist > + : ApplicationInterface { + QRESULT queryInterface( const QUuid &uuid, QUnknownInterface **iface ) { + *iface = 0; + if ( uuid == IID_QUnknown ) *iface = this; + else if ( uuid ==IID_QtopiaApplication ) *iface = this; + else return QS_FALSE; + (*iface)->addRef(); + return QS_OK; + } + + QWidget* createMainWindow ( const QString& appName, QWidget* parent, + const char* name, Qt::WFlags fl ) { + qWarning("StringList is %s", applications().join(":").latin1() ); + return OPrivate< Opie::Typelist >::multiFactory( appName, parent, name, fl ); + } + + QStringList applications()const { + QStringList _list; + return OPrivate< Opie::Typelist >::multiString( _list ); + } + + Q_REFCOUNT +}; + + +/* If the library version should be build */ +#ifdef OPIE_APP_INTERFACE +#define OPIE_EXPORT_APP( factory ) Q_EXPORT_INTERFACE() { Q_CREATE_INSTANCE( factory ) } +#else + +#define OPIE_EXPORT_APP( Factory ) \ +int main( int argc, char **argv ) { \ + QPEApplication a(argc, argv ); \ + QWidget *mw = 0;\ +\ + /* method from TT */ \ + QString executableName = QString::fromLatin1( argv[0] ); \ + executableName = executableName.right(executableName.length() \ + - executableName.findRev('/') - 1); \ + \ + Factory f; \ + QStringList list = f.applications(); \ + if (list.contains(executableName) ) \ + mw = f.createMainWindow(executableName, 0, 0, 0 ); \ + else \ + mw = f.createMainWindow( list[0], 0, 0, 0 ); \ +\ + if( mw ) { \ + if ( mw->metaObject()->slotNames().contains("setDocument(const QString&)" ) ) \ + a.showMainDocumentWidget( mw ); \ + else \ + a.showMainWidget( mw ); \ +\ + int rv = a.exec(); \ + delete mw; \ + return rv; \ + }else \ + return -1; \ +} +#endif diff --git a/library/applicationinterface.h b/library/applicationinterface.h new file mode 100644 index 0000000..b37a2c5 --- a/dev/null +++ b/library/applicationinterface.h @@ -0,0 +1,32 @@ +/* + * GPLv2 (C) 2002-2003 Trolltech + * (C) 2003 zecke@handhelds.org + */ + + +#ifndef APPLICATIONINTERFACE_H +#define APPLICATIONINTERFACE_H + +#include +#include + +#ifndef QT_NO_COMPONENT +// {07E15B48-B947-4334-B866-D2AD58157D8C} +#ifndef IID_QtopiaApplication +#define IID_QtopiaApplication QUuid( 0x07e15b48, 0xb947, 0x4334, 0xb8, 0x66, 0xd2, 0xad, 0x58, 0x15, 0x7d, 0x8c) +#endif +#endif + +struct ApplicationInterface : public QUnknownInterface +{ +public: + virtual QWidget *createMainWindow( const QString &appName, QWidget *parent=0, + const char *name=0, Qt::WFlags f=0 ) = 0; + virtual QStringList applications() const = 0; +}; + +/* + * Use an extended interface for QObejct, Opie::Part in the future + */ + +#endif -- cgit v0.9.0.2