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
01926 QString KApplication::caption() const
01927 {
01928
01929 if( !aCaption.isNull() )
01930 return aCaption;
01931 else
01932
01933 if ( KGlobal::instance()->aboutData() )
01934 return KGlobal::instance()->aboutData()->programName();
01935 else
01936
01937 return name();
01938 }
01939
01940
01941
01942
01943
01944
01945 QString KApplication::makeStdCaption( const QString &userCaption,
01946 bool withAppName, bool modified ) const
01947 {
01948 QString s = userCaption.isEmpty() ? caption() : userCaption;
01949
01950
01951 if (modified)
01952 s += QString::fromUtf8(" [") + i18n("modified") + QString::fromUtf8("]");
01953
01954 if ( !userCaption.isEmpty() ) {
01955
01956
01957 if ( withAppName && !caption().isNull() && !userCaption.endsWith(caption()) )
01958 s += QString::fromUtf8(" - ") + caption();
01959 }
01960
01961 return s;
01962 }
01963
01964 QPalette KApplication::createApplicationPalette()
01965 {
01966 KConfig *config = KGlobal::config();
01967 KConfigGroupSaver saver( config, "General" );
01968 return createApplicationPalette( config, KGlobalSettings::contrast() );
01969 }
01970
01971 QPalette KApplication::createApplicationPalette( KConfig *config, int contrast_ )
01972 {
01973 QColor kde34Background( 239, 239, 239 );
01974 QColor kde34Blue( 103,141,178 );
01975
01976 QColor kde34Button;
01977 if ( QPixmap::defaultDepth() > 8 )
01978 kde34Button.setRgb( 221, 223, 228 );
01979 else
01980 kde34Button.setRgb( 220, 220, 220 );
01981
01982 QColor kde34Link( 0, 0, 238 );
01983 QColor kde34VisitedLink( 82, 24, 139 );
01984
01985 QColor background = config->readColorEntry( "background", &kde34Background );
01986 QColor foreground = config->readColorEntry( "foreground", &black );
01987 QColor button = config->readColorEntry( "buttonBackground", &kde34Button );
01988 QColor buttonText = config->readColorEntry( "buttonForeground", &black );
01989 QColor highlight = config->readColorEntry( "selectBackground", &kde34Blue );
01990 QColor highlightedText = config->readColorEntry( "selectForeground", &white );
01991 QColor base = config->readColorEntry( "windowBackground", &white );
01992 QColor baseText = config->readColorEntry( "windowForeground", &black );
01993 QColor link = config->readColorEntry( "linkColor", &kde34Link );
01994 QColor visitedLink = config->readColorEntry( "visitedLinkColor", &kde34VisitedLink );
01995
01996 int highlightVal, lowlightVal;
01997 highlightVal = 100 + (2*contrast_+4)*16/10;
01998 lowlightVal = 100 + (2*contrast_+4)*10;
01999
02000 QColor disfg = foreground;
02001
02002 int h, s, v;
02003 disfg.hsv( &h, &s, &v );
02004 if (v > 128)
02005
02006 disfg = disfg.dark(lowlightVal);
02007 else if (disfg != black)
02008
02009 disfg = disfg.light(highlightVal);
02010 else
02011
02012 disfg = Qt::darkGray;
02013
02014
02015 QColorGroup disabledgrp(disfg, background,
02016 background.light(highlightVal),
02017 background.dark(lowlightVal),
02018 background.dark(120),
02019 background.dark(120), base);
02020
02021 QColorGroup colgrp(foreground, background, background.light(highlightVal),
02022 background.dark(lowlightVal),
02023 background.dark(120),
02024 baseText, base);
02025
02026 int inlowlightVal = lowlightVal-25;
02027 if(inlowlightVal < 120)
02028 inlowlightVal = 120;
02029
02030 colgrp.setColor(QColorGroup::Highlight, highlight);
02031 colgrp.setColor(QColorGroup::HighlightedText, highlightedText);
02032 colgrp.setColor(QColorGroup::Button, button);
02033 colgrp.setColor(QColorGroup::ButtonText, buttonText);
02034 colgrp.setColor(QColorGroup::Midlight, background.light(110));
02035 colgrp.setColor(QColorGroup::Link, link);
02036 colgrp.setColor(QColorGroup::LinkVisited, visitedLink);
02037
02038 disabledgrp.setColor(QColorGroup::Button, button);
02039
02040 QColor disbtntext = buttonText;
02041 disbtntext.hsv( &h, &s, &v );
02042 if (v > 128)
02043
02044 disbtntext = disbtntext.dark(lowlightVal);
02045 else if (disbtntext != black)
02046
02047 disbtntext = disbtntext.light(highlightVal);
02048 else
02049
02050 disbtntext = Qt::darkGray;
02051
02052 disabledgrp.setColor(QColorGroup::ButtonText, disbtntext);
02053 disabledgrp.setColor(QColorGroup::Midlight, background.light(110));
02054 disabledgrp.setColor(QColorGroup::Highlight, highlight.dark(120));
02055 disabledgrp.setColor(QColorGroup::Link, link);
02056 disabledgrp.setColor(QColorGroup::LinkVisited, visitedLink);
02057
02058 return QPalette(colgrp, disabledgrp, colgrp);
02059 }
02060
02061
02062 void KApplication::kdisplaySetPalette()
02063 {
02064 #ifdef Q_WS_MACX
02065
02066 {
02067 KConfig *config = KGlobal::config();
02068 KConfigGroupSaver saver( config, "General" );
02069 bool do_not_set_palette = FALSE;
02070 if(config->readBoolEntry("nopaletteChange", &do_not_set_palette))
02071 return;
02072 }
02073 #endif
02074 QApplication::setPalette( createApplicationPalette(), true);
02075 emit kdisplayPaletteChanged();
02076 emit appearanceChanged();
02077 }
02078
02079
02080 void KApplication::kdisplaySetFont()
02081 {
02082 QApplication::setFont(KGlobalSettings::generalFont(), true);
02083 QApplication::setFont(KGlobalSettings::menuFont(), true, "QMenuBar");
02084 QApplication::setFont(KGlobalSettings::menuFont(), true, "QPopupMenu");
02085 QApplication::setFont(KGlobalSettings::menuFont(), true, "KPopupTitle");
02086
02087
02088 QStyleSheet* sheet = QStyleSheet::defaultSheet();
02089 sheet->item ("pre")->setFontFamily (KGlobalSettings::fixedFont().family());
02090 sheet->item ("code")->setFontFamily (KGlobalSettings::fixedFont().family());
02091 sheet->item ("tt")->setFontFamily (KGlobalSettings::fixedFont().family());
02092
02093 emit kdisplayFontChanged();
02094 emit appearanceChanged();
02095 }
02096
02097
02098 void KApplication::kdisplaySetStyle()
02099 {
02100 if (useStyles)
02101 {
02102 applyGUIStyle();
02103 emit kdisplayStyleChanged();
02104 emit appearanceChanged();
02105 }
02106 }
02107
02108
02109 void KApplication::propagateSettings(SettingsCategory arg)
02110 {
02111 KConfigBase* config = KGlobal::config();
02112 KConfigGroupSaver saver( config, "KDE" );
02113
02114 int num = config->readNumEntry("CursorBlinkRate", QApplication::cursorFlashTime());
02115 if ((num != 0) && (num < 200))
02116 num = 200;
02117 if (num > 2000)
02118 num = 2000;
02119 QApplication::setCursorFlashTime(num);
02120 num = config->readNumEntry("DoubleClickInterval", QApplication::doubleClickInterval());
02121 QApplication::setDoubleClickInterval(num);
02122 num = config->readNumEntry("StartDragTime", QApplication::startDragTime());
02123 QApplication::setStartDragTime(num);
02124 num = config->readNumEntry("StartDragDist", QApplication::startDragDistance());
02125 QApplication::setStartDragDistance(num);
02126 num = config->readNumEntry("WheelScrollLines", QApplication::wheelScrollLines());
02127 QApplication::setWheelScrollLines(num);
02128
02129 bool b = config->readBoolEntry("EffectAnimateMenu", false);
02130 QApplication::setEffectEnabled( Qt::UI_AnimateMenu, b);
02131 b = config->readBoolEntry("EffectFadeMenu", false);
02132 QApplication::setEffectEnabled( Qt::UI_FadeMenu, b);
02133 b = config->readBoolEntry("EffectAnimateCombo", false);
02134 QApplication::setEffectEnabled( Qt::UI_AnimateCombo, b);
02135 b = config->readBoolEntry("EffectAnimateTooltip", false);
02136 QApplication::setEffectEnabled( Qt::UI_AnimateTooltip, b);
02137 b = config->readBoolEntry("EffectFadeTooltip", false);
02138 QApplication::setEffectEnabled( Qt::UI_FadeTooltip, b);
02139 b = !config->readBoolEntry("EffectNoTooltip", false);
02140 QToolTip::setGloballyEnabled( b );
02141
02142 emit settingsChanged(arg);
02143 }
02144
02145 void KApplication::installKDEPropertyMap()
02146 {
02147 #ifndef QT_NO_SQL
02148 static bool installed = false;
02149 if (installed) return;
02150 installed = true;
02157
02158 QSqlPropertyMap *kdeMap = new QSqlPropertyMap;
02159 kdeMap->insert( "KColorButton", "color" );
02160 kdeMap->insert( "KComboBox", "currentItem" );
02161 kdeMap->insert( "KDatePicker", "date" );
02162 kdeMap->insert( "KDateWidget", "date" );
02163 kdeMap->insert( "KDateTimeWidget", "dateTime" );
02164 kdeMap->insert( "KEditListBox", "items" );
02165 kdeMap->insert( "KFontCombo", "family" );
02166 kdeMap->insert( "KFontRequester", "font" );
02167 kdeMap->insert( "KFontChooser", "font" );
02168 kdeMap->insert( "KHistoryCombo", "currentItem" );
02169 kdeMap->insert( "KListBox", "currentItem" );
02170 kdeMap->insert( "KLineEdit", "text" );
02171 kdeMap->insert( "KRestrictedLine", "text" );
02172 kdeMap->insert( "KSqueezedTextLabel", "text" );
02173 kdeMap->insert( "KTextBrowser", "source" );
02174 kdeMap->insert( "KTextEdit", "text" );
02175 kdeMap->insert( "KURLRequester", "url" );
02176 kdeMap->insert( "KPasswordEdit", "password" );
02177 kdeMap->insert( "KIntNumInput", "value" );
02178 kdeMap->insert( "KIntSpinBox", "value" );
02179 kdeMap->insert( "KDoubleNumInput", "value" );
02180 #if QT_VERSION < 0x030200
02181 kdeMap->insert( "QRadioButton", "checked" );
02182 #endif
02183
02184
02185 kdeMap->insert( "QGroupBox", "checked" );
02186 kdeMap->insert( "QTabWidget", "currentPage" );
02187
02188 QSqlPropertyMap::installDefaultMap( kdeMap );
02189 #endif
02190 }
02191
02192 void KApplication::invokeHelp( const QString& anchor,
02193 const QString& _appname) const
02194 {
02195 return invokeHelp( anchor, _appname, "" );
02196 }
02197
02198 #ifndef Q_WS_WIN
02199
02200
02201 void KApplication::invokeHelp( const QString& anchor,
02202 const QString& _appname,
02203 const QCString& startup_id ) const
02204 {
02205 QString url;
02206 QString appname;
02207 if (_appname.isEmpty())
02208 appname = name();
02209 else
02210 appname = _appname;
02211
02212 if (!anchor.isEmpty())
02213 url = QString("help:/%1?anchor=%2").arg(appname).arg(anchor);
02214 else
02215 url = QString("help:/%1/index.html").arg(appname);
02216
02217 QString error;
02218 if ( !dcopClient()->isApplicationRegistered("khelpcenter") )
02219 {
02220 if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, startup_id, false))
02221 {
02222 if (Tty != kapp->type())
02223 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Help Center"),
02224 i18n("Could not launch the KDE Help Center:\n\n%1").arg(error), i18n("&OK"));
02225 else
02226 kdWarning() << "Could not launch help:\n" << error << endl;
02227 return;
02228 }
02229 }
02230 else
02231 DCOPRef( "khelpcenter", "KHelpCenterIface" ).send( "openUrl", url, startup_id );
02232 }
02233 #endif
02234
02235 void KApplication::invokeHTMLHelp( const QString& _filename, const QString& topic ) const
02236 {
02237 kdWarning() << "invoking HTML help is deprecated! use docbook and invokeHelp!\n";
02238
02239 QString filename;
02240
02241 if( _filename.isEmpty() )
02242 filename = QString(name()) + "/index.html";
02243 else
02244 filename = _filename;
02245
02246 QString url;
02247 if (!topic.isEmpty())
02248 url = QString("help:/%1#%2").arg(filename).arg(topic);
02249 else
02250 url = QString("help:/%1").arg(filename);
02251
02252 QString error;
02253 if ( !dcopClient()->isApplicationRegistered("khelpcenter") )
02254 {
02255 if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, "", false))
02256 {
02257 if (Tty != kapp->type())
02258 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Help Center"),
02259 i18n("Could not launch the KDE Help Center:\n\n%1").arg(error), i18n("&OK"));
02260 else
02261 kdWarning() << "Could not launch help:\n" << error << endl;
02262 return;
02263 }
02264 }
02265 else
02266 DCOPRef( "khelpcenter", "KHelpCenterIface" ).send( "openUrl", url );
02267 }
02268
02269
02270 void KApplication::invokeMailer(const QString &address, const QString &subject)
02271 {
02272 return invokeMailer(address,subject,"");
02273 }
02274
02275 void KApplication::invokeMailer(const QString &address, const QString &subject, const QCString& startup_id)
02276 {
02277 invokeMailer(address, QString::null, QString::null, subject, QString::null, QString::null,
02278 QStringList(), startup_id );
02279 }
02280
02281 void KApplication::invokeMailer(const KURL &mailtoURL)
02282 {
02283 return invokeMailer( mailtoURL, "" );
02284 }
02285
02286 void KApplication::invokeMailer(const KURL &mailtoURL, const QCString& startup_id )
02287 {
02288 return invokeMailer( mailtoURL, startup_id, false);
02289 }
02290
02291 void KApplication::invokeMailer(const KURL &mailtoURL, const QCString& startup_id, bool allowAttachments )
02292 {
02293 QString address = KURL::decode_string(mailtoURL.path()), subject, cc, bcc, body;
02294 QStringList queries = QStringList::split('&', mailtoURL.query().mid(1));
02295 QStringList attachURLs;
02296 for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
02297 {
02298 QString q = (*it).lower();
02299 if (q.startsWith("subject="))
02300 subject = KURL::decode_string((*it).mid(8));
02301 else
02302 if (q.startsWith("cc="))
02303 cc = cc.isEmpty()? KURL::decode_string((*it).mid(3)): cc + ',' + KURL::decode_string((*it).mid(3));
02304 else
02305 if (q.startsWith("bcc="))
02306 bcc = bcc.isEmpty()? KURL::decode_string((*it).mid(4)): bcc + ',' + KURL::decode_string((*it).mid(4));
02307 else
02308 if (q.startsWith("body="))
02309 body = KURL::decode_string((*it).mid(5));
02310 else
02311 if (allowAttachments && q.startsWith("attach="))
02312 attachURLs.push_back(KURL::decode_string((*it).mid(7)));
02313 else
02314 if (allowAttachments && q.startsWith("attachment="))
02315 attachURLs.push_back(KURL::decode_string((*it).mid(11)));
02316 else
02317 if (q.startsWith("to="))
02318 address = address.isEmpty()? KURL::decode_string((*it).mid(3)): address + ',' + KURL::decode_string((*it).mid(3));
02319 }
02320
02321 invokeMailer( address, cc, bcc, subject, body, QString::null, attachURLs, startup_id );
02322 }
02323
02324 void KApplication::invokeMailer(const QString &to, const QString &cc, const QString &bcc,
02325 const QString &subject, const QString &body,
02326 const QString & messageFile, const QStringList &attachURLs)
02327 {
02328 return invokeMailer(to,cc,bcc,subject,body,messageFile,attachURLs,"");
02329 }
02330
02331 #ifndef Q_WS_WIN
02332
02333
02334
02335 static QStringList splitEmailAddressList( const QString & aStr )
02336 {
02337
02338
02339
02340
02341
02342
02343
02344
02345
02346 QStringList list;
02347
02348 if (aStr.isEmpty())
02349 return list;
02350
02351 QString addr;
02352 uint addrstart = 0;
02353 int commentlevel = 0;
02354 bool insidequote = false;
02355
02356 for (uint index=0; index<aStr.length(); index++) {
02357
02358
02359 switch (aStr[index].latin1()) {
02360 case '"' :
02361 if (commentlevel == 0)
02362 insidequote = !insidequote;
02363 break;
02364 case '(' :
02365 if (!insidequote)
02366 commentlevel++;
02367 break;
02368 case ')' :
02369 if (!insidequote) {
02370 if (commentlevel > 0)
02371 commentlevel--;
02372 else {
02373
02374
02375 return list;
02376 }
02377 }
02378 break;
02379 case '\\' :
02380 index++;
02381 break;
02382 case ',' :
02383 if (!insidequote && (commentlevel == 0)) {
02384 addr = aStr.mid(addrstart, index-addrstart);
02385 if (!addr.isEmpty())
02386 list += addr.simplifyWhiteSpace();
02387 addrstart = index+1;
02388 }
02389 break;
02390 }
02391 }
02392
02393 if (!insidequote && (commentlevel == 0)) {
02394 addr = aStr.mid(addrstart, aStr.length()-addrstart);
02395 if (!addr.isEmpty())
02396 list += addr.simplifyWhiteSpace();
02397 }
02398
02399
02400
02401
02402
02403 return list;
02404 }
02405
02406 void KApplication::invokeMailer(const QString &_to, const QString &_cc, const QString &_bcc,
02407 const QString &subject, const QString &body,
02408 const QString & , const QStringList &attachURLs,
02409 const QCString& startup_id )
02410 {
02411 KConfig config("emaildefaults");
02412
02413 config.setGroup("Defaults");
02414 QString group = config.readEntry("Profile","Default");
02415
02416 config.setGroup( QString("PROFILE_%1").arg(group) );
02417 QString command = config.readPathEntry("EmailClient");
02418
02419 QString to, cc, bcc;
02420 if (command.isEmpty() || command == QString::fromLatin1("kmail")
02421 || command.endsWith("/kmail"))
02422 {
02423 command = QString::fromLatin1("kmail --composer -s %s -c %c -b %b --body %B --attach %A -- %t");
02424 if ( !_to.isEmpty() )
02425 {
02426
02427
02428 to = QString( "=?utf8?b?%1?=" )
02429 .arg( KCodecs::base64Encode( _to.utf8(), false ) );
02430 }
02431 if ( !_cc.isEmpty() )
02432 cc = QString( "=?utf8?b?%1?=" )
02433 .arg( KCodecs::base64Encode( _cc.utf8(), false ) );
02434 if ( !_bcc.isEmpty() )
02435 bcc = QString( "=?utf8?b?%1?=" )
02436 .arg( KCodecs::base64Encode( _bcc.utf8(), false ) );
02437 } else {
02438 to = _to;
02439 cc = _cc;
02440 bcc = _bcc;
02441 }
02442
02443 if (config.readBoolEntry("TerminalClient", false))
02444 {
02445 KConfigGroup confGroup( KGlobal::config(), "General" );
02446 QString preferredTerminal = confGroup.readPathEntry("TerminalApplication", "konsole");
02447 command = preferredTerminal + " -e " + command;
02448 }
02449
02450 QStringList cmdTokens = KShell::splitArgs(command);
02451 QString cmd = cmdTokens[0];
02452 cmdTokens.remove(cmdTokens.begin());
02453
02454 KURL url;
02455 QStringList qry;
02456 if (!to.isEmpty())
02457 {
02458 QStringList tos = splitEmailAddressList( to );
02459 url.setPath( tos.first() );
02460 tos.remove( tos.begin() );
02461 for (QStringList::ConstIterator it = tos.begin(); it != tos.end(); ++it)
02462 qry.append( "to=" + KURL::encode_string( *it ) );
02463 }
02464 const QStringList ccs = splitEmailAddressList( cc );
02465 for (QStringList::ConstIterator it = ccs.begin(); it != ccs.end(); ++it)
02466 qry.append( "cc=" + KURL::encode_string( *it ) );
02467 const QStringList bccs = splitEmailAddressList( bcc );
02468 for (QStringList::ConstIterator it = bccs.begin(); it != bccs.end(); ++it)
02469 qry.append( "bcc=" + KURL::encode_string( *it ) );
02470 for (QStringList::ConstIterator it = attachURLs.begin(); it != attachURLs.end(); ++it)
02471 qry.append( "attach=" + KURL::encode_string( *it ) );
02472 if (!subject.isEmpty())
02473 qry.append( "subject=" + KURL::encode_string( subject ) );
02474 if (!body.isEmpty())
02475 qry.append( "body=" + KURL::encode_string( body ) );
02476 url.setQuery( qry.join( "&" ) );
02477 if ( ! (to.isEmpty() && qry.isEmpty()) )
02478 url.setProtocol("mailto");
02479
02480 QMap<QChar, QString> keyMap;
02481 keyMap.insert('t', to);
02482 keyMap.insert('s', subject);
02483 keyMap.insert('c', cc);
02484 keyMap.insert('b', bcc);
02485 keyMap.insert('B', body);
02486 keyMap.insert('u', url.url());
02487
02488 for (QStringList::Iterator it = cmdTokens.begin(); it != cmdTokens.end(); )
02489 {
02490 if (*it == "%A")
02491 {
02492 if (it == cmdTokens.begin())
02493 continue;
02494 QStringList::ConstIterator urlit = attachURLs.begin();
02495 QStringList::ConstIterator urlend = attachURLs.end();
02496 if ( urlit != urlend )
02497 {
02498 QStringList::Iterator previt = it;
02499 --previt;
02500 *it = *urlit;
02501 ++it;
02502 while ( ++urlit != urlend )
02503 {
02504 cmdTokens.insert( it, *previt );
02505 cmdTokens.insert( it, *urlit );
02506 }
02507 } else {
02508 --it;
02509 it = cmdTokens.remove( cmdTokens.remove( it ) );
02510 }
02511 } else {
02512 *it = KMacroExpander::expandMacros(*it, keyMap);
02513 ++it;
02514 }
02515 }
02516
02517 QString error;
02518
02519
02520 if (kdeinitExec(cmd, cmdTokens, &error, NULL, startup_id ))
02521 if (Tty != kapp->type())
02522 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Mail Client"),
02523 i18n("Could not launch the mail client:\n\n%1").arg(error), i18n("&OK"));
02524 else
02525 kdWarning() << "Could not launch mail client:\n" << error << endl;
02526 }
02527 #endif
02528
02529 void KApplication::invokeBrowser( const QString &url )
02530 {
02531 return invokeBrowser( url, "" );
02532 }
02533
02534 #ifndef Q_WS_WIN
02535
02536
02537 void KApplication::invokeBrowser( const QString &url, const QCString& startup_id )
02538 {
02539 QString error;
02540
02541 if (startServiceByDesktopName("kfmclient", url, &error, 0, 0, startup_id, false))
02542 {
02543 if (Tty != kapp->type())
02544 QMessageBox::critical(kapp->mainWidget(), i18n("Could not Launch Browser"),
02545 i18n("Could not launch the browser:\n\n%1").arg(error), i18n("&OK"));
02546 else
02547 kdWarning() << "Could not launch browser:\n" << error << endl;
02548 return;
02549 }
02550 }
02551 #endif
02552
02553 void KApplication::cut()
02554 {
02555 invokeEditSlot( SLOT( cut() ) );
02556 }
02557
02558 void KApplication::copy()
02559 {
02560 invokeEditSlot( SLOT( copy() ) );
02561 }
02562
02563 void KApplication::paste()
02564 {
02565 invokeEditSlot( SLOT( paste() ) );
02566 }
02567
02568 void KApplication::clear()
02569 {
02570 invokeEditSlot( SLOT( clear() ) );
02571 }
02572
02573 void KApplication::selectAll()
02574 {
02575 invokeEditSlot( SLOT( selectAll() ) );
02576 }
02577
02578 QCString
02579 KApplication::launcher()
02580 {
02581 return "klauncher";
02582 }
02583
02584 static int
02585 startServiceInternal( const QCString &function,
02586 const QString& _name, const QStringList &URLs,
02587 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02588 {
02589 struct serviceResult
02590 {
02591 int result;
02592 QCString dcopName;
02593 QString error;
02594 pid_t pid;
02595 };
02596
02597
02598 DCOPClient *dcopClient;
02599 if (kapp)
02600 dcopClient = kapp->dcopClient();
02601 else
02602 dcopClient = new DCOPClient;
02603
02604 if (!dcopClient->isAttached())
02605 {
02606 if (!dcopClient->attach())
02607 {
02608 if (error)
02609 *error = i18n("Could not register with DCOP.\n");
02610 return -1;
02611 }
02612 }
02613 QByteArray params;
02614 QDataStream stream(params, IO_WriteOnly);
02615 stream << _name << URLs;
02616 QCString replyType;
02617 QByteArray replyData;
02618 QCString _launcher = KApplication::launcher();
02619 QValueList<QCString> envs;
02620 #ifdef Q_WS_X11
02621 if (qt_xdisplay()) {
02622 QCString dpystring(XDisplayString(qt_xdisplay()));
02623 envs.append( QCString("DISPLAY=") + dpystring );
02624 } else if( getenv( "DISPLAY" )) {
02625 QCString dpystring( getenv( "DISPLAY" ));
02626 envs.append( QCString("DISPLAY=") + dpystring );
02627 }
02628 #endif
02629 stream << envs;
02630 #if defined Q_WS_X11
02631
02632 stream << ( startup_id.isEmpty() ? KStartupInfo::createNewStartupId() : startup_id );
02633 #endif
02634 if( function.left( 12 ) != "kdeinit_exec" )
02635 stream << noWait;
02636
02637 if (!dcopClient->call(_launcher, _launcher,
02638 function, params, replyType, replyData))
02639 {
02640 if (error)
02641 *error = i18n("KLauncher could not be reached via DCOP.\n");
02642 if (!kapp)
02643 delete dcopClient;
02644 return -1;
02645 }
02646 if (!kapp)
02647 delete dcopClient;
02648
02649 if (noWait)
02650 return 0;
02651
02652 QDataStream stream2(replyData, IO_ReadOnly);
02653 serviceResult result;
02654 stream2 >> result.result >> result.dcopName >> result.error >> result.pid;
02655 if (dcopService)
02656 *dcopService = result.dcopName;
02657 if (error)
02658 *error = result.error;
02659 if (pid)
02660 *pid = result.pid;
02661 return result.result;
02662 }
02663
02664 int
02665 KApplication::startServiceByName( const QString& _name, const QString &URL,
02666 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02667 {
02668 QStringList URLs;
02669 if (!URL.isEmpty())
02670 URLs.append(URL);
02671 return startServiceInternal(
02672 "start_service_by_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02673 _name, URLs, error, dcopService, pid, startup_id, noWait);
02674 }
02675
02676 int
02677 KApplication::startServiceByName( const QString& _name, const QStringList &URLs,
02678 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02679 {
02680 return startServiceInternal(
02681 "start_service_by_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02682 _name, URLs, error, dcopService, pid, startup_id, noWait);
02683 }
02684
02685 int
02686 KApplication::startServiceByDesktopPath( const QString& _name, const QString &URL,
02687 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02688 {
02689 QStringList URLs;
02690 if (!URL.isEmpty())
02691 URLs.append(URL);
02692 return startServiceInternal(
02693 "start_service_by_desktop_path(QString,QStringList,QValueList<QCString>,QCString,bool)",
02694 _name, URLs, error, dcopService, pid, startup_id, noWait);
02695 }
02696
02697 int
02698 KApplication::startServiceByDesktopPath( const QString& _name, const QStringList &URLs,
02699 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02700 {
02701 return startServiceInternal(
02702 "start_service_by_desktop_path(QString,QStringList,QValueList<QCString>,QCString,bool)",
02703 _name, URLs, error, dcopService, pid, startup_id, noWait);
02704 }
02705
02706 int
02707 KApplication::startServiceByDesktopName( const QString& _name, const QString &URL,
02708 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02709 {
02710 QStringList URLs;
02711 if (!URL.isEmpty())
02712 URLs.append(URL);
02713 return startServiceInternal(
02714 "start_service_by_desktop_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02715 _name, URLs, error, dcopService, pid, startup_id, noWait);
02716 }
02717
02718 int
02719 KApplication::startServiceByDesktopName( const QString& _name, const QStringList &URLs,
02720 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02721 {
02722 return startServiceInternal(
02723 "start_service_by_desktop_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02724 _name, URLs, error, dcopService, pid, startup_id, noWait);
02725 }
02726
02727 int
02728 KApplication::kdeinitExec( const QString& name, const QStringList &args,
02729 QString *error, int *pid )
02730 {
02731 return kdeinitExec( name, args, error, pid, "" );
02732 }
02733
02734 int
02735 KApplication::kdeinitExec( const QString& name, const QStringList &args,
02736 QString *error, int *pid, const QCString& startup_id )
02737 {
02738 return startServiceInternal("kdeinit_exec(QString,QStringList,QValueList<QCString>,QCString)",
02739 name, args, error, 0, pid, startup_id, false);
02740 }
02741
02742 int
02743 KApplication::kdeinitExecWait( const QString& name, const QStringList &args,
02744 QString *error, int *pid )
02745 {
02746 return kdeinitExecWait( name, args, error, pid, "" );
02747 }
02748
02749 int
02750 KApplication::kdeinitExecWait( const QString& name, const QStringList &args,
02751 QString *error, int *pid, const QCString& startup_id )
02752 {
02753 return startServiceInternal("kdeinit_exec_wait(QString,QStringList,QValueList<QCString>,QCString)",
02754 name, args, error, 0, pid, startup_id, false);
02755 }
02756
02757 QString KApplication::tempSaveName( const QString& pFilename ) const
02758 {
02759 QString aFilename;
02760
02761 if( QDir::isRelativePath(pFilename) )
02762 {
02763 kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
02764 aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
02765 }
02766 else
02767 aFilename = pFilename;
02768
02769 QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
02770 if( !aAutosaveDir.exists() )
02771 {
02772 if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
02773 {
02774
02775 aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
02776 }
02777 }
02778
02779 aFilename.replace( "/", "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
02780
02781 return aFilename;
02782 }
02783
02784
02785 QString KApplication::checkRecoverFile( const QString& pFilename,
02786 bool& bRecover ) const
02787 {
02788 QString aFilename;
02789
02790 if( QDir::isRelativePath(pFilename) )
02791 {
02792 kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
02793 aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
02794 }
02795 else
02796 aFilename = pFilename;
02797
02798 QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
02799 if( !aAutosaveDir.exists() )
02800 {
02801 if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
02802 {
02803
02804 aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
02805 }
02806 }
02807
02808 aFilename.replace( "/", "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
02809
02810 if( QFile( aFilename ).exists() )
02811 {
02812 bRecover = true;
02813 return aFilename;
02814 }
02815 else
02816 {
02817 bRecover = false;
02818 return pFilename;
02819 }
02820 }
02821
02822
02823 bool checkAccess(const QString& pathname, int mode)
02824 {
02825 int accessOK = access( QFile::encodeName(pathname), mode );
02826 if ( accessOK == 0 )
02827 return true;
02828
02829
02830
02831
02832 if ( (mode & W_OK) == 0 )
02833 return false;
02834
02835
02836 if (!access( QFile::encodeName(pathname), F_OK))
02837 return false;
02838
02839
02840 QString dirName(pathname);
02841 int pos = dirName.findRev('/');
02842 if ( pos == -1 )
02843 return false;
02844 else if ( pos == 0 )
02845 pos = 1;
02846
02847 dirName.truncate(pos);
02848
02849 accessOK = access( QFile::encodeName(dirName), W_OK );
02850
02851 if ( accessOK == 0 )
02852 return true;
02853 else
02854 return false;
02855 }
02856
02857 void KApplication::setTopWidget( QWidget *topWidget )
02858 {
02859 if( !topWidget )
02860 return;
02861
02862
02863 if ( !topWidget->inherits("KMainWindow") ) {
02864 topWidget->setCaption( caption() );
02865 }
02866
02867
02868 topWidget->setIcon( icon() );
02869 #if defined Q_WS_X11
02870
02871 KWin::setIcons(topWidget->winId(), icon(), miniIcon() );
02872
02873
02874 KStartupInfo::setWindowStartupId( topWidget->winId(), startupId());
02875 #endif
02876 }
02877
02878 QCString KApplication::startupId() const
02879 {
02880 return d->startup_id;
02881 }
02882
02883 void KApplication::setStartupId( const QCString& startup_id )
02884 {
02885 if( startup_id.isEmpty())
02886 d->startup_id = "0";
02887 else
02888 {
02889 d->startup_id = startup_id;
02890 #if defined Q_WS_X11
02891 KStartupInfoId id;
02892 id.initId( startup_id );
02893 long timestamp = id.timestamp();
02894 if( timestamp != 0 )
02895 updateUserTimestamp( timestamp );
02896 #endif
02897 }
02898 }
02899
02900
02901
02902 void KApplication::read_app_startup_id()
02903 {
02904 #if defined Q_WS_X11
02905 KStartupInfoId id = KStartupInfo::currentStartupIdEnv();
02906 KStartupInfo::resetStartupEnv();
02907 d->startup_id = id.id();
02908 #endif
02909 }
02910
02911 int KApplication::random()
02912 {
02913 static bool init = false;
02914 if (!init)
02915 {
02916 unsigned int seed;
02917 init = true;
02918 int fd = open("/dev/urandom", O_RDONLY);
02919 if (fd < 0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed))
02920 {
02921
02922 srand(getpid());
02923 seed = rand()+time(0);
02924 }
02925 if (fd >= 0) close(fd);
02926 srand(seed);
02927 }
02928 return rand();
02929 }
02930
02931 QString KApplication::randomString(int length)
02932 {
02933 if (length <=0 ) return QString::null;
02934
02935 QString str; str.setLength( length );
02936 int i = 0;
02937 while (length--)
02938 {
02939 int r=random() % 62;
02940 r+=48;
02941 if (r>57) r+=7;
02942 if (r>90) r+=6;
02943 str[i++] = char(r);
02944
02945 }
02946 return str;
02947 }
02948
02949 bool KApplication::authorize(const QString &genericAction)
02950 {
02951 if (!d->actionRestrictions)
02952 return true;
02953
02954 KConfig *config = KGlobal::config();
02955 KConfigGroupSaver saver( config, "KDE Action Restrictions" );
02956 return config->readBoolEntry(genericAction, true);
02957 }
02958
02959 bool KApplication::authorizeKAction(const char *action)
02960 {
02961 if (!d->actionRestrictions || !action)
02962 return true;
02963
02964 static const QString &action_prefix = KGlobal::staticQString( "action/" );
02965
02966 return authorize(action_prefix + action);
02967 }
02968
02969 bool KApplication::authorizeControlModule(const QString &menuId)
02970 {
02971 if (menuId.isEmpty() || kde_kiosk_exception)
02972 return true;
02973 KConfig *config = KGlobal::config();
02974 KConfigGroupSaver saver( config, "KDE Control Module Restrictions" );
02975 return config->readBoolEntry(menuId, true);
02976 }
02977
02978 QStringList KApplication::authorizeControlModules(const QStringList &menuIds)
02979 {
02980 KConfig *config = KGlobal::config();
02981 KConfigGroupSaver saver( config, "KDE Control Module Restrictions" );
02982 QStringList result;
02983 for(QStringList::ConstIterator it = menuIds.begin();
02984 it != menuIds.end(); ++it)
02985 {
02986 if (config->readBoolEntry(*it, true))
02987 result.append(*it);
02988 }
02989 return result;
02990 }
02991
02992 void KApplication::initUrlActionRestrictions()
02993 {
02994 d->urlActionRestrictions.setAutoDelete(true);
02995 d->urlActionRestrictions.clear();
02996 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02997 ("open", QString::null, QString::null, QString::null, QString::null, QString::null, QString::null, true));
02998 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02999 ("list", QString::null, QString::null, QString::null, QString::null, QString::null, QString::null, true));
03000
03001
03002
03003
03004
03005 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03006 ("link", QString::null, QString::null, QString::null, ":internet", QString::null, QString::null, true));
03007 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03008 ("redirect", QString::null, QString::null, QString::null, ":internet", QString::null, QString::null, true));
03009
03010
03011
03012 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03013 ("redirect", QString::null, QString::null, QString::null, "file", QString::null, QString::null, true));
03014 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03015 ("redirect", ":internet", QString::null, QString::null, "file", QString::null, QString::null, false));
03016
03017
03018 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03019 ("redirect", ":local", QString::null, QString::null, QString::null, QString::null, QString::null, true));
03020
03021
03022 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03023 ("redirect", QString::null, QString::null, QString::null, "about", QString::null, QString::null, true));
03024
03025
03026 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
03027 ("redirect", QString::null, QString::null, QString::null, "=", QString::null, QString::null, true));
03028
03029 KConfig *config = KGlobal::config();
03030 KConfigGroupSaver saver( config, "KDE URL Restrictions" );
03031 int count = config->readNumEntry("rule_count");
03032 QString keyFormat = QString("rule_%1");
03033 for(int i = 1; i <= count; i++)
03034 {
03035 QString key = keyFormat.arg(i);
03036 QStringList rule = config->readListEntry(key);
03037 if (rule.count() != 8)
03038 continue;
03039 QString action = rule[0];
03040 QString refProt = rule[1];
03041 QString refHost = rule[2];
03042 QString refPath = rule[3];
03043 QString urlProt = rule[4];
03044 QString urlHost = rule[5];
03045 QString urlPath = rule[6];
03046 QString strEnabled = rule[7].lower();
03047
03048 bool bEnabled = (strEnabled == "true");
03049
03050 if (refPath.startsWith("$HOME"))
03051 refPath.replace(0, 5, QDir::homeDirPath());
03052 else if (refPath.startsWith("~"))
03053 refPath.replace(0, 1, QDir::homeDirPath());
03054 if (urlPath.startsWith("$HOME"))
03055 urlPath.replace(0, 5, QDir::homeDirPath());
03056 else if (urlPath.startsWith("~"))
03057 urlPath.replace(0, 1, QDir::homeDirPath());
03058
03059 if (refPath.startsWith("$TMP"))
03060 refPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
03061 if (urlPath.startsWith("$TMP"))
03062 urlPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
03063
03064 d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
03065 ( action, refProt, refHost, refPath, urlProt, urlHost, urlPath, bEnabled));
03066 }
03067 }
03068
03069 void KApplication::allowURLAction(const QString &action, const KURL &_baseURL, const KURL &_destURL)
03070 {
03071 if (authorizeURLAction(action, _baseURL, _destURL))
03072 return;
03073
03074 d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
03075 ( action, _baseURL.protocol(), _baseURL.host(), _baseURL.path(-1),
03076 _destURL.protocol(), _destURL.host(), _destURL.path(-1), true));
03077 }
03078
03079 bool KApplication::authorizeURLAction(const QString &action, const KURL &_baseURL, const KURL &_destURL)
03080 {
03081 if (_destURL.isEmpty())
03082 return true;
03083
03084 bool result = false;
03085 if (d->urlActionRestrictions.isEmpty())
03086 initUrlActionRestrictions();
03087
03088 KURL baseURL(_baseURL);
03089 baseURL.setPath(QDir::cleanDirPath(baseURL.path()));
03090 QString baseClass = KProtocolInfo::protocolClass(baseURL.protocol());
03091 KURL destURL(_destURL);
03092 destURL.setPath(QDir::cleanDirPath(destURL.path()));
03093 QString destClass = KProtocolInfo::protocolClass(destURL.protocol());
03094
03095 for(KApplicationPrivate::URLActionRule *rule = d->urlActionRestrictions.first();
03096 rule; rule = d->urlActionRestrictions.next())
03097 {
03098 if ((result != rule->permission) &&
03099 (action == rule->action) &&
03100 rule->baseMatch(baseURL, baseClass) &&
03101 rule->destMatch(destURL, destClass, baseURL, baseClass))
03102 {
03103 result = rule->permission;
03104 }
03105 }
03106 return result;
03107 }
03108
03109
03110 uint KApplication::keyboardModifiers()
03111 {
03112 #ifdef Q_WS_X11
03113 Window root;
03114 Window child;
03115 int root_x, root_y, win_x, win_y;
03116 uint keybstate;
03117 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03118 &root_x, &root_y, &win_x, &win_y, &keybstate );
03119 return keybstate & 0x00ff;
03120 #elif defined W_WS_MACX
03121 return GetCurrentEventKeyModifiers() & 0x00ff;
03122 #else
03123
03124 return 0;
03125 #endif
03126 }
03127
03128 uint KApplication::mouseState()
03129 {
03130 uint mousestate;
03131 #ifdef Q_WS_X11
03132 Window root;
03133 Window child;
03134 int root_x, root_y, win_x, win_y;
03135 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03136 &root_x, &root_y, &win_x, &win_y, &mousestate );
03137 #elif defined(Q_WS_WIN)
03138 const bool mousebtn_swapped = GetSystemMetrics(SM_SWAPBUTTON);
03139 if (GetAsyncKeyState(VK_LBUTTON))
03140 mousestate |= (mousebtn_swapped ? Button3Mask : Button1Mask);
03141 if (GetAsyncKeyState(VK_MBUTTON))
03142 mousestate |= Button2Mask;
03143 if (GetAsyncKeyState(VK_RBUTTON))
03144 mousestate |= (mousebtn_swapped ? Button1Mask : Button3Mask);
03145 #elif defined(Q_WS_MACX)
03146 mousestate = GetCurrentEventButtonState();
03147 #else
03148
03149 #endif
03150 return mousestate & 0xff00;
03151 }
03152
03153 Qt::ButtonState KApplication::keyboardMouseState()
03154 {
03155 int ret = 0;
03156 #ifdef Q_WS_X11
03157 Window root;
03158 Window child;
03159 int root_x, root_y, win_x, win_y;
03160 uint state;
03161 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
03162 &root_x, &root_y, &win_x, &win_y, &state );
03163
03164 if( state & Button1Mask )
03165 ret |= LeftButton;
03166 if( state & Button2Mask )
03167 ret |= MidButton;
03168 if( state & Button3Mask )
03169 ret |= RightButton;
03170 if( state & ShiftMask )
03171 ret |= ShiftButton;
03172 if( state & ControlMask )
03173 ret |= ControlButton;
03174 if( state & KKeyNative::modX( KKey::ALT ))
03175 ret |= AltButton;
03176 if( state & KKeyNative::modX( KKey::WIN ))
03177 ret |= MetaButton;
03178 #elif defined(Q_WS_WIN)
03179 const bool mousebtn_swapped = GetSystemMetrics(SM_SWAPBUTTON);
03180 if (GetAsyncKeyState(VK_LBUTTON))
03181 ret |= (mousebtn_swapped ? RightButton : LeftButton);
03182 if (GetAsyncKeyState(VK_MBUTTON))
03183 ret |= MidButton;
03184 if (GetAsyncKeyState(VK_RBUTTON))
03185 ret |= (mousebtn_swapped ? LeftButton : RightButton);
03186 if (GetAsyncKeyState(VK_SHIFT))
03187 ret |= ShiftButton;
03188 if (GetAsyncKeyState(VK_CONTROL))
03189 ret |= ControlButton;
03190 if (GetAsyncKeyState(VK_MENU))
03191 ret |= AltButton;
03192 if (GetAsyncKeyState(VK_LWIN) || GetAsyncKeyState(VK_RWIN))
03193 ret |= MetaButton;
03194 #else
03195
03196 #endif
03197 return static_cast< ButtonState >( ret );
03198 }
03199
03200 void KApplication::installSigpipeHandler()
03201 {
03202 #ifdef Q_OS_UNIX
03203 struct sigaction act;
03204 act.sa_handler = SIG_IGN;
03205 sigemptyset( &act.sa_mask );
03206 act.sa_flags = 0;
03207 sigaction( SIGPIPE, &act, 0 );
03208 #endif
03209 }
03210
03211 void KApplication::sigpipeHandler(int)
03212 {
03213 int saved_errno = errno;
03214
03215 #ifndef NDEBUG
03216 char msg[1000];
03217 sprintf(msg, "*** SIGPIPE *** (ignored, pid = %ld)\n", (long) getpid());
03218 write(2, msg, strlen(msg));
03219 #endif
03220
03221
03222 errno = saved_errno;
03223 }
03224
03225 bool KApplication::guiEnabled()
03226 {
03227 return kapp && kapp->d->guiEnabled;
03228 }
03229
03230 void KApplication::virtual_hook( int id, void* data )
03231 { KInstance::virtual_hook( id, data ); }
03232
03233 void KSessionManaged::virtual_hook( int, void* )
03234 { }
03235
03236 #include "kapplication.moc"