00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include "config.h"
00024
00025 #undef QT_NO_TRANSLATION
00026 #include <qtranslator.h>
00027 #define QT_NO_TRANSLATION
00028 #undef Unsorted
00029 #include <qdir.h>
00030 #include <qptrcollection.h>
00031 #include <qwidgetlist.h>
00032 #include <qstrlist.h>
00033 #include <qfile.h>
00034 #include <qmessagebox.h>
00035 #include <qtextstream.h>
00036 #include <qregexp.h>
00037 #include <qlineedit.h>
00038 #include <qtextedit.h>
00039 #include <qsessionmanager.h>
00040 #include <qptrlist.h>
00041 #include <qtimer.h>
00042 #include <qstylesheet.h>
00043 #include <qpixmapcache.h>
00044 #include <qtooltip.h>
00045 #include <qstylefactory.h>
00046 #ifndef QT_NO_SQL
00047 #include <qsqlpropertymap.h>
00048 #endif
00049
00050 #undef QT_NO_TRANSLATION
00051 #include "kapplication.h"
00052 #define QT_NO_TRANSLATION
00053 #include <kglobal.h>
00054 #include <kstandarddirs.h>
00055 #include <kdebug.h>
00056 #include <klocale.h>
00057 #include <kstyle.h>
00058 #include <kiconloader.h>
00059 #include <kclipboard.h>
00060 #include <kconfig.h>
00061 #include <ksimpleconfig.h>
00062 #include <kcmdlineargs.h>
00063 #include <kaboutdata.h>
00064 #include <kglobalsettings.h>
00065 #include <kcrash.h>
00066 #include <kdatastream.h>
00067 #include <klibloader.h>
00068 #include <kmimesourcefactory.h>
00069 #include <kstdaccel.h>
00070 #include <kaccel.h>
00071 #include <kcheckaccelerators.h>
00072 #include <qptrdict.h>
00073
00074 #include <kstartupinfo.h>
00075
00076 #include <dcopclient.h>
00077
00078 #include <sys/types.h>
00079 #ifdef HAVE_SYS_STAT_H
00080 #include <sys/stat.h>
00081 #endif
00082 #include <sys/wait.h>
00083
00084 #include "kwin.h"
00085
00086 #include <fcntl.h>
00087 #include <stdlib.h>
00088 #include <signal.h>
00089 #include <unistd.h>
00090 #include <time.h>
00091 #include <sys/time.h>
00092 #include <errno.h>
00093 #include <string.h>
00094 #include <netdb.h>
00095 #ifndef Q_WS_QWS //FIXME(E): NetWM should talk to QWS...
00096 #include <netwm.h>
00097 #endif
00098
00099 #include "kprocctrl.h"
00100
00101 #ifdef HAVE_PATHS_H
00102 #include <paths.h>
00103 #endif
00104
00105 #ifdef Q_WS_X11
00106 #include <X11/Xlib.h>
00107 #include <X11/Xutil.h>
00108 #include <X11/Xatom.h>
00109 #include <X11/SM/SMlib.h>
00110 #endif
00111 #include <KDE-ICE/ICElib.h>
00112
00113 #if defined(Q_WS_X11)
00114
00115 const int XKeyPress = KeyPress;
00116 const int XKeyRelease = KeyRelease;
00117 #undef KeyPress
00118 #endif
00119
00120 #ifdef Q_WS_X11
00121 #define DISPLAY "DISPLAY"
00122 #elif defined(Q_WS_QWS)
00123 #define DISPLAY "QWS_DISPLAY"
00124 #endif
00125
00126 #include <kipc.h>
00127
00128 #include "kappdcopiface.h"
00129
00130 bool kde_have_kipc = true;
00131
00132 KApplication* KApplication::KApp = 0L;
00133 bool KApplication::loadedByKdeinit = false;
00134 DCOPClient *KApplication::s_DCOPClient = 0L;
00135 bool KApplication::s_dcopClientNeedsPostInit = false;
00136
00137 static Atom atom_DesktopWindow;
00138 static Atom atom_NetSupported;
00139 static Atom atom_KdeNetUserTime;
00140
00141 template class QPtrList<KSessionManaged>;
00142
00143 #ifdef Q_WS_X11
00144 extern "C" {
00145 static int kde_xio_errhandler( Display * )
00146 {
00147 return kapp->xioErrhandler();
00148 }
00149
00150 static int kde_x_errhandler( Display *dpy, XErrorEvent *err )
00151 {
00152 char errstr[256];
00153 XGetErrorText( dpy, err->error_code, errstr, 256 );
00154 if ( err->error_code != BadWindow )
00155 kdWarning() << "KDE detected X Error: " << errstr << " " << err->error_code
00156 << "\n Major opcode: " << err->request_code << endl;
00157 return 0;
00158 }
00159 }
00160 #endif
00161
00162 extern "C" {
00163 static void kde_ice_ioerrorhandler( IceConn conn )
00164 {
00165 if(kapp)
00166 kapp->iceIOErrorHandler( conn );
00167
00168 }
00169 }
00170
00171
00172
00173
00174 class KApplicationPrivate
00175 {
00176 public:
00177 KApplicationPrivate()
00178 : actionRestrictions( false ),
00179 refCount( 1 ),
00180 oldIceIOErrorHandler( 0 ),
00181 checkAccelerators( 0 ),
00182 overrideStyle( QString::null ),
00183 startup_id( "0" ),
00184 m_KAppDCOPInterface( 0L ),
00185 session_save( false )
00186 {
00187 }
00188
00189 ~KApplicationPrivate()
00190 {}
00191
00192
00193 bool actionRestrictions : 1;
00200 int refCount;
00201 IceIOErrorHandler oldIceIOErrorHandler;
00202 KCheckAccelerators* checkAccelerators;
00203 QString overrideStyle;
00204 QString geometry_arg;
00205 QCString startup_id;
00206 KAppDCOPInterface *m_KAppDCOPInterface;
00207 bool session_save;
00208
00209 class URLActionRule
00210 {
00211 public:
00212 #define checkExactMatch(s, b) \
00213 if (s.isEmpty()) b = true; \
00214 else if (s[s.length()-1] == '!') \
00215 { b = false; s.truncate(s.length()-1); } \
00216 else b = true;
00217 #define checkStartWildCard(s, b) \
00218 if (s.isEmpty()) b = true; \
00219 else if (s[0] == '*') \
00220 { b = true; s = s.mid(1); } \
00221 else b = false;
00222 #define checkEqual(s, b) \
00223 b = (s == "=");
00224
00225 URLActionRule(const QString &act,
00226 const QString &bProt, const QString &bHost, const QString &bPath,
00227 const QString &dProt, const QString &dHost, const QString &dPath,
00228 bool perm)
00229 : action(act),
00230 baseProt(bProt), baseHost(bHost), basePath(bPath),
00231 destProt(dProt), destHost(dHost), destPath(dPath),
00232 permission(perm)
00233 {
00234 checkExactMatch(baseProt, baseProtWildCard);
00235 checkStartWildCard(baseHost, baseHostWildCard);
00236 checkExactMatch(basePath, basePathWildCard);
00237 checkExactMatch(destProt, destProtWildCard);
00238 checkStartWildCard(destHost, destHostWildCard);
00239 checkExactMatch(destPath, destPathWildCard);
00240 checkEqual(destProt, destProtEqual);
00241 checkEqual(destHost, destHostEqual);
00242 }
00243
00244 bool baseMatch(const KURL &url)
00245 {
00246 if (baseProtWildCard)
00247 {
00248 if (!baseProt.isEmpty() && !url.protocol().startsWith(baseProt))
00249 return false;
00250 }
00251 else
00252 {
00253 if (url.protocol() != baseProt)
00254 return false;
00255 }
00256 if (baseHostWildCard)
00257 {
00258 if (!baseHost.isEmpty() && !url.host().endsWith(baseHost))
00259 return false;
00260 }
00261 else
00262 {
00263 if (url.host() != baseHost)
00264 return false;
00265 }
00266 if (basePathWildCard)
00267 {
00268 if (!basePath.isEmpty() && !url.path().startsWith(basePath))
00269 return false;
00270 }
00271 else
00272 {
00273 if (url.path() != basePath)
00274 return false;
00275 }
00276 return true;
00277 }
00278
00279 bool destMatch(const KURL &url, const KURL &base)
00280 {
00281 if (destProtEqual)
00282 {
00283 if (url.protocol() != base.protocol())
00284 return false;
00285 }
00286 else if (destProtWildCard)
00287 {
00288 if (!destProt.isEmpty() && !url.protocol().startsWith(destProt))
00289 return false;
00290 }
00291 else
00292 {
00293 if (url.protocol() != destProt)
00294 return false;
00295 }
00296 if (destHostWildCard)
00297 {
00298 if (!destHost.isEmpty() && !url.host().endsWith(destHost))
00299 return false;
00300 }
00301 else if (destHostEqual)
00302 {
00303 if (url.host() != base.host())
00304 return false;
00305 }
00306 else
00307 {
00308 if (url.host() != destHost)
00309 return false;
00310 }
00311 if (destPathWildCard)
00312 {
00313 if (!destPath.isEmpty() && !url.path().startsWith(destPath))
00314 return false;
00315 }
00316 else
00317 {
00318 if (url.path() != destPath)
00319 return false;
00320 }
00321 return true;
00322 }
00323
00324 QString action;
00325 QString baseProt;
00326 QString baseHost;
00327 QString basePath;
00328 QString destProt;
00329 QString destHost;
00330 QString destPath;
00331 bool baseProtWildCard : 1;
00332 bool baseHostWildCard : 1;
00333 bool basePathWildCard : 1;
00334 bool destProtWildCard : 1;
00335 bool destHostWildCard : 1;
00336 bool destPathWildCard : 1;
00337 bool destProtEqual : 1;
00338 bool destHostEqual : 1;
00339 bool permission;
00340 };
00341 QPtrList<URLActionRule> urlActionRestrictions;
00342
00343 QString sessionKey;
00344 QString pSessionConfigFile;
00345 };
00346
00347
00348 static QPtrList<QWidget>*x11Filter = 0;
00349 static bool autoDcopRegistration = true;
00350
00351 void KApplication::installX11EventFilter( QWidget* filter )
00352 {
00353 if ( !filter )
00354 return;
00355 if (!x11Filter)
00356 x11Filter = new QPtrList<QWidget>;
00357 connect ( filter, SIGNAL( destroyed() ), this, SLOT( x11FilterDestroyed() ) );
00358 x11Filter->append( filter );
00359 }
00360
00361 void KApplication::x11FilterDestroyed()
00362 {
00363 if ( !x11Filter || !sender() )
00364 return;
00365 QWidget *w = static_cast<QWidget *>(const_cast<QObject *>(sender()));
00366 x11Filter->removeRef( w );
00367 if ( x11Filter->isEmpty() ) {
00368 delete x11Filter;
00369 x11Filter = 0;
00370 }
00371 }
00372
00373
00374
00375
00376
00377 extern bool g_bKillAccelOverride;
00378
00379 bool KApplication::notify(QObject *receiver, QEvent *event)
00380 {
00381 QEvent::Type t = event->type();
00382 if (g_bKillAccelOverride)
00383 {
00384 g_bKillAccelOverride = false;
00385
00386 if (t == QEvent::AccelOverride)
00387 {
00388 static_cast<QKeyEvent *>(event)->accept();
00389 return true;
00390 }
00391 else
00392 kdWarning(125) << "g_bKillAccelOverride set, but received an event other than AccelOverride." << endl;
00393 }
00394
00395 if ((t == QEvent::AccelOverride) || (t == QEvent::KeyPress))
00396 {
00397 static const KShortcut& _selectAll = KStdAccel::selectAll();
00398 if (receiver && receiver->inherits("QLineEdit"))
00399 {
00400 QLineEdit *edit = static_cast<QLineEdit *>(receiver);
00401
00402 QKeyEvent *kevent = static_cast<QKeyEvent *>(event);
00403 KKey key(kevent);
00404 if (_selectAll.contains(key))
00405 {
00406 if (t == QEvent::KeyPress)
00407 {
00408 edit->selectAll();
00409 return true;
00410 }
00411 else
00412 {
00413 kevent->accept();
00414 }
00415 }
00416
00417 if (key == KKey(Qt::CTRL + Qt::Key_U))
00418 {
00419 if (t == QEvent::KeyPress)
00420 {
00421 if (!edit->isReadOnly())
00422 {
00423 QString t(edit->text());
00424 t = t.mid(edit->cursorPosition());
00425 edit->validateAndSet(t, 0, 0, 0);
00426 }
00427 return true;
00428 }
00429 else
00430 {
00431 kevent->accept();
00432 }
00433
00434 }
00435 }
00436 if (receiver && receiver->inherits("QTextEdit"))
00437 {
00438 QTextEdit *medit = static_cast<QTextEdit *>(receiver);
00439
00440 QKeyEvent *kevent = static_cast<QKeyEvent *>(event);
00441 if (_selectAll.contains(KKey(kevent)))
00442 {
00443 if (t == QEvent::KeyPress)
00444 {
00445 medit->selectAll();
00446 return true;
00447 }
00448 else
00449 {
00450 kevent->accept();
00451 }
00452 }
00453 }
00454 }
00455 return QApplication::notify(receiver, event);
00456 }
00457
00458
00459
00460 static QPtrList<KSessionManaged>* sessionClients()
00461 {
00462 static QPtrList<KSessionManaged>* session_clients = 0L;
00463 if ( !session_clients )
00464 session_clients = new QPtrList<KSessionManaged>;
00465 return session_clients;
00466 }
00467
00468
00469
00470
00471
00472
00473 QString KApplication::sessionConfigName() const
00474 {
00475 #if QT_VERSION < 0x030100
00476 return QString("session/%1_%2_%3").arg(name()).arg(sessionId()).arg(d->sessionKey);
00477 #else
00478 QString sessKey = sessionKey();
00479 if ( sessKey.isEmpty() && !d->sessionKey.isEmpty() )
00480 sessKey = d->sessionKey;
00481 return QString("session/%1_%2_%3").arg(name()).arg(sessionId()).arg(sessKey);
00482 #endif
00483 }
00484
00485 #ifndef Q_WS_QWS
00486 static SmcConn mySmcConnection = 0;
00487 static SmcConn tmpSmcConnection = 0;
00488 #else
00489
00490
00491 #endif
00492 static QTime* smModificationTime = 0;
00493
00494 KApplication::KApplication( int& argc, char** argv, const QCString& rAppName,
00495 bool allowStyles, bool GUIenabled ) :
00496 QApplication( argc, argv, GUIenabled ), KInstance(rAppName),
00497 #ifdef Q_WS_X11
00498 display(0L),
00499 #endif
00500 d (new KApplicationPrivate())
00501 {
00502 read_app_startup_id();
00503 if (!GUIenabled)
00504 allowStyles = false;
00505 useStyles = allowStyles;
00506 Q_ASSERT (!rAppName.isEmpty());
00507 setName(rAppName);
00508
00509 KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00510 parseCommandLine( );
00511 init(GUIenabled);
00512 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00513 }
00514
00515 KApplication::KApplication( bool allowStyles, bool GUIenabled ) :
00516 QApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00517 GUIenabled ),
00518 KInstance( KCmdLineArgs::about),
00519 #ifdef Q_WS_X11
00520 display(0L),
00521 #endif
00522 d (new KApplicationPrivate)
00523 {
00524 read_app_startup_id();
00525 if (!GUIenabled)
00526 allowStyles = false;
00527 useStyles = allowStyles;
00528 setName( instanceName() );
00529
00530 parseCommandLine( );
00531 init(GUIenabled);
00532 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00533 }
00534
00535 KApplication::KApplication( bool allowStyles, bool GUIenabled, KInstance* _instance ) :
00536 QApplication( *KCmdLineArgs::qt_argc(), *KCmdLineArgs::qt_argv(),
00537 GUIenabled ),
00538 KInstance( _instance ),
00539 #ifdef Q_WS_X11
00540 display(0L),
00541 #endif
00542 d (new KApplicationPrivate)
00543 {
00544 read_app_startup_id();
00545 if (!GUIenabled)
00546 allowStyles = false;
00547 useStyles = allowStyles;
00548 setName( instanceName() );
00549
00550 parseCommandLine( );
00551 init(GUIenabled);
00552 }
00553
00554 #ifdef Q_WS_X11
00555 KApplication::KApplication(Display *display, int& argc, char** argv, const QCString& rAppName,
00556 bool allowStyles, bool GUIenabled ) :
00557 QApplication( display ), KInstance(rAppName),
00558 display(0L),
00559 d (new KApplicationPrivate())
00560 {
00561 read_app_startup_id();
00562 if (!GUIenabled)
00563 allowStyles = false;
00564 useStyles = allowStyles;
00565
00566 Q_ASSERT (!rAppName.isEmpty());
00567 setName(rAppName);
00568
00569 KCmdLineArgs::initIgnore(argc, argv, rAppName.data());
00570 parseCommandLine( );
00571 init(GUIenabled);
00572 d->m_KAppDCOPInterface = new KAppDCOPInterface(this);
00573 }
00574 #endif
00575
00576 int KApplication::xioErrhandler()
00577 {
00578 if(kapp)
00579 {
00580 emit shutDown();
00581 exit( 1 );
00582 }
00583 return 0;
00584 }
00585
00586 void KApplication::iceIOErrorHandler( _IceConn *conn )
00587 {
00588 emit shutDown();
00589
00590 if ( d->oldIceIOErrorHandler != NULL )
00591 (*d->oldIceIOErrorHandler)( conn );
00592
00593 exit( 1 );
00594 }
00595
00596 class KDETranslator : public QTranslator
00597 {
00598 public:
00599 KDETranslator(QObject *parent) : QTranslator(parent, "kdetranslator") {}
00600 virtual QTranslatorMessage findMessage(const char* context,
00601 const char *sourceText,
00602 const char* message) const
00603 {
00604 QTranslatorMessage res;
00605 res.setTranslation(KGlobal::locale()->translateQt(context, sourceText, message));
00606 return res;
00607 }
00608 };
00609
00610 void KApplication::init(bool GUIenabled)
00611 {
00612 if ((getuid() != geteuid()) ||
00613 (getgid() != getegid()))
00614 {
00615 fprintf(stderr, "The KDE libraries are not designed to run with suid privileges.\n");
00616 ::exit(127);
00617 }
00618
00619 if( KProcessController::theKProcessController == 0 )
00620 (void) new KProcessController();
00621
00622 (void) KClipboardSynchronizer::self();
00623
00624 QApplication::setDesktopSettingsAware( false );
00625
00626 KApp = this;
00627
00628
00629 #ifdef Q_WS_X11 //FIXME(E)
00630
00631 if ( GUIenabled ) {
00632 const int max = 20;
00633 Atom* atoms[max];
00634 char* names[max];
00635 Atom atoms_return[max];
00636 int n = 0;
00637
00638 atoms[n] = &kipcCommAtom;
00639 names[n++] = (char *) "KIPC_COMM_ATOM";
00640
00641 atoms[n] = &atom_DesktopWindow;
00642 names[n++] = (char *) "KDE_DESKTOP_WINDOW";
00643
00644 atoms[n] = &atom_NetSupported;
00645 names[n++] = (char *) "_NET_SUPPORTED";
00646
00647 atoms[n] = &atom_KdeNetUserTime;
00648 names[n++] = (char *) "_KDE_NET_USER_TIME";
00649
00650 XInternAtoms( qt_xdisplay(), names, n, FALSE, atoms_return );
00651 for (int i = 0; i < n; i++ )
00652 *atoms[i] = atoms_return[i];
00653 }
00654 #endif
00655
00656 dcopAutoRegistration();
00657 dcopClientPostInit();
00658
00659 smw = 0;
00660
00661
00662 kipcEventMask = (1 << KIPC::StyleChanged) | (1 << KIPC::PaletteChanged) |
00663 (1 << KIPC::FontChanged) | (1 << KIPC::BackgroundChanged) |
00664 (1 << KIPC::ToolbarStyleChanged) | (1 << KIPC::SettingsChanged) |
00665 (1 << KIPC::ClipboardConfigChanged);
00666
00667
00668 (void) KGlobal::locale();
00669
00670 KConfig* config = KGlobal::config();
00671 d->actionRestrictions = config->hasGroup("KDE Action Restrictions" );
00672
00673 if (GUIenabled)
00674 {
00675 #ifdef Q_WS_X11
00676
00677 fcntl(ConnectionNumber(qt_xdisplay()), F_SETFD, FD_CLOEXEC);
00678
00679 XSetErrorHandler( kde_x_errhandler );
00680 XSetIOErrorHandler( kde_xio_errhandler );
00681 #endif
00682
00683 connect( this, SIGNAL( aboutToQuit() ), this, SIGNAL( shutDown() ) );
00684
00685 #ifdef Q_WS_X11 //FIXME(E)
00686 display = desktop()->x11Display();
00687 #endif
00688
00689 {
00690 QStringList plugins = KGlobal::dirs()->resourceDirs( "qtplugins" );
00691 QStringList::Iterator it = plugins.begin();
00692 while (it != plugins.end()) {
00693 addLibraryPath( *it );
00694 ++it;
00695 }
00696
00697 }
00698 kdisplaySetStyle();
00699 kdisplaySetFont();
00700
00701 propagateSettings(SETTINGS_QT);
00702
00703
00704 QMimeSourceFactory::setDefaultFactory (mimeSourceFactory());
00705
00706 KConfigGroupSaver saver( config, "Development" );
00707 if( config->hasKey( "CheckAccelerators" ) || config->hasKey( "AutoCheckAccelerators" ))
00708 d->checkAccelerators = new KCheckAccelerators( this );
00709 }
00710
00711
00712
00713 bool rtl = reverseLayout();
00714 installTranslator(new KDETranslator(this));
00715 setReverseLayout( rtl );
00716 if (i18n( "_: Dear Translator! Translate this string to the string 'LTR' in "
00717 "left-to-right languages (as english) or to 'RTL' in right-to-left "
00718 "languages (such as Hebrew and Arabic) to get proper widget layout." ) == "RTL")
00719
00720 setReverseLayout( !rtl );
00721
00722
00723 KGlobal::dirs()->addResourceType("appdata", KStandardDirs::kde_default("data")
00724 + QString::fromLatin1(name()) + '/');
00725 pSessionConfig = 0L;
00726 bSessionManagement = true;
00727
00728 #ifdef Q_WS_X11
00729
00730 if (GUIenabled && kde_have_kipc )
00731 {
00732 smw = new QWidget(0,0);
00733 long data = 1;
00734 XChangeProperty(qt_xdisplay(), smw->winId(),
00735 atom_DesktopWindow, atom_DesktopWindow,
00736 32, PropModeReplace, (unsigned char *)&data, 1);
00737 }
00738 #else
00739
00740 #endif
00741
00742 d->oldIceIOErrorHandler = IceSetIOErrorHandler( kde_ice_ioerrorhandler );
00743 }
00744
00745 static int my_system (const char *command) {
00746 int pid, status;
00747
00748 QApplication::flushX();
00749 pid = fork();
00750 if (pid == -1)
00751 return -1;
00752 if (pid == 0) {
00753 const char* shell = "/bin/sh";
00754 execl(shell, shell, "-c", command, 0L);
00755 ::exit(127);
00756 }
00757 do {
00758 if (waitpid(pid, &status, 0) == -1) {
00759 if (errno != EINTR)
00760 return -1;
00761 } else
00762 return status;
00763 } while(1);
00764 }
00765
00766
00767 DCOPClient *KApplication::dcopClient()
00768 {
00769 if (s_DCOPClient)
00770 return s_DCOPClient;
00771
00772 s_DCOPClient = new DCOPClient();
00773 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
00774 if (args->isSet("dcopserver"))
00775 {
00776 s_DCOPClient->setServerAddress( args->getOption("dcopserver"));
00777 }
00778 if( kapp ) {
00779 connect(s_DCOPClient, SIGNAL(attachFailed(const QString &)),
00780 kapp, SLOT(dcopFailure(const QString &)));
00781 connect(s_DCOPClient, SIGNAL(blockUserInput(bool) ),
00782 kapp, SLOT(dcopBlockUserInput(bool)) );
00783 }
00784 else
00785 s_dcopClientNeedsPostInit = true;
00786
00787 DCOPClient::setMainClient( s_DCOPClient );
00788 return s_DCOPClient;
00789 }
00790
00791 void KApplication::dcopClientPostInit()
00792 {
00793 if( s_dcopClientNeedsPostInit )
00794 {
00795 s_dcopClientNeedsPostInit = false;
00796 connect(s_DCOPClient, SIGNAL(blockUserInput(bool) ),
00797 SLOT(dcopBlockUserInput(bool)) );
00798 s_DCOPClient->bindToApp();
00799 }
00800 }
00801
00802 void KApplication::dcopAutoRegistration()
00803 {
00804 if (autoDcopRegistration)
00805 {
00806 ( void ) dcopClient();
00807 if( dcopClient()->appId().isEmpty())
00808 dcopClient()->registerAs(name());
00809 }
00810 }
00811
00812 void KApplication::disableAutoDcopRegistration()
00813 {
00814 autoDcopRegistration = false;
00815 }
00816
00817 KConfig* KApplication::sessionConfig()
00818 {
00819 if (pSessionConfig)
00820 return pSessionConfig;
00821
00822
00823 pSessionConfig = new KConfig( sessionConfigName(), false, false);
00824 return pSessionConfig;
00825 }
00826
00827 void KApplication::ref()
00828 {
00829 d->refCount++;
00830
00831 }
00832
00833 void KApplication::deref()
00834 {
00835 d->refCount--;
00836
00837 if ( d->refCount <= 0 )
00838 quit();
00839 }
00840
00841 KSessionManaged::KSessionManaged()
00842 {
00843 sessionClients()->remove( this );
00844 sessionClients()->append( this );
00845 }
00846
00847 KSessionManaged::~KSessionManaged()
00848 {
00849 sessionClients()->remove( this );
00850 }
00851
00852 bool KSessionManaged::saveState(QSessionManager&)
00853 {
00854 return true;
00855 }
00856
00857 bool KSessionManaged::commitData(QSessionManager&)
00858 {
00859 return true;
00860 }
00861
00862
00863 void KApplication::disableSessionManagement() {
00864 bSessionManagement = false;
00865 }
00866
00867
00868 bool KApplication::requestShutDown(
00869 ShutdownConfirm confirm, ShutdownType sdtype, ShutdownMode sdmode )
00870 {
00871 #ifdef Q_WS_X11
00872 QApplication::syncX();
00873
00874 if ( confirm == ShutdownConfirmYes ||
00875 sdtype != ShutdownTypeDefault ||
00876 sdmode != ShutdownModeDefault )
00877 {
00878 QByteArray data;
00879 QDataStream arg(data, IO_WriteOnly);
00880 arg << (int)confirm << (int)sdtype << (int)sdmode;
00881 return dcopClient()->send( "ksmserver", "ksmserver",
00882 "logout(int,int,int)", data );
00883 }
00884
00885 if ( mySmcConnection ) {
00886
00887 SmcRequestSaveYourself( mySmcConnection, SmSaveBoth, True,
00888 SmInteractStyleAny,
00889 confirm == ShutdownConfirmNo, True );
00890
00891
00892 IceFlush(SmcGetIceConnection(mySmcConnection));
00893 return TRUE;
00894 }
00895
00896
00897
00898 propagateSessionManager();
00899 QCString smEnv = ::getenv("SESSION_MANAGER");
00900 if (smEnv.isEmpty())
00901 return FALSE;
00902
00903 if (! tmpSmcConnection) {
00904 char cerror[256];
00905 char* myId = 0;
00906 char* prevId = 0;
00907 SmcCallbacks cb;
00908 tmpSmcConnection = SmcOpenConnection( 0, 0, 1, 0,
00909 0, &cb,
00910 prevId,
00911 &myId,
00912 255,
00913 cerror );
00914 ::free( myId );
00915 if (!tmpSmcConnection )
00916 return FALSE;
00917 }
00918
00919 SmcRequestSaveYourself( tmpSmcConnection, SmSaveBoth, True,
00920 SmInteractStyleAny, False, True );
00921
00922
00923 IceFlush(SmcGetIceConnection(tmpSmcConnection));
00924 return TRUE;
00925 #else
00926
00927 return false;
00928 #endif
00929 }
00930
00931 void KApplication::propagateSessionManager()
00932 {
00933 QCString fName = QFile::encodeName(locateLocal("socket", "KSMserver"));
00934 QCString display = ::getenv(DISPLAY);
00935
00936 display.replace(QRegExp("\\.[0-9]+$"), "");
00937 int i;
00938 while( (i = display.find(':')) >= 0)
00939 display[i] = '_';
00940
00941 fName += "_"+display;
00942 QCString smEnv = ::getenv("SESSION_MANAGER");
00943 bool check = smEnv.isEmpty();
00944 if ( !check && smModificationTime ) {
00945 QFileInfo info( fName );
00946 QTime current = info.lastModified().time();
00947 check = current > *smModificationTime;
00948 }
00949 if ( check ) {
00950 delete smModificationTime;
00951 QFile f( fName );
00952 if ( !f.open( IO_ReadOnly ) )
00953 return;
00954 QFileInfo info ( f );
00955 smModificationTime = new QTime( info.lastModified().time() );
00956 QTextStream t(&f);
00957 t.setEncoding( QTextStream::Latin1 );
00958 QString s = t.readLine();
00959 f.close();
00960 ::setenv( "SESSION_MANAGER", s.latin1(), TRUE );
00961 }
00962 }
00963
00964 void KApplication::commitData( QSessionManager& sm )
00965 {
00966 d->session_save = true;
00967 bool cancelled = false;
00968 for (KSessionManaged* it = sessionClients()->first();
00969 it && !cancelled;
00970 it = sessionClients()->next() ) {
00971 cancelled = !it->commitData( sm );
00972 }
00973 if ( cancelled )
00974 sm.cancel();
00975
00976 if ( sm.allowsInteraction() ) {
00977 QWidgetList done;
00978 QWidgetList *list = QApplication::topLevelWidgets();
00979 bool cancelled = FALSE;
00980 QWidget* w = list->first();
00981 while ( !cancelled && w ) {
00982 if ( !w->testWState( WState_ForceHide ) && !w->inherits("KMainWindow") ) {
00983 QCloseEvent e;
00984 sendEvent( w, &e );
00985 cancelled = !e.isAccepted();
00986 if ( !cancelled )
00987 done.append( w );
00988 delete list;
00989 list = QApplication::topLevelWidgets();
00990 w = list->first();
00991 } else {
00992 w = list->next();
00993 }
00994 while ( w && done.containsRef( w ) )
00995 w = list->next();
00996 }
00997 delete list;
00998 }
00999
01000
01001 if ( !bSessionManagement )
01002 sm.setRestartHint( QSessionManager::RestartNever );
01003 d->session_save = false;
01004 }
01005
01006 void KApplication::saveState( QSessionManager& sm )
01007 {
01008 d->session_save = true;
01009 #ifndef Q_WS_QWS
01010 static bool firstTime = true;
01011 mySmcConnection = (SmcConn) sm.handle();
01012
01013 if ( !bSessionManagement ) {
01014 sm.setRestartHint( QSessionManager::RestartNever );
01015 d->session_save = false;
01016 return;
01017 }
01018
01019 #if QT_VERSION < 0x030100
01020 {
01021
01022 timeval tv;
01023 gettimeofday( &tv, 0 );
01024 d->sessionKey = QString::number( tv.tv_sec ) + "_" + QString::number(tv.tv_usec);
01025 }
01026 #endif
01027
01028 if ( firstTime ) {
01029 firstTime = false;
01030 d->session_save = false;
01031 return;
01032 }
01033
01034
01035
01036
01037
01038
01039
01040 if ( pSessionConfig ) {
01041 delete pSessionConfig;
01042 pSessionConfig = 0;
01043 }
01044
01045
01046 QStringList restartCommand = sm.restartCommand();
01047 #if QT_VERSION < 0x030100
01048 restartCommand.clear();
01049 restartCommand << argv()[0] << "-session" << sm.sessionId() << "-smkey" << d->sessionKey;
01050 sm.setRestartCommand( restartCommand );
01051 #endif
01052
01053
01054 QCString multiHead = getenv("KDE_MULTIHEAD");
01055 if (multiHead.lower() == "true") {
01056
01057
01058
01059
01060
01061
01062 QCString displayname = getenv(DISPLAY);
01063 if (! displayname.isNull()) {
01064
01065
01066 restartCommand.append("-display");
01067 restartCommand.append(displayname);
01068 }
01069 sm.setRestartCommand( restartCommand );
01070 }
01071
01072
01073
01074 emit saveYourself();
01075 bool cancelled = false;
01076 for (KSessionManaged* it = sessionClients()->first();
01077 it && !cancelled;
01078 it = sessionClients()->next() ) {
01079 cancelled = !it->saveState( sm );
01080 }
01081
01082
01083 if ( pSessionConfig ) {
01084 pSessionConfig->sync();
01085 QStringList discard;
01086 discard << "rm" << locateLocal("config", sessionConfigName());
01087 sm.setDiscardCommand( discard );
01088 }
01089
01090 if ( cancelled )
01091 sm.cancel();
01092 #else
01093
01094 #endif
01095 d->session_save = false;
01096 }
01097
01098 bool KApplication::sessionSaving() const
01099 {
01100 return d->session_save;
01101 }
01102
01103 void KApplication::startKdeinit()
01104 {
01105
01106 QString srv = KStandardDirs::findExe(QString::fromLatin1("kdeinit"));
01107 if (srv.isEmpty())
01108 srv = KStandardDirs::findExe(QString::fromLatin1("kdeinit"), KDEDIR+QString::fromLatin1("/bin"));
01109 if (srv.isEmpty())
01110 return;
01111 if (kapp && (Tty != kapp->type()))
01112 setOverrideCursor( Qt::waitCursor );
01113 my_system(QFile::encodeName(srv)+" --suicide");
01114 if (kapp && (Tty != kapp->type()))
01115 restoreOverrideCursor();
01116 }
01117
01118 void KApplication::dcopFailure(const QString &msg)
01119 {
01120 static int failureCount = 0;
01121 failureCount++;
01122 if (failureCount == 1)
01123 {
01124 startKdeinit();
01125 return;
01126 }
01127 if (failureCount == 2)
01128 {
01129 QString msgStr(i18n("There was an error setting up inter-process\n"
01130 "communications for KDE. The message returned\n"
01131 "by the system was:\n\n"));
01132 msgStr += msg;
01133 msgStr += i18n("\n\nPlease check that the \"dcopserver\" program is running!");
01134
01135 if (Tty != kapp->type())
01136 {
01137 QMessageBox::critical
01138 (
01139 kapp->mainWidget(),
01140 i18n("DCOP communications error (%1)").arg(kapp->caption()),
01141 msgStr,
01142 i18n("OK")
01143 );
01144 }
01145 else
01146 {
01147 fprintf(stderr, "%s\n", msgStr.local8Bit().data());
01148 }
01149
01150 return;
01151 }
01152 }
01153
01154 static const KCmdLineOptions qt_options[] =
01155 {
01156
01157 #ifdef Q_WS_X11
01158 { "display <displayname>", I18N_NOOP("Use the X-server display 'displayname'."), 0},
01159 #else
01160 { "display <displayname>", I18N_NOOP("Use the QWS display 'displayname'."), 0},
01161 #endif
01162 { "session <sessionId>", I18N_NOOP("Restore the application for the given 'sessionId'."), 0},
01163 { "cmap", I18N_NOOP("Causes the application to install a private color\nmap on an 8-bit display."), 0},
01164 { "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},
01165 { "nograb", I18N_NOOP("tells Qt to never grab the mouse or the keyboard."), 0},
01166 { "dograb", I18N_NOOP("running under a debugger can cause an implicit\n-nograb, use -dograb to override."), 0},
01167 { "sync", I18N_NOOP("switches to synchronous mode for debugging."), 0},
01168 { "fn", 0, 0},
01169 { "font <fontname>", I18N_NOOP("defines the application font."), 0},
01170 { "bg", 0, 0},
01171 { "background <color>", I18N_NOOP("sets the default background color and an\napplication palette (light and dark shades are\ncalculated)."), 0},
01172 { "fg", 0, 0},
01173 { "foreground <color>", I18N_NOOP("sets the default foreground color."), 0},
01174 { "btn", 0, 0},
01175 { "button <color>", I18N_NOOP("sets the default button color."), 0},
01176 { "name <name>", I18N_NOOP("sets the application name."), 0},
01177 { "title <title>", I18N_NOOP("sets the application title (caption)."), 0},
01178 #ifdef Q_WS_X11
01179 { "visual TrueColor", I18N_NOOP("forces the application to use a TrueColor visual on\nan 8-bit display."), 0},
01180 { "inputstyle <inputstyle>", I18N_NOOP("sets XIM (X Input Method) input style. Possible\nvalues are onthespot, overthespot, offthespot and\nroot."), 0 },
01181 { "im <XIM server>", I18N_NOOP("set XIM server."),0},
01182 { "noxim", I18N_NOOP("disable XIM."), 0 },
01183 #endif
01184 #ifdef Q_WS_QWS
01185 { "qws", I18N_NOOP("forces the application to run as QWS Server."), 0},
01186 #endif
01187 { "reverse", I18N_NOOP("mirrors the whole layout of widgets."), 0},
01188 { 0, 0, 0 }
01189 };
01190
01191 static const KCmdLineOptions kde_options[] =
01192 {
01193 { "caption <caption>", I18N_NOOP("Use 'caption' as name in the titlebar."), 0},
01194 { "icon <icon>", I18N_NOOP("Use 'icon' as the application icon."), 0},
01195 { "miniicon <icon>", I18N_NOOP("Use 'icon' as the icon in the titlebar."), 0},
01196 { "config <filename>", I18N_NOOP("Use alternative configuration file."), 0},
01197 { "dcopserver <server>", I18N_NOOP("Use the DCOP Server specified by 'server'."), 0},
01198 { "nocrashhandler", I18N_NOOP("Disable crash handler, to get core dumps."), 0},
01199 { "waitforwm", I18N_NOOP("Waits for a WM_NET compatible windowmanager."), 0},
01200 { "style <style>", I18N_NOOP("sets the application GUI style."), 0},
01201 { "geometry <geometry>", I18N_NOOP("sets the client geometry of the main widget."), 0},
01202 #if QT_VERSION < 0x030100
01203 { "smkey <sessionKey>", I18N_NOOP("Define a 'sessionKey' for the session id. Only valid with -session"), 0},
01204 #else
01205 { "smkey <sessionKey>", 0, 0},
01206
01207
01208 #endif
01209 { 0, 0, 0 }
01210 };
01211
01212 void
01213 KApplication::addCmdLineOptions()
01214 {
01215 KCmdLineArgs::addCmdLineOptions(qt_options, "Qt", "qt");
01216 KCmdLineArgs::addCmdLineOptions(kde_options, "KDE", "kde");
01217 }
01218
01219 void KApplication::parseCommandLine( )
01220 {
01221 KCmdLineArgs *args = KCmdLineArgs::parsedArgs("kde");
01222
01223 if (args->isSet("config"))
01224 {
01225 QString config = QString::fromLocal8Bit(args->getOption("config"));
01226 setConfigName(config);
01227 }
01228
01229 if (args->isSet("style"))
01230 {
01231
01232 QStringList styles = QStyleFactory::keys();
01233 QString reqStyle(args->getOption("style").lower());
01234
01235 for (QStringList::ConstIterator it = styles.begin(); it != styles.end(); ++it)
01236 if ((*it).lower() == reqStyle)
01237 {
01238 d->overrideStyle = *it;
01239 break;
01240 }
01241
01242 if (d->overrideStyle.isEmpty())
01243 fprintf(stderr, "%s", i18n("The style %1 was not found\n").arg(reqStyle).local8Bit().data());
01244 }
01245
01246 if (args->isSet("caption"))
01247 {
01248 aCaption = QString::fromLocal8Bit(args->getOption("caption"));
01249 }
01250
01251 if (args->isSet("miniicon"))
01252 {
01253 const char *tmp = args->getOption("miniicon");
01254 aMiniIconPixmap = SmallIcon(tmp);
01255 aMiniIconName = tmp;
01256 }
01257
01258 if (args->isSet("icon"))
01259 {
01260 const char *tmp = args->getOption("icon");
01261 aIconPixmap = DesktopIcon( tmp );
01262 aIconName = tmp;
01263 if (aMiniIconPixmap.isNull())
01264 {
01265 aMiniIconPixmap = SmallIcon( tmp );
01266 aMiniIconName = tmp;
01267 }
01268 }
01269
01270 bool nocrashhandler = (getenv("KDE_DEBUG") != NULL);
01271 if (!nocrashhandler && args->isSet("crashhandler"))
01272 {
01273
01274 KCrash::setCrashHandler(KCrash::defaultCrashHandler);
01275 KCrash::setEmergencySaveFunction(NULL);
01276
01277 KCrash::setApplicationName(QString(args->appName()));
01278 }
01279
01280 #ifdef Q_WS_X11
01281 if ( args->isSet( "waitforwm" ) ) {
01282 Atom type;
01283 (void) desktop();
01284 int format;
01285 unsigned long length, after;
01286 unsigned char *data;
01287 while ( XGetWindowProperty( qt_xdisplay(), qt_xrootwin(), atom_NetSupported,
01288 0, 1, FALSE, AnyPropertyType, &type, &format,
01289 &length, &after, &data ) != Success || !length ) {
01290 if ( data )
01291 XFree( data );
01292 XEvent event;
01293 XWindowEvent( qt_xdisplay(), qt_xrootwin(), PropertyChangeMask, &event );
01294 }
01295 if ( data )
01296 XFree( data );
01297 }
01298 #else
01299
01300 #endif
01301
01302 if (args->isSet("geometry"))
01303 {
01304 d->geometry_arg = args->getOption("geometry");
01305 }
01306
01307 if (args->isSet("smkey"))
01308 {
01309 d->sessionKey = args->getOption("smkey");
01310 }
01311
01312 }
01313
01314 QString KApplication::geometryArgument() const
01315 {
01316 return d->geometry_arg;
01317 }
01318
01319 QPixmap KApplication::icon() const
01320 {
01321 if( aIconPixmap.isNull()) {
01322 KApplication *that = const_cast<KApplication *>(this);
01323 that->aIconPixmap = DesktopIcon( instanceName() );
01324 }
01325 return aIconPixmap;
01326 }
01327
01328 QString KApplication::iconName() const
01329 {
01330 return aIconName.isNull() ? (QString)instanceName() : aIconName;
01331 }
01332
01333 QPixmap KApplication::miniIcon() const
01334 {
01335 if (aMiniIconPixmap.isNull()) {
01336 KApplication *that = const_cast<KApplication *>(this);
01337 that->aMiniIconPixmap = SmallIcon( instanceName() );
01338 }
01339 return aMiniIconPixmap;
01340 }
01341
01342 QString KApplication::miniIconName() const
01343 {
01344 return aMiniIconName.isNull() ? (QString)instanceName() : aMiniIconName;
01345 }
01346
01347 extern void kDebugCleanup();
01348
01349 KApplication::~KApplication()
01350 {
01351 delete d->m_KAppDCOPInterface;
01352
01353
01354
01355
01356 KGlobal::deleteStaticDeleters();
01357 KLibLoader::cleanUp();
01358
01359 delete smw;
01360
01361
01362 delete s_DCOPClient;
01363 s_DCOPClient = 0L;
01364
01365 delete KProcessController::theKProcessController;
01366
01367 if ( d->oldIceIOErrorHandler != NULL )
01368 IceSetIOErrorHandler( d->oldIceIOErrorHandler );
01369
01370 delete d;
01371 KApp = 0;
01372
01373 #ifndef Q_WS_QWS
01374 mySmcConnection = 0;
01375 delete smModificationTime;
01376 smModificationTime = 0;
01377
01378
01379 if (tmpSmcConnection) {
01380 SmcCloseConnection( tmpSmcConnection, 0, 0 );
01381 tmpSmcConnection = 0;
01382 }
01383 #else
01384
01385 #endif
01386 }
01387
01388
01389 #ifdef Q_WS_X11
01390 class KAppX11HackWidget: public QWidget
01391 {
01392 public:
01393 bool publicx11Event( XEvent * e) { return x11Event( e ); }
01394 };
01395 #endif
01396
01397
01398
01399 static bool kapp_block_user_input = false;
01400
01401 void KApplication::dcopBlockUserInput( bool b )
01402 {
01403 kapp_block_user_input = b;
01404 }
01405
01406 #ifdef Q_WS_X11
01407 bool KApplication::x11EventFilter( XEvent *_event )
01408 {
01409 if ( activeWindow() ) {
01410 switch ( _event->type ) {
01411 case ButtonPress:
01412 case ButtonRelease:
01413 case XKeyPress:
01414 {
01415 timeval tv;
01416 gettimeofday( &tv, NULL );
01417 unsigned long now = tv.tv_sec * 10 + tv.tv_usec / 100000;
01418 XChangeProperty(qt_xdisplay(), activeWindow()->winId(),
01419 atom_KdeNetUserTime, XA_CARDINAL,
01420 32, PropModeReplace, (unsigned char *)&now, 1);
01421 }
01422 break;
01423 default: break;
01424 }
01425 }
01426
01427
01428 if ( kapp_block_user_input ) {
01429 switch ( _event->type ) {
01430 case ButtonPress:
01431 case ButtonRelease:
01432 case XKeyPress:
01433 case XKeyRelease:
01434 case MotionNotify:
01435 return TRUE;
01436 default:
01437 break;
01438 }
01439 }
01440
01441 if (x11Filter) {
01442 for (QWidget *w=x11Filter->first(); w; w=x11Filter->next()) {
01443 if (((KAppX11HackWidget*) w)->publicx11Event(_event))
01444 return true;
01445 }
01446 }
01447
01448 if ((_event->type == ClientMessage) &&
01449 (_event->xclient.message_type == kipcCommAtom))
01450 {
01451 XClientMessageEvent *cme = (XClientMessageEvent *) _event;
01452
01453 int id = cme->data.l[0];
01454 int arg = cme->data.l[1];
01455 if ((id < 32) && (kipcEventMask & (1 << id)))
01456 {
01457 switch (id)
01458 {
01459 case KIPC::StyleChanged:
01460 KGlobal::config()->reparseConfiguration();
01461 kdisplaySetStyle();
01462 break;
01463
01464 case KIPC::ToolbarStyleChanged:
01465 KGlobal::config()->reparseConfiguration();
01466 if (useStyles)
01467 emit toolbarAppearanceChanged(arg);
01468 break;
01469
01470 case KIPC::PaletteChanged:
01471 KGlobal::config()->reparseConfiguration();
01472 kdisplaySetPalette();
01473 break;
01474
01475 case KIPC::FontChanged:
01476 KGlobal::config()->reparseConfiguration();
01477 KGlobalSettings::rereadFontSettings();
01478 kdisplaySetFont();
01479 break;
01480
01481 case KIPC::BackgroundChanged:
01482 emit backgroundChanged(arg);
01483 break;
01484
01485 case KIPC::SettingsChanged:
01486 KGlobal::config()->reparseConfiguration();
01487 if (arg == SETTINGS_PATHS)
01488 KGlobalSettings::rereadPathSettings();
01489 else if (arg == SETTINGS_MOUSE)
01490 KGlobalSettings::rereadMouseSettings();
01491 propagateSettings((SettingsCategory)arg);
01492 break;
01493
01494 case KIPC::IconChanged:
01495 QPixmapCache::clear();
01496 KGlobal::config()->reparseConfiguration();
01497 KGlobal::instance()->newIconLoader();
01498 emit iconChanged(arg);
01499 break;
01500
01501 case KIPC::ClipboardConfigChanged:
01502 KClipboardSynchronizer::newConfiguration(arg);
01503 break;
01504 }
01505 }
01506 else if (id >= 32)
01507 {
01508 emit kipcMessage(id, arg);
01509 }
01510 return true;
01511 }
01512
01513 return false;
01514 }
01515 #endif
01516
01517 void KApplication::addKipcEventMask(int id)
01518 {
01519 if (id >= 32)
01520 {
01521 kdDebug(101) << "Cannot use KIPC event mask for message IDs >= 32\n";
01522 return;
01523 }
01524 kipcEventMask |= (1 << id);
01525 }
01526
01527 void KApplication::removeKipcEventMask(int id)
01528 {
01529 if (id >= 32)
01530 {
01531 kdDebug(101) << "Cannot use KIPC event mask for message IDs >= 32\n";
01532 return;
01533 }
01534 kipcEventMask &= ~(1 << id);
01535 }
01536
01537 void KApplication::enableStyles()
01538 {
01539 if (!useStyles)
01540 {
01541 useStyles = true;
01542 applyGUIStyle();
01543 }
01544 }
01545
01546 void KApplication::disableStyles()
01547 {
01548 useStyles = false;
01549 }
01550
01551 void KApplication::applyGUIStyle()
01552 {
01553 if ( !useStyles ) return;
01554
01555 KConfigGroup pConfig (KGlobal::config(), "General");
01556 QString defaultStyle = KStyle::defaultStyle();
01557 QString styleStr = pConfig.readEntry("widgetStyle", defaultStyle);
01558
01559 if (d->overrideStyle.isEmpty()) {
01560
01561
01562
01563 QStyle* sp = QStyleFactory::create( styleStr );
01564
01565
01566 if ( !sp && styleStr != defaultStyle)
01567 sp = QStyleFactory::create( defaultStyle );
01568 if ( !sp )
01569 sp = QStyleFactory::create( *(QStyleFactory::keys().begin()) );
01570 setStyle(sp);
01571 }
01572 else
01573 setStyle(d->overrideStyle);
01574
01575 kdisplaySetPalette();
01576 }
01577
01578 QString KApplication::caption() const
01579 {
01580
01581 if( !aCaption.isNull() )
01582 return aCaption;
01583 else
01584
01585 if ( KGlobal::instance()->aboutData() )
01586 return KGlobal::instance()->aboutData()->programName();
01587 else
01588
01589 return name();
01590 }
01591
01592
01593
01594
01595
01596
01597 QString KApplication::makeStdCaption( const QString &userCaption,
01598 bool withAppName, bool modified ) const
01599 {
01600 QString s = userCaption.isEmpty() ? caption() : userCaption;
01601
01602
01603 if (modified)
01604 s += QString::fromUtf8(" [") + i18n("modified") + QString::fromUtf8("]");
01605
01606 if ( !userCaption.isEmpty() ) {
01607
01608
01609 if ( withAppName && !caption().isNull() && !userCaption.endsWith(caption()) )
01610 s += QString::fromUtf8(" - ") + caption();
01611 }
01612
01613 return s;
01614 }
01615
01616 QPalette KApplication::createApplicationPalette()
01617 {
01618 KConfig *config = KGlobal::config();
01619 KConfigGroupSaver saver( config, "General" );
01620 return createApplicationPalette( config, KGlobalSettings::contrast() );
01621 }
01622
01623 QPalette KApplication::createApplicationPalette( KConfig *config, int contrast_ )
01624 {
01625 QColor kde31Background( 238, 238, 230 );
01626 QColor kde31Beige( 255,221,118 );
01627
01628 QColor kde31Button;
01629 if ( QPixmap::defaultDepth() > 8 )
01630 kde31Button.setRgb( 238, 234, 222 );
01631 else
01632 kde31Button.setRgb( 220, 220, 220 );
01633
01634 QColor kde31Link( 0, 0, 192 );
01635 QColor kde31VisitedLink( 128, 0,128 );
01636
01637 QColor background = config->readColorEntry( "background", &kde31Background );
01638 QColor foreground = config->readColorEntry( "foreground", &black );
01639 QColor button = config->readColorEntry( "buttonBackground", &kde31Button );
01640 QColor buttonText = config->readColorEntry( "buttonForeground", &foreground );
01641 QColor highlight = config->readColorEntry( "selectBackground", &kde31Beige );
01642 QColor highlightedText = config->readColorEntry( "selectForeground", &black );
01643 QColor base = config->readColorEntry( "windowBackground", &white );
01644 QColor baseText = config->readColorEntry( "windowForeground", &black );
01645 QColor link = config->readColorEntry( "linkColor", &kde31Link );
01646 QColor visitedLink = config->readColorEntry( "visitedLinkColor", &kde31VisitedLink );
01647
01648 int highlightVal, lowlightVal;
01649 highlightVal = 100 + (2*contrast_+4)*16/10;
01650 lowlightVal = 100 + (2*contrast_+4)*10;
01651
01652 QColor disfg = foreground;
01653
01654 int h, s, v;
01655 disfg.hsv( &h, &s, &v );
01656 if (v > 128)
01657
01658 disfg = disfg.dark(lowlightVal);
01659 else if (disfg != black)
01660
01661 disfg = disfg.light(highlightVal);
01662 else
01663
01664 disfg = Qt::darkGray;
01665
01666
01667 QColorGroup disabledgrp(disfg, background,
01668 background.light(highlightVal),
01669 background.dark(lowlightVal),
01670 background.dark(120),
01671 background.dark(120), base);
01672
01673 QColorGroup colgrp(foreground, background, background.light(highlightVal),
01674 background.dark(lowlightVal),
01675 background.dark(120),
01676 baseText, base);
01677
01678 int inlowlightVal = lowlightVal-25;
01679 if(inlowlightVal < 120)
01680 inlowlightVal = 120;
01681
01682 colgrp.setColor(QColorGroup::Highlight, highlight);
01683 colgrp.setColor(QColorGroup::HighlightedText, highlightedText);
01684 colgrp.setColor(QColorGroup::Button, button);
01685 colgrp.setColor(QColorGroup::ButtonText, buttonText);
01686 colgrp.setColor(QColorGroup::Midlight, background.light(110));
01687 colgrp.setColor(QColorGroup::Link, link);
01688 colgrp.setColor(QColorGroup::LinkVisited, visitedLink);
01689
01690 disabledgrp.setColor(QColorGroup::Button, button);
01691
01692 QColor disbtntext = buttonText;
01693 disbtntext.hsv( &h, &s, &v );
01694 if (v > 128)
01695
01696 disbtntext = disbtntext.dark(lowlightVal);
01697 else if (disbtntext != black)
01698
01699 disbtntext = disbtntext.light(highlightVal);
01700 else
01701
01702 disbtntext = Qt::darkGray;
01703
01704 disabledgrp.setColor(QColorGroup::ButtonText, disbtntext);
01705 disabledgrp.setColor(QColorGroup::Midlight, background.light(110));
01706 disabledgrp.setColor(QColorGroup::Link, link);
01707 disabledgrp.setColor(QColorGroup::LinkVisited, visitedLink);
01708
01709 return QPalette(colgrp, disabledgrp, colgrp);
01710 }
01711
01712
01713 void KApplication::kdisplaySetPalette()
01714 {
01715 QApplication::setPalette( createApplicationPalette(), true);
01716 emit kdisplayPaletteChanged();
01717 emit appearanceChanged();
01718 }
01719
01720
01721 void KApplication::kdisplaySetFont()
01722 {
01723 QApplication::setFont(KGlobalSettings::generalFont(), true);
01724 QApplication::setFont(KGlobalSettings::menuFont(), true, "QMenuBar");
01725 QApplication::setFont(KGlobalSettings::menuFont(), true, "QPopupMenu");
01726 QApplication::setFont(KGlobalSettings::menuFont(), true, "KPopupTitle");
01727
01728
01729 QStyleSheet* sheet = QStyleSheet::defaultSheet();
01730 sheet->item ("pre")->setFontFamily (KGlobalSettings::fixedFont().family());
01731 sheet->item ("code")->setFontFamily (KGlobalSettings::fixedFont().family());
01732 sheet->item ("tt")->setFontFamily (KGlobalSettings::fixedFont().family());
01733
01734 emit kdisplayFontChanged();
01735 emit appearanceChanged();
01736 }
01737
01738
01739 void KApplication::kdisplaySetStyle()
01740 {
01741 if (useStyles)
01742 {
01743 applyGUIStyle();
01744 emit kdisplayStyleChanged();
01745 emit appearanceChanged();
01746 }
01747 }
01748
01749
01750 void KApplication::propagateSettings(SettingsCategory arg)
01751 {
01752 KConfigBase* config = KGlobal::config();
01753 KConfigGroupSaver saver( config, "KDE" );
01754
01755 int num = config->readNumEntry("CursorBlinkRate", QApplication::cursorFlashTime());
01756 if (num < 200)
01757 num = 200;
01758 if (num > 2000)
01759 num = 2000;
01760 QApplication::setCursorFlashTime(num);
01761 num = config->readNumEntry("DoubleClickInterval", QApplication::doubleClickInterval());
01762 QApplication::setDoubleClickInterval(num);
01763 num = config->readNumEntry("StartDragTime", QApplication::startDragTime());
01764 QApplication::setStartDragTime(num);
01765 num = config->readNumEntry("StartDragDist", QApplication::startDragDistance());
01766 QApplication::setStartDragDistance(num);
01767 num = config->readNumEntry("WheelScrollLines", QApplication::wheelScrollLines());
01768 QApplication::setWheelScrollLines(num);
01769
01770 bool b = config->readBoolEntry("EffectAnimateMenu", false);
01771 QApplication::setEffectEnabled( Qt::UI_AnimateMenu, b);
01772 b = config->readBoolEntry("EffectFadeMenu", false);
01773 QApplication::setEffectEnabled( Qt::UI_FadeMenu, b);
01774 b = config->readBoolEntry("EffectAnimateCombo", false);
01775 QApplication::setEffectEnabled( Qt::UI_AnimateCombo, b);
01776 b = config->readBoolEntry("EffectAnimateTooltip", false);
01777 QApplication::setEffectEnabled( Qt::UI_AnimateTooltip, b);
01778 b = config->readBoolEntry("EffectFadeTooltip", false);
01779 QApplication::setEffectEnabled( Qt::UI_FadeTooltip, b);
01780 b = !config->readBoolEntry("EffectNoTooltip", false);
01781 QToolTip::setGloballyEnabled( b );
01782
01783 emit settingsChanged(arg);
01784 }
01785
01786 void KApplication::installKDEPropertyMap()
01787 {
01788 #ifndef QT_NO_SQL
01789
01790 QSqlPropertyMap *kdeMap = new QSqlPropertyMap;
01791 kdeMap->insert( "KColorButton", "color" );
01792 kdeMap->insert( "KComboBox", "currentItem" );
01793 kdeMap->insert( "KDatePicker", "date" );
01794 kdeMap->insert( "KEditListBox", "currentItem" );
01795 kdeMap->insert( "KFontCombo", "family" );
01796 kdeMap->insert( "KFontRequester", "font" );
01797 kdeMap->insert( "KHistoryCombo", "currentItem" );
01798 kdeMap->insert( "KListBox", "currentItem" );
01799 kdeMap->insert( "KLineEdit", "text" );
01800 kdeMap->insert( "KRestrictedLine", "text" );
01801 kdeMap->insert( "KSqueezedTextLabel", "text" );
01802 kdeMap->insert( "KTextBrowser", "source" );
01803 kdeMap->insert( "KTextEdit", "text" );
01804 kdeMap->insert( "KURLRequester", "url" );
01805 kdeMap->insert( "KPasswordEdit", "password" );
01806 kdeMap->insert( "KIntNumInput", "value" );
01807 kdeMap->insert( "KDoubleNumInput", "value" );
01808
01809
01810 kdeMap->insert( "QRadioButton", "checked" );
01811 kdeMap->insert( "QTabWidget", "currentPage" );
01812
01813 QSqlPropertyMap::installDefaultMap( kdeMap );
01814 #endif
01815
01816 }
01817
01818 void KApplication::invokeHelp( const QString& anchor,
01819 const QString& _appname) const
01820 {
01821 QString url;
01822 QString appname;
01823 if (_appname.isEmpty())
01824 appname = name();
01825 else
01826 appname = _appname;
01827
01828 if (!anchor.isEmpty())
01829 url = QString("help:/%1?anchor=%2").arg(appname).arg(anchor);
01830 else
01831 url = QString("help:/%1/index.html").arg(appname);
01832
01833 QString error;
01834
01835 if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, "", true))
01836 {
01837 kdWarning() << "Could not launch help:\n" << error << endl;
01838 return;
01839 }
01840 }
01841
01842 void KApplication::invokeHTMLHelp( const QString& _filename, const QString& topic ) const
01843 {
01844 kdWarning() << "invoking HTML help is deprecated! use docbook and invokeHelp!\n";
01845
01846 QString filename;
01847
01848 if( _filename.isEmpty() )
01849 filename = QString(name()) + "/index.html";
01850 else
01851 filename = _filename;
01852
01853 QString url;
01854 if (!topic.isEmpty())
01855 url = QString("help:/%1#%2").arg(filename).arg(topic);
01856 else
01857 url = QString("help:/%1").arg(filename);
01858
01859 QString error;
01860
01861 if (startServiceByDesktopName("khelpcenter", url, &error, 0, 0, "", true))
01862 {
01863 kdWarning() << "Could not launch help:\n" << error << endl;
01864 return;
01865 }
01866 }
01867
01868
01869 void KApplication::invokeMailer(const QString &address, const QString &subject)
01870 {
01871 invokeMailer(address, QString::null, QString::null, subject, QString::null, QString::null, QStringList());
01872 }
01873
01874 void KApplication::invokeMailer(const KURL &mailtoURL)
01875 {
01876 QString address = KURL::decode_string(mailtoURL.path()), subject, cc, bcc, body, attach;
01877 QStringList queries = QStringList::split('&', mailtoURL.query().mid(1));
01878 for (QStringList::Iterator it = queries.begin(); it != queries.end(); ++it)
01879 {
01880 QString q = (*it).lower();
01881 if (q.startsWith("subject="))
01882 subject = KURL::decode_string((*it).mid(8));
01883 else
01884 if (q.startsWith("cc="))
01885 cc = KURL::decode_string((*it).mid(3));
01886 else
01887 if (q.startsWith("bcc="))
01888 bcc = KURL::decode_string((*it).mid(4));
01889 else
01890 if (q.startsWith("body="))
01891 body = KURL::decode_string((*it).mid(5));
01892
01893
01894
01895 }
01896
01897 invokeMailer( address, cc, bcc, subject, body, QString::null, QStringList() );
01898 }
01899
01900 void KApplication::invokeMailer(const QString &to, const QString &cc, const QString &bcc,
01901 const QString &subject, const QString &body,
01902 const QString & , const QStringList &attachURLs)
01903 {
01904 KConfig config("emaildefaults");
01905 config.setGroup( QString::fromLatin1("PROFILE_Default") );
01906 QString command = config.readPathEntry("EmailClient");
01907
01908 if (command.isEmpty() || command == QString::fromLatin1("kmail")
01909 || command.right(6) == "/kmail")
01910 command = QString::fromLatin1("kmail --composer -s %s -c %c -b %b --body %B --attach %A -- %t");
01911
01912
01913
01914
01915
01916
01917 if (config.readBoolEntry("TerminalClient", false))
01918 command = "konsole -e " + command;
01919
01920
01921
01922
01923
01924 QStringList cmdTokens = QStringList::split(' ', command.simplifyWhiteSpace());
01925 QString cmd = cmdTokens[0];
01926 cmdTokens.remove(cmdTokens.begin());
01927 QString lastToken;
01928 QStringList newTokens;
01929
01930 for (QStringList::Iterator it = cmdTokens.begin(); it != cmdTokens.end(); ++it)
01931 {
01932 if ((*it).find("%t") >= 0)
01933 (*it).replace(QRegExp("%t"), to);
01934 else
01935 if ((*it).find("%s") >= 0)
01936 (*it).replace(QRegExp("%s"), subject);
01937 else
01938 if ((*it).find("%c") >= 0)
01939 (*it).replace(QRegExp("%c"), cc);
01940 else
01941 if ((*it).find("%b") >= 0)
01942 (*it).replace(QRegExp("%b"), bcc);
01943 else
01944 if ((*it).find("%B") >= 0)
01945 (*it).replace(QRegExp("%B"), body);
01946 else
01947 if ((*it).find("%A") >= 0)
01948 {
01949 QStringList::ConstIterator urlit = attachURLs.begin();
01950 QStringList::ConstIterator urlend = attachURLs.end();
01951 if ( urlit != urlend )
01952 {
01953 (*it).replace(QRegExp("%A"), (*urlit));
01954 ++urlit;
01955 QStringList::Iterator nextit = it; nextit++;
01956 for ( ; urlit != urlend ; ++urlit )
01957 {
01958 it = cmdTokens.insert( nextit, lastToken );
01959 it = cmdTokens.insert( nextit, (*urlit) );
01960 }
01961 } else
01962 (*it).replace(QRegExp("%A"), QString::null);
01963 }
01964 lastToken = (*it);
01965 }
01966 QString error;
01967
01968 if (kdeinitExec(cmd, cmdTokens, &error))
01969 {
01970 kdWarning() << "Could not launch mail client:\n" << error << endl;
01971 }
01972 }
01973
01974
01975 void KApplication::invokeBrowser( const QString &url )
01976 {
01977 QString error;
01978
01979 if (startServiceByDesktopName("kfmclient", url, &error, 0, 0, "", true))
01980 {
01981 kdWarning() << "Could not launch browser:\n" << error << endl;
01982 return;
01983 }
01984 }
01985
01986 QCString
01987 KApplication::launcher()
01988 {
01989 return "klauncher";
01990 }
01991
01992 static int
01993 startServiceInternal( const QCString &function,
01994 const QString& _name, const QStringList &URLs,
01995 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
01996 {
01997 struct serviceResult
01998 {
01999 int result;
02000 QCString dcopName;
02001 QString error;
02002 pid_t pid;
02003 };
02004
02005
02006 DCOPClient *dcopClient;
02007 if (kapp)
02008 dcopClient = kapp->dcopClient();
02009 else
02010 dcopClient = new DCOPClient;
02011
02012 if (!dcopClient->isAttached())
02013 {
02014 if (!dcopClient->attach())
02015 {
02016 if (error)
02017 *error = i18n("Could not register with DCOP.\n");
02018 return -1;
02019 }
02020 }
02021 QByteArray params;
02022 QDataStream stream(params, IO_WriteOnly);
02023 stream << _name << URLs;
02024 QCString replyType;
02025 QByteArray replyData;
02026 QCString _launcher = KApplication::launcher();
02027 QValueList<QCString> envs;
02028 #ifdef Q_WS_X11
02029 if (qt_xdisplay()) {
02030 QCString dpystring(XDisplayString(qt_xdisplay()));
02031 envs.append( QCString("DISPLAY=") + dpystring );
02032 } else if( getenv( "DISPLAY" )) {
02033 QCString dpystring( getenv( "DISPLAY" ));
02034 envs.append( QCString("DISPLAY=") + dpystring );
02035 }
02036 #endif
02037 stream << envs;
02038 if( !startup_id.isNull())
02039 stream << startup_id << noWait;
02040
02041 if (!dcopClient->call(_launcher, _launcher,
02042 function, params, replyType, replyData))
02043 {
02044 if (error)
02045 *error = i18n("KLauncher could not be reached via DCOP.\n");
02046 if (!kapp)
02047 delete dcopClient;
02048 return -1;
02049 }
02050 if (!kapp)
02051 delete dcopClient;
02052
02053 if (noWait)
02054 return 0;
02055
02056 QDataStream stream2(replyData, IO_ReadOnly);
02057 serviceResult result;
02058 stream2 >> result.result >> result.dcopName >> result.error >> result.pid;
02059 if (dcopService)
02060 *dcopService = result.dcopName;
02061 if (error)
02062 *error = result.error;
02063 if (pid)
02064 *pid = result.pid;
02065 return result.result;
02066 }
02067
02068 int
02069 KApplication::startServiceByName( const QString& _name, const QString &URL,
02070 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02071 {
02072 QStringList URLs;
02073 if (!URL.isEmpty())
02074 URLs.append(URL);
02075 return startServiceInternal(
02076 "start_service_by_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02077 _name, URLs, error, dcopService, pid, startup_id, noWait);
02078 }
02079
02080 int
02081 KApplication::startServiceByName( const QString& _name, const QStringList &URLs,
02082 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02083 {
02084 return startServiceInternal(
02085 "start_service_by_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02086 _name, URLs, error, dcopService, pid, startup_id, noWait);
02087 }
02088
02089 int
02090 KApplication::startServiceByDesktopPath( const QString& _name, const QString &URL,
02091 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02092 {
02093 QStringList URLs;
02094 if (!URL.isEmpty())
02095 URLs.append(URL);
02096 return startServiceInternal(
02097 "start_service_by_desktop_path(QString,QStringList,QValueList<QCString>,QCString,bool)",
02098 _name, URLs, error, dcopService, pid, startup_id, noWait);
02099 }
02100
02101 int
02102 KApplication::startServiceByDesktopPath( const QString& _name, const QStringList &URLs,
02103 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02104 {
02105 return startServiceInternal(
02106 "start_service_by_desktop_path(QString,QStringList,QValueList<QCString>,QCString,bool)",
02107 _name, URLs, error, dcopService, pid, startup_id, noWait);
02108 }
02109
02110 int
02111 KApplication::startServiceByDesktopName( const QString& _name, const QString &URL,
02112 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02113 {
02114 QStringList URLs;
02115 if (!URL.isEmpty())
02116 URLs.append(URL);
02117 return startServiceInternal(
02118 "start_service_by_desktop_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02119 _name, URLs, error, dcopService, pid, startup_id, noWait);
02120 }
02121
02122 int
02123 KApplication::startServiceByDesktopName( const QString& _name, const QStringList &URLs,
02124 QString *error, QCString *dcopService, int *pid, const QCString& startup_id, bool noWait )
02125 {
02126 return startServiceInternal(
02127 "start_service_by_desktop_name(QString,QStringList,QValueList<QCString>,QCString,bool)",
02128 _name, URLs, error, dcopService, pid, startup_id, noWait);
02129 }
02130
02131 int
02132 KApplication::kdeinitExec( const QString& name, const QStringList &args,
02133 QString *error, int *pid )
02134 {
02135 return startServiceInternal("kdeinit_exec(QString,QStringList,QValueList<QCString>)",
02136 name, args, error, 0, pid, QCString(), false);
02137 }
02138
02139 int
02140 KApplication::kdeinitExecWait( const QString& name, const QStringList &args,
02141 QString *error, int *pid )
02142 {
02143 return startServiceInternal("kdeinit_exec_wait(QString,QStringList,QValueList<QCString>)",
02144 name, args, error, 0, pid, QCString(), false);
02145 }
02146
02147 QString KApplication::tempSaveName( const QString& pFilename ) const
02148 {
02149 QString aFilename;
02150
02151 if( pFilename[0] != '/' )
02152 {
02153 kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
02154 aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
02155 }
02156 else
02157 aFilename = pFilename;
02158
02159 QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
02160 if( !aAutosaveDir.exists() )
02161 {
02162 if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
02163 {
02164
02165 aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
02166 }
02167 }
02168
02169 aFilename.replace( QRegExp( "/" ),"\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
02170
02171 return aFilename;
02172 }
02173
02174
02175 QString KApplication::checkRecoverFile( const QString& pFilename,
02176 bool& bRecover ) const
02177 {
02178 QString aFilename;
02179
02180 if( pFilename[0] != '/' )
02181 {
02182 kdWarning(101) << "Relative filename passed to KApplication::tempSaveName" << endl;
02183 aFilename = QFileInfo( QDir( "." ), pFilename ).absFilePath();
02184 }
02185 else
02186 aFilename = pFilename;
02187
02188 QDir aAutosaveDir( QDir::homeDirPath() + "/autosave/" );
02189 if( !aAutosaveDir.exists() )
02190 {
02191 if( !aAutosaveDir.mkdir( aAutosaveDir.absPath() ) )
02192 {
02193
02194 aAutosaveDir.setPath( KGlobal::dirs()->saveLocation("tmp") );
02195 }
02196 }
02197
02198 aFilename.replace( QRegExp( "/" ), "\\!" ).prepend( "#" ).append( "#" ).prepend( "/" ).prepend( aAutosaveDir.absPath() );
02199
02200 if( QFile( aFilename ).exists() )
02201 {
02202 bRecover = true;
02203 return aFilename;
02204 }
02205 else
02206 {
02207 bRecover = false;
02208 return pFilename;
02209 }
02210 }
02211
02212
02213 bool checkAccess(const QString& pathname, int mode)
02214 {
02215 int accessOK = access( QFile::encodeName(pathname), mode );
02216 if ( accessOK == 0 )
02217 return true;
02218
02219
02220
02221
02222 if ( (mode & W_OK) == 0 )
02223 return false;
02224
02225
02226 if (!access( QFile::encodeName(pathname), F_OK))
02227 return false;
02228
02229
02230 QString dirName(pathname);
02231 int pos = dirName.findRev('/');
02232 if ( pos == -1 )
02233 return false;
02234 else if ( pos == 0 )
02235 pos = 1;
02236
02237 dirName.truncate(pos);
02238
02239 accessOK = access( QFile::encodeName(dirName), W_OK );
02240
02241 if ( accessOK == 0 )
02242 return true;
02243 else
02244 return false;
02245 }
02246
02247 void KApplication::setTopWidget( QWidget *topWidget )
02248 {
02249 if( topWidget != 0 )
02250 {
02251 #ifdef Q_WS_X11 // FIXME(E): Implement for Qt/Embedded
02252 Window leader = topWidget->winId();
02253 char* argv = const_cast< char* >( KCmdLineArgs::appName());
02254 XSetCommand(display, leader, &argv, 1);
02255
02256 XWMHints *hints = XGetWMHints(display, topWidget->winId());
02257 if (hints)
02258 {
02259 if (!(hints->flags & WindowGroupHint))
02260 {
02261 hints->window_group = leader;
02262 hints->flags |= WindowGroupHint;
02263 }
02264 if (!(hints->flags & InputHint))
02265 {
02266 hints->input = True;
02267 hints->flags |= InputHint;
02268 }
02269 XSetWMHints(display, topWidget->winId(), hints);
02270 XFree(reinterpret_cast<char *>(hints));
02271 }
02272
02273 #endif
02274
02275 if ( !topWidget->inherits("KMainWindow") ) {
02276 topWidget->setCaption( caption() );
02277 #ifndef Q_WS_QWS // FIXME(E): Implement for Qt/Embedded
02278 NETWinInfo info(qt_xdisplay(), topWidget->winId(), qt_xrootwin(), NET::WMName );
02279 info.setName( caption().utf8().data() );
02280 #endif
02281 }
02282
02283
02284 topWidget->setIcon( icon() );
02285 #ifdef Q_WS_X11 // FIXME(E): Implement for Qt/Embedded
02286 KWin::setIcons(topWidget->winId(), icon(), miniIcon() );
02287
02288
02289 XSetIconName( qt_xdisplay(), topWidget->winId(), caption().utf8() );
02290
02291
02292 KStartupInfo::setWindowStartupId( topWidget->winId(), startupId());
02293 #endif
02294 }
02295 }
02296
02297 QCString KApplication::startupId() const
02298 {
02299 return d->startup_id;
02300 }
02301
02302 void KApplication::setStartupId( const QCString& startup_id )
02303 {
02304 if( startup_id.isEmpty())
02305 d->startup_id = "0";
02306 else
02307 d->startup_id = startup_id;
02308 }
02309
02310
02311
02312 void KApplication::read_app_startup_id()
02313 {
02314 #ifdef Q_WS_X11
02315 KStartupInfoId id = KStartupInfo::currentStartupIdEnv();
02316 KStartupInfo::resetStartupEnv();
02317 d->startup_id = id.id();
02318 #endif
02319 }
02320
02321 int KApplication::random()
02322 {
02323 static int init = false;
02324 if (!init)
02325 {
02326 unsigned int seed;
02327 init = true;
02328 int fd = open("/dev/urandom", O_RDONLY);
02329 if (fd <= 0 || ::read(fd, &seed, sizeof(seed)) != sizeof(seed))
02330 {
02331
02332 srand(getpid());
02333 seed = rand()+time(0);
02334 }
02335 if (fd >= 0) close(fd);
02336 srand(seed);
02337 }
02338 return rand();
02339 }
02340
02341 QString KApplication::randomString(int length)
02342 {
02343 if (length <=0 ) return QString::null;
02344
02345 QString str;
02346 while (--length)
02347 {
02348 int r=random() % 62;
02349 r+=48;
02350 if (r>57) r+=7;
02351 if (r>90) r+=6;
02352 str += char(r);
02353
02354 }
02355 return str;
02356 }
02357
02358 bool KApplication::authorize(const QString &genericAction)
02359 {
02360 if (!d->actionRestrictions)
02361 return true;
02362
02363 KConfig *config = KGlobal::config();
02364 KConfigGroupSaver saver( config, "KDE Action Restrictions" );
02365 return config->readBoolEntry(genericAction, true);
02366 }
02367
02368 bool KApplication::authorizeKAction(const char *action)
02369 {
02370 if (!d->actionRestrictions || !action)
02371 return true;
02372
02373 static const QString &action_prefix = KGlobal::staticQString( "action/" );
02374
02375 return authorize(action_prefix + action);
02376 }
02377
02378 void KApplication::initUrlActionRestrictions()
02379 {
02380 d->urlActionRestrictions.setAutoDelete(true);
02381 d->urlActionRestrictions.clear();
02382 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02383 ("open", QString::null, QString::null, QString::null, QString::null, QString::null, QString::null, true));
02384 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02385 ("list", QString::null, QString::null, QString::null, QString::null, QString::null, QString::null, true));
02386
02387
02388
02389
02390
02391 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02392 ("link", QString::null, QString::null, QString::null, "http", QString::null, QString::null, true));
02393 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02394 ("link", QString::null, QString::null, QString::null, "ftp", QString::null, QString::null, true));
02395 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02396 ("link", QString::null, QString::null, QString::null, "news", QString::null, QString::null, true));
02397 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02398 ("link", QString::null, QString::null, QString::null, "mailto", QString::null, QString::null, true));
02399 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02400 ("redirect", QString::null, QString::null, QString::null, "http", QString::null, QString::null, true));
02401 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02402 ("redirect", QString::null, QString::null, QString::null, "ftp", QString::null, QString::null, true));
02403 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02404 ("redirect", QString::null, QString::null, QString::null, "mailto", QString::null, QString::null, true));
02405 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02406 ("redirect", QString::null, QString::null, QString::null, "rtsp", QString::null, QString::null, true));
02407 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02408 ("redirect", QString::null, QString::null, QString::null, "mms", QString::null, QString::null, true));
02409
02410
02411
02412 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02413 ("redirect", QString::null, QString::null, QString::null, "file", QString::null, QString::null, true));
02414 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02415 ("redirect", "http", QString::null, QString::null, "file", QString::null, QString::null, false));
02416 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02417 ("redirect", "ftp", QString::null, QString::null, "file", QString::null, QString::null, false));
02418 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02419 ("redirect", "webdav", QString::null, QString::null, "file", QString::null, QString::null, false));
02420
02421
02422 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02423 ("redirect", "lan", QString::null, QString::null, QString::null, QString::null, QString::null, true));
02424
02425
02426 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02427 ("redirect", "info", QString::null, QString::null, "help", QString::null, QString::null, true));
02428
02429 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02430 ("redirect", QString::null, QString::null, QString::null, "about", QString::null, QString::null, true));
02431 d->urlActionRestrictions.append( new KApplicationPrivate::URLActionRule
02432 ("redirect", QString::null, QString::null, QString::null, "=", QString::null, QString::null, true));
02433
02434 KConfig *config = KGlobal::config();
02435 KConfigGroupSaver saver( config, "KDE URL Restrictions" );
02436 int count = config->readNumEntry("rule_count");
02437 QString keyFormat = QString("rule_%1");
02438 for(int i = 1; i <= count; i++)
02439 {
02440 QString key = keyFormat.arg(i);
02441 QStringList rule = config->readListEntry(key);
02442 if (rule.count() != 8)
02443 continue;
02444 QString action = rule[0];
02445 QString refProt = rule[1];
02446 QString refHost = rule[2];
02447 QString refPath = rule[3];
02448 QString urlProt = rule[4];
02449 QString urlHost = rule[5];
02450 QString urlPath = rule[6];
02451 QString strEnabled = rule[7].lower();
02452
02453 bool bEnabled = (strEnabled == "true");
02454
02455 if (refPath.startsWith("$HOME"))
02456 refPath.replace(0, 5, QDir::homeDirPath());
02457 else if (refPath.startsWith("~"))
02458 refPath.replace(0, 1, QDir::homeDirPath());
02459 if (urlPath.startsWith("$HOME"))
02460 urlPath.replace(0, 5, QDir::homeDirPath());
02461 else if (urlPath.startsWith("~"))
02462 urlPath.replace(0, 1, QDir::homeDirPath());
02463
02464 if (refPath.startsWith("$TMP"))
02465 refPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
02466 if (urlPath.startsWith("$TMP"))
02467 urlPath.replace(0, 4, KGlobal::dirs()->saveLocation("tmp"));
02468
02469 d->urlActionRestrictions.append(new KApplicationPrivate::URLActionRule
02470 ( action, refProt, refHost, refPath, urlProt, urlHost, urlPath, bEnabled));
02471 }
02472 }
02473
02474 bool KApplication::authorizeURLAction(const QString &action, const KURL &_baseURL, const KURL &_destURL)
02475 {
02476 bool result = false;
02477 if (d->urlActionRestrictions.isEmpty())
02478 initUrlActionRestrictions();
02479
02480 KURL baseURL(_baseURL);
02481 baseURL.setPath(QDir::cleanDirPath(baseURL.path()));
02482 KURL destURL(_destURL);
02483 destURL.setPath(QDir::cleanDirPath(destURL.path()));
02484
02485 for(KApplicationPrivate::URLActionRule *rule = d->urlActionRestrictions.first();
02486 rule; rule = d->urlActionRestrictions.next())
02487 {
02488 if ((result != rule->permission) &&
02489 (action == rule->action) &&
02490 rule->baseMatch(baseURL) &&
02491 rule->destMatch(destURL, baseURL))
02492 {
02493 result = rule->permission;
02494 }
02495 }
02496 return result;
02497 }
02498
02499
02500 uint KApplication::keyboardModifiers()
02501 {
02502 Window root;
02503 Window child;
02504 int root_x, root_y, win_x, win_y;
02505 uint keybstate;
02506 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
02507 &root_x, &root_y, &win_x, &win_y, &keybstate );
02508 return keybstate & 0x00ff;
02509 }
02510
02511 uint KApplication::mouseState()
02512 {
02513 Window root;
02514 Window child;
02515 int root_x, root_y, win_x, win_y;
02516 uint keybstate;
02517 XQueryPointer( qt_xdisplay(), qt_xrootwin(), &root, &child,
02518 &root_x, &root_y, &win_x, &win_y, &keybstate );
02519 return keybstate & 0xff00;
02520 }
02521
02522 void KApplication::virtual_hook( int id, void* data )
02523 { KInstance::virtual_hook( id, data ); }
02524
02525 void KSessionManaged::virtual_hook( int, void* )
02526 { }
02527
02528 #include "kapplication.moc"
02529 #define KeyPress XKeyPress