2 * Copyright (c) 2004 Gunnar Schmi Dt <gunnar@schmi-dt.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program 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
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
18 #include <QtGui/QPainter>
19 #include <QtGui/qdrawutil.h>
20 #include <QtGui/QCursor>
21 #include <QtGui/QImage>
22 #include <QtGui/QMouseEvent>
23 #include <QtCore/QTimerEvent>
24 #include <QtGui/QResizeEvent>
25 #include <QtCore/QProcess>
26 #include <QtGui/QX11Info>
29 #include <kaboutapplicationdialog.h>
30 #include <kaboutdata.h>
33 #include <kglobalsettings.h>
34 #include <kcolorscheme.h>
35 #include <kapplication.h>
36 #include <kiconloader.h>
37 #include <kiconeffect.h>
38 #include <kshortcut.h>
39 #include <kdemacros.h>
40 #include <ktoolinvocation.h>
41 #include "kdeexportfix.h"
43 #include "kbstate.moc"
48 #include <X11/Xutil.h>
49 #include <X11/XKBlib.h>
52 #include <X11/keysymdef.h>
53 #include <X11/extensions/XKB.h>
55 KDE_EXPORT K3PanelApplet
* init(QWidget
*parent
, const QString
& configFile
)
57 KGlobal::locale()->insertCatalog("kbstateapplet");
58 KbStateApplet
*applet
= new KbStateApplet(configFile
, K3PanelApplet::Normal
, K3PanelApplet::About
, parent
, "kbstateapplet");
64 const unsigned int mask
;
69 const bool isModifier
;
72 static ModifierKey modifierKeys
[] = {
73 { ShiftMask
, 0, I18N_NOOP("Shift"), "shiftkey", "", true },
74 { ControlMask
, 0, I18N_NOOP("Control"), "controlkey", "", true },
75 { 0, XK_Alt_L
, I18N_NOOP("Alt"), "altkey", "", true },
76 { 0, 0, I18N_NOOP("Win"), "superkey", "", true },
77 { 0, XK_Meta_L
, I18N_NOOP("Meta"), "metakey", "", true },
78 { 0, XK_Super_L
, I18N_NOOP("Super"), "superkey", "", true },
79 { 0, XK_Hyper_L
, I18N_NOOP("Hyper"), "hyperkey", "", true },
80 { 0, 0, I18N_NOOP("Alt Graph"), "", I18N_NOOP("æ"), true },
81 { 0, XK_Num_Lock
, I18N_NOOP("Num Lock"), "lockkey", I18N_NOOP("Num"), false },
82 { LockMask
, 0, I18N_NOOP("Caps Lock"), "capskey", "", false },
83 { 0, XK_Scroll_Lock
, I18N_NOOP("Scroll Lock"), "lockkey", I18N_NOOP("Scroll"), false },
84 { 0, 0, "", "", "", false }
88 /********************************************************************/
90 KbStateApplet::KbStateApplet(const QString
& configFile
, K3PanelApplet::Type t
, int actions
,
91 QWidget
*parent
, const char *name
)
92 : K3PanelApplet( configFile
, t
, actions
, parent
),
93 componentData("kbstateapplet")
97 for (int i
= 0; i
< 8; i
++) {
100 m_iconLoader
= new KIconLoader(componentData
.componentName(), componentData
.dirs());
104 mouse
= new MouseIcon (m_iconLoader
, this, "mouse");
105 sticky
= new TimeoutIcon (m_iconLoader
, "", "kbstate_stickykeys", this, "sticky");
106 slow
= new TimeoutIcon (m_iconLoader
, "", "kbstate_slowkeys", this, "slow");
107 bounce
= new TimeoutIcon (m_iconLoader
, "", "", this, "bounce");
109 xkb
= XkbGetMap(QX11Info::display(), 0, XkbUseCoreKbd
);
112 XkbGetControls (QX11Info::display(), XkbAllControlsMask
, xkb
);
114 accessxFeatures
= xkb
->ctrls
->enabled_ctrls
;
121 //startTimer(100); // ten times a second
122 connect(KGlobalSettings::self(), SIGNAL(kdisplayPaletteChanged()), SLOT(paletteChanged()));
124 kapp
->installX11EventFilter (this);
125 int opcode_rtn
, error_rtn
;
126 XkbQueryExtension (QX11Info::display(), &opcode_rtn
, &xkb_base_event_type
, &error_rtn
, NULL
, NULL
);
127 XkbSelectEvents (QX11Info::display(), XkbUseCoreKbd
, XkbAllEventsMask
,
133 KbStateApplet::~KbStateApplet() {
134 kapp
->removeX11EventFilter (this);
140 // Builds, connects _popup menu
141 void KbStateApplet::buildPopupMenu()
143 sizePopup
=new KMenu(this);
144 sizePopup
->setCheckable( true );
145 sizePopup
->insertItem(i18n("Small"), 13);
146 sizePopup
->insertItem(i18n("Medium"), 20);
147 sizePopup
->insertItem(i18n("Large"), 26);
148 connect(sizePopup
,SIGNAL(activated(int)), this, SLOT(setIconDim(int)));
150 showPopup
=new KMenu(this);
151 showPopup
->setCheckable( true );
152 modifierItem
=showPopup
->insertItem(i18n("Modifier Keys"), this, SLOT(toggleModifier()));
153 lockkeysItem
=showPopup
->insertItem(i18n("Lock Keys"), this, SLOT(toggleLockkeys()));
154 mouseItem
=showPopup
->insertItem(i18n("Mouse Status"), this, SLOT(toggleMouse()));
155 accessxItem
=showPopup
->insertItem(i18n("AccessX Status"), this, SLOT(toggleAccessX()));
157 popup
= new KMenu(this);
158 popup
->setCheckable( true );
159 popup
->addTitle(i18n("Keyboard Status Applet"));
160 popup
->insertItem(i18n("Set Icon Size"),sizePopup
);
161 fillSpaceItem
= popup
->insertItem(i18n("Fill Available Space"),
162 this, SLOT(toggleFillSpace()));
163 popup
->insertItem(i18n("Show"),showPopup
);
164 popup
->addAction(i18n("Configure AccessX Features..."), this, SLOT(configureAccessX()));
165 popup
->addAction(i18n("Configure Keyboard..."), this, SLOT(configureKeyboard()));
166 popup
->addAction(i18n("Configure Mouse..."), this, SLOT(configureMouse()));
167 popup
->addSeparator();
168 popup
->addAction(i18n("About"), this, SLOT(about()));
169 setCustomMenu(popup
);
173 void KbStateApplet::updateMenu()
175 showPopup
->setItemChecked (modifierItem
, showModifiers
);
176 showPopup
->setItemChecked (lockkeysItem
, showLockkeys
);
177 showPopup
->setItemChecked (mouseItem
, showMouse
);
178 showPopup
->setItemChecked (accessxItem
, showAccessX
);
179 popup
->setItemChecked (fillSpaceItem
, fillSpace
);
180 sizePopup
->setItemChecked(13, size
== 13);
181 sizePopup
->setItemChecked(20, size
== 20);
182 sizePopup
->setItemChecked(26, size
== 26);
186 void calculateSizes (int space
, int modifiers
, int lockkeys
, int accessx
,
187 bool showMouse
, int &lines
, int &length
, int &size
)
188 // Calculates the layout based on a given number of modifiers, lockkeys and
191 // lines: number of lines
192 // length: number of icons per line
193 // size: size of the icons
195 // Calculate lines and length
199 lines
= space
>=size
? space
/size
: 1;
200 length
= modifiers
+ lockkeys
+ accessx
;
202 if (length
> 0 && lines
>= 2) {
203 length
= (length
+ lines
-1)/lines
;
205 // As we want to have some line breaks, we need to do some corrections:
206 // Calculate the number of lines that are really needed:
207 int linesNeeded
= (modifiers
+length
-1)/length
+ (lockkeys
+length
-1)/length
;
208 int tmp1
= modifiers
%length
== 0 ? 0 : length
- modifiers
%length
;
209 int tmp2
= lockkeys
%length
== 0 ? 0 : length
- lockkeys
%length
;
210 if ((tmp1
+ tmp2
) < accessx
)
211 linesNeeded
= (modifiers
+lockkeys
+accessx
+ length
-1)/length
;
213 // If we need more lines than we have, try with more icons per line:
214 while (linesNeeded
> lines
) {
216 linesNeeded
= (modifiers
+length
-1)/length
+ (lockkeys
+length
-1)/length
;
217 int tmp1
= modifiers
%length
== 0 ? 0 : length
- modifiers
%length
;
218 int tmp2
= lockkeys
%length
== 0 ? 0 : length
- lockkeys
%length
;
219 if ((tmp1
+ tmp2
) < accessx
)
220 linesNeeded
= (modifiers
+lockkeys
+accessx
+ length
-1)/length
;
226 int KbStateApplet::widthForHeight(int h
) const {
228 int size
= this->size
;
231 if ((accessxFeatures
& XkbStickyKeysMask
) != 0)
233 if ((accessxFeatures
& XkbSlowKeysMask
) != 0)
235 if ((accessxFeatures
& XkbBounceKeysMask
) != 0)
238 calculateSizes (h
, showModifiers
?modifiers
.count():0,
239 showLockkeys
?lockkeys
.count():0,
240 showAccessX
?accessx
:0,
241 showMouse
, lines
, length
, size
);
249 int KbStateApplet::heightForWidth(int w
) const {
251 int size
= this->size
;
254 if ((accessxFeatures
& XkbStickyKeysMask
) != 0)
256 if ((accessxFeatures
& XkbSlowKeysMask
) != 0)
258 if ((accessxFeatures
& XkbBounceKeysMask
) != 0)
261 calculateSizes (w
, showModifiers
?modifiers
.count():0,
262 showLockkeys
?lockkeys
.count():0,
263 showAccessX
?accessx
:0,
264 showMouse
, lines
, length
, size
);
272 void KbStateApplet::mousePressEvent(QMouseEvent
*e
) {
273 if (e
->button() == Qt::RightButton
)
274 popup
->popup(e
->globalPos());
277 void KbStateApplet::setIconDim (int size
) {
286 void KbStateApplet::resizeEvent( QResizeEvent
*e
) {
287 QWidget::resizeEvent(e
);
291 void KbStateApplet::toggleFillSpace() {
292 fillSpace
= !fillSpace
;
300 void KbStateApplet::layout() {
301 int size
= this->size
;
303 int lines
, length
, x
,y
,dx
,dy
, ldx
,ldy
;
304 int modifierCount
= showModifiers
?modifiers
.count():0;
305 int lockkeyCount
= showLockkeys
?lockkeys
.count():0;
306 int accessxCount
= 0;
309 if ((accessxFeatures
& XkbStickyKeysMask
) != 0)
311 if ((accessxFeatures
& XkbSlowKeysMask
) != 0)
313 if ((accessxFeatures
& XkbBounceKeysMask
) != 0)
317 if (orientation() == Qt::Vertical
) {
318 calculateSizes (width(), modifierCount
, lockkeyCount
, accessxCount
,
319 showMouse
, lines
, length
, size
);
322 size
= width()/lines
;
324 x
= (width()-lines
*size
)/2;
332 calculateSizes (height(), modifierCount
, lockkeyCount
, accessxCount
,
333 showMouse
, lines
, length
, size
);
336 size
= height()/lines
;
339 y
= (height()-lines
*size
)/2;
348 for (icon
= modifiers
.first(); icon
; icon
= modifiers
.next()) {
350 icon
->setGeometry (x
, y
, size
, size
);
353 item
++; x
+=dx
; y
+=dy
;
355 x
= x
- length
*dx
+ ldx
;
356 y
= y
- length
*dy
+ ldy
;
364 int lockkeyLines
= (lockkeyCount
+length
-1)/length
;
365 int accessxLines
= lines
- (modifierCount
+length
-1)/length
- lockkeyLines
;
370 if (lockkeyLines
*length
+ accessxLines
*length
371 >= lockkeyCount
+ accessxCount
)
373 if (lines
> 1 && item
> 1) {
374 x
= x
- (item
-1)*dx
+ ldx
;
375 y
= y
- (item
-1)*dy
+ ldy
;
383 if (showMouse
&& showAccessX
&& accessxLines
> 0) {
384 mouse
->setGeometry (x
, y
, size
, size
);
388 item
++; x
+=dx
; y
+=dy
;
390 x
= x
- length
*dx
+ ldx
;
391 y
= y
- length
*dy
+ ldy
;
399 if ((accessxFeatures
& XkbStickyKeysMask
) != 0
400 && showAccessX
&& accessxLines
> 0)
402 sticky
->setGeometry (x
, y
, size
, size
);
406 item
++; x
+=dx
; y
+=dy
;
408 x
= x
- length
*dx
+ ldx
;
409 y
= y
- length
*dy
+ ldy
;
417 if ((accessxFeatures
& XkbSlowKeysMask
) != 0
418 && showAccessX
&& accessxLines
> 0)
420 slow
->setGeometry (x
, y
, size
, size
);
424 item
++; x
+=dx
; y
+=dy
;
426 x
= x
- length
*dx
+ ldx
;
427 y
= y
- length
*dy
+ ldy
;
435 if ((accessxFeatures
& XkbBounceKeysMask
) != 0
436 && showAccessX
&& accessxLines
> 0)
438 bounce
->setGeometry (x
, y
, size
, size
);
442 item
++; x
+=dx
; y
+=dy
;
444 x
= x
- length
*dx
+ ldx
;
445 y
= y
- length
*dy
+ ldy
;
455 x
= x
- (item
-1)*dx
+ ldx
;
456 y
= y
- (item
-1)*dy
+ ldy
;
460 for (icon
= lockkeys
.first(); icon
; icon
= lockkeys
.next()) {
462 icon
->setGeometry (x
, y
, size
, size
);
465 item
++; x
+=dx
; y
+=dy
;
467 x
= x
- length
*dx
+ ldx
;
468 y
= y
- length
*dy
+ ldy
;
476 if ((accessxFeatures
& XkbBounceKeysMask
) != 0
477 && showAccessX
&& accessxCount
> 0)
479 bounce
->setGeometry (x
, y
, size
, size
);
482 item
++; x
+=dx
; y
+=dy
;
486 if ((accessxFeatures
& XkbSlowKeysMask
) != 0
487 && showAccessX
&& accessxCount
> 0)
489 slow
->setGeometry (x
, y
, size
, size
);
492 item
++; x
+=dx
; y
+=dy
;
496 if ((accessxFeatures
& XkbStickyKeysMask
) != 0
497 && showAccessX
&& accessxCount
> 0)
499 sticky
->setGeometry (x
, y
, size
, size
);
502 item
++; x
+=dx
; y
+=dy
;
506 if (showMouse
&& accessxCount
> 0)
508 mouse
->setGeometry (x
, y
, size
, size
);
511 item
++; x
+=dx
; y
+=dy
;
516 void KbStateApplet::paletteChanged() {
517 for (int i
= 0; i
< 8; i
++) {
519 icons
[i
]->updateImages();
527 void KbStateApplet::initMasks() {
528 for (int i
= 0; i
< 8; i
++) {
535 for (int i
= 0; strcmp(modifierKeys
[i
].name
, "") != 0; i
++) {
536 int mask
= modifierKeys
[i
].mask
;
538 if (modifierKeys
[i
].keysym
!= 0)
539 mask
= XkbKeysymToModifiers (this->x11Display(), modifierKeys
[i
].keysym
);
541 #warning "kde4: how to port it ?"
544 else if (strcmp(modifierKeys
[i
].name
, "Win") == 0)
545 mask
= KKeyNative::modXWin();
548 mask
= XkbKeysymToModifiers (this->x11Display(), XK_Mode_switch
)
549 | XkbKeysymToModifiers (this->x11Display(), XK_ISO_Level3_Shift
)
550 | XkbKeysymToModifiers (this->x11Display(), XK_ISO_Level3_Latch
)
551 | XkbKeysymToModifiers (this->x11Display(), XK_ISO_Level3_Lock
);
554 for (map
= 0; map
< 8; map
++) {
555 if ((mask
& (1 << map
)) != 0)
558 if ((map
<= 7) && !(icons
[map
])) {
559 icons
[map
] = new KeyIcon (i
, m_iconLoader
, this, modifierKeys
[i
].name
);
560 icons
[map
]->setToolTip( i18n (modifierKeys
[i
].name
));
561 connect (icons
[map
], SIGNAL(stateChangeRequest (KeyIcon
*,bool,bool)),
562 SLOT(stateChangeRequest (KeyIcon
*,bool,bool)));
563 if (modifierKeys
[i
].isModifier
)
564 modifiers
.append(icons
[map
]);
566 lockkeys
.append(icons
[map
]);
571 bool KbStateApplet::x11Event (XEvent
*evt
) {
572 if (evt
->type
== xkb_base_event_type
+ XkbEventCode
) {
573 XkbEvent
*kbevt
= (XkbEvent
*)evt
;
574 switch (kbevt
->any
.xkb_type
) {
578 mouse
->setState (kbevt
->state
.ptr_buttons
);
580 case XkbAccessXNotify
:
581 switch (kbevt
->accessx
.detail
) {
583 slow
->setGlyth(i18nc("a (the first letter in the alphabet)", "a"));
584 slow
->setImage("unlatched");
586 case XkbAXN_SKAccept
:
587 slow
->setImage("keypressok");
589 case XkbAXN_SKRelease
:
591 slow
->setImage("kbstate_slowkeys");
593 case XkbAXN_SKReject
:
594 slow
->setImage("keypressno", kbevt
->accessx
.sk_delay
>150?kbevt
->accessx
.sk_delay
:150);
596 case XkbAXN_BKAccept
:
597 slow
->setGlyth(i18nc("a (the first letter in the alphabet)", "a"));
598 bounce
->setImage("keypressok", kbevt
->accessx
.sk_delay
>150?kbevt
->accessx
.sk_delay
:150);
600 case XkbAXN_BKReject
:
601 slow
->setGlyth(i18nc("a (the first letter in the alphabet)", "a"));
602 bounce
->setImage("keypressno", kbevt
->accessx
.sk_delay
>150?kbevt
->accessx
.sk_delay
:150);
606 case XkbControlsNotify
: {
607 XkbControlsNotifyEvent
* event
= (XkbControlsNotifyEvent
*)evt
;
608 accessxFeatures
= event
->enabled_ctrls
;
610 if ((accessxFeatures
& XkbMouseKeysMask
) != 0) {
611 XkbGetControls (QX11Info::display(), XkbMouseKeysMask
, xkb
);
612 if (xkb
->ctrls
->mk_dflt_btn
< 1)
613 mouse
->setActiveKey (1);
614 else if (xkb
->ctrls
->mk_dflt_btn
> 3)
615 mouse
->setActiveKey (1);
617 mouse
->setActiveKey (xkb
->ctrls
->mk_dflt_btn
);
620 mouse
->setActiveKey (0);
627 case XkbExtensionDeviceNotify
:
628 /* This is a hack around the fact that XFree86's XKB doesn't give AltGr notifications */
637 void KbStateApplet::timerEvent(QTimerEvent
*) {
638 XkbStateRec state_return
;
639 XkbGetState (this->x11Display(), XkbUseCoreKbd
, &state_return
);
640 unsigned char latched
= XkbStateMods (&state_return
);
641 unsigned char locked
= XkbModLocks (&state_return
);
642 int mods
= ((int)latched
)<<8 | locked
;
646 for (int i
= 0; i
< 8; i
++) {
648 icons
[i
]->setState ((latched
&(1<<i
)) != 0, (locked
&(1<<i
)) != 0);
653 void KbStateApplet::stateChangeRequest (KeyIcon
*source
, bool latched
, bool locked
) {
654 for (int i
= 0; i
< 8; i
++) {
655 if (icons
[i
] == source
) {
657 XkbLockModifiers (this->x11Display(), XkbUseCoreKbd
, 1<<i
, 1<<i
);
659 XkbLockModifiers (this->x11Display(), XkbUseCoreKbd
, 1<<i
, 0);
660 XkbLatchModifiers (this->x11Display(), XkbUseCoreKbd
, 1<<i
, 1<<i
);
663 XkbLockModifiers (this->x11Display(), XkbUseCoreKbd
, 1<<i
, 0);
664 XkbLatchModifiers (this->x11Display(), XkbUseCoreKbd
, 1<<i
, 0);
671 void KbStateApplet::toggleModifier() {
672 showModifiers
= !showModifiers
;
679 void KbStateApplet::toggleLockkeys() {
680 showLockkeys
= !showLockkeys
;
687 void KbStateApplet::toggleMouse() {
688 showMouse
= !showMouse
;
695 void KbStateApplet::toggleAccessX() {
696 showAccessX
= !showAccessX
;
703 void KbStateApplet::configureAccessX() {
704 KToolInvocation::startServiceByDesktopName("kcmaccess");
707 void KbStateApplet::configureKeyboard() {
708 // The modulename "keyboard" is ambiguous on SuSE systems
709 // as there is also a YaST-module called "keyboard".
712 QProcess::startDetached("kcmshell4",arg
);
715 void KbStateApplet::configureMouse() {
716 KToolInvocation::startServiceByDesktopName("mouse");
719 void KbStateApplet::about() {
720 KAboutData
about("kbstateapplet", 0, ki18n("Keyboard Status Applet"), "0.2",
721 ki18n("Panel applet that shows the state of the modifier keys"), KAboutData::License_GPL_V2
, ki18n("(C) 2004 Gunnar Schmi Dt"));
722 KAboutApplicationDialog
a(&about
, this);
726 void KbStateApplet::loadConfig()
728 KConfigGroup
c(config(), "General");
729 size
= c
.readEntry("IconDim", 20);
730 fillSpace
= c
.readEntry("fill space", true);
731 showModifiers
= c
.readEntry("Modifierkeys visible", true);
732 showLockkeys
= c
.readEntry("Lockkeys visible", true);
733 showMouse
= c
.readEntry("Mouse status visible", true);
734 showAccessX
= c
.readEntry("Slowkeys status visible", true);
735 showAccessX
= c
.readEntry("AccessX status visible", showAccessX
);
738 void KbStateApplet::saveConfig()
740 KConfigGroup
c(config(), "General");
741 c
.writeEntry("IconDim", size
);
742 c
.writeEntry("fill space", fillSpace
);
743 c
.writeEntry("Modifierkeys visible", showModifiers
);
744 c
.writeEntry("Lockkeys visible", showLockkeys
);
745 c
.writeEntry("Mouse status visible", showMouse
);
746 c
.writeEntry("AccessX status visible", showAccessX
);
750 /********************************************************************/
752 KeyIcon::KeyIcon (int keyId
, KIconLoader
*iconLoader
,
753 QWidget
*parent
, const char *name
)
754 : StatusIcon (modifierKeys
[keyId
].name
, parent
, name
) {
755 this->iconLoader
= iconLoader
;
757 this->tristate
= (modifierKeys
[keyId
].isModifier
);
761 connect (this, SIGNAL(clicked()), SLOT(clickedSlot()));
764 KeyIcon::~KeyIcon () {
767 void KeyIcon::setState (bool latched
, bool locked
) {
768 latched
= latched
| locked
;
775 void KeyIcon::clickedSlot () {
777 emit
stateChangeRequest (this, !isLocked
, isLatched
&!isLocked
);
779 emit
stateChangeRequest (this, false, !isLocked
);
783 void KeyIcon::resizeEvent( QResizeEvent
*e
)
785 QWidget::resizeEvent(e
);
789 void KeyIcon::updateImages () {
790 int size
= width()<height() ? width() : height();
792 locked
= iconLoader
->loadIcon("lock_overlay", KIconLoader::Panel
, size
-4);
793 if (strcmp(modifierKeys
[keyId
].icon
, "")) {
794 latched
= iconLoader
->loadIcon(modifierKeys
[keyId
].icon
, KIconLoader::NoGroup
, size
-4);
795 unlatched
= iconLoader
->loadIcon(modifierKeys
[keyId
].icon
, KIconLoader::NoGroup
, size
-4);
797 QImage img
= latched
.convertToImage();
798 KIconEffect::colorize(img
, KColorScheme(QPalette::Active
, KColorScheme::Selection
).foreground().color(), 1.0);
799 latched
.convertFromImage (img
);
801 img
= unlatched
.convertToImage();
802 KIconEffect::colorize(img
, KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color(), 1.0);
803 unlatched
.convertFromImage (img
);
809 void KeyIcon::drawButton (QPainter
*p
) {
812 int x
= (width()-locked
.width())/2;
813 int y
= (height()-locked
.height())/2;
815 if (isLocked
|| isLatched
) {
816 qDrawShadePanel (p
, 0, 0, width(), height(), colorGroup(), true, 1, NULL
);
817 p
->fillRect (1,1,width()-2,height()-2, KColorScheme(QPalette::Active
, KColorScheme::Selection
).background().color());
818 if (strcmp(modifierKeys
[keyId
].icon
, ""))
819 p
->drawPixmap (x
+1,y
+1, latched
);
820 black
= KColorScheme(QPalette::Active
, KColorScheme::Selection
).foreground().color();
824 qDrawShadePanel (p
, 0, 0, width(), height(), colorGroup(), false, 1, NULL
);
825 if (strcmp(modifierKeys
[keyId
].icon
, ""))
826 p
->drawPixmap (x
,y
, unlatched
);
827 black
= KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color();
830 QString text
= i18n(modifierKeys
[keyId
].text
);
831 if (!text
.isEmpty() && !text
.isNull()) {
832 QFont font
= KGlobalSettings::generalFont();
833 font
.setWeight(QFont::Black
);
834 QFontMetrics
metrics(font
);
835 QRect rect
= metrics
.boundingRect (text
);
837 if (!strcmp(modifierKeys
[keyId
].name
, "Alt Graph"))
838 size
= rect
.width()>rect
.height()?rect
.width():rect
.height();
840 size
= rect
.width()>12*rect
.height()/5?rect
.width():12*rect
.height()/5;
842 if (font
.pixelSize() != -1)
843 font
.setPixelSize (font
.pixelSize()*width()*19/size
/32);
845 font
.setPointSizeFloat (font
.pointSizeFloat()*width()*19/size
/32);
849 if (!strcmp(modifierKeys
[keyId
].name
, "Alt Graph"))
850 p
->drawText (o
,o
, width(), height(), Qt::AlignCenter
, text
);
852 p
->drawText (o
,o
, width(), height()*(251)/384, Qt::AlignCenter
, text
);
854 if (tristate
&& isLocked
) {
855 p
->drawPixmap(x
+o
,y
+o
, locked
);
859 /********************************************************************/
861 MouseIcon::MouseIcon (KIconLoader
*iconLoader
, QWidget
*parent
, const char *name
)
862 : StatusIcon ("", parent
, name
)
864 this->iconLoader
= iconLoader
;
868 connect (this, SIGNAL(clicked()), SLOT(clickedSlot()));
871 MouseIcon::~MouseIcon () {
874 void MouseIcon::setState (int state
) {
880 void MouseIcon::setActiveKey (int activekey
) {
881 this->activekey
= activekey
;
886 void MouseIcon::resizeEvent( QResizeEvent
*e
)
888 QWidget::resizeEvent(e
);
892 QPixmap
loadIcon(KIconLoader
*iconLoader
, int size
, const QColor
&color
, const QString
&name
) {
893 QPixmap result
= iconLoader
->loadIcon(name
, KIconLoader::NoGroup
, size
);
895 QImage img
= result
.convertToImage();
896 KIconEffect::colorize(img
, color
, 1.0);
897 result
.convertFromImage (img
);
902 void MouseIcon::updateImages () {
903 int size
= width()<height() ? width() : height();
905 QColor textcolor
= KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color();
906 QColor basecolor
= KColorScheme(QPalette::Active
, KColorScheme::View
).background().color();
907 mouse
= loadIcon (iconLoader
, size
, textcolor
, "kbstate_mouse");
908 leftSelected
= loadIcon (iconLoader
, size
, textcolor
,
909 "kbstate_mouse_left_selected");
910 middleSelected
= loadIcon (iconLoader
, size
, textcolor
,
911 "kbstate_mouse_mid_selected");
912 rightSelected
= loadIcon (iconLoader
, size
, textcolor
,
913 "kbstate_mouse_right_selected");
914 leftDot
= loadIcon (iconLoader
, size
, textcolor
, "kbstate_mouse_left");
915 middleDot
= loadIcon (iconLoader
, size
, textcolor
, "kbstate_mouse_mid");
916 rightDot
= loadIcon (iconLoader
, size
, textcolor
, "kbstate_mouse_right");
917 leftDotSelected
= loadIcon (iconLoader
, size
, basecolor
,
918 "kbstate_mouse_left");
919 middleDotSelected
= loadIcon (iconLoader
, size
, basecolor
,
920 "kbstate_mouse_mid");
921 rightDotSelected
= loadIcon (iconLoader
, size
, basecolor
,
922 "kbstate_mouse_right");
927 void MouseIcon::drawButton (QPainter
*p
) {
928 p
->drawPixmap(0,0, mouse
);
929 if ((state
& Button1Mask
) != 0)
930 p
->drawPixmap(0,0, leftSelected
);
931 if ((state
& Button2Mask
) != 0)
932 p
->drawPixmap(0,0, middleSelected
);
933 if ((state
& Button3Mask
) != 0)
934 p
->drawPixmap(0,0, rightSelected
);
939 if ((state
& Button1Mask
) != 0)
940 p
->drawPixmap(0,0, leftDotSelected
);
942 p
->drawPixmap(0,0, leftDot
);
945 if ((state
& Button2Mask
) != 0)
946 p
->drawPixmap(0,0, middleDotSelected
);
948 p
->drawPixmap(0,0, middleDot
);
951 if ((state
& Button3Mask
) != 0)
952 p
->drawPixmap(0,0, rightDotSelected
);
954 p
->drawPixmap(0,0, rightDot
);
959 /********************************************************************/
961 TimeoutIcon::TimeoutIcon (KIconLoader
*iconLoader
, const QString
&text
,
962 const QString
&featurename
,
963 QWidget
*parent
, const char *name
)
964 : StatusIcon (text
, parent
, name
) {
965 this->iconLoader
= iconLoader
;
966 this->featurename
= featurename
;
968 setImage (featurename
);
969 connect (&timer
, SIGNAL(timeout()), this, SLOT(timeout()));
972 TimeoutIcon::~TimeoutIcon () {
975 void TimeoutIcon::update () {
976 int size
= width()<height() ? width() : height();
977 if (pixmap
.width() != size
)
978 pixmap
= iconLoader
->loadIcon(iconname
, KIconLoader::NoGroup
, size
);
980 QImage img
= pixmap
.convertToImage();
981 KIconEffect::colorize(img
, KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color(), 1.0);
982 pixmap
.convertFromImage (img
);
988 void TimeoutIcon::setGlyth (const QString
&glyth
) {
992 QImage img
= pixmap
.convertToImage();
993 KIconEffect::colorize(img
, KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color(), 1.0);
994 pixmap
.convertFromImage (img
);
1000 void TimeoutIcon::setImage (const QString
&name
, int timeout
) {
1003 if (!name
.isNull() && !name
.isEmpty()) {
1004 int size
= width()<height() ? width() : height();
1005 pixmap
= iconLoader
->loadIcon(iconname
, KIconLoader::NoGroup
, size
);
1007 QImage img
= pixmap
.convertToImage();
1008 KIconEffect::colorize(img
, KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color(), 1.0);
1009 pixmap
.convertFromImage (img
);
1015 timer
.start (timeout
, true);
1018 void TimeoutIcon::timeout () {
1020 setImage(featurename
);
1024 void TimeoutIcon::drawButton (QPainter
*p
) {
1025 QString text
= glyth
;
1029 if (!iconname
.isNull() && !iconname
.isEmpty())
1030 p
->drawPixmap(0,0, image
);
1031 else if (glyth
== " ") {
1032 text
= i18nc("a (the first letter in the alphabet)", "a");
1037 QFont font
= KGlobalSettings::generalFont();
1038 font
.setWeight(QFont::Black
);
1039 QFontMetrics
metrics(font
);
1040 QRect rect
= metrics
.boundingRect (text
);
1041 int size
= count
*rect
.width() > rect
.height()
1042 ? count
*rect
.width() : rect
.height();
1043 if (font
.pixelSize() != -1)
1044 font
.setPixelSize (font
.pixelSize()*width()*factor
/size
/64);
1046 font
.setPointSizeFloat (font
.pointSizeFloat()*width()*factor
/size
/64);
1050 p
->setPen (KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color());
1051 p
->drawText (0,0, width()/2, height()/2, Qt::AlignCenter
, text
);
1054 QColor t
= KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color();
1055 QColor b
= KColorScheme(QPalette::Active
, KColorScheme::View
).background().color();
1056 p
->setPen (QColor ((2*t
.red()+3*b
.red())/5,
1057 (2*t
.green()+3*b
.green())/5,
1058 (2*t
.blue()+3*b
.blue())/5));
1059 p
->drawText (width()/2,0, width()/2, height(), Qt::AlignCenter
, text
);
1060 p
->setPen (QColor ((2*t
.red()+b
.red())/3,
1061 (2*t
.green()+b
.green())/3,
1062 (2*t
.blue()+b
.blue())/3));
1063 p
->drawText (0,0, width(), height(), Qt::AlignCenter
, text
);
1064 p
->setPen (KColorScheme(QPalette::Active
, KColorScheme::View
).foreground().color());
1065 p
->drawText (0,0, width()/2, height(), Qt::AlignCenter
, text
);
1069 /********************************************************************/
1071 StatusIcon::StatusIcon (const QString
&text
, QWidget
*parent
, const char *name
)
1072 : QPushButton (text
, parent
) {
1073 setObjectName(name
);
1074 setSizePolicy(QSizePolicy(QSizePolicy::Ignored
, QSizePolicy::Ignored
));
1077 StatusIcon::~StatusIcon () {
1080 QSize
StatusIcon::minimumSizeHint () const {