~ubuntu-branches/ubuntu/warty/kdebase/warty

« back to all changes in this revision

Viewing changes to kcontrol/keys/shortcuts.cpp

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-09-16 04:51:45 UTC
  • Revision ID: james.westby@ubuntu.com-20040916045145-9vr63kith3k1cpza
Tags: upstream-3.2.2
ImportĀ upstreamĀ versionĀ 3.2.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * shortcuts.cpp
 
3
 *
 
4
 * Copyright (c) 1999 Matthias Hoelzer-Kluepfel <hoelzer@kde.org>
 
5
 * Copyright (c) 2001 Ellis Whitehead <ellis@kde.org>
 
6
 *
 
7
 * Requires the Qt widget libraries, available at no cost at
 
8
 * http://www.troll.no/
 
9
 *
 
10
 *  This program is free software; you can redistribute it and/or modify
 
11
 *  it under the terms of the GNU General Public License as published by
 
12
 *  the Free Software Foundation; either version 2 of the License, or
 
13
 *  (at your option) any later version.
 
14
 *
 
15
 *  This program is distributed in the hope that it will be useful,
 
16
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
17
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
18
 *  GNU General Public License for more details.
 
19
 *
 
20
 *  You should have received a copy of the GNU General Public License
 
21
 *  along with this program; if not, write to the Free Software
 
22
 *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
 
23
 */
 
24
 
 
25
#include "shortcuts.h"
 
26
 
 
27
#include <qdir.h>
 
28
#include <qlayout.h>
 
29
#include <qwhatsthis.h>
 
30
 
 
31
#include <kapplication.h>
 
32
#include <kdebug.h>
 
33
#include <kipc.h>
 
34
#include <kkeynative.h>
 
35
#include <kinputdialog.h>
 
36
#include <klocale.h>
 
37
#include <kmessagebox.h>
 
38
#include <kshortcutlist.h>
 
39
#include <ksimpleconfig.h>
 
40
#include <kstandarddirs.h>
 
41
 
 
42
ShortcutsModule::ShortcutsModule( QWidget *parent, const char *name )
 
43
: QWidget( parent, name )
 
44
{
 
45
        initGUI();
 
46
}
 
47
 
 
48
ShortcutsModule::~ShortcutsModule()
 
49
{
 
50
        delete m_pListGeneral;
 
51
        delete m_pListSequence;
 
52
        delete m_pListApplication;
 
53
}
 
54
 
 
55
// Called when [Reset] is pressed
 
56
void ShortcutsModule::load()
 
57
{
 
58
        kdDebug(125) << "ShortcutsModule::load()" << endl;
 
59
        slotSchemeCur();
 
60
}
 
61
 
 
62
// When [Apply] or [OK] are clicked.
 
63
void ShortcutsModule::save()
 
64
{
 
65
        kdDebug(125) << "ShortcutsModule::save()" << endl;
 
66
 
 
67
        // FIXME: This isn't working.  Why? -- ellis, 2002/01/27
 
68
        // Check for old group,
 
69
        if( KGlobal::config()->hasGroup( "Keys" ) ) {
 
70
                KGlobal::config()->deleteGroup( "Keys", true, true );
 
71
        }
 
72
        KGlobal::config()->sync();
 
73
 
 
74
        m_pkcGeneral->commitChanges();
 
75
        m_pkcSequence->commitChanges();
 
76
        m_pkcApplication->save();
 
77
 
 
78
        m_actionsGeneral.writeActions( "Global Shortcuts", 0, true, true );
 
79
        m_actionsSequence.writeActions( "Global Shortcuts", 0, true, true );
 
80
 
 
81
        KIPC::sendMessageAll( KIPC::SettingsChanged, KApplication::SETTINGS_SHORTCUTS );
 
82
}
 
83
 
 
84
void ShortcutsModule::defaults()
 
85
{
 
86
        m_pkcGeneral->allDefault();
 
87
        m_pkcSequence->allDefault();
 
88
        m_pkcApplication->allDefault();
 
89
}
 
90
 
 
91
QString ShortcutsModule::quickHelp() const
 
92
{
 
93
  return i18n("<h1>Key Bindings</h1> Using key bindings you can configure certain actions to be"
 
94
    " triggered when you press a key or a combination of keys, e.g. Ctrl+C is normally bound to"
 
95
    " 'Copy'. KDE allows you to store more than one 'scheme' of key bindings, so you might want"
 
96
    " to experiment a little setting up your own scheme while you can still change back to the"
 
97
    " KDE defaults.<p> In the tab 'Global Shortcuts' you can configure non-application specific"
 
98
    " bindings like how to switch desktops or maximize a window. In the tab 'Application Shortcuts'"
 
99
    " you will find bindings typically used in applications, such as copy and paste.");
 
100
}
 
101
 
 
102
void ShortcutsModule::initGUI()
 
103
{
 
104
        kdDebug(125) << "A-----------" << endl;
 
105
        KAccelActions* keys = &m_actionsGeneral;
 
106
// see also KShortcutsModule::init() below !!!
 
107
#define NOSLOTS
 
108
#define KICKER_ALL_BINDINGS
 
109
#include "../../kwin/kwinbindings.cpp"
 
110
#include "../../kicker/core/kickerbindings.cpp"
 
111
#include "../../kdesktop/kdesktopbindings.cpp"
 
112
#include "../../klipper/klipperbindings.cpp"
 
113
#include "../../kxkb/kxkbbindings.cpp"
 
114
 
 
115
        kdDebug(125) << "B-----------" << endl;
 
116
        m_actionsSequence.init( m_actionsGeneral );
 
117
 
 
118
        kdDebug(125) << "C-----------" << endl;
 
119
        createActionsGeneral();
 
120
        kdDebug(125) << "D-----------" << endl;
 
121
        createActionsSequence();
 
122
        kdDebug(125) << "E-----------" << endl;
 
123
 
 
124
        kdDebug(125) << "F-----------" << endl;
 
125
        QVBoxLayout* pVLayout = new QVBoxLayout( this, KDialog::marginHint() );
 
126
 
 
127
        pVLayout->addSpacing( KDialog::marginHint() );
 
128
 
 
129
        // (o) [Current      ] <Remove>   ( ) New <Save>
 
130
 
 
131
        QHBoxLayout *pHLayout = new QHBoxLayout( pVLayout, KDialog::spacingHint() );
 
132
        QButtonGroup* pGroup = new QButtonGroup( this );
 
133
        pGroup->hide();
 
134
 
 
135
        m_prbPre = new QRadioButton( "", this );
 
136
        connect( m_prbPre, SIGNAL(clicked()), SLOT(slotSchemeCur()) );
 
137
        pGroup->insert( m_prbPre );
 
138
        pHLayout->addWidget( m_prbPre );
 
139
 
 
140
        m_pcbSchemes = new KComboBox( this );
 
141
        connect( m_pcbSchemes, SIGNAL(activated(int)), SLOT(slotSelectScheme(int)) );
 
142
        pHLayout->addWidget( m_pcbSchemes );
 
143
 
 
144
        pHLayout->addSpacing( KDialog::marginHint() );
 
145
 
 
146
        m_pbtnRemove = new QPushButton( i18n("&Remove"), this );
 
147
        m_pbtnRemove->setEnabled( false );
 
148
        connect( m_pbtnRemove, SIGNAL(clicked()), SLOT(slotRemoveScheme()) );
 
149
        QWhatsThis::add( m_pbtnRemove, i18n("Click here to remove the selected key bindings scheme. You can not"
 
150
                " remove the standard system wide schemes, 'Current scheme' and 'KDE default'.") );
 
151
        pHLayout->addWidget( m_pbtnRemove );
 
152
 
 
153
        pHLayout->addSpacing( KDialog::marginHint() * 3 );
 
154
 
 
155
        m_prbNew = new QRadioButton( i18n("New scheme"), this );
 
156
        m_prbNew->setEnabled( false );
 
157
        pGroup->insert( m_prbNew );
 
158
        pHLayout->addWidget( m_prbNew );
 
159
 
 
160
        m_pbtnSave = new QPushButton( i18n("&Save..."), this );
 
161
        m_pbtnSave->setEnabled( false );
 
162
        QWhatsThis::add( m_pbtnSave, i18n("Click here to add a new key bindings scheme. You will be prompted for a name.") );
 
163
        connect( m_pbtnSave, SIGNAL(clicked()), SLOT(slotSaveSchemeAs()) );
 
164
        pHLayout->addWidget( m_pbtnSave );
 
165
 
 
166
        pHLayout->addStretch( 1 );
 
167
 
 
168
        m_pTab = new QTabWidget( this );
 
169
        m_pTab->setMargin( KDialog::marginHint() );
 
170
        pVLayout->addWidget( m_pTab );
 
171
 
 
172
        m_pListGeneral = new KAccelShortcutList( m_actionsGeneral, true );
 
173
        m_pkcGeneral = new KKeyChooser( m_pListGeneral, this, KKeyChooser::Global, false );
 
174
        m_pTab->addTab( m_pkcGeneral, i18n("&Global Shortcuts") );
 
175
        connect( m_pkcGeneral, SIGNAL(keyChange()), SLOT(slotKeyChange()) );
 
176
 
 
177
        m_pListSequence = new KAccelShortcutList( m_actionsSequence, true );
 
178
        m_pkcSequence = new KKeyChooser( m_pListSequence, this, KKeyChooser::Global, false );
 
179
        m_pTab->addTab( m_pkcSequence, i18n("Shortcut Se&quences") );
 
180
        connect( m_pkcSequence, SIGNAL(keyChange()), SLOT(slotKeyChange()) );
 
181
 
 
182
        m_pListApplication = new KStdAccel::ShortcutList;
 
183
        m_pkcApplication = new KKeyChooser( m_pListApplication, this, KKeyChooser::Standard, false );
 
184
        m_pTab->addTab( m_pkcApplication, i18n("App&lication Shortcuts") );
 
185
        connect( m_pkcApplication, SIGNAL(keyChange()), SLOT(slotKeyChange()) );
 
186
 
 
187
        kdDebug(125) << "G-----------" << endl;
 
188
        readSchemeNames();
 
189
 
 
190
        kdDebug(125) << "I-----------" << endl;
 
191
        slotSchemeCur();
 
192
 
 
193
        kdDebug(125) << "J-----------" << endl;
 
194
}
 
195
 
 
196
void ShortcutsModule::createActionsGeneral()
 
197
{
 
198
        KAccelActions& actions = m_actionsGeneral;
 
199
 
 
200
        for( uint i = 0; i < actions.count(); i++ ) {
 
201
                QString sConfigKey = actions[i].name();
 
202
                //kdDebug(125) << "sConfigKey: " << sConfigKey << endl;
 
203
                int iLastSpace = sConfigKey.findRev( ' ' );
 
204
                bool bIsNum = false;
 
205
                if( iLastSpace >= 0 )
 
206
                        sConfigKey.mid( iLastSpace+1 ).toInt( &bIsNum );
 
207
 
 
208
                //kdDebug(125) << "sConfigKey: " << sConfigKey
 
209
                //      << " bIsNum: " << bIsNum << endl;
 
210
                if( bIsNum && !sConfigKey.contains( ':' ) ) {
 
211
                        actions[i].setConfigurable( false );
 
212
                        actions[i].setName( QString::null );
 
213
                }
 
214
        }
 
215
}
 
216
 
 
217
void ShortcutsModule::createActionsSequence()
 
218
{
 
219
        KAccelActions& actions = m_actionsSequence;
 
220
 
 
221
        for( uint i = 0; i < actions.count(); i++ ) {
 
222
                QString sConfigKey = actions[i].name();
 
223
                //kdDebug(125) << "sConfigKey: " << sConfigKey << endl;
 
224
                int iLastSpace = sConfigKey.findRev( ' ' );
 
225
                bool bIsNum = false;
 
226
                if( iLastSpace >= 0 )
 
227
                        sConfigKey.mid( iLastSpace+1 ).toInt( &bIsNum );
 
228
 
 
229
                //kdDebug(125) << "sConfigKey: " << sConfigKey
 
230
                //      << " bIsNum: " << bIsNum << endl;
 
231
                if( !bIsNum && !sConfigKey.contains( ':' ) ) {
 
232
                        actions[i].setConfigurable( false );
 
233
                        actions[i].setName( QString::null );
 
234
                }
 
235
        }
 
236
}
 
237
 
 
238
void ShortcutsModule::readSchemeNames()
 
239
{
 
240
        QStringList schemes = KGlobal::dirs()->findAllResources("data", "kcmkeys/*.kksrc");
 
241
 
 
242
        m_pcbSchemes->clear();
 
243
        m_rgsSchemeFiles.clear();
 
244
 
 
245
        i18n("User-Defined Scheme");
 
246
        m_pcbSchemes->insertItem( i18n("Current Scheme") );
 
247
        m_rgsSchemeFiles.append( "cur" );
 
248
 
 
249
        // This for system files
 
250
        for ( QStringList::ConstIterator it = schemes.begin(); it != schemes.end(); it++) {
 
251
        // KPersonalizer relies on .kksrc files containing all the keyboard shortcut
 
252
        //  schemes for various setups.  It also requires the KDE defaults to be in
 
253
        //  a .kksrc file.  The KDE defaults shouldn't be listed here.
 
254
                //if( r.search( *it ) != -1 )
 
255
                //   continue;
 
256
 
 
257
                KSimpleConfig config( *it, true );
 
258
                config.setGroup( "Settings" );
 
259
                QString str = config.readEntry( "Name" );
 
260
 
 
261
                m_pcbSchemes->insertItem( str );
 
262
                m_rgsSchemeFiles.append( *it );
 
263
        }
 
264
}
 
265
 
 
266
void ShortcutsModule::resizeEvent( QResizeEvent * )
 
267
{
 
268
        //m_pTab->setGeometry(0,0,width(),height());
 
269
}
 
270
 
 
271
void ShortcutsModule::slotSchemeCur()
 
272
{
 
273
        kdDebug(125) << "ShortcutsModule::slotSchemeCur()" << endl;
 
274
        //m_pcbSchemes->setCurrentItem( 0 );
 
275
        slotSelectScheme();
 
276
}
 
277
 
 
278
void ShortcutsModule::slotKeyChange()
 
279
{
 
280
        kdDebug(125) << "ShortcutsModule::slotKeyChange()" << endl;
 
281
        m_prbNew->setEnabled( true );
 
282
        m_prbNew->setChecked( true );
 
283
        m_pbtnSave->setEnabled( true );
 
284
        emit changed( true );
 
285
}
 
286
 
 
287
void ShortcutsModule::slotSelectScheme( int )
 
288
{
 
289
        i18n("Your current changes will be lost if you load another scheme before saving this one.");
 
290
        kdDebug(125) << "ShortcutsModule::slotSelectScheme( " << m_pcbSchemes->currentItem() << " )" << endl;
 
291
        QString sFilename = m_rgsSchemeFiles[ m_pcbSchemes->currentItem() ];
 
292
 
 
293
        if( sFilename == "cur" ) {
 
294
                // TODO: remove nulls params
 
295
                m_pkcGeneral->syncToConfig( "Global Shortcuts", 0, true );
 
296
                m_pkcSequence->syncToConfig( "Global Shortcuts", 0, true );
 
297
                m_pkcApplication->syncToConfig( "Shortcuts", 0, false );
 
298
        } else {
 
299
                KSimpleConfig config( sFilename );
 
300
                config.setGroup( "Settings" );
 
301
                //m_sBaseSchemeFile = config.readEntry( "Name" );
 
302
 
 
303
                // If the user's keyboard layout doesn't support the Win key,
 
304
                //  but this layout scheme requires it,
 
305
                if( !KKeyNative::keyboardHasWinKey()
 
306
                    && config.readBoolEntry( "Uses Win Modifier", false ) ) {
 
307
                        // TODO: change "Win" to Win's label.
 
308
                        int ret = KMessageBox::warningContinueCancel( this,
 
309
                                i18n("This scheme requires the \"%1\" modifier key, which is not "
 
310
                                "available on your keyboard layout. Do you wish to view it anyway?" )
 
311
                                .arg(i18n("Win")) );
 
312
                        if( ret == KMessageBox::Cancel )
 
313
                                return;
 
314
                }
 
315
 
 
316
                m_pkcGeneral->syncToConfig( "Global Shortcuts", &config, true );
 
317
                m_pkcSequence->syncToConfig( "Global Shortcuts", &config, true );
 
318
                m_pkcApplication->syncToConfig( "Shortcuts", &config, false );
 
319
        }
 
320
 
 
321
        m_prbPre->setChecked( true );
 
322
        m_prbNew->setEnabled( false );
 
323
        m_pbtnSave->setEnabled( false );
 
324
        emit changed(true);
 
325
}
 
326
 
 
327
void ShortcutsModule::slotSaveSchemeAs()
 
328
{
 
329
        QString sName, sFile;
 
330
        bool bNameValid, ok;
 
331
        int iScheme = -1;
 
332
 
 
333
        sName = m_pcbSchemes->currentText();
 
334
 
 
335
        do {
 
336
                bNameValid = true;
 
337
 
 
338
                sName = KInputDialog::getText( i18n( "Save Key Scheme" ),
 
339
                        i18n( "Enter a name for the key scheme:" ), sName, &ok, this );
 
340
 
 
341
                if( ok ) {
 
342
                        sName = sName.simplifyWhiteSpace();
 
343
                        sFile = sName;
 
344
 
 
345
                        int ind = 0;
 
346
                        while( ind < (int) sFile.length() ) {
 
347
                                // parse the string for first white space
 
348
                                ind = sFile.find(" ");
 
349
                                if( ind == -1 ) {
 
350
                                        ind = sFile.length();
 
351
                                        break;
 
352
                                }
 
353
 
 
354
                                // remove from string
 
355
                                sFile.remove( ind, 1 );
 
356
 
 
357
                                // Make the next letter upper case
 
358
                                QString s = sFile.mid( ind, 1 );
 
359
                                s = s.upper();
 
360
                                sFile.replace( ind, 1, s );
 
361
                        }
 
362
 
 
363
                        iScheme = -1;
 
364
                        for( int i = 0; i < (int) m_pcbSchemes->count(); i++ ) {
 
365
                                if( sName.lower() == (m_pcbSchemes->text(i)).lower() ) {
 
366
                                        iScheme = i;
 
367
 
 
368
                                        int result = KMessageBox::warningContinueCancel( 0,
 
369
                                        i18n("A key scheme with the name '%1' already exists.\n"
 
370
                                                "Do you want to overwrite it?\n").arg(sName),
 
371
                                        i18n("Save key scheme"),
 
372
                                        i18n("Overwrite"));
 
373
                                        bNameValid = (result == KMessageBox::Continue);
 
374
                                }
 
375
                        }
 
376
                } else
 
377
                        return;
 
378
        } while( !bNameValid );
 
379
 
 
380
        disconnect( m_pcbSchemes, SIGNAL(activated(int)), this, SLOT(slotSelectScheme(int)) );
 
381
 
 
382
        QString kksPath = KGlobal::dirs()->saveLocation( "data", "kcmkeys/" );
 
383
 
 
384
        QDir dir( kksPath );
 
385
        if( !dir.exists() && !dir.mkdir( kksPath ) ) {
 
386
                qWarning("KShortcutsModule: Could not make directory to store user info.");
 
387
                return;
 
388
        }
 
389
 
 
390
        sFile.prepend( kksPath );
 
391
        sFile += ".kksrc";
 
392
        if( iScheme == -1 ) {
 
393
                m_pcbSchemes->insertItem( sName );
 
394
                //m_pcbSchemes->setFocus();
 
395
                m_pcbSchemes->setCurrentItem( m_pcbSchemes->count()-1 );
 
396
                m_rgsSchemeFiles.append( sFile );
 
397
        } else {
 
398
                //m_pcbSchemes->setFocus();
 
399
                m_pcbSchemes->setCurrentItem( iScheme );
 
400
        }
 
401
 
 
402
        KSimpleConfig *config = new KSimpleConfig( sFile );
 
403
 
 
404
        config->setGroup( "Settings" );
 
405
        config->writeEntry( "Name", sName );
 
406
        delete config;
 
407
 
 
408
        saveScheme();
 
409
 
 
410
        connect( m_pcbSchemes, SIGNAL(activated(int)), SLOT(slotSelectScheme(int)) );
 
411
        slotSelectScheme();
 
412
}
 
413
 
 
414
void ShortcutsModule::saveScheme()
 
415
{
 
416
        QString sFilename = m_rgsSchemeFiles[ m_pcbSchemes->currentItem() ];
 
417
        KSimpleConfig config( sFilename );
 
418
 
 
419
        m_pkcGeneral->commitChanges();
 
420
        m_pkcSequence->commitChanges();
 
421
        m_pkcApplication->commitChanges();
 
422
 
 
423
        m_pListGeneral->writeSettings( "Global Shortcuts", &config, true );
 
424
        m_pListSequence->writeSettings( "Global Shortcuts", &config, true );
 
425
        m_pListApplication->writeSettings( "Shortcuts", &config, true );
 
426
}
 
427
 
 
428
void ShortcutsModule::slotRemoveScheme()
 
429
{
 
430
}
 
431
 
 
432
#include "shortcuts.moc"