• Skip to content
  • Skip to link menu
Trinity API Reference
  • Trinity API Reference
  • tdeui
 

tdeui

  • tdeui
tdeshortcutdialog.cpp
1/* This file is part of the KDE libraries
2 Copyright (C) 2002,2003 Ellis Whitehead <ellis@kde.org>
3
4 This library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public
6 License as published by the Free Software Foundation; either
7 version 2 of the License, or (at your option) any later version.
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 "tdeshortcutdialog.h"
21
22#include <tqvariant.h>
23
24#ifdef TQ_WS_X11
25 #define XK_XKB_KEYS
26 #define XK_MISCELLANY
27 #include <X11/Xlib.h> // For x11Event()
28 #include <X11/keysymdef.h> // For XK_...
29
30 #ifdef KeyPress
31 const int XKeyPress = KeyPress;
32 const int XKeyRelease = KeyRelease;
33 const int XFocusOut = FocusOut;
34 const int XFocusIn = FocusIn;
35 #undef KeyRelease
36 #undef KeyPress
37 #undef FocusOut
38 #undef FocusIn
39 #endif
40#elif defined(TQ_WS_WIN)
41# include <kkeyserver.h>
42#endif
43
44#include <tdeshortcutdialog_simple.h>
45#include <tdeshortcutdialog_advanced.h>
46
47#include <tqbuttongroup.h>
48#include <tqcheckbox.h>
49#include <tqframe.h>
50#include <tqlayout.h>
51#include <tqradiobutton.h>
52#include <tqtimer.h>
53#include <tqvbox.h>
54
55#include <tdeapplication.h>
56#include <tdeconfig.h>
57#include <kdebug.h>
58#include <tdeglobal.h>
59#include <kiconloader.h>
60#include <kkeynative.h>
61#include <tdelocale.h>
62#include <kstdguiitem.h>
63#include <kpushbutton.h>
64
65bool TDEShortcutDialog::s_showMore = false;
66
67TDEShortcutDialog::TDEShortcutDialog( const TDEShortcut& shortcut, bool bQtShortcut, TQWidget* parent, const char* name )
68: KDialogBase( parent, name, true, i18n("Configure Shortcut"),
69 KDialogBase::Details|KDialogBase::Ok|KDialogBase::Cancel, KDialogBase::Cancel, true )
70{
71 setButtonText(Details, i18n("Advanced"));
72 m_stack = new TQVBox(this);
73 m_stack->setMinimumWidth(360);
74 m_stack->setSpacing(0);
75 m_stack->setMargin(0);
76 setMainWidget(m_stack);
77
78 m_simple = new TDEShortcutDialogSimple(m_stack);
79
80 m_adv = new TDEShortcutDialogAdvanced(m_stack);
81 m_adv->hide();
82
83 m_bQtShortcut = bQtShortcut;
84
85 m_iSeq = 0;
86 m_iKey = 0;
87 m_ptxtCurrent = 0;
88 m_bRecording = false;
89 m_mod = 0;
90
91 m_simple->m_btnClearShortcut->setPixmap( SmallIcon( "locationbar_erase" ) );
92 m_adv->m_btnClearPrimary->setPixmap( SmallIcon( "locationbar_erase" ) );
93 m_adv->m_btnClearAlternate->setPixmap( SmallIcon( "locationbar_erase" ) );
94 connect(m_simple->m_btnClearShortcut, TQ_SIGNAL(clicked()),
95 this, TQ_SLOT(slotClearShortcut()));
96 connect(m_adv->m_btnClearPrimary, TQ_SIGNAL(clicked()),
97 this, TQ_SLOT(slotClearPrimary()));
98 connect(m_adv->m_btnClearAlternate, TQ_SIGNAL(clicked()),
99 this, TQ_SLOT(slotClearAlternate()));
100
101 connect(m_adv->m_txtPrimary, TQ_SIGNAL(clicked()),
102 m_adv->m_btnPrimary, TQ_SLOT(animateClick()));
103 connect(m_adv->m_txtAlternate, TQ_SIGNAL(clicked()),
104 m_adv->m_btnAlternate, TQ_SLOT(animateClick()));
105 connect(m_adv->m_btnPrimary, TQ_SIGNAL(clicked()),
106 this, TQ_SLOT(slotSelectPrimary()));
107 connect(m_adv->m_btnAlternate, TQ_SIGNAL(clicked()),
108 this, TQ_SLOT(slotSelectAlternate()));
109
110 KGuiItem ok = KStdGuiItem::ok();
111 ok.setText( i18n( "OK" ) );
112 setButtonOK( ok );
113
114 KGuiItem cancel = KStdGuiItem::cancel();
115 cancel.setText( i18n( "Cancel" ) );
116 setButtonCancel( cancel );
117
118 setShortcut( shortcut );
119 resize( 0, 0 );
120
121 s_showMore = TDEConfigGroup(TDEGlobal::config(), "General").readBoolEntry("ShowAlternativeShortcutConfig", s_showMore);
122 updateDetails();
123
124 #ifdef TQ_WS_X11
125 tdeApp->installX11EventFilter( this ); // Allow button to capture X Key Events.
126 #endif
127}
128
129TDEShortcutDialog::~TDEShortcutDialog()
130{
131 TDEConfigGroup group(TDEGlobal::config(), "General");
132 group.writeEntry("ShowAlternativeShortcutConfig", s_showMore);
133}
134
135void TDEShortcutDialog::setShortcut( const TDEShortcut & shortcut )
136{
137 m_shortcut = shortcut;
138 updateShortcutDisplay();
139}
140
141void TDEShortcutDialog::updateShortcutDisplay()
142{
143 TQString s[2] = { m_shortcut.seq(0).toString(), m_shortcut.seq(1).toString() };
144
145 if( m_bRecording ) {
146 m_ptxtCurrent->setDefault( true );
147 m_ptxtCurrent->setFocus();
148
149 // Display modifiers for the first key in the KKeySequence
150 if( m_iKey == 0 ) {
151 if( m_mod ) {
152 TQString keyModStr;
153 if( m_mod & KKey::WIN ) keyModStr += KKey::modFlagLabel(KKey::WIN) + "+";
154 if( m_mod & KKey::ALT ) keyModStr += KKey::modFlagLabel(KKey::ALT) + "+";
155 if( m_mod & KKey::CTRL ) keyModStr += KKey::modFlagLabel(KKey::CTRL) + "+";
156 if( m_mod & KKey::SHIFT ) keyModStr += KKey::modFlagLabel(KKey::SHIFT) + "+";
157 s[m_iSeq] = keyModStr;
158 }
159 }
160 // When in the middle of entering multi-key shortcuts,
161 // add a "," to the end of the displayed shortcut.
162 else
163 s[m_iSeq] += ",";
164 }
165 else {
166 m_adv->m_txtPrimary->setDefault( false );
167 m_adv->m_txtAlternate->setDefault( false );
168 this->setFocus();
169 }
170
171 s[0].replace('&', TQString::fromLatin1("&&"));
172 s[1].replace('&', TQString::fromLatin1("&&"));
173
174 m_simple->m_txtShortcut->setText( s[0] );
175 m_adv->m_txtPrimary->setText( s[0] );
176 m_adv->m_txtAlternate->setText( s[1] );
177
178 // Determine the enable state of the 'Less' button
179 bool bLessOk;
180 // If there is no shortcut defined,
181 if( m_shortcut.count() == 0 )
182 bLessOk = true;
183 // If there is a single shortcut defined, and it is not a multi-key shortcut,
184 else if( m_shortcut.count() == 1 && m_shortcut.seq(0).count() <= 1 )
185 bLessOk = true;
186 // Otherwise, we have an alternate shortcut or multi-key shortcut(s).
187 else
188 bLessOk = false;
189 enableButton(Details, bLessOk);
190}
191
192void TDEShortcutDialog::slotDetails()
193{
194 s_showMore = (m_adv->isHidden());
195 updateDetails();
196}
197
198void TDEShortcutDialog::updateDetails()
199{
200 bool showAdvanced = s_showMore || (m_shortcut.count() > 1);
201 setDetails(showAdvanced);
202 m_bRecording = false;
203 m_iSeq = 0;
204 m_iKey = 0;
205
206 if (showAdvanced)
207 {
208 m_simple->hide();
209 m_adv->show();
210 m_adv->m_btnPrimary->setChecked( true );
211 slotSelectPrimary();
212 }
213 else
214 {
215 m_ptxtCurrent = m_simple->m_txtShortcut;
216 m_adv->hide();
217 m_simple->show();
218 m_simple->m_txtShortcut->setDefault( true );
219 m_simple->m_txtShortcut->setFocus();
220 m_adv->m_btnMultiKey->setChecked( false );
221 }
222 tdeApp->processEvents();
223 adjustSize();
224}
225
226void TDEShortcutDialog::slotSelectPrimary()
227{
228 m_bRecording = false;
229 m_iSeq = 0;
230 m_iKey = 0;
231 m_ptxtCurrent = m_adv->m_txtPrimary;
232 m_ptxtCurrent->setDefault(true);
233 m_ptxtCurrent->setFocus();
234 updateShortcutDisplay();
235}
236
237void TDEShortcutDialog::slotSelectAlternate()
238{
239 m_bRecording = false;
240 m_iSeq = 1;
241 m_iKey = 0;
242 m_ptxtCurrent = m_adv->m_txtAlternate;
243 m_ptxtCurrent->setDefault(true);
244 m_ptxtCurrent->setFocus();
245 updateShortcutDisplay();
246}
247
248void TDEShortcutDialog::slotClearShortcut()
249{
250 m_shortcut.setSeq( 0, KKeySequence() );
251 updateShortcutDisplay();
252}
253
254void TDEShortcutDialog::slotClearPrimary()
255{
256 m_shortcut.setSeq( 0, KKeySequence() );
257 m_adv->m_btnPrimary->setChecked( true );
258 slotSelectPrimary();
259}
260
261void TDEShortcutDialog::slotClearAlternate()
262{
263 if( m_shortcut.count() == 2 )
264 m_shortcut.init( m_shortcut.seq(0) );
265 m_adv->m_btnAlternate->setChecked( true );
266 slotSelectAlternate();
267}
268
269void TDEShortcutDialog::slotMultiKeyMode( bool bOn )
270{
271 // If turning off multi-key mode during a recording,
272 if( !bOn && m_bRecording ) {
273 m_bRecording = false;
274 m_iKey = 0;
275 updateShortcutDisplay();
276 }
277}
278
279#ifdef TQ_WS_X11
280/* we don't use the generic Qt code on X11 because it allows us
281 to grab the keyboard so that all keypresses are seen
282 */
283bool TDEShortcutDialog::x11Event( XEvent *pEvent )
284{
285 switch( pEvent->type ) {
286 case XKeyPress:
287 x11KeyPressEvent( pEvent );
288 return true;
289 case XKeyRelease:
290 x11KeyReleaseEvent( pEvent );
291 return true;
292 case XFocusIn:
293 {
294 XFocusInEvent *fie = (XFocusInEvent*)pEvent;
295 if (fie->mode != NotifyGrab && fie->mode != NotifyUngrab) {
296 grabKeyboard();
297 }
298 }
299 break;
300 case XFocusOut:
301 {
302 XFocusOutEvent *foe = (XFocusOutEvent*)pEvent;
303 if (foe->mode != NotifyGrab && foe->mode != NotifyUngrab) {
304 releaseKeyboard();
305 }
306 }
307 break;
308 default:
309 //kdDebug(125) << "x11Event->type = " << pEvent->type << endl;
310 break;
311 }
312 return KDialogBase::x11Event( pEvent );
313}
314
315static uint getModsFromModX( uint keyModX )
316{
317 uint mod = 0;
318 if( keyModX & KKeyNative::modX(KKey::SHIFT) ) mod += KKey::SHIFT;
319 if( keyModX & KKeyNative::modX(KKey::CTRL) ) mod += KKey::CTRL;
320 if( keyModX & KKeyNative::modX(KKey::ALT) ) mod += KKey::ALT;
321 if( keyModX & KKeyNative::modX(KKey::WIN) ) mod += KKey::WIN;
322 return mod;
323}
324
325static bool convertSymXToMod( uint keySymX, uint* pmod )
326{
327 switch( keySymX ) {
328 // Don't allow setting a modifier key as an accelerator.
329 // Also, don't release the focus yet. We'll wait until
330 // we get a 'normal' key.
331 case XK_Shift_L: case XK_Shift_R: *pmod = KKey::SHIFT; break;
332 case XK_Control_L: case XK_Control_R: *pmod = KKey::CTRL; break;
333 case XK_Alt_L: case XK_Alt_R: *pmod = KKey::ALT; break;
334 // FIXME: check whether the Meta or Super key are for the Win modifier
335 case XK_Meta_L: case XK_Meta_R:
336 case XK_Super_L: case XK_Super_R: *pmod = KKey::WIN; break;
337 case XK_Hyper_L: case XK_Hyper_R:
338 case XK_Mode_switch:
339 case XK_Num_Lock:
340 case XK_Caps_Lock:
341 break;
342 default:
343 return false;
344 }
345 return true;
346}
347
348void TDEShortcutDialog::x11KeyPressEvent( XEvent* pEvent )
349{
350 KKeyNative keyNative( pEvent );
351 uint keyModX = keyNative.mod();
352 uint keySymX = keyNative.sym();
353
354 m_mod = getModsFromModX( keyModX );
355
356 if( keySymX ) {
357 m_bRecording = true;
358
359 uint mod = 0;
360 if( convertSymXToMod( keySymX, &mod ) ) {
361 if( mod )
362 m_mod |= mod;
363 }
364 else
365 keyPressed( KKey(keyNative) );
366 }
367 updateShortcutDisplay();
368}
369
370void TDEShortcutDialog::x11KeyReleaseEvent( XEvent* pEvent )
371{
372 // We're only interested in the release of modifier keys,
373 // and then only when it's for the first key in a sequence.
374 if( m_bRecording && m_iKey == 0 ) {
375 KKeyNative keyNative( pEvent );
376 uint keyModX = keyNative.mod();
377 uint keySymX = keyNative.sym();
378
379 m_mod = getModsFromModX( keyModX );
380
381 uint mod = 0;
382 if( convertSymXToMod( keySymX, &mod ) && mod ) {
383 m_mod &= ~mod;
384 if( !m_mod )
385 m_bRecording = false;
386 }
387 updateShortcutDisplay();
388 }
389}
390#elif defined(TQ_WS_WIN)
391void TDEShortcutDialog::keyPressEvent( TQKeyEvent * e )
392{
393 kdDebug() << e->text() << " " << (int)e->text()[0].latin1()<< " " << (int)e->ascii() << endl;
394 //if key is a letter, it must be stored as lowercase
395 int keyQt = TQChar( e->key() & 0xff ).isLetter() ?
396 (TQChar( e->key() & 0xff ).lower().latin1() | (e->key() & 0xffff00) )
397 : e->key();
398 int modQt = KKeyServer::qtButtonStateToMod( e->state() );
399 KKeyNative keyNative( KKey(keyQt, modQt) );
400 m_mod = keyNative.mod();
401 uint keySym = keyNative.sym();
402
403 switch( keySym ) {
404 case Key_Shift:
405 m_mod |= KKey::SHIFT;
406 m_bRecording = true;
407 break;
408 case Key_Control:
409 m_mod |= KKey::CTRL;
410 m_bRecording = true;
411 break;
412 case Key_Alt:
413 m_mod |= KKey::ALT;
414 m_bRecording = true;
415 break;
416 case Key_Menu:
417 case Key_Meta: //unused
418 break;
419 default:
420 if( keyNative.sym() == Key_Return && m_iKey > 0 ) {
421 accept();
422 return;
423 }
424 //accept
425 if (keyNative.sym()) {
426 KKey key = keyNative;
427 key.simplify();
428 KKeySequence seq;
429 if( m_iKey == 0 )
430 seq = key;
431 else {
432 seq = m_shortcut.seq( m_iSeq );
433 seq.setKey( m_iKey, key );
434 }
435 m_shortcut.setSeq( m_iSeq, seq );
436
437 if(m_adv->m_btnMultiKey->isChecked())
438 m_iKey++;
439
440 m_bRecording = true;
441
442 updateShortcutDisplay();
443
444 if( !m_adv->m_btnMultiKey->isChecked() )
445 TQTimer::singleShot(500, this, TQ_SLOT(accept()));
446 }
447 return;
448 }
449
450 // If we are editing the first key in the sequence,
451 // display modifier keys which are held down
452 if( m_iKey == 0 ) {
453 updateShortcutDisplay();
454 }
455}
456
457bool TDEShortcutDialog::event ( TQEvent * e )
458{
459 if (e->type()==TQEvent::KeyRelease) {
460 int modQt = KKeyServer::qtButtonStateToMod( static_cast<TQKeyEvent*>(e)->state() );
461 KKeyNative keyNative( KKey(static_cast<TQKeyEvent*>(e)->key(), modQt) );
462 uint keySym = keyNative.sym();
463
464 bool change = true;
465 switch( keySym ) {
466 case Key_Shift:
467 if (m_mod & KKey::SHIFT)
468 m_mod ^= KKey::SHIFT;
469 break;
470 case Key_Control:
471 if (m_mod & KKey::CTRL)
472 m_mod ^= KKey::CTRL;
473 break;
474 case Key_Alt:
475 if (m_mod & KKey::ALT)
476 m_mod ^= KKey::ALT;
477 break;
478 default:
479 change = false;
480 }
481 if (change)
482 updateShortcutDisplay();
483 }
484 return KDialogBase::event(e);
485}
486#endif
487
488void TDEShortcutDialog::keyPressed( KKey key )
489{
490 kdDebug(125) << "keyPressed: " << key.toString() << endl;
491
492 key.simplify();
493 if( m_bQtShortcut ) {
494 key = key.keyCodeQt();
495 if( key.isNull() ) {
496 // TODO: message box about key not able to be used as application shortcut
497 }
498 }
499
500 KKeySequence seq;
501 if( m_iKey == 0 )
502 seq = key;
503 else {
504 // Remove modifiers
505 key.init( key.sym(), 0 );
506 seq = m_shortcut.seq( m_iSeq );
507 seq.setKey( m_iKey, key );
508 }
509
510 m_shortcut.setSeq( m_iSeq, seq );
511
512 m_mod = 0;
513 if( m_adv->m_btnMultiKey->isChecked() && m_iKey < KKeySequence::MAX_KEYS - 1 )
514 m_iKey++;
515 else {
516 m_iKey = 0;
517 m_bRecording = false;
518 }
519
520 updateShortcutDisplay();
521
522 if( !m_adv->m_btnMultiKey->isChecked() )
523 TQTimer::singleShot(500, this, TQ_SLOT(accept()));
524}
525
526#include "tdeshortcutdialog.moc"
KDialogBase
A dialog base class with standard buttons and predefined layouts.
Definition: kdialogbase.h:192
KDialogBase::enableButton
void enableButton(ButtonCode id, bool state)
Enable or disable (gray out) a general action button.
Definition: kdialogbase.cpp:838
KDialogBase::Details
@ Details
Show Details button.
Definition: kdialogbase.h:211
KDialogBase::setDetails
void setDetails(bool showDetails)
Sets the status of the Details button.
Definition: kdialogbase.cpp:1127
KDialogBase::adjustSize
virtual void adjustSize()
Adjust the size of the dialog to fit the contents just before TQDialog::exec() or TQDialog::show() is...
Definition: kdialogbase.cpp:427
KDialogBase::keyPressEvent
virtual void keyPressEvent(TQKeyEvent *e)
Maps some keys to the actions buttons.
Definition: kdialogbase.cpp:1553
KGuiItem
An abstract class for GUI data such as ToolTip and Icon.
Definition: kguiitem.h:39
KKeyNative
KKeySequence
KKeySequence::setKey
bool setKey(uint i, const KKey &key)
KKeySequence::toString
TQString toString() const
KKeySequence::count
uint count() const
KKey
KKey::modFlagLabel
static TQString modFlagLabel(ModFlag f)
TDEConfigBase::readBoolEntry
bool readBoolEntry(const TQString &pKey, bool bDefault=false) const
TDEConfigGroup
TDEGlobal::config
static TDEConfig * config()
TDEShortcut
TDEShortcut::count
uint count() const
TDEShortcut::init
bool init(int keyQt)
TDEShortcut::seq
const KKeySequence & seq(uint i) const
TDEShortcut::setSeq
bool setSeq(uint i, const KKeySequence &keySeq)
endl
kndbgstream & endl(kndbgstream &s)
kdDebug
kdbgstream kdDebug(int area=0)
KKeyServer::qtButtonStateToMod
int qtButtonStateToMod(TQt::ButtonState s)
TDEStdAccel::key
int key(StdAccel id)
TDEStdAccel::name
TQString name(StdAccel id)
TDEStdAccel::shortcut
const TDEShortcut & shortcut(StdAccel id)
tdelocale.h

tdeui

Skip menu "tdeui"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

tdeui

Skip menu "tdeui"
  • arts
  • dcop
  • dnssd
  • interfaces
  •   kspeech
  •     interface
  •     library
  •   tdetexteditor
  • kate
  • kded
  • kdoctools
  • kimgio
  • kjs
  • libtdemid
  • libtdescreensaver
  • tdeabc
  • tdecmshell
  • tdecore
  • tdefx
  • tdehtml
  • tdeinit
  • tdeio
  •   bookmarks
  •   httpfilter
  •   kpasswdserver
  •   kssl
  •   tdefile
  •   tdeio
  •   tdeioexec
  • tdeioslave
  •   http
  • tdemdi
  •   tdemdi
  • tdenewstuff
  • tdeparts
  • tdeprint
  • tderandr
  • tderesources
  • tdespell2
  • tdesu
  • tdeui
  • tdeunittest
  • tdeutils
  • tdewallet
Generated for tdeui by doxygen 1.9.4
This website is maintained by Timothy Pearson.