/* This file is part of the KDE libraries Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) Copyright (C) 1998, 1999, 2000 KDE Team Copyright (C) 2008 Nick Shaforostoff This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #define INCLUDE_MENUITEM_DEF #include "kcheckaccelerators.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "kacceleratormanager.h" #include void KCheckAccelerators::initiateIfNeeded(QObject* parent) { KConfigGroup cg( KGlobal::config(), "Development" ); QString sKey = cg.readEntry( "CheckAccelerators" ).trimmed(); int key=0; if( !sKey.isEmpty() ) { KShortcut cuts( sKey ); if( !cuts.isEmpty() ) key = cuts.primary()[0]; } bool autoCheck = cg.readEntry( "AutoCheckAccelerators", true ); bool copyWidgetText = cg.readEntry( "CopyWidgetText", false ); if (!copyWidgetText && key==0 && !autoCheck) return; new KCheckAccelerators(parent, key, autoCheck, copyWidgetText); } KCheckAccelerators::KCheckAccelerators(QObject* parent, int key_, bool autoCheck_, bool copyWidgetText_) : QObject(parent) , key(key_) , block(false) , autoCheck(autoCheck_) , copyWidgetText(copyWidgetText_) , drklash(0) { setObjectName( "kapp_accel_filter" ); KConfigGroup cg( KGlobal::config(), "Development" ); alwaysShow = cg.readEntry( "AlwaysShowCheckAccelerators", false ); copyWidgetTextCommand = cg.readEntry( "CopyWidgetTextCommand", "" ); parent->installEventFilter( this ); connect( &autoCheckTimer, SIGNAL(timeout()), SLOT(autoCheckSlot())); } bool KCheckAccelerators::eventFilter(QObject* obj, QEvent* e) { if ( block ) return false; switch ( e->type() ) { // just simplify debuggin case QEvent::ShortcutOverride: if ( key && (static_cast(e)->key() == key) ) { block = true; checkAccelerators( false ); block = false; e->accept(); return true; } break; case QEvent::ChildAdded: case QEvent::ChildRemoved: // Only care about widgets; this also avoids starting the timer in other threads if ( !static_cast(e)->child()->isWidgetType() ) break; // fall-through case QEvent::Resize: case QEvent::LayoutRequest: case QEvent::WindowActivate: case QEvent::WindowDeactivate: if( autoCheck ) { autoCheckTimer.setSingleShot( true ); autoCheckTimer.start( 20 ); // 20 ms } break; //case QEvent::MouseButtonDblClick: case QEvent::MouseButtonPress: if ( copyWidgetText && static_cast(e)->button() == Qt::MidButton ) { //kWarning()<<"obj"<(obj)->childAt(static_cast(e)->pos()); if (!w) w=static_cast(obj); if (!w) return false; //kWarning()<<"MouseButtonDblClick"<(w)) text=static_cast(w)->text(); else if (qobject_cast(w)) text=static_cast(w)->text(); else if (qobject_cast(w)) text=static_cast(w)->currentText(); else if (qobject_cast(w)) text=static_cast(w)->tabText( static_cast(w)->tabAt(static_cast(e)->pos()) ); else if (qobject_cast(w)) text=static_cast(w)->title(); else if (qobject_cast(obj)) { QAction* a=static_cast(obj)->actionAt(static_cast(e)->pos()); if (!a) return false; text=a->text(); if (text.isEmpty()) text=a->iconText(); } if (text.isEmpty()) return false; if (static_cast(e)->modifiers() == Qt::ControlModifier) text.remove('&'); //kWarning()<setText(text); } else { QProcess* script=new QProcess(this); script->start(copyWidgetTextCommand.arg(text).arg(KGlobal::activeComponent().catalogName())); connect(script,SIGNAL(finished(int,QProcess::ExitStatus)),script,SLOT(deleteLater())); } e->accept(); return true; //kWarning()<<"MouseButtonDblClick"<(obj)->childAt(static_cast(e)->globalPos()); } return false; case QEvent::Timer: case QEvent::MouseMove: case QEvent::Paint: return false; default: // kDebug(125) << "KCheckAccelerators::eventFilter " << e->type() << " " << autoCheck; break; } return false; } void KCheckAccelerators::autoCheckSlot() { if( block ) { autoCheckTimer.setSingleShot( true ); autoCheckTimer.start( 20 ); return; } block = true; checkAccelerators( !alwaysShow ); block = false; } void KCheckAccelerators::createDialog(QWidget *actWin, bool automatic) { if ( drklash ) return; drklash = new QDialog( actWin ); drklash->setAttribute( Qt::WA_DeleteOnClose ); drklash->setObjectName( "kapp_accel_check_dlg" ); drklash->setWindowTitle( i18nc("@title:window", "Dr. Klash' Accelerator Diagnosis" )); drklash->resize( 500, 460 ); QVBoxLayout* layout = new QVBoxLayout( drklash ); drklash_view = new KTextBrowser( drklash ); layout->addWidget( drklash_view); QCheckBox* disableAutoCheck = NULL; if( automatic ) { disableAutoCheck = new QCheckBox( i18nc("@option:check","Disable automatic checking" ), drklash ); connect(disableAutoCheck, SIGNAL(toggled(bool)), SLOT(slotDisableCheck(bool))); layout->addWidget( disableAutoCheck ); } QPushButton* btnClose = new QPushButton( i18nc("@action:button", "Close" ), drklash ); btnClose->setDefault( true ); layout->addWidget( btnClose ); connect( btnClose, SIGNAL(clicked()), drklash, SLOT(close()) ); if (disableAutoCheck) disableAutoCheck->setFocus(); else drklash_view->setFocus(); } void KCheckAccelerators::slotDisableCheck(bool on) { autoCheck = !on; if (!on) autoCheckSlot(); } void KCheckAccelerators::checkAccelerators( bool automatic ) { QWidget* actWin = qApp->activeWindow(); if ( !actWin ) return; KAcceleratorManager::manage(actWin); QString a, c, r; KAcceleratorManager::last_manage(a, c, r); if (automatic) // for now we only show dialogs on F12 checks return; if (c.isEmpty() && r.isEmpty() && (automatic || a.isEmpty())) return; QString s; if ( ! c.isEmpty() ) { s += i18n("

Accelerators changed

"); s += "" + c + "
Old TextNew Text
"; } if ( ! r.isEmpty() ) { s += i18n("

Accelerators removed

"); s += "" + r + "
Old Text
"; } if ( ! a.isEmpty() ) { s += i18n("

Accelerators added (just for your info)

"); s += "" + a + "
New Text
"; } createDialog(actWin, automatic); drklash_view->setHtml(s); drklash->show(); drklash->raise(); // dlg will be destroyed before returning } #include "moc_kcheckaccelerators.cpp"