/* * This file is part of Maliit framework * * * Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies). * All rights reserved. * * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License version 2.1 as published by the Free Software Foundation * and appearing in the file LICENSE.LGPL included in the packaging * of this file. */ #include "mimonscreenplugins.h" #include #include #include #include #include #include using namespace std::tr1::placeholders; namespace { const char * const EnabledSubViews = MALIIT_CONFIG_ROOT"onscreen/enabled"; const char * const ActiveSubView = MALIIT_CONFIG_ROOT"onscreen/active"; bool equalPlugin(const MImOnScreenPlugins::SubView &subView, const QString &plugin) { return subView.plugin == plugin; } bool notEqualPlugin(const MImOnScreenPlugins::SubView &subView, const QString &plugin) { return subView.plugin != plugin; } QStringList toSettings(const QList &subViews) { QStringList result; Q_FOREACH(const MImOnScreenPlugins::SubView &subView, subViews) { result.push_back(subView.plugin + ":" + subView.id); } return result; } QList fromSettings(const QStringList& list) { QList result; Q_FOREACH (const QString &value, list) { QString plugin = value.section(':', 0, 0); QString subview = value.section(':', 1, -1); result.push_back(MImOnScreenPlugins::SubView(plugin, subview)); } return result; } QSet findEnabledPlugins(const QList &enabledSubViews) { QSet result; Q_FOREACH (const MImOnScreenPlugins::SubView &subView, enabledSubViews) { result.insert(subView.plugin); } return result; } } MImOnScreenPlugins::SubView::SubView() : plugin() , id() {} MImOnScreenPlugins::SubView::SubView(const QString &new_plugin, const QString &new_id) : plugin(new_plugin) , id(new_id) {} bool MImOnScreenPlugins::SubView::operator==(const MImOnScreenPlugins::SubView &other) const { return (plugin == other.plugin && id == other.id); } MImOnScreenPlugins::MImOnScreenPlugins(): QObject(), mAvailableSubViews(), mEnabledSubViews(), mLastEnabledSubViews(), mActiveSubView(), mEnabledSubViewsSettings(EnabledSubViews), mActiveSubViewSettings(ActiveSubView), mAllSubviewsEnabled(false) { connect(&mEnabledSubViewsSettings, SIGNAL(valueChanged()), this, SLOT(updateEnabledSubviews())); connect(&mActiveSubViewSettings, SIGNAL(valueChanged()), this, SLOT(updateActiveSubview())); updateEnabledSubviews(); updateActiveSubview(); } bool MImOnScreenPlugins::isEnabled(const QString &plugin) const { QList mEnabledAndAvailableSubViews; std::remove_copy_if(mEnabledSubViews.begin(), mEnabledSubViews.end(), std::back_inserter(mEnabledAndAvailableSubViews), std::tr1::bind(&MImOnScreenPlugins::isSubViewUnavailable, this, _1)); return std::find_if(mEnabledAndAvailableSubViews.begin(), mEnabledAndAvailableSubViews.end(), std::tr1::bind(equalPlugin, _1, plugin)) != mEnabledAndAvailableSubViews.end(); } bool MImOnScreenPlugins::isSubViewEnabled(const SubView &subView) const { return mEnabledSubViews.contains(subView); } QList MImOnScreenPlugins::enabledSubViews() const { return mEnabledSubViews; } QList MImOnScreenPlugins::enabledSubViews(const QString &plugin) const { QList result; std::remove_copy_if(mEnabledSubViews.begin(), mEnabledSubViews.end(), std::back_inserter(result), std::tr1::bind(notEqualPlugin, _1, plugin)); return result; } void MImOnScreenPlugins::setEnabledSubViews(const QList &subViews) { mEnabledSubViewsSettings.set(QVariant(toSettings(subViews))); } void MImOnScreenPlugins::setAutoEnabledSubViews(const QList &subViews) { // Update the enabled subviews list without saving the configuration to disk mEnabledSubViews = subViews; } void MImOnScreenPlugins::updateAvailableSubViews(const QList &availableSubViews) { mAvailableSubViews = availableSubViews; autoDetectActiveSubView(); } bool MImOnScreenPlugins::isSubViewAvailable(const SubView &subview) const { return mAvailableSubViews.contains(subview); } bool MImOnScreenPlugins::isSubViewUnavailable(const SubView &subview) const { return !mAvailableSubViews.contains(subview); } void MImOnScreenPlugins::updateEnabledSubviews() { const QStringList &list = mEnabledSubViewsSettings.value().toStringList(); const QList oldEnabledSubviews = mEnabledSubViews; mEnabledSubViews = fromSettings(list); // Changed subviews cause emission of enabledPluginsChanged() signal // because some subview from the setting might not really exists and therefore // changed subview might have implications to enabled plugins. if (mEnabledSubViews != oldEnabledSubviews) { Q_EMIT enabledPluginsChanged(); } } void MImOnScreenPlugins::updateActiveSubview() { const QString &active = mActiveSubViewSettings.value().toString(); if (active.isEmpty()) { mActiveSubView = MImOnScreenPlugins::SubView(MALIIT_DEFAULT_PLUGIN); return; } const QList &activeList = fromSettings(QStringList() << active); const MImOnScreenPlugins::SubView &subView = activeList.first(); if (mActiveSubView == subView) { return; } setAutoActiveSubView(subView); } const MImOnScreenPlugins::SubView MImOnScreenPlugins::activeSubView() { return mActiveSubView; } void MImOnScreenPlugins::setActiveSubView(const MImOnScreenPlugins::SubView &subView) { if (mActiveSubView == subView) return; mActiveSubView = subView; QList subViews; subViews << subView; mActiveSubViewSettings.set(toSettings(subViews)); Q_EMIT activeSubViewChanged(); } void MImOnScreenPlugins::setAutoActiveSubView(const MImOnScreenPlugins::SubView &subView) { // Update the active subview without writing the configuration to disk if (mActiveSubView == subView) return; mActiveSubView = subView; Q_EMIT activeSubViewChanged(); } void MImOnScreenPlugins::setAllSubViewsEnabled(bool enable) { if (mAllSubviewsEnabled != enable) { mAllSubviewsEnabled = enable; if (mAllSubviewsEnabled) { mLastEnabledSubViews = mEnabledSubViews; } else { if (not mLastEnabledSubViews.contains(mActiveSubView)) { mLastEnabledSubViews.append(mActiveSubView); } } setEnabledSubViews(mAllSubviewsEnabled ? mAvailableSubViews : mLastEnabledSubViews); } } void MImOnScreenPlugins::autoDetectActiveSubView() { // If no subviews are enabled by the configuration, try to auto-detect // them. if (enabledSubViews().empty()) { autoDetectEnabledSubViews(); } // If we still don't have an enabled subview, enable the first available // one. if (enabledSubViews().empty()) { MImOnScreenPlugins::SubView subView = mAvailableSubViews.first(); setAutoEnabledSubViews(QList() << subView); } // If we have an active subview in the configuration, check that it is // enabled // If we don't have an active subview, auto-activate the first enabled // one. if (mActiveSubView.id.isEmpty() || !isSubViewEnabled(mActiveSubView)) { MImOnScreenPlugins::SubView subView = enabledSubViews().first(); setAutoActiveSubView(subView); } } void MImOnScreenPlugins::autoDetectEnabledSubViews() { const QString &plugin = mActiveSubView.plugin; QList to_enable; // Try to auto-detect subviews for the selected plugin by looking for // subviews that coincide with the languages selected for use on the // system. // FIXME: This works for the keyboard plugin, but won't work everywhere. // The methodology for auto-configuring subviews should be somehow // plugin-dictated. QStringList langs = QLocale::system().uiLanguages(); Q_FOREACH (QString lang, langs) { // Convert to lower case, remove any .utf8 suffix, and use _ as // the separator between language and country. lang = lang.split('.')[0].toLower().replace("-", "_"); MImOnScreenPlugins::SubView subView(plugin, lang); // First try the language code as-is if (isSubViewAvailable(subView) && !to_enable.contains(subView)) { to_enable << subView; continue; } // See if we get a match if we expand "de" to "de_de" if (!lang.contains('_')) { subView.id = lang + "_" + lang; if (isSubViewAvailable(subView) && !to_enable.contains(subView)) { to_enable << subView; } continue; } // See if we get a match if we trim "de_at" to "de" subView.id = lang.split("_").first(); if (isSubViewAvailable(subView) && !to_enable.contains(subView)) { to_enable << subView; } } if (!to_enable.isEmpty()) { setAutoEnabledSubViews(to_enable); } }