src/hbcore/utils/hbwidgetloader.cpp
changeset 0 16d8024aca5e
child 1 f7ac710697a9
equal deleted inserted replaced
-1:000000000000 0:16d8024aca5e
       
     1 /****************************************************************************
       
     2 **
       
     3 ** Copyright (C) 2008-2010 Nokia Corporation and/or its subsidiary(-ies).
       
     4 ** All rights reserved.
       
     5 ** Contact: Nokia Corporation (developer.feedback@nokia.com)
       
     6 **
       
     7 ** This file is part of the HbCore module of the UI Extensions for Mobile.
       
     8 **
       
     9 ** GNU Lesser General Public License Usage
       
    10 ** This file may be used under the terms of the GNU Lesser General Public
       
    11 ** License version 2.1 as published by the Free Software Foundation and
       
    12 ** appearing in the file LICENSE.LGPL included in the packaging of this file.
       
    13 ** Please review the following information to ensure the GNU Lesser General
       
    14 ** Public License version 2.1 requirements will be met:
       
    15 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
       
    16 **
       
    17 ** In addition, as a special exception, Nokia gives you certain additional
       
    18 ** rights.  These rights are described in the Nokia Qt LGPL Exception
       
    19 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
       
    20 **
       
    21 ** If you have questions regarding the use of this file, please contact
       
    22 ** Nokia at developer.feedback@nokia.com.
       
    23 **
       
    24 ****************************************************************************/
       
    25 
       
    26 #include "hbwidgetloader_p.h"
       
    27 #include "hbwidgetloadersyntax_p.h"
       
    28 #include "hbwidgetloaderactions_p.h"
       
    29 
       
    30 #include "hbinstance.h"
       
    31 #include "hbtheme_p.h"
       
    32 
       
    33 #include <QtDebug>
       
    34 #include <QFile>
       
    35 #include <QStringList>
       
    36 #include <hbwidget.h>
       
    37 #include <QFileInfo>
       
    38 
       
    39 class HbThemeClient;
       
    40 
       
    41 // Uncomment the following in order to get additional debug prints
       
    42 //#define HB_WIDGETLOADER_DEBUG
       
    43  
       
    44 #ifndef HB_WIDGETLOADER_DEBUG
       
    45 #define HB_WIDGETLOADER_PRINT(a) 
       
    46 #else
       
    47 #include <QDebug>
       
    48 #define HB_WIDGETLOADER_PRINT(a) qDebug() << QString(a);
       
    49 #endif // HB_WIDGETLOADER_DEBUG
       
    50 
       
    51 #define hbInstance (HbInstance::instance())
       
    52 
       
    53 // cache at the client side to store the mesh items.
       
    54 // key used here is the filename+layoutname+sectionname.
       
    55 
       
    56 typedef QHash<QString,LayoutDefinition*> ClientHashForLayoutDefs;
       
    57 Q_GLOBAL_STATIC(ClientHashForLayoutDefs,clientLayoutDefsCache)
       
    58 
       
    59 // List of files that doesn't exist.
       
    60 // This reduces the check QFile::exists() at client side as well as the server side.
       
    61 // also no unnecessary IPC calls.
       
    62 Q_GLOBAL_STATIC(QStringList,filesNotPresent)
       
    63 
       
    64 class HbWidgetLoaderPrivate
       
    65 {
       
    66     Q_DECLARE_PUBLIC(HbWidgetLoader)    
       
    67         
       
    68 public:
       
    69 
       
    70     HbWidgetLoaderPrivate();
       
    71     virtual ~HbWidgetLoaderPrivate();
       
    72     
       
    73     void setWidget( HbWidget* widget );
       
    74     
       
    75     bool updateCacheIfNeeded(const QString &fileName, const QString &name, const QString &section);
       
    76     
       
    77     static QString version();
       
    78 private:
       
    79     Q_DISABLE_COPY(HbWidgetLoaderPrivate)
       
    80 
       
    81 public:
       
    82     HbWidgetLoader* q_ptr;
       
    83     
       
    84     HbWidgetLoaderActions* mActions;
       
    85     HbWidgetLoaderSyntax* mSyntax;    
       
    86 };
       
    87 
       
    88 
       
    89 /*
       
    90     \class HbWidgetLoader
       
    91     \internal
       
    92     \proto
       
    93 */
       
    94 LayoutDefinition *HbWidgetLoaderActions::mCacheLayout = NULL;
       
    95 QString HbWidgetLoaderActions::mCacheFileName = QString();
       
    96 QString HbWidgetLoaderActions::mCacheName = QString();
       
    97 QString HbWidgetLoaderActions::mCacheSection = QString();
       
    98 QDateTime HbWidgetLoaderActions::mCacheModified = QDateTime();
       
    99 
       
   100 /*!
       
   101     Constructor.
       
   102  */
       
   103 HbWidgetLoader::HbWidgetLoader()
       
   104 : d_ptr(new HbWidgetLoaderPrivate)
       
   105 {
       
   106     Q_D(HbWidgetLoader);
       
   107     d->q_ptr = this;
       
   108 }
       
   109 
       
   110 /*!
       
   111     Destructor.
       
   112 */
       
   113 HbWidgetLoader::~HbWidgetLoader()
       
   114 {
       
   115     delete d_ptr;
       
   116 }
       
   117 
       
   118 /*!
       
   119     Set widget. Temporary solution for time being.
       
   120     \param widget 
       
   121 */
       
   122 void HbWidgetLoader::setWidget( HbWidget* widget )
       
   123 {
       
   124     Q_D(HbWidgetLoader);
       
   125     
       
   126     d->mActions->reset();       
       
   127     d->mActions->mWidget = widget;
       
   128 }
       
   129 
       
   130 /*!
       
   131     Prints current version of widget loader and minimum version of supported WidgetML in brackets
       
   132     For example "3.2 (1.4)" means that current version is 3.2 and WidgetML versions from 1.4 to 3.2 are supported   
       
   133 */
       
   134 QString HbWidgetLoader::version()
       
   135 {
       
   136     return HbWidgetLoaderPrivate::version();       
       
   137 }
       
   138 
       
   139 /*!
       
   140     Loads and processes a WidgetML file.
       
   141 
       
   142     Proto:
       
   143     - Assumes that a widget is set with setWidget.
       
   144     - If the widget already has a layout assumes it's HbMeshLayout.
       
   145     - If the widget doesn't have a layout creates HbMeshLayout and sets it to widget.
       
   146     - Creates the anchor edge attachments for existing child items of the widget.
       
   147 
       
   148     \param fileName file to be processed.
       
   149     \param name the name of the layout to be loaded.
       
   150     \param section space separated route to section, that you want to load.
       
   151     \param storage specifies where to store the mesh items.
       
   152     \return true if file was loaded and processed successfully.
       
   153 */
       
   154 bool HbWidgetLoader::load( const QString &fileName, const QString &name, const QString &section,const HbMemoryManager::MemoryType storage )
       
   155 {
       
   156     Q_D(HbWidgetLoader);
       
   157     bool result = false;
       
   158 
       
   159     LayoutDefinition* sharedLayoutDef = NULL;
       
   160 
       
   161     // if the storage is SharedMemory
       
   162     if (storage == HbMemoryManager::SharedMemory) {
       
   163         // check in the client side cache if the vector of meshitems is present.
       
   164         QString key (fileName + name + section);
       
   165         if(clientLayoutDefsCache()->contains(key)){
       
   166             // present in the client cache.
       
   167             sharedLayoutDef = clientLayoutDefsCache()->value(key);
       
   168             //update the widget layout.
       
   169             d->mActions->updateWidget(sharedLayoutDef);
       
   170             return true;
       
   171         }
       
   172 
       
   173         // Not found in the client cache.
       
   174         if (filesNotPresent()->contains(fileName)){
       
   175             return false;
       
   176         } 
       
   177         // Check for the availability of the file, as QFile::Exists takes more time this 
       
   178         // method is used
       
   179         QFile file(fileName);        
       
   180         bool fileExists = file.open(QIODevice::ReadOnly);
       
   181         file.close();
       
   182         if (!fileExists) {
       
   183             // file doesn't exist save the info in the filesNotPresent list.
       
   184             filesNotPresent()->append(fileName);
       
   185             return false;
       
   186         }
       
   187 
       
   188         // get the shared layout definition address.
       
   189         sharedLayoutDef = HbThemeClient::global()->getSharedLayoutDefs(fileName, name, section);
       
   190 
       
   191         if (sharedLayoutDef){
       
   192             // This will update the widgets layout anchors.
       
   193             d->mActions->updateWidget(sharedLayoutDef);
       
   194 
       
   195             // Insert in to the client side cache.
       
   196             clientLayoutDefsCache()->insert(key, sharedLayoutDef);
       
   197             return true;
       
   198         }
       
   199     }
       
   200     //fall back
       
   201     result = d->updateCacheIfNeeded(fileName, name, section);
       
   202     if (result){
       
   203         d->mActions->updateWidget(0);
       
   204     }
       
   205     return result;
       
   206 }
       
   207 
       
   208 /*!
       
   209     This is an overloaded member function, provided for convenience.
       
   210     \param device IO device to be processed.
       
   211     \param name the name of the layout to be loaded.
       
   212     \param section space separated route to section, that you want to load.
       
   213     \return true if input was loaded and processed successfully.
       
   214 */
       
   215 bool HbWidgetLoader::load( QIODevice *device, const QString &name, const QString &section,const HbMemoryManager::MemoryType storage  )
       
   216 {
       
   217     Q_D(HbWidgetLoader);    
       
   218     Q_UNUSED(storage);
       
   219 	
       
   220     bool result = d->mSyntax->load(device, name, section);
       
   221     if (result){
       
   222     	HbWidgetLoaderActions::mCacheName = name;
       
   223         HbWidgetLoaderActions::mCacheSection = section;
       
   224         HbWidgetLoaderActions::mCacheFileName = QString();
       
   225         HbWidgetLoaderActions::mCacheModified = QDateTime();
       
   226 		d->mActions->updateWidget(0);
       
   227     }
       
   228     
       
   229     return result;
       
   230 }
       
   231 
       
   232 
       
   233 HbWidgetLoaderPrivate::HbWidgetLoaderPrivate() : q_ptr(0)
       
   234 {
       
   235     mActions = new HbWidgetLoaderActions();
       
   236     mSyntax = new HbWidgetLoaderSyntax(mActions);
       
   237 }
       
   238 
       
   239 HbWidgetLoaderPrivate::~HbWidgetLoaderPrivate()
       
   240 {
       
   241     delete mActions;
       
   242     delete mSyntax;
       
   243 }
       
   244 
       
   245 bool HbWidgetLoaderPrivate::updateCacheIfNeeded(const QString &fileName, const QString &name, const QString &section)
       
   246 {
       
   247     QFileInfo info(fileName);
       
   248     
       
   249 #ifdef HB_WIDGETLOADER_DEBUG
       
   250     qDebug() << "Cached layout currently contains" << HbWidgetLoaderActions::mCacheLayout.count() << "items";
       
   251 #endif
       
   252     bool cacheHit = (name == HbWidgetLoaderActions::mCacheName
       
   253 		&& section == HbWidgetLoaderActions::mCacheSection
       
   254 		&& fileName == HbWidgetLoaderActions::mCacheFileName 
       
   255 		&& info.lastModified() == HbWidgetLoaderActions::mCacheModified);
       
   256 		
       
   257     if(cacheHit){
       
   258 #ifdef HB_WIDGETLOADER_DEBUG
       
   259         qDebug() << "Cache hit.";
       
   260 #endif
       
   261     	return true;
       
   262     }
       
   263     
       
   264     
       
   265 #ifdef HB_WIDGETLOADER_DEBUG
       
   266 	qDebug() << "Cache miss, reloading cache data";
       
   267 #endif
       
   268 		
       
   269 	QFile file(fileName);
       
   270 	if( !file.open( QFile::ReadOnly | QFile::Text ) ) {
       
   271 	    qWarning( "Unable to open file ");
       
   272 	    return false;
       
   273 	}
       
   274 	    
       
   275     bool result = mSyntax->load(&file, name, section);
       
   276     if(result){
       
   277     	HbWidgetLoaderActions::mCacheName = name;
       
   278         HbWidgetLoaderActions::mCacheSection = section;
       
   279         HbWidgetLoaderActions::mCacheFileName = fileName;
       
   280         HbWidgetLoaderActions::mCacheModified = info.lastModified();
       
   281     }
       
   282     
       
   283     return result;
       
   284 }
       
   285 
       
   286 QString HbWidgetLoaderPrivate::version()
       
   287 {
       
   288     return HbWidgetLoaderSyntax::version();
       
   289 }
       
   290