--- a/src/hbcore/inputfw/hbinputmodecache.cpp Mon Oct 04 17:49:30 2010 +0300
+++ b/src/hbcore/inputfw/hbinputmodecache.cpp Mon Oct 18 18:23:13 2010 +0300
@@ -23,6 +23,7 @@
**
****************************************************************************/
#include "hbinputmodecache_p.h"
+#include "hbinputmodecache_p_p.h"
#include <QInputContextPlugin>
#include <QLocale>
@@ -30,6 +31,9 @@
#include <QLibrary>
#include <QPluginLoader>
#include <QDir>
+#include <QSharedMemory>
+#include <QDataStream>
+#include <QBuffer>
#include "hbinpututils.h"
#include "hbinputmethod.h"
@@ -42,50 +46,217 @@
/*!
@alpha
-@hbcore
\class HbInputModeCache
\brief Input framework's internal input mode resolver class.
*/
/// @cond
-class HbInputMethodListItem
+void HbInputMethodListItem::setValues(QInputContextPlugin *plugin, const QString &key)
+{
+ if (plugin) {
+ descriptor.setKey(key);
+ descriptor.setDisplayName(plugin->displayName(key));
+
+ HbInputContextPlugin *extension = qobject_cast<HbInputContextPlugin *>(plugin);
+ if (extension) {
+ descriptor.setDisplayNames(extension->displayNames(key));
+ descriptor.setIcon(extension->icon(key));
+ descriptor.setIcons(extension->icons(key));
+ }
+ }
+}
+
+QDataStream &operator<<(QDataStream &out, const HbInputMethodListItem &item)
+{
+ out << item.descriptor;
+ out << item.languages;
+ return out;
+}
+
+QDataStream &operator>>(QDataStream &in, HbInputMethodListItem &item)
+{
+ in >> item.descriptor;
+ in >> item.languages;
+ item.cached = 0;
+ item.toBeRemoved = false;
+ return in;
+}
+
+HbInputModeCachePrivate::HbInputModeCachePrivate()
+ : mSharedMethodList(0),
+ mMethodListModTime(0),
+ mMethodListLastUpdate(0),
+ mMethodsFetchedFromDisk(false),
+ mShuttingDown(false)
{
-public:
- HbInputMethodListItem() : cached(0), toBeRemoved(false) {}
- bool operator==(const HbInputMethodListItem &item) const {
- return (descriptor.pluginNameAndPath() == item.descriptor.pluginNameAndPath() &&
- descriptor.key() == item.descriptor.key());
+ mSharedMethodList = new QSharedMemory(HbInputMethodListKey);
+ // sharedMethodList is only attached when the list is updated
+ mMethodListModTime = new QSharedMemory(HbInputMethodListModTimeKey);
+ mMethodListModTime->attach();
+}
+
+HbInputModeCachePrivate::~HbInputModeCachePrivate()
+{
+ delete mSharedMethodList;
+ delete mMethodListModTime;
+}
+
+void HbInputModeCachePrivate::refresh()
+{
+ // Shared memory data is used if available (checked every time we refresh)
+ // Otherwise the methods are read from disk, but just once during modecache lifetime
+ if (!readInputMethodDataFromSharedMemory() && !mMethodsFetchedFromDisk) {
+ readInputMethodDataFromDisk(&mMethods);
+ pruneRemovedMethods();
+ mMethodsFetchedFromDisk = true;
+ }
+}
+
+void HbInputModeCachePrivate::readInputMethodDataFromDisk(QList<HbInputMethodListItem>* methodList, const QDir &readPath)
+{
+ bool readFromSinglePath = (readPath != QDir());
+ // First go through all the previously found entries and
+ // tag them not refreshed. In case a directory is defined, only marks entries
+ // in that directory
+ for (int i = 0; i < methodList->size(); ++i) {
+ if (readFromSinglePath) {
+ if (methodList->at(i).descriptor.pluginNameAndPath().left(methodList->at(i).descriptor.pluginNameAndPath().lastIndexOf(QDir::separator()))
+ == readPath.absolutePath()) {
+ (*methodList)[i].toBeRemoved = true;
+ }
+ } else {
+ (*methodList)[i].toBeRemoved = true;
+ }
}
-public:
- HbInputMethodDescriptor descriptor;
- QStringList languages;
- HbInputMethod *cached;
- bool toBeRemoved;
-};
+ // Query plugin paths and scan the folders.
+ QStringList folders = HbInputSettingProxy::instance()->inputMethodPluginPaths();
+ foreach(const QString &folder, folders) {
+ QDir dir(folder);
+ if (!readFromSinglePath || readPath == dir) {
+ for (unsigned int i = 0; i < dir.count(); i++) {
+ QString path = QString(dir.absolutePath());
+ if (path.right(1) != "\\" && path.right(1) != "/") {
+ path += QDir::separator();
+ }
+ path += dir[i];
+ QInputContextPlugin *inputContextPlugin = pluginInstance(path);
+ if (inputContextPlugin) {
+ HbInputMethodListItem listItem;
+ listItem.descriptor.setPluginNameAndPath(dir.absolutePath() + QDir::separator() + dir[i]);
-class HbInputModeCachePrivate
+ // For each found plugin, check if there is already a list item for it.
+ // If not, then add one.
+ QStringList contextKeys = inputContextPlugin->keys();
+ foreach(const QString &key, contextKeys) {
+ listItem.setValues(inputContextPlugin, key);
+
+ int index = methodList->indexOf(listItem);
+ if (index >= 0) {
+ // The method is already in the list, the situation hasn't changed.
+ // just tag it not to be removed.
+ (*methodList)[index].toBeRemoved = false;
+ } else {
+ listItem.languages = inputContextPlugin->languages(key);
+ methodList->append(listItem);
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+bool HbInputModeCachePrivate::readInputMethodDataFromSharedMemory()
{
-public:
- HbInputModeCachePrivate() : mWatcher(new QFileSystemWatcher()), mShuttingDown(false) {}
- ~HbInputModeCachePrivate() {}
- void refresh(const QString &directory = QString());
- QInputContextPlugin *pluginInstance(const QString &pluginFileName) const;
- HbInputMethod *methodInstance(const QString &pluginFileName, const QString &key) const;
- HbInputModeProperties propertiesFromString(const QString &entry) const;
- HbInputModeProperties propertiesFromState(const HbInputState &state) const;
- HbInputMethod *cachedMethod(HbInputMethodListItem &item);
- void updateMonitoredPaths();
- bool isMappedLanguage(const HbInputLanguage &language) const;
+ // Check if the shared list has been modified
+ if (!mMethodListModTime->isAttached()) {
+ // Shared memory is not attached
+ // Revert to in-process handling
+ return false;
+ }
+ // No locking, since in case the value is corrupt we just need to read the list again
+ // on the next run
+ uint *newModTime = static_cast<uint *>(mMethodListModTime->data());
+ if (*newModTime == mMethodListLastUpdate) {
+ // The internal list is still in sync with the one in shared memory
+ return true;
+ }
+ // Modifications done since last update, try to attach the method list
+ // Revert to in-process handling if not successful
+ if (!mSharedMethodList->attach()) {
+ return false;
+ }
+ // Attached successfully, update the modification time
+ mMethodListLastUpdate = *newModTime;
+
+ // To start updating the list, first mark all methods for removal
+ for (int k = 0; k < mMethods.count(); k++) {
+ mMethods[k].toBeRemoved = true;
+ }
+
+ // Get a copy of the list from shared memory
+ mSharedMethodList->lock();
+ QByteArray array(static_cast<const char *>(mSharedMethodList->data())+sizeof(int), *static_cast<int *>(mSharedMethodList->data()));
+ // array now has a copy of the data, so we can unlock and detach
+ mSharedMethodList->unlock();
+ mSharedMethodList->detach();
+
+ // Next read the entries from the array to a temporary list
+ QDataStream in(&array, QIODevice::ReadOnly);
+ QList<HbInputMethodListItem> newMethodList;
+ in >> newMethodList;
-public:
- QFileSystemWatcher *mWatcher;
- QList<HbInputMethodListItem> mMethods;
- bool mShuttingDown;
-};
+ // Go through the temporary list and append new methods to internal list
+ // Duplicates are marked as not to be removed, the rest will be removed by pruneRemovedMethods
+ foreach (const HbInputMethodListItem& item, newMethodList) {
+ int index = mMethods.indexOf(item);
+ if (index >= 0) {
+ mMethods[index].toBeRemoved = false;
+ } else {
+ mMethods.append(item);
+ }
+ }
+ pruneRemovedMethods();
+ return true;
+}
-QInputContextPlugin *HbInputModeCachePrivate::pluginInstance(const QString &pluginFileName) const
+void HbInputModeCachePrivate::pruneRemovedMethods()
+{
+ // Go through the cache list and find out if some of the previous items need to be
+ // removed after the refresh.
+ for (int i = 0; i < mMethods.count(); i++) {
+ if (mMethods.at(i).toBeRemoved) {
+ if (mMethods.at(i).cached && mMethods.at(i).cached->isActiveMethod()) {
+ // If the item to be removed happens to be the active one,
+ // try to deal with the situation.
+ mMethods.at(i).cached->forceUnfocus();
+ // The active custom method is being removed.
+ // Clear out related setting proxy values.
+ if (mMethods.at(i).descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Horizontal).pluginNameAndPath()) {
+ HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Horizontal, HbInputMethodDescriptor());
+ }
+ if (mMethods.at(i).descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Vertical).pluginNameAndPath()) {
+ HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Vertical, HbInputMethodDescriptor());
+ }
+
+ // Replace it with null input context.
+ HbInputMethod *master = HbInputMethodNull::Instance();
+ master->d_ptr->mIsActive = true;
+ QInputContext *proxy = master->d_ptr->proxy();
+ if (proxy != qApp->inputContext()) {
+ qApp->setInputContext(proxy);
+ }
+ }
+ delete mMethods[i].cached;
+ mMethods.removeAt(i);
+ i--;
+ }
+ }
+}
+
+QInputContextPlugin *HbInputModeCachePrivate::pluginInstance(const QString &pluginFileName)
{
if (QLibrary::isLibrary(pluginFileName)) {
QPluginLoader loader(pluginFileName);
@@ -108,7 +279,7 @@
QStringList languages = plugin->languages(key);
QList<HbInputModeProperties> modeList;
foreach(const QString &language, languages) {
- modeList.append(propertiesFromString(language));
+ modeList.append(HbInputModeProperties::fromString(language));
}
result->d_ptr->mInputModes = modeList;
}
@@ -118,122 +289,6 @@
return 0;
}
-void HbInputModeCachePrivate::refresh(const QString &directory)
-{
- Q_UNUSED(directory);
- // optimize later so that if the directory is given, only changes concerning
- // it are taken into account.
-
- // First go through all the previously found entries and
- // tag them not refreshed.
- for (int k = 0; k < mMethods.count(); k++) {
- mMethods[k].toBeRemoved = true;
- }
-
- // Query plugin paths and scan the folders.
- QStringList folders = HbInputSettingProxy::instance()->inputMethodPluginPaths();
- foreach(const QString &folder, folders) {
- QDir dir(folder);
- for (unsigned int i = 0; i < dir.count(); i++) {
- QString path = QString(dir.absolutePath());
- if (path.right(1) != "\\" && path.right(1) != "/") {
- path += QDir::separator();
- }
- path += dir[i];
- QInputContextPlugin *inputContextPlugin = pluginInstance(path);
- if (inputContextPlugin) {
- HbInputMethodListItem listItem;
- listItem.descriptor.setPluginNameAndPath(dir.absolutePath() + QDir::separator() + dir[i]);
-
- // For each found plugin, check if there is already a list item for it.
- // If not, then add one.
- QStringList contextKeys = inputContextPlugin->keys();
- foreach(const QString &key, contextKeys) {
- listItem.descriptor.setKey(key);
- listItem.descriptor.setDisplayName(inputContextPlugin->displayName(key));
-
- HbInputContextPlugin *extension = qobject_cast<HbInputContextPlugin *>(inputContextPlugin);
- if (extension) {
- listItem.descriptor.setDisplayNames(extension->displayNames(key));
- listItem.descriptor.setIcon(extension->icon(key));
- listItem.descriptor.setIcons(extension->icons(key));
- }
-
- int index = mMethods.indexOf(listItem);
- if (index >= 0) {
- // The method is already in the list, the situation hasn't changed.
- // just tag it not to be removed.
- mMethods[index].toBeRemoved = false;
- } else {
- listItem.languages = inputContextPlugin->languages(key);
- mMethods.append(listItem);
- }
- }
- }
- }
- }
-
- // Go through the cache list and find out if some of the previous items need to be
- // removed after the refresh.
- for (int i = 0; i < mMethods.count(); i++) {
- if (mMethods[i].toBeRemoved) {
- if (mMethods[i].cached && mMethods[i].cached->isActiveMethod()) {
- // If the item to be removed happens to be the active one,
- // try to deal with the situation.
- mMethods[i].cached->forceUnfocus();
- // The active custom method is being removed.
- // Clear out related setting proxy values.
- if (mMethods[i].descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Horizontal).pluginNameAndPath()) {
- HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Horizontal, HbInputMethodDescriptor());
- }
- if (mMethods[i].descriptor.pluginNameAndPath() == HbInputSettingProxy::instance()->preferredInputMethod(Qt::Vertical).pluginNameAndPath()) {
- HbInputSettingProxy::instance()->setPreferredInputMethod(Qt::Vertical, HbInputMethodDescriptor());
- }
-
- // Replace it with null input context.
- HbInputMethod *master = HbInputMethodNull::Instance();
- master->d_ptr->mIsActive = true;
- QInputContext *proxy = master->d_ptr->proxy();
- if (proxy != qApp->inputContext()) {
- qApp->setInputContext(proxy);
- }
- }
- delete mMethods[i].cached;
- mMethods.removeAt(i);
- i--;
- }
- }
-}
-
-HbInputModeProperties HbInputModeCachePrivate::propertiesFromString(const QString &entry) const
-{
- HbInputModeProperties result;
-
- QStringList parts = entry.split(' ');
- if (parts.count() == 4) {
- // See HbInputModeProperties::toString() for details,
- QString languageStr = parts[0] + QString(" ") + parts[1];
- HbInputLanguage language;
- language.fromString(languageStr);
- result.setLanguage(language);
- result.setInputMode((HbInputModeType)parts[2].toLong());
- result.setKeyboard((HbKeyboardType)parts[3].toLong());
- }
-
- return result;
-}
-
-HbInputModeProperties HbInputModeCachePrivate::propertiesFromState(const HbInputState &state) const
-{
- HbInputModeProperties result;
-
- result.setLanguage(state.language());
- result.setKeyboard(state.keyboard());
- result.setInputMode(state.inputMode());
-
- return HbInputModeProperties(result);
-}
-
HbInputMethod *HbInputModeCachePrivate::cachedMethod(HbInputMethodListItem &item)
{
if (!item.cached) {
@@ -243,36 +298,9 @@
return item.cached;
}
-void HbInputModeCachePrivate::updateMonitoredPaths()
-{
- QStringList watchedDirs = mWatcher->directories();
- if (!watchedDirs.isEmpty()) {
- mWatcher->removePaths(watchedDirs);
- }
-
- QStringList paths = HbInputSettingProxy::instance()->inputMethodPluginPaths();
- foreach(const QString &path, paths) {
- QDir dir(path);
- if (!dir.exists() && path.left(1) == "f") {
- mWatcher->addPath(QString("f:") + QDir::separator());
- } else {
- mWatcher->addPath(path);
- }
- }
-}
-
bool HbInputModeCachePrivate::isMappedLanguage(const HbInputLanguage &language) const
{
- if (language.defined()) {
- QList<HbInputLanguage> languages = HbKeymapFactory::instance()->availableLanguages();
- foreach(const HbInputLanguage &mappedLanguage, languages) {
- if (mappedLanguage == language) {
- return true;
- }
- }
- }
-
- return false;
+ return (HbKeymapFactory::instance()->keymap(language) != 0);
}
/// @endcond
@@ -295,10 +323,6 @@
{
Q_D(HbInputModeCache);
- // Start to monitor file system for changes.
- d->updateMonitoredPaths();
- connect(d->mWatcher, SIGNAL(directoryChanged(const QString &)), this, SLOT(directoryChanged(const QString &)));
-
d->refresh();
}
@@ -313,22 +337,6 @@
/*!
\internal
-This slot is called whenever a change in input method plugin file system is detected and
-the list needs to be refreshed.
-*/
-void HbInputModeCache::directoryChanged(const QString &directory)
-{
- Q_D(HbInputModeCache);
-
- d->updateMonitoredPaths();
-
- if (!d->mShuttingDown) {
- d->refresh(directory);
- }
-}
-
-/*!
-\internal
Shuts down the object safely. This is needed mainly for singleton object. There has been a lot
of problems related to randown singleton desctruction order and additional shutdown step is
needed to guarantee that it will be done safely. The slot is connected to
@@ -344,8 +352,6 @@
method.cached = 0;
}
d->mMethods.clear();
- delete d->mWatcher;
- d->mWatcher = 0;
}
/*!
@@ -355,11 +361,12 @@
HbInputMethod *HbInputModeCache::loadInputMethod(const HbInputMethodDescriptor &inputMethod)
{
Q_D(HbInputModeCache);
+ d->refresh();
for (int i = 0; i < d->mMethods.count(); i++) {
- if (d->mMethods[i].descriptor.pluginNameAndPath() == inputMethod.pluginNameAndPath() &&
- d->mMethods[i].descriptor.key() == inputMethod.key()) {
- if (!d->mMethods[i].cached) {
+ if (d->mMethods.at(i).descriptor.pluginNameAndPath() == inputMethod.pluginNameAndPath() &&
+ d->mMethods.at(i).descriptor.key() == inputMethod.key()) {
+ if (!d->mMethods.at(i).cached) {
d->mMethods[i].cached = d->methodInstance(inputMethod.pluginNameAndPath(), inputMethod.key());
}
@@ -377,12 +384,13 @@
QList<HbInputMethodDescriptor> HbInputModeCache::listCustomInputMethods()
{
Q_D(HbInputModeCache);
+ d->refresh();
QList<HbInputMethodDescriptor> result;
foreach(const HbInputMethodListItem &item, d->mMethods) {
foreach(const QString &language, item.languages) {
- HbInputModeProperties properties = d->propertiesFromString(language);
+ HbInputModeProperties properties = HbInputModeProperties::fromString(language);
if (properties.inputMode() == HbInputModeCustom) {
result.append(item.descriptor);
break;
@@ -400,12 +408,13 @@
QList<HbInputMethodDescriptor> HbInputModeCache::listCustomInputMethods(Qt::Orientation orientation, const HbInputLanguage &language)
{
Q_D(HbInputModeCache);
+ d->refresh();
QList<HbInputMethodDescriptor> result;
- foreach (const HbInputMethodListItem &item, d->mMethods) {
- foreach (const QString &lang, item.languages) {
- HbInputModeProperties properties = d->propertiesFromString(lang);
+ for (int i = 0; i < d->mMethods.count(); i++) {
+ foreach (const QString &lang, d->mMethods.at(i).languages) {
+ HbInputModeProperties properties = HbInputModeProperties::fromString(lang);
// Find custom methods that supports given language or any language and
// supports given orientation
@@ -413,7 +422,8 @@
(properties.language() == language || properties.language() == HbInputLanguage()) &&
((orientation == Qt::Vertical && properties.keyboard() == HbKeyboardTouchPortrait) ||
(orientation == Qt::Horizontal && properties.keyboard() == HbKeyboardTouchLandscape))) {
- result.append(item.descriptor);
+
+ result.append(d->mMethods[i].descriptor);
break;
}
}
@@ -429,23 +439,40 @@
HbInputMethodDescriptor HbInputModeCache::defaultInputMethod(Qt::Orientation orientation)
{
Q_D(HbInputModeCache);
+ d->refresh();
- HbInputMethodDescriptor result;
- foreach (const HbInputMethodListItem &item, d->mMethods) {
- foreach (const QString &language, item.languages) {
- HbInputModeProperties properties = d->propertiesFromString(language);
+ HbInputLanguage currentLanguage = HbInputSettingProxy::instance()->globalInputLanguage();
+ bool mapped = d->isMappedLanguage(currentLanguage);
+
+ for (int i = 0; i < d->mMethods.count(); i++) {
+ foreach (const QString &language, d->mMethods[i].languages) {
+ HbInputModeProperties properties = HbInputModeProperties::fromString(language);
+
+ if (properties.language().undefined()) {
+ // The input method reports language range but current language is not mapped
+ // language. Skip this one.
+ if (!mapped) {
+ continue;
+ }
+ } else {
+ // The input method reports support for specific language but it is not an exact
+ // match to current language. Skip this one
+ if (properties.language() != currentLanguage) {
+ // It is not direct match either.
+ continue;
+ }
+ }
// Find default method that supports given orientation
if (properties.inputMode() == HbInputModeDefault &&
((orientation == Qt::Vertical && properties.keyboard() == HbKeyboardTouchPortrait) ||
(orientation == Qt::Horizontal && properties.keyboard() == HbKeyboardTouchLandscape))) {
- result = item.descriptor;
- break;
+ return d->mMethods[i].descriptor;
}
}
}
- return result;
+ return HbInputMethodDescriptor();
}
/*!
@@ -455,15 +482,16 @@
HbInputMethod *HbInputModeCache::findStateHandler(const HbInputState &state)
{
Q_D(HbInputModeCache);
+ d->refresh();
- HbInputModeProperties stateProperties = d->propertiesFromState(state);
+ HbInputModeProperties stateProperties(state);
int languageRangeIndex = -1;
// First check if there is a method that matches excatly (ie. also specifies
// the language).
for (int i = 0; i < d->mMethods.count(); i++) {
foreach(const QString &language, d->mMethods[i].languages) {
- HbInputModeProperties properties = d->propertiesFromString(language);
+ HbInputModeProperties properties = HbInputModeProperties::fromString(language);
if (properties.language().undefined() &&
properties.keyboard() == stateProperties.keyboard() &&
properties.inputMode() == stateProperties.inputMode()) {
@@ -507,9 +535,10 @@
\sa HbInputMethod
*/
-HbInputMethod *HbInputModeCache::activeMethod() const
+HbInputMethod *HbInputModeCache::activeMethod()
{
- Q_D(const HbInputModeCache);
+ Q_D(HbInputModeCache);
+ d->refresh();
foreach(const HbInputMethodListItem &item, d->mMethods) {
if (item.cached && item.cached->isActiveMethod()) {
@@ -524,15 +553,16 @@
\internal
Lists available input languages.
*/
-QList<HbInputLanguage> HbInputModeCache::listInputLanguages() const
+QList<HbInputLanguage> HbInputModeCache::listInputLanguages()
{
- Q_D(const HbInputModeCache);
+ Q_D(HbInputModeCache);
+ d->refresh();
QList<HbInputLanguage> result;
foreach(const HbInputMethodListItem &item, d->mMethods) {
foreach(const QString &language, item.languages) {
- HbInputModeProperties mode = d->propertiesFromString(language);
+ HbInputModeProperties mode = HbInputModeProperties::fromString(language);
if (mode.inputMode() != HbInputModeCustom) {
if (mode.language().undefined()) {
// This is language range. Let's add everything
@@ -559,14 +589,15 @@
\internal
Returns true if given input method is able to handle given input state.
*/
-bool HbInputModeCache::acceptsState(const HbInputMethod *inputMethod, const HbInputState &state) const
+bool HbInputModeCache::acceptsState(const HbInputMethod *inputMethod, const HbInputState &state)
{
- Q_D(const HbInputModeCache);
+ Q_D(HbInputModeCache);
+ d->refresh();
foreach(const HbInputMethodListItem &item, d->mMethods) {
if (item.cached == inputMethod) {
foreach(const QString &language, item.languages) {
- HbInputModeProperties mode = d->propertiesFromString(language);
+ HbInputModeProperties mode = HbInputModeProperties::fromString(language);
// Check if keyboard type matches.
if (mode.keyboard() == state.keyboard()) {
// Check if input mode matches or it is a custom input method but
@@ -594,9 +625,10 @@
Returns input method descriptor for given input method. Returns empty descriptor if the framework
doesn't recognize given input method.
*/
-HbInputMethodDescriptor HbInputModeCache::descriptor(const HbInputMethod *inputMethod) const
+HbInputMethodDescriptor HbInputModeCache::descriptor(const HbInputMethod *inputMethod)
{
- Q_D(const HbInputModeCache);
+ Q_D(HbInputModeCache);
+ d->refresh();
foreach(const HbInputMethodListItem &item, d->mMethods) {
if (item.cached == inputMethod) {