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

« back to all changes in this revision

Viewing changes to kcontrol/keys/keyconfig.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
// KDE Shortcut config module
 
3
//
 
4
// Copyright (c)  Mark Donohoe 1998
 
5
// Copyright (c)  Matthias Ettrich 1998
 
6
// Converted to generic key configuration module, Duncan Haldane 1998.
 
7
// Layout fixes copyright (c) 2000 Preston Brown <pbrown@kde.org>
 
8
 
 
9
#include <config.h>
 
10
#include <stdlib.h>
 
11
 
 
12
#include <unistd.h>
 
13
 
 
14
#include <qlabel.h>
 
15
#include <qdir.h>
 
16
#include <qlayout.h>
 
17
#include <qwhatsthis.h>
 
18
#include <qcheckbox.h>
 
19
#include <qregexp.h>
 
20
 
 
21
#include <kdebug.h>
 
22
#include <klocale.h>
 
23
#include <kstandarddirs.h>
 
24
#include <ksimpleconfig.h>
 
25
#include <kmessagebox.h>
 
26
#include <kseparator.h>
 
27
#include <dcopclient.h>
 
28
#include <kapplication.h>
 
29
#include <kkey_x11.h>   // Used in KKeyModule::init()
 
30
 
 
31
#include "keyconfig.h"
 
32
#include "keyconfig.moc"
 
33
 
 
34
#define KICKER_ALL_BINDINGS
 
35
 
 
36
//----------------------------------------------------------------------------
 
37
 
 
38
KKeyModule::KKeyModule( QWidget *parent, bool isGlobal, bool bSeriesOnly, bool bSeriesNone, const char *name )
 
39
  : QWidget( parent, name )
 
40
{
 
41
        init( isGlobal, bSeriesOnly, bSeriesNone );
 
42
}
 
43
 
 
44
KKeyModule::KKeyModule( QWidget *parent, bool isGlobal, const char *name )
 
45
  : QWidget( parent, name )
 
46
{
 
47
        init( isGlobal, false, false );
 
48
}
 
49
 
 
50
void KKeyModule::init( bool isGlobal, bool _bSeriesOnly, bool bSeriesNone )
 
51
{
 
52
  QString wtstr;
 
53
 
 
54
  KeyType = isGlobal ? "global" : "standard";
 
55
 
 
56
  bSeriesOnly = _bSeriesOnly;
 
57
 
 
58
  kdDebug(125) << "KKeyModule::init() - Get default key bindings." << endl;
 
59
  if ( KeyType == "global" ) {
 
60
    KAccelActions* keys = &actions;
 
61
// see also KKeyModule::init() below !!!
 
62
#define NOSLOTS
 
63
#define KShortcuts KAccelShortcuts
 
64
#include "../../kwin/kwinbindings.cpp"
 
65
#include "../../kicker/core/kickerbindings.cpp"
 
66
#include "../../kdesktop/kdesktopbindings.cpp"
 
67
#include "../../klipper/klipperbindings.cpp"
 
68
#include "../../kxkb/kxkbbindings.cpp"
 
69
#undef KShortcuts
 
70
    KeyScheme = "Global Key Scheme";
 
71
    KeySet    = "Global Keys";
 
72
    // Sorting Hack: I'll re-write the module once feature-adding begins again.
 
73
    if( bSeriesOnly || bSeriesNone ) {
 
74
        for( uint i = 0; i < actions.size(); i++ ) {
 
75
                QString sConfigKey = actions[i].m_sName;
 
76
                //kdDebug(125) << "sConfigKey: " << sConfigKey << endl;
 
77
                int iLastSpace = sConfigKey.findRev( ' ' );
 
78
                bool bIsNum = false;
 
79
                if( iLastSpace >= 0 )
 
80
                        sConfigKey.mid( iLastSpace+1 ).toInt( &bIsNum );
 
81
 
 
82
                kdDebug(125) << "sConfigKey: " << sConfigKey
 
83
                        << " bIsNum: " << bIsNum
 
84
                        << " bSeriesOnly: " << bSeriesOnly << endl;
 
85
                if( ((bSeriesOnly && !bIsNum) || (bSeriesNone && bIsNum)) && !sConfigKey.contains( ':' ) ) {
 
86
                        actions.removeAction( sConfigKey );
 
87
                        i--;
 
88
                }
 
89
        }
 
90
    }
 
91
  }
 
92
 
 
93
  if ( KeyType == "standard" ) {
 
94
    for(uint i=0; i<KStdAccel::NB_STD_ACCELS; i++) {
 
95
      KStdAccel::StdAccel id = (KStdAccel::StdAccel)i;
 
96
      actions.insertAction( KStdAccel::action(id),
 
97
                          KStdAccel::description(id),
 
98
                          KStdAccel::defaultKey3(id),
 
99
                          KStdAccel::defaultKey4(id) );
 
100
    }
 
101
 
 
102
    KeyScheme = "Standard Key Scheme";
 
103
    KeySet    = "Keys";
 
104
  }
 
105
 
 
106
  //kdDebug(125) << "KKeyModule::init() - Read current key bindings from config." << endl;
 
107
  //actions.readActions( KeySet );
 
108
 
 
109
  sFileList = new QStringList();
 
110
  sList = new QListBox( this );
 
111
 
 
112
  //readSchemeNames();
 
113
  sList->setCurrentItem( 0 );
 
114
  connect( sList, SIGNAL( highlighted( int ) ),
 
115
           SLOT( slotPreviewScheme( int ) ) );
 
116
 
 
117
  QLabel *label = new QLabel( sList, i18n("&Key Scheme"), this );
 
118
 
 
119
  wtstr = i18n("Here you can see a list of the existing key binding schemes with 'Current scheme'"
 
120
    " referring to the settings you are using right now. Select a scheme to use, remove or"
 
121
    " change it.");
 
122
  QWhatsThis::add( label, wtstr );
 
123
  QWhatsThis::add( sList, wtstr );
 
124
 
 
125
  addBt = new QPushButton(  i18n("&Save Scheme..."), this );
 
126
  connect( addBt, SIGNAL( clicked() ), SLOT( slotAdd() ) );
 
127
  QWhatsThis::add(addBt, i18n("Click here to add a new key bindings scheme. You will be prompted for a name."));
 
128
 
 
129
  removeBt = new QPushButton(  i18n("&Remove Scheme"), this );
 
130
  removeBt->setEnabled(FALSE);
 
131
  connect( removeBt, SIGNAL( clicked() ), SLOT( slotRemove() ) );
 
132
  QWhatsThis::add( removeBt, i18n("Click here to remove the selected key bindings scheme. You can not"
 
133
    " remove the standard system wide schemes, 'Current scheme' and 'KDE default'.") );
 
134
 
 
135
  // Hack to get this setting only displayed once.  It belongs in main.cpp instead.
 
136
  // That move will take a lot of UI redesigning, though, so i'll do it once CVS
 
137
  //  opens up for feature commits again. -- ellis
 
138
  /* Needed to remove because this depended upon non-BC changes in KeyEntry.*/
 
139
  // If this is the "Global Keys" section of the KDE Control Center:
 
140
  if( isGlobal && !bSeriesOnly ) {
 
141
        preferMetaBt = new QCheckBox( i18n("Prefer 4-modifier defaults"), this );
 
142
        if( !KKeySequence::keyboardHasMetaKey() )
 
143
                preferMetaBt->setEnabled( false );
 
144
        preferMetaBt->setChecked( KKeySequence::useFourModifierKeys() );
 
145
        connect( preferMetaBt, SIGNAL(clicked()), SLOT(slotPreferMeta()) );
 
146
        QWhatsThis::add( preferMetaBt, i18n("If your keyboard has a Meta key, but you would "
 
147
                "like KDE to prefer the 3-modifier configuration defaults, then this option "
 
148
                "should be unchecked.") );
 
149
  } else
 
150
        preferMetaBt = 0;
 
151
 
 
152
  KSeparator* line = new KSeparator( KSeparator::HLine, this );
 
153
 
 
154
  kc = new KeyChooserSpec( actions, this, isGlobal );
 
155
  connect( kc, SIGNAL(keyChange()), this, SLOT(slotKeyChange()) );
 
156
 
 
157
  readScheme();
 
158
 
 
159
  QGridLayout *topLayout = new QGridLayout( this, 6, 2,
 
160
                                            KDialog::marginHint(),
 
161
                                            KDialog::spacingHint());
 
162
  topLayout->addWidget(label, 0, 0);
 
163
  topLayout->addMultiCellWidget(sList, 1, 2, 0, 0);
 
164
  topLayout->addWidget(addBt, 1, 1);
 
165
  topLayout->addWidget(removeBt, 2, 1);
 
166
  if( preferMetaBt )
 
167
    topLayout->addWidget(preferMetaBt, 3, 0);
 
168
  topLayout->addMultiCellWidget(line, 4, 4, 0, 1);
 
169
  topLayout->addRowSpacing(3, 15);
 
170
  topLayout->addMultiCellWidget(kc, 5, 5, 0, 1);
 
171
 
 
172
  setMinimumSize(topLayout->sizeHint());
 
173
}
 
174
 
 
175
KKeyModule::~KKeyModule (){
 
176
  //kdDebug() << "KKeyModule destructor" << endl;
 
177
    delete kc;
 
178
    delete sFileList;
 
179
}
 
180
 
 
181
bool KKeyModule::writeSettings( const QString& sGroup, KConfig* pConfig )
 
182
{
 
183
        kc->commitChanges();
 
184
        actions.writeActions( sGroup, pConfig, true, false );
 
185
        return true;
 
186
}
 
187
 
 
188
bool KKeyModule::writeSettingsGlobal( const QString& sGroup )
 
189
{
 
190
        kc->commitChanges();
 
191
        actions.writeActions( sGroup, 0, true, true );
 
192
        return true;
 
193
}
 
194
 
 
195
void KKeyModule::load()
 
196
{
 
197
  kc->listSync();
 
198
}
 
199
 
 
200
/*void KKeyModule::save()
 
201
{
 
202
  if( preferMetaBt )
 
203
    KKeySequence::useFourModifierKeys( preferMetaBt->isChecked() );
 
204
 
 
205
  kc->commitChanges();
 
206
  actions.writeActions( KeySet, 0, true, true );
 
207
  if ( KeyType == "global" ) {
 
208
    if ( !kapp->dcopClient()->isAttached() )
 
209
      kapp->dcopClient()->attach();
 
210
    // TODO: create a reconfigureKeys() method.
 
211
    kapp->dcopClient()->send("kwin", "", "reconfigure()", "");
 
212
    kapp->dcopClient()->send("kdesktop", "", "configure()", "");
 
213
    kapp->dcopClient()->send("kicker", "Panel", "configure()", "");
 
214
  }
 
215
}*/
 
216
 
 
217
void KKeyModule::defaults()
 
218
{
 
219
  if( preferMetaBt )
 
220
    preferMetaBt->setChecked( false );
 
221
  KKeySequence::useFourModifierKeys( false );
 
222
  kc->allDefault();
 
223
}
 
224
 
 
225
/*void KKeyModule::slotRemove()
 
226
{
 
227
  QString kksPath =
 
228
        KGlobal::dirs()->saveLocation("data", "kcmkeys/" + KeyType);
 
229
 
 
230
  QDir d( kksPath );
 
231
  if (!d.exists()) // what can we do?
 
232
    return;
 
233
 
 
234
  d.setFilter( QDir::Files );
 
235
  d.setSorting( QDir::Name );
 
236
  d.setNameFilter("*.kksrc");
 
237
 
 
238
  uint ind = sList->currentItem();
 
239
 
 
240
  if ( !d.remove( *sFileList->at( ind ) ) ) {
 
241
    KMessageBox::sorry( 0,
 
242
                        i18n("This key scheme could not be removed.\n"
 
243
                             "Perhaps you do not have permission to alter the file "
 
244
                             "system where the key scheme is stored." ));
 
245
    return;
 
246
  }
 
247
 
 
248
  sList->removeItem( ind );
 
249
  sFileList->remove( sFileList->at(ind) );
 
250
}*/
 
251
 
 
252
void KKeyModule::slotKeyChange()
 
253
{
 
254
        emit keyChange();
 
255
        //emit keysChanged( &dict );
 
256
}
 
257
 
 
258
/*void KKeyModule::slotSave( )
 
259
{
 
260
    KSimpleConfig config(*sFileList->at( sList->currentItem() ) );
 
261
    //  global=true is necessary in order to
 
262
    //  let both 'Global Shortcuts' and 'Shortcut Sequences' be
 
263
    //  written to the same scheme file.
 
264
    kc->commitChanges();
 
265
    actions.writeActions( KeyScheme, &config, KeyType == "global", KeyType == "global" );
 
266
}*/
 
267
 
 
268
void KKeyModule::slotPreferMeta()
 
269
{
 
270
        kc->setPreferFourModifierKeys( preferMetaBt->isChecked() );
 
271
}
 
272
 
 
273
void KKeyModule::readScheme( int index )
 
274
{
 
275
  kdDebug(125) << "readScheme( " << index << " )\n";
 
276
  if( index == 1 )
 
277
    kc->allDefault( false );
 
278
  //else if( index == 2 )
 
279
  //  kc->allDefault( true );
 
280
  else {
 
281
    KConfigBase* config = 0;
 
282
    if( index == 0 )    config = new KConfig( "kdeglobals" );
 
283
    //else              config = new KSimpleConfig( *sFileList->at( index ), true );
 
284
 
 
285
    actions.readActions( (index == 0) ? KeySet : KeyScheme, config );
 
286
    kc->listSync();
 
287
    delete config;
 
288
  }
 
289
}
 
290
 
 
291
/*void KKeyModule::slotAdd()
 
292
{
 
293
  QString sName;
 
294
 
 
295
  if ( sList->currentItem() >= nSysSchemes )
 
296
     sName = sList->currentText();
 
297
  SaveScm ss( 0,  "save scheme", sName );
 
298
 
 
299
  bool nameValid;
 
300
  QString sFile;
 
301
  int exists = -1;
 
302
 
 
303
  do {
 
304
 
 
305
    nameValid = TRUE;
 
306
 
 
307
    if ( ss.exec() ) {
 
308
      sName = ss.nameLine->text();
 
309
      if ( sName.stripWhiteSpace().isEmpty() )
 
310
        return;
 
311
 
 
312
      sName = sName.simplifyWhiteSpace();
 
313
      sFile = sName;
 
314
 
 
315
      int ind = 0;
 
316
      while ( ind < (int) sFile.length() ) {
 
317
 
 
318
        // parse the string for first white space
 
319
 
 
320
        ind = sFile.find(" ");
 
321
        if (ind == -1) {
 
322
          ind = sFile.length();
 
323
          break;
 
324
        }
 
325
 
 
326
        // remove from string
 
327
 
 
328
        sFile.remove( ind, 1);
 
329
 
 
330
        // Make the next letter upper case
 
331
 
 
332
        QString s = sFile.mid( ind, 1 );
 
333
        s = s.upper();
 
334
        sFile.replace( ind, 1, s );
 
335
 
 
336
      }
 
337
 
 
338
      exists = -1;
 
339
      for ( int i = 0; i < (int) sList->count(); i++ ) {
 
340
        if ( sName.lower() == (sList->text(i)).lower() ) {
 
341
          exists = i;
 
342
 
 
343
          int result = KMessageBox::warningContinueCancel( 0,
 
344
               i18n("A key scheme with the name '%1' already exists.\n"
 
345
                    "Do you want to overwrite it?\n").arg(sName),
 
346
                   i18n("Save Key Scheme"),
 
347
                   i18n("Overwrite"));
 
348
          if (result == KMessageBox::Continue)
 
349
             nameValid = true;
 
350
          else
 
351
             nameValid = false;
 
352
        }
 
353
      }
 
354
    } else return;
 
355
 
 
356
  } while ( nameValid == FALSE );
 
357
 
 
358
  disconnect( sList, SIGNAL( highlighted( int ) ), this,
 
359
              SLOT( slotPreviewScheme( int ) ) );
 
360
 
 
361
 
 
362
  QString kksPath = KGlobal::dirs()->saveLocation("data", "kcmkeys/");
 
363
 
 
364
  QDir d( kksPath );
 
365
  if ( !d.exists() )
 
366
    if ( !d.mkdir( kksPath ) ) {
 
367
      qWarning("KKeyModule: Could not make directory to store user info.");
 
368
      return;
 
369
    }
 
370
 
 
371
  kksPath +=  KeyType ;
 
372
  kksPath += "/";
 
373
 
 
374
  d.setPath( kksPath );
 
375
  if ( !d.exists() )
 
376
    if ( !d.mkdir( kksPath ) ) {
 
377
      qWarning("KKeyModule: Could not make directory to store user info.");
 
378
      return;
 
379
    }
 
380
 
 
381
  sFile.prepend( kksPath );
 
382
  sFile += ".kksrc";
 
383
  if (exists == -1)
 
384
  {
 
385
     sList->insertItem( sName );
 
386
     sList->setFocus();
 
387
     sList->setCurrentItem( sList->count()-1 );
 
388
     sFileList->append( sFile );
 
389
  }
 
390
  else
 
391
  {
 
392
     sList->setFocus();
 
393
     sList->setCurrentItem( exists );
 
394
  }
 
395
 
 
396
  KSimpleConfig *config =
 
397
    new KSimpleConfig( sFile );
 
398
 
 
399
  config->setGroup( KeyScheme );
 
400
  config->writeEntry( "Name", sName );
 
401
  delete config;
 
402
 
 
403
  slotSave();
 
404
 
 
405
  connect( sList, SIGNAL( highlighted( int ) ), this,
 
406
           SLOT( slotPreviewScheme( int ) ) );
 
407
 
 
408
  slotPreviewScheme( sList->currentItem() );
 
409
}*/
 
410
 
 
411
/*void KKeyModule::slotPreviewScheme( int indx )
 
412
{
 
413
  readScheme( indx );
 
414
 
 
415
  // Set various appropriate for the scheme
 
416
 
 
417
  if ( indx < nSysSchemes ||
 
418
       (*sFileList->at(indx)).contains( "/global-" ) ||
 
419
       (*sFileList->at(indx)).contains( "/app-" ) ) {
 
420
    removeBt->setEnabled( FALSE );
 
421
  } else {
 
422
    removeBt->setEnabled( TRUE );
 
423
  }
 
424
}*/
 
425
 
 
426
/*void KKeyModule::readSchemeNames( )
 
427
{
 
428
  QStringList schemes = KGlobal::dirs()->findAllResources("data", "kcmkeys/" + KeyType + "/*.kksrc");
 
429
  //QRegExp r( "-kde[34].kksrc$" );
 
430
  QRegExp r( "-kde3.kksrc$" );
 
431
 
 
432
  sList->clear();
 
433
  sFileList->clear();
 
434
  sList->insertItem( i18n("Current Scheme"), 0 );
 
435
  sFileList->append( "Not a kcsrc file" );
 
436
  sList->insertItem( i18n("KDE Traditional"), 1 );
 
437
  sFileList->append( "Not a kcsrc file" );
 
438
  //sList->insertItem( i18n("KDE Extended (With 'Win' Key)"), 2 );
 
439
  //sList->insertItem( i18n("KDE Default for 4 Modifiers (Meta/Alt/Ctrl/Shift)"), 2 );
 
440
  //sFileList->append( "Not a kcsrc file" );
 
441
  nSysSchemes = 2;
 
442
 
 
443
  // This for system files
 
444
  for ( QStringList::ConstIterator it = schemes.begin(); it != schemes.end(); it++) {
 
445
    // KPersonalizer relies on .kksrc files containing all the keyboard shortcut
 
446
    //  schemes for various setups.  It also requires the KDE defaults to be in
 
447
    //  a .kksrc file.  The KDE defaults shouldn't be listed here.
 
448
    //if( r.search( *it ) != -1 )
 
449
    //   continue;
 
450
 
 
451
    KSimpleConfig config( *it, true );
 
452
    // TODO: Put 'Name' in "Settings" group
 
453
    config.setGroup( KeyScheme );
 
454
    QString str = config.readEntry( "Name" );
 
455
 
 
456
    sList->insertItem( str );
 
457
    sFileList->append( *it );
 
458
  }
 
459
}*/
 
460
 
 
461
/*void KKeyModule::updateKeys( const KAccelActions* map_P )
 
462
    {
 
463
    kc->updateKeys( map_P );
 
464
    }*/
 
465
 
 
466
// write all the global keys to kdeglobals
 
467
// this is needed to be able to check for conflicts with global keys in app's keyconfig
 
468
// dialogs, kdeglobals is empty as long as you don't apply any change in controlcenter/keys
 
469
void KKeyModule::init()
 
470
{
 
471
  kdDebug(125) << "KKeyModule::init()\n";
 
472
 
 
473
  /*kdDebug(125) << "KKeyModule::init() - Initialize # Modifier Keys Settings\n";
 
474
  KConfigGroupSaver cgs( KGlobal::config(), "Keyboard" );
 
475
  QString fourMods = KGlobal::config()->readEntry( "Use Four Modifier Keys", KAccel::keyboardHasMetaKey() ? "true" : "false" );
 
476
  KAccel::useFourModifierKeys( fourMods == "true" );
 
477
  bool bUseFourModifierKeys = KAccel::useFourModifierKeys();
 
478
  KGlobal::config()->writeEntry( "User Four Modifier Keys", bUseFourModifierKeys ? "true" : "false", true, true );
 
479
  */
 
480
  KAccelActions* keys = new KAccelActions();
 
481
 
 
482
  kdDebug(125) << "KKeyModule::init() - Load Included Bindings\n";
 
483
// this should match the included files above
 
484
#define NOSLOTS
 
485
#define KShortcuts KAccelShortcuts
 
486
#include "../../klipper/klipperbindings.cpp"
 
487
#include "../../kwin/kwinbindings.cpp"
 
488
#include "../../kicker/core/kickerbindings.cpp"
 
489
#include "../../kdesktop/kdesktopbindings.cpp"
 
490
#include "../../kxkb/kxkbbindings.cpp"
 
491
#undef KShortcuts
 
492
 
 
493
  kdDebug(125) << "KKeyModule::init() - Read Config Bindings\n";
 
494
  keys->readActions( "Global Keys" );
 
495
 
 
496
  {
 
497
    KSimpleConfig cfg( "kdeglobals" );
 
498
    cfg.deleteGroup( "Global Keys" );
 
499
  }
 
500
 
 
501
  kdDebug(125) << "KKeyModule::init() - Write Config Bindings\n";
 
502
  keys->writeActions( "Global Keys", 0, true, true );
 
503
}
 
504
 
 
505
//-----------------------------------------------------------------
 
506
// KeyChooserSpec
 
507
//-----------------------------------------------------------------
 
508
 
 
509
KeyChooserSpec::KeyChooserSpec( KAccelActions& actions, QWidget* parent, bool bGlobal )
 
510
    : KKeyChooser( actions, parent, bGlobal, false, true ), m_bGlobal( bGlobal )
 
511
    {
 
512
    //if( global )
 
513
    //    globalDict()->clear(); // don't check against global keys twice
 
514
    }
 
515
 
 
516
/*void KeyChooserSpec::updateKeys( const KAccelActions* map_P )
 
517
    {
 
518
    if( global )
 
519
        {
 
520
        stdDict()->clear();
 
521
        for( KAccelActions::ConstIterator gIt( map_P->begin());
 
522
             gIt != map_P->end();
 
523
             ++gIt )
 
524
            {
 
525
            int* keyCode = new int;
 
526
            *keyCode = ( *gIt ).aConfigKeyCode;
 
527
            stdDict()->insert( gIt.key(), keyCode);
 
528
            }
 
529
        }
 
530
    else
 
531
        {
 
532
        globalDict()->clear();
 
533
        for( KAccelActions::ConstIterator gIt( map_P->begin());
 
534
             gIt != map_P->end();
 
535
             ++gIt )
 
536
            {
 
537
            int* keyCode = new int;
 
538
            *keyCode = ( *gIt ).aConfigKeyCode;
 
539
            globalDict()->insert( gIt.key(), keyCode);
 
540
            }
 
541
        }
 
542
    }
 
543
*/