00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #include "config.h"
00022
00023 #undef QT_NO_TRANSLATION
00024 #include <qtranslator.h>
00025 #define QT_NO_TRANSLATION
00026 #include <qdir.h>
00027 #include <qptrcollection.h>
00028 #include <qwidgetlist.h>
00029 #include <qstrlist.h>
00030 #include <qfile.h>
00031 #include <qmessagebox.h>
00032 #include <qtextstream.h>
00033 #include <qregexp.h>
00034 #include <qlineedit.h>
00035 #include <qtextedit.h>
00036 #include <qsessionmanager.h>
00037 #include <qptrlist.h>
00038 #include <qtimer.h>
00039 #include <qstylesheet.h>
00040 #include <qpixmapcache.h>
00041 #include <qtooltip.h>
00042 #include <qstylefactory.h>
00043 #include <qmetaobject.h>
00044 #ifndef QT_NO_SQL
00045 #include <qsqlpropertymap.h>
00046 #endif
00047
00048 #undef QT_NO_TRANSLATION
00049 #include "kapplication.h"
00050 #define QT_NO_TRANSLATION
00051 #include <kglobal.h>
00052 #include <kstandarddirs.h>
00053 #include <kdebug.h>
00054 #include <klocale.h>
00055 #include <kstyle.h>
00056 #include <kiconloader.h>
00057 #include <kclipboard.h>
00058 #include <kconfig.h>
00059 #include <ksimpleconfig.h>
00060 #include <kcmdlineargs.h>
00061 #include <kaboutdata.h>
00062 #include <kglobalsettings.h>
00063 #include <kcrash.h>
00064 #include <kdatastream.h>
00065 #include <klibloader.h>
00066 #include <kmimesourcefactory.h>
00067 #include <kstdaccel.h>
00068 #include <kaccel.h>
00069 #include "kcheckaccelerators.h"
00070 #include <qptrdict.h>
00071 #include <kmacroexpander.h>
00072 #include <kshell.h>
00073 #include <kprotocolinfo.h>
00074 #include <kkeynative.h>
00075 #include <kmdcodec.h>
00076
00077 #if defined Q_WS_X11
00078 #include <kstartupinfo.h>
00079 #endif
00080
00081 #include <dcopclient.h>
00082 #include <dcopref.h>
00083
00084 #include <sys/types.h>
00085 #ifdef HAVE_SYS_STAT_H
00086 #include <sys/stat.h>
00087 #endif
00088 #include <sys/wait.h>
00089
00090 #ifndef Q_WS_WIN
00091 #include "kwin.h"
00092 #endif
00093
00094 #include <fcntl.h>
00095 #include <stdlib.h>
00096 #include <signal.h>
00097 #include <unistd.h>
00098 #include <time.h>
00099 #include <sys/time.h>
00100 #include <errno.h>
00101 #include <string.h>
00102 #include <netdb.h>
00103 #if defined Q_WS_X11
00104
00105 #include <netwm.h>
00106 #endif
00107
00108 #include "kprocctrl.h"
00109
00110 #ifdef HAVE_PATHS_H
00111 #include <paths.h>
00112 #endif
00113
00114 #ifdef Q_WS_X11
00115 #include <X11/Xlib.h>
00116 #include <X11/Xutil.h>
00117 #include <X11/Xatom.h>
00118 #include <X11/SM/SMlib.h>
00119 #include <fixx11h.h>
00120 #endif
00121
00122 #ifndef Q_WS_WIN
00123 #include <KDE-ICE/ICElib.h>
00124 #else
00125 typedef void* IceIOErrorHandler;
00126 #include <windows.h>
00127
00128 #define Button1Mask (1<<8)
00129 #define Button2Mask (1<<9)
00130 #define Button3Mask (1<<10)
00131 #endif
00132
00133 #ifdef Q_WS_X11
00134 #define DISPLAY "DISPLAY"
00135 #elif defined(Q_WS_QWS)
00136 #define DISPLAY "QWS_DISPLAY"
00137 #endif
00138
00139 #if defined Q_WS_X11
00140 #include <kipc.h>
00141 #endif
00142
00143 #ifdef Q_WS_MACX
00144 #include <Carbon/Carbon.h>
00145 #include <qimage.h>
00146 #endif
00147
00148 #include "kappdcopiface.h"
00149
00150
00151 KDE_EXPORT bool kde_have_kipc = true;
00152 bool kde_kiosk_exception = false;
00153 bool kde_kiosk_admin = false;
00154
00155 KApplication* KApplication::KApp = 0L;
00156 bool KApplication::loadedByKdeinit = false;
00157 DCOPClient *KApplication::s_DCOPClient = 0L;
00158 bool KApplication::s_dcopClientNeedsPostInit = false;
00159
00160 #ifdef Q_WS_X11
00161 static Atom atom_DesktopWindow;
00162 static Atom atom_NetSupported;
00163 extern Time qt_x_time;
00164 extern Time qt_x_user_time;
00165 static Atom kde_xdnd_drop;
00166 #endif
00167
00168
00169
00170 KDECORE_EXPORT bool qt_qclipboard_bailout_hack = false;
00171
00172 template class QPtrList<KSessionManaged>;
00173
00174 #ifdef Q_WS_X11
00175 extern "C" {
00176 static int kde_xio_errhandler( Display * dpy )
00177 {
00178 return kapp->xioErrhandler( dpy );
00179 }
00180
00181 static int kde_x_errhandler( Display *dpy, XErrorEvent *err )
00182 {
00183 return kapp->xErrhandler( dpy, err );
00184 }
00185
00186 }
00187
00188 extern "C" {
00189 static void kde_ice_ioerrorhandler( IceConn conn )
00190 {
00191 if(kapp)
00192 kapp->iceIOErrorHandler( conn );
00193
00194 }
00195 }
00196 #endif
00197
00198 #ifdef Q_WS_WIN
00199 void KApplication_init_windows(bool GUIenabled);
00200
00201 class QAssistantClient;
00202 #endif
00203
00204
00205
00206
00207 class KApplicationPrivate
00208 {
00209 public:
00210 KApplicationPrivate()
00211 : actionRestrictions( false ),
00212 refCount( 1 ),
00213 oldIceIOErrorHandler( 0 ),
00214 checkAccelerators( 0 ),
00215 overrideStyle( QString::null ),
00216 startup_id( "0" ),
00217 app_started_timer( NULL ),
00218 m_KAppDCOPInterface( 0L ),
00219 session_save( false )
00220 #ifdef Q_WS_X11
00221 ,oldXErrorHandler( NULL )
00222 ,oldXIOErrorHandler( NULL )
00223 #elif defined Q_WS_WIN
00224 ,qassistantclient( 0 )
00225 #endif
00226 {
00227 }
00228
00229 ~KApplicationPrivate()
00230 {
00231 #ifdef Q_WS_WIN
00232 delete qassistantclient;
00233 #endif
00234 }
00235
00236
00237 bool actionRestrictions : 1;
00238 bool guiEnabled : 1;
00245 int refCount;
00246 IceIOErrorHandler oldIceIOErrorHandler;
00247 KCheckAccelerators* checkAccelerators;
00248 QString overrideStyle;
00249 QString geometry_arg;
00250 QCString startup_id;
00251 QTimer* app_started_timer;
00252 KAppDCOPInterface *m_KAppDCOPInterface;
00253 bool session_save;
00254 #ifdef Q_WS_X11
00255 int (*oldXErrorHandler)(Display*,XErrorEvent*);
00256 int (*oldXIOErrorHandler)(Display*);
00257 #elif defined Q_WS_WIN
00258 QAssistantClient* qassistantclient;
00259 #endif
00260
00261 class URLActionRule
00262 {
00263 public:
00264 #define checkExactMatch(s, b) \
00265 if (s.isEmpty()) b = true; \
00266 else if (s[s.length()-1] == '!') \
00267 { b = false; s.truncate(s.length()-1); } \
00268 else b = true;
00269 #define checkStartWildCard(s, b) \
00270 if (s.isEmpty()) b = true; \
00271 else if (s[0] == '*') \
00272 { b = true; s = s.mid(1); } \
00273 else b = false;
00274 #define checkEqual(s, b) \
00275 b = (s == "=");
00276
00277 URLActionRule(const QString &act,
00278 const QString &bProt, const QString &bHost, const QString &bPath,
00279 const QString &dProt, const QString &dHost, const QString &dPath,
00280 bool perm)
00281 : action(act),
00282 baseProt(bProt), baseHost(bHost), basePath(bPath),
00283 destProt(dProt), destHost(dHost), destPath(dPath),
00284 permission(perm)
00285 {
00286 checkExactMatch(baseProt, baseProtWildCard);
00287 checkStartWildCard(baseHost, baseHostWildCard);
00288 checkExactMatch(basePath, basePathWildCard);
00289 checkExactMatch(destProt, destProtWildCard);
00290 checkStartWildCard(destHost, destHostWildCard);
00291 checkExactMatch(destPath, destPathWildCard);
00292 checkEqual(destProt, destProtEqual);
00293 checkEqual(destHost, destHostEqual);
00294 }
00295
00296 bool baseMatch(const KURL &url, const QString &protClass)
00297 {
00298 if (baseProtWildCard)
00299 {
00300 if ( !baseProt.isEmpty() && !url.protocol().startsWith(baseProt) &&
00301 (protClass.isEmpty() || (protClass != baseProt)) )
00302 return false;
00303 }
00304 else
00305 {
00306 if ( (url.protocol() != baseProt) &&
00307 (protClass.isEmpty() || (protClass != baseProt)) )
00308 return false;
00309 }
00310 if (baseHostWildCard)
00311 {
00312 if (!baseHost.isEmpty() && !url.host().endsWith(baseHost))
00313 return false;
00314 }
00315 else
00316 {
00317 if (url.host() != baseHost)
00318 return false;
00319 }
00320 if (basePathWildCard)
00321 {
00322 if (!basePath.isEmpty() && !url.path().startsWith(basePath))
00323 return false;
00324 }
00325 else
00326 {
00327 if (url.path() != basePath)
00328 return false;
00329 }
00330 return true;
00331 }
00332
00333 bool destMatch(const KURL &url, const QString &protClass, const KURL &base, const QString &baseClass)
00334 {
00335 if (destProtEqual)
00336 {
00337 if ( (url.protocol() != base.protocol()) &&
00338 (protClass.isEmpty() || baseClass.isEmpty() || protClass != baseClass) )
00339 return false;
00340 }
00341 else if (destProtWildCard)
00342 {
00343 if ( !destProt.isEmpty() && !url.protocol().startsWith(destProt) &&
00344 (protClass.isEmpty() || (protClass != destProt)) )
00345 return false;
00346 }
00347 else
00348 {
00349 if ( (url.protocol() != destProt) &&
00350 (protClass.isEmpty() || (protClass != destProt)) )
00351 return false;
00352 }
00353 if (destHostWildCard)
00354 {
00355 if (!destHost.isEmpty() && !url.host().endsWith(destHost))
00356 return false;
00357 }
00358 else if (destHostEqual)
00359 {
00360 if (url.host() != base.host())
00361 return false;
00362 }
00363 else
00364 {
00365 if (url.host() != destHost)
00366 return false;
00367 }
00368 if (destPathWildCard)
00369 {
00370 if (!destPath.isEmpty() && !url.path().startsWith(destPath))
00371 return false;
00372 }
00373 else
00374 {
00375 if (url.path() != destPath)
00376 return false;
00377 }
00378 return true;
00379 }
00380
00381 QString action;
00382 QString baseProt;
00383 QString baseHost;
00384 QString basePath;
00385 QString destProt;
00386 QString destHost;
00387 QString destPath;
00388 bool baseProtWildCard : 1;
00389 bool baseHostWildCard : 1;
00390 bool basePathWildCard : 1;
00391 bool destProtWildCard : 1;
00392 bool destHostWildCard : 1;
00393 bool destPathWildCard : 1;
00394 bool destProtEqual : 1;
00395 bool destHostEqual : 1;
00396 bool permission;
00397 };
00398 QPtrList<URLActionRule> urlActionRestrictions;
00399
00400 QString sessionKey;
00401 QString pSessionConfigFile;
00402 };
00403
00404
00405 static QPtrList<QWidget>*x11Filter = 0;
00406 static bool autoDcopRegistration = true;
00407
00408 void KApplication::installX11EventFilter( QWidget* filter )
00409 {
00410 if ( !filter )
00411 return;
00412 if (!x11Filter)
00413 x11Filter = new QPtrList<QWidget>;
00414 connect ( filter, SIGNAL( destroyed() ), this, SLOT( x11FilterDestroyed() ) );
00415 x11Filter->append( filter );
00416 }
00417
00418 void KApplication::x11FilterDestroyed()
00419 {
00420 removeX11EventFilter( static_cast< const QWidget* >( sender()));
00421 }
00422
00423 void KApplication::removeX11EventFilter( const QWidget* filter )
00424 {
00425 if ( !x11Filter || !filter )
00426 return;
00427 x11Filter->removeRef( filter );
00428 if ( x11Filter->isEmpty() ) {
00429 delete x11Filter;
00430 x11Filter = 0;
00431 }
00432 }
00433
00434
00435
00436
00437
00438 extern bool kde_g_bKillAccelOverride;
00439
00440 bool KApplication::notify(QObject *receiver, QEvent *event)
00441 {
00442 QEvent::Type t = event->type();
00443 if (kde_g_bKillAccelOverride)
00444 {
00445 kde_g_bKillAccelOverride = false;
00446
00447 if (t == QEvent::AccelOverride)
00448 {
00449 static_cast<QKeyEvent *>(event)->accept();
00450 return true;
00451 }
00452 else
00453 kdWarning(125) << "kde_g_bKillAccelOverride set, but received an event other than AccelOverride." << endl;
00454 }
00455
00456 if ((t == QEvent::AccelOverride) || (t == QEvent::KeyPress))
00457 {
00458 static const KShortcut& _selectAll = KStdAccel::selectAll();
00459 QLineEdit *edit = ::qt_cast<QLineEdit *>(receiver);
00460 if (edit)
00461 {
00462
00463 QKeyEvent *kevent = static_cast<QKeyEvent *>(event);
00464 KKey key(kevent);
00465 if (_selectAll.contains(key))
00466 {
00467 if (t == QEvent::KeyPress)
00468 {
00469 edit->selectAll();
00470 return true;
00471 }
00472 else
00473 {
00474 kevent->accept();
00475 }
00476 }
00477
00478 if (key == KKey(Qt::CTRL + Qt::Key_U))
00479 {
00480 if (t == QEvent::KeyPress)
00481 {
00482 if (!edit->isReadOnly())
00483 {
00484 QString t(edit->text());
00485 t = t.mid(edit->cursorPosition());
00486 edit->validateAndSet(t, 0, 0, 0);
00487 }
00488 return true;
00489 }
00490 else
00491 {
00492 kevent->accept();
00493 }
00494
00495 }
00496 }
00497 QTextEdit *medit = ::qt_cast<QTextEdit *>(receiver);
00498 if (medit)
00499 {
00500
00501 QKeyEvent *kevent = static_cast<QKeyEvent *>(event);
00502 if (_selectAll.contains(KKey(kevent)))
00503 {
00504 if (t == QEvent::KeyPress)
00505 {
00506 medit->selectAll();
00507 return true;
00508 }
00509 else
00510 {
00511 kevent->accept();
00512 }
00513 }
00514 }
00515 }
00516 if( t == QEvent::Show && receiver->isWidgetType())
00517 {
00518 QWidget* w = static_cast< QWidget* >( receiver );
00519 #if defined Q_WS_X11
00520 if( w->isTopLevel() && !startupId().isEmpty())
00521 KStartupInfo::setWindowStartupId( w->winId(), startupId());
00522 #endif
00523 if( w->isTopLevel() && !w->testWFlags( WX11BypassWM ) && !w->isPopup() && !event->spontaneous())
00524 {
00525 if( d->app_started_timer == NULL )
00526 {
00527 d->app_started_timer = new QTimer( this );
00528 connect( d->app_started_timer, SIGNAL( timeout()), SLOT( checkAppStartedSlot()));
00529 }
00530 if( !d->app_started_timer->isActive())
00531 d->app_started_timer->start( 0, true );
00532 }
00533 if( w->isTopLevel() && ( w->icon() == NULL || w->icon()->isNull()))
00534 {
00535
00536 static QPixmap* ic = NULL;
00537 if( ic == NULL )
00538 ic = new QPixmap( KGlobal::iconLoader()->loadIcon( iconName(),
00539 KIcon::NoGroup, 0, KIcon::DefaultState, NULL, true ));
00540 if( !ic->isNull())
00541 {
00542 w->setIcon( *ic );
00543 #if defined Q_WS_X11
00544 KWin::setIcons( w->winId(), *ic, miniIcon());
00545 #endif
00546 }
00547 }
00548 }
00549 return QApplication::notify(receiver, event);
00550 }
00551
00552 void KApplication::checkAppStartedSlot()
00553 {
00554 #if defined Q_WS_X11
00555 KStartupInfo::handleAutoAppStartedSending();
00556 #endif
00557 }
00558
00559
00560 static QPtrList<KSessionManaged>* sessionClients()
00561 {
00562 static QPtrList<KSessionManaged>* session_clients = 0L;
00563 if ( !session_clients )
00564 session_clients = new QPtrList<KSessionManaged>;
00565 return session_clients;
00566 }
00567
00568
00569
00570
00571
00572
00573 QString KApplication::sessionConfigName() const
00574 {
00575 #if QT_VERSION < 0x030100
00576 return QString("session/%1_%2_%3").arg(name()).arg(sessionId()).arg(d->sessionKey);
00577 #else
00578 QString sessKey = sessionKey();
00579 if ( sessKey.isEmpty() && !d->sessionKey.isEmpty() )
00580 sessKey = d->sessionKey;
00581 return QString("session/%1_%2_%3").arg(name()).arg(sessionId()).arg(sessKey);
00582 #endif
00583 }
00584
00585 #ifdef Q_WS_X11
00586 static SmcConn mySmcConnection = 0;
00587 static SmcConn tmpSmcConnection = 0;
00588 #else
00589
00590
00591 #endif
00592 static QTime* smModificationTime = 0;
00593
00594 KApplication::KApplication( int& argc, char** argv, const QCString& rAppName,
00595 bool allowStyles, bool GUIenabled ) :
00596 QApplication( argc, argv, GUIenabled ), KInstance(rAppName),
00597 #ifdef Q_WS_X11
00598 display(0L),
00599 #endif
00600 d (new KApplicationPrivate())
00601 {
00602 aIconPixmap.pm.icon = 0L;
00603 aIconPixmap.pm.miniIcon = 0L;
00604 read_app_startup_id();
00605 if (!GUIenabled)
00606 allowStyles = false;
00607 useStyles = allowStyles;
00608 Q_ASSERT (!rAppName.isEmpty());
00609 setName(rAppName);
00610
00611 installSigpipeHandler();
00612 KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00613 parseCommandLine( );
00614 init(GUIenabled);
00615 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00616 }
00617
00618 KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
00619 QApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00620 GUIenabled ),
00621 KInstance( KCmdLineArgs::about),
00622 #ifdef Q_WS_X11
00623 display(0L),
00624 #endif
00625 d (new KApplicationPrivate)
00626 {
00627 aIconPixmap.pm.icon = 0L;
00628 aIconPixmap.pm.miniIcon = 0L;
00629 read_app_startup_id();
00630 if (!GUIenabled)
00631 allowStyles = false;
00632 useStyles = allowStyles;
00633 setName( instanceName() );
00634
00635 installSigpipeHandler();
00636 parseCommandLine( );
00637 init(GUIenabled);
00638 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00639 }
00640
00641 #ifdef Q_WS_X11
00642 KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
00643 bool allowStyles ) :
00644 QApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00645 visual, colormap ),
00646 KInstance( KCmdLineArgs::about), display(0L), d (new KApplicationPrivate)
00647 {
00648 aIconPixmap.pm.icon = 0L;
00649 aIconPixmap.pm.miniIcon = 0L;
00650 read_app_startup_id();
00651 useStyles = allowStyles;
00652 setName( instanceName() );
00653 installSigpipeHandler();
00654 parseCommandLine( );
00655 init( true );
00656 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00657 }
00658
00659 KApplication::KApplication( Display *dpy, Qt::HANDLE visual, Qt::HANDLE colormap,
00660 bool allowStyles, KInstance * _instance ) :
00661 QApplication( dpy, *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00662 visual, colormap ),
00663 KInstance( _instance ), display(0L), d (new KApplicationPrivate)
00664 {
00665 aIconPixmap.pm.icon = 0L;
00666 aIconPixmap.pm.miniIcon = 0L;
00667 read_app_startup_id();
00668 useStyles = allowStyles;
00669 setName( instanceName() );
00670 installSigpipeHandler();
00671 parseCommandLine( );
00672 init( true );
00673 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00674 }
00675 #endif
00676
00677 KApplication::KApplication( bool allowStyles, bool GUIenabled, KInstance* _instance ) :
00678 QApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00679 GUIenabled ),
00680 KInstance( _instance ),
00681 #ifdef Q_WS_X11
00682 display(0L),
00683 #endif
00684 d (new KApplicationPrivate)
00685 {
00686 aIconPixmap.pm.icon = 0L;
00687 aIconPixmap.pm.miniIcon = 0L;
00688 read_app_startup_id();
00689 if (!GUIenabled)
00690 allowStyles = false;
00691 useStyles = allowStyles;
00692 setName( instanceName() );
00693
00694 installSigpipeHandler();
00695 parseCommandLine( );
00696 init(GUIenabled);
00697 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00698 }
00699
00700 #ifdef Q_WS_X11
00701 KApplication::KApplication(Display *display, int& argc, char** argv, const QCString& rAppName,
00702 bool allowStyles, bool GUIenabled ) :
00703 QApplication( display ), KInstance(rAppName),
00704 display(0L),
00705 d (new KApplicationPrivate())
00706 {
00707 aIconPixmap.pm.icon = 0L;
00708 aIconPixmap.pm.miniIcon = 0L;
00709 read_app_startup_id();
00710 if (!GUIenabled)
00711 allowStyles = false;
00712 useStyles = allowStyles;
00713
00714 Q_ASSERT (!rAppName.isEmpty());
00715 setName(rAppName);
00716
00717 installSigpipeHandler();
00718 KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00719 parseCommandLine( );
00720 init(GUIenabled);
00721 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00722 }
00723 #endif
00724
00725 int KApplication::xioErrhandler( Display* dpy )
00726 {
00727 if(kapp)
00728 {
00729 emit shutDown();
00730 #ifdef Q_WS_X11
00731 d->oldXIOErrorHandler( dpy );
00732 #else
00733 Q_UNUSED(dpy);
00734 #endif
00735 }
00736 exit( 1 );
00737 return 0;
00738 }
00739
00740 int KApplication::xErrhandler( Display* dpy, void* err_ )
00741 {
00742 #ifdef Q_WS_X11
00743 XErrorEvent* err = static_cast< XErrorEvent* >( err_ );
00744 if(kapp)
00745 {
00746
00747 d->oldXErrorHandler( dpy, err );
00748 }
00749 #endif
00750 return 0;
00751 }
00752
00753 void KApplication::iceIOErrorHandler( _IceConn *conn )
00754 {
00755 emit shutDown();
00756
00757 #ifdef Q_WS_X11
00758 if ( d->oldIceIOErrorHandler != NULL )
00759 (*d->oldIceIOErrorHandler)( conn );
00760 #endif
00761 exit( 1 );
00762 }
00763
00764 class KDETranslator : public QTranslator
00765 {
00766 public:
00767 KDETranslator(QObject *parent) : QTranslator(parent, "kdetranslator") {}
00768 virtual QTranslatorMessage findMessage(const char* context,
00769 const char *sourceText,
00770 const char* message) const
00771 {
00772 QTranslatorMessage res;
00773 res.setTranslation(KGlobal::locale()->translateQt(context, sourceText, message));
00774 return res;
00775 }
00776 };
00777
00778 void KApplication::init(bool GUIenabled)
00779 {
00780 d->guiEnabled = GUIenabled;
00781 if ((getuid() != geteuid()) ||
00782 (getgid() != getegid()))
00783 {
00784 fprintf(stderr, "The KDE libraries are not designed to run with suid privileges.\n");
00785 ::exit(127);
00786 }
00787
00788 KProcessController::ref();
00789
00790 (void) KClipboardSynchronizer::self();
00791
00792 QApplication::setDesktopSettingsAware( false );
00793
00794 KApp = this;
00795
00796
00797 #ifdef Q_WS_X11 //FIXME(E)
00798
00799 if ( GUIenabled ) {
00800 const int max = 20;
00801 Atom* atoms[max];
00802 char* names[max];
00803 Atom atoms_return[max];
00804 int n = 0;
00805
00806 atoms[n] = &kipcCommAtom;
00807 names[n++] = (char *) "KIPC_COMM_ATOM";
00808
00809 atoms[n] = &atom_DesktopWindow;
00810 names[n++] = (char *) "KDE_DESKTOP_WINDOW";
00811
00812 atoms[n] = &atom_NetSupported;
00813 names[n++] = (char *) "_NET_SUPPORTED";
00814
00815 atoms[n] = &kde_xdnd_drop;
00816 names[n++] = (char *) "XdndDrop";
00817
00818 XInternAtoms( qt_xdisplay(), names, n, false, atoms_return );
00819
00820 for (int i = 0; i < n; i++ )
00821 *atoms[i] = atoms_return[i];
00822 }
00823 #endif
00824
00825 dcopAutoRegistration();
00826 dcopClientPostInit();
00827
00828 smw = 0;
00829
00830
00831 #if defined Q_WS_X11
00832 kipcEventMask = (1 << KIPC::StyleChanged) | (1 << KIPC::PaletteChanged) |
00833 (1 << KIPC::FontChanged) | (1 << KIPC::BackgroundChanged) |
00834 (1 << KIPC::ToolbarStyleChanged) | (1 << KIPC::SettingsChanged) |
00835 (1 << KIPC::ClipboardConfigChanged);
00836 #endif
00837
00838
00839 (void) KGlobal::locale();
00840
00841 KConfig* config = KGlobal::config();
00842 d->actionRestrictions = config->hasGroup("KDE Action Restrictions" ) && !kde_kiosk_exception;
00843
00844
00845
00846
00847 QCString readOnly = getenv("KDE_HOME_READONLY");
00848 if (readOnly.isEmpty() && (qstrcmp(name(), "kdialog") != 0))
00849 {
00850 KConfigGroupSaver saver(config, "KDE Action Restrictions");
00851 if (config->readBoolEntry("warn_unwritable_config",true))
00852 config->checkConfigFilesWritable(true);
00853 }
00854
00855 if (GUIenabled)
00856 {
00857 #ifdef Q_WS_X11
00858
00859 fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, FD_CLOEXEC);
00860
00861 d->oldXErrorHandler = XSetErrorHandler( kde_x_errhandler );
00862 d->oldXIOErrorHandler = XSetIOErrorHandler( kde_xio_errhandler );
00863 #endif
00864
00865 connect( this, SIGNAL( aboutToQuit() ), this, SIGNAL( shutDown() ) );
00866
00867 #ifdef Q_WS_X11 //FIXME(E)
00868 display = desktop()->x11Display();
00869 #endif
00870
00871 {
00872 QStringList plugins = KGlobal::dirs()->resourceDirs( "qtplugins" );
00873 QStringList::Iterator it = plugins.begin();
00874 while (it != plugins.end()) {
00875 addLibraryPath( *it );
00876 ++it;
00877 }
00878
00879 }
00880 kdisplaySetStyle();
00881 kdisplaySetFont();
00882
00883 propagateSettings(SETTINGS_QT);
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893 QMimeSourceFactory* oldDefaultFactory = QMimeSourceFactory::takeDefaultFactory();
00894 QMimeSourceFactory::setDefaultFactory( mimeSourceFactory() );
00895 if ( oldDefaultFactory ) {
00896 QMimeSourceFactory::addFactory( oldDefaultFactory );
00897 }
00898
00899 d->checkAccelerators = new KCheckAccelerators( this );
00900 }
00901
00902 #ifdef Q_WS_MACX
00903 if (GUIenabled) {
00904 QPixmap pixmap = KGlobal::iconLoader()->loadIcon( KCmdLineArgs::appName(),
00905 KIcon::NoGroup, KIcon::SizeLarge, KIcon::DefaultState, 0L, false );
00906 if (!pixmap.isNull()) {
00907 QImage i = pixmap.convertToImage().convertDepth(32).smoothScale(40, 40);
00908 for(int y = 0; y < i.height(); y++) {
00909 uchar *l = i.scanLine(y);
00910 for(int x = 0; x < i.width(); x+=4)
00911 *(l+x) = 255;
00912 }
00913 CGColorSpaceRef cs = CGColorSpaceCreateDeviceRGB();
00914 CGDataProviderRef dp = CGDataProviderCreateWithData(NULL,
00915 i.bits(), i.numBytes(), NULL);
00916 CGImageRef ir = CGImageCreate(i.width(), i.height(), 8, 32, i.bytesPerLine(),
00917 cs, kCGImageAlphaNoneSkipFirst, dp,
00918 0, 0, kCGRenderingIntentDefault);
00919
00920 SetApplicationDockTileImage(ir);
00921 CGImageRelease(ir);
00922 CGColorSpaceRelease(cs);
00923 CGDataProviderRelease(dp);
00924 }
00925 }
00926 #endif
00927
00928
00929
00930
00931 bool rtl = reverseLayout();
00932 installTranslator(new KDETranslator(this));
00933 setReverseLayout( rtl );
00934 if (i18n( "_: Dear Translator! Translate this string to the string 'LTR' in "
00935 "left-to-right languages (as english) or to 'RTL' in right-to-left "
00936 "languages (such as Hebrew and Arabic) to get proper widget layout." ) == "RTL")
00937 setReverseLayout( !rtl );
00938
00939
00940 KGlobal::dirs()->addResourceType("appdata", KStandardDirs::kde_default("data")
00941 + QString::fromLatin1(name()) + '/');
00942 pSessionConfig = 0L;
00943 bSessionManagement = true;
00944
00945 #ifdef Q_WS_X11
00946
00947 if (GUIenabled && kde_have_kipc )
00948 {
00949 smw = new QWidget(0,0);
00950 long data = 1;
00951 XChangeProperty(qt_xdisplay(), smw->winId(),
00952 atom_DesktopWindow, atom_DesktopWindow,
00953 32, PropModeReplace, (unsigned char *)&data, 1);
00954 }
00955 d->oldIceIOErrorHandler = IceSetIOErrorHandler( kde_ice_ioerrorhandler );
00956 #elif defined(Q_WS_WIN)
00957 KApplication_init_windows(GUIenabled);
00958 #else
00959
00960 #endif
00961 }
00962
00963 static int my_system (const char *command) {
00964 int pid, status;
00965
00966 QApplication::flushX();
00967 pid = fork();
00968 if (pid == -1)
00969 return -1;
00970 if (pid == 0) {
00971 const char* shell = "/bin/sh";
00972 execl(shell, shell, "-c", command, (void *)0);
00973 ::exit(127);
00974 }
00975 do {
00976 if (waitpid(pid, &status, 0) == -1) {
00977 if (errno != EINTR)
00978 return -1;
00979 } else
00980 return status;
00981 } while(1);
00982 }
00983
00984
00985 DCOPClient *KApplication::dcopClient()
00986 {
00987 if (s_DCOPClient)
00988 return s_DCOPClient;
00989
00990 s_DCOPClient = new DCOPClient();
00991 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
00992 if (args && args->isSet("dcopserver"))
00993 {
00994 s_DCOPClient->setServerAddress( args->getOption("dcopserver"));
00995 }
00996 if( kapp ) {
00997 connect(s_DCOPClient, SIGNAL(attachFailed(const QString &)),
00998 kapp, SLOT(dcopFailure(const QString &)));
00999 connect(s_DCOPClient, SIGNAL(blockUserInput(bool) ),
01000 kapp, SLOT(dcopBlockUserInput(bool)) );
01001 }
01002 else
01003 s_dcopClientNeedsPostInit = true;
01004
01005 DCOPClient::setMainClient( s_DCOPClient );
01006 return s_DCOPClient;
01007 }
01008
01009 void KApplication::dcopClientPostInit()
01010 {
01011 if( s_dcopClientNeedsPostInit )
01012 {
01013 s_dcopClientNeedsPostInit = false;
01014 connect(s_DCOPClient, SIGNAL(blockUserInput(bool) ),
01015 SLOT(dcopBlockUserInput(bool)) );
01016 s_DCOPClient->bindToApp();
01017 }
01018 }
01019
01020 void KApplication::dcopAutoRegistration()
01021 {
01022 if (autoDcopRegistration)
01023 {
01024 ( void ) dcopClient();
01025 if( dcopClient()->appId().isEmpty())
01026 dcopClient()->registerAs(name());
01027 }
01028 }
01029
01030 void KApplication::disableAutoDcopRegistration()
01031 {
01032 autoDcopRegistration = false;
01033 }
01034
01035 KConfig* KApplication::sessionConfig()
01036 {
01037 if (pSessionConfig)
01038 return pSessionConfig;
01039
01040
01041 pSessionConfig = new KConfig( sessionConfigName(), false, false);
01042 return pSessionConfig;
01043 }
01044
01045 void KApplication::ref()
01046 {
01047 d->refCount++;
01048
01049 }
01050
01051 void KApplication::deref()
01052 {
01053 d->refCount--;
01054
01055 if ( d->refCount <= 0 )
01056 quit();
01057 }
01058
01059 KSessionManaged::KSessionManaged()
01060 {
01061 sessionClients()->remove( this );
01062 sessionClients()->append( this );
01063 }
01064
01065 KSessionManaged::~KSessionManaged()
01066 {
01067 sessionClients()->remove( this );
01068 }
01069
01070 bool KSessionManaged::saveState(QSessionManager&)
01071 {
01072 return true;
01073 }
01074
01075 bool KSessionManaged::commitData(QSessionManager&)
01076 {
01077 return true;
01078 }
01079
01080
01081 void KApplication::disableSessionManagement() {
01082 bSessionManagement = false;
01083 }
01084
01085 void KApplication::enableSessionManagement() {
01086 bSessionManagement = true;
01087 #ifdef Q_WS_X11
01088
01089
01090
01091
01092
01093
01094
01095
01096
01097 if( mySmcConnection ) {
01098 SmcRequestSaveYourself( mySmcConnection, SmSaveLocal, False,
01099 SmInteractStyleAny,
01100 False, False );
01101
01102
01103 IceFlush(SmcGetIceConnection(mySmcConnection));
01104 }
01105 #endif
01106 }
01107
01108
01109 bool KApplication::requestShutDown(
01110 ShutdownConfirm confirm, ShutdownType sdtype, ShutdownMode sdmode )
01111 {
01112 #ifdef Q_WS_X11
01113 QApplication::syncX();
01114
01115 if ( confirm == ShutdownConfirmYes ||
01116 sdtype != ShutdownTypeDefault ||
01117 sdmode != ShutdownModeDefault )
01118 {
01119 QByteArray data;
01120 QDataStream arg(data, IO_WriteOnly);
01121 arg << (int)confirm << (int)sdtype << (int)sdmode;
01122 return dcopClient()->send( "ksmserver", "ksmserver",
01123 "logout(int,int,int)", data );
01124 }
01125
01126 if ( mySmcConnection ) {
01127
01128 SmcRequestSaveYourself( mySmcConnection, SmSaveBoth, True,
01129 SmInteractStyleAny,
01130 confirm == ShutdownConfirmNo, True );
01131
01132
01133 IceFlush(SmcGetIceConnection(mySmcConnection));
01134 return true;
01135 }
01136
01137
01138
01139 propagateSessionManager();
01140 QCString smEnv = ::getenv("SESSION_MANAGER");
01141 if (smEnv.isEmpty())
01142 return false;
01143
01144 if (! tmpSmcConnection) {
01145 char cerror[256];
01146 char* myId = 0;
01147 char* prevId = 0;
01148 SmcCallbacks cb;
01149 tmpSmcConnection = SmcOpenConnection( 0, 0, 1, 0,
01150 0, &cb,
01151 prevId,
01152 &myId,
01153 255,
01154 cerror );
01155 ::free( myId );
01156 if (!tmpSmcConnection )
01157 return false;
01158 }
01159
01160 SmcRequestSaveYourself( tmpSmcConnection, SmSaveBoth, True,
01161 SmInteractStyleAny, False, True );
01162
01163
01164 IceFlush(SmcGetIceConnection(tmpSmcConnection));
01165 return true;
01166 #else
01167
01168 return false;
01169 #endif
01170 }
01171
01172 void KApplication::propagateSessionManager()
01173 {
01174 #ifdef Q_WS_X11
01175 QCString fName = QFile::encodeName(locateLocal("socket", "KSMserver"));
01176 QCString display = ::getenv(DISPLAY);
01177
01178 display.replace(QRegExp("\\.[0-9]+$"), "");
01179 int i;
01180 while( (i = display.find(':')) >= 0)
01181 display[i] = '_';
01182
01183 fName += "_"+display;
01184 QCString smEnv = ::getenv("SESSION_MANAGER");
01185 bool check = smEnv.isEmpty();
01186 if ( !check && smModificationTime ) {
01187 QFileInfo info( fName );
01188 QTime current = info.lastModified().time();
01189 check = current > *smModificationTime;
01190 }
01191 if ( check ) {
01192 delete smModificationTime;
01193 QFile f( fName );
01194 if ( !f.open( IO_ReadOnly ) )
01195 return;
01196 QFileInfo info ( f );
01197 smModificationTime = new QTime( info.lastModified().time() );
01198 QTextStream t(&f);
01199 t.setEncoding( QTextStream::Latin1 );
01200 QString s = t.readLine();
01201 f.close();
01202 ::setenv( "SESSION_MANAGER", s.latin1(), true );
01203 }
01204 #endif
01205 }
01206
01207 void KApplication::commitData( QSessionManager& sm )
01208 {
01209 d->session_save = true;
01210 bool canceled = false;
01211 for (KSessionManaged* it = sessionClients()->first();
01212 it && !canceled;
01213 it = sessionClients()->next() ) {
01214 canceled = !it->commitData( sm );
01215 }
01216 if ( canceled )
01217 sm.cancel();
01218
01219 if ( sm.allowsInteraction() ) {
01220 QWidgetList done;
01221 QWidgetList *list = QApplication::topLevelWidgets();
01222 bool canceled = false;
01223 QWidget* w = list->first();
01224 while ( !canceled && w ) {
01225 if ( !w->testWState( WState_ForceHide ) && !w->inherits("KMainWindow") ) {
01226 QCloseEvent e;
01227 sendEvent( w, &e );
01228 canceled = !e.isAccepted();
01229 if ( !canceled )
01230 done.append( w );
01231 delete list;
01232 list = QApplication::topLevelWidgets();
01233 w = list->first();
01234 } else {
01235 w = list->next();
01236 }
01237 while ( w && done.containsRef( w ) )
01238 w = list->next();
01239 }
01240 delete list;
01241 }
01242
01243
01244 if ( !bSessionManagement )
01245 sm.setRestartHint( QSessionManager::RestartNever );
01246 else
01247 sm.setRestartHint( QSessionManager::RestartIfRunning );
01248 d->session_save = false;
01249 }
01250
01251 void KApplication::saveState( QSessionManager& sm )
01252 {
01253 d->session_save = true;
01254 #ifdef Q_WS_X11
01255 static bool firstTime = true;
01256 mySmcConnection = (SmcConn) sm.handle();
01257
01258 if ( !bSessionManagement ) {
01259 sm.setRestartHint( QSessionManager::RestartNever );
01260 d->session_save = false;
01261 return;
01262 }
01263 else
01264 sm.setRestartHint( QSessionManager::RestartIfRunning );
01265
01266 #if QT_VERSION < 0x030100
01267 {
01268
01269 timeval tv;
01270 gettimeofday( &tv, 0 );
01271 d->sessionKey = QString::number( tv.tv_sec ) + "_" + QString::number(tv.tv_usec);
01272 }
01273 #endif
01274
01275 if ( firstTime ) {
01276 firstTime = false;
01277 d->session_save = false;
01278 return;
01279 }
01280
01281
01282
01283
01284
01285
01286
01287 if ( pSessionConfig ) {
01288 delete pSessionConfig;
01289 pSessionConfig = 0;
01290 }
01291
01292
01293 QStringList restartCommand = sm.restartCommand();
01294 #if QT_VERSION < 0x030100
01295 restartCommand.clear();
01296 restartCommand << argv()[0] << "-session" << sm.sessionId() << "-smkey" << d->sessionKey;
01297 sm.setRestartCommand( restartCommand );
01298 #endif
01299
01300
01301 QCString multiHead = getenv("KDE_MULTIHEAD");
01302 if (multiHead.lower() == "true") {
01303
01304
01305
01306
01307
01308
01309 QCString displayname = getenv(DISPLAY);
01310 if (! displayname.isNull()) {
01311
01312
01313 restartCommand.append("-display");
01314 restartCommand.append(displayname);
01315 }
01316 sm.setRestartCommand( restartCommand );
01317 }
01318
01319
01320
01321 emit saveYourself();
01322 bool canceled = false;
01323 for (KSessionManaged* it = sessionClients()->first();
01324 it && !canceled;
01325 it = sessionClients()->next() ) {
01326 canceled = !it->saveState( sm );
01327 }
01328
01329
01330 if ( pSessionConfig ) {
01331 pSessionConfig->sync();
01332 QStringList discard;
01333 discard << "rm" << locateLocal("config", sessionConfigName());
01334 sm.setDiscardCommand( discard );
01335 } else {
01336 sm.setDiscardCommand( "" );
01337 }
01338
01339 if ( canceled )
01340 sm.cancel();
01341 #else
01342
01343 #endif
01344 d->session_save = false;
01345 }
01346
01347 bool KApplication::sessionSaving() const
01348 {
01349 return d->session_save;
01350 }
01351
01352 void KApplication::startKdeinit()
01353 {
01354 #ifndef Q_WS_WIN //TODO
01355
01356 QString srv = KStandardDirs::findExe(QString::fromLatin1("kdeinit"));
01357 if (srv.isEmpty())
01358 srv = KStandardDirs::findExe(QString::fromLatin1("kdeinit"), KGlobal::dirs()->kfsstnd_defaultbindir());
01359 if (srv.isEmpty())
01360 return;
01361 if (kapp && (Tty != kapp->type()))
01362 setOverrideCursor( Qt::waitCursor );
01363 my_system(QFile::encodeName(srv)+" --suicide");
01364 if (kapp && (Tty != kapp->type()))
01365 restoreOverrideCursor();
01366 #endif
01367 }
01368
01369 void KApplication::dcopFailure(const QString &msg)
01370 {
01371 static int failureCount = 0;
01372 failureCount++;
01373 if (failureCount == 1)
01374 {
01375 startKdeinit();
01376 return;
01377 }
01378 if (failureCount == 2)
01379 {
01380 QString msgStr(i18n("There was an error setting up inter-process "
01381 "communications for KDE. The message returned "
01382 "by the system was:\n\n"));
01383 msgStr += msg;
01384 msgStr += i18n("\n\nPlease check that the \"dcopserver\" program is running!");
01385
01386 if (Tty != kapp->type())
01387 {
01388 QMessageBox::critical
01389 (
01390 kapp->mainWidget(),
01391 i18n("DCOP communications error (%1)").arg(kapp->caption()),
01392 msgStr,
01393 i18n("&OK")
01394 );
01395 }
01396 else
01397 {
01398 fprintf(stderr, "%s\n", msgStr.local8Bit().data());
01399 }
01400
01401 return;
01402 }
01403 }
01404
01405 static const KCmdLineOptions qt_options[] =
01406 {
01407
01408 #ifdef Q_WS_X11
01409 { "display <displayname>", I18N_NOOP("Use the X-server display 'displayname'"), 0},
01410 #else
01411 { "display <displayname>", I18N_NOOP("Use the QWS display 'displayname'"), 0},
01412 #endif
01413 { "session <sessionId>", I18N_NOOP("Restore the application for the given 'sessionId'"), 0},
01414 { "cmap", I18N_NOOP("Causes the application to install a private color\nmap on an 8-bit display"), 0},
01415 { "ncols <count>", I18N_NOOP("Limits the number of colors allocated in the color\ncube on an 8-bit display, if the application is\nusing the QApplication::ManyColor color\nspecification"), 0},
01416 { "nograb", I18N_NOOP("tells Qt to never grab the mouse or the keyboard"), 0},
01417 { "dograb", I18N_NOOP("running under a debugger can cause an implicit\n-nograb, use -dograb to override"), 0},
01418 { "sync", I18N_NOOP("switches to synchronous mode for debugging"), 0},
01419 { "fn", 0, 0},
01420 { "font <fontname>", I18N_NOOP("defines the application font"), 0},
01421 { "bg", 0, 0},
01422 { "background <color>", I18N_NOOP("sets the default background color and an\napplication palette (light and dark shades are\ncalculated)"), 0},
01423 { "fg", 0, 0},
01424 { "foreground <color>", I18N_NOOP("sets the default foreground color"), 0},
01425 { "btn", 0, 0},
01426 { "button <color>", I18N_NOOP("sets the default button color"), 0},
01427 { "name <name>", I18N_NOOP("sets the application name"), 0},
01428 { "title <title>", I18N_NOOP("sets the application title (caption)"), 0},
01429 #ifdef Q_WS_X11
01430 { "visual TrueColor", I18N_NOOP("forces the application to use a TrueColor visual on\nan 8-bit display"), 0},
01431 { "inputstyle <inputstyle>", I18N_NOOP("sets XIM (X Input Method) input style. Possible\nvalues are onthespot, overthespot, offthespot and\nroot"), 0 },
01432 { "im <XIM server>", I18N_NOOP("set XIM server"),0},
01433 { "noxim", I18N_NOOP("disable XIM"), 0 },
01434 #endif
01435 #ifdef Q_WS_QWS
01436 { "qws", I18N_NOOP("forces the application to run as QWS Server"), 0},
01437 #endif
01438 { "reverse", I18N_NOOP("mirrors the whole layout of widgets"), 0},
01439 KCmdLineLastOption
01440 };
01441
01442 static const KCmdLineOptions kde_options[] =
01443 {
01444 { "caption <caption>", I18N_NOOP("Use 'caption' as name in the titlebar"), 0},
01445 { "icon <icon>", I18N_NOOP("Use 'icon' as the application icon"), 0},
01446 { "miniicon <icon>", I18N_NOOP("Use 'icon' as the icon in the titlebar"), 0},
01447 { "config <filename>", I18N_NOOP("Use alternative configuration file"), 0},
01448 { "dcopserver <server>", I18N_NOOP("Use the DCOP Server specified by 'server'"), 0},
01449 { "nocrashhandler", I18N_NOOP("Disable crash handler, to get core dumps"), 0},
01450 { "waitforwm", I18N_NOOP("Waits for a WM_NET compatible windowmanager"), 0},
01451 { "style <style>", I18N_NOOP("sets the application GUI style"), 0},
01452 { "geometry <geometry>", I18N_NOOP("sets the client geometry of the main widget - see man X for the argument format"), 0},
01453 #if QT_VERSION < 0x030100
01454 { "smkey <sessionKey>", I18N_NOOP("Define a 'sessionKey' for the session id. Only valid with -session"), 0},
01455 #else
01456 { "smkey <sessionKey>", 0, 0},
01457
01458
01459 #endif
01460 KCmdLineLastOption
01461 };
01462
01463 void
01464 KApplication::addCmdLineOptions()
01465 {
01466 KCmdLineArgs::addCmdLineOptions(qt_options, "Qt", "qt");
01467 KCmdLineArgs::addCmdLineOptions(kde_options, "KDE", "kde");
01468 }
01469
01470 void KApplication::parseCommandLine( )
01471 {
01472 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
01473
01474 if ( !args ) return;
01475
01476 if (args->isSet("config"))
01477 {
01478 QString config = QString::fromLocal8Bit(args->getOption("config"));
01479 setConfigName(config);
01480 }
01481
01482 if (args->isSet("style"))
01483 {
01484
01485 QStringList styles = QStyleFactory::keys();
01486 QString reqStyle(args->getOption("style").lower());
01487
01488 for (QStringList::ConstIterator it = styles.begin(); it != styles.end(); ++it)
01489 if ((*it).lower() == reqStyle)
01490 {
01491 d->overrideStyle = *it;
01492 break;
01493 }
01494
01495 if (d->overrideStyle.isEmpty())
01496 fprintf(stderr, "%s", i18n("The style %1 was not found\n").arg(reqStyle).local8Bit().data());
01497 }
01498
01499 if (args->isSet("caption"))
01500 {
01501 aCaption = QString::fromLocal8Bit(args->getOption("caption"));
01502 }
01503
01504 if (args->isSet("miniicon"))
01505 {
01506 const char *tmp = args->getOption("miniicon");
01507 if (!aIconPixmap.pm.miniIcon) {
01508 aIconPixmap.pm.miniIcon = new QPixmap;
01509 }
01510 *aIconPixmap.pm.miniIcon = SmallIcon(tmp);
01511 aMiniIconName = tmp;
01512 }
01513
01514 if (args->isSet("icon"))
01515 {
01516 const char *tmp = args->getOption("icon");
01517 if (!aIconPixmap.pm.icon) {
01518 aIconPixmap.pm.icon = new QPixmap;
01519 }
01520 *aIconPixmap.pm.icon = DesktopIcon( tmp );
01521 aIconName = tmp;
01522 if (!aIconPixmap.pm.miniIcon) {
01523 aIconPixmap.pm.miniIcon = new QPixmap;
01524 }
01525 if (aIconPixmap.pm.miniIcon->isNull())
01526 {
01527 *aIconPixmap.pm.miniIcon = SmallIcon( tmp );
01528 aMiniIconName = tmp;
01529 }
01530 }
01531
01532 bool nocrashhandler = (getenv("KDE_DEBUG") != NULL);
01533 if (!nocrashhandler && args->isSet("crashhandler"))
01534 {
01535
01536 KCrash::setCrashHandler(KCrash::defaultCrashHandler);
01537 KCrash::setEmergencySaveFunction(NULL);
01538
01539 KCrash::setApplicationName(QString(args->appName()));
01540 }
01541
01542 #ifdef Q_WS_X11
01543 if ( args->isSet( "waitforwm" ) ) {
01544 Atom type;
01545 (void) desktop();
01546 int format;
01547 unsigned long length, after;
01548 unsigned char *data;
01549 while ( XGetWindowProperty( qt_xdisplay(), qt_xrootwin(), atom_NetSupported,
01550 0, 1, false, AnyPropertyType, &type, &format,
01551 &length, &after, &data ) != Success || !length ) {
01552 if ( data )
01553 XFree( data );
01554 XEvent event;
01555 XWindowEvent( qt_xdisplay(), qt_xrootwin(), PropertyChangeMask, &event );
01556 }
01557 if ( data )
01558 XFree( data );
01559 }
01560 #else
01561
01562 #endif
01563
01564 if (args->isSet("geometry"))
01565 {
01566 d->geometry_arg = args->getOption("geometry");
01567 }
01568
01569 if (args->isSet("smkey"))
01570 {
01571 d->sessionKey = args->getOption("smkey");
01572 }
01573
01574 }
01575
01576 QString KApplication::geometryArgument() const
01577 {
01578 return d->geometry_arg;
01579 }
01580
01581 QPixmap KApplication::icon() const
01582 {
01583 if( !aIconPixmap.pm.icon) {
01584 aIconPixmap.pm.icon = new QPixmap;
01585 }
01586 if( aIconPixmap.pm.icon->isNull()) {
01587 *aIconPixmap.pm.icon = DesktopIcon( instanceName() );
01588 }
01589 return *aIconPixmap.pm.icon;
01590 }
01591
01592 QString KApplication::iconName() const
01593 {
01594 return aIconName.isNull() ? (QString)instanceName() : aIconName;
01595 }
01596
01597 QPixmap KApplication::miniIcon() const
01598 {
01599 if (!aIconPixmap.pm.miniIcon) {
01600 aIconPixmap.pm.miniIcon = new QPixmap;
01601 }
01602 if (aIconPixmap.pm.miniIcon->isNull()) {
01603 *aIconPixmap.pm.miniIcon = SmallIcon( instanceName() );
01604 }
01605 return *aIconPixmap.pm.miniIcon;
01606 }
01607
01608 QString KApplication::miniIconName() const
01609 {
01610 return aMiniIconName.isNull() ? (QString)instanceName() : aMiniIconName;
01611 }
01612
01613 extern void kDebugCleanup();
01614
01615 KApplication::~KApplication()
01616 {
01617 delete aIconPixmap.pm.miniIcon;
01618 aIconPixmap.pm.miniIcon = 0L;
01619 delete aIconPixmap.pm.icon;
01620 aIconPixmap.pm.icon = 0L;
01621 delete d->m_KAppDCOPInterface;
01622
01623
01624
01625
01626 KGlobal::deleteStaticDeleters();
01627 KLibLoader::cleanUp();
01628
01629 delete smw;
01630
01631
01632 delete s_DCOPClient;
01633 s_DCOPClient = 0L;
01634
01635 KProcessController::deref();
01636
01637 #ifdef Q_WS_X11
01638 if ( d->oldXErrorHandler != NULL )
01639 XSetErrorHandler( d->oldXErrorHandler );
01640 if ( d->oldXIOErrorHandler != NULL )
01641 XSetIOErrorHandler( d->oldXIOErrorHandler );
01642 if ( d->oldIceIOErrorHandler != NULL )
01643 IceSetIOErrorHandler( d->oldIceIOErrorHandler );
01644 #endif
01645
01646 delete d;
01647 KApp = 0;
01648
01649 #ifdef Q_WS_X11
01650 mySmcConnection = 0;
01651 delete smModificationTime;
01652 smModificationTime = 0;
01653
01654
01655 if (tmpSmcConnection) {
01656 SmcCloseConnection( tmpSmcConnection, 0, 0 );
01657 tmpSmcConnection = 0;
01658 }
01659 #else
01660
01661 #endif
01662 }
01663
01664
01665 #ifdef Q_WS_X11
01666 class KAppX11HackWidget: public QWidget
01667 {
01668 public:
01669 bool publicx11Event( XEvent * e) { return x11Event( e ); }
01670 };
01671 #endif
01672
01673
01674
01675 static bool kapp_block_user_input = false;
01676
01677 void KApplication::dcopBlockUserInput( bool b )
01678 {
01679 kapp_block_user_input = b;
01680 }
01681
01682 #ifdef Q_WS_X11
01683 bool KApplication::x11EventFilter( XEvent *_event )
01684 {
01685 switch ( _event->type ) {
01686 case ClientMessage:
01687 {
01688 #if KDE_IS_VERSION( 3, 3, 91 )
01689 #warning This should be already in Qt, check.
01690 #endif
01691
01692
01693
01694
01695
01696 if( _event->xclient.message_type == kde_xdnd_drop )
01697 {
01698 if( _event->xclient.data.l[ 1 ] == 1 << 24
01699 && _event->xclient.data.l[ 2 ] == 0
01700 && _event->xclient.data.l[ 4 ] == 0
01701 && _event->xclient.data.l[ 3 ] != 0 )
01702 {
01703 if( qt_x_user_time == 0
01704 || ( _event->xclient.data.l[ 3 ] - qt_x_user_time ) < 100000U )
01705 {
01706 qt_x_user_time = _event->xclient.data.l[ 3 ];
01707 }
01708 }
01709 else
01710 {
01711 if( qt_x_user_time == 0
01712 || ( _event->xclient.data.l[ 2 ] - qt_x_user_time ) < 100000U )
01713 {
01714 qt_x_user_time = _event->xclient.data.l[ 2 ];
01715 }
01716 }
01717 }
01718 }
01719 default: break;
01720 }
01721
01722 if ( kapp_block_user_input ) {
01723 switch ( _event->type ) {
01724 case ButtonPress:
01725 case ButtonRelease:
01726 case XKeyPress:
01727 case XKeyRelease:
01728 case MotionNotify:
01729 case EnterNotify:
01730 case LeaveNotify:
01731 return true;
01732 default:
01733 break;
01734 }
01735 }
01736
01737 if (x11Filter) {
01738 for (QWidget *w=x11Filter->first(); w; w=x11Filter->next()) {
01739 if (((KAppX11HackWidget*) w)->publicx11Event(_event))
01740 return true;
01741 }
01742 }
01743
01744 if ((_event->type == ClientMessage) &&
01745 (_event->xclient.message_type == kipcCommAtom))
01746 {
01747 XClientMessageEvent *cme = (XClientMessageEvent *) _event;
01748
01749 int id = cme->data.l[0];
01750 int arg = cme->data.l[1];
01751 if ((id < 32) && (kipcEventMask & (1 << id)))
01752 {
01753 switch (id)
01754 {
01755 case KIPC::StyleChanged:
01756 KGlobal::config()->reparseConfiguration();
01757 kdisplaySetStyle();
01758 break;
01759
01760 case KIPC::ToolbarStyleChanged:
01761 KGlobal::config()->reparseConfiguration();
01762 if (useStyles)
01763 emit toolbarAppearanceChanged(arg);
01764 break;
01765
01766 case KIPC::PaletteChanged:
01767 KGlobal::config()->reparseConfiguration();
01768 kdisplaySetPalette();
01769 break;
01770
01771 case KIPC::FontChanged:
01772 KGlobal::config()->reparseConfiguration();
01773 KGlobalSettings::rereadFontSettings();
01774 kdisplaySetFont();
01775 break;
01776
01777 case KIPC::BackgroundChanged:
01778 emit backgroundChanged(arg);
01779 break;
01780
01781 case KIPC::SettingsChanged:
01782 KGlobal::config()->reparseConfiguration();
01783 if (arg == SETTINGS_PATHS)
01784 KGlobalSettings::rereadPathSettings();
01785 else if (arg == SETTINGS_MOUSE)
01786 KGlobalSettings::rereadMouseSettings();
01787 propagateSettings((SettingsCategory)arg);
01788 break;
01789
01790 case KIPC::IconChanged:
01791 QPixmapCache::clear();
01792 KGlobal::config()->reparseConfiguration();
01793 KGlobal::instance()->newIconLoader();
01794 emit iconChanged(arg);
01795 break;
01796
01797 case KIPC::ClipboardConfigChanged:
01798 KClipboardSynchronizer::newConfiguration(arg);
01799 break;
01800 }
01801 }
01802 else if (id >= 32)
01803 {
01804 emit kipcMessage(id, arg);
01805 }
01806 return true;
01807 }
01808 return false;
01809 }
01810 #endif // Q_WS_X11
01811
01812 void KApplication::updateUserTimestamp( unsigned long time )
01813 {
01814 #if defined Q_WS_X11
01815 if( time == 0 )
01816 {
01817 Window w = XCreateSimpleWindow( qt_xdisplay(), qt_xrootwin(), 0, 0, 1, 1, 0, 0, 0 );
01818 XSelectInput( qt_xdisplay(), w, PropertyChangeMask );
01819 unsigned char data[ 1 ];
01820 XChangeProperty( qt_xdisplay(), w, XA_ATOM, XA_ATOM, 8, PropModeAppend, data, 1 );
01821 XEvent ev;
01822 XWindowEvent( qt_xdisplay(), w, PropertyChangeMask, &ev );
01823 time = ev.xproperty.time;
01824 XDestroyWindow( qt_xdisplay(), w );
01825 }
01826 if( qt_x_user_time == 0
01827 || time - qt_x_user_time < 1000000000U )
01828 qt_x_user_time = time;
01829 #endif
01830 }
01831
01832 unsigned long KApplication::userTimestamp() const
01833 {
01834 #if defined Q_WS_X11
01835 return qt_x_user_time;
01836 #else
01837 return 0;
01838 #endif
01839 }
01840
01841 void KApplication::updateRemoteUserTimestamp( const QCString& dcopId, unsigned long time )
01842 {
01843 #if defined Q_WS_X11
01844 if( time == 0 )
01845 time = qt_x_user_time;
01846 DCOPRef( dcopId, "MainApplication-Interface" ).call( "updateUserTimestamp", time );
01847 #endif
01848 }
01849
01850 void KApplication::invokeEditSlot( const char *slot )
01851 {
01852 QObject *object = focusWidget();
01853 if( !object )
01854 return;
01855
01856 QMetaObject *meta = object->metaObject();
01857
01858 int idx = meta->findSlot( slot + 1, true );
01859 if( idx < 0 )
01860 return;
01861
01862 object->qt_invoke( idx, 0 );
01863 }
01864
01865 void KApplication::addKipcEventMask(int id)
01866 {
01867 if (id >= 32)
01868 {
01869 kdDebug(101) << "Cannot use KIPC event mask for message IDs >= 32\n";
01870 return;
01871 }
01872 kipcEventMask |= (1 << id);
01873 }
01874
01875 void KApplication::removeKipcEventMask(int id)
01876 {
01877 if (id >= 32)
01878 {
01879 kdDebug(101) << "Cannot use KIPC event mask for message IDs >= 32\n";
01880 return;
01881 }
01882 kipcEventMask &= ~(1 << id);
01883 }
01884
01885 void KApplication::enableStyles()
01886 {
01887 if (!useStyles)
01888 {
01889 useStyles = true;
01890 applyGUIStyle();
01891 }
01892 }
01893
01894 void KApplication::disableStyles()
01895 {
01896 useStyles = false;
01897 }
01898
01899 void KApplication::applyGUIStyle()
01900 {
01901 if ( !useStyles ) return;
01902
01903 KConfigGroup pConfig (KGlobal::config(), "General");
01904 QString defaultStyle = KStyle::defaultStyle();
01905 QString styleStr = pConfig.readEntry("widgetStyle", defaultStyle);
01906
01907 if (d->overrideStyle.isEmpty()) {
01908
01909
01910
01911 QStyle* sp = QStyleFactory::create( styleStr );
01912
01913
01914 if ( !sp && styleStr != defaultStyle)
01915 sp = QStyleFactory::create( defaultStyle );
01916 if ( !sp )
01917 sp = QStyleFactory::create( *(QStyleFactory::keys().begin()) );
01918 setStyle(sp);
01919 }
01920 else
01921 setStyle(d->overrideStyle);
01922
01923 kdisplaySetPalette();
01924
01925 QApplication::x11_apply_settings();
01926 }
01927
01928 QString KApplication::caption() const
01929 {
01930
01931 if( !aCaption.isNull() )
01932 return aCaption;
01933 else
01934
01935 if ( KGlobal::instance()->aboutData() )
01936 return KGlobal::instance()->aboutData()->programName();
01937 else
01938
01939 return name();
01940 }
01941
01942
01943
01944
01945
01946
01947 QString KApplication::makeStdCaption( const QString &userCaption,
01948 bool withAppName, bool modified ) const
01949 {
01950 QString s = userCaption.isEmpty() ? caption() : userCaption;
01951
01952
01953 if (modified)
01954 s += QString::fromUtf8(" [") + i18n("modified") + QString::fromUtf8("]");
01955
01956 if ( !userCaption.isEmpty() ) {
01957
01958
01959 if ( withAppName && !caption().isNull() && !userCaption.endsWith(caption()) )
01960 s += QString::fromUtf8(" - ") + caption();
01961 }
01962
01963 return s;
01964 }
01965
01966 QPalette KApplication::createApplicationPalette()
01967 {
01968 KConfig *config = KGlobal::config();
01969 KConfigGroupSaver saver( config, "General" );
01970 return createApplicationPalette( config, KGlobalSettings::contrast() );
01971 }
01972
01973 QPalette KApplication::createApplicationPalette( KConfig *config, int contrast_ )
01974 {
01975 QColor kde34Background( 239, 239, 239 );
01976 QColor kde34Blue( 103,141,178 );
01977
01978 QColor kde34Button;
01979 if ( QPixmap::defaultDepth() > 8 )
01980 kde34Button.setRgb( 221, 223, 228 );
01981 else
01982 kde34Button.setRgb( 220, 220, 220 );
01983
01984 QColor kde34Link( 0, 0, 238 );
01985 QColor kde34VisitedLink( 82, 24, 139 );
01986
01987 QColor background = config->readColorEntry( "background", &kde34Background );
01988 QColor foreground = config->readColorEntry( "foreground", &black );
01989 QColor button = config->readColorEntry( "buttonBackground", &kde34Button );
01990 QColor buttonText = config->readColorEntry( "buttonForeground", &black );
01991 QColor highlight = config->readColorEntry( "selectBackground", &kde34Blue );
01992 QColor highlightedText = config->readColorEntry( "selectForeground", &white );
01993 QColor base = config->readColorEntry( "windowBackground", &white );
01994 QColor baseText = config->readColorEntry( "windowForeground", &black );
01995 QColor link = config->readColorEntry( "linkColor", &kde34Link );
01996 QColor visitedLink = config->readColorEntry( "visitedLinkColor", &kde34VisitedLink );
01997
01998 int highlightVal, lowlightVal;
01999 highlightVal = 100 + (2*contrast_+4)*16/10;
02000 lowlightVal = 100 + (2*contrast_+4)*10;
02001
02002 QColor disfg = foreground;
02003
02004 int h, s, v;
02005 disfg.hsv( &h, &s, &v );
02006 if (v > 128)
02007
02008 disfg = disfg.dark(lowlightVal);
02009 else if (disfg != black)
02010
02011 disfg = disfg.light(highlightVal);
02012 else
02013
02014 disfg = Qt::darkGray;
02015
02016
02017 QColorGroup disabledgrp(disfg, background,
02018 background.light(highlightVal),
02019 background.dark(lowlightVal),
02020 background.dark(120),
02021 background.dark(120), base);
02022
02023 QColorGroup colgrp(foreground, background, background.light(highlightVal),
02024 background.dark(lowlightVal),
02025 background.dark(120),
02026 baseText, base);
02027
02028 int inlowlightVal = lowlightVal-25;
02029 if(inlowlightVal < 120)
02030 inlowlightVal = 120;
02031
02032 colgrp.setColor(QColorGroup::Highlight, highlight);
02033 colgrp.setColor(QColorGroup::HighlightedText, highlightedText);
02034 colgrp.setColor(QColorGroup::Button, button);
02035 colgrp.setColor(QColorGroup::ButtonText, buttonText);
02036 colgrp.setColor(QColorGroup::Midlight, background.light(110));
02037 colgrp.setColor(QColorGroup::Link, link);
02038 colgrp.setColor(QColorGroup::LinkVisited, visitedLink);
02039
02040 disabledgrp.setColor(QColorGroup::Button, button);
02041
02042 QColor disbtntext = buttonText;
02043 disbtntext.hsv( &h, &s, &v );
02044 if (v > 128)
02045
02046 disbtntext = disbtntext.dark(lowlightVal);
02047 else if (disbtntext != black)
02048
02049 disbtntext = disbtntext.light(highlightVal);
02050 else
02051
02052 disbtntext = Qt::darkGray;
02053
02054 disabledgrp.setColor(QColorGroup::ButtonText, disbtntext);
02055 disabledgrp.setColor(QColorGroup::Midlight, background.light(110));
02056 disabledgrp.setColor(QColorGroup::Highlight, highlight.dark(120));
02057 disabledgrp.setColor(QColorGroup::Link, link);
02058 disabledgrp.setColor(QColorGroup::LinkVisited, visitedLink);
02059
02060 return QPalette(colgrp, disabledgrp, colgrp);
02061 }
02062
02063
02064 void KApplication::kdisplaySetPalette()
02065 {
02066 #ifdef Q_WS_MACX
02067
02068 {
02069 KConfig *config = KGlobal::config();
02070 KConfigGroupSaver saver( config, "General" );
02071 bool do_not_set_palette = FALSE;
02072 if(config->readBoolEntry("nopaletteChange", &do_not_set_palette))
02073 return;
02074 }
02075 #endif
02076 QApplication::setPalette( createApplicationPalette(), true);
02077 emit kdisplayPaletteChanged();
02078 emit appearanceChanged();
02079 }
02080
02081
02082 void KApplication::kdisplaySetFont()
02083 {
02084 QApplication::setFont(KGlobalSettings::generalFont(), true);
02085 QApplication::setFont(KGlobalSettings::menuFont(), true, "QMenuBar");
02086 QApplication::setFont(KGlobalSettings::menuFont(), true, "QPopupMenu");
02087 QApplication::setFont(KGlobalSettings::menuFont(), true, "KPopupTitle");
02088
02089
02090 QStyleSheet* sheet = QStyleSheet::defaultSheet();
02091 sheet->item ("pre")->setFontFamily (KGlobalSettings::fixedFont().family());
02092 sheet->item ("code")->setFontFamily (KGlobalSettings::fixedFont().family());
02093 sheet->item ("tt")->setFontFamily (KGlobalSettings::fixedFont().family());
02094
02095 emit kdisplayFontChanged();
02096 emit appearanceChanged();
02097 }
02098
02099
02100 void KApplication::kdisplaySetStyle()
02101 {
02102 if (useStyles)
02103 {
02104 applyGUIStyle();
02105 emit kdisplayStyleChanged();
02106 emit appearanceChanged();
02107 }
02108 }
02109
02110
02111 void KApplication::propagateSettings(SettingsCategory arg)
02112 {
02113 KConfigBase* config = KGlobal::config();
02114 KConfigGroupSaver saver( config, "KDE" );
02115
02116 int num = config->readNumEntry("CursorBlinkRate", QApplication::cursorFlashTime());
02117 if ((num != 0) && (num < 200))
02118 num = 200;
02119 if (num > 2000)
02120 num = 2000;
02121 QApplication::setCursorFlashTime(num);
02122 num = config->readNumEntry("DoubleClickInterval", QApplication::doubleClickInterval());
02123 QApplication::setDoubleClickInterval(num);
02124 num = config->readNumEntry("StartDragTime", QApplication::startDragTime());
02125 QApplication::setStartDragTime(num);
02126 num = config->readNumEntry("StartDragDist", QApplication::startDragDistance());
02127 QApplication::setStartDragDistance(num);
02128 num = config->readNumEntry("WheelScrollLines", QApplication::wheelScrollLines());
02129 QApplication::setWheelScrollLines(num);
02130
02131 bool b = config->readBoolEntry("EffectAnimateMenu", false);
02132 QApplication::setEffectEnabled( Qt::UI_AnimateMenu, b);
02133 b = config->readBoolEntry("EffectFadeMenu", false);
02134 QApplication::setEffectEnabled( Qt::UI_FadeMenu, b);
02135 b = config->readBoolEntry("EffectAnimateCombo", false);
02136 QApplication::setEffectEnabled( Qt::UI_AnimateCombo, b);
02137 b = config->readBoolEntry("EffectAnimateTooltip", false);
02138 QApplication::setEffectEnabled( Qt::UI_AnimateTooltip, b);
02139 b = config->readBoolEntry("EffectFadeTooltip", false);
02140 QApplication::setEffectEnabled( Qt::UI_FadeTooltip, b);
02141 b = !config->readBoolEntry("EffectNoTooltip", false);
02142 QToolTip::setGloballyEnabled( b );
02143
02144 emit settingsChanged(arg);
02145 }
02146
02147 void KApplication::installKDEPropertyMap()
02148 {
02149 #ifndef QT_NO_SQL
02150 static bool installed = false;
02151 if (installed) return;
02152 installed = true;
02159
02160 QSqlPropertyMap *kdeMap = new QSqlPropertyMap;
02161 kdeMap->insert( "KColorButton", "color" );
02162 kdeMap->insert( "KComboBox", "currentItem" );
02163 kdeMap->insert( "KDatePicker", "date" );
02164 kdeMap->insert( "KDateWidget", "date" );
02165 kdeMap->insert( "KDateTimeWidget", "dateTime" );
02166 kdeMap->insert( "KEditListBox", "items" );
02167 kdeMap->insert( "KFontCombo", "family" );
02168 kdeMap->insert( "KFontRequester", "font" );
02169 kdeMap->insert( "KFontChooser", "font" );
02170 kdeMap->insert( "KHistoryCombo", "currentItem" );
02171 kdeMap->insert( "KListBox", "currentItem" );
02172 kdeMap->insert( "KLineEdit", "text" );
02173 kdeMap->insert( "KRestrictedLine", "text" );
02174 kdeMap->insert( "KSqueezedTextLabel", "text" );
02175 kdeMap->insert( "KTextBrowser", "source" );
02176 kdeMap->insert( "KTextEdit", "text" );
02177 kdeMap->insert( "KURLRequester", "url" );
02178 kdeMap->insert( "KPasswordEdit", "password" );
02179 kdeMap->insert( "KIntNumInput", "value" );
02180 kdeMap->insert( "KIntSpinBox", "value" );
02181 kdeMap->insert( "KDoubleNumInput", "value" );
02182 #if QT_VERSION < 0x030200
02183 kdeMap->insert( "QRadioButton", "checked" );
02184 #endif
02185
02186
02187 kdeMap->insert( "QGroupBox", "checked" );
02188 kdeMap->insert( "QTabWidget", "currentPage" );
02189
02190 QSqlPropertyMap::installDefaultMap( kdeMap );
02191 #endif
02192 }
02193
02194 void KApplication::invokeHelp( const QString& anchor,
02195 const QString& _appname) const
02196 {
02197 return invokeHelp( anchor, _appname, "" );
02198 }
02199
02200 #ifndef Q_WS_WIN
02201
02202
02203 void KApplication::invokeHelp( const QString& anchor,
02204 const QString& _appname,
02205 const QCString& startup_id ) const
02206 {
02207 QString url;
02208 QString appname;
02209 if (_appname.isEmpty())
02210 appname = name();
02211 else
02212 appname = _appname;
02213
02214 if (!anchor.isEmpty())
02215 url = QString("help:/%1?anchor=%2").arg(appname).arg(anchor);
02216 else
02217 url = QString("help:/%1/index.html").arg(appname);
02218
02219 QString error;
02220 if ( !dcopClient()->isApplicationRegistered("khelpcenter") )
02221 {
02222 if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, startup_id, false))
02223 {
02224 if (Tty != kapp->type())
02225 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Help Center"),
02226 i18n("Could not launch the KDE Help Center:\n\n%1").arg(error), i18n("&OK"));
02227 else
02228 kdWarning() << "Could not launch help:\n" << error << endl;
02229 return;
02230 }
02231 }
02232 else
02233 DCOPRef( "khelpcenter", "KHelpCenterIface" ).send( "openUrl", url, startup_id );
02234 }
02235 #endif
02236
02237 void KApplication::invokeHTMLHelp( const QString& _filename, const QString& topic ) const
02238 {
02239 kdWarning() << "invoking HTML help is deprecated! use docbook and invokeHelp!\n";
02240
02241 QString filename;
02242
02243 if( _filename.isEmpty() )
02244 filename = QString(name()) + "/index.html";
02245 else
02246 filename = _filename;
02247
02248 QString url;
02249 if (!topic.isEmpty())
02250 url = QString("help:/%1#%2").arg(filename).arg(topic);
02251 else
02252 url = QString("help:/%1").arg(filename);
02253
02254 QString error;
02255 if ( !dcopClient()->isApplicationRegistered("khelpcenter") )
02256 {
02257 if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, "", false))
02258 {
02259 if (Tty != kapp->type())
02260 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Help Center"),
02261 i18n("Could not launch the KDE Help Center:\n\n%1").arg(error), i18n("&OK"));
02262 else
02263 kdWarning() << "Could not launch help:\n" << error << endl;
02264 return;
02265 }
02266 }
02267 else
02268 DCOPRef( "khelpcenter", "KHelpCenterIface" ).send( "openUrl", url );
02269 }
02270
02271
02272 void KApplication::invokeMailer(const QString &address, const QString &subject)
02273 {
02274 return invokeMailer(address,subject,"");
02275 }
02276
02277 void KApplication::invokeMailer(const QString &address, const QString &subject, const QCString& startup_id)
02278 {
02279 invokeMailer(address, QString::null, QString::null, subject, QString::null, QString::null,
02280 QStringList(), startup_id );
02281 }
02282
02283 void KApplication::invokeMailer(const KURL &mailtoURL)
02284 {
02285 return invokeMailer( mailtoURL, "" );
02286 }
02287
02288 void KApplication::invokeMailer(const KURL &mailtoURL, const QCString& startup_id )
02289 {
02290 return invokeMailer( mailtoURL, startup_id, false);
02291 }
02292
02293 void KApplication::invokeMailer(const KURL &mailtoURL, const QCString& startup_id, bool allowAttachments )
02294 {
02295 QString address = KURL::decode_string(mailtoURL.path()), subject, cc, bcc, body;
02296 QStringList queries = QStringList::split('&', mailtoURL.query().mid(1));
02297 QStringList attachURLs;
02298 for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
02299 {
02300 QString q = (*it).lower();
02301 if (q.startsWith("subject="))
02302 subject = KURL::decode_string((*it).mid(8));
02303 else
02304 if (q.startsWith("cc="))
02305 cc = cc.isEmpty()? KURL::decode_string((*it).mid(3)): cc + ',' + KURL::decode_string((*it).mid(3));
02306 else
02307 if (q.startsWith("bcc="))
02308 bcc = bcc.isEmpty()? KURL::decode_string((*it).mid(4)): bcc + ',' + KURL::decode_string((*it).mid(4));
02309 else
02310 if (q.startsWith("body="))
02311 body = KURL::decode_string((*it).mid(5));
02312 else
02313 if (allowAttachments && q.startsWith("attach="))
02314 attachURLs.push_back(KURL::decode_string((*it).mid(7)));
02315 else
02316 if (allowAttachments && q.startsWith("attachment="))
02317 attachURLs.push_back(KURL::decode_string((*it).mid(11)));
02318 else
02319 if (q.startsWith("to="))
02320 address = address.isEmpty()? KURL::decode_string((*it).mid(3)): address + ',' + KURL::decode_string((*it).mid(3));
02321 }
02322
02323 invokeMailer( address, cc, bcc, subject, body, QString::null, attachURLs, startup_id );
02324 }
02325
02326 void KApplication::invokeMailer(const QString &to, const QString &cc, const QString &bcc,
02327 const QString &subject, const QString &body,
02328 const QString & messageFile, const QStringList &attachURLs)
02329 {
02330 return invokeMailer(to,cc,bcc,subject,body,messageFile,attachURLs,"");
02331 }
02332
02333 #ifndef Q_WS_WIN
02334
02335
02336
02337 static QStringList splitEmailAddressList( const QString & aStr )
02338 {
02339
02340
02341
02342
02343
02344
02345
02346
02347
02348 QStringList list;
02349
02350 if (aStr.isEmpty())
02351 return list;
02352
02353 QString addr;
02354 uint addrstart = 0;
02355 int commentlevel = 0;
02356 bool insidequote = false;
02357
02358 for (uint index=0; index<aStr.length(); index++) {
02359
02360
02361 switch (aStr[index].latin1()) {
02362 case '"' :
02363 if (commentlevel == 0)
02364 insidequote = !insidequote;
02365 break;
02366 case '(' :
02367 if (!insidequote)
02368 commentlevel++;
02369 break;
02370 case ')' :
02371 if (!insidequote) {
02372 if (commentlevel > 0)
02373 commentlevel--;
02374 else {
02375
02376
02377 return list;
02378 }
02379 }
02380 break;
02381 case '\\' :
02382 index++;
02383 break;
02384 case ',' :
02385 if (!insidequote && (commentlevel == 0)) {
02386 addr = aStr.mid(addrstart, index-addrstart);
02387 if (!addr.isEmpty())
02388 list += addr.simplifyWhiteSpace();
02389 addrstart = index+1;
02390 }
02391 break;
02392 }
02393 }
02394
02395 if (!insidequote && (commentlevel == 0)) {
02396 addr = aStr.mid(addrstart, aStr.length()-addrstart);
02397 if (!addr.isEmpty())
02398 list += addr.simplifyWhiteSpace();
02399 }
02400
02401
02402
02403
02404
02405 return list;
02406 }
02407
02408 void KApplication::invokeMailer(const QString &_to, const QString &_cc, const QString &_bcc,
02409 const QString &subject, const QString &body,
02410 const QString & , const QStringList &attachURLs,
02411 const QCString& startup_id )
02412 {
02413 KConfig config("emaildefaults");
02414
02415 config.setGroup("Defaults");
02416 QString group = config.readEntry("Profile","Default");
02417
02418 config.setGroup( QString("PROFILE_%1").arg(group) );
02419 QString command = config.readPathEntry("EmailClient");
02420
02421 QString to, cc, bcc;
02422 if (command.isEmpty() || command == QString::fromLatin1("kmail")
02423 || command.endsWith("/kmail"))
02424 {
02425 command = QString::fromLatin1("kmail --composer -s %s -c %c -b %b --body %B --attach %A -- %t");
02426 if ( !_to.isEmpty() )
02427 {
02428
02429
02430 to = QString( "=?utf8?b?%1?=" )
02431 .arg( KCodecs::base64Encode( _to.utf8(), false ) );
02432 }
02433 if ( !_cc.isEmpty() )
02434 cc = QString( "=?utf8?b?%1?=" )
02435 .arg( KCodecs::base64Encode( _cc.utf8(), false ) );
02436 if ( !_bcc.isEmpty() )
02437 bcc = QString( "=?utf8?b?%1?=" )
02438 .arg( KCodecs::base64Encode( _bcc.utf8(), false ) );
02439 } else {
02440 to = _to;
02441 cc = _cc;
02442 bcc = _bcc;
02443 }
02444
02445 if (config.readBoolEntry("TerminalClient", false))
02446 {
02447 KConfigGroup confGroup( KGlobal::config(), "General" );
02448 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", "konsole");
02449 command = preferredTerminal + " -e " + command;
02450 }
02451
02452 QStringList cmdTokens = KShell::splitArgs(command);
02453 QString cmd = cmdTokens[0];
02454 cmdTokens.remove(cmdTokens.begin());
02455
02456 KURL url;
02457 QStringList qry;
02458 if (!to.isEmpty())
02459 {
02460 QStringList tos = splitEmailAddressList( to );
02461 url.setPath( tos.first() );
02462 tos.remove( tos.begin() );
02463 for (QStringList::ConstIterator it = tos.begin(); it != tos.end(); ++it)
02464 qry.append( "to=" + KURL::encode_string( *it ) );
02465 }
02466 const QStringList ccs = splitEmailAddressList( cc );
02467 for (QStringList::ConstIterator it = ccs.begin(); it != ccs.end(); ++it)
02468 qry.append( "cc=" + KURL::encode_string( *it ) );
02469 const QStringList bccs = splitEmailAddressList( bcc );
02470 for (QStringList::ConstIterator it = bccs.begin(); it != bccs.end(); ++it)
02471 qry.append( "bcc=" + KURL::encode_string( *it ) );
02472 for (QStringList::ConstIterator it = attachURLs.begin(); it != attachURLs.end(); ++it)
02473 qry.append( "attach=" + KURL::encode_string( *it ) );
02474 if (!subject.isEmpty())
02475 qry.append( "subject=" + KURL::encode_string( subject ) );
02476 if (!body.isEmpty())
02477 qry.append( "body=" + KURL::encode_string( body ) );
02478 url.setQuery( qry.join( "&" ) );
02479 if ( ! (to.isEmpty() && qry.isEmpty()) )
02480 url.setProtocol("mailto");
02481
02482 QMap<QChar, QString> keyMap;
02483 keyMap.insert('t', to);
02484 keyMap.insert('s', subject);
02485 keyMap.insert('c', cc);
02486 keyMap.insert('b', bcc);
02487 keyMap.insert('B', body);
02488 keyMap.insert('u', url.url());
02489
02490 for (QStringList::Iterator it = cmdTokens.begin(); it != cmdTokens.end(); )
02491 {
02492 if (*it == "%A")
02493 {
02494 if (it == cmdTokens.begin())
02495 continue;
02496 QStringList::ConstIterator urlit = attachURLs.begin();
02497 QStringList::ConstIterator urlend = attachURLs.end();
02498 if ( urlit != urlend )
02499 {
02500 QStringList::Iterator previt = it;
02501 --previt;
02502 *it = *urlit;
02503 ++it;
02504 while ( ++urlit != urlend )
02505 {
02506 cmdTokens.insert( it, *previt );
02507 cmdTokens.insert( it, *urlit );
02508 }
02509 } else {
02510 --it;
02511 it = cmdTokens.remove( cmdTokens.remove( it ) );
02512 }
02513 } else {
02514 *it = KMacroExpander::expandMacros(*it, keyMap);
02515 ++it;
02516 }
02517 }
02518
02519 QString error;
02520
02521
02522 if (kdeinitExec(cmd, cmdTokens, &error, NULL, startup_id ))
02523 if (Tty != kapp->type())
02524 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Mail Client"),
02525 i18n("Could not launch the mail client:\n\n%1").arg(error), i18n("&OK"));
02526 else
02527 kdWarning() << "Could not launch mail client:\n" << error << endl;
02528 }
02529 #endif
02530
02531 void KApplication::invokeBrowser( const QString &url )
02532 {
02533 return invokeBrowser( url, "" );
02534 }
02535
02536 #ifndef Q_WS_WIN
02537
02538
02539 void KApplication::invokeBrowser( const QString &url, const QCString& startup_id )
02540 {
02541 QString error;
02542
02543 if (startServiceByDesktopName("kfmclient", url, &error, 0, 0, startup_id, false))
02544 {
02545 if (Tty != kapp->type())
02546 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Browser"),
02547 i18n("Could not launch the browser:\n\n%1").arg(error), i18n("&OK"));
02548 else
02549 kdWarning() << "Could not launch browser:\n" << error << endl;
02550 return;
02551 }
02552 }
02553 #endif
02554
02555 void KApplication::cut()
02556 {
02557 invokeEditSlot( SLOT( cut() ) );
02558 }
02559
02560 void KApplication::copy()
02561 {
02562 invokeEditSlot( SLOT( copy() ) );
02563 }
02564
02565 void KApplication::paste()
02566 {
02567 invokeEditSlot( SLOT( paste() ) );
02568 }
02569
02570 void KApplication::clear()
02571 {
02572 invokeEditSlot( SLOT( clear() ) );
02573 }
02574
02575 void KApplication::selectAll()
02576 {
02577 invokeEditSlot( SLOT( selectAll() ) );
02578 }
02579
02580 QCString
02581 KApplication::launcher()
02582 {
02583 return "klauncher";
02584 }
02585
02586 static int
02587 startServiceInternal( const QCString &function,
02588 const QString& _name, const QStringList &URLs,
02589 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02590 {
02591 struct serviceResult
02592 {
02593 int result;
02594 QCString dcopName;
02595 QString error;
02596 pid_t pid;
02597 };
02598
02599
02600 DCOPClient *dcopClient;
02601 if (kapp)
02602 dcopClient = kapp->dcopClient();
02603 else
02604 dcopClient = new DCOPClient;
02605
02606 if (!dcopClient->isAttached())
02607 {
02608 if (!dcopClient->attach())
02609 {
02610 if (error)
02611 *error = i18n("Could not register with DCOP.\n");
02612 return -1;
02613 }
02614 }
02615 QByteArray params;
02616 QDataStream stream(params, IO_WriteOnly);
02617 stream << _name << URLs;
02618 QCString replyType;
02619 QByteArray replyData;
02620 QCString _launcher = KApplication::launcher();
02621 QValueList<QCString> envs;
02622 #ifdef Q_WS_X11
02623 if (qt_xdisplay()) {
02624 QCString dpystring(XDisplayString(qt_xdisplay()));
02625 envs.append( QCString("DISPLAY=") + dpystring );
02626 } else if( getenv( "DISPLAY" )) {
02627 QCString dpystring( getenv( "DISPLAY" ));
02628 envs.append( QCString("DISPLAY=") + dpystring );
02629 }
02630 #endif
02631 stream << envs;
02632 #if defined Q_WS_X11
02633
02634 stream << ( startup_id.isEmpty() ? KStartupInfo::createNewStartupId() : startup_id );
02635 #endif
02636 if( function.left( 12 ) != "kdeinit_exec" )
02637 stream << noWait;
02638
02639 if (!dcopClient->call(_launcher, _launcher,
02640 function, params, replyType, replyData))
02641 {
02642 if (error)
02643 *error = i18n("KLauncher could not be reached via DCOP.\n");
02644 if (!kapp)
02645 delete dcopClient;
02646 return -1;
02647 }
02648 if (!kapp)
02649 delete dcopClient;
02650
02651 if (noWait)
02652 return 0;
02653
02654 QDataStream stream2(replyData, IO_ReadOnly);
02655 serviceResult result;
02656 stream2 >> result.result >> result.dcopName >> result.error >> result.pid;
02657 if (dcopService)
02658 *dcopService = result.dcopName;
02659 if (error)
02660 *error = result.error;
02661 if (pid)
02662 *pid = result.pid;
02663 return result.result;
02664 }
02665
02666 int
02667 KApplication::startServiceByName( const QString& _name, const QString &URL,
02668 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02669 {
02670 QStringList URLs;
02671 if (!URL.isEmpty())
02672 URLs.append(URL);
02673 return startServiceInternal(
02674 "start_service_by_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02675 _name, URLs, error, dcopService, pid, startup_id, noWait);
02676 }
02677
02678 int
02679 KApplication::startServiceByName( const QString& _name, const QStringList &URLs,
02680 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02681 {
02682 return startServiceInternal(
02683 "start_service_by_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02684 _name, URLs, error, dcopService, pid, startup_id, noWait);
02685 }
02686
02687 int
02688 KApplication::startServiceByDesktopPath( const QString& _name, const QString &URL,
02689 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02690 {
02691 QStringList URLs;
02692 if (!URL.isEmpty())
02693 URLs.append(URL);
02694 return startServiceInternal(
02695 "start_service_by_desktop_path(QString,QStringList,QValueList<QCString>,QCString,bool)",
02696 _name, URLs, error, dcopService, pid, startup_id, noWait);
02697 }
02698
02699 int
02700 KApplication::startServiceByDesktopPath( const QString& _name, const QStringList &URLs,
02701 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02702 {
02703 return startServiceInternal(
02704 "start_service_by_desktop_path(QString,QStringList,QValueList<QCString>,QCString,bool)",
02705 _name, URLs, error, dcopService, pid, startup_id, noWait);
02706 }
02707
02708 int
02709 KApplication::startServiceByDesktopName( const QString& _name, const QString &URL,
02710 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02711 {
02712 QStringList URLs;
02713 if (!URL.isEmpty())
02714 URLs.append(URL);
02715 return startServiceInternal(
02716 "start_service_by_desktop_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02717 _name, URLs, error, dcopService, pid, startup_id, noWait);
02718 }
02719
02720 int
02721 KApplication::startServiceByDesktopName( const QString& _name, const QStringList &URLs,
02722 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02723 {
02724 return startServiceInternal(
02725 "start_service_by_desktop_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02726 _name, URLs, error, dcopService, pid, startup_id, noWait);
02727 }
02728
02729 int
02730 KApplication::kdeinitExec( const QString& name, const QStringList &args,
02731 QString *error, int *pid )
02732 {
02733 return kdeinitExec( name, args, error, pid, "" );
02734 }
02735
02736 int
02737 KApplication::kdeinitExec( const QString& name, const QStringList &args,
02738 QString *error, int *pid, const QCString& startup_id )
02739 {
02740 return startServiceInternal("kdeinit_exec(QString,QStringList,QValueList<QCString>,QCString)",
02741 name, args, error, 0, pid, startup_id, false);
02742 }
02743
02744 int
02745 KApplication::kdeinitExecWait( const QString& name, const QStringList &args,
02746 QString *error, int *pid )
02747 {
02748 return kdeinitExecWait( name, args, error, pid, "" );
02749 }
02750
02751 int
02752 KApplication::kdeinitExecWait( const QString& name, const QStringList &args,
02753 QString *error, int *pid, const QCString& startup_id )
02754 {
02755 return startServiceInternal("kdeinit_exec_wait(QString,QStringList,QValueList<QCString>,QCString)",
02756 name, args, error, 0, pid, startup_id, false);
02757 }
02758
02759 QString KApplication::tempSaveName( const QString& pFilename ) const
02760 {
02761 QString aFilename;
02762
02763 if( QDir::isRelativePath(pFilename) )
02764 {
02765 kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
02766 aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
02767 }
02768 else
02769 aFilename = pFilename;
02770
02771 QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
02772 if( !aAutosaveDir.exists() )
02773 {
02774 if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
02775 {
02776
02777 aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
02778 }
02779 }
02780
02781 aFilename.replace( "/", "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
02782
02783 return aFilename;
02784 }
02785
02786
02787 QString KApplication::checkRecoverFile( const QString& pFilename,
02788 bool& bRecover ) const
02789 {
02790 QString aFilename;
02791
02792 if( QDir::isRelativePath(pFilename) )
02793 {
02794 kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
02795 aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
02796 }
02797 else
02798 aFilename = pFilename;
02799
02800 QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
02801 if( !aAutosaveDir.exists() )
02802 {
02803 if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
02804 {
02805
02806 aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
02807 }
02808 }
02809
02810 aFilename.replace( "/", "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
02811
02812 if( QFile( aFilename ).exists() )
02813 {
02814 bRecover = true;
02815 return aFilename;
02816 }
02817 else
02818 {
02819 bRecover = false;
02820 return pFilename;
02821 }
02822 }
02823
02824
02825 bool checkAccess(const QString& pathname, int mode)
02826 {
02827 int accessOK = access( QFile::encodeName(pathname), mode );
02828 if ( accessOK == 0 )
02829 return true;
02830
02831
02832
02833
02834 if ( (mode & W_OK) == 0 )
02835 return false;
02836
02837
02838 if (!access( QFile::encodeName(pathname), F_OK))
02839 return false;
02840
02841
02842 QString dirName(pathname);
02843 int pos = dirName.findRev('/');
02844 if ( pos == -1 )
02845 return false;
02846 else if ( pos == 0 )
02847 pos = 1;
02848
02849 dirName.truncate(pos);
02850
02851 accessOK = access( QFile::encodeName(dirName), W_OK );
02852
02853 if ( accessOK == 0 )
02854 return true;
02855 else
02856 return false;
02857 }
02858
02859 void KApplication::setTopWidget( QWidget *topWidget )
02860 {
02861 if( !topWidget )
02862 return;
02863
02864
02865 if ( !topWidget->inherits("KMainWindow") ) {
02866 topWidget->setCaption( caption() );
02867 }
02868
02869
02870 topWidget->setIcon( icon() );
02871 #if defined Q_WS_X11
02872
02873 KWin::setIcons(topWidget->winId(), icon(), miniIcon() );
02874
02875
02876 KStartupInfo::setWindowStartupId( topWidget->winId(), startupId());
02877 #endif
02878 }
02879
02880 QCString KApplication::startupId() const
02881 {
02882 return d->startup_id;
02883 }
02884
02885 void KApplication::setStartupId( const QCString& startup_id )
02886 {
02887 if( startup_id == d->startup_id )
02888 return;
02889 #if defined Q_WS_X11
02890 KStartupInfo::handleAutoAppStartedSending();
02891 #endif
02892 if( startup_id.isEmpty())
02893 d->startup_id = "0";
02894 else
02895 {
02896 d->startup_id = startup_id;
02897 #if defined Q_WS_X11
02898 KStartupInfoId id;
02899 id.initId( startup_id );
02900 long timestamp = id.timestamp();
02901 if( timestamp != 0 )
02902 updateUserTimestamp( timestamp );
02903 #endif
02904 }
02905 }
02906
02907
02908
02909 void KApplication::read_app_startup_id()
02910 {
02911 #if defined Q_WS_X11
02912 KStartupInfoId id = KStartupInfo::currentStartupIdEnv();
02913 KStartupInfo::resetStartupEnv();
02914 d->startup_id = id.id();
02915 #endif
02916 }
02917
02918 int KApplication::random()
02919 {
02920 static bool init = false;
02921 if (!init)
02922 {
02923 unsigned int seed;
02924 init = true;
02925 int fd = open("/dev/urandom", O_RDONLY);
02926 if (fd < 0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed))
02927 {
02928
02929 srand(getpid());
02930 seed = rand()+time(0);
02931 }
02932 if (fd >= 0) close(fd);
02933 srand(seed);
02934 }
02935 return rand();
02936 }
02937
02938 QString KApplication::randomString(int length)
02939 {
02940 if (length <=0 ) return QString::null;
02941
02942 QString str; str.setLength( length );
02943 int i = 0;
02944 while (length--)
02945 {
02946 int r=random() % 62;
02947 r+=48;
02948 if (r>57) r+=7;
02949 if (r>90) r+=6;
02950 str[i++] = char(r);
02951
02952 }
02953 return str;
02954 }
02955
02956 bool KApplication::authorize(const QString &genericAction)
02957 {
02958 if (!d->actionRestrictions)
02959 return true;
02960
02961 KConfig *config = KGlobal::config();
02962 KConfigGroupSaver saver( config, "KDE Action Restrictions" );
02963 return config->readBoolEntry(genericAction, true);
02964 }
02965
02966 bool KApplication::authorizeKAction(const char *action)
02967 {
02968 if (!d->actionRestrictions || !action)
02969 return true;
02970
02971 static const QString &action_prefix = KGlobal::staticQString( "action/" );
02972
02973 return authorize(action_prefix + action);
02974 }
02975
02976 bool KApplication::authorizeControlModule(const QString &menuId)
02977 {
02978 if (menuId.isEmpty() || kde_kiosk_exception)
02979 return true;
02980 KConfig *config = KGlobal::config();
02981 KConfigGroupSaver saver( config, "KDE Control Module Restrictions" );
02982 return config->readBoolEntry(menuId, true);
02983 }
02984
02985 QStringList KApplication::authorizeControlModules(const QStringList &menuIds)
02986 {
02987 KConfig *config = KGlobal::config();
02988 KConfigGroupSaver saver( config, "KDE Control Module Restrictions" );
02989 QStringList result;
02990 for(QStringList::ConstIterator it = menuIds.begin();
02991 it != menuIds.end(); ++it)
02992 {
02993 if (config->readBoolEntry(*it, true))
02994 result.append(*it);
02995 }
02996 return result;
02997 }
02998
02999 void KApplication::initUrlActionRestrictions()
03000 {
03001 d->urlActionRestrictions.setAutoDelete(true);
03002 d->urlActionRestrictions.clear();
03003 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03004 ("open", QString::null, QString::null, QString::null, QString::null, QString::null, QString::null, true));
03005 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03006 ("list", QString::null, QString::null, QString::null, QString::null, QString::null, QString::null, true));
03007
03008
03009
03010
03011
03012 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03013 ("link", QString::null, QString::null, QString::null, ":internet", QString::null, QString::null, true));
03014 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03015 ("redirect", QString::null, QString::null, QString::null, ":internet", QString::null, QString::null, true));
03016
03017
03018
03019 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03020 ("redirect", QString::null, QString::null, QString::null, "file", QString::null, QString::null, true));
03021 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03022 ("redirect", ":internet", QString::null, QString::null, "file", QString::null, QString::null, false));
03023
03024
03025 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03026 ("redirect", ":local", QString::null, QString::null, QString::null, QString::null, QString::null, true));
03027
03028
03029 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03030 ("redirect", QString::null, QString::null, QString::null, "about", QString::null, QString::null, true));
03031
03032
03033 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03034 ("redirect", QString::null, QString::null, QString::null, "=", QString::null, QString::null, true));
03035
03036 KConfig *config = KGlobal::config();
03037 KConfigGroupSaver saver( config, "KDE URL Restrictions" );
03038 int count = config->readNumEntry("rule_count");
03039 QString keyFormat = QString("rule_%1");
03040 for(int i = 1; i <= count; i++)
03041 {
03042 QString key = keyFormat.arg(i);
03043 QStringList rule = config->readListEntry(key);
03044 if (rule.count() != 8)
03045 continue;
03046 QString action = rule[0];
03047 QString refProt = rule[1];
03048 QString refHost = rule[2];
03049 QString refPath = rule[3];
03050 QString urlProt = rule[4];
03051 QString urlHost = rule[5];
03052 QString urlPath = rule[6];
03053 QString strEnabled = rule[7].lower();
03054
03055 bool bEnabled = (strEnabled == "true");
03056
03057 if (refPath.startsWith("$HOME"))
03058 refPath.replace(0, 5, QDir::homeDirPath());
03059 else if (refPath.startsWith("~"))
03060 refPath.replace(0, 1, QDir::homeDirPath());
03061 if (urlPath.startsWith("$HOME"))
03062 urlPath.replace(0, 5, QDir::homeDirPath());
03063 else if (urlPath.startsWith("~"))
03064 urlPath.replace(0, 1, QDir::homeDirPath());
03065
03066 if (refPath.startsWith("$TMP"))
03067 refPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
03068 if (urlPath.startsWith("$TMP"))
03069 urlPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
03070
03071 d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
03072 ( action, refProt, refHost, refPath, urlProt, urlHost, urlPath, bEnabled));
03073 }
03074 }
03075
03076 void KApplication::allowURLAction(const QString &action, const KURL &_baseURL, const KURL &_destURL)
03077 {
03078 if (authorizeURLAction(action, _baseURL, _destURL))
03079 return;
03080
03081 d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
03082 ( action, _baseURL.protocol(), _baseURL.host(), _baseURL.path(-1),
03083 _destURL.protocol(), _destURL.host(), _destURL.path(-1), true));
03084 }
03085
03086 bool KApplication::authorizeURLAction(const QString &action, const KURL &_baseURL, const KURL &_destURL)
03087 {
03088 if (_destURL.isEmpty())
03089 return true;
03090
03091 bool result = false;
03092 if (d->urlActionRestrictions.isEmpty())
03093 initUrlActionRestrictions();
03094
03095 KURL baseURL(_baseURL);
03096 baseURL.setPath(QDir::cleanDirPath(baseURL.path()));
03097 QString baseClass = KProtocolInfo::protocolClass(baseURL.protocol());
03098 KURL destURL(_destURL);
03099 destURL.setPath(QDir::cleanDirPath(destURL.path()));
03100 QString destClass = KProtocolInfo::protocolClass(destURL.protocol());
03101
03102 for(KApplicationPrivate::URLActionRule *rule = d->urlActionRestrictions.first();
03103 rule; rule = d->urlActionRestrictions.next())
03104 {
03105 if ((result != rule->permission) &&
03106 (action == rule->action) &&
03107 rule->baseMatch(baseURL, baseClass) &&
03108 rule->destMatch(destURL, destClass, baseURL, baseClass))
03109 {
03110 result = rule->permission;
03111 }
03112 }
03113 return result;
03114 }
03115
03116
03117 uint KApplication::keyboardModifiers()
03118 {
03119 #ifdef Q_WS_X11
03120 Window root;
03121 Window child;
03122 int root_x, root_y, win_x, win_y;
03123 uint keybstate;
03124 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03125 &root_x, &root_y, &win_x, &win_y, &keybstate );
03126 return keybstate & 0x00ff;
03127 #elif defined W_WS_MACX
03128 return GetCurrentEventKeyModifiers() & 0x00ff;
03129 #else
03130
03131 return 0;
03132 #endif
03133 }
03134
03135 uint KApplication::mouseState()
03136 {
03137 uint mousestate;
03138 #ifdef Q_WS_X11
03139 Window root;
03140 Window child;
03141 int root_x, root_y, win_x, win_y;
03142 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03143 &root_x, &root_y, &win_x, &win_y, &mousestate );
03144 #elif defined(Q_WS_WIN)
03145 const bool mousebtn_swapped = GetSystemMetrics(SM_SWAPBUTTON);
03146 if (GetAsyncKeyState(VK_LBUTTON))
03147 mousestate |= (mousebtn_swapped ? Button3Mask : Button1Mask);
03148 if (GetAsyncKeyState(VK_MBUTTON))
03149 mousestate |= Button2Mask;
03150 if (GetAsyncKeyState(VK_RBUTTON))
03151 mousestate |= (mousebtn_swapped ? Button1Mask : Button3Mask);
03152 #elif defined(Q_WS_MACX)
03153 mousestate = GetCurrentEventButtonState();
03154 #else
03155
03156 #endif
03157 return mousestate & 0xff00;
03158 }
03159
03160 Qt::ButtonState KApplication::keyboardMouseState()
03161 {
03162 int ret = 0;
03163 #ifdef Q_WS_X11
03164 Window root;
03165 Window child;
03166 int root_x, root_y, win_x, win_y;
03167 uint state;
03168 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03169 &root_x, &root_y, &win_x, &win_y, &state );
03170
03171 if( state & Button1Mask )
03172 ret |= LeftButton;
03173 if( state & Button2Mask )
03174 ret |= MidButton;
03175 if( state & Button3Mask )
03176 ret |= RightButton;
03177 if( state & ShiftMask )
03178 ret |= ShiftButton;
03179 if( state & ControlMask )
03180 ret |= ControlButton;
03181 if( state & KKeyNative::modX( KKey::ALT ))
03182 ret |= AltButton;
03183 if( state & KKeyNative::modX( KKey::WIN ))
03184 ret |= MetaButton;
03185 #elif defined(Q_WS_WIN)
03186 const bool mousebtn_swapped = GetSystemMetrics(SM_SWAPBUTTON);
03187 if (GetAsyncKeyState(VK_LBUTTON))
03188 ret |= (mousebtn_swapped ? RightButton : LeftButton);
03189 if (GetAsyncKeyState(VK_MBUTTON))
03190 ret |= MidButton;
03191 if (GetAsyncKeyState(VK_RBUTTON))
03192 ret |= (mousebtn_swapped ? LeftButton : RightButton);
03193 if (GetAsyncKeyState(VK_SHIFT))
03194 ret |= ShiftButton;
03195 if (GetAsyncKeyState(VK_CONTROL))
03196 ret |= ControlButton;
03197 if (GetAsyncKeyState(VK_MENU))
03198 ret |= AltButton;
03199 if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN))
03200 ret |= MetaButton;
03201 #else
03202
03203 #endif
03204 return static_cast< ButtonState >( ret );
03205 }
03206
03207 void KApplication::installSigpipeHandler()
03208 {
03209 #ifdef Q_OS_UNIX
03210 struct sigaction act;
03211 act.sa_handler = SIG_IGN;
03212 sigemptyset( &act.sa_mask );
03213 act.sa_flags = 0;
03214 sigaction( SIGPIPE, &act, 0 );
03215 #endif
03216 }
03217
03218 void KApplication::sigpipeHandler(int)
03219 {
03220 int saved_errno = errno;
03221
03222 #ifndef NDEBUG
03223 char msg[1000];
03224 sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid());
03225 write(2, msg, strlen(msg));
03226 #endif
03227
03228
03229 errno = saved_errno;
03230 }
03231
03232 bool KApplication::guiEnabled()
03233 {
03234 return kapp && kapp->d->guiEnabled;
03235 }
03236
03237 void KApplication::virtual_hook( int id, void* data )
03238 { KInstance::virtual_hook( id, data ); }
03239
03240 void KSessionManaged::virtual_hook( int, void* )
03241 { }
03242
03243 #include "kapplication.moc"