src/hbutils/document/hbdocumentloader.cpp
changeset 34 ed14f46c0e55
parent 7 923ff622b8b9
equal deleted inserted replaced
31:7516d6d86cf5 34:ed14f46c0e55
    34 
    34 
    35 /*!
    35 /*!
    36     @stable
    36     @stable
    37     @hbutils
    37     @hbutils
    38     \class HbDocumentLoader
    38     \class HbDocumentLoader
    39     \brief HbDocumentLoader allows applications to construct widget hierarchies from DocML files.
    39     \brief The HbDocumentLoader class loads UI definitions from DocML files and constructs a hierarchy of widgets in memory.
    40     
    40     
    41     You can load a document using \c HbDocumentLoader::load method. Afther that you can access to
    41     HbDocumentLoader loads and parses UI definitions from DocML files.
    42     loaded objects by processing returned objects roots tree, or by using \c findObject / \c findWidget
    42     A DocML file usually contains a UI definition of a view or a dialog, and defines layouts, widgets and actions.
    43     methods (\c HbDocumentLoader always keeps references to loaded objects)
    43     Using HbDocumentLoader you can load an entire UI screen by calling the load() method, which returns an object list to the caller.
    44      
    44     The object list contains the root objects defined at the top level of the DocML file (child elements of <hbdocument>). Each root object
    45     \c HbDocumentLoader uses \c HbDocumentLoader::createObject method to retrieve objects. By default, 
    45     may have child objects, so a hierarchy of objects is returned to the caller. Object ownership is passed to the caller.
    46     this method creates always new instances based on class name. In addition to basic \c QObject 
    46     
    47     classes provided by Qt, only public widgets of Hb library are supported. Thus, in order to be 
    47     An HbDocumentLoader object keeps references to the loaded objects until the reset() method is called, but it is up to your code
    48     able to create your own custom widgets, you have to derive from this class and override 
    48     to manage the lifecycle of the returned objects. For widgets this is often easy, since they have either a containing view or a
    49     \c createObject method.
    49     layout as a parent: Qt's object cleanup policy means that child objects are automatically deleted. 
    50 
    50     You must be careful to manage the lifecycle of any root objects returned by load() that are not owned by another object,
    51     See \c HbDocumentLoader::createBinary for information about DocML binary conversion
    51     such as HbAction objects that do not have a menu or toolbar role.  
    52     in build time.
    52             
    53 
    53     A DocML file contains only a UI definition. To connect your UI objects in code you must get pointers to them.
    54     Use the \c HbDocumentLoaderPlugin to add tool support for custom widgets.
    54     Use the findObject() and findWidget() methods to get pointers to your UI objects, which you can then connect using their signals and slots. 
    55     
    55          
    56     Example code:
    56     HbDocumentLoader uses the createObject() method to create objects. By default, this method always creates new object instances
    57     \snippet{documentloadersample.cpp,1}
    57     based on the class name in the DocML. This method can create the public widgets of the Hb library and some basic objects that derive
    58 
    58     from QObject, such as HbAction. 
    59     For more information about DocML syntax, please refer to S60QtProgrammersGuide.
    59     In order to be able to load your own classes of objects from DocML, for example to load your own custom widgets, you can either:
    60 */
    60     - create your own custom loader by subclassing from HbDocumentLoader and overriding the createObject() method.
    61 
    61     - create an  HbDocumentLoaderPlugin object in a separate library.
    62 /*!
    62       
    63     Constructor. 
    63     HbDocumentLoader can load DocML in either text-based or binary format. Using a binary format reduces the time to load and parse a DocML file.
       
    64     You can create binary DocML files by specifying your DocML files in your project file. To declare a DocML file for conversion to binary format, add the following to the project file:
       
    65     \code
       
    66     DOCML += hello_docml_world.docml
       
    67     \endcode
       
    68     When the build process runs, files with the suffix docml.bin are created. You create entries in the resource file to load the binary DocML.
       
    69     The following shows a binary DocML file declared in the resource file. The binary file is given an alias ending in .docml which is used to reference it in code.
       
    70     \code
       
    71     <RCC>
       
    72     <qresource prefix="/docml">
       
    73         <file alias="hello_docml_world.docml">hello_docml_world.docml.bin</file>
       
    74     </qresource>
       
    75     </RCC>
       
    76     \endcode
       
    77     
       
    78     \section _usecases_hbdocumentloader Using the HbDocumentLoader class.
       
    79     
       
    80     \subsection _uc_001_hbdocumentloader Loading a simple DocML file containing a view definition.
       
    81         
       
    82     \code
       
    83     int main(int argc, char *argv[])
       
    84     {
       
    85         HbApplication app(argc, argv);
       
    86         HbMainWindow window;
       
    87 
       
    88         // Create a document loader object.
       
    89         HbDocumentLoader loader;
       
    90         bool ok = false;
       
    91 
       
    92         // Load the DocML file.
       
    93         loader.load(":/docml/hello_docml_world.docml", &ok);
       
    94 
       
    95         if (ok) {
       
    96             // Get the view and add it to the main window.
       
    97             HbView* view = qobject_cast<HbView*>(loader.findWidget("view"));
       
    98             window.addView(view);
       
    99         } 
       
   100         else {
       
   101             qFatal("Unable to read :/docml/hello_docml_world.docml");
       
   102         }
       
   103 
       
   104         window.show();
       
   105         return app.exec();
       
   106     }
       
   107     \endcode
       
   108     
       
   109     \subsection _uc_002_hbdocumentloader Getting pointers to loaded objects and taking ownership.
       
   110     Call findObject() and findWidget() to get pointers to and take ownership of loaded objects
       
   111 
       
   112     \code
       
   113     const QString LIST_VIEW = ":/resources/ui/listview.docml";
       
   114     
       
   115     HbDocumentLoader* loader;
       
   116     loader = new HbDocumentLoader();
       
   117 
       
   118     HbView* listView; 
       
   119     HbListView* notesList;
       
   120     HbAction* newNoteAction;
       
   121     HbAction* deleteNoteAction;
       
   122     
       
   123     // Load the DocML which defines the notes list view
       
   124     bool loaded = false;
       
   125     loader->reset();
       
   126     loader->load(LIST_VIEW, &loaded);
       
   127     Q_ASSERT_X(loaded, "Notes::load", "Unable to load view from DocML");
       
   128     if ( loaded ) {
       
   129 
       
   130         QGraphicsWidget *widget = loader->findWidget(QString("view"));
       
   131         if (widget) {
       
   132 
       
   133             // Widgets
       
   134             listView = qobject_cast<HbView*>(widget);
       
   135             notesList = qobject_cast<HbListView*>(loader->findWidget("notesList"));
       
   136 
       
   137             // Actions
       
   138             newNoteAction = qobject_cast<HbAction*>(loader->findObject("newNoteAction"));
       
   139             deleteNoteAction = qobject_cast<HbAction*>(loader->findObject("deleteNoteAction"));
       
   140           }
       
   141     \endcode
       
   142     
       
   143     
       
   144 */
       
   145 
       
   146 /*!
       
   147     Default Constructor. 
    64     
   148     
    65     Use HbDocumentLoader(const HbMainWindow *window) constructor if an application 
   149     Use HbDocumentLoader(const HbMainWindow *window) constructor if an application 
    66     have HbMainWindow. If the main window parameter is omitted 
   150     has an HbMainWindow. If the main window parameter is omitted 
    67     HbDeviceProfile::current() is used to access device profile.
   151     HbDeviceProfile::current() is used to access the device profile.
    68  */
   152  */
    69 HbDocumentLoader::HbDocumentLoader()
   153 HbDocumentLoader::HbDocumentLoader()
    70 : d_ptr(new HbDocumentLoaderPrivate(0))
   154 : d_ptr(new HbDocumentLoaderPrivate(0))
    71 {
   155 {
    72     Q_D(HbDocumentLoader);
   156     Q_D(HbDocumentLoader);
    74 }
   158 }
    75 
   159 
    76 /*!
   160 /*!
    77     Constructor. 
   161     Constructor. 
    78     
   162     
    79     HbMainWindow is needed to access device profile of the application's main window.
   163     HbMainWindow is needed to access the device profile of the application's main window.
    80     HbDeviceProfile::current() is used in case of the window parameter is omitted.
   164     HbDeviceProfile::current() is used in case where the window parameter is omitted.
    81     \param window main window of the loaded layout.
   165     \param window main window of the loaded layout.
    82  */
   166  */
    83 
   167 
    84 HbDocumentLoader::HbDocumentLoader(const HbMainWindow *window)
   168 HbDocumentLoader::HbDocumentLoader(const HbMainWindow *window)
    85 : d_ptr(new HbDocumentLoaderPrivate(window))
   169 : d_ptr(new HbDocumentLoaderPrivate(window))
    95 {
   179 {
    96     delete d_ptr;
   180     delete d_ptr;
    97 }
   181 }
    98 
   182 
    99 /*!
   183 /*!
   100     Loads and processes DocML file. If After processing of file was successful,
   184     Loads and processes a DocML file. 
   101     it returnes root objects list as a return parameter. Otherwise returnes empty list. 
   185 
   102     Qwnership to loaded objects is passed to the caller.
   186     On successful execution, returns a list of root objects. This list contains 
   103     \param fileName file to be processed.
   187     only the objects which do not have an owner already. For example the child of a parent 
   104     \param section space separated route to section, that you want to load.
   188     widget is never returned, and the parent is returned only if it does not 
   105     \param ok indicates if loading was successful.
   189     have its own parent or a specific role like a menu-role. The document 
   106     \return root objects list.
   190     loader instance does not own any of the objects: the ones which do not 
       
   191     have any other owner are returned within the root object list. The caller 
       
   192     is resposible of handling the lifecycle of the returned objects.
       
   193 
       
   194     Usually this returns the view or the dialog which the loaded DocML files defines. 
       
   195 
       
   196     There are also situations when this function returns an empty list. These cases 
       
   197     usually include sections, which change the existing properties of loaded objects and do not 
       
   198     create any new root objects. Also, any objects passed to the document loader using the setObjectTree() 
       
   199     function are not returned. The success of calling load() cannot therefore be
       
   200     determined directly by the number of the returned objects. 
       
   201     Check the parameter \a ok to see if the document was loaded successfully.
       
   202 
       
   203     
       
   204 
       
   205     \param fileName The %file to be loaded.
       
   206     \param section Space separated path to the section to load.
       
   207     \param ok Indicates whether loading was successful.
       
   208     \return Root objects list. On failed execution, returns an empty list and deletes the created object hierarchy, which 
       
   209     may be incomplete.
   107 */
   210 */
   108 QObjectList HbDocumentLoader::load( const QString &fileName, const QString &section , bool *ok )
   211 QObjectList HbDocumentLoader::load( const QString &fileName, const QString &section , bool *ok )
   109 {
   212 {
   110     QFile file( fileName );
   213     QFile file( fileName );
   111     
   214     
   120     return load( &file, section, ok ) ;
   223     return load( &file, section, ok ) ;
   121 }
   224 }
   122 
   225 
   123 /*!
   226 /*!
   124     This is an overloaded member function, provided for convenience.
   227     This is an overloaded member function, provided for convenience.
   125     \param device IO device to be processed.
   228     \param device The IO device to be processed.
   126     \param section space separated route to section, that you want to load.
   229     \param section Space separated route to the section that you want to load.
   127     \param ok indicates if loading was successful.
   230     \param ok Indicates whether loading was successful.
   128     \return root objects list.
   231     \return Root objects list.
   129 */
   232 */
   130 QObjectList HbDocumentLoader::load( QIODevice *device, const QString &section, bool *ok )
   233 QObjectList HbDocumentLoader::load( QIODevice *device, const QString &section, bool *ok )
   131 {
   234 {
   132     Q_D(HbDocumentLoader);
   235     Q_D(HbDocumentLoader);
   133  
   236  
   138     }
   241     }
   139     return d->takeAll();
   242     return d->takeAll();
   140 }
   243 }
   141 
   244 
   142 /*!
   245 /*!
   143     This is an overloaded member function, provided for convenience. Loads part of DocML that is
   246     This is an overloaded member function, provided for convenience. It loads the part of the DocML that is
   144     outside of any section.
   247     outside of any section.
   145     \param fileName file to be processed.
   248     \param fileName The %file to be processed.
   146     \param ok indicates if loading was successful.
   249     \param ok Indicates whether loading was successful.
   147     \return root objects list.
   250     \return Root objects list.
   148 */
   251 */
   149 QObjectList HbDocumentLoader::load( const QString &fileName, bool *ok )
   252 QObjectList HbDocumentLoader::load( const QString &fileName, bool *ok )
   150 {
   253 {
   151     return load( fileName, QString(), ok );
   254     return load( fileName, QString(), ok );
   152 }
   255 }
   153 
   256 
   154 /*!
   257 /*!
   155     This is an overloaded member function, provided for convenience. Loads part of DocML that is
   258     This is an overloaded member function, provided for convenience. It loads the part of the DocML that is
   156     outside of any section.
   259     outside of any section.
   157     \param device IO device to be processed.
   260     \param device IO device to be processed.
   158     \param ok indicates if loading was successful.
   261     \param ok Indicates if loading was successful.
   159     \return root objects list.
   262     \return Root objects list.
   160 */
   263 */
   161 QObjectList HbDocumentLoader::load( QIODevice *device, bool *ok ) 
   264 QObjectList HbDocumentLoader::load( QIODevice *device, bool *ok ) 
   162 {
   265 {
   163     return load( device, QString(), ok );
   266     return load( device, QString(), ok );
   164 }
   267 }
   165 
   268 
   166 /*!
   269 /*!
   167     Converts DocML document to binary document. 
   270     Converts a text-based DocML document to a binary document at runtime. 
   168 
   271 
   169     You can also convert DocML files to binary format in build time by listing the files in "DOCML"
   272     You can also convert DocML files to binary format at build time by listing the files in the "DOCML"
   170     variable in the .pro file. This will create a binary docml file called <file_name>.bin that
   273     variable in the .pro file. This will create a binary docml file called <file_name>.bin that
   171     can be included to the resources (.qrc). 
   274     can be included with the application resources (.qrc file). 
   172     
   275     
   173     Known issues: Currently the resource compiler gives warnings about missing binary files during
   276     Known issues: Currently the resource compiler gives warnings about missing binary files during
   174     qmake. It's ok to ignore these warnings. 
   277     qmake. You can safely ignore these warnings.
   175 
   278 
   176     For more information about DocML binary format, please refer to S60QtProgrammersGuide.
   279     \param srcDevice Source IO device to be processed.
   177 
   280     \param dstDevice Destination IO device to which to write the binary DocML.
   178     \param srcDevice source IO device to be processed.
   281     \return True if the conversion to binary was successful.
   179     \param dstDevice destination IO device where to write to.
       
   180     \return true if conversion was ok.
       
   181 */
   282 */
   182 bool HbDocumentLoader::createBinary( QIODevice *srcDevice, QIODevice *dstDevice )
   283 bool HbDocumentLoader::createBinary( QIODevice *srcDevice, QIODevice *dstDevice )
   183 {
   284 {
   184     Q_D(HbDocumentLoader);
   285     Q_D(HbDocumentLoader);
   185     return d->createBinary( srcDevice, dstDevice );
   286     return d->createBinary( srcDevice, dstDevice );
   186 }
   287 }
   187 
   288 
   188 /*!
   289 /*!
   189     Retrieves widget of which object name equals to \a name.
   290     Retrieves widget whose object name is \a name. 
   190     \param name object name of desired widget.
   291     \param name The name of the widget in DocML. 
   191     \return widget or 0 if not found.
   292     \return The found widget or 0 if not found.
   192 */
   293 */
   193 QGraphicsWidget *HbDocumentLoader::findWidget(const QString &name) const
   294 QGraphicsWidget *HbDocumentLoader::findWidget(const QString &name) const
   194 {
   295 {
   195     const Q_D(HbDocumentLoader);
   296     const Q_D(HbDocumentLoader);
   196     return d->findWidget(name);
   297     return d->findWidget(name);
   197 }
   298 }
   198 
   299 
   199 
   300 
   200 /*!
   301 /*!
   201     Retrieves object of which object name equals to \a name.
   302     Retrieves object whose object name is \a name.
   202     \param name object name of desired widget.
   303     \param name The name of the widget in DocML. 
   203     \return object or 0 if not found.
   304     \return The found object or 0 if not found.
   204 */
   305 */
   205 QObject *HbDocumentLoader::findObject(const QString &name) const
   306 QObject *HbDocumentLoader::findObject(const QString &name) const
   206 {
   307 {
   207     const Q_D(HbDocumentLoader);
   308     const Q_D(HbDocumentLoader);
   208     return d->findObject(name);
   309     return d->findObject(name);
   209 }
   310 }
   210 
   311 
   211 
   312 
   212 /*!
   313 /*!
   213     Inserts object tree to document loader. You can pass as an input parameter 
   314     Inserts an object tree into the document loader object. 
   214     output of "load" mothod. 
   315     You can use the output of the load() method as the \a roots parameter. 
   215 
   316 
   216     Document loader does not take ownership of the objects.
   317     The document loader does not take ownership of the passed objects.
   217 
   318 
   218     \param roots root objects list.
   319     \param roots The list of root objects to add to the loader.
   219     \return true if success, false otherwise.
   320     \return True if the objects were successfully added to the document loader, false otherwise.
   220 */
   321 */
   221 bool HbDocumentLoader::setObjectTree( QObjectList roots )
   322 bool HbDocumentLoader::setObjectTree( QObjectList roots )
   222 {
   323 {
   223     Q_D(HbDocumentLoader);
   324     Q_D(HbDocumentLoader);
   224     return d->setObjectTree( roots );    
   325     return d->setObjectTree( roots );    
   225 }
   326 }
   226 
   327 
   227 /*!
   328 /*!
   228     Looks up an object which inherits class \a type and of which
   329     Looks up an object which inherits class \a type and for which the 
   229     object name equals to \a name. If you decide override this method,
   330     object name is \a name. If you decide to override this method in your own document loader class,
   230     you should call this base class method in case you are
   331     call this base class method in case you are
   231     not able to handle the case.
   332     not able to create an instance of the specified object type.
   232     \param type type of the desired object.
   333     \param type The type of the object to create.
   233     \param name object name of the desired object.
   334     \param name The object name of the object to create.
   234     \return object or 0 if not found.
   335     \return The created object or 0 if it could not be created.
   235 */
   336 */
   236 QObject *HbDocumentLoader::createObject(const QString& type, const QString &name)
   337 QObject *HbDocumentLoader::createObject(const QString& type, const QString &name)
   237 {
   338 {
   238 #ifdef HB_BOOTSTRAPPED
   339 #ifdef HB_BOOTSTRAPPED
   239     Q_UNUSED(type);
   340     Q_UNUSED(type);
   245 #endif
   346 #endif
   246 }
   347 }
   247 
   348 
   248 
   349 
   249 /*!
   350 /*!
   250     Sets loader to initial state. 
   351     Sets loader to an initial state without references to any loaded objects.
   251 */
   352 */
   252 void HbDocumentLoader::reset()
   353 void HbDocumentLoader::reset()
   253 {
   354 {
   254     Q_D(HbDocumentLoader);
   355     Q_D(HbDocumentLoader);
   255     d->reset();
   356     d->reset();
   256 }
   357 }
   257 
   358 
   258 
   359 
   259 /*!
   360 /*!
   260     Prints current version of document loader and minimum version of supported DocML in brackets
   361     Prints the current version of the document loader and the minimum version of supported DocML in brackets
   261     For example "3.2 (1.4)" means that current version is 3.2 and DocML versions from 1.4 to 3.2 are supported   
   362     For example "3.2 (1.4)" means that current version is 3.2 and DocML versions from 1.4 to 3.2 are supported   
   262 */
   363 */
   263 QString HbDocumentLoader::version()
   364 QString HbDocumentLoader::version()
   264 {
   365 {
   265     return HbDocumentLoaderPrivate::version();
   366     return HbDocumentLoaderPrivate::version();