KDEUI
kcheckaccelerators.cpp
Go to the documentation of this file.
00001 /* This file is part of the KDE libraries 00002 Copyright (C) 1997 Matthias Kalle Dalheimer (kalle@kde.org) 00003 Copyright (C) 1998, 1999, 2000 KDE Team 00004 Copyright (C) 2008 Nick Shaforostoff <shaforostoff@kde.ru> 00005 00006 This library is free software; you can redistribute it and/or 00007 modify it under the terms of the GNU Library General Public 00008 License as published by the Free Software Foundation; either 00009 version 2 of the License, or (at your option) any later version. 00010 00011 This library is distributed in the hope that it will be useful, 00012 but WITHOUT ANY WARRANTY; without even the implied warranty of 00013 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 00014 Library General Public License for more details. 00015 00016 You should have received a copy of the GNU Library General Public License 00017 along with this library; see the file COPYING.LIB. If not, write to 00018 the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, 00019 Boston, MA 02110-1301, USA. 00020 */ 00021 00022 #define INCLUDE_MENUITEM_DEF 00023 00024 #include "kcheckaccelerators.h" 00025 00026 #include <config.h> 00027 00028 #include <QApplication> 00029 #include <QCheckBox> 00030 #include <QDialog> 00031 #include <QShortcutEvent> 00032 #include <QMouseEvent> 00033 #include <QLayout> 00034 #include <QMenuBar> 00035 #include <QMetaObject> 00036 #include <QPushButton> 00037 #include <QTabBar> 00038 00039 #include <QLabel> 00040 #include <QComboBox> 00041 #include <QGroupBox> 00042 #include <QClipboard> 00043 #include <QProcess> 00044 00045 #include <kconfig.h> 00046 #include <kdebug.h> 00047 #include <kglobal.h> 00048 #include <kcomponentdata.h> 00049 #include <klocale.h> 00050 #include <kshortcut.h> 00051 #include <ktextbrowser.h> 00052 00053 #include "kacceleratormanager.h" 00054 #include <kconfiggroup.h> 00055 00056 void KCheckAccelerators::initiateIfNeeded(QObject* parent) 00057 { 00058 KConfigGroup cg( KGlobal::config(), "Development" ); 00059 QString sKey = cg.readEntry( "CheckAccelerators" ).trimmed(); 00060 int key=0; 00061 if( !sKey.isEmpty() ) { 00062 KShortcut cuts( sKey ); 00063 if( !cuts.isEmpty() ) 00064 key = cuts.primary()[0]; 00065 } 00066 bool autoCheck = cg.readEntry( "AutoCheckAccelerators", true ); 00067 bool copyWidgetText = cg.readEntry( "CopyWidgetText", false ); 00068 00069 if (!copyWidgetText && key==0 && !autoCheck) 00070 return; 00071 00072 new KCheckAccelerators(parent, key, autoCheck, copyWidgetText); 00073 } 00074 00075 KCheckAccelerators::KCheckAccelerators(QObject* parent, int key_, bool autoCheck_, bool copyWidgetText_) 00076 : QObject(parent) 00077 , key(key_) 00078 , block(false) 00079 , autoCheck(autoCheck_) 00080 , copyWidgetText(copyWidgetText_) 00081 , drklash(0) 00082 { 00083 setObjectName( "kapp_accel_filter" ); 00084 00085 KConfigGroup cg( KGlobal::config(), "Development" ); 00086 alwaysShow = cg.readEntry( "AlwaysShowCheckAccelerators", false ); 00087 copyWidgetTextCommand = cg.readEntry( "CopyWidgetTextCommand", "" ); 00088 00089 parent->installEventFilter( this ); 00090 connect( &autoCheckTimer, SIGNAL(timeout()), SLOT(autoCheckSlot())); 00091 } 00092 00093 bool KCheckAccelerators::eventFilter(QObject* obj, QEvent* e) 00094 { 00095 if ( block ) 00096 return false; 00097 00098 switch ( e->type() ) { // just simplify debuggin 00099 case QEvent::ShortcutOverride: 00100 if ( key && (static_cast<QKeyEvent*>(e)->key() == key) ) { 00101 block = true; 00102 checkAccelerators( false ); 00103 block = false; 00104 e->accept(); 00105 return true; 00106 } 00107 break; 00108 case QEvent::ChildAdded: 00109 case QEvent::ChildRemoved: 00110 // Only care about widgets; this also avoids starting the timer in other threads 00111 if ( !static_cast<QChildEvent *>(e)->child()->isWidgetType() ) 00112 break; 00113 // fall-through 00114 case QEvent::Resize: 00115 case QEvent::LayoutRequest: 00116 case QEvent::WindowActivate: 00117 case QEvent::WindowDeactivate: 00118 if( autoCheck ) { 00119 autoCheckTimer.setSingleShot( true ); 00120 autoCheckTimer.start( 20 ); // 20 ms 00121 } 00122 break; 00123 //case QEvent::MouseButtonDblClick: 00124 case QEvent::MouseButtonPress: 00125 if ( copyWidgetText && static_cast<QMouseEvent*>(e)->button() == Qt::MidButton ) { 00126 //kWarning()<<"obj"<<obj; 00127 QWidget* w=static_cast<QWidget*>(obj)->childAt(static_cast<QMouseEvent*>(e)->pos()); 00128 if (!w) 00129 w=static_cast<QWidget*>(obj); 00130 if (!w) 00131 return false; 00132 //kWarning()<<"MouseButtonDblClick"<<w; 00133 QString text; 00134 if (qobject_cast<QLabel*>(w)) 00135 text=static_cast<QLabel*>(w)->text(); 00136 else if (qobject_cast<QAbstractButton*>(w)) 00137 text=static_cast<QAbstractButton*>(w)->text(); 00138 else if (qobject_cast<QComboBox*>(w)) 00139 text=static_cast<QComboBox*>(w)->currentText(); 00140 else if (qobject_cast<QTabBar*>(w)) 00141 text=static_cast<QTabBar*>(w)->tabText( static_cast<QTabBar*>(w)->tabAt(static_cast<QMouseEvent*>(e)->pos()) ); 00142 else if (qobject_cast<QGroupBox*>(w)) 00143 text=static_cast<QGroupBox*>(w)->title(); 00144 else if (qobject_cast<QMenu*>(obj)) 00145 { 00146 QAction* a=static_cast<QMenu*>(obj)->actionAt(static_cast<QMouseEvent*>(e)->pos()); 00147 if (!a) 00148 return false; 00149 text=a->text(); 00150 if (text.isEmpty()) 00151 text=a->iconText(); 00152 } 00153 if (text.isEmpty()) 00154 return false; 00155 00156 if (static_cast<QMouseEvent*>(e)->modifiers() == Qt::ControlModifier) 00157 text.remove('&'); 00158 00159 //kWarning()<<KGlobal::activeComponent().catalogName()<<text; 00160 if (copyWidgetTextCommand.isEmpty()) 00161 { 00162 QClipboard *clipboard = QApplication::clipboard(); 00163 clipboard->setText(text); 00164 } 00165 else 00166 { 00167 QProcess* script=new QProcess(this); 00168 script->start(copyWidgetTextCommand.arg(text).arg(KGlobal::activeComponent().catalogName())); 00169 connect(script,SIGNAL(finished(int,QProcess::ExitStatus)),script,SLOT(deleteLater())); 00170 } 00171 e->accept(); 00172 return true; 00173 00174 //kWarning()<<"MouseButtonDblClick"<<static_cast<QWidget*>(obj)->childAt(static_cast<QMouseEvent*>(e)->globalPos()); 00175 } 00176 return false; 00177 case QEvent::Timer: 00178 case QEvent::MouseMove: 00179 case QEvent::Paint: 00180 return false; 00181 default: 00182 // kDebug(125) << "KCheckAccelerators::eventFilter " << e->type() << " " << autoCheck; 00183 break; 00184 } 00185 return false; 00186 } 00187 00188 void KCheckAccelerators::autoCheckSlot() 00189 { 00190 if( block ) 00191 { 00192 autoCheckTimer.setSingleShot( true ); 00193 autoCheckTimer.start( 20 ); 00194 return; 00195 } 00196 block = true; 00197 checkAccelerators( !alwaysShow ); 00198 block = false; 00199 } 00200 00201 void KCheckAccelerators::createDialog(QWidget *actWin, bool automatic) 00202 { 00203 if ( drklash ) 00204 return; 00205 00206 drklash = new QDialog( actWin ); 00207 drklash->setAttribute( Qt::WA_DeleteOnClose ); 00208 drklash->setObjectName( "kapp_accel_check_dlg" ); 00209 drklash->setWindowTitle( i18nc("@title:window", "Dr. Klash' Accelerator Diagnosis" )); 00210 drklash->resize( 500, 460 ); 00211 QVBoxLayout* layout = new QVBoxLayout( drklash ); 00212 drklash_view = new KTextBrowser( drklash ); 00213 layout->addWidget( drklash_view); 00214 QCheckBox* disableAutoCheck = NULL; 00215 if( automatic ) { 00216 disableAutoCheck = new QCheckBox( i18nc("@option:check","Disable automatic checking" ), drklash ); 00217 connect(disableAutoCheck, SIGNAL(toggled(bool)), SLOT(slotDisableCheck(bool))); 00218 layout->addWidget( disableAutoCheck ); 00219 } 00220 QPushButton* btnClose = new QPushButton( i18nc("@action:button", "Close" ), drklash ); 00221 btnClose->setDefault( true ); 00222 layout->addWidget( btnClose ); 00223 connect( btnClose, SIGNAL(clicked()), drklash, SLOT(close()) ); 00224 if (disableAutoCheck) 00225 disableAutoCheck->setFocus(); 00226 else 00227 drklash_view->setFocus(); 00228 } 00229 00230 void KCheckAccelerators::slotDisableCheck(bool on) 00231 { 00232 autoCheck = !on; 00233 if (!on) 00234 autoCheckSlot(); 00235 } 00236 00237 void KCheckAccelerators::checkAccelerators( bool automatic ) 00238 { 00239 QWidget* actWin = qApp->activeWindow(); 00240 if ( !actWin ) 00241 return; 00242 00243 KAcceleratorManager::manage(actWin); 00244 QString a, c, r; 00245 KAcceleratorManager::last_manage(a, c, r); 00246 00247 if (automatic) // for now we only show dialogs on F12 checks 00248 return; 00249 00250 if (c.isEmpty() && r.isEmpty() && (automatic || a.isEmpty())) 00251 return; 00252 00253 QString s; 00254 00255 if ( ! c.isEmpty() ) { 00256 s += i18n("<h2>Accelerators changed</h2>"); 00257 s += "<table border><tr><th><b>Old Text</b></th><th><b>New Text</b></th></tr>" 00258 + c + "</table>"; 00259 } 00260 00261 if ( ! r.isEmpty() ) { 00262 s += i18n("<h2>Accelerators removed</h2>"); 00263 s += "<table border><tr><th><b>Old Text</b></th></tr>" + r + "</table>"; 00264 } 00265 00266 if ( ! a.isEmpty() ) { 00267 s += i18n("<h2>Accelerators added (just for your info)</h2>"); 00268 s += "<table border><tr><th><b>New Text</b></th></tr>" + a + "</table>"; 00269 } 00270 00271 createDialog(actWin, automatic); 00272 drklash_view->setHtml(s); 00273 drklash->show(); 00274 drklash->raise(); 00275 00276 // dlg will be destroyed before returning 00277 } 00278 00279 #include "kcheckaccelerators.moc"
KDE 4.6 API Reference