File indexing completed on 2024-11-24 05:00:21

0001 /*
0002     SPDX-FileCopyrightText: 2014 Weng Xuetian <wengxt@gmail.com>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 #include "enginemanager.h"
0007 
0008 #define THRESHOLD 256
0009 
0010 EngineManager::EngineManager()
0011     : m_engines(nullptr)
0012     , m_length(0)
0013 {
0014 }
0015 
0016 EngineManager::~EngineManager()
0017 {
0018     freeOldEngine();
0019 }
0020 
0021 void EngineManager::freeOldEngine()
0022 {
0023     if (m_engines) {
0024         for (size_t i = 0; i < m_length; i++) {
0025             g_object_unref(m_engines[i]);
0026         }
0027         g_free(m_engines);
0028     }
0029 }
0030 
0031 void EngineManager::setEngines(IBusEngineDesc **engines)
0032 {
0033     freeOldEngine();
0034     m_engineMap.clear();
0035     m_history.clear();
0036 
0037     m_engines = engines;
0038     m_length = 0;
0039     if (engines) {
0040         while (engines[m_length]) {
0041             m_length++;
0042         }
0043     }
0044 }
0045 
0046 void EngineManager::setUseGlobalEngine(gboolean use)
0047 {
0048     m_useGlobalEngine = use;
0049     if (use) {
0050         m_engineMap.clear();
0051     }
0052 }
0053 
0054 void EngineManager::setCurrentContext(const gchar *input_context_path)
0055 {
0056     m_currentContext = QString::fromLatin1(input_context_path);
0057 }
0058 
0059 QString EngineManager::currentEngine()
0060 {
0061     if (m_engineMap.contains(m_currentContext)) {
0062         return m_engineMap[m_currentContext];
0063     } else if (m_length > 0) {
0064         return QString::fromUtf8(ibus_engine_desc_get_name(m_engines[0]));
0065     } else {
0066         return QString();
0067     }
0068 }
0069 
0070 void EngineManager::setCurrentEngine(const char *name)
0071 {
0072     if (!m_useGlobalEngine && !m_currentContext.isEmpty()) {
0073         if (!m_engineMap.contains(m_currentContext)) {
0074             m_history.enqueue(m_currentContext);
0075         }
0076         m_engineMap[m_currentContext] = QString::fromUtf8(name);
0077         if (m_engineMap.size() > THRESHOLD) {
0078             m_engineMap.remove(m_history.dequeue());
0079             Q_ASSERT(m_engineMap.size() == m_history.size());
0080         }
0081     }
0082 }
0083 
0084 const char *EngineManager::navigate(IBusEngineDesc *engine, bool forward)
0085 {
0086     if (length() == 0) {
0087         return "";
0088     }
0089 
0090     size_t i = 0;
0091     for (; i < m_length; i++) {
0092         if (m_engines[i] == engine || 0 == g_strcmp0(ibus_engine_desc_get_name(engine), ibus_engine_desc_get_name(m_engines[i]))) {
0093             break;
0094         }
0095     }
0096     i = (i + (forward ? 1 : (length() - 1))) % length();
0097     return ibus_engine_desc_get_name(m_engines[i]);
0098 }
0099 
0100 void EngineManager::moveToFirst(IBusEngineDesc *engine)
0101 {
0102     size_t i = 0;
0103     while (i < length()) {
0104         if (m_engines[i] == engine || 0 == g_strcmp0(ibus_engine_desc_get_name(engine), ibus_engine_desc_get_name(m_engines[i]))) {
0105             break;
0106         }
0107         i++;
0108     }
0109     if (i == 0) {
0110         return;
0111     }
0112     if (i >= m_length) {
0113         return;
0114     }
0115 
0116     engine = m_engines[i];
0117 
0118     for (int j = i; j > 0; j--) {
0119         m_engines[j] = m_engines[j - 1];
0120     }
0121     m_engines[0] = engine;
0122 }
0123 
0124 size_t EngineManager::getIndexByName(const char *name)
0125 {
0126     size_t i = 0;
0127     for (; i < m_length; i++) {
0128         if (0 == g_strcmp0(name, ibus_engine_desc_get_name(m_engines[i]))) {
0129             break;
0130         }
0131     }
0132     return i;
0133 }
0134 
0135 void EngineManager::setOrder(const gchar **engine_names, size_t len)
0136 {
0137     size_t k = 0;
0138     for (size_t i = 0; i < len; i++) {
0139         size_t j = getIndexByName(engine_names[i]);
0140         if (j < length() && j >= k) {
0141             if (j != k) {
0142                 IBusEngineDesc *temp = m_engines[k];
0143                 m_engines[k] = m_engines[j];
0144                 m_engines[j] = temp;
0145             }
0146             k++;
0147         }
0148     }
0149 }
0150 
0151 QStringList EngineManager::engineOrder()
0152 {
0153     QStringList list;
0154     for (size_t i = 0; i < m_length; i++) {
0155         list << QString::fromUtf8(ibus_engine_desc_get_name(m_engines[i]));
0156     }
0157     return list;
0158 }