~ubuntu-branches/ubuntu/utopic/kde-workspace/utopic-proposed

« back to all changes in this revision

Viewing changes to khotkeys/libkhotkeysprivate/settings.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Michał Zając
  • Date: 2011-07-09 08:31:15 UTC
  • Revision ID: james.westby@ubuntu.com-20110709083115-ohyxn6z93mily9fc
Tags: upstream-4.6.90
Import upstream version 4.6.90

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/**
 
2
 * Copyright (C) 1999-2001 Lubos Lunak <l.lunak@kde.org>
 
3
 * Copyright (C) 2009 Michael Jansen <kde@michael-jansen.biz>
 
4
 *
 
5
 * This library is free software; you can redistribute it and/or
 
6
 * modify it under the terms of the GNU Library General Public
 
7
 * License version 2 as published by the Free Software Foundation.
 
8
 *
 
9
 * This library is distributed in the hope that it will be useful,
 
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 
12
 * Library General Public License for more details.
 
13
 *
 
14
 * You should have received a copy of the GNU Library General Public License
 
15
 * along with this library; see the file COPYING.LIB. If not, write to
 
16
 * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 
17
 * Boston, MA 02110-1301, USA.
 
18
 **/
 
19
 
 
20
#include "settings.h"
 
21
 
 
22
#include "action_data/action_data.h"
 
23
#include "settings_reader_v2.h"
 
24
#include "settings_writer.h"
 
25
#include "windows_helper/window_selection_list.h"
 
26
 
 
27
#include <KDE/KConfig>
 
28
#include <KDE/KDebug>
 
29
#include <KDE/KMessageBox>
 
30
#include <KDE/KStandardDirs>
 
31
 
 
32
#include <QtGui/QApplication>
 
33
 
 
34
namespace KHotKeys
 
35
{
 
36
 
 
37
// Settings
 
38
 
 
39
Settings::Settings()
 
40
    : m_actions( NULL ),
 
41
      gestures_exclude(NULL)
 
42
    {
 
43
    reinitialize();
 
44
    }
 
45
 
 
46
 
 
47
Settings::~Settings()
 
48
    {
 
49
    delete m_actions; m_actions = 0;
 
50
    }
 
51
 
 
52
 
 
53
ActionDataGroup *Settings::actions()
 
54
    {
 
55
    return m_actions;
 
56
    }
 
57
 
 
58
 
 
59
const ActionDataGroup *Settings::actions() const
 
60
    {
 
61
    return m_actions;
 
62
    }
 
63
 
 
64
 
 
65
bool Settings::areGesturesDisabled() const
 
66
    {
 
67
    return gestures_disabled;
 
68
    }
 
69
 
 
70
 
 
71
void Settings::disableDaemon()
 
72
    {
 
73
    daemon_disabled = true;
 
74
    }
 
75
 
 
76
 
 
77
void Settings::disableGestures()
 
78
    {
 
79
    gestures_disabled = true;
 
80
    }
 
81
 
 
82
 
 
83
void Settings::enableDaemon()
 
84
    {
 
85
    daemon_disabled = false;
 
86
    }
 
87
 
 
88
 
 
89
void Settings::enableGestures()
 
90
    {
 
91
    gestures_disabled = false;
 
92
    }
 
93
 
 
94
 
 
95
void Settings::exportTo(
 
96
        ActionDataBase *what,
 
97
        KConfigBase &config,
 
98
        const QString &id,
 
99
        KHotKeys::ActionState state,
 
100
        bool allowMerging)
 
101
    {
 
102
    SettingsWriter writer(this, state, id, allowMerging);
 
103
    writer.exportTo(what, config);
 
104
    }
 
105
 
 
106
 
 
107
int Settings::gestureMouseButton() const
 
108
    {
 
109
    return gesture_mouse_button;
 
110
    }
 
111
 
 
112
 
 
113
Windowdef_list *Settings::gesturesExclude()
 
114
    {
 
115
    return gestures_exclude;
 
116
    }
 
117
 
 
118
 
 
119
const Windowdef_list *Settings::gesturesExclude() const
 
120
    {
 
121
    return gestures_exclude;
 
122
    }
 
123
 
 
124
 
 
125
int Settings::gestureTimeOut() const
 
126
    {
 
127
    return gesture_timeout;
 
128
    }
 
129
 
 
130
 
 
131
bool Settings::isDaemonDisabled() const
 
132
    {
 
133
    return daemon_disabled;
 
134
    }
 
135
 
 
136
 
 
137
bool Settings::loadDefaults()
 
138
    {
 
139
    reinitialize();
 
140
 
 
141
    // Load the default set.
 
142
    QString installPath = KGlobal::dirs()->installPath("data");
 
143
 
 
144
    KConfig file(installPath + "khotkeys/defaults.khotkeys");
 
145
    if (read_settings(m_actions, file, true, Enabled))
 
146
        {
 
147
        kDebug() << "Loaded defaults from" << file.name();
 
148
        already_imported.append("defaults");
 
149
        return true;
 
150
        }
 
151
    else
 
152
        {
 
153
        kDebug() << "Failed to load defaults from" << file.name();
 
154
        return false;
 
155
        }
 
156
 
 
157
    }
 
158
 
 
159
 
 
160
void Settings::reinitialize()
 
161
    {
 
162
    // Rereading settings. First delete what we have
 
163
    setActions(NULL);
 
164
 
 
165
    gestures_disabled = true;
 
166
    gesture_mouse_button = 2;
 
167
    gesture_timeout = 300;
 
168
    gestures_exclude = NULL,
 
169
 
 
170
    daemon_disabled = false;
 
171
 
 
172
    // Currently unused
 
173
    voice_shortcut = KShortcut();
 
174
 
 
175
    already_imported = QStringList();
 
176
    }
 
177
 
 
178
 
 
179
void Settings::setActions( ActionDataGroup *actions )
 
180
    {
 
181
    delete m_actions;
 
182
 
 
183
    m_actions = actions
 
184
        ? actions
 
185
        : new ActionDataGroup(
 
186
                NULL,
 
187
                "should never see",
 
188
                "should never see",
 
189
                NULL,
 
190
                ActionDataGroup::SYSTEM_ROOT);
 
191
    m_actions->enable();
 
192
    }
 
193
 
 
194
 
 
195
void Settings::setGesturesExclude( Windowdef_list *gestures )
 
196
    {
 
197
    delete gestures_exclude;
 
198
    gestures_exclude = gestures;
 
199
    }
 
200
 
 
201
 
 
202
void Settings::setGestureMouseButton( int mouse_button )
 
203
    {
 
204
    gesture_mouse_button = mouse_button;
 
205
    }
 
206
 
 
207
 
 
208
void Settings::setGestureTimeOut(int timeout)
 
209
    {
 
210
    gesture_timeout = timeout;
 
211
    }
 
212
 
 
213
 
 
214
void Settings::setVoiceShortcut( const KShortcut &shortcut )
 
215
    {
 
216
    voice_shortcut = shortcut;
 
217
    }
 
218
 
 
219
 
 
220
ActionDataGroup *Settings::takeActions()
 
221
    {
 
222
    ActionDataGroup *res = m_actions;
 
223
    m_actions = 0;
 
224
    return res;
 
225
    }
 
226
 
 
227
 
 
228
KShortcut Settings::voiceShortcut() const
 
229
    {
 
230
    return voice_shortcut;
 
231
    }
 
232
 
 
233
 
 
234
bool Settings::import(KConfig& config, ImportType ask, ActionState state)
 
235
    {
 
236
    return importFrom(m_actions, config, ask, state);
 
237
    }
 
238
 
 
239
 
 
240
bool Settings::isConfigFileValid(KConfigBase const &config, ImportType ask)
 
241
    {
 
242
    bool valid = false;
 
243
 
 
244
    // The file is only valid if it has a main group
 
245
    KConfigGroup mainGroup( &config, "Main" );
 
246
    if (mainGroup.isValid())
 
247
        {
 
248
        // Now check the version
 
249
        int version = mainGroup.readEntry( "Version", -1234576 );
 
250
        switch (version)
 
251
            {
 
252
            case 2:
 
253
                valid = true;
 
254
                break;
 
255
 
 
256
            case 1:         // Version 1 files no longer supported
 
257
                kDebug() << "Version 1 file encountered.";
 
258
                break;
 
259
 
 
260
            case -1234576:  // No Version entry -> invalid file
 
261
                kDebug() << "No version specified in file:";
 
262
                valid = false;
 
263
                break;
 
264
 
 
265
            default:
 
266
                kDebug() << "Invalid Version found:" << version;
 
267
                valid = false;
 
268
                break;
 
269
            }
 
270
        }
 
271
 
 
272
    // if it's valid we are finished.
 
273
    if (valid) return valid;
 
274
 
 
275
    // See if we should inform the user.
 
276
    switch (ask)
 
277
        {
 
278
        case ImportAsk:
 
279
                {
 
280
                KMessageBox::information(
 
281
                        QApplication::activeWindow(),
 
282
                        "The specified file is empty or not a configuration file",
 
283
                        "Import actions");
 
284
                }
 
285
            break;
 
286
 
 
287
        case ImportSilent:
 
288
            break;
 
289
 
 
290
        default:
 
291
            Q_ASSERT(false);
 
292
        }
 
293
 
 
294
    return valid;
 
295
    }
 
296
 
 
297
 
 
298
bool Settings::importFrom(ActionDataGroup *element, KConfigBase const &config, ImportType ask, ActionState state)
 
299
    {
 
300
    // Make sure the given file is valid
 
301
    if (!isConfigFileValid(config, ask)) return false;
 
302
 
 
303
    KConfigGroup mainGroup(&config, "Main");
 
304
    // A file can have a import id.
 
305
    QString import_id = mainGroup.readEntry( "ImportId" );
 
306
    if (!import_id.isEmpty())
 
307
        {
 
308
        // File has a id. Check for a previous import.
 
309
        if (already_imported.contains( import_id ))
 
310
            {
 
311
            switch (ask)
 
312
                {
 
313
                case ImportAsk:
 
314
                    // Ask the user?
 
315
                    if( ask == ImportSilent
 
316
                            || ( ask == ImportAsk && KMessageBox::warningContinueCancel(
 
317
                                    NULL,
 
318
                                    i18n( "This \"actions\" file has already been imported before. "
 
319
                                          "Are you sure you want to import it again?" )) != KMessageBox::Continue ) )
 
320
                        {
 
321
                        return true; // import "successful"
 
322
                        }
 
323
                    break;
 
324
 
 
325
                case ImportSilent:
 
326
                    return true;
 
327
 
 
328
                default:
 
329
                    // Unknown ImportType. Most likely None.
 
330
                    Q_ASSERT(false);
 
331
                    return true;
 
332
                }
 
333
            }
 
334
        else
 
335
            {
 
336
            already_imported.append(import_id);
 
337
            }
 
338
        }
 
339
    else
 
340
        {
 
341
        switch (ask)
 
342
            {
 
343
            case ImportAsk:
 
344
                if (KMessageBox::warningContinueCancel(
 
345
                                NULL,
 
346
                                i18n( "This \"actions\" file has no ImportId field and therefore it cannot be determined "
 
347
                                      "whether or not it has been imported already. Are you sure you want to import it?" ))
 
348
                        == KMessageBox::Cancel )
 
349
                    {
 
350
                    return true;
 
351
                    }
 
352
                break;
 
353
 
 
354
            case ImportSilent:
 
355
                return true;
 
356
 
 
357
            default:
 
358
                // Unknown ImportType. Most likely None.
 
359
                Q_ASSERT(false);
 
360
                return true;
 
361
            }
 
362
        }
 
363
 
 
364
    // Include Disabled, Disable the imported actions
 
365
    return read_settings(element, config, true, state);
 
366
    }
 
367
 
 
368
 
 
369
void Settings::validate()
 
370
    {
 
371
    // Create the KMenuEdit group if it does not yet exist
 
372
    get_system_group(ActionDataGroup::SYSTEM_MENUENTRIES);
 
373
    }
 
374
 
 
375
 
 
376
ActionDataGroup *Settings::get_system_group(ActionDataGroup::system_group_t group_id)
 
377
    {
 
378
    Q_ASSERT(m_actions);
 
379
 
 
380
    // Search for the menuentries system group.
 
381
    ActionDataGroup *system_group = NULL;
 
382
 
 
383
    Q_FOREACH(KHotKeys::ActionDataBase* element, m_actions->children())
 
384
        {
 
385
        ActionDataGroup *group = dynamic_cast<ActionDataGroup*>(element);
 
386
 
 
387
        if (group && (group->system_group() == group_id))
 
388
            {
 
389
            system_group = group;
 
390
            break;
 
391
            }
 
392
        }
 
393
 
 
394
    // Check if we found the group
 
395
    if (system_group==NULL)
 
396
        {
 
397
        switch (group_id)
 
398
            {
 
399
            case ActionDataGroup::SYSTEM_MENUENTRIES:
 
400
                system_group = new ActionDataGroup(
 
401
                        m_actions,
 
402
                        "KMenuEdit",
 
403
                        "KMenuEdit Global Shortcuts",
 
404
                        NULL,
 
405
                        ActionDataGroup::SYSTEM_MENUENTRIES);
 
406
                system_group->enable();
 
407
                break;
 
408
 
 
409
            default:
 
410
                Q_ASSERT(false);
 
411
                return NULL;
 
412
            }
 
413
        }
 
414
 
 
415
    Q_ASSERT(system_group);
 
416
    return system_group;
 
417
    }
 
418
 
 
419
 
 
420
bool Settings::reread_settings(bool include_disabled)
 
421
    {
 
422
    KConfig config( KHOTKEYS_CONFIG_FILE );
 
423
 
 
424
    // If we read the main settings and there is no main. Initialize the file
 
425
    // and return
 
426
    KConfigGroup mainGroup( &config, "Main" ); // main group
 
427
    if (!mainGroup.exists())
 
428
        {
 
429
        loadDefaults();
 
430
        validate();
 
431
        return false;
 
432
        }
 
433
 
 
434
    // First delete what we have
 
435
    reinitialize();
 
436
 
 
437
    // ### Read the global configurations. Reinitialize sets the default
 
438
    daemon_disabled = mainGroup.readEntry( "Disabled", daemon_disabled);
 
439
 
 
440
    // ### List of already imported configuration files
 
441
    already_imported = mainGroup.readEntry(
 
442
            "AlreadyImported",
 
443
            QStringList());
 
444
 
 
445
    // ### Gestures
 
446
    KConfigGroup gesturesConfig( &config, "Gestures" );
 
447
    // ### Read the gesture configurations. Reinitialize sets the default.
 
448
    // Keep them
 
449
    gestures_disabled = gesturesConfig.readEntry( "Disabled", gestures_disabled);
 
450
    gesture_mouse_button = gesturesConfig.readEntry( "MouseButton", gesture_mouse_button );
 
451
    gesture_mouse_button = qBound( 2, gesture_mouse_button, 9 );
 
452
    gesture_timeout = gesturesConfig.readEntry( "Timeout", gesture_timeout );
 
453
 
 
454
    // Somhow gesture_timeout found it's way into my config file. Fix it for
 
455
    // everyone else too.
 
456
    if (gesture_timeout < 100) gesture_timeout = 300;
 
457
 
 
458
    KConfigGroup gesturesExcludeConfig( &config, "GesturesExclude" );
 
459
    delete gestures_exclude;
 
460
    gestures_exclude = new Windowdef_list( gesturesExcludeConfig );
 
461
 
 
462
    // ### Voice
 
463
    KConfigGroup voiceConfig( &config, "Voice" );
 
464
    voice_shortcut=KShortcut( voiceConfig.readEntry("Shortcut" , "")  );
 
465
 
 
466
    bool rc = read_settings(m_actions, config, include_disabled, Retain);
 
467
    // Ensure the system groups exist
 
468
    validate();
 
469
    return rc;
 
470
    }
 
471
 
 
472
 
 
473
bool Settings::read_settings(ActionDataGroup *root, KConfigBase const &config, bool include_disabled, ActionState stateStrategy)
 
474
    {
 
475
    // Make sure the given file is valid
 
476
    if (!isConfigFileValid(config, ImportSilent)) return false;
 
477
 
 
478
    KConfigGroup mainGroup( &config, "Main" ); // main group
 
479
    int version = mainGroup.readEntry( "Version", -1234576 );
 
480
    QString import_id = mainGroup.readEntry( "ImportId" );
 
481
    switch (version)
 
482
        {
 
483
        case 2:
 
484
                {
 
485
                kDebug() << "Version 2 File!";
 
486
                SettingsReaderV2 reader(this, include_disabled, stateStrategy, import_id);
 
487
                reader.read(config, root);
 
488
                }
 
489
            break;
 
490
 
 
491
        default:
 
492
            // All other values are impossible because of the
 
493
            // isConfigFileValid() call above.
 
494
            Q_ASSERT(false);
 
495
            return false;
 
496
        }
 
497
 
 
498
    return true;
 
499
    }
 
500
 
 
501
 
 
502
bool Settings::update()
 
503
    {
 
504
    QStringList updates(KGlobal::dirs()->findAllResources("data", "khotkeys/*.khotkeys"));
 
505
    bool imported(false);
 
506
 
 
507
    Q_FOREACH (const QString &path, updates)
 
508
        {
 
509
        // Import checks if the file was already imported.
 
510
        KConfig file(path);
 
511
        if (import(file, ImportSilent, Retain))
 
512
            {
 
513
            kDebug() << "Imported file" << path;
 
514
            imported = true;
 
515
            }
 
516
        }
 
517
 
 
518
    if (imported)
 
519
        {
 
520
        write();
 
521
        }
 
522
    return false;
 
523
    }
 
524
 
 
525
 
 
526
void Settings::write()
 
527
    {
 
528
    KConfig cfg( KHOTKEYS_CONFIG_FILE );
 
529
    SettingsWriter writer(this, Retain);
 
530
    writer.writeTo(cfg);
 
531
    }
 
532
 
 
533
} // namespace KHotKeys