/* * Copyright (c) 2004 Gunnar Schmi Dt * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kdeexportfix.h" #include "kbstate.h" #include "kbstate.moc" extern "C" { #include #include #include #define XK_MISCELLANY #define XK_XKB_KEYS #include #include KDE_EXPORT KPanelApplet* init(TQWidget *parent, const TQString& configFile) { KGlobal::locale()->insertCatalogue("kbstateapplet"); KbStateApplet *applet = new KbStateApplet(configFile, KPanelApplet::Normal, KPanelApplet::About, parent, "kbstateapplet"); return applet; } } struct ModifierKey { const unsigned int mask; const KeySym keysym; const char *name; const char *icon; const char *text; const bool isModifier; }; static ModifierKey modifierKeys[] = { { ShiftMask, 0, I18N_NOOP("Shift"), "shiftkey", "", true }, { ControlMask, 0, I18N_NOOP("Control"), "controlkey", "", true }, { 0, XK_Alt_L, I18N_NOOP("Alt"), "altkey", "", true }, { 0, 0, I18N_NOOP("Win"), "superkey", "", true }, { 0, XK_Meta_L, I18N_NOOP("Meta"), "metakey", "", true }, { 0, XK_Super_L, I18N_NOOP("Super"), "superkey", "", true }, { 0, XK_Hyper_L, I18N_NOOP("Hyper"), "hyperkey", "", true }, { 0, 0, I18N_NOOP("Alt Graph"), "", I18N_NOOP("æ"), true }, { 0, XK_Num_Lock, I18N_NOOP("Num Lock"), "lockkey", I18N_NOOP("Num"), false }, { LockMask, 0, I18N_NOOP("Caps Lock"), "capskey", "", false }, { 0, XK_Scroll_Lock, I18N_NOOP("Scroll Lock"), "lockkey", I18N_NOOP("Scroll"), false }, { 0, 0, "", "", "", false } }; /********************************************************************/ KbStateApplet::KbStateApplet(const TQString& configFile, Type t, int actions, TQWidget *parent, const char *name) : KPanelApplet( configFile, t, actions, parent, name ) { for (int i = 0; i < 8; i++) { icons[i] = 0; } instance = new KInstance ("kbstateapplet"); loadConfig(); initMasks(); mouse = new MouseIcon (instance, this, "mouse"); sticky = new TimeoutIcon (instance, "", "kbstate_stickykeys", this, "sticky"); slow = new TimeoutIcon (instance, "", "kbstate_slowkeys", this, "slow"); bounce = new TimeoutIcon (instance, "", "", this, "bounce"); xkb = XkbGetMap(qt_xdisplay(), 0, XkbUseCoreKbd); if (xkb != 0) { XkbGetControls (qt_xdisplay(), XkbAllControlsMask, xkb); if (xkb->ctrls != 0) accessxFeatures = xkb->ctrls->enabled_ctrls; else accessxFeatures = 0; } else accessxFeatures = 0; //startTimer(100); // ten times a second connect(kapp, TQT_SIGNAL(kdisplayPaletteChanged()), TQT_SLOT(paletteChanged())); kapp->installX11EventFilter (this); int opcode_rtn, error_rtn; XkbQueryExtension (this->x11Display(), &opcode_rtn, &xkb_base_event_type, &error_rtn, NULL, NULL); XkbSelectEvents (this->x11Display(), XkbUseCoreKbd, XkbAllEventsMask, XkbAllEventsMask); buildPopupMenu(); } KbStateApplet::~KbStateApplet() { kapp->removeX11EventFilter (this); setCustomMenu(0); delete instance; delete popup; delete sizePopup; } // Builds, connects _popup menu void KbStateApplet::buildPopupMenu() { sizePopup=new KPopupMenu(this); sizePopup->setCheckable( true ); sizePopup->insertItem(i18n("Small"), 13); sizePopup->insertItem(i18n("Medium"), 20); sizePopup->insertItem(i18n("Large"), 26); connect(sizePopup,TQT_SIGNAL(activated(int)), this, TQT_SLOT(setIconDim(int))); showPopup=new KPopupMenu(this); showPopup->setCheckable( true ); modifierItem=showPopup->insertItem(i18n("Modifier Keys"), this, TQT_SLOT(toggleModifier())); lockkeysItem=showPopup->insertItem(i18n("Lock Keys"), this, TQT_SLOT(toggleLockkeys())); mouseItem=showPopup->insertItem(i18n("Mouse Status"), this, TQT_SLOT(toggleMouse())); accessxItem=showPopup->insertItem(i18n("AccessX Status"), this, TQT_SLOT(toggleAccessX())); popup = new KPopupMenu(this); popup->setCheckable( true ); popup->insertTitle(0, i18n("Keyboard Status Applet")); popup->insertItem(i18n("Set Icon Size"),sizePopup); fillSpaceItem = popup->insertItem(i18n("Fill Available Space"), this, TQT_SLOT(toggleFillSpace())); popup->insertItem(i18n("Show"),showPopup); popup->insertItem(i18n("Configure AccessX Features..."), this, TQT_SLOT(configureAccessX())); popup->insertItem(i18n("Configure Keyboard..."), this, TQT_SLOT(configureKeyboard())); popup->insertItem(i18n("Configure Mouse..."), this, TQT_SLOT(configureMouse())); popup->insertSeparator(); popup->insertItem(i18n("About"), this, TQT_SLOT(about())); setCustomMenu(popup); updateMenu(); } void KbStateApplet::updateMenu() { if (popup) { showPopup->setItemChecked (modifierItem, showModifiers); showPopup->setItemChecked (lockkeysItem, showLockkeys); showPopup->setItemChecked (mouseItem, showMouse); showPopup->setItemChecked (accessxItem, showAccessX); popup->setItemChecked (fillSpaceItem, fillSpace); sizePopup->setItemChecked(13, size == 13); sizePopup->setItemChecked(20, size == 20); sizePopup->setItemChecked(26, size == 26); } } void calculateSizes (int space, int modifiers, int lockkeys, int accessx, bool showMouse, int &lines, int &length, int &size) // Calculates the layout based on a given number of modifiers, lockkeys and // accessx features. // Output: // lines: number of lines // length: number of icons per line // size: size of the icons { // Calculate lines and length if (showMouse) ++accessx; lines = space>=size ? space/size : 1; length = modifiers + lockkeys + accessx; if (length > 0 && lines >= 2) { length = (length + lines-1)/lines; // As we want to have some line breaks, we need to do some corrections: // Calculate the number of lines that are really needed: int linesNeeded = (modifiers+length-1)/length + (lockkeys+length-1)/length; int tmp1 = modifiers%length == 0 ? 0 : length - modifiers%length; int tmp2 = lockkeys%length == 0 ? 0 : length - lockkeys%length; if ((tmp1 + tmp2) < accessx) linesNeeded = (modifiers+lockkeys+accessx + length-1)/length; // If we need more lines than we have, try with more icons per line: while (linesNeeded > lines) { length++; linesNeeded = (modifiers+length-1)/length + (lockkeys+length-1)/length; int tmp1 = modifiers%length == 0 ? 0 : length - modifiers%length; int tmp2 = lockkeys%length == 0 ? 0 : length - lockkeys%length; if ((tmp1 + tmp2) < accessx) linesNeeded = (modifiers+lockkeys+accessx + length-1)/length; } lines = linesNeeded; } } int KbStateApplet::widthForHeight(int h) const { int lines, length; int size = this->size; int accessx = 0; if ((accessxFeatures & XkbStickyKeysMask) != 0) accessx++; if ((accessxFeatures & XkbSlowKeysMask) != 0) accessx++; if ((accessxFeatures & XkbBounceKeysMask) != 0) accessx++; calculateSizes (h, showModifiers?modifiers.count():0, showLockkeys?lockkeys.count():0, showAccessX?accessx:0, showMouse, lines, length, size); if (fillSpace) size = h/lines; return length*size; } int KbStateApplet::heightForWidth(int w) const { int lines, length; int size = this->size; int accessx = 0; if ((accessxFeatures & XkbStickyKeysMask) != 0) accessx++; if ((accessxFeatures & XkbSlowKeysMask) != 0) accessx++; if ((accessxFeatures & XkbBounceKeysMask) != 0) accessx++; calculateSizes (w, showModifiers?modifiers.count():0, showLockkeys?lockkeys.count():0, showAccessX?accessx:0, showMouse, lines, length, size); if (fillSpace) size = w/lines; return length*size; } void KbStateApplet::mousePressEvent(TQMouseEvent *e) { if (e->button() == Qt::RightButton) popup->popup(e->globalPos()); } void KbStateApplet::setIconDim (int size) { this->size = size; saveConfig(); updateMenu(); update(); updateGeometry(); emit updateLayout(); } void KbStateApplet::toggleFillSpace() { fillSpace = !fillSpace; saveConfig(); updateMenu(); layout(); updateGeometry(); emit updateLayout(); } void KbStateApplet::resizeEvent( TQResizeEvent*e ) { TQWidget::resizeEvent(e); layout(); } void KbStateApplet::layout() { int size = this->size; int lines, length, x,y,dx,dy, ldx,ldy; int modifierCount = showModifiers?modifiers.count():0; int lockkeyCount = showLockkeys?lockkeys.count():0; int accessxCount = 0; if (showAccessX) { if ((accessxFeatures & XkbStickyKeysMask) != 0) accessxCount++; if ((accessxFeatures & XkbSlowKeysMask) != 0) accessxCount++; if ((accessxFeatures & XkbBounceKeysMask) != 0) accessxCount++; } if (orientation() ==Qt::Vertical) { calculateSizes (width(), modifierCount, lockkeyCount, accessxCount, showMouse, lines, length, size); if (fillSpace) size = width()/lines; x = (width()-lines*size)/2; y = 0; dx = 0; dy = size; ldx= size; ldy= 0; } else { calculateSizes (height(), modifierCount, lockkeyCount, accessxCount, showMouse, lines, length, size); if (fillSpace) size = height()/lines; x = 0; y = (height()-lines*size)/2; dx = size; dy = 0; ldx= 0; ldy= size; } StatusIcon *icon; int item = 1; for (icon = modifiers.first(); icon; icon = modifiers.next()) { if (showModifiers) { icon->setGeometry (x, y, size, size); icon->show(); icon->update(); item++; x+=dx; y+=dy; if (item > length) { x = x - length*dx + ldx; y = y - length*dy + ldy; item = 1; } } else icon->hide(); } int lockkeyLines = (lockkeyCount+length-1)/length; int accessxLines = lines - (modifierCount+length-1)/length - lockkeyLines; if (showMouse) ++accessxCount; if (lockkeyLines*length + accessxLines*length >= lockkeyCount + accessxCount) { if (lines > 1 && item > 1) { x = x - (item-1)*dx + ldx; y = y - (item-1)*dy + ldy; item = 1; } } else { accessxLines++; } if (showMouse && showAccessX && accessxLines > 0) { mouse->setGeometry (x, y, size, size); mouse->show(); mouse->update(); accessxCount--; item++; x+=dx; y+=dy; if (item > length) { x = x - length*dx + ldx; y = y - length*dy + ldy; item = 1; accessxLines--; } } else mouse->hide(); if ((accessxFeatures & XkbStickyKeysMask) != 0 && showAccessX && accessxLines > 0) { sticky->setGeometry (x, y, size, size); sticky->show(); sticky->update(); accessxCount--; item++; x+=dx; y+=dy; if (item > length) { x = x - length*dx + ldx; y = y - length*dy + ldy; item = 1; accessxLines--; } } else sticky->hide(); if ((accessxFeatures & XkbSlowKeysMask) != 0 && showAccessX && accessxLines > 0) { slow->setGeometry (x, y, size, size); slow->show(); slow->update(); accessxCount--; item++; x+=dx; y+=dy; if (item > length) { x = x - length*dx + ldx; y = y - length*dy + ldy; item = 1; accessxLines--; } } else slow->hide(); if ((accessxFeatures & XkbBounceKeysMask) != 0 && showAccessX && accessxLines > 0) { bounce->setGeometry (x, y, size, size); bounce->show(); bounce->update(); accessxCount--; item++; x+=dx; y+=dy; if (item > length) { x = x - length*dx + ldx; y = y - length*dy + ldy; item = 1; accessxLines--; } } else bounce->hide(); if (lines > 1) { if (item != 1) { x = x - (item-1)*dx + ldx; y = y - (item-1)*dy + ldy; } item = 1; } for (icon = lockkeys.first(); icon; icon = lockkeys.next()) { if (showLockkeys) { icon->setGeometry (x, y, size, size); icon->show(); icon->update(); item++; x+=dx; y+=dy; if (item > length) { x = x - length*dx + ldx; y = y - length*dy + ldy; item = 1; } } else icon->hide(); } if ((accessxFeatures & XkbBounceKeysMask) != 0 && showAccessX && accessxCount > 0) { bounce->setGeometry (x, y, size, size); bounce->show(); bounce->update(); item++; x+=dx; y+=dy; accessxCount--; } if ((accessxFeatures & XkbSlowKeysMask) != 0 && showAccessX && accessxCount > 0) { slow->setGeometry (x, y, size, size); slow->show(); slow->update(); item++; x+=dx; y+=dy; accessxCount--; } if ((accessxFeatures & XkbStickyKeysMask) != 0 && showAccessX && accessxCount > 0) { sticky->setGeometry (x, y, size, size); sticky->show(); sticky->update(); item++; x+=dx; y+=dy; accessxCount--; } if (showMouse && accessxCount > 0) { mouse->setGeometry (x, y, size, size); mouse->show(); mouse->update(); item++; x+=dx; y+=dy; accessxCount--; } } void KbStateApplet::paletteChanged() { for (int i = 0; i < 8; i++) { if (icons[i]) icons[i]->updateImages(); } mouse->update(); sticky->update(); slow->update(); bounce->update(); } void KbStateApplet::initMasks() { for (int i = 0; i < 8; i++) { if (icons[i]) delete icons[i]; icons[i] = 0; } state = 0; for (int i = 0; strcmp(modifierKeys[i].name, "") != 0; i++) { int mask = modifierKeys[i].mask; if (mask == 0) if (modifierKeys[i].keysym != 0) mask = XkbKeysymToModifiers (this->x11Display(), modifierKeys[i].keysym); else if (!strcmp(modifierKeys[i].name, "Win")) mask = KKeyNative::modX(KKey::WIN); else mask = XkbKeysymToModifiers (this->x11Display(), XK_Mode_switch) | XkbKeysymToModifiers (this->x11Display(), XK_ISO_Level3_Shift) | XkbKeysymToModifiers (this->x11Display(), XK_ISO_Level3_Latch) | XkbKeysymToModifiers (this->x11Display(), XK_ISO_Level3_Lock); int map = 0; for (map = 0; map < 8; map++) { if ((mask & (1 << map)) != 0) break; } if ((map <= 7) && !(icons[map])) { icons[map] = new KeyIcon (i, instance, this, modifierKeys[i].name); TQToolTip::add (icons[map], i18n (modifierKeys[i].name)); connect (icons[map], TQT_SIGNAL(stateChangeRequest (KeyIcon*,bool,bool)), TQT_SLOT(stateChangeRequest (KeyIcon*,bool,bool))); if (modifierKeys[i].isModifier) modifiers.append(icons[map]); else lockkeys.append(icons[map]); } } } bool KbStateApplet::x11Event (XEvent *evt) { if (evt->type == xkb_base_event_type + XkbEventCode) { XkbEvent *kbevt = (XkbEvent *)evt; switch (kbevt->any.xkb_type) { case XkbStateNotify: timerEvent (0); mouse->setState (kbevt->state.ptr_buttons); break; case XkbAccessXNotify: switch (kbevt->accessx.detail) { case XkbAXN_SKPress: slow->setGlyth(i18n("a (the first letter in the alphabet)", "a")); slow->setImage("unlatched"); break; case XkbAXN_SKAccept: slow->setImage("keypressok"); break; case XkbAXN_SKRelease: slow->setGlyth(" "); slow->setImage("kbstate_slowkeys"); break; case XkbAXN_SKReject: slow->setImage("keypressno", kbevt->accessx.sk_delay>150?kbevt->accessx.sk_delay:150); break; case XkbAXN_BKAccept: slow->setGlyth(i18n("a (the first letter in the alphabet)", "a")); bounce->setImage("keypressok", kbevt->accessx.sk_delay>150?kbevt->accessx.sk_delay:150); break; case XkbAXN_BKReject: slow->setGlyth(i18n("a (the first letter in the alphabet)", "a")); bounce->setImage("keypressno", kbevt->accessx.sk_delay>150?kbevt->accessx.sk_delay:150); break; } break; case XkbControlsNotify: { XkbControlsNotifyEvent* event = (XkbControlsNotifyEvent*)evt; accessxFeatures = event->enabled_ctrls; if ((accessxFeatures & XkbMouseKeysMask) != 0) { XkbGetControls (qt_xdisplay(), XkbMouseKeysMask, xkb); if (xkb->ctrls->mk_dflt_btn < 1) mouse->setActiveKey (1); else if (xkb->ctrls->mk_dflt_btn > 3) mouse->setActiveKey (1); else mouse->setActiveKey (xkb->ctrls->mk_dflt_btn); } else mouse->setActiveKey (0); layout(); updateGeometry(); emit updateLayout(); break; } case XkbExtensionDeviceNotify: /* This is a hack around the fact that XFree86's XKB doesn't give AltGr notifications */ break; default: break; } } return false; } void KbStateApplet::timerEvent(TQTimerEvent*) { XkbStateRec state_return; XkbGetState (this->x11Display(), XkbUseCoreKbd, &state_return); unsigned char latched = XkbStateMods (&state_return); unsigned char locked = XkbModLocks (&state_return); int mods = ((int)latched)<<8 | locked; if (state != mods) { state = mods; for (int i = 0; i < 8; i++) { if (icons[i]) icons[i]->setState ((latched&(1<x11Display(), XkbUseCoreKbd, 1<x11Display(), XkbUseCoreKbd, 1<x11Display(), XkbUseCoreKbd, 1<x11Display(), XkbUseCoreKbd, 1<x11Display(), XkbUseCoreKbd, 1<startServiceByDesktopName("kcmaccess"); } void KbStateApplet::configureKeyboard() { // The modulename "keyboard" is ambiguous on SuSE systems // as there is also a YaST-module called "keyboard". KProcess proc; proc << "kcmshell"; proc << "kde/keyboard"; proc.start(KProcess::DontCare); proc.detach(); } void KbStateApplet::configureMouse() { kapp->startServiceByDesktopName("mouse"); } void KbStateApplet::about() { KAboutData about("kbstateapplet", I18N_NOOP("Keyboard Status Applet"), "0.2", I18N_NOOP("Panel applet that shows the state of the modifier keys"), KAboutData::License_GPL_V2, "(C) 2004 Gunnar Schmi Dt"); KAboutApplication a(&about, this); a.exec(); } void KbStateApplet::loadConfig() { KConfig *c = config(); c->setGroup("General"); size = c->readNumEntry("IconDim", 20); fillSpace = c->readBoolEntry("fill space", true); showModifiers = c->readBoolEntry("Modifierkeys visible",true); showLockkeys = c->readBoolEntry("Lockkeys visible",true); showMouse = c->readBoolEntry("Mouse status visible",true); showAccessX = c->readBoolEntry("Slowkeys status visible",true); showAccessX = c->readBoolEntry("AccessX status visible",showAccessX); } void KbStateApplet::saveConfig() { KConfig *c = config(); c->setGroup("General"); c->writeEntry("IconDim", size); c->writeEntry("fill space", fillSpace); c->writeEntry("Modifierkeys visible", showModifiers); c->writeEntry("Lockkeys visible", showLockkeys); c->writeEntry("Mouse status visible", showMouse); c->writeEntry("AccessX status visible", showAccessX); c->sync(); } /********************************************************************/ KeyIcon::KeyIcon (int keyId, KInstance *instance, TQWidget *parent, const char *name) : StatusIcon (modifierKeys[keyId].name, parent, name) { this->instance = instance; this->keyId = keyId; this->tristate = (modifierKeys[keyId].isModifier); isLocked = false; isLatched = false; updateImages (); connect (this, TQT_SIGNAL(clicked()), TQT_SLOT(clickedSlot())); } KeyIcon::~KeyIcon () { } void KeyIcon::setState (bool latched, bool locked) { latched = latched | locked; isLatched = latched; isLocked = locked; update(); } void KeyIcon::clickedSlot () { if (tristate) emit stateChangeRequest (this, !isLocked, isLatched&!isLocked); else emit stateChangeRequest (this, false, !isLocked); } void KeyIcon::resizeEvent( TQResizeEvent*e ) { TQWidget::resizeEvent(e); updateImages(); } void KeyIcon::updateImages () { int size = width()iconLoader()->loadIcon("lock_overlay", KIcon::Panel, size-4); if (strcmp(modifierKeys[keyId].icon, "")) { latched = instance->iconLoader()->loadIcon(modifierKeys[keyId].icon, KIcon::NoGroup, size-4); unlatched = instance->iconLoader()->loadIcon(modifierKeys[keyId].icon, KIcon::NoGroup, size-4); TQImage img = latched.convertToImage(); KIconEffect::colorize(img, KGlobalSettings::highlightedTextColor(), 1.0); latched.convertFromImage (img); img = unlatched.convertToImage(); KIconEffect::colorize(img, KGlobalSettings::textColor(), 1.0); unlatched.convertFromImage (img); } update(); } void KeyIcon::drawButton (TQPainter *p) { TQColor black; int x = (width()-locked.width())/2; int y = (height()-locked.height())/2; int o = 0; if (isLocked || isLatched) { qDrawShadePanel (p, 0, 0, width(), height(), colorGroup(), true, 1, NULL); p->fillRect (1,1,width()-2,height()-2, KGlobalSettings::highlightColor()); if (strcmp(modifierKeys[keyId].icon, "")) p->drawPixmap (x+1,y+1, latched); black = KGlobalSettings::highlightedTextColor(); o = 1; } else { qDrawShadePanel (p, 0, 0, width(), height(), colorGroup(), false, 1, NULL); if (strcmp(modifierKeys[keyId].icon, "")) p->drawPixmap (x,y, unlatched); black = KGlobalSettings::textColor(); } TQString text = i18n(modifierKeys[keyId].text); if (!text.isEmpty() && !text.isNull()) { TQFont font = KGlobalSettings::generalFont(); font.setWeight(TQFont::Black); TQFontMetrics metrics(font); TQRect rect = metrics.boundingRect (text); int size; if (!strcmp(modifierKeys[keyId].name, "Alt Graph")) size = rect.width()>rect.height()?rect.width():rect.height(); else size = rect.width()>12*rect.height()/5?rect.width():12*rect.height()/5; if (font.pixelSize() != -1) font.setPixelSize (font.pixelSize()*width()*19/size/32); else font.setPointSizeFloat (font.pointSizeFloat()*width()*19/size/32); p->setPen (black); p->setFont (font); if (!strcmp(modifierKeys[keyId].name, "Alt Graph")) p->drawText (o,o, width(), height(), TQt::AlignCenter, text); else p->drawText (o,o, width(), height()*(251)/384, TQt::AlignCenter, text); } if (tristate && isLocked) { p->drawPixmap(x+o,y+o, locked); } } /********************************************************************/ MouseIcon::MouseIcon (KInstance *instance, TQWidget *parent, const char *name) : StatusIcon ("", parent, name) { this->instance = instance; state = 0; activekey = 0; updateImages (); connect (this, TQT_SIGNAL(clicked()), TQT_SLOT(clickedSlot())); } MouseIcon::~MouseIcon () { } void MouseIcon::setState (int state) { this->state = state; update(); } void MouseIcon::setActiveKey (int activekey) { this->activekey = activekey; update(); } void MouseIcon::resizeEvent( TQResizeEvent*e ) { TQWidget::resizeEvent(e); updateImages(); } TQPixmap loadIcon(KInstance *instance, int size, TQColor color, TQString name) { KIconLoader *loader = instance->iconLoader(); TQPixmap result = loader->loadIcon(name, KIcon::NoGroup, size); TQImage img = result.convertToImage(); KIconEffect::colorize(img, color, 1.0); result.convertFromImage (img); return result; } void MouseIcon::updateImages () { int size = width()drawPixmap(0,0, mouse); if ((state & Button1Mask) != 0) p->drawPixmap(0,0, leftSelected); if ((state & Button2Mask) != 0) p->drawPixmap(0,0, middleSelected); if ((state & Button3Mask) != 0) p->drawPixmap(0,0, rightSelected); switch (activekey) { case 0: break; case 1: if ((state & Button1Mask) != 0) p->drawPixmap(0,0, leftDotSelected); else p->drawPixmap(0,0, leftDot); break; case 2: if ((state & Button2Mask) != 0) p->drawPixmap(0,0, middleDotSelected); else p->drawPixmap(0,0, middleDot); break; case 3: if ((state & Button3Mask) != 0) p->drawPixmap(0,0, rightDotSelected); else p->drawPixmap(0,0, rightDot); break; } } /********************************************************************/ TimeoutIcon::TimeoutIcon (KInstance *instance, const TQString &text, const TQString &featurename, TQWidget *parent, const char *name) : StatusIcon (text, parent, name) { this->instance = instance; this->featurename = featurename; glyth = " "; setImage (featurename); connect (&timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeout())); } TimeoutIcon::~TimeoutIcon () { } void TimeoutIcon::update () { int size = width()iconLoader()->loadIcon(iconname, KIcon::NoGroup, size); TQImage img = pixmap.convertToImage(); KIconEffect::colorize(img, KGlobalSettings::textColor(), 1.0); pixmap.convertFromImage (img); image = pixmap; TQWidget::update(); } void TimeoutIcon::setGlyth (const TQString &glyth) { timer.stop(); this->glyth = glyth; TQImage img = pixmap.convertToImage(); KIconEffect::colorize(img, KGlobalSettings::textColor(), 1.0); pixmap.convertFromImage (img); image = pixmap; update(); } void TimeoutIcon::setImage (const TQString &name, int timeout) { timer.stop(); iconname = name; if (!name.isNull() && !name.isEmpty()) { int size = width()iconLoader()->loadIcon(iconname, KIcon::NoGroup, size); TQImage img = pixmap.convertToImage(); KIconEffect::colorize(img, KGlobalSettings::textColor(), 1.0); pixmap.convertFromImage (img); image = pixmap; } update(); if (timeout > 0) timer.start (timeout, true); } void TimeoutIcon::timeout () { setGlyth (" "); setImage(featurename); } void TimeoutIcon::drawButton (TQPainter *p) { TQString text = glyth; int count = 1; int factor = 19; if (!iconname.isNull() && !iconname.isEmpty()) p->drawPixmap(0,0, image); else if (glyth == " ") { text = i18n("a (the first letter in the alphabet)", "a"); count = 3; factor = 64; } TQFont font = KGlobalSettings::generalFont(); font.setWeight(TQFont::Black); TQFontMetrics metrics(font); TQRect rect = metrics.boundingRect (text); int size = count*rect.width() > rect.height() ? count*rect.width() : rect.height(); if (font.pixelSize() != -1) font.setPixelSize (font.pixelSize()*width()*factor/size/64); else font.setPointSizeFloat (font.pointSizeFloat()*width()*factor/size/64); p->setFont (font); if (count == 1) { p->setPen (KGlobalSettings::textColor()); p->drawText (0,0, width()/2, height()/2, TQt::AlignCenter, text); } else { TQColor t = KGlobalSettings::textColor(); TQColor b = KGlobalSettings::baseColor(); p->setPen (TQColor ((2*t.red()+3*b.red())/5, (2*t.green()+3*b.green())/5, (2*t.blue()+3*b.blue())/5)); p->drawText (width()/2,0, width()/2, height(), TQt::AlignCenter, text); p->setPen (TQColor ((2*t.red()+b.red())/3, (2*t.green()+b.green())/3, (2*t.blue()+b.blue())/3)); p->drawText (0,0, width(), height(), TQt::AlignCenter, text); p->setPen (KGlobalSettings::textColor()); p->drawText (0,0, width()/2, height(), TQt::AlignCenter, text); } } /********************************************************************/ StatusIcon::StatusIcon (const TQString &text, TQWidget *parent, const char *name) : TQPushButton (text, parent, name) { setSizePolicy(TQSizePolicy(TQSizePolicy::Ignored, TQSizePolicy::Ignored)); } StatusIcon::~StatusIcon () { } TQSize StatusIcon::minimumSizeHint () const { return TQSize (0,0); }