~unity-team/ubuntu-system-settings/welcome-wizard

« back to all changes in this revision

Viewing changes to plugins/language/language-plugin.cpp

  • Committer: Michael Terry
  • Date: 2013-12-02 13:32:53 UTC
  • mfrom: (485.1.27 ubuntu-system-settings)
  • Revision ID: michael.terry@canonical.com-20131202133253-pntc3mswpdk3aw05
MergeĀ fromĀ trunk

Show diffs side-by-side

added added

removed removed

Lines of Context:
32
32
 
33
33
#define LAYOUTS_DIR "/usr/share/maliit/plugins/com/ubuntu/languages"
34
34
 
 
35
void managerLoaded(GObject    *object,
 
36
                   GParamSpec *pspec,
 
37
                   gpointer    user_data);
 
38
 
35
39
LanguagePlugin::LanguagePlugin(QObject *parent) :
36
40
    QObject(parent),
37
 
    m_languageLocales(NULL),
38
 
    m_languageNames(NULL),
39
 
    m_languageCodes(NULL),
40
 
    m_indicesByBcp47Name(NULL),
41
 
    m_indicesByLocaleName(NULL),
42
41
    m_currentLanguage(-1),
43
42
    m_nextCurrentLanguage(-1),
44
 
    m_manager(NULL),
 
43
    m_manager(act_user_manager_get_default()),
45
44
    m_user(NULL),
46
 
    m_maliitSettings(NULL),
47
 
    m_keyboardLayouts(NULL),
48
 
    m_keyboardLayoutsModel(NULL),
49
 
    m_spellCheckingModel(NULL)
 
45
    m_maliitSettings(g_settings_new(UBUNTU_KEYBOARD_SCHEMA_ID))
50
46
{
 
47
    if (m_manager != NULL) {
 
48
        g_object_ref(m_manager);
 
49
 
 
50
        gboolean loaded;
 
51
        g_object_get(m_manager, "is-loaded", &loaded, NULL);
 
52
 
 
53
        if (loaded)
 
54
            managerLoaded();
 
55
        else
 
56
            g_signal_connect(m_manager, "notify::is-loaded", G_CALLBACK(::managerLoaded), this);
 
57
    }
 
58
 
 
59
    updateLanguageLocales();
 
60
    updateCurrentLanguage();
 
61
    updateKeyboardLayouts();
 
62
    updateKeyboardLayoutsModel();
 
63
    updateSpellCheckingModel();
51
64
}
52
65
 
53
66
LanguagePlugin::~LanguagePlugin()
54
67
{
55
 
    delete m_languageLocales;
56
 
    delete m_languageNames;
57
 
    delete m_languageCodes;
58
 
    delete m_indicesByBcp47Name;
59
 
    delete m_indicesByLocaleName;
60
 
 
61
 
    if (m_manager != NULL) {
62
 
        g_signal_handlers_disconnect_by_data(m_manager, this);
63
 
        g_object_unref(m_manager);
64
 
    }
65
 
 
66
68
    if (m_user != NULL) {
67
69
        g_signal_handlers_disconnect_by_data(m_user, this);
68
70
        g_object_unref(m_user);
69
71
    }
70
72
 
71
 
    if (m_maliitSettings != NULL)
 
73
    if (m_manager != NULL) {
 
74
        g_signal_handlers_disconnect_by_data(m_manager, this);
 
75
        g_object_unref(m_manager);
 
76
    }
 
77
 
 
78
    if (m_maliitSettings != NULL) {
 
79
        g_signal_handlers_disconnect_by_data(m_maliitSettings, this);
72
80
        g_object_unref(m_maliitSettings);
 
81
    }
73
82
 
74
 
    for (QList<KeyboardLayout *>::const_iterator i(m_keyboardLayouts->begin()); i != m_keyboardLayouts->end(); ++i)
 
83
    for (QList<KeyboardLayout *>::const_iterator i(m_keyboardLayouts.begin()); i != m_keyboardLayouts.end(); ++i)
75
84
        delete *i;
76
 
 
77
 
    delete m_keyboardLayouts;
78
 
    delete m_keyboardLayoutsModel;
79
 
    delete m_spellCheckingModel;
80
85
}
81
86
 
82
87
const QStringList &
83
88
LanguagePlugin::languageNames() const
84
89
{
85
 
    languageLocales();
86
 
    return *m_languageNames;
 
90
    return m_languageNames;
87
91
}
88
92
 
89
93
const QStringList &
90
94
LanguagePlugin::languageCodes() const
91
95
{
92
 
    languageLocales();
93
 
    return *m_languageCodes;
 
96
    return m_languageCodes;
94
97
}
95
98
 
96
99
int
97
100
LanguagePlugin::currentLanguage() const
98
101
{
99
 
    if (m_currentLanguage < 0) {
100
 
        ActUserManager *manager(act_user_manager_get_default());
101
 
 
102
 
        if (manager != NULL) {
103
 
            gboolean loaded;
104
 
            g_object_get(manager, "is-loaded", &loaded, NULL);
105
 
 
106
 
            if (loaded) {
107
 
                const char *name(qPrintable(qgetenv("USER")));
108
 
 
109
 
                if (name != NULL && name[0] != '\0') {
110
 
                    ActUser *user(act_user_manager_get_user(manager, name));
111
 
 
112
 
                    if (user != NULL && act_user_is_loaded(user)) {
113
 
                        const char *language(act_user_get_language(user));
114
 
                        m_currentLanguage = indexForLanguage(language);
115
 
 
116
 
                        if (m_currentLanguage < 0) {
117
 
                            QLocale locale(language);
118
 
                            m_currentLanguage = indexForLocale(locale);
119
 
 
120
 
                            if (m_currentLanguage < 0) {
121
 
                                locale = QLocale(locale.language());
122
 
                                m_currentLanguage = indexForLocale(locale);
123
 
                            }
124
 
                        }
125
 
                    }
126
 
                }
127
 
            }
128
 
        }
129
 
    }
130
 
 
131
 
    if (m_currentLanguage < 0) {
132
 
        QLocale locale(QLocale::system());
133
 
        m_currentLanguage = indexForLocale(locale);
134
 
 
135
 
        if (m_currentLanguage < 0) {
136
 
            locale = QLocale(locale.language());
137
 
            m_currentLanguage = indexForLocale(locale);
138
 
        }
139
 
    }
140
 
 
141
102
    return m_currentLanguage;
142
103
}
143
104
 
144
105
void
145
 
LanguagePlugin::userSetCurrentLanguage(ActUser *user)
146
 
{
147
 
    if (act_user_is_loaded(user)) {
148
 
        if (m_user != NULL) {
149
 
            g_signal_handlers_disconnect_by_data(m_user, this);
150
 
            g_object_unref(m_user);
151
 
            m_user = NULL;
152
 
        }
153
 
 
154
 
        if (m_nextCurrentLanguage != m_currentLanguage) {
155
 
            QString languageCode(languageCodes()[m_nextCurrentLanguage]);
156
 
            act_user_set_language(user, qPrintable(languageCode.left(languageCode.indexOf('.'))));
157
 
            act_user_set_formats_locale(user, qPrintable(languageCode));
158
 
            m_currentLanguage = m_nextCurrentLanguage;
159
 
            Q_EMIT currentLanguageChanged();
160
 
        }
161
 
    }
162
 
}
163
 
 
164
 
void
165
 
userSetCurrentLanguage(GObject    *object,
166
 
                       GParamSpec *pspec,
167
 
                       gpointer    user_data)
168
 
{
169
 
    Q_UNUSED(pspec);
170
 
 
171
 
    LanguagePlugin *plugin(static_cast<LanguagePlugin *>(user_data));
172
 
    plugin->userSetCurrentLanguage(ACT_USER(object));
173
 
}
174
 
 
175
 
void
176
 
LanguagePlugin::managerSetCurrentLanguage(ActUserManager *manager)
177
 
{
178
 
    gboolean loaded;
179
 
    g_object_get(manager, "is-loaded", &loaded, NULL);
180
 
 
181
 
    if (loaded) {
182
 
        if (m_manager != NULL) {
183
 
            g_signal_handlers_disconnect_by_data(m_manager, this);
184
 
            g_object_unref(m_manager);
185
 
            m_manager = NULL;
186
 
        }
187
 
 
188
 
        const char *name(qPrintable(qgetenv("USER")));
189
 
 
190
 
        if (name != NULL && name[0] != '\0') {
191
 
            ActUser *user(act_user_manager_get_user(manager, name));
192
 
 
193
 
            if (user != NULL) {
194
 
                if (act_user_is_loaded(user))
195
 
                    userSetCurrentLanguage(user);
196
 
                else {
197
 
                    m_user = static_cast<ActUser *>(g_object_ref(user));
198
 
                    g_signal_connect(user, "notify::is-loaded", G_CALLBACK(::userSetCurrentLanguage), this);
199
 
                }
200
 
            }
201
 
        }
202
 
    }
203
 
}
204
 
 
205
 
void
206
 
managerSetCurrentLanguage(GObject    *object,
207
 
                          GParamSpec *pspec,
208
 
                          gpointer    user_data)
209
 
{
210
 
    Q_UNUSED(pspec);
211
 
 
212
 
    LanguagePlugin *plugin(static_cast<LanguagePlugin *>(user_data));
213
 
    plugin->managerSetCurrentLanguage(ACT_USER_MANAGER(object));
214
 
}
215
 
 
216
 
void
217
106
LanguagePlugin::setCurrentLanguage(int index)
218
107
{
219
 
    if (index >= 0 && index < languageLocales().length()) {
220
 
        ActUserManager *manager(act_user_manager_get_default());
221
 
 
222
 
        if (manager != NULL) {
223
 
            m_nextCurrentLanguage = index;
224
 
 
225
 
            gboolean loaded;
226
 
            g_object_get(manager, "is-loaded", &loaded, NULL);
227
 
 
228
 
            if (loaded)
229
 
                managerSetCurrentLanguage(manager);
230
 
            else {
231
 
                m_manager = static_cast<ActUserManager *>(g_object_ref(manager));
232
 
                g_signal_connect(manager, "notify::is-loaded", G_CALLBACK(::managerSetCurrentLanguage), this);
233
 
            }
234
 
        }
 
108
    if (index >= 0 && index < m_languageLocales.length()) {
 
109
        m_nextCurrentLanguage = index;
 
110
 
 
111
        updateCurrentLanguage();
235
112
    }
236
113
}
237
114
 
238
115
SubsetModel *
239
116
LanguagePlugin::keyboardLayoutsModel()
240
117
{
241
 
    if (m_keyboardLayoutsModel == NULL) {
242
 
        QVariantList superset;
243
 
 
244
 
        for (QList<KeyboardLayout *>::const_iterator i(keyboardLayouts().begin()); i != keyboardLayouts().end(); ++i) {
245
 
            QVariantList element;
246
 
 
247
 
            if (!(*i)->displayName().isEmpty())
248
 
                element += (*i)->displayName();
249
 
            else
250
 
                element += (*i)->name();
251
 
 
252
 
            element += (*i)->shortName();
253
 
            superset += QVariant(element);
254
 
        }
255
 
 
256
 
        GVariantIter *iter;
257
 
        const gchar *language;
258
 
        QList<int> subset;
259
 
 
260
 
        g_settings_get(maliitSettings(), KEY_ENABLED_LAYOUTS, "as", &iter);
261
 
 
262
 
        while (g_variant_iter_next(iter, "&s", &language)) {
263
 
            for (int i(0); i < keyboardLayouts().length(); i++) {
264
 
                if (keyboardLayouts()[i]->name() == language) {
265
 
                    subset += i;
266
 
                    break;
267
 
                }
268
 
            }
269
 
        }
270
 
 
271
 
        g_variant_iter_free(iter);
272
 
 
273
 
        QStringList customRoles;
274
 
        customRoles += "language";
275
 
        customRoles += "icon";
276
 
 
277
 
        m_keyboardLayoutsModel = new SubsetModel();
278
 
        m_keyboardLayoutsModel->setCustomRoles(customRoles);
279
 
        m_keyboardLayoutsModel->setSuperset(superset);
280
 
        m_keyboardLayoutsModel->setSubset(subset);
281
 
        m_keyboardLayoutsModel->setAllowEmpty(false);
282
 
 
283
 
        connect(m_keyboardLayoutsModel, SIGNAL(subsetChanged()), SLOT(updateKeyboardLayouts()));
284
 
    }
285
 
 
286
 
    return m_keyboardLayoutsModel;
 
118
    return &m_keyboardLayoutsModel;
287
119
}
288
120
 
289
121
void
290
 
LanguagePlugin::updateKeyboardLayouts()
 
122
LanguagePlugin::keyboardLayoutsModelChanged()
291
123
{
292
124
    GVariantBuilder builder;
293
125
    GVariant *currentLayouts;
294
126
 
295
127
    g_variant_builder_init(&builder, G_VARIANT_TYPE("as"));
296
128
 
297
 
    for (QList<int>::const_iterator i(keyboardLayoutsModel()->subset().begin()); i != keyboardLayoutsModel()->subset().end(); ++i)
298
 
        g_variant_builder_add(&builder, "s", qPrintable(keyboardLayouts()[*i]->name()));
 
129
    for (QList<int>::const_iterator i(m_keyboardLayoutsModel.subset().begin()); i != m_keyboardLayoutsModel.subset().end(); ++i)
 
130
        g_variant_builder_add(&builder, "s", qPrintable(m_keyboardLayouts[*i]->name()));
299
131
 
300
132
    currentLayouts = g_variant_ref_sink(g_variant_builder_end(&builder));
301
 
    g_settings_set_value(maliitSettings(), KEY_ENABLED_LAYOUTS, currentLayouts);
 
133
    g_settings_set_value(m_maliitSettings, KEY_ENABLED_LAYOUTS, currentLayouts);
302
134
    g_variant_unref(currentLayouts);
303
135
}
304
136
 
319
151
SubsetModel *
320
152
LanguagePlugin::spellCheckingModel()
321
153
{
322
 
    if (m_spellCheckingModel == NULL) {
323
 
        // TODO: populate spell checking model
324
 
        QVariantList superset;
325
 
 
326
 
        for (QStringList::const_iterator i(languageNames().begin()); i != languageNames().end(); ++i) {
327
 
            QVariantList element;
328
 
            element += *i;
329
 
            superset += QVariant(element);
330
 
        }
331
 
 
332
 
        m_spellCheckingModel = new SubsetModel();
333
 
        m_spellCheckingModel->setCustomRoles(QStringList("language"));
334
 
        m_spellCheckingModel->setSuperset(superset);
335
 
        m_spellCheckingModel->setSubset(QList<int>());
336
 
        m_spellCheckingModel->setAllowEmpty(false);
337
 
 
338
 
        connect(m_spellCheckingModel, SIGNAL(subsetChanged()), SLOT(updateSpellChecking()));
339
 
    }
340
 
 
341
 
    return m_spellCheckingModel;
 
154
    return &m_spellCheckingModel;
342
155
}
343
156
 
344
157
void
345
 
LanguagePlugin::updateSpellChecking()
 
158
LanguagePlugin::spellCheckingModelChanged()
346
159
{
347
 
    // TODO: update spell checking
 
160
    // TODO: update spell checking model
348
161
}
349
162
 
350
163
bool
351
164
LanguagePlugin::autoCapitalization() const
352
165
{
353
 
    return g_settings_get_boolean(maliitSettings(), KEY_AUTO_CAPITALIZATION);
 
166
    return g_settings_get_boolean(m_maliitSettings, KEY_AUTO_CAPITALIZATION);
354
167
}
355
168
 
356
169
void
357
170
LanguagePlugin::setAutoCapitalization(bool value)
358
171
{
359
172
    if (value != autoCapitalization()) {
360
 
        g_settings_set_boolean(maliitSettings(), KEY_AUTO_CAPITALIZATION, value);
 
173
        g_settings_set_boolean(m_maliitSettings, KEY_AUTO_CAPITALIZATION, value);
361
174
        Q_EMIT autoCapitalizationChanged();
362
175
    }
363
176
}
365
178
bool
366
179
LanguagePlugin::autoCompletion() const
367
180
{
368
 
    return g_settings_get_boolean(maliitSettings(), KEY_AUTO_COMPLETION);
 
181
    return g_settings_get_boolean(m_maliitSettings, KEY_AUTO_COMPLETION);
369
182
}
370
183
 
371
184
void
372
185
LanguagePlugin::setAutoCompletion(bool value)
373
186
{
374
187
    if (value != autoCompletion()) {
375
 
        g_settings_set_boolean(maliitSettings(), KEY_AUTO_COMPLETION, value);
 
188
        g_settings_set_boolean(m_maliitSettings, KEY_AUTO_COMPLETION, value);
376
189
        Q_EMIT autoCompletionChanged();
377
190
    }
378
191
}
380
193
bool
381
194
LanguagePlugin::predictiveText() const
382
195
{
383
 
    return g_settings_get_boolean(maliitSettings(), KEY_PREDICTIVE_TEXT);
 
196
    return g_settings_get_boolean(m_maliitSettings, KEY_PREDICTIVE_TEXT);
384
197
}
385
198
 
386
199
void
387
200
LanguagePlugin::setPredictiveText(bool value)
388
201
{
389
202
    if (value != predictiveText()) {
390
 
        g_settings_set_boolean(maliitSettings(), KEY_PREDICTIVE_TEXT, value);
 
203
        g_settings_set_boolean(m_maliitSettings, KEY_PREDICTIVE_TEXT, value);
391
204
        Q_EMIT predictiveTextChanged();
392
205
    }
393
206
}
395
208
bool
396
209
LanguagePlugin::keyPressFeedback() const
397
210
{
398
 
    return g_settings_get_boolean(maliitSettings(), KEY_KEY_PRESS_FEEDBACK);
 
211
    return g_settings_get_boolean(m_maliitSettings, KEY_KEY_PRESS_FEEDBACK);
399
212
}
400
213
 
401
214
void
402
215
LanguagePlugin::setKeyPressFeedback(bool value)
403
216
{
404
217
    if (value != keyPressFeedback()) {
405
 
        g_settings_set_boolean(maliitSettings(), KEY_KEY_PRESS_FEEDBACK, value);
 
218
        g_settings_set_boolean(m_maliitSettings, KEY_KEY_PRESS_FEEDBACK, value);
406
219
        Q_EMIT keyPressFeedbackChanged();
407
220
    }
408
221
}
422
235
    return name0 < name1;
423
236
}
424
237
 
425
 
const QList<QLocale> &
426
 
LanguagePlugin::languageLocales() const
427
 
{
428
 
    if (m_languageLocales == NULL) {
429
 
        delete m_languageNames;
430
 
        delete m_languageCodes;
431
 
        delete m_indicesByBcp47Name;
432
 
        delete m_indicesByLocaleName;
433
 
 
434
 
        m_languageLocales = new QList<QLocale>;
435
 
        m_languageNames = new QStringList;
436
 
        m_languageCodes = new QStringList;
437
 
        m_indicesByBcp47Name = new QHash<QString, unsigned int>;
438
 
        m_indicesByLocaleName = new QHash<QString, unsigned int>;
439
 
 
440
 
        QProcess localeProcess;
441
 
        localeProcess.start("locale", QStringList("-a"), QIODevice::ReadOnly);
442
 
        localeProcess.waitForFinished();
443
 
 
444
 
        QString localeOutput(localeProcess.readAllStandardOutput());
445
 
        QStringList localeNames(localeOutput.split(QRegExp("\\s+")));
446
 
        QHash<QString, QString> localeNamesByBcp47Name;
447
 
        QHash<QString, unsigned int> countsByLanguage;
448
 
 
449
 
        for (QStringList::const_iterator i(localeNames.begin()); i != localeNames.end(); ++i) {
450
 
            QLocale locale(i->left(i->indexOf('.')));
451
 
            QString bcp47Name(locale.bcp47Name());
452
 
            QString language(locale.nativeLanguageName());
453
 
 
454
 
            if (!language.isEmpty() && !localeNamesByBcp47Name.contains(bcp47Name)) {
455
 
                *m_languageLocales += locale;
456
 
                localeNamesByBcp47Name[bcp47Name] = *i;
457
 
                countsByLanguage[language]++;
458
 
            }
459
 
        }
460
 
 
461
 
        qSort(m_languageLocales->begin(), m_languageLocales->end(), compareLocales);
462
 
 
463
 
        for (int i(0); i < m_languageLocales->length(); i++) {
464
 
            const QLocale &locale((*m_languageLocales)[i]);
465
 
            QString bcp47Name(locale.bcp47Name());
466
 
            QString language(locale.nativeLanguageName());
467
 
            unsigned int count(countsByLanguage[language]);
468
 
 
469
 
            if (count > 1)
470
 
                *m_languageNames += QString("%1 - %2").arg(language).arg(locale.nativeCountryName());
471
 
            else
472
 
                *m_languageNames += language;
473
 
 
474
 
            *m_languageCodes += localeNamesByBcp47Name[bcp47Name];
475
 
            (*m_indicesByBcp47Name)[bcp47Name] = i;
476
 
            (*m_indicesByLocaleName)[localeNamesByBcp47Name[bcp47Name]] = i;
477
 
        }
478
 
    }
479
 
 
480
 
    return *m_languageLocales;
481
 
}
482
 
 
483
 
int
484
 
LanguagePlugin::indexForLocale(const QLocale &locale) const
485
 
{
486
 
    languageLocales();
487
 
    return m_indicesByBcp47Name->value(locale.bcp47Name(), -1);
488
 
}
489
 
 
490
 
int
491
 
LanguagePlugin::indexForLanguage(const QString &language) const
492
 
{
493
 
    languageLocales();
494
 
    return m_indicesByLocaleName->value(language, -1);
495
 
}
496
 
 
497
 
GSettings *
498
 
LanguagePlugin::maliitSettings() const
499
 
{
500
 
    if (m_maliitSettings == NULL)
501
 
        m_maliitSettings = g_settings_new(UBUNTU_KEYBOARD_SCHEMA_ID);
502
 
 
503
 
    return m_maliitSettings;
504
 
}
505
 
 
506
238
static bool
507
239
compareLayouts(const KeyboardLayout *layout0,
508
240
               const KeyboardLayout *layout1)
523
255
    return name0 < name1;
524
256
}
525
257
 
526
 
const QList<KeyboardLayout *> &
527
 
LanguagePlugin::keyboardLayouts() const
528
 
{
529
 
    if (m_keyboardLayouts == NULL) {
530
 
        m_keyboardLayouts = new QList<KeyboardLayout *>;
531
 
 
532
 
        QDir layoutsDir(LAYOUTS_DIR);
533
 
        layoutsDir.setFilter(QDir::Files);
534
 
        layoutsDir.setNameFilters(QStringList("*.xml"));
535
 
        layoutsDir.setSorting(QDir::Name);
536
 
 
537
 
        QFileInfoList fileInfoList(layoutsDir.entryInfoList());
538
 
 
539
 
        for (QFileInfoList::const_iterator i(fileInfoList.begin()); i != fileInfoList.end(); ++i) {
540
 
            KeyboardLayout *layout(new KeyboardLayout(*i));
541
 
 
542
 
            if (!layout->language().isEmpty())
543
 
                *m_keyboardLayouts += layout;
544
 
            else
545
 
                delete layout;
546
 
        }
547
 
 
548
 
        qSort(m_keyboardLayouts->begin(), m_keyboardLayouts->end(), compareLayouts);
549
 
    }
550
 
 
551
 
    return *m_keyboardLayouts;
 
258
void
 
259
LanguagePlugin::updateLanguageLocales()
 
260
{
 
261
    m_languageLocales.clear();
 
262
    m_languageNames.clear();
 
263
    m_languageCodes.clear();
 
264
    m_indicesByBcp47Name.clear();
 
265
    m_indicesByLocaleName.clear();
 
266
 
 
267
    QProcess localeProcess;
 
268
    localeProcess.start("locale", QStringList("-a"), QIODevice::ReadOnly);
 
269
    localeProcess.waitForFinished();
 
270
 
 
271
    QString localeOutput(localeProcess.readAllStandardOutput());
 
272
    QStringList localeNames(localeOutput.split(QRegExp("\\s+")));
 
273
    QHash<QString, QString> localeNamesByBcp47Name;
 
274
    QHash<QString, unsigned int> countsByLanguage;
 
275
 
 
276
    for (QStringList::const_iterator i(localeNames.begin()); i != localeNames.end(); ++i) {
 
277
        QLocale locale(i->left(i->indexOf('.')));
 
278
        QString bcp47Name(locale.bcp47Name());
 
279
        QString language(locale.nativeLanguageName());
 
280
 
 
281
        if (!language.isEmpty() && !localeNamesByBcp47Name.contains(bcp47Name)) {
 
282
            m_languageLocales += locale;
 
283
            localeNamesByBcp47Name[bcp47Name] = *i;
 
284
            countsByLanguage[language]++;
 
285
        }
 
286
    }
 
287
 
 
288
    qSort(m_languageLocales.begin(), m_languageLocales.end(), compareLocales);
 
289
 
 
290
    for (int i(0); i < m_languageLocales.length(); i++) {
 
291
        const QLocale &locale(m_languageLocales[i]);
 
292
        QString bcp47Name(locale.bcp47Name());
 
293
        QString language(locale.nativeLanguageName());
 
294
        unsigned int count(countsByLanguage[language]);
 
295
 
 
296
        if (count > 1)
 
297
            m_languageNames += QString("%1 - %2").arg(language).arg(locale.nativeCountryName());
 
298
        else
 
299
            m_languageNames += language;
 
300
 
 
301
        m_languageCodes += localeNamesByBcp47Name[bcp47Name];
 
302
        m_indicesByBcp47Name[bcp47Name] = i;
 
303
        m_indicesByLocaleName[localeNamesByBcp47Name[bcp47Name]] = i;
 
304
    }
 
305
}
 
306
 
 
307
void
 
308
LanguagePlugin::updateCurrentLanguage()
 
309
{
 
310
    int previousLanguage(m_currentLanguage);
 
311
 
 
312
    if (m_user != NULL && act_user_is_loaded(m_user)) {
 
313
        if (m_nextCurrentLanguage >= 0) {
 
314
            m_currentLanguage = m_nextCurrentLanguage;
 
315
            m_nextCurrentLanguage = -1;
 
316
 
 
317
            QString languageCode(m_languageCodes[m_currentLanguage]);
 
318
            act_user_set_language(m_user, qPrintable(languageCode.left(languageCode.indexOf('.'))));
 
319
            act_user_set_formats_locale(m_user, qPrintable(languageCode));
 
320
        } else {
 
321
            const char *language(act_user_get_language(m_user));
 
322
            m_currentLanguage = indexForLanguage(language);
 
323
 
 
324
            if (m_currentLanguage < 0) {
 
325
                QLocale locale(language);
 
326
                m_currentLanguage = indexForLocale(locale);
 
327
 
 
328
                if (m_currentLanguage < 0) {
 
329
                    locale = QLocale(locale.language());
 
330
                    m_currentLanguage = indexForLocale(locale);
 
331
                }
 
332
            }
 
333
        }
 
334
    }
 
335
 
 
336
    if (m_currentLanguage < 0) {
 
337
        QLocale locale(QLocale::system());
 
338
        m_currentLanguage = indexForLocale(locale);
 
339
 
 
340
        if (m_currentLanguage < 0) {
 
341
            locale = QLocale(locale.language());
 
342
            m_currentLanguage = indexForLocale(locale);
 
343
        }
 
344
    }
 
345
 
 
346
    if (m_currentLanguage != previousLanguage)
 
347
        Q_EMIT currentLanguageChanged();
 
348
}
 
349
 
 
350
void
 
351
LanguagePlugin::updateKeyboardLayouts()
 
352
{
 
353
    m_keyboardLayouts.clear();
 
354
 
 
355
    QDir layoutsDir(LAYOUTS_DIR);
 
356
    layoutsDir.setFilter(QDir::Files);
 
357
    layoutsDir.setNameFilters(QStringList("*.xml"));
 
358
    layoutsDir.setSorting(QDir::Name);
 
359
 
 
360
    QFileInfoList fileInfoList(layoutsDir.entryInfoList());
 
361
 
 
362
    for (QFileInfoList::const_iterator i(fileInfoList.begin()); i != fileInfoList.end(); ++i) {
 
363
        KeyboardLayout *layout(new KeyboardLayout(*i));
 
364
 
 
365
        if (!layout->language().isEmpty())
 
366
            m_keyboardLayouts += layout;
 
367
        else
 
368
            delete layout;
 
369
    }
 
370
 
 
371
    qSort(m_keyboardLayouts.begin(), m_keyboardLayouts.end(), compareLayouts);
 
372
}
 
373
 
 
374
void enabledLayoutsChanged(GSettings *settings,
 
375
                           gchar     *key,
 
376
                           gpointer   user_data);
 
377
 
 
378
void
 
379
LanguagePlugin::updateKeyboardLayoutsModel()
 
380
{
 
381
    QStringList customRoles;
 
382
    customRoles += "language";
 
383
    customRoles += "icon";
 
384
 
 
385
    m_keyboardLayoutsModel.setCustomRoles(customRoles);
 
386
 
 
387
    QVariantList superset;
 
388
 
 
389
    for (QList<KeyboardLayout *>::const_iterator i(m_keyboardLayouts.begin()); i != m_keyboardLayouts.end(); ++i) {
 
390
        QVariantList element;
 
391
 
 
392
        if (!(*i)->displayName().isEmpty())
 
393
            element += (*i)->displayName();
 
394
        else
 
395
            element += (*i)->name();
 
396
 
 
397
        element += (*i)->shortName();
 
398
        superset += QVariant(element);
 
399
    }
 
400
 
 
401
    m_keyboardLayoutsModel.setSuperset(superset);
 
402
 
 
403
    enabledLayoutsChanged();
 
404
 
 
405
    m_keyboardLayoutsModel.setAllowEmpty(false);
 
406
 
 
407
    connect(&m_keyboardLayoutsModel, SIGNAL(subsetChanged()), SLOT(keyboardLayoutsModelChanged()));
 
408
 
 
409
    g_signal_connect(m_maliitSettings, "changed::" KEY_ENABLED_LAYOUTS, G_CALLBACK(::enabledLayoutsChanged), this);
 
410
}
 
411
 
 
412
void
 
413
LanguagePlugin::updateSpellCheckingModel()
 
414
{
 
415
    // TODO: populate spell checking model
 
416
    QVariantList superset;
 
417
 
 
418
    for (QStringList::const_iterator i(m_languageNames.begin()); i != m_languageNames.end(); ++i) {
 
419
        QVariantList element;
 
420
        element += *i;
 
421
        superset += QVariant(element);
 
422
    }
 
423
 
 
424
    m_spellCheckingModel.setCustomRoles(QStringList("language"));
 
425
    m_spellCheckingModel.setSuperset(superset);
 
426
    m_spellCheckingModel.setSubset(QList<int>());
 
427
    m_spellCheckingModel.setAllowEmpty(false);
 
428
 
 
429
    connect(&m_spellCheckingModel, SIGNAL(subsetChanged()), SLOT(spellCheckingModelChanged()));
 
430
}
 
431
 
 
432
int
 
433
LanguagePlugin::indexForLocale(const QLocale &locale) const
 
434
{
 
435
    return m_indicesByBcp47Name.value(locale.bcp47Name(), -1);
 
436
}
 
437
 
 
438
int
 
439
LanguagePlugin::indexForLanguage(const QString &language) const
 
440
{
 
441
    return m_indicesByLocaleName.value(language, -1);
 
442
}
 
443
 
 
444
void
 
445
LanguagePlugin::userLoaded()
 
446
{
 
447
    if (act_user_is_loaded(m_user)) {
 
448
        g_signal_handlers_disconnect_by_data(m_user, this);
 
449
 
 
450
        updateCurrentLanguage();
 
451
    }
 
452
}
 
453
 
 
454
void
 
455
userLoaded(GObject    *object,
 
456
           GParamSpec *pspec,
 
457
           gpointer    user_data)
 
458
{
 
459
    Q_UNUSED(object);
 
460
    Q_UNUSED(pspec);
 
461
 
 
462
    LanguagePlugin *plugin(static_cast<LanguagePlugin *>(user_data));
 
463
    plugin->userLoaded();
 
464
}
 
465
 
 
466
void
 
467
LanguagePlugin::managerLoaded()
 
468
{
 
469
    gboolean loaded;
 
470
    g_object_get(m_manager, "is-loaded", &loaded, NULL);
 
471
 
 
472
    if (loaded) {
 
473
        g_signal_handlers_disconnect_by_data(m_manager, this);
 
474
 
 
475
        const char *name(qPrintable(qgetenv("USER")));
 
476
 
 
477
        if (name != NULL) {
 
478
            m_user = act_user_manager_get_user(m_manager, name);
 
479
 
 
480
            if (m_user != NULL) {
 
481
                g_object_ref(m_user);
 
482
 
 
483
                if (act_user_is_loaded(m_user))
 
484
                    userLoaded();
 
485
                else
 
486
                    g_signal_connect(m_user, "notify::is-loaded", G_CALLBACK(::userLoaded), this);
 
487
            }
 
488
        }
 
489
    }
 
490
}
 
491
 
 
492
void
 
493
managerLoaded(GObject    *object,
 
494
              GParamSpec *pspec,
 
495
              gpointer    user_data)
 
496
{
 
497
    Q_UNUSED(object);
 
498
    Q_UNUSED(pspec);
 
499
 
 
500
    LanguagePlugin *plugin(static_cast<LanguagePlugin *>(user_data));
 
501
    plugin->managerLoaded();
 
502
}
 
503
 
 
504
void
 
505
LanguagePlugin::enabledLayoutsChanged()
 
506
{
 
507
    GVariantIter *iter;
 
508
    const gchar *language;
 
509
    QList<int> subset;
 
510
 
 
511
    g_settings_get(m_maliitSettings, KEY_ENABLED_LAYOUTS, "as", &iter);
 
512
 
 
513
    while (g_variant_iter_next(iter, "&s", &language)) {
 
514
        for (int i(0); i < m_keyboardLayouts.length(); i++) {
 
515
            if (m_keyboardLayouts[i]->name() == language) {
 
516
                subset += i;
 
517
                break;
 
518
            }
 
519
        }
 
520
    }
 
521
 
 
522
    g_variant_iter_free(iter);
 
523
 
 
524
    m_keyboardLayoutsModel.setSubset(subset);
 
525
}
 
526
 
 
527
void
 
528
enabledLayoutsChanged(GSettings *settings,
 
529
                      gchar     *key,
 
530
                      gpointer   user_data)
 
531
{
 
532
    Q_UNUSED(settings);
 
533
    Q_UNUSED(key);
 
534
 
 
535
    LanguagePlugin *plugin(static_cast<LanguagePlugin *>(user_data));
 
536
    plugin->enabledLayoutsChanged();
552
537
}