autostart.cpp

00001 /*
00002  *
00003  *  This file is part of the KDE libraries
00004  *  Copyright (c) 2001 Waldo Bastian <bastian@kde.org>
00005  *
00006  * $Id: autostart.cpp 534738 2006-04-27 18:04:45Z lunakl $
00007  *
00008  *  This library is free software; you can redistribute it and/or
00009  *  modify it under the terms of the GNU Library General Public
00010  *  License version 2 as published by the Free Software Foundation.
00011  *
00012  *  This library is distributed in the hope that it will be useful,
00013  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  *  Library General Public License for more details.
00016  *
00017  *  You should have received a copy of the GNU Library General Public License
00018  *  along with this library; see the file COPYING.LIB.  If not, write to
00019  *  the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020  *  Boston, MA 02110-1301, USA.
00021  **/
00022 
00023 #include "autostart.h"
00024 
00025 #include <kconfig.h>
00026 #include <kdesktopfile.h>
00027 #include <kglobal.h>
00028 #include <kstandarddirs.h>
00029 
00030 class AutoStartItem
00031 {
00032 public:
00033    QString name;
00034    QString service;
00035    QString startAfter;
00036    int     phase;
00037 };
00038 
00039 class AutoStartList: public QPtrList<AutoStartItem>
00040 {
00041 public:
00042    AutoStartList() { }
00043 };
00044 
00045 AutoStart::AutoStart( bool new_startup )
00046   : m_newStartup( new_startup ), m_phase( new_startup ? -1 : 0), m_phasedone(false)
00047 {
00048   m_startList = new AutoStartList;
00049   m_startList->setAutoDelete(true);
00050   KGlobal::dirs()->addResourceType("autostart", "share/autostart");
00051   QString xdgconf_dirs = KGlobal::dirs()->kfsstnd_xdg_conf_prefixes();
00052   if (xdgconf_dirs.isEmpty())
00053       xdgconf_dirs = "/etc/xdg";
00054   QStringList xdgconf_dirslist = QStringList::split( ':', xdgconf_dirs );
00055   for ( QStringList::Iterator d = xdgconf_dirslist.begin(); d != xdgconf_dirslist.end(); ++d )
00056       KGlobal::dirs()->addResourceDir("autostart", (*d) + "/autostart");
00057 }
00058 
00059 AutoStart::~AutoStart()
00060 {
00061     delete m_startList;
00062 }
00063 
00064 void
00065 AutoStart::setPhase(int phase)
00066 {
00067    if (phase > m_phase)
00068    {
00069       m_phase = phase;
00070       m_phasedone = false;
00071    }
00072 }
00073 
00074 void AutoStart::setPhaseDone()
00075 {
00076    m_phasedone = true;
00077 }
00078 
00079 static QString extractName(QString path)
00080 {
00081   int i = path.findRev('/');
00082   if (i >= 0)
00083      path = path.mid(i+1);
00084   i = path.findRev('.');
00085   if (i >= 0)
00086      path = path.left(i);
00087   return path;
00088 }
00089 
00090 static bool startCondition(const QString &condition)
00091 {
00092   if (condition.isEmpty())
00093      return true;
00094 
00095   QStringList list = QStringList::split(':', condition, true);
00096   if (list.count() < 4) 
00097      return true;
00098   if (list[0].isEmpty() || list[2].isEmpty()) 
00099      return true;
00100 
00101   KConfig config(list[0], true, false);
00102   if (!list[1].isEmpty())
00103      config.setGroup(list[1]);
00104 
00105   bool defaultValue = (list[3].lower() == "true");
00106 
00107   return config.readBoolEntry(list[2], defaultValue);
00108 }
00109 
00110 void
00111 AutoStart::loadAutoStartList()
00112 {
00113    QStringList files = KGlobal::dirs()->findAllResources("autostart", "*.desktop", false, true);
00114    
00115    for(QStringList::ConstIterator it = files.begin();
00116        it != files.end();
00117        ++it)
00118    {
00119        KDesktopFile config(*it, true);
00120        if (!startCondition(config.readEntry("X-KDE-autostart-condition")))
00121           continue;
00122        if (!config.tryExec())
00123           continue;
00124        if (config.readBoolEntry("Hidden", false))
00125           continue;
00126 
00127        if (config.hasKey("OnlyShowIn"))
00128        {
00129           if (!config.readListEntry("OnlyShowIn", ';').contains("KDE"))
00130               continue;
00131        }
00132        if (config.hasKey("NotShowIn"))
00133        {
00134            if (config.readListEntry("NotShowIn", ';').contains("KDE"))
00135                continue;
00136        }
00137        
00138        AutoStartItem *item = new AutoStartItem;
00139        item->name = extractName(*it);
00140        item->service = *it;
00141        item->startAfter = config.readEntry("X-KDE-autostart-after");
00142        if( m_newStartup )
00143        {
00144           item->phase = config.readNumEntry("X-KDE-autostart-phase", 2);
00145           if (item->phase < 0)
00146              item->phase = 0;
00147        }
00148        else
00149        {
00150           item->phase = config.readNumEntry("X-KDE-autostart-phase", 1);
00151           if (item->phase < 1)
00152              item->phase = 1;
00153        }
00154        m_startList->append(item);
00155    }
00156 } 
00157 
00158 QString
00159 AutoStart::startService()
00160 {
00161    if (m_startList->isEmpty())
00162       return 0;
00163 
00164    while(!m_started.isEmpty())
00165    {
00166 
00167      // Check for items that depend on previously started items
00168      QString lastItem = m_started[0];
00169      for(AutoStartItem *item = m_startList->first(); 
00170          item; item = m_startList->next())
00171      {
00172         if (item->phase == m_phase
00173         &&  item->startAfter == lastItem)
00174         {
00175            m_started.prepend(item->name);
00176            QString service = item->service;
00177            m_startList->remove();
00178            return service;
00179         }
00180      }
00181      m_started.remove(m_started.begin());
00182    }
00183    
00184    // Check for items that don't depend on anything
00185    AutoStartItem *item;
00186    for(item = m_startList->first();
00187        item; item = m_startList->next())
00188    {
00189       if (item->phase == m_phase
00190       &&  item->startAfter.isEmpty())
00191       {
00192          m_started.prepend(item->name);
00193          QString service = item->service;
00194          m_startList->remove();
00195          return service;
00196       }
00197    }
00198 
00199    // Just start something in this phase
00200    for(item = m_startList->first();
00201        item; item = m_startList->next())
00202    {
00203       if (item->phase == m_phase)
00204       {
00205          m_started.prepend(item->name);
00206          QString service = item->service;
00207          m_startList->remove();
00208          return service;
00209       }
00210    }
00211 
00212    return 0;
00213 }
KDE Home | KDE Accessibility Home | Description of Access Keys